@jini-ai/agent-runtime 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/auth.d.ts CHANGED
@@ -13,11 +13,13 @@ export declare function antigravityAuthGuidance(hostName?: string): string;
13
13
  export declare function antigravityQuotaGuidance(): string;
14
14
  export declare function reasonixAuthGuidance(hostName?: string): string;
15
15
  export declare function claudeAuthGuidance(hostName?: string): string;
16
+ export declare function geminiAuthGuidance(hostName?: string): string;
16
17
  export declare function isCursorAuthFailureText(text: string): boolean;
17
18
  export declare function isAntigravityAuthFailureText(text: string): boolean;
18
19
  export declare function isDeepSeekAuthFailureText(text: string): boolean;
19
20
  export declare function isReasonixAuthFailureText(text: string): boolean;
20
21
  export declare function isClaudeAuthFailureText(text: string): boolean;
22
+ export declare function isGeminiAuthFailureText(text: string): boolean;
21
23
  export declare function classifyAgentAuthFailure(agentId: string, text: string, hostName?: string): AgentAuthProbeResult | null;
22
24
  export type AgentServiceFailureCode = 'AGENT_AUTH_REQUIRED' | 'RATE_LIMITED' | 'UPSTREAM_UNAVAILABLE';
23
25
  export declare function classifyAgentServiceFailure(text: string): AgentServiceFailureCode | null;
