Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions agents/integrations/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
## Source Of Truth

- `src/shared/core/agents/agent-provider-registry.ts`
- `packages/plugins/src/agents/impl/*`
- `packages/plugins/src/agents/registry.ts`
- `src/main/core/dependencies/dependency-managers.ts`
- `src/main/core/pty/`

## Current Providers (32)
## Current Providers (34)

codex, claude, grok, devin, qwen, qoder, droid, gemini, antigravity, cursor, copilot, amp, commandcode, opencode, hermes, charm, auggie, goose, kimi, kilocode, kiro, rovo, cline, continue, codebuff, freebuff, mistral, jules, junie, pi, autohand, letta
codex, claude, grok, devin, qwen, qoder, droid, gemini, antigravity, cursor, copilot, amp, commandcode, opencode, hermes, charm, auggie, goose, kimi, kilocode, kiro, rovo, cline, continue, codebuff, freebuff, mistral, jules, junie, pi, autohand, letta, mimocode, zero

## Provider Metadata Includes

Expand Down Expand Up @@ -39,8 +41,10 @@ or notify an inferred status for that event.
## Adding Or Changing A Provider

1. update `src/shared/core/agents/agent-provider-registry.ts`
2. update allowlisted agent env vars in `src/main/core/pty/pty-env.ts` if needed
3. add or update hook/plugin installation in `src/main/core/agent-hooks/` if the provider
2. add or update the provider plugin under `packages/plugins/src/agents/impl/*`
3. register the plugin in `packages/plugins/src/agents/registry.ts`
4. update allowlisted agent env vars in `src/main/core/pty/pty-env.ts` if needed
5. add or update hook/plugin installation in `src/main/core/agent-hooks/` if the provider
supports explicit events
4. validate detection behavior in `src/main/core/dependencies/`
5. add or update tests for any non-standard behavior
6. validate detection behavior in `src/main/core/dependencies/`
7. add or update tests for any non-standard behavior
4 changes: 4 additions & 0 deletions apps/emdash-desktop/src/assets/images/zero.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const AGENT_PROVIDER_IDS = [
'letta',
'autohand',
'mimocode',
'zero',
] as const;

export type AgentProviderId = (typeof AGENT_PROVIDER_IDS)[number];
Expand Down Expand Up @@ -732,6 +733,21 @@ export const AGENT_PROVIDERS: AgentProviderDefinition[] = [
terminalOnly: true,
supportsHooks: true,
},
{
id: 'zero',
name: 'Zero',
description:
'Terminal coding agent with multi-provider model support, local-first configuration, and terminal-first coding workflows.',
docUrl: 'https://zero.gitlawb.com/',
installCommand: 'npm install -g @gitlawb/zero',
commands: ['zero'],
versionArgs: ['--version'],
cli: 'zero',
useKeystrokeInjection: true,
icon: 'zero.svg',
alt: 'Zero CLI',
terminalOnly: true,
},
];

const PROVIDER_MAP = new Map<string, AgentProviderDefinition>(
Expand Down
12 changes: 12 additions & 0 deletions packages/plugins/src/agents/impl/zero/icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { AgentIconAsset } from '@emdash/core/agents/plugins';

export const icon: AgentIconAsset = {
kind: 'svg',
alt: 'Zero CLI',
variants: [
{
minSize: 0,
light: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" fill="#070708"/><text x="32" y="46" font-family="ui-monospace, Menlo, monospace" font-size="42" font-weight="800" text-anchor="middle" fill="#caff3f">0</text></svg>`,
},
],
};
42 changes: 42 additions & 0 deletions packages/plugins/src/agents/impl/zero/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { CommandContext } from '@emdash/core/agents/plugins';
import { describe, expect, it } from 'vitest';
import { pluginRegistry } from '../../registry';

const zero = pluginRegistry.get('zero')!;

function build(ctx: CommandContext) {
return zero.behavior.prompt!.buildCommand(ctx);
}

describe('zero plugin', () => {
it('registers install metadata and binary name', () => {
expect(zero.metadata.websiteUrl).toBe('https://zero.gitlawb.com/');
Comment thread
janburzinski marked this conversation as resolved.
expect(zero.capabilities.hostDependency.binaryNames).toEqual(['zero']);
expect(zero.capabilities.hostDependency.installCommands.macos?.[0]?.command).toBe(
'npm install -g @gitlawb/zero'
);
expect(zero.capabilities.hostDependency.updates).toMatchObject({
kind: 'supported',
releaseSource: { kind: 'npm', package: '@gitlawb/zero' },
});
expect(zero.capabilities.mcp.kind).toBe('none');
expect(zero.capabilities.sessions.kind).toBe('stateless');
});

it('starts the TUI and leaves prompt delivery to keystroke injection', () => {
expect(zero.capabilities.prompt.kind).toBe('keystroke');

const result = build({
cli: 'zero',
autoApprove: true,
initialPrompt: 'Fix the bug',
sessionId: 'conv-1',
isResuming: false,
model: '',
});

expect(result.command).toBe('zero');
expect(result.args).toEqual([]);
expect(result.env).toEqual({});
});
});
29 changes: 29 additions & 0 deletions packages/plugins/src/agents/impl/zero/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { definePlugin, registerPluginBehavior } from '@emdash/core/agents/plugins';
import { buildStandardCommand, npmDependency } from '@emdash/core/agents/plugins/helpers';
import { icon } from './icon';

export const plugin = definePlugin(
{
id: 'zero',
name: 'Zero',
description:
'Terminal coding agent with multi-provider model support, local-first configuration, and terminal-first coding workflows.',
websiteUrl: 'https://zero.gitlawb.com/',
},
{
hostDependency: npmDependency({ id: 'zero', package: '@gitlawb/zero' }),
prompt: {
kind: 'keystroke',
},
sessions: {
kind: 'stateless',
},
},
{ icon }
);

export const provider = registerPluginBehavior(plugin, {
prompt: {
buildCommand: (ctx) => buildStandardCommand(ctx, {}),
},
});
2 changes: 2 additions & 0 deletions packages/plugins/src/agents/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { provider as pi } from './impl/pi';
import { provider as qoder } from './impl/qoder';
import { provider as qwen } from './impl/qwen';
import { provider as rovo } from './impl/rovo';
import { provider as zero } from './impl/zero';

export const pluginRegistry = createPluginRegistry<CLIAgentPluginProvider>();

Expand Down Expand Up @@ -70,6 +71,7 @@ for (const p of [
qoder,
qwen,
rovo,
zero,
]) {
pluginRegistry.register(p);
}
Loading