@smithers-orchestrator/cli 0.20.4 → 0.21.0
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/agent-detection.d.ts +16 -3
- package/dist/argv-utils.d.ts +21 -0
- package/dist/eval-suite.d.ts +201 -0
- package/dist/hijack.d.ts +1 -1
- package/dist/json-args.d.ts +24 -0
- package/dist/token-store.d.ts +8 -0
- package/dist/workflows.d.ts +30 -1
- package/package.json +16 -16
- package/src/AgentAvailability.ts +3 -1
- package/src/AskOptions.ts +1 -1
- package/src/DiscoveredWorkflow.ts +4 -0
- package/src/NativeHijackEngine.ts +1 -0
- package/src/agent-commands/agentAddWizard.js +16 -3
- package/src/agent-commands/regenerateAgentsTsIfPresent.js +15 -2
- package/src/agent-commands/runAgentAdd.js +14 -2
- package/src/agent-detection.js +123 -22
- package/src/argv-utils.js +73 -0
- package/src/ask.js +13 -2
- package/src/eval-suite.js +560 -0
- package/src/hijack.js +9 -0
- package/src/index.js +335 -173
- package/src/json-args.js +59 -0
- package/src/mcp/semantic-tools.js +9 -1
- package/src/token-store.js +39 -0
- package/src/workflow-pack.js +238 -10
- package/src/workflows.js +193 -5
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
type AgentAvailabilityStatus$1 = "likely-subscription" | "api-key" | "binary-only" | "unavailable";
|
|
2
2
|
|
|
3
3
|
type AgentAvailability$1 = {
|
|
4
|
-
id: "claude" | "codex" | "gemini" | "pi" | "kimi" | "amp";
|
|
4
|
+
id: "claude" | "codex" | "antigravity" | "gemini" | "pi" | "kimi" | "amp";
|
|
5
5
|
displayName: string;
|
|
6
6
|
binary: string;
|
|
7
|
+
deprecated?: boolean;
|
|
8
|
+
deprecationReason?: string;
|
|
7
9
|
hasBinary: boolean;
|
|
8
10
|
hasAuthSignal: boolean;
|
|
9
11
|
hasApiKeySignal: boolean;
|
|
@@ -15,6 +17,15 @@ type AgentAvailability$1 = {
|
|
|
15
17
|
unusableReasons: string[];
|
|
16
18
|
};
|
|
17
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Extracts detection-derived provider ids from a generated `.smithers/agents.ts`.
|
|
22
|
+
* Account labels are deliberately ignored; the accounts registry remains the
|
|
23
|
+
* source of truth for account-backed providers.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} source
|
|
26
|
+
* @returns {Set<string>}
|
|
27
|
+
*/
|
|
28
|
+
declare function extractGeneratedDetectionProviderIds(source: string): Set<string>;
|
|
18
29
|
/**
|
|
19
30
|
* @param {AgentAvailability} agent
|
|
20
31
|
*/
|
|
@@ -33,12 +44,14 @@ declare function detectAvailableAgents(env?: NodeJS.ProcessEnv, options?: {
|
|
|
33
44
|
}): AgentAvailability[];
|
|
34
45
|
/**
|
|
35
46
|
* @param {NodeJS.ProcessEnv} [env]
|
|
36
|
-
* @param {{ cwd?: string }} [options]
|
|
47
|
+
* @param {{ cwd?: string; preserveProviderIds?: Iterable<string>; scaffoldProviderIds?: Iterable<string> }} [options]
|
|
37
48
|
*/
|
|
38
49
|
declare function generateAgentsTs(env?: NodeJS.ProcessEnv, options?: {
|
|
39
50
|
cwd?: string;
|
|
51
|
+
preserveProviderIds?: Iterable<string>;
|
|
52
|
+
scaffoldProviderIds?: Iterable<string>;
|
|
40
53
|
}): string;
|
|
41
54
|
type AgentAvailability = AgentAvailability$1;
|
|
42
55
|
type AgentAvailabilityStatus = AgentAvailabilityStatus$1;
|
|
43
56
|
|
|
44
|
-
export { type AgentAvailability, type AgentAvailabilityStatus, describeUnavailableAgent, detectAvailableAgents, formatNoUsableAgentsMessage, generateAgentsTs };
|
|
57
|
+
export { type AgentAvailability, type AgentAvailabilityStatus, describeUnavailableAgent, detectAvailableAgents, extractGeneratedDetectionProviderIds, formatNoUsableAgentsMessage, generateAgentsTs };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string[]} argv
|
|
3
|
+
*/
|
|
4
|
+
declare function parseMcpSurfaceArgv(argv: string[]): {
|
|
5
|
+
surface: string;
|
|
6
|
+
argv: string[];
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* @param {string[]} argv
|
|
10
|
+
* @returns {number}
|
|
11
|
+
*/
|
|
12
|
+
declare function findFirstPositionalIndex(argv: string[], startIndex?: number): number;
|
|
13
|
+
/**
|
|
14
|
+
* Incur treats union-typed options as value-bearing flags, so a bare
|
|
15
|
+
* `--resume --run-id value` would consume `--run-id` as the resume value.
|
|
16
|
+
*
|
|
17
|
+
* @param {string[]} argv
|
|
18
|
+
*/
|
|
19
|
+
declare function rewriteBareResumeFlagArgv(argv: string[]): string[];
|
|
20
|
+
|
|
21
|
+
export { findFirstPositionalIndex, parseMcpSurfaceArgv, rewriteBareResumeFlagArgv };
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string} value
|
|
3
|
+
* @param {string} fallback
|
|
4
|
+
* @param {number} maxLength
|
|
5
|
+
*/
|
|
6
|
+
declare function slugifyEvalToken(value: string, fallback?: string, maxLength?: number): string;
|
|
7
|
+
/**
|
|
8
|
+
* @param {unknown} raw
|
|
9
|
+
* @param {number} index
|
|
10
|
+
*/
|
|
11
|
+
declare function normalizeEvalCase(raw: unknown, index: number): {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
input: Record<string, unknown>;
|
|
15
|
+
annotations: Record<string, string | number | boolean>;
|
|
16
|
+
expected: {
|
|
17
|
+
status: string;
|
|
18
|
+
};
|
|
19
|
+
metadata: Record<string, unknown>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* @param {string} root
|
|
23
|
+
* @param {string} path
|
|
24
|
+
* @param {{ maxCases?: number }} [options]
|
|
25
|
+
*/
|
|
26
|
+
declare function loadEvalCases(root: string, path: string, options?: {
|
|
27
|
+
maxCases?: number;
|
|
28
|
+
}): {
|
|
29
|
+
path: string;
|
|
30
|
+
cases: {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
input: Record<string, unknown>;
|
|
34
|
+
annotations: Record<string, string | number | boolean>;
|
|
35
|
+
expected: {
|
|
36
|
+
status: string;
|
|
37
|
+
};
|
|
38
|
+
metadata: Record<string, unknown>;
|
|
39
|
+
}[];
|
|
40
|
+
totalCases: number;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* @param {string} suiteId
|
|
44
|
+
* @param {string} caseId
|
|
45
|
+
*/
|
|
46
|
+
declare function evalRunId(suiteId: string, caseId: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* @param {{
|
|
49
|
+
* suiteId?: string;
|
|
50
|
+
* runLabel?: string;
|
|
51
|
+
* workflowPath: string;
|
|
52
|
+
* casesPath: string;
|
|
53
|
+
* loadedCases: ReturnType<typeof loadEvalCases>;
|
|
54
|
+
* }} input
|
|
55
|
+
*/
|
|
56
|
+
declare function buildEvalPlan(input: {
|
|
57
|
+
suiteId?: string;
|
|
58
|
+
runLabel?: string;
|
|
59
|
+
workflowPath: string;
|
|
60
|
+
casesPath: string;
|
|
61
|
+
loadedCases: ReturnType<typeof loadEvalCases>;
|
|
62
|
+
}): {
|
|
63
|
+
suiteId: string;
|
|
64
|
+
runLabel: string | null;
|
|
65
|
+
workflowPath: string;
|
|
66
|
+
casesPath: string;
|
|
67
|
+
totalCases: number;
|
|
68
|
+
plannedCases: number;
|
|
69
|
+
cases: {
|
|
70
|
+
runId: string;
|
|
71
|
+
id: string;
|
|
72
|
+
name: string;
|
|
73
|
+
input: Record<string, unknown>;
|
|
74
|
+
annotations: Record<string, string | number | boolean>;
|
|
75
|
+
expected: {
|
|
76
|
+
status: string;
|
|
77
|
+
};
|
|
78
|
+
metadata: Record<string, unknown>;
|
|
79
|
+
}[];
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* @param {{ getRun(runId: string): Promise<unknown> }} adapter
|
|
83
|
+
* @param {Array<{ runId: string }>} cases
|
|
84
|
+
*/
|
|
85
|
+
declare function assertEvalRunIdsAvailable(adapter: {
|
|
86
|
+
getRun(runId: string): Promise<unknown>;
|
|
87
|
+
}, cases: Array<{
|
|
88
|
+
runId: string;
|
|
89
|
+
}>): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* @param {Array<{ passed: boolean; status?: string; durationMs?: number }>} results
|
|
92
|
+
*/
|
|
93
|
+
declare function summarizeEvalResults(results: Array<{
|
|
94
|
+
passed: boolean;
|
|
95
|
+
status?: string;
|
|
96
|
+
durationMs?: number;
|
|
97
|
+
}>): {
|
|
98
|
+
total: number;
|
|
99
|
+
passed: number;
|
|
100
|
+
failed: number;
|
|
101
|
+
byStatus: {};
|
|
102
|
+
durationMs: number;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* @param {ReturnType<typeof normalizeEvalCase>} testCase
|
|
106
|
+
* @param {{ status?: string; output?: unknown; error?: unknown }} result
|
|
107
|
+
*/
|
|
108
|
+
declare function evaluateEvalCaseResult(testCase: ReturnType<typeof normalizeEvalCase>, result: {
|
|
109
|
+
status?: string;
|
|
110
|
+
output?: unknown;
|
|
111
|
+
error?: unknown;
|
|
112
|
+
}): {
|
|
113
|
+
passed: boolean;
|
|
114
|
+
assertions: {
|
|
115
|
+
name: string;
|
|
116
|
+
passed: boolean;
|
|
117
|
+
expected: any;
|
|
118
|
+
actual: unknown;
|
|
119
|
+
}[];
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* @param {{
|
|
123
|
+
* plan: ReturnType<typeof buildEvalPlan>;
|
|
124
|
+
* results: Array<Record<string, unknown> & { passed: boolean; status?: string; durationMs?: number }>;
|
|
125
|
+
* startedAtMs: number;
|
|
126
|
+
* finishedAtMs: number;
|
|
127
|
+
* reportPath?: string | null;
|
|
128
|
+
* }} input
|
|
129
|
+
*/
|
|
130
|
+
declare function buildEvalReport(input: {
|
|
131
|
+
plan: ReturnType<typeof buildEvalPlan>;
|
|
132
|
+
results: Array<Record<string, unknown> & {
|
|
133
|
+
passed: boolean;
|
|
134
|
+
status?: string;
|
|
135
|
+
durationMs?: number;
|
|
136
|
+
}>;
|
|
137
|
+
startedAtMs: number;
|
|
138
|
+
finishedAtMs: number;
|
|
139
|
+
reportPath?: string | null;
|
|
140
|
+
}): {
|
|
141
|
+
suiteId: string;
|
|
142
|
+
runLabel: string | null;
|
|
143
|
+
workflowPath: string;
|
|
144
|
+
casesPath: string;
|
|
145
|
+
startedAtMs: number;
|
|
146
|
+
finishedAtMs: number;
|
|
147
|
+
durationMs: number;
|
|
148
|
+
reportPath: string | null;
|
|
149
|
+
summary: {
|
|
150
|
+
total: number;
|
|
151
|
+
passed: number;
|
|
152
|
+
failed: number;
|
|
153
|
+
byStatus: {};
|
|
154
|
+
durationMs: number;
|
|
155
|
+
};
|
|
156
|
+
results: (Record<string, unknown> & {
|
|
157
|
+
passed: boolean;
|
|
158
|
+
status?: string;
|
|
159
|
+
durationMs?: number;
|
|
160
|
+
})[];
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* @param {string} root
|
|
164
|
+
* @param {string} suiteId
|
|
165
|
+
*/
|
|
166
|
+
declare function defaultEvalReportPath(root: string, suiteId: string): string;
|
|
167
|
+
/**
|
|
168
|
+
* @param {string} root
|
|
169
|
+
* @param {string} suiteId
|
|
170
|
+
* @param {string | undefined} path
|
|
171
|
+
*/
|
|
172
|
+
declare function resolveEvalReportPath(root: string, suiteId: string, path: string | undefined): string;
|
|
173
|
+
/**
|
|
174
|
+
* @param {string} root
|
|
175
|
+
* @param {string} suiteId
|
|
176
|
+
* @param {{ path?: string; force?: boolean }} [options]
|
|
177
|
+
*/
|
|
178
|
+
declare function assertEvalReportWritable(root: string, suiteId: string, options?: {
|
|
179
|
+
path?: string;
|
|
180
|
+
force?: boolean;
|
|
181
|
+
}): string;
|
|
182
|
+
/**
|
|
183
|
+
* @param {string} root
|
|
184
|
+
* @param {Record<string, unknown>} report
|
|
185
|
+
* @param {{ path?: string; force?: boolean }} [options]
|
|
186
|
+
*/
|
|
187
|
+
declare function writeEvalReport(root: string, report: Record<string, unknown>, options?: {
|
|
188
|
+
path?: string;
|
|
189
|
+
force?: boolean;
|
|
190
|
+
}): string;
|
|
191
|
+
/**
|
|
192
|
+
* @param {ReturnType<typeof buildEvalPlan>} plan
|
|
193
|
+
*/
|
|
194
|
+
declare function renderEvalPlan(plan: ReturnType<typeof buildEvalPlan>): string;
|
|
195
|
+
/**
|
|
196
|
+
* @param {ReturnType<typeof buildEvalReport>} report
|
|
197
|
+
*/
|
|
198
|
+
declare function renderEvalReport(report: ReturnType<typeof buildEvalReport>): string;
|
|
199
|
+
declare const EVAL_CASE_STATUSES: string[];
|
|
200
|
+
|
|
201
|
+
export { EVAL_CASE_STATUSES, assertEvalReportWritable, assertEvalRunIdsAvailable, buildEvalPlan, buildEvalReport, defaultEvalReportPath, evalRunId, evaluateEvalCaseResult, loadEvalCases, normalizeEvalCase, renderEvalPlan, renderEvalReport, resolveEvalReportPath, slugifyEvalToken, summarizeEvalResults, writeEvalReport };
|
package/dist/hijack.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _smithers_orchestrator_db_adapter from '@smithers-orchestrator/db/adapter';
|
|
2
2
|
import { H as HijackCandidate$1 } from './HijackCandidate-FxLeKpcZ.js';
|
|
3
3
|
|
|
4
|
-
type NativeHijackEngine$1 = "claude-code" | "codex" | "gemini" | "pi" | "kimi" | "forge" | "amp";
|
|
4
|
+
type NativeHijackEngine$1 = "claude-code" | "antigravity" | "codex" | "gemini" | "pi" | "kimi" | "forge" | "amp";
|
|
5
5
|
|
|
6
6
|
type HijackLaunchSpec$1 = {
|
|
7
7
|
command: string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string | undefined} raw
|
|
3
|
+
* @param {string} label
|
|
4
|
+
* @returns {string | undefined}
|
|
5
|
+
*/
|
|
6
|
+
declare function readJsonArgumentPayload(raw: string | undefined, label: string): string | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* @param {string | undefined} raw
|
|
9
|
+
* @param {string} label
|
|
10
|
+
*/
|
|
11
|
+
declare function parseJsonArgument(raw: string | undefined, label: string): any;
|
|
12
|
+
/**
|
|
13
|
+
* @param {string | undefined} raw
|
|
14
|
+
* @param {string} label
|
|
15
|
+
* @param {(opts: { code: string; message: string; exitCode: number }) => unknown} fail
|
|
16
|
+
*/
|
|
17
|
+
declare function parseJsonInput(raw: string | undefined, label: string, fail: (opts: {
|
|
18
|
+
code: string;
|
|
19
|
+
message: string;
|
|
20
|
+
exitCode: number;
|
|
21
|
+
}) => unknown): any;
|
|
22
|
+
declare const CLI_JSON_ARGUMENT_MAX_BYTES: number;
|
|
23
|
+
|
|
24
|
+
export { CLI_JSON_ARGUMENT_MAX_BYTES, parseJsonArgument, parseJsonInput, readJsonArgumentPayload };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare function smithersTokenStorePath(): string;
|
|
2
|
+
declare function readSmithersTokenStore(): {
|
|
3
|
+
tokens: any;
|
|
4
|
+
};
|
|
5
|
+
declare function writeSmithersTokenStore(store: any): void;
|
|
6
|
+
declare function parseTokenScopes(raw: any): any;
|
|
7
|
+
|
|
8
|
+
export { parseTokenScopes, readSmithersTokenStore, smithersTokenStorePath, writeSmithersTokenStore };
|
package/dist/workflows.d.ts
CHANGED
|
@@ -2,8 +2,12 @@ type WorkflowSourceType$1 = "user" | "seeded" | "generated" | (string & {});
|
|
|
2
2
|
|
|
3
3
|
type DiscoveredWorkflow$1 = {
|
|
4
4
|
id: string;
|
|
5
|
+
metadataVersion: 1;
|
|
5
6
|
displayName: string;
|
|
6
7
|
sourceType: WorkflowSourceType$1;
|
|
8
|
+
description: string;
|
|
9
|
+
tags: string[];
|
|
10
|
+
aliases: string[];
|
|
7
11
|
entryFile: string;
|
|
8
12
|
path: string;
|
|
9
13
|
};
|
|
@@ -29,7 +33,32 @@ declare function resolveWorkflow(id: string, root: string): DiscoveredWorkflow;
|
|
|
29
33
|
* @returns {DiscoveredWorkflow}
|
|
30
34
|
*/
|
|
31
35
|
declare function createWorkflowFile(name: string, root: string): DiscoveredWorkflow;
|
|
36
|
+
/**
|
|
37
|
+
* @param {DiscoveredWorkflow} workflow
|
|
38
|
+
* @param {{ root?: string }} [options]
|
|
39
|
+
* @returns {string}
|
|
40
|
+
*/
|
|
41
|
+
declare function renderWorkflowSkill(workflow: DiscoveredWorkflow, options?: {
|
|
42
|
+
root?: string;
|
|
43
|
+
}): string;
|
|
44
|
+
/**
|
|
45
|
+
* @param {string} root
|
|
46
|
+
* @param {{ workflowId?: string; output?: string; force?: boolean }} [options]
|
|
47
|
+
*/
|
|
48
|
+
declare function writeWorkflowSkillFiles(root: string, options?: {
|
|
49
|
+
workflowId?: string;
|
|
50
|
+
output?: string;
|
|
51
|
+
force?: boolean;
|
|
52
|
+
}): {
|
|
53
|
+
rootDir: string;
|
|
54
|
+
workflowId: string;
|
|
55
|
+
outputPath: string;
|
|
56
|
+
force: boolean;
|
|
57
|
+
workflows: DiscoveredWorkflow$1[];
|
|
58
|
+
writtenFiles: string[];
|
|
59
|
+
skippedFiles: string[];
|
|
60
|
+
};
|
|
32
61
|
type WorkflowSourceType = WorkflowSourceType$1;
|
|
33
62
|
type DiscoveredWorkflow = DiscoveredWorkflow$1;
|
|
34
63
|
|
|
35
|
-
export { type DiscoveredWorkflow, type WorkflowSourceType, createWorkflowFile, discoverWorkflows, resolveWorkflow, validateWorkflowName };
|
|
64
|
+
export { type DiscoveredWorkflow, type WorkflowSourceType, createWorkflowFile, discoverWorkflows, renderWorkflowSkill, resolveWorkflow, validateWorkflowName, writeWorkflowSkillFiles };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smithers-orchestrator/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Smithers command-line interface, MCP server, and local workflow tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -32,21 +32,21 @@
|
|
|
32
32
|
"picocolors": "^1.1.1",
|
|
33
33
|
"react": "^19.2.5",
|
|
34
34
|
"zod": "^4.3.6",
|
|
35
|
-
"@smithers-orchestrator/accounts": "0.
|
|
36
|
-
"@smithers-orchestrator/agents": "0.
|
|
37
|
-
"@smithers-orchestrator/
|
|
38
|
-
"@smithers-orchestrator/
|
|
39
|
-
"@smithers-orchestrator/devtools": "0.
|
|
40
|
-
"@smithers-orchestrator/
|
|
41
|
-
"@smithers-orchestrator/errors": "0.
|
|
42
|
-
"@smithers-orchestrator/
|
|
43
|
-
"@smithers-orchestrator/
|
|
44
|
-
"@smithers-orchestrator/
|
|
45
|
-
"@smithers-orchestrator/
|
|
46
|
-
"@smithers-orchestrator/server": "0.
|
|
47
|
-
"@smithers-orchestrator/time-travel": "0.
|
|
48
|
-
"@smithers-orchestrator/
|
|
49
|
-
"@smithers-orchestrator/
|
|
35
|
+
"@smithers-orchestrator/accounts": "0.21.0",
|
|
36
|
+
"@smithers-orchestrator/agents": "0.21.0",
|
|
37
|
+
"@smithers-orchestrator/db": "0.21.0",
|
|
38
|
+
"@smithers-orchestrator/driver": "0.21.0",
|
|
39
|
+
"@smithers-orchestrator/devtools": "0.21.0",
|
|
40
|
+
"@smithers-orchestrator/engine": "0.21.0",
|
|
41
|
+
"@smithers-orchestrator/errors": "0.21.0",
|
|
42
|
+
"@smithers-orchestrator/memory": "0.21.0",
|
|
43
|
+
"@smithers-orchestrator/observability": "0.21.0",
|
|
44
|
+
"@smithers-orchestrator/protocol": "0.21.0",
|
|
45
|
+
"@smithers-orchestrator/openapi": "0.21.0",
|
|
46
|
+
"@smithers-orchestrator/server": "0.21.0",
|
|
47
|
+
"@smithers-orchestrator/time-travel": "0.21.0",
|
|
48
|
+
"@smithers-orchestrator/scheduler": "0.21.0",
|
|
49
|
+
"@smithers-orchestrator/components": "0.21.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/bun": "latest",
|
package/src/AgentAvailability.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { AgentAvailabilityStatus } from "./AgentAvailabilityStatus.ts";
|
|
2
2
|
|
|
3
3
|
export type AgentAvailability = {
|
|
4
|
-
id: "claude" | "codex" | "gemini" | "pi" | "kimi" | "amp";
|
|
4
|
+
id: "claude" | "codex" | "antigravity" | "gemini" | "pi" | "kimi" | "amp";
|
|
5
5
|
displayName: string;
|
|
6
6
|
binary: string;
|
|
7
|
+
deprecated?: boolean;
|
|
8
|
+
deprecationReason?: string;
|
|
7
9
|
hasBinary: boolean;
|
|
8
10
|
hasAuthSignal: boolean;
|
|
9
11
|
hasApiKeySignal: boolean;
|
package/src/AskOptions.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SmithersToolSurface } from "@smithers-orchestrator/agents/agent-contract";
|
|
2
2
|
|
|
3
|
-
export type AskAgentId = "claude" | "codex" | "kimi" | "gemini" | "pi";
|
|
3
|
+
export type AskAgentId = "claude" | "codex" | "kimi" | "antigravity" | "gemini" | "pi";
|
|
4
4
|
|
|
5
5
|
export type AskOptions = {
|
|
6
6
|
agent?: AskAgentId;
|
|
@@ -2,8 +2,12 @@ import type { WorkflowSourceType } from "./WorkflowSourceType.ts";
|
|
|
2
2
|
|
|
3
3
|
export type DiscoveredWorkflow = {
|
|
4
4
|
id: string;
|
|
5
|
+
metadataVersion: 1;
|
|
5
6
|
displayName: string;
|
|
6
7
|
sourceType: WorkflowSourceType;
|
|
8
|
+
description: string;
|
|
9
|
+
tags: string[];
|
|
10
|
+
aliases: string[];
|
|
7
11
|
entryFile: string;
|
|
8
12
|
path: string;
|
|
9
13
|
};
|
|
@@ -6,8 +6,9 @@ import { runAgentAdd, pingAccount } from "./runAgentAdd.js";
|
|
|
6
6
|
|
|
7
7
|
const PROVIDER_CHOICES = [
|
|
8
8
|
{ value: "claude-code", label: "Claude Code (subscription)", hint: "Pro / Max plan via `claude` CLI" },
|
|
9
|
+
{ value: "antigravity", label: "Antigravity (subscription)", hint: "Google account via `agy` CLI" },
|
|
9
10
|
{ value: "codex", label: "Codex (subscription)", hint: "ChatGPT Plus/Pro via `codex` CLI" },
|
|
10
|
-
{ value: "gemini", label: "Gemini (subscription)", hint: "Google account via `gemini` CLI" },
|
|
11
|
+
{ value: "gemini", label: "Gemini (deprecated subscription)", hint: "Legacy/enterprise Google account via `gemini` CLI" },
|
|
11
12
|
{ value: "kimi", label: "Kimi (subscription)", hint: "OAuth via `kimi` CLI" },
|
|
12
13
|
{ value: "anthropic-api", label: "Anthropic API key", hint: "Pay-per-token via api.anthropic.com" },
|
|
13
14
|
{ value: "openai-api", label: "OpenAI API key", hint: "Pay-per-token via api.openai.com (used by Codex)" },
|
|
@@ -16,6 +17,7 @@ const PROVIDER_CHOICES = [
|
|
|
16
17
|
|
|
17
18
|
const SUBSCRIPTION_LOGIN_BIN = {
|
|
18
19
|
"claude-code": "claude",
|
|
20
|
+
"antigravity": "agy",
|
|
19
21
|
"codex": "codex",
|
|
20
22
|
"gemini": "gemini",
|
|
21
23
|
"kimi": "kimi",
|
|
@@ -23,6 +25,7 @@ const SUBSCRIPTION_LOGIN_BIN = {
|
|
|
23
25
|
|
|
24
26
|
const SUBSCRIPTION_DIR_ENV_VAR = {
|
|
25
27
|
"claude-code": "CLAUDE_CONFIG_DIR",
|
|
28
|
+
"antigravity": "GEMINI_DIR",
|
|
26
29
|
"codex": "CODEX_HOME",
|
|
27
30
|
"gemini": "GEMINI_DIR",
|
|
28
31
|
"kimi": "KIMI_SHARE_DIR",
|
|
@@ -33,15 +36,24 @@ const SUBSCRIPTION_DIR_ENV_VAR = {
|
|
|
33
36
|
* dedicated subcommand (`codex login`, `kimi login`); others authenticate via
|
|
34
37
|
* a slash command inside the REPL (`claude` then /login).
|
|
35
38
|
*
|
|
36
|
-
* @type {Record<string, { args: string[]; postInstructions?: string }>}
|
|
39
|
+
* @type {Record<string, { args: string[] | ((configDir: string) => string[]); postInstructions?: string }>}
|
|
37
40
|
*/
|
|
38
41
|
const SUBSCRIPTION_LOGIN_RECIPE = {
|
|
39
42
|
"claude-code": { args: [], postInstructions: "Inside Claude Code, type /login and follow the browser flow." },
|
|
43
|
+
"antigravity": { args: (configDir) => ["--gemini_dir", configDir], postInstructions: "Antigravity will open Google Sign-In or print a browser authorization URL." },
|
|
40
44
|
"codex": { args: ["login"] },
|
|
41
45
|
"gemini": { args: [], postInstructions: "Inside Gemini, type /auth (or follow the prompt) to sign in." },
|
|
42
46
|
"kimi": { args: ["login"] },
|
|
43
47
|
};
|
|
44
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @param {string[] | ((configDir: string) => string[])} args
|
|
51
|
+
* @param {string} configDir
|
|
52
|
+
*/
|
|
53
|
+
function resolveLoginArgs(args, configDir) {
|
|
54
|
+
return typeof args === "function" ? args(configDir) : args;
|
|
55
|
+
}
|
|
56
|
+
|
|
45
57
|
function bail() {
|
|
46
58
|
outro("Cancelled.");
|
|
47
59
|
process.exit(130);
|
|
@@ -102,7 +114,8 @@ export async function agentAddWizard(opts = {}) {
|
|
|
102
114
|
const bin = SUBSCRIPTION_LOGIN_BIN[provider];
|
|
103
115
|
const envVar = SUBSCRIPTION_DIR_ENV_VAR[provider];
|
|
104
116
|
const recipe = SUBSCRIPTION_LOGIN_RECIPE[provider] ?? { args: [] };
|
|
105
|
-
const
|
|
117
|
+
const loginArgs = resolveLoginArgs(recipe.args, configDir);
|
|
118
|
+
const loginCmd = `${envVar}=${configDir} ${bin}${loginArgs.length ? " " + loginArgs.join(" ") : ""}`;
|
|
106
119
|
const lines = [
|
|
107
120
|
"Open another terminal and run:",
|
|
108
121
|
"",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { generateAgentsTs } from "../agent-detection.js";
|
|
3
|
+
import { extractGeneratedDetectionProviderIds, generateAgentsTs } from "../agent-detection.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* If the current working directory contains a `.smithers/agents.ts` that was
|
|
@@ -19,7 +19,20 @@ export function regenerateAgentsTsIfPresent(cwd = process.cwd()) {
|
|
|
19
19
|
if (!existing.startsWith("// smithers-source: generated")) {
|
|
20
20
|
return { rewritten: false, path, reason: "agents.ts has been edited by hand; not overwriting" };
|
|
21
21
|
}
|
|
22
|
-
const
|
|
22
|
+
const scaffoldFiles = {
|
|
23
|
+
claude: "claude-code.ts",
|
|
24
|
+
codex: "codex.ts",
|
|
25
|
+
antigravity: "antigravity.ts",
|
|
26
|
+
gemini: "gemini.ts",
|
|
27
|
+
};
|
|
28
|
+
const scaffoldProviderIds = Object.entries(scaffoldFiles)
|
|
29
|
+
.filter(([, file]) => existsSync(join(cwd, ".smithers", "agents", file)))
|
|
30
|
+
.map(([providerId]) => providerId);
|
|
31
|
+
const next = generateAgentsTs(process.env, {
|
|
32
|
+
cwd,
|
|
33
|
+
preserveProviderIds: extractGeneratedDetectionProviderIds(existing),
|
|
34
|
+
scaffoldProviderIds,
|
|
35
|
+
});
|
|
23
36
|
if (next === existing) {
|
|
24
37
|
return { rewritten: false, path, reason: "no changes" };
|
|
25
38
|
}
|
|
@@ -12,6 +12,7 @@ import { regenerateAgentsTsIfPresent } from "./regenerateAgentsTsIfPresent.js";
|
|
|
12
12
|
*/
|
|
13
13
|
const SUBSCRIPTION_LOGIN_BIN = {
|
|
14
14
|
"claude-code": "claude",
|
|
15
|
+
"antigravity": "agy",
|
|
15
16
|
"codex": "codex",
|
|
16
17
|
"gemini": "gemini",
|
|
17
18
|
"kimi": "kimi",
|
|
@@ -24,10 +25,11 @@ const SUBSCRIPTION_LOGIN_BIN = {
|
|
|
24
25
|
* Subcommand args appended to the login command. Some CLIs use a dedicated
|
|
25
26
|
* subcommand (`codex login`, `kimi login`); others authenticate via a slash
|
|
26
27
|
* command inside the REPL (the user types /login after launching).
|
|
27
|
-
* @type {Record<string, string[]>}
|
|
28
|
+
* @type {Record<string, string[] | ((configDir: string) => string[])>}
|
|
28
29
|
*/
|
|
29
30
|
const SUBSCRIPTION_LOGIN_ARGS = {
|
|
30
31
|
"claude-code": [],
|
|
32
|
+
"antigravity": (configDir) => ["--gemini_dir", configDir],
|
|
31
33
|
"codex": ["login"],
|
|
32
34
|
"gemini": [],
|
|
33
35
|
"kimi": ["login"],
|
|
@@ -39,6 +41,7 @@ const SUBSCRIPTION_LOGIN_ARGS = {
|
|
|
39
41
|
*/
|
|
40
42
|
const SUBSCRIPTION_DIR_ENV_VAR = {
|
|
41
43
|
"claude-code": "CLAUDE_CONFIG_DIR",
|
|
44
|
+
"antigravity": "GEMINI_DIR",
|
|
42
45
|
"codex": "CODEX_HOME",
|
|
43
46
|
"gemini": "GEMINI_DIR",
|
|
44
47
|
"kimi": "KIMI_SHARE_DIR",
|
|
@@ -47,6 +50,15 @@ const SUBSCRIPTION_DIR_ENV_VAR = {
|
|
|
47
50
|
"gemini-api": null,
|
|
48
51
|
};
|
|
49
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @param {string} provider
|
|
55
|
+
* @param {string} configDir
|
|
56
|
+
*/
|
|
57
|
+
function subscriptionLoginArgs(provider, configDir) {
|
|
58
|
+
const args = SUBSCRIPTION_LOGIN_ARGS[provider] ?? [];
|
|
59
|
+
return typeof args === "function" ? args(configDir) : args;
|
|
60
|
+
}
|
|
61
|
+
|
|
50
62
|
/**
|
|
51
63
|
* @param {string} dir
|
|
52
64
|
* @returns {boolean}
|
|
@@ -94,7 +106,7 @@ export function runAgentAdd(input) {
|
|
|
94
106
|
if (!populated && !input.skipLogin && !input.force) {
|
|
95
107
|
const bin = SUBSCRIPTION_LOGIN_BIN[input.provider];
|
|
96
108
|
const envVar = SUBSCRIPTION_DIR_ENV_VAR[input.provider];
|
|
97
|
-
const subArgs =
|
|
109
|
+
const subArgs = subscriptionLoginArgs(input.provider, configDir);
|
|
98
110
|
const cmd = `${envVar}=${configDir} ${bin}${subArgs.length ? " " + subArgs.join(" ") : ""}`;
|
|
99
111
|
const detail = `Config dir ${configDir} is empty. Run the following in another terminal to log in, then re-run \`smithers agents add\`:\n\n ${cmd}\n\n(or pass --skip-login to register the empty dir, --force to register without verification)`;
|
|
100
112
|
return { ok: false, reason: "login-required", detail, configDir };
|