package/dist/auth.js CHANGED
@@ -55,6 +55,17 @@ function reasonixAuthGuidanceText(hostName) {
55
55
  function claudeAuthGuidanceText(hostName) {
56
56
  return `Claude Code is installed but is not authenticated. Run \`claude auth login\` or open \`claude\` and complete login in a terminal, then rescan. If ${hostName} was launched outside an interactive shell, your shell rc files (e.g. ~/.zshrc) may not be loaded into its environment.`;
57
57
  }
58
+ // Gemini CLI has two distinct sign-in failures, and one fix covers both. With no auth method
59
+ // configured, headless mode exits with "Please set an Auth method in your <settings.json> or
60
+ // specify one of the following environment variables before running: GEMINI_API_KEY,
61
+ // GOOGLE_GENAI_USE_VERTEXAI, GOOGLE_GENAI_USE_GCA". With "Login with Google" on a free / Google AI
62
+ // Pro / Ultra account it dies with `IneligibleTierError: This client is no longer supported for
63
+ // Gemini Code Assist for individuals` (Google stopped serving those tiers on 2026-06-18; API keys,
64
+ // Vertex AI and Code Assist licenses still work). Signing in again cannot fix the second one, so
65
+ // the guidance points at an API key or Antigravity instead of a re-login.
66
+ function geminiAuthGuidanceText(hostName) {
67
+ return `Gemini CLI is installed but has no usable sign-in. Google no longer serves Gemini CLI's "Login with Google" for free, Google AI Pro or Ultra accounts. Use a Gemini API key instead: run \`gemini\` in a terminal, type /auth, choose "Use Gemini API key", and make GEMINI_API_KEY available to ${hostName}'s process environment (or configure Vertex AI). Google's replacement for individual accounts is Antigravity (\`agy\`), which you can pick here instead.`;
68
+ }
58
69
  export function cursorAuthGuidance(hostName = DEFAULT_HOST_NAME) {
59
70
  return cursorAuthGuidanceText(hostName);
60
71
  }
@@ -73,6 +84,9 @@ export function reasonixAuthGuidance(hostName = DEFAULT_HOST_NAME) {
73
84
  export function claudeAuthGuidance(hostName = DEFAULT_HOST_NAME) {
74
85
  return claudeAuthGuidanceText(hostName);
75
86
  }
87
+ export function geminiAuthGuidance(hostName = DEFAULT_HOST_NAME) {
88
+ return geminiAuthGuidanceText(hostName);
89
+ }
76
90
  export function isCursorAuthFailureText(text) {
77
91
  const value = String(text || '');
78
92
  if (!value.trim())
@@ -145,6 +159,16 @@ export function isClaudeAuthFailureText(text) {
145
159
  /authentication required/i.test(value) ||
146
160
  /please (?:sign|log)[ _-]?in/i.test(value));
147
161
  }
162
+ export function isGeminiAuthFailureText(text) {
163
+ const value = String(text || '');
164
+ if (!value.trim())
165
+ return false;
166
+ return (/please set an auth method/i.test(value) ||
167
+ /IneligibleTierError/.test(value) ||
168
+ /no longer supported for gemini code assist/i.test(value) ||
169
+ /error authenticating/i.test(value) ||
170
+ /api key not valid/i.test(value));
171
+ }
148
172
  export function classifyAgentAuthFailure(agentId, text, hostName = DEFAULT_HOST_NAME) {
149
173
  if (agentId === 'claude') {
150
174
  if (!isClaudeAuthFailureText(text))
@@ -171,6 +195,11 @@ export function classifyAgentAuthFailure(agentId, text, hostName = DEFAULT_HOST_
171
195
  return null;
172
196
  return { status: 'missing', message: reasonixAuthGuidance(hostName) };
173
197
  }
198
+ if (agentId === 'gemini') {
199
+ if (!isGeminiAuthFailureText(text))
200
+ return null;
201
+ return { status: 'missing', message: geminiAuthGuidance(hostName) };
202
+ }
174
203
  return null;
175
204
  }
176
205
  // A bare HTTP status number (`500`, `429`, …) is too noisy to trust on its own
@@ -250,7 +279,7 @@ function genericAuthGuidance(agentName, hostName) {
250
279
  // regex (e.g. cursor-agent's healthy `status` output mentions "login" in
251
280
  // ways the generic matcher would misread). The generic classifier is only a
252
281
  // fallback for adapters with no tailored classifier of their own.
253
- const TAILORED_AUTH_AGENTS = new Set(['claude', 'cursor-agent', 'deepseek', 'antigravity', 'reasonix']);
282
+ const TAILORED_AUTH_AGENTS = new Set(['claude', 'cursor-agent', 'deepseek', 'antigravity', 'reasonix', 'gemini']);
254
283
  function hasNonEmptyEnv(env, keys) {
255
284
  return keys.some((key) => {
256
285
  const value = env[key];
@@ -0,0 +1,13 @@
1
+ export declare const auggieAgentDef: {
2
+ id: string;
3
+ name: string;
4
+ bin: string;
5
+ versionArgs: string[];
6
+ fetchModels: (resolvedBin: string, env: import("../types.js").RuntimeEnv) => Promise<import("../types.js").RuntimeModelOption[]>;
7
+ fallbackModels: import("../types.js").RuntimeModelOption[];
8
+ buildArgs: () => string[];
9
+ streamFormat: string;
10
+ externalMcpInjection: "acp-merge";
11
+ imageDelivery: "native";
12
+ };
13
+ //# sourceMappingURL=auggie.d.ts.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @module defs/auggie
3
+ *
4
+ * Augment Code's Auggie CLI (`auggie`, npm `@augmentcode/auggie`). Runs over ACP: `auggie --acp`
5
+ * is the launch command the official ACP registry lists
6
+ * (<https://github.com/agentclientprotocol/registry>, `auggie/agent.json`). Sign-in is
7
+ * `auggie login` in a terminal.
8
+ */
9
+ import { detectAcpModels, DEFAULT_MODEL_OPTION } from './shared.js';
10
+ export const auggieAgentDef = {
11
+ id: 'auggie',
12
+ name: 'Auggie CLI',
13
+ bin: 'auggie',
14
+ versionArgs: ['--version'],
15
+ fetchModels: async (resolvedBin, env) => detectAcpModels({
16
+ bin: resolvedBin,
17
+ args: ['--acp'],
18
+ env,
19
+ timeoutMs: 15_000,
20
+ defaultModelOption: DEFAULT_MODEL_OPTION,
21
+ }),
22
+ fallbackModels: [DEFAULT_MODEL_OPTION],
23
+ buildArgs: () => ['--acp'],
24
+ streamFormat: 'acp-json-rpc',
25
+ externalMcpInjection: 'acp-merge',
26
+ // ACP's `resource_link` prompt blocks carry images natively for every
27
+ // `acp-json-rpc` def — see `types.ts#RuntimeAgentDef.imageDelivery`'s doc.
28
+ imageDelivery: 'native',
29
+ };
30
+ //# sourceMappingURL=auggie.js.map
@@ -0,0 +1,13 @@
1
+ export declare const clineAgentDef: {
2
+ id: string;
3
+ name: string;
4
+ bin: string;
5
+ versionArgs: string[];
6
+ fetchModels: (resolvedBin: string, env: import("../types.js").RuntimeEnv) => Promise<import("../types.js").RuntimeModelOption[]>;
7
+ fallbackModels: import("../types.js").RuntimeModelOption[];
8
+ buildArgs: () => string[];
9
+ streamFormat: string;
10
+ externalMcpInjection: "acp-merge";
11
+ imageDelivery: "native";
12
+ };
13
+ //# sourceMappingURL=cline.d.ts.map
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @module defs/cline
3
+ *
4
+ * Cline CLI (`cline`, npm `cline`). Runs over ACP: `cline --acp` is both the launch command the
5
+ * official ACP registry lists (<https://github.com/agentclientprotocol/registry>, `cline/agent.json`)
6
+ * and what an installed `cline` 3.0.60 answered live — `initialize` returned
7
+ * `promptCapabilities.image: true` and three `authMethods`, and `session/new` on a machine with no
8
+ * sign-in failed with "Authentication required: Call authenticate before starting a session",
9
+ * which `auth.ts`'s generic classifier already reads as a missing sign-in (fix: `cline auth`).
10
+ */
11
+ import { detectAcpModels, DEFAULT_MODEL_OPTION } from './shared.js';
12
+ export const clineAgentDef = {
13
+ id: 'cline',
14
+ name: 'Cline',
15
+ bin: 'cline',
16
+ versionArgs: ['--version'],
17
+ fetchModels: async (resolvedBin, env) => detectAcpModels({
18
+ bin: resolvedBin,
19
+ args: ['--acp'],
20
+ env,
21
+ timeoutMs: 15_000,
22
+ defaultModelOption: DEFAULT_MODEL_OPTION,
23
+ }),
24
+ fallbackModels: [DEFAULT_MODEL_OPTION],
25
+ buildArgs: () => ['--acp'],
26
+ streamFormat: 'acp-json-rpc',
27
+ externalMcpInjection: 'acp-merge',
28
+ // ACP's `resource_link` prompt blocks carry images natively for every
29
+ // `acp-json-rpc` def — see `types.ts#RuntimeAgentDef.imageDelivery`'s doc.
30
+ imageDelivery: 'native',
31
+ };
32
+ //# sourceMappingURL=cline.js.map
@@ -0,0 +1,11 @@
1
+ export declare const crushAgentDef: {
2
+ id: string;
3
+ name: string;
4
+ bin: string;
5
+ versionArgs: string[];
6
+ fallbackModels: import("../types.js").RuntimeModelOption[];
7
+ buildArgs: (_prompt: string, _imagePaths: string[], _extra: string[] | undefined, options?: import("../types.js").RuntimeBuildOptions | undefined) => string[];
8
+ promptViaStdin: true;
9
+ streamFormat: string;
10
+ };
11
+ //# sourceMappingURL=crush.d.ts.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @module defs/crush
3
+ *
4
+ * Charm's Crush (`crush`). Checked against upstream source (`internal/cmd/run.go` / `root.go`):
5
+ * `crush run [prompt...]` runs one prompt non-interactively and exits; with no prompt args, piped
6
+ * stdin becomes the whole prompt ("no prompt provided" only when both are empty). The answer is
7
+ * plain text on stdout, the spinner goes to stderr and `--quiet` hides it. `--yolo` (root flag)
8
+ * skips permission requests; `--model` takes `model` or `provider/model`.
9
+ *
10
+ * No `externalMcpInjection`: Crush reads MCP servers from its `crush.json` config, with no
11
+ * per-run flag to point it elsewhere.
12
+ */
13
+ import { DEFAULT_MODEL_OPTION } from './shared.js';
14
+ export const crushAgentDef = {
15
+ id: 'crush',
16
+ name: 'Crush',
17
+ bin: 'crush',
18
+ versionArgs: ['--version'],
19
+ // Models come from the providers the user configured in Crush; there is no stable default
20
+ // list to ship, so the picker offers the CLI default and accepts any typed id.
21
+ fallbackModels: [DEFAULT_MODEL_OPTION],
22
+ buildArgs: (_prompt, _imagePaths, _extra, options = {}) => {
23
+ const args = ['run', '--quiet'];
24
+ // See `RuntimeBuildOptions.permissionMode`'s doc: bypass is the default (unchanged
25
+ // behavior) unless a caller explicitly opts into a restricted run.
26
+ if (options.permissionMode !== 'restricted') {
27
+ args.push('--yolo');
28
+ }
29
+ if (options.model && options.model !== 'default') {
30
+ args.push('--model', options.model);
31
+ }
32
+ return args;
33
+ },
34
+ promptViaStdin: true,
35
+ streamFormat: 'plain',
36
+ };
37
+ //# sourceMappingURL=crush.js.map
@@ -0,0 +1,11 @@
1
+ export declare const droidAgentDef: {
2
+ id: string;
3
+ name: string;
4
+ bin: string;
5
+ versionArgs: string[];
6
+ fallbackModels: import("../types.js").RuntimeModelOption[];
7
+ buildArgs: (_prompt: string, _imagePaths: string[], _extra: string[] | undefined, options?: import("../types.js").RuntimeBuildOptions | undefined) => string[];
8
+ promptViaStdin: true;
9
+ streamFormat: string;
10
+ };
11
+ //# sourceMappingURL=droid.d.ts.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @module defs/droid
3
+ *
4
+ * Factory's Droid CLI (`droid`). Uses the documented headless mode, `droid exec`
5
+ * (<https://docs.factory.ai/reference/cli-reference>, <https://docs.factory.ai/droid-exec/overview>):
6
+ * the prompt can be piped on stdin (`cat file | droid exec`), `--output-format text` prints the
7
+ * final answer, and `-m/--model` picks the model. `droid exec` is read-only unless given an
8
+ * autonomy level; `--skip-permissions-unsafe` lifts every permission check (it cannot be combined
9
+ * with `--auto`). Auth is `FACTORY_API_KEY` or a prior `droid` login.
10
+ *
11
+ * Not ACP: the ACP registry launches Droid with `droid exec --output-format acp-daemon`, but that
12
+ * value is not in the CLI reference, newer builds were reported to switch to `acp`, and the daemon
13
+ * variant was reported to fail with stdio MCP servers. The documented text mode is the stable one.
14
+ * No `externalMcpInjection` for the same reason.
15
+ */
16
+ import { DEFAULT_MODEL_OPTION } from './shared.js';
17
+ export const droidAgentDef = {
18
+ id: 'droid',
19
+ name: 'Factory Droid',
20
+ bin: 'droid',
21
+ versionArgs: ['--version'],
22
+ fallbackModels: [DEFAULT_MODEL_OPTION],
23
+ buildArgs: (_prompt, _imagePaths, _extra, options = {}) => {
24
+ const args = ['exec', '--output-format', 'text'];
25
+ // See `RuntimeBuildOptions.permissionMode`'s doc: bypass is the default (unchanged
26
+ // behavior); a restricted run keeps `droid exec`'s own read-only default.
27
+ if (options.permissionMode !== 'restricted') {
28
+ args.push('--skip-permissions-unsafe');
29
+ }
30
+ if (options.model && options.model !== 'default') {
31
+ args.push('--model', options.model);
32
+ }
33
+ return args;
34
+ },
35
+ promptViaStdin: true,
36
+ streamFormat: 'plain',
37
+ };
38
+ //# sourceMappingURL=droid.js.map
@@ -0,0 +1,17 @@
1
+ export declare const geminiAgentDef: {
2
+ id: string;
3
+ name: string;
4
+ bin: string;
5
+ versionArgs: string[];
6
+ versionProbeTimeoutMs: number;
7
+ helpArgs: string[];
8
+ capabilityFlags: {
9
+ "--skip-trust": string;
10
+ };
11
+ fallbackModels: import("../types.js").RuntimeModelOption[];
12
+ buildArgs: (_prompt: string, _imagePaths: string[], extraAllowedDirs?: string[] | undefined, options?: import("../types.js").RuntimeBuildOptions | undefined) => string[];
13
+ promptViaStdin: true;
14
+ streamFormat: string;
15
+ eventParser: string;
16
+ };
17
+ //# sourceMappingURL=gemini.d.ts.map
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @module defs/gemini
3
+ *
4
+ * Google's Gemini CLI (`gemini`, npm `@google/gemini-cli`). Checked against an installed
5
+ * `gemini` 0.58.0 (`gemini --help` and the bundled headless code path) and the upstream headless
6
+ * docs (<https://geminicli.com/docs/cli/headless>):
7
+ *
8
+ * - Headless mode starts whenever stdin is not a TTY; the whole piped stdin becomes the prompt
9
+ * (`-p` is only needed to pass the prompt in argv, and would be "appended to input on stdin").
10
+ * So the prompt goes over stdin, like the Qwen Code fork, which avoids Windows `spawn
11
+ * ENAMETOOLONG` on large composed prompts.
12
+ * - `--output-format stream-json` emits the JSONL `init` / `message` / `tool_use` /
13
+ * `tool_result` / `error` / `result` events that `json-event-stream.ts`'s `gemini` parser
14
+ * already reads.
15
+ * - `--approval-mode yolo` auto-approves every tool (the `--yolo` alias does the same).
16
+ * - Since folder trust landed, a headless run in an untrusted directory exits with "Gemini CLI
17
+ * is not running in a trusted directory. To proceed, either use `--skip-trust`, …". The host
18
+ * already chose the run's cwd, so the def trusts it for this session only. Older builds
19
+ * reject unknown flags, so `--skip-trust` is gated on the `--help` capability probe.
20
+ * - `--include-directories` (repeatable) widens the workspace to dirs outside the cwd.
21
+ *
22
+ * Auth: since 2026-06-18 Google no longer serves Gemini CLI's "Login with Google" for free /
23
+ * Google AI Pro / Ultra individual accounts (the run dies with `IneligibleTierError: This client
24
+ * is no longer supported for Gemini Code Assist for individuals`). A Gemini API key, Vertex AI,
25
+ * or a Gemini Code Assist license still works. There is no side-effect-free auth-status
26
+ * subcommand, so no `authProbe`; `auth.ts#classifyAgentAuthFailure` turns the failure text into
27
+ * setup guidance instead.
28
+ */
29
+ import { DEFAULT_MODEL_OPTION } from './shared.js';
30
+ import { agentCapabilities } from '../capabilities.js';
31
+ const SKIP_TRUST_FLAG = '--skip-trust';
32
+ export const geminiAgentDef = {
33
+ id: 'gemini',
34
+ name: 'Gemini CLI',
35
+ bin: 'gemini',
36
+ versionArgs: ['--version'],
37
+ // A cold `gemini --version` took 4.7 s on the dev machine (warm ~2 s), past the 3 s default.
38
+ versionProbeTimeoutMs: 10_000,
39
+ helpArgs: ['--help'],
40
+ capabilityFlags: {
41
+ [SKIP_TRUST_FLAG]: 'skipTrust',
42
+ },
43
+ // No `models` subcommand. `auto` and the concrete ids below are the ones the installed
44
+ // 0.58.0 bundle and the upstream model docs name; any other id can still be typed in.
45
+ fallbackModels: [
46
+ DEFAULT_MODEL_OPTION,
47
+ { id: 'auto', label: 'auto' },
48
+ { id: 'gemini-3.1-pro-preview', label: 'gemini-3.1-pro-preview' },
49
+ { id: 'gemini-3.5-flash', label: 'gemini-3.5-flash' },
50
+ { id: 'gemini-3-pro-preview', label: 'gemini-3-pro-preview' },
51
+ { id: 'gemini-3-flash-preview', label: 'gemini-3-flash-preview' },
52
+ { id: 'gemini-2.5-pro', label: 'gemini-2.5-pro' },
53
+ { id: 'gemini-2.5-flash', label: 'gemini-2.5-flash' },
54
+ ],
55
+ buildArgs: (_prompt, _imagePaths, extraAllowedDirs = [], options = {}) => {
56
+ const args = ['--output-format', 'stream-json'];
57
+ if (agentCapabilities.get('gemini')?.skipTrust) {
58
+ args.push(SKIP_TRUST_FLAG);
59
+ }
60
+ // See `RuntimeBuildOptions.permissionMode`'s doc: bypass is the default (unchanged
61
+ // behavior) unless a caller explicitly opts into a restricted run.
62
+ if (options.permissionMode !== 'restricted') {
63
+ args.push('--approval-mode', 'yolo');
64
+ }
65
+ if (options.model && options.model !== 'default') {
66
+ args.push('--model', options.model);
67
+ }
68
+ const dirs = (extraAllowedDirs || []).filter((d) => typeof d === 'string' && d.length > 0);
69
+ for (const d of dirs)
70
+ args.push('--include-directories', d);
71
+ return args;
72
+ },
73
+ promptViaStdin: true,
74
+ streamFormat: 'json-event-stream',
75
+ eventParser: 'gemini',
76
+ // No `externalMcpInjection` yet: Gemini CLI reads `mcpServers` from `settings.json` (user,
77
+ // project `.gemini/settings.json`, or a system file named by
78
+ // `GEMINI_CLI_SYSTEM_SETTINGS_PATH`), with no per-run `--mcp-config` flag. A run-scoped
79
+ // system-settings file is the likely strategy, but it is not wired or verified live.
80
+ };
81
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1,13 @@
1
+ export declare const gooseAgentDef: {
2
+ id: string;
3
+ name: string;
4
+ bin: string;
5
+ versionArgs: string[];
6
+ fetchModels: (resolvedBin: string, env: import("../types.js").RuntimeEnv) => Promise<import("../types.js").RuntimeModelOption[]>;
7
+ fallbackModels: import("../types.js").RuntimeModelOption[];
8
+ buildArgs: () => string[];
9
+ streamFormat: string;
10
+ externalMcpInjection: "acp-merge";
11
+ imageDelivery: "native";
12
+ };
13
+ //# sourceMappingURL=goose.d.ts.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @module defs/goose
3
+ *
4
+ * Block's goose (`goose`). Runs over ACP: `goose acp` is the launch command the official ACP
5
+ * registry lists (<https://github.com/agentclientprotocol/registry>, `goose/agent.json`). The
6
+ * provider and model come from goose's own config, so `goose configure` has to have been run once.
7
+ *
8
+ * Name clash: `pressly/goose` (a Go database-migration tool) also installs a `goose` binary. On a
9
+ * machine that has only that one, detection will list goose as installed and the first run will
10
+ * fail on the unknown `acp` command.
11
+ */
12
+ import { detectAcpModels, DEFAULT_MODEL_OPTION } from './shared.js';
13
+ export const gooseAgentDef = {
14
+ id: 'goose',
15
+ name: 'goose',
16
+ bin: 'goose',
17
+ versionArgs: ['--version'],
18
+ fetchModels: async (resolvedBin, env) => detectAcpModels({
19
+ bin: resolvedBin,
20
+ args: ['acp'],
21
+ env,
22
+ timeoutMs: 15_000,
23
+ defaultModelOption: DEFAULT_MODEL_OPTION,
24
+ }),
25
+ fallbackModels: [DEFAULT_MODEL_OPTION],
26
+ buildArgs: () => ['acp'],
27
+ streamFormat: 'acp-json-rpc',
28
+ externalMcpInjection: 'acp-merge',
29
+ // ACP's `resource_link` prompt blocks carry images natively for every
30
+ // `acp-json-rpc` def — see `types.ts#RuntimeAgentDef.imageDelivery`'s doc.
31
+ imageDelivery: 'native',
32
+ };
33
+ //# sourceMappingURL=goose.js.map
@@ -10,13 +10,19 @@ export * from './aider.js';
10
10
  export * from './amp.js';
11
11
  export * from './amr.js';
12
12
  export * from './antigravity.js';
13
+ export * from './auggie.js';
13
14
  export * from './claude.js';
15
+ export * from './cline.js';
14
16
  export * from './codebuddy.js';
15
17
  export * from './codex.js';
16
18
  export * from './copilot.js';
19
+ export * from './crush.js';
17
20
  export * from './cursor-agent.js';
21
+ export * from './droid.js';
22
+ export * from './gemini.js';
18
23
  export * from './deepseek.js';
19
24
  export * from './devin.js';
25
+ export * from './goose.js';
20
26
  export * from './grok-build.js';
21
27
  export * from './hermes.js';
22
28
  export * from './kilo.js';
@@ -10,13 +10,19 @@ export * from './aider.js';
10
10
  export * from './amp.js';
11
11
  export * from './amr.js';
12
12
  export * from './antigravity.js';
13
+ export * from './auggie.js';
13
14
  export * from './claude.js';
15
+ export * from './cline.js';
14
16
  export * from './codebuddy.js';
15
17
  export * from './codex.js';
16
18
  export * from './copilot.js';
19
+ export * from './crush.js';
17
20
  export * from './cursor-agent.js';
21
+ export * from './droid.js';
22
+ export * from './gemini.js';
18
23
  export * from './deepseek.js';
19
24
  export * from './devin.js';
25
+ export * from './goose.js';
20
26
  export * from './grok-build.js';
21
27
  export * from './hermes.js';
22
28
  export * from './kilo.js';
@@ -28,13 +28,19 @@ import { expandHomePath } from './paths.js';
28
28
  const AGENT_BIN_ENV_KEYS = new Map([
29
29
  ['amr', 'VELA_BIN'],
30
30
  ['aider', 'AIDER_BIN'],
31
+ ['auggie', 'AUGGIE_BIN'],
31
32
  ['claude', 'CLAUDE_BIN'],
33
+ ['cline', 'CLINE_BIN'],
32
34
  ['codebuddy', 'CODEBUDDY_BIN'],
33
35
  ['codex', 'CODEX_BIN'],
34
36
  ['copilot', 'COPILOT_BIN'],
37
+ ['crush', 'CRUSH_BIN'],
35
38
  ['cursor-agent', 'CURSOR_AGENT_BIN'],
36
39
  ['deepseek', 'DEEPSEEK_BIN'],
37
40
  ['devin', 'DEVIN_BIN'],
41
+ ['droid', 'DROID_BIN'],
42
+ ['gemini', 'GEMINI_BIN'],
43
+ ['goose', 'GOOSE_BIN'],
38
44
  ['hermes', 'HERMES_BIN'],
39
45
  ['kimi', 'KIMI_BIN'],
40
46
  ['kiro', 'KIRO_BIN'],
package/dist/metadata.js CHANGED
@@ -35,6 +35,10 @@ export const DEFAULT_AGENT_INSTALL_LINKS = {
35
35
  installUrl: 'https://cursor.com/docs/cli/overview',
36
36
  docsUrl: 'https://docs.cursor.com/en/cli/overview',
37
37
  },
38
+ gemini: {
39
+ installUrl: 'https://github.com/google-gemini/gemini-cli',
40
+ docsUrl: 'https://geminicli.com/docs/',
41
+ },
38
42
  qwen: {
39
43
  installUrl: 'https://github.com/QwenLM/qwen-code',
40
44
  docsUrl: 'https://qwenlm.github.io/qwen-code-docs/en/index',
@@ -74,6 +78,26 @@ export const DEFAULT_AGENT_INSTALL_LINKS = {
74
78
  installUrl: 'https://www.codebuddy.cn',
75
79
  docsUrl: 'https://www.codebuddy.cn/docs/workbuddy/Overview',
76
80
  },
81
+ cline: {
82
+ installUrl: 'https://cline.bot/cli',
83
+ docsUrl: 'https://docs.cline.bot/cline-cli/overview',
84
+ },
85
+ goose: {
86
+ installUrl: 'https://github.com/block/goose',
87
+ docsUrl: 'https://block.github.io/goose/',
88
+ },
89
+ auggie: {
90
+ installUrl: 'https://github.com/augmentcode/auggie',
91
+ docsUrl: 'https://docs.augmentcode.com/cli/overview',
92
+ },
93
+ crush: {
94
+ installUrl: 'https://github.com/charmbracelet/crush',
95
+ docsUrl: 'https://github.com/charmbracelet/crush',
96
+ },
97
+ droid: {
98
+ installUrl: 'https://factory.ai/product/cli',
99
+ docsUrl: 'https://docs.factory.ai/droid-exec/overview',
100
+ },
77
101
  };
78
102
  function sanitizeHttpsUrl(value) {
79
103
  if (!value)
@@ -287,7 +287,7 @@ export async function testProviderConnection(input) {
287
287
  kind: 'auth_failed',
288
288
  latencyMs: Date.now() - start,
289
289
  model,
290
- detail: 'No API key — connection test needs the key from this browser.',
290
+ detail: 'No API key saved. Save one to test the connection.',
291
291
  };
292
292
  }
293
293
  const validated = await validateBaseUrlResolved(input.baseUrl, input.dnsLookup ?? defaultDnsLookup);
@@ -32,7 +32,7 @@ function missingApiKeyResponse(startedAt) {
32
32
  ok: false,
33
33
  kind: 'auth_failed',
34
34
  latencyMs: Date.now() - startedAt,
35
- detail: 'No API key — model discovery needs the key from this browser.',
35
+ detail: 'No API key saved. Save one to load models.',
36
36
  };
37
37
  }
38
38
  const BEDROCK_MODEL_OPTIONS = [
@@ -7,8 +7,8 @@ export declare function getAgentDef(id: string): RuntimeAgentDef | null;
7
7
  * tools) into a session run by this
8
8
  * def, per its own `externalMcpInjection` declaration (`types.ts`'s own doc names the six wired
9
9
  * strategies and the defs that leave the field `undefined` because the CLI has no mechanism to
10
- * receive one — `aider`, `amp`, `copilot`, `cursor-agent`, `deepseek`, `grok-build`, `pi`,
11
- * `qoder`, and `qwen` today, each documenting why in its own def file).
10
+ * receive one — `aider`, `amp`, `copilot`, `crush`, `cursor-agent`, `deepseek`, `droid`,
11
+ * `gemini`, `grok-build`, `pi`, `qoder`, and `qwen` today, each documenting why in its own def file).
12
12
  *
13
13
  * This is the single seam a tool-availability UI (e.g. the chat runtime picker's "No tools" badge)
14
14
  * should read instead of hardcoding a runtime-id list: that list goes stale the moment a def gains
package/dist/registry.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @module registry
3
3
  *
4
- * The static `BASE_AGENT_DEFS` catalog (the 24 built-in CLI adapters), a
4
+ * The static `BASE_AGENT_DEFS` catalog (the built-in CLI adapters), a
5
5
  * dup-id guard, and `getAgentDef(id)` lookup.
6
6
  *
7
7
  * Ported from OD's `apps/daemon/src/runtimes/registry.ts`. Per the
@@ -17,7 +17,7 @@
17
17
  * can reintroduce a de-branded, sandbox-free local-profile loader as an
18
18
  * injected port if a consumer needs it. See `source-map.md`.
19
19
  */
20
- import { aiderAgentDef, ampAgentDef, amrAgentDef, antigravityAgentDef, claudeAgentDef, codebuddyAgentDef, codexAgentDef, copilotAgentDef, cursorAgentDef, deepseekAgentDef, devinAgentDef, grokBuildAgentDef, hermesAgentDef, kiloAgentDef, kimiAgentDef, kiroAgentDef, mimoAgentDef, opencodeAgentDef, piAgentDef, qoderAgentDef, qwenAgentDef, reasonixAgentDef, traeCliAgentDef, vibeAgentDef, } from './defs/index.js';
20
+ import { aiderAgentDef, ampAgentDef, amrAgentDef, antigravityAgentDef, auggieAgentDef, claudeAgentDef, clineAgentDef, codebuddyAgentDef, codexAgentDef, copilotAgentDef, crushAgentDef, cursorAgentDef, deepseekAgentDef, devinAgentDef, droidAgentDef, geminiAgentDef, gooseAgentDef, grokBuildAgentDef, hermesAgentDef, kiloAgentDef, kimiAgentDef, kiroAgentDef, mimoAgentDef, opencodeAgentDef, piAgentDef, qoderAgentDef, qwenAgentDef, reasonixAgentDef, traeCliAgentDef, vibeAgentDef, } from './defs/index.js';
21
21
  export const BASE_AGENT_DEFS = [
22
22
  amrAgentDef,
23
23
  claudeAgentDef,
@@ -30,6 +30,7 @@ export const BASE_AGENT_DEFS = [
30
30
  kimiAgentDef,
31
31
  cursorAgentDef,
32
32
  qwenAgentDef,
33
+ geminiAgentDef,
33
34
  qoderAgentDef,
34
35
  copilotAgentDef,
35
36
  ampAgentDef,
@@ -43,6 +44,11 @@ export const BASE_AGENT_DEFS = [
43
44
  reasonixAgentDef,
44
45
  codebuddyAgentDef,
45
46
  mimoAgentDef,
47
+ clineAgentDef,
48
+ gooseAgentDef,
49
+ auggieAgentDef,
50
+ crushAgentDef,
51
+ droidAgentDef,
46
52
  ];
47
53
  export const AGENT_DEFS = [...BASE_AGENT_DEFS];
48
54
  const ids = new Set();
@@ -60,8 +66,8 @@ export function getAgentDef(id) {
60
66
  * tools) into a session run by this
61
67
  * def, per its own `externalMcpInjection` declaration (`types.ts`'s own doc names the six wired
62
68
  * strategies and the defs that leave the field `undefined` because the CLI has no mechanism to
63
- * receive one — `aider`, `amp`, `copilot`, `cursor-agent`, `deepseek`, `grok-build`, `pi`,
64
- * `qoder`, and `qwen` today, each documenting why in its own def file).
69
+ * receive one — `aider`, `amp`, `copilot`, `crush`, `cursor-agent`, `deepseek`, `droid`,
70
+ * `gemini`, `grok-build`, `pi`, `qoder`, and `qwen` today, each documenting why in its own def file).
65
71
  *
66
72
  * This is the single seam a tool-availability UI (e.g. the chat runtime picker's "No tools" badge)
67
73
  * should read instead of hardcoding a runtime-id list: that list goes stale the moment a def gains
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jini-ai/agent-runtime",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "description": "Coding-agent runtime adapters: runtime registry, detection, launch, stream parsers, and the ACP/pi-rpc subprocess transport.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {