@claudexor/harness-agy 3.5.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/LICENSE +21 -0
- package/README.md +13 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +316 -0
- package/dist/index.js.map +1 -0
- package/dist/parse.d.ts +14 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +240 -0
- package/dist/parse.js.map +1 -0
- package/dist/profile.d.ts +85 -0
- package/dist/profile.d.ts.map +1 -0
- package/dist/profile.js +160 -0
- package/dist/profile.js.map +1 -0
- package/dist/vendor-cli-version.d.ts +15 -0
- package/dist/vendor-cli-version.d.ts.map +1 -0
- package/dist/vendor-cli-version.js +14 -0
- package/dist/vendor-cli-version.js.map +1 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anton Razzhigaev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @claudexor/harness-agy
|
|
2
|
+
|
|
3
|
+
Adapter for Google's Antigravity CLI (`agy`): translates
|
|
4
|
+
`agy -p --output-format stream-json` into typed `HarnessEvent`s.
|
|
5
|
+
|
|
6
|
+
Accounts are NAMED credential profiles only (there is no engine-default agy
|
|
7
|
+
credential): each profile is a Claudexor-owned HOME whose vendor config root
|
|
8
|
+
(`$HOME/.gemini/...`) holds a file-based OAuth token. See
|
|
9
|
+
`src/profile.ts` for the mechanism and its constraints (never create a
|
|
10
|
+
keychain inside a profile HOME).
|
|
11
|
+
|
|
12
|
+
Fixtures under `fixtures/` pin the recorded 1.1.13 stream shapes; see
|
|
13
|
+
`fixtures/manifest.yaml` for provenance and stream-semantics expectations.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { HarnessAdapter } from "@claudexor/core";
|
|
2
|
+
export { AGY_BIN, agyProfileRunEnv, agyTokenFilePresent, canonicalAgyProfileHome, } from "./profile.js";
|
|
3
|
+
/**
|
|
4
|
+
* The vendor's two quota GROUPS map onto disjoint halves of the same
|
|
5
|
+
* inventory: "Gemini Models" and "Claude and GPT models" (PLAN §1.2 F8). The
|
|
6
|
+
* split is DERIVED from the one model list so a slug the vendor adds cannot
|
|
7
|
+
* land in neither half and silently escape window scoping (INV-138).
|
|
8
|
+
*/
|
|
9
|
+
export declare const AGY_GEMINI_MODELS: ("claude-opus-4-6-thinking" | "claude-sonnet-4-6" | "gemini-3.1-pro-high" | "gemini-3.1-pro-low" | "gemini-3.5-flash-high" | "gemini-3.5-flash-low" | "gemini-3.5-flash-medium" | "gemini-3.6-flash-high" | "gemini-3.6-flash-low" | "gemini-3.6-flash-medium" | "gemini-3.7-flash-high" | "gemini-3.7-flash-low" | "gemini-3.7-flash-medium" | "gpt-oss-120b-medium")[];
|
|
10
|
+
export declare const AGY_THIRD_PARTY_MODELS: ("claude-opus-4-6-thinking" | "claude-sonnet-4-6" | "gemini-3.1-pro-high" | "gemini-3.1-pro-low" | "gemini-3.5-flash-high" | "gemini-3.5-flash-low" | "gemini-3.5-flash-medium" | "gemini-3.6-flash-high" | "gemini-3.6-flash-low" | "gemini-3.6-flash-medium" | "gemini-3.7-flash-high" | "gemini-3.7-flash-low" | "gemini-3.7-flash-medium" | "gpt-oss-120b-medium")[];
|
|
11
|
+
export declare function createAgyAdapter(): HarnessAdapter;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAclE,OAAO,EACL,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AA2DtB;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,0WAA0D,CAAC;AACzF,eAAO,MAAM,sBAAsB,0WAA2D,CAAC;AAe/F,wBAAgB,gBAAgB,IAAI,cAAc,CA4LjD"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { ConformanceReport as ConformanceReportSchema, HarnessManifest as HarnessManifestSchema, } from "@claudexor/schema";
|
|
2
|
+
import { HarnessUnavailableError, promptWithInstructions, runCapture, runCliHarness, } from "@claudexor/core";
|
|
3
|
+
import { CLAUDEXOR_VERSION, nowIso, redactSecrets } from "@claudexor/util";
|
|
4
|
+
import { parseAgyEvent } from "./parse.js";
|
|
5
|
+
import { AGY_BIN, probeAgyCredentialProfile, resolveAgyProfileRoute } from "./profile.js";
|
|
6
|
+
import { AGY_VENDOR_CLI_VERSION } from "./vendor-cli-version.js";
|
|
7
|
+
// The package publishes only what other packages consume. The profile probe,
|
|
8
|
+
// the route resolver and the stream parser are reached through the adapter
|
|
9
|
+
// this file returns, so re-exporting them would be a dead public surface.
|
|
10
|
+
export { AGY_BIN, agyProfileRunEnv, agyTokenFilePresent, canonicalAgyProfileHome, } from "./profile.js";
|
|
11
|
+
/**
|
|
12
|
+
* Access mapping, each leg LIVE-PROVEN on agy 1.1.13 (PLAN §1.2 F11, §1.2d):
|
|
13
|
+
* plan mode answered read-only prompts and withheld a requested write;
|
|
14
|
+
* accept-edits wrote into the workspace; --dangerously-skip-permissions wrote
|
|
15
|
+
* and ran commands. Owner decision Л-7 admits full access explicitly.
|
|
16
|
+
*/
|
|
17
|
+
function accessArgs(access) {
|
|
18
|
+
switch (access) {
|
|
19
|
+
case "readonly":
|
|
20
|
+
return ["--mode", "plan"];
|
|
21
|
+
case "workspace_write":
|
|
22
|
+
return ["--mode", "accept-edits"];
|
|
23
|
+
case "full":
|
|
24
|
+
case "external_sandbox_full":
|
|
25
|
+
return ["--dangerously-skip-permissions"];
|
|
26
|
+
case "inherit_native":
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function detectVersion() {
|
|
31
|
+
try {
|
|
32
|
+
const r = await runCapture(AGY_BIN(), ["--version"], { timeoutMs: 10_000 });
|
|
33
|
+
return r.stdout.trim() || `${AGY_BIN()} (version unknown)`;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Manifest model truth (INV-104): the vendor's own list, captured live from
|
|
41
|
+
* `agy models` on the pinned version (evidence: PLAN §1.2 F9 and the sprint
|
|
42
|
+
* evidence dir; the vendor emits TSV, not JSON, in 1.1.13). Slugs
|
|
43
|
+
* carry the reasoning effort (`-high`/`-medium`/`-low`) exactly like Cursor's
|
|
44
|
+
* inventory, so the effort ladder is deliberately empty and an effort hint is
|
|
45
|
+
* disclosed as ignored rather than mapped (Л-21). No live `models()`:
|
|
46
|
+
* `agy models --output-format json` is rejected by 1.1.13 (upstream #777) and
|
|
47
|
+
* the unauthenticated plain listing fails — an empty live list would refuse
|
|
48
|
+
* every explicit model (PLAN §2.6).
|
|
49
|
+
*/
|
|
50
|
+
const AGY_KNOWN_MODELS = [
|
|
51
|
+
"gemini-3.7-flash-high",
|
|
52
|
+
"gemini-3.7-flash-medium",
|
|
53
|
+
"gemini-3.7-flash-low",
|
|
54
|
+
"gemini-3.6-flash-high",
|
|
55
|
+
"gemini-3.6-flash-medium",
|
|
56
|
+
"gemini-3.6-flash-low",
|
|
57
|
+
"gemini-3.5-flash-high",
|
|
58
|
+
"gemini-3.5-flash-medium",
|
|
59
|
+
"gemini-3.5-flash-low",
|
|
60
|
+
"gemini-3.1-pro-high",
|
|
61
|
+
"gemini-3.1-pro-low",
|
|
62
|
+
"claude-sonnet-4-6",
|
|
63
|
+
"claude-opus-4-6-thinking",
|
|
64
|
+
"gpt-oss-120b-medium",
|
|
65
|
+
];
|
|
66
|
+
/**
|
|
67
|
+
* The vendor's two quota GROUPS map onto disjoint halves of the same
|
|
68
|
+
* inventory: "Gemini Models" and "Claude and GPT models" (PLAN §1.2 F8). The
|
|
69
|
+
* split is DERIVED from the one model list so a slug the vendor adds cannot
|
|
70
|
+
* land in neither half and silently escape window scoping (INV-138).
|
|
71
|
+
*/
|
|
72
|
+
export const AGY_GEMINI_MODELS = AGY_KNOWN_MODELS.filter((m) => m.startsWith("gemini-"));
|
|
73
|
+
export const AGY_THIRD_PARTY_MODELS = AGY_KNOWN_MODELS.filter((m) => !m.startsWith("gemini-"));
|
|
74
|
+
const AGY_ENABLED_INTENTS = [
|
|
75
|
+
"explain",
|
|
76
|
+
"plan",
|
|
77
|
+
"spec",
|
|
78
|
+
"implement",
|
|
79
|
+
"repair",
|
|
80
|
+
"create_from_scratch",
|
|
81
|
+
"review",
|
|
82
|
+
"verify",
|
|
83
|
+
"synthesize",
|
|
84
|
+
"audit",
|
|
85
|
+
];
|
|
86
|
+
export function createAgyAdapter() {
|
|
87
|
+
return {
|
|
88
|
+
id: "agy",
|
|
89
|
+
async discover() {
|
|
90
|
+
const version = await detectVersion();
|
|
91
|
+
if (version === null) {
|
|
92
|
+
throw new HarnessUnavailableError("agy not found on PATH (install Antigravity CLI or set CLAUDEXOR_AGY_BIN)");
|
|
93
|
+
}
|
|
94
|
+
return HarnessManifestSchema.parse({
|
|
95
|
+
id: "agy",
|
|
96
|
+
display_name: "Antigravity",
|
|
97
|
+
kind: "local_cli",
|
|
98
|
+
version,
|
|
99
|
+
adapter_version: CLAUDEXOR_VERSION,
|
|
100
|
+
provider_family: "google",
|
|
101
|
+
capabilities: {
|
|
102
|
+
plan: true,
|
|
103
|
+
implement: true,
|
|
104
|
+
create_from_scratch: true,
|
|
105
|
+
review: true,
|
|
106
|
+
verify: true,
|
|
107
|
+
synthesize: true,
|
|
108
|
+
read_files: true,
|
|
109
|
+
// No MCP flag path exists (config is file-only), so no browser
|
|
110
|
+
// injector is wired — honest false (INV-066).
|
|
111
|
+
browser_tool: false,
|
|
112
|
+
// Built-in web tools with no enforceable off switch (cursor parity).
|
|
113
|
+
web_policy: "uncontrolled",
|
|
114
|
+
// D-16 default recommendation (В-10): the fenced-block tier costs
|
|
115
|
+
// zero extra vendor turns; the schema-constrained tier is proven to
|
|
116
|
+
// force a SECOND turn per run (PLAN §1.2e) and stays off until the
|
|
117
|
+
// owner opts in.
|
|
118
|
+
work_report_transport: "validated",
|
|
119
|
+
// Effort rides the model slug (`-high`), not a flag (Л-21).
|
|
120
|
+
effort_levels: [],
|
|
121
|
+
known_models: [...AGY_KNOWN_MODELS],
|
|
122
|
+
known_models_verified_against: AGY_VENDOR_CLI_VERSION,
|
|
123
|
+
},
|
|
124
|
+
capability_profile: {
|
|
125
|
+
auth: {
|
|
126
|
+
supported_sources: ["native_session"],
|
|
127
|
+
preferred_source: "native_session",
|
|
128
|
+
credential_transports: [
|
|
129
|
+
// The profile HOME relocates the vendor's whole config root and
|
|
130
|
+
// its file-based OAuth token (Л-15/Л-16): config_file, HOME.
|
|
131
|
+
{ source: "native_session", kind: "config_file", relocatable_by: ["HOME"] },
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
// readonly = vendor plan mode: write tools are withheld
|
|
135
|
+
// (permission-denied), reads and answers flow (live-proven F11).
|
|
136
|
+
access_control: { readonly_mechanism: "permission_deny" },
|
|
137
|
+
isolation: { supported_containment: ["env_or_file_injection"] },
|
|
138
|
+
// No proven attachment path yet — honest empty set (INV-064/065).
|
|
139
|
+
attachment_inputs: [],
|
|
140
|
+
},
|
|
141
|
+
auth_modes: ["local_session"],
|
|
142
|
+
access_profiles_supported: [
|
|
143
|
+
"readonly",
|
|
144
|
+
"workspace_write",
|
|
145
|
+
"full",
|
|
146
|
+
"external_sandbox_full",
|
|
147
|
+
"inherit_native",
|
|
148
|
+
],
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
async doctor(spec) {
|
|
152
|
+
const version = await detectVersion();
|
|
153
|
+
const installedSemver = version === null ? null : (/\d+\.\d+\.\d+/.exec(version)?.[0] ?? null);
|
|
154
|
+
const versionDrift = version !== null && installedSemver !== AGY_VENDOR_CLI_VERSION
|
|
155
|
+
? `installed agy "${version}" differs from the verified ${AGY_VENDOR_CLI_VERSION}; the file-token profile mechanism is re-proven per version (R-2')`
|
|
156
|
+
: null;
|
|
157
|
+
// Л-24: the account isolation mechanism — one Claudexor-owned HOME per
|
|
158
|
+
// identity, with the vendor keeping its token in a file inside it — was
|
|
159
|
+
// proven on macOS across three live Google accounts. The same HOME lever
|
|
160
|
+
// exists on every platform the vendor supports, but nobody has run it
|
|
161
|
+
// there, so the platform says so instead of implying a proof it lacks.
|
|
162
|
+
const platformProof = process.platform === "darwin"
|
|
163
|
+
? null
|
|
164
|
+
: `named-account isolation is unverified on ${process.platform}: the mechanism is the same profile HOME proven on macOS, but no live multi-account run has been recorded here`;
|
|
165
|
+
const requestedSource = spec.authSource;
|
|
166
|
+
if (requestedSource !== undefined && requestedSource !== "native_session") {
|
|
167
|
+
return ConformanceReportSchema.parse({
|
|
168
|
+
harness_id: "agy",
|
|
169
|
+
status: "unavailable",
|
|
170
|
+
checks: [
|
|
171
|
+
version === null
|
|
172
|
+
? { id: "installed", status: "fail", detail: "agy not found" }
|
|
173
|
+
: { id: "installed", status: "pass", detail: redactSecrets(version) },
|
|
174
|
+
{
|
|
175
|
+
id: "auth_source",
|
|
176
|
+
status: "fail",
|
|
177
|
+
detail: `agy does not support ${requestedSource}`,
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
enabled_intents: [],
|
|
181
|
+
disabled_intents: AGY_ENABLED_INTENTS,
|
|
182
|
+
reasons: [`agy does not support auth source ${requestedSource}`],
|
|
183
|
+
auth_sources: [
|
|
184
|
+
{
|
|
185
|
+
source: requestedSource,
|
|
186
|
+
availability: "unavailable",
|
|
187
|
+
verification: "not_run",
|
|
188
|
+
detail: `agy does not support ${requestedSource}`,
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
if (version === null) {
|
|
194
|
+
return ConformanceReportSchema.parse({
|
|
195
|
+
harness_id: "agy",
|
|
196
|
+
status: "unavailable",
|
|
197
|
+
checks: [{ id: "installed", status: "fail", detail: "agy not found" }],
|
|
198
|
+
enabled_intents: [],
|
|
199
|
+
disabled_intents: AGY_ENABLED_INTENTS,
|
|
200
|
+
reasons: ["agy not found (install Antigravity CLI or set CLAUDEXOR_AGY_BIN)"],
|
|
201
|
+
auth_sources: [
|
|
202
|
+
{
|
|
203
|
+
source: "native_session",
|
|
204
|
+
availability: "unknown",
|
|
205
|
+
verification: "not_run",
|
|
206
|
+
detail: "agy binary not installed",
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
// Owner decision Л-4: agy has NO engine-default credential store — every
|
|
212
|
+
// account is a named profile. The harness-level doctor therefore reports
|
|
213
|
+
// the default subject honestly unavailable with the remedy; PINNED
|
|
214
|
+
// routing is admitted by the per-profile probe (INV-135 round-15 #1),
|
|
215
|
+
// exactly like a logged-out cursor default with valid named profiles.
|
|
216
|
+
return ConformanceReportSchema.parse({
|
|
217
|
+
harness_id: "agy",
|
|
218
|
+
status: "unavailable",
|
|
219
|
+
checks: [
|
|
220
|
+
{ id: "installed", status: "pass", detail: redactSecrets(version) },
|
|
221
|
+
{
|
|
222
|
+
id: "default_credential",
|
|
223
|
+
status: "fail",
|
|
224
|
+
detail: "agy has no engine-default credential by design; accounts are named profiles",
|
|
225
|
+
},
|
|
226
|
+
...(versionDrift
|
|
227
|
+
? [{ id: "version_pin", status: "fail", detail: versionDrift }]
|
|
228
|
+
: [{ id: "version_pin", status: "pass", detail: AGY_VENDOR_CLI_VERSION }]),
|
|
229
|
+
...(platformProof
|
|
230
|
+
? [{ id: "platform_isolation", status: "warn", detail: platformProof }]
|
|
231
|
+
: []),
|
|
232
|
+
],
|
|
233
|
+
enabled_intents: [],
|
|
234
|
+
disabled_intents: AGY_ENABLED_INTENTS,
|
|
235
|
+
reasons: [
|
|
236
|
+
"agy routes only through named accounts: add one (`claudexor profiles add agy <id>` + `claudexor profiles login agy <id>`) and pin it (--profile)",
|
|
237
|
+
...(versionDrift ? [versionDrift] : []),
|
|
238
|
+
...(platformProof ? [platformProof] : []),
|
|
239
|
+
],
|
|
240
|
+
auth_sources: [
|
|
241
|
+
{
|
|
242
|
+
source: "native_session",
|
|
243
|
+
availability: "unavailable",
|
|
244
|
+
verification: "not_run",
|
|
245
|
+
detail: "no default store by design (accounts are named profiles)",
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
});
|
|
249
|
+
},
|
|
250
|
+
run(spec) {
|
|
251
|
+
return runAgy(spec);
|
|
252
|
+
},
|
|
253
|
+
review(spec) {
|
|
254
|
+
return runAgy(spec);
|
|
255
|
+
},
|
|
256
|
+
// INV-135: pinned routing is admitted by THIS probe (there is no default
|
|
257
|
+
// store for the harness doctor to credit).
|
|
258
|
+
async probeCredentialProfile(profile, abortSignal) {
|
|
259
|
+
// The signal must reach the live probe: dropping it left an aborted
|
|
260
|
+
// doctor sweep waiting out the probe's own 30s timeout.
|
|
261
|
+
return probeAgyCredentialProfile(profile, undefined, abortSignal);
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
async function* runAgy(spec) {
|
|
266
|
+
const profile = spec.credential_profile;
|
|
267
|
+
// Л-4: no engine-default credential — an unpinned agy run has nothing to
|
|
268
|
+
// route. Typed stream refusal (error then completed), the one refusal
|
|
269
|
+
// mechanism every adapter's profile gate uses.
|
|
270
|
+
if (!profile) {
|
|
271
|
+
yield {
|
|
272
|
+
type: "error",
|
|
273
|
+
session_id: spec.session_id,
|
|
274
|
+
ts: nowIso(),
|
|
275
|
+
error: "agy has no engine-default credential; pin a named account (--profile, or `claudexor profiles add agy <id>`)",
|
|
276
|
+
};
|
|
277
|
+
yield { type: "completed", session_id: spec.session_id, ts: nowIso() };
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const route = resolveAgyProfileRoute(profile, spec.env);
|
|
281
|
+
if ("refusal" in route) {
|
|
282
|
+
yield { type: "error", session_id: spec.session_id, ts: nowIso(), error: route.refusal };
|
|
283
|
+
yield { type: "completed", session_id: spec.session_id, ts: nowIso() };
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const args = ["-p", promptWithInstructions(spec), "--output-format", "stream-json"];
|
|
287
|
+
// Л-18: without --add-dir agy resolves relative paths against its own app
|
|
288
|
+
// data dir instead of the workspace (live-proven §1.2d).
|
|
289
|
+
args.push("--add-dir", spec.cwd);
|
|
290
|
+
args.push(...accessArgs(spec.access));
|
|
291
|
+
if (spec.model_hint)
|
|
292
|
+
args.push("--model", spec.model_hint);
|
|
293
|
+
// INV-137: the vendor conversation id is the resumable native session.
|
|
294
|
+
if (spec.resume_session_id)
|
|
295
|
+
args.push("--conversation", spec.resume_session_id);
|
|
296
|
+
yield* runCliHarness({
|
|
297
|
+
bin: AGY_BIN(),
|
|
298
|
+
args,
|
|
299
|
+
spec,
|
|
300
|
+
env: route.env,
|
|
301
|
+
label: "agy",
|
|
302
|
+
redact: redactSecrets,
|
|
303
|
+
parseEvent: (obj, sessionId) => {
|
|
304
|
+
const out = parseAgyEvent(obj, sessionId);
|
|
305
|
+
if (out) {
|
|
306
|
+
for (const ev of out) {
|
|
307
|
+
ev.credential_route = "vendor_native";
|
|
308
|
+
ev.credential_source = "native_session";
|
|
309
|
+
ev.credential_profile_id = profile.profile_id;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return out;
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/parse.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HarnessEvent } from "@claudexor/schema";
|
|
2
|
+
type Json = any;
|
|
3
|
+
/**
|
|
4
|
+
* Map an Antigravity CLI (`agy -p --output-format stream-json`) ND-JSON event
|
|
5
|
+
* to normalized events. Field shapes are pinned by RECORDED fixtures captured
|
|
6
|
+
* on agy 1.1.13 (fixtures/manifest.yaml): `init` / `step_update` / `result`,
|
|
7
|
+
* with `step_update.step_type` an OPEN vocabulary
|
|
8
|
+
* (user_input | agent_response | tool | checkpoint | finish | unknown | …).
|
|
9
|
+
* Unknown step types are recognized no-ops (empty array, never a drop);
|
|
10
|
+
* unknown TOP-LEVEL events return `null` so the run loop counts them.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseAgyEvent(obj: Json, sessionId: string): HarnessEvent[] | null;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,mBAAmB,CAAC;AAGzE,KAAK,IAAI,GAAG,GAAG,CAAC;AAEhB;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE,GAAG,IAAI,CAqJjF"}
|
package/dist/parse.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { nowIso, redactSecrets } from "@claudexor/util";
|
|
2
|
+
/**
|
|
3
|
+
* Map an Antigravity CLI (`agy -p --output-format stream-json`) ND-JSON event
|
|
4
|
+
* to normalized events. Field shapes are pinned by RECORDED fixtures captured
|
|
5
|
+
* on agy 1.1.13 (fixtures/manifest.yaml): `init` / `step_update` / `result`,
|
|
6
|
+
* with `step_update.step_type` an OPEN vocabulary
|
|
7
|
+
* (user_input | agent_response | tool | checkpoint | finish | unknown | …).
|
|
8
|
+
* Unknown step types are recognized no-ops (empty array, never a drop);
|
|
9
|
+
* unknown TOP-LEVEL events return `null` so the run loop counts them.
|
|
10
|
+
*/
|
|
11
|
+
export function parseAgyEvent(obj, sessionId) {
|
|
12
|
+
const ts = nowIso();
|
|
13
|
+
// A non-string `event` must not be COERCED: an object whose `toString` is
|
|
14
|
+
// not callable throws, and the run loop would report a mid-stream parse
|
|
15
|
+
// failure as "the harness failed to start" and drop the rest of the run.
|
|
16
|
+
const event = typeof obj?.event === "string" ? obj.event : "";
|
|
17
|
+
if (event === "init") {
|
|
18
|
+
const nativeId = stringOrUndef(obj.conversation_id);
|
|
19
|
+
const model = stringOrUndef(obj.init?.model);
|
|
20
|
+
return [
|
|
21
|
+
{
|
|
22
|
+
type: "started",
|
|
23
|
+
session_id: sessionId,
|
|
24
|
+
ts,
|
|
25
|
+
...(model ? { observed_model: model } : {}),
|
|
26
|
+
// The vendor conversation id IS the resumable native session
|
|
27
|
+
// (`agy --conversation <id>`); surface it for INV-137 lane resume.
|
|
28
|
+
...(nativeId ? { payload: { native_session_id: nativeId } } : {}),
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
if (event === "step_update") {
|
|
33
|
+
const step = obj.step_update ?? {};
|
|
34
|
+
const stepType = typeof step.step_type === "string" ? step.step_type : "";
|
|
35
|
+
const events = [];
|
|
36
|
+
if (stepType === "tool") {
|
|
37
|
+
const info = step.tool_info ?? {};
|
|
38
|
+
const name = typeof info.name === "string" && info.name
|
|
39
|
+
? info.name
|
|
40
|
+
: typeof step.tool_name === "string" && step.tool_name
|
|
41
|
+
? step.tool_name
|
|
42
|
+
: "tool";
|
|
43
|
+
const target = boundedTarget(primaryToolTarget(info.parameters));
|
|
44
|
+
const tool = { name, kind: toolKindFor(name), target };
|
|
45
|
+
const state = typeof step.state === "string" ? step.state : "";
|
|
46
|
+
if (state === "ACTIVE") {
|
|
47
|
+
// ACTIVE/DONE arrive as a pair per call (fixture-pinned): ACTIVE is
|
|
48
|
+
// the call, DONE the result.
|
|
49
|
+
events.push({ type: "tool_call", session_id: sessionId, ts, text: name, tool });
|
|
50
|
+
}
|
|
51
|
+
else if (state === "DONE") {
|
|
52
|
+
const errorDetail = summarize(info.error);
|
|
53
|
+
if (errorDetail) {
|
|
54
|
+
events.push({
|
|
55
|
+
type: "tool_result",
|
|
56
|
+
session_id: sessionId,
|
|
57
|
+
ts,
|
|
58
|
+
text: `tool_result: error: ${errorDetail}`,
|
|
59
|
+
tool: { ...tool, status: "error", error_summary: errorDetail },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const output = summarize(info.output);
|
|
64
|
+
events.push({
|
|
65
|
+
type: "tool_result",
|
|
66
|
+
session_id: sessionId,
|
|
67
|
+
ts,
|
|
68
|
+
text: "tool_result",
|
|
69
|
+
tool: { ...tool, status: "ok", content_summary: output || undefined },
|
|
70
|
+
});
|
|
71
|
+
if (isWriteTool(name)) {
|
|
72
|
+
events.push({
|
|
73
|
+
type: "file_change",
|
|
74
|
+
session_id: sessionId,
|
|
75
|
+
ts,
|
|
76
|
+
tool: { name, kind: "file" },
|
|
77
|
+
payload: { path: boundedTarget(primaryToolTarget(info.parameters)), tool: name },
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Any OTHER state (PENDING/CANCELLED/ERROR/absent, or a future value) is
|
|
83
|
+
// a recognized lifecycle no-op: claiming success for it would fabricate
|
|
84
|
+
// a completed tool call — and, for a write-named tool, a file change
|
|
85
|
+
// that never happened (Ф0 review #1).
|
|
86
|
+
}
|
|
87
|
+
else if (typeof step.text_delta === "string" && step.text_delta) {
|
|
88
|
+
// agent_response chunks: completed narration segments (not display
|
|
89
|
+
// deltas — no payload.delta). The typed final comes from `result`.
|
|
90
|
+
events.push({ type: "message", session_id: sessionId, ts, text: step.text_delta });
|
|
91
|
+
}
|
|
92
|
+
// user_input / checkpoint / finish / unknown / future types: recognized
|
|
93
|
+
// lifecycle no-ops. Step usage is deliberately NOT emitted: the recorded
|
|
94
|
+
// fixtures prove the per-step usages sum EXACTLY to the terminal
|
|
95
|
+
// aggregate, so emitting both counted every token twice (sol review).
|
|
96
|
+
// The one authoritative usage event rides `result`.
|
|
97
|
+
return events;
|
|
98
|
+
}
|
|
99
|
+
if (event === "result") {
|
|
100
|
+
const r = obj.result ?? {};
|
|
101
|
+
const status = typeof r.status === "string" ? r.status : "";
|
|
102
|
+
const events = [];
|
|
103
|
+
const usage = stepUsage(r.usage);
|
|
104
|
+
if (status === "SUCCESS") {
|
|
105
|
+
// Л-20: with a schema envelope the parsed object rides
|
|
106
|
+
// `structured_output` while `response` concatenates prose AND the JSON;
|
|
107
|
+
// serialize the parsed object as the typed final (codex model) instead
|
|
108
|
+
// of parsing mixed text. Without a schema the final is `response`.
|
|
109
|
+
// Only an OBJECT envelope is a structured final: `false`/`0`/`""` are
|
|
110
|
+
// not envelopes and must fall through to the prose response (review #7).
|
|
111
|
+
const structured = r.structured_output !== null && typeof r.structured_output === "object"
|
|
112
|
+
? r.structured_output
|
|
113
|
+
: null;
|
|
114
|
+
const finalText = structured !== null
|
|
115
|
+
? JSON.stringify(structured)
|
|
116
|
+
: typeof r.response === "string"
|
|
117
|
+
? r.response
|
|
118
|
+
: "";
|
|
119
|
+
if (finalText.trim()) {
|
|
120
|
+
events.push({
|
|
121
|
+
type: "message",
|
|
122
|
+
session_id: sessionId,
|
|
123
|
+
ts,
|
|
124
|
+
text: finalText,
|
|
125
|
+
final: true,
|
|
126
|
+
payload: {
|
|
127
|
+
final_source: structured !== null ? "structured_output" : "result",
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// Vendor soft-deny class (upstream #794): SUCCESS with an empty
|
|
133
|
+
// response means a permission-denied turn that did nothing. Honest
|
|
134
|
+
// typed error, never a silent empty success.
|
|
135
|
+
events.push({
|
|
136
|
+
type: "error",
|
|
137
|
+
session_id: sessionId,
|
|
138
|
+
ts,
|
|
139
|
+
error: "agy reported SUCCESS with an empty response (no output produced; commonly a vendor soft-deny of a required tool permission)",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
events.push({
|
|
145
|
+
type: "error",
|
|
146
|
+
session_id: sessionId,
|
|
147
|
+
ts,
|
|
148
|
+
error: summarize(r.error) || `agy terminal status ${status || "unknown"}`,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (usage)
|
|
152
|
+
events.push({ type: "usage", session_id: sessionId, ts, usage });
|
|
153
|
+
return events;
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
/** Tools that MUTATE the workspace. The regex catches the vendor's naming
|
|
158
|
+
* convention; the allowlist covers proven writers whose names do not match
|
|
159
|
+
* (`generate_image` writes an image file — Ф0 review #5). `sed_file` is
|
|
160
|
+
* deliberately absent: whether it mutates on 1.1.13 is unverified, and
|
|
161
|
+
* claiming a file change we cannot prove is the same defect class as #1. */
|
|
162
|
+
const WRITE_TOOL_NAMES = new Set(["generate_image"]);
|
|
163
|
+
const WRITE_TOOLS_RE = /write|edit|replace|apply|patch/i;
|
|
164
|
+
function isWriteTool(name) {
|
|
165
|
+
return WRITE_TOOL_NAMES.has(name) || WRITE_TOOLS_RE.test(name);
|
|
166
|
+
}
|
|
167
|
+
function toolKindFor(name) {
|
|
168
|
+
const n = name.toLowerCase();
|
|
169
|
+
if (n.includes("command") || n.includes("shell") || n.includes("bash"))
|
|
170
|
+
return "command";
|
|
171
|
+
if (n.includes("search") || n.includes("grep") || n.includes("glob") || n.includes("list_dir"))
|
|
172
|
+
return "search";
|
|
173
|
+
if (n.includes("browser") || n.includes("url") || n.includes("web"))
|
|
174
|
+
return "web";
|
|
175
|
+
if (isWriteTool(n) || n.includes("read") || n.includes("file") || n.includes("view"))
|
|
176
|
+
return "file";
|
|
177
|
+
if (n.includes("mcp"))
|
|
178
|
+
return "mcp";
|
|
179
|
+
return "other";
|
|
180
|
+
}
|
|
181
|
+
/** The one human-meaningful target among agy's PascalCase tool parameters. */
|
|
182
|
+
function primaryToolTarget(parameters) {
|
|
183
|
+
if (!parameters || typeof parameters !== "object")
|
|
184
|
+
return undefined;
|
|
185
|
+
const p = parameters;
|
|
186
|
+
for (const key of [
|
|
187
|
+
"TargetFile",
|
|
188
|
+
"AbsolutePath",
|
|
189
|
+
"DirectoryPath",
|
|
190
|
+
"CommandLine",
|
|
191
|
+
"Query",
|
|
192
|
+
"Url",
|
|
193
|
+
]) {
|
|
194
|
+
const v = p[key];
|
|
195
|
+
if (typeof v === "string" && v)
|
|
196
|
+
return v;
|
|
197
|
+
}
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* agy usage: {input_tokens, output_tokens, thinking_tokens, cache_read_tokens,
|
|
202
|
+
* total_tokens}. `thinking_tokens` has no schema home and is deliberately
|
|
203
|
+
* DROPPED (disclosed absence), never folded into output (PLAN R-9).
|
|
204
|
+
*/
|
|
205
|
+
function stepUsage(raw) {
|
|
206
|
+
if (!raw || typeof raw !== "object")
|
|
207
|
+
return null;
|
|
208
|
+
const u = raw;
|
|
209
|
+
const usage = {};
|
|
210
|
+
if (typeof u.input_tokens === "number")
|
|
211
|
+
usage.input_tokens = u.input_tokens;
|
|
212
|
+
if (typeof u.output_tokens === "number")
|
|
213
|
+
usage.output_tokens = u.output_tokens;
|
|
214
|
+
if (typeof u.cache_read_tokens === "number")
|
|
215
|
+
usage.cached_input_tokens = u.cache_read_tokens;
|
|
216
|
+
return Object.keys(usage).length ? usage : null;
|
|
217
|
+
}
|
|
218
|
+
function summarize(value) {
|
|
219
|
+
if (typeof value === "string")
|
|
220
|
+
return value.trim() ? redactSecrets(value).trim().replace(/\s+/g, " ").slice(0, 1000) : "";
|
|
221
|
+
// A non-string detail (the vendor sometimes nests an object) must not be
|
|
222
|
+
// silently dropped into a generic message (Ф0 review #7).
|
|
223
|
+
if (value === null || value === undefined)
|
|
224
|
+
return "";
|
|
225
|
+
try {
|
|
226
|
+
return redactSecrets(JSON.stringify(value)).trim().slice(0, 1000);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return "";
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function boundedTarget(value) {
|
|
233
|
+
if (typeof value !== "string" || !value.trim())
|
|
234
|
+
return undefined;
|
|
235
|
+
return redactSecrets(value).slice(0, 500);
|
|
236
|
+
}
|
|
237
|
+
function stringOrUndef(v) {
|
|
238
|
+
return typeof v === "string" && v ? v : undefined;
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { CredentialProfile, CredentialProfileStatus } from "@claudexor/schema";
|
|
2
|
+
type EnvMap = Record<string, string | null | undefined>;
|
|
3
|
+
export declare const AGY_BIN: () => string;
|
|
4
|
+
/** Canonical, Claudexor-owned HOME for one named Antigravity identity. */
|
|
5
|
+
export declare function canonicalAgyProfileHome(locator: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* The vendor's file-based OAuth token inside a profile HOME. agy lands on
|
|
8
|
+
* file storage because its keyring lookup FAILS in a scoped HOME (macOS: no
|
|
9
|
+
* login keychain in `$HOME/Library/Keychains` → `falling back to file`); the
|
|
10
|
+
* profile mechanism therefore REQUIRES that no keychain ever be created
|
|
11
|
+
* inside the profile HOME. Live-proven on three separate Google accounts
|
|
12
|
+
* (PLAN §1.2a-1.2c); re-proven per AGY_VENDOR_CLI_VERSION bump because the
|
|
13
|
+
* fallback is a vendor error path, not a documented mode (R-2').
|
|
14
|
+
*/
|
|
15
|
+
export declare function agyTokenPath(profileHome: string): string;
|
|
16
|
+
/** The token must be a regular FILE: a directory at that path is a malformed
|
|
17
|
+
* profile, not a login, and must refuse rather than route (Ф0 review #11). */
|
|
18
|
+
export declare function agyTokenFilePresent(profileHome: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Exact strict-profile env: the profile HOME selects the vendor's whole
|
|
21
|
+
* config root (`$HOME/.gemini/...`) — agy has no config-dir env var, HOME is
|
|
22
|
+
* the single lever. `USERPROFILE` mirrors HOME for the win32 resolver, the
|
|
23
|
+
* auto-updater is pinned off so the closed vendor binary cannot replace
|
|
24
|
+
* itself mid-run, and the provider scrub drops every API-key route
|
|
25
|
+
* (`GEMINI_API_KEY` included) so a native subscription run can never silently
|
|
26
|
+
* turn metered (INV-061).
|
|
27
|
+
*
|
|
28
|
+
* Unlike Cursor — whose mutable state is separately relocatable via
|
|
29
|
+
* `CURSOR_CONFIG_DIR`, so a run keeps state in its LANE home and reads auth
|
|
30
|
+
* from the profile — agy has exactly one lever. Overriding HOME therefore
|
|
31
|
+
* moves the vendor's conversations/brain/cache into the profile HOME too, and
|
|
32
|
+
* the per-lane home is unused for agy runs. Deliberate, not an oversight: a
|
|
33
|
+
* lane-scoped `.gemini` would be a dead directory the vendor never reads.
|
|
34
|
+
* What holds today is per-lane RESUME: a lane replays its own vendor
|
|
35
|
+
* conversation by id (`--conversation`, INV-137). Nothing scopes those
|
|
36
|
+
* conversations to a lane yet — the vendor's project mechanism
|
|
37
|
+
* (`--new-project`/`--project`, Л-19) is not wired here — so one profile HOME
|
|
38
|
+
* accumulates every thread's vendor state, and conversations are NOT scoped per
|
|
39
|
+
* chat thread.
|
|
40
|
+
*/
|
|
41
|
+
export declare function agyProfileRunEnv(profileHome: string, specEnv?: EnvMap): EnvMap;
|
|
42
|
+
export type AgyResolvedProfileRoute = {
|
|
43
|
+
home: string;
|
|
44
|
+
env: EnvMap;
|
|
45
|
+
} | {
|
|
46
|
+
refusal: string;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* INV-135 strict profile routing: an agy profile is exactly its
|
|
50
|
+
* `config_dir_login` HOME with a present vendor token file, or a typed
|
|
51
|
+
* refusal. There is NO engine-default agy credential (owner decision Л-4),
|
|
52
|
+
* so no fallback ladder exists to fall into.
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveAgyProfileRoute(profile: Pick<CredentialProfile, "profile_id" | "credential_kind" | "isolation_locator">, specEnv?: EnvMap): AgyResolvedProfileRoute;
|
|
55
|
+
export interface AgyProfileProbeDeps {
|
|
56
|
+
/** Injectable live probe (tests): print-mode `/model` under the profile env. */
|
|
57
|
+
runModelProbe: (env: EnvMap, abortSignal?: AbortSignal) => Promise<AgyModelProbe>;
|
|
58
|
+
}
|
|
59
|
+
export type AgyModelProbe = {
|
|
60
|
+
kind: "authenticated";
|
|
61
|
+
modelId: string | null;
|
|
62
|
+
} | {
|
|
63
|
+
kind: "unauthenticated";
|
|
64
|
+
detail: string;
|
|
65
|
+
} | {
|
|
66
|
+
kind: "probe_failed";
|
|
67
|
+
detail: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Quota-free liveness probe: `agy -p "/model" --output-format json` answers
|
|
71
|
+
* from the CLI without spending a turn (vendor 1.1.11+ print-mode
|
|
72
|
+
* slash-commands). SUCCESS proves the profile's token authenticates in the
|
|
73
|
+
* exact env its runs will spawn with (INV-067); an auth error is an honest
|
|
74
|
+
* logged-out/revoked verdict, and a spawn/parse failure stays `unknown`.
|
|
75
|
+
*/
|
|
76
|
+
export declare function defaultAgyModelProbe(env: EnvMap, abortSignal?: AbortSignal): Promise<AgyModelProbe>;
|
|
77
|
+
/**
|
|
78
|
+
* Doctor projection for one agy profile (INV-135): the SAME route resolution
|
|
79
|
+
* the run uses, then the quota-free live probe. A valid profile must admit
|
|
80
|
+
* the route even though agy has no default store at all — the orchestrator
|
|
81
|
+
* consults THIS probe for pinned routing.
|
|
82
|
+
*/
|
|
83
|
+
export declare function probeAgyCredentialProfile(profile: CredentialProfile, deps?: AgyProfileProbeDeps, abortSignal?: AbortSignal): Promise<CredentialProfileStatus>;
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../src/profile.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAIpF,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAExD,eAAO,MAAM,OAAO,cAA+C,CAAC;AAEpE,0EAA0E;AAC1E,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;8EAC8E;AAC9E,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAMhE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GAAG,MAAM,CASlF;AAED,MAAM,MAAM,uBAAuB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1F;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,iBAAiB,GAAG,mBAAmB,CAAC,EACxF,OAAO,GAAE,MAAW,GACnB,uBAAuB,CAezB;AAED,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CACnF;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7C;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,aAAa,CAAC,CAwBxB;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,iBAAiB,EAC1B,IAAI,GAAE,mBAA6D,EACnE,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,uBAAuB,CAAC,CAgClC"}
|
package/dist/profile.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { canonicalIsolationLocator, providerScrubEnv, runCapture } from "@claudexor/core";
|
|
4
|
+
import { CredentialProfileStatus as CredentialProfileStatusSchema } from "@claudexor/schema";
|
|
5
|
+
import { nowIso, redactSecrets } from "@claudexor/util";
|
|
6
|
+
export const AGY_BIN = () => process.env.CLAUDEXOR_AGY_BIN || "agy";
|
|
7
|
+
/** Canonical, Claudexor-owned HOME for one named Antigravity identity. */
|
|
8
|
+
export function canonicalAgyProfileHome(locator) {
|
|
9
|
+
return canonicalIsolationLocator(locator, "credential profile Antigravity HOME");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The vendor's file-based OAuth token inside a profile HOME. agy lands on
|
|
13
|
+
* file storage because its keyring lookup FAILS in a scoped HOME (macOS: no
|
|
14
|
+
* login keychain in `$HOME/Library/Keychains` → `falling back to file`); the
|
|
15
|
+
* profile mechanism therefore REQUIRES that no keychain ever be created
|
|
16
|
+
* inside the profile HOME. Live-proven on three separate Google accounts
|
|
17
|
+
* (PLAN §1.2a-1.2c); re-proven per AGY_VENDOR_CLI_VERSION bump because the
|
|
18
|
+
* fallback is a vendor error path, not a documented mode (R-2').
|
|
19
|
+
*/
|
|
20
|
+
export function agyTokenPath(profileHome) {
|
|
21
|
+
return join(profileHome, ".gemini", "antigravity-cli", "antigravity-oauth-token");
|
|
22
|
+
}
|
|
23
|
+
/** The token must be a regular FILE: a directory at that path is a malformed
|
|
24
|
+
* profile, not a login, and must refuse rather than route (Ф0 review #11). */
|
|
25
|
+
export function agyTokenFilePresent(profileHome) {
|
|
26
|
+
try {
|
|
27
|
+
return statSync(agyTokenPath(profileHome)).isFile();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Exact strict-profile env: the profile HOME selects the vendor's whole
|
|
35
|
+
* config root (`$HOME/.gemini/...`) — agy has no config-dir env var, HOME is
|
|
36
|
+
* the single lever. `USERPROFILE` mirrors HOME for the win32 resolver, the
|
|
37
|
+
* auto-updater is pinned off so the closed vendor binary cannot replace
|
|
38
|
+
* itself mid-run, and the provider scrub drops every API-key route
|
|
39
|
+
* (`GEMINI_API_KEY` included) so a native subscription run can never silently
|
|
40
|
+
* turn metered (INV-061).
|
|
41
|
+
*
|
|
42
|
+
* Unlike Cursor — whose mutable state is separately relocatable via
|
|
43
|
+
* `CURSOR_CONFIG_DIR`, so a run keeps state in its LANE home and reads auth
|
|
44
|
+
* from the profile — agy has exactly one lever. Overriding HOME therefore
|
|
45
|
+
* moves the vendor's conversations/brain/cache into the profile HOME too, and
|
|
46
|
+
* the per-lane home is unused for agy runs. Deliberate, not an oversight: a
|
|
47
|
+
* lane-scoped `.gemini` would be a dead directory the vendor never reads.
|
|
48
|
+
* What holds today is per-lane RESUME: a lane replays its own vendor
|
|
49
|
+
* conversation by id (`--conversation`, INV-137). Nothing scopes those
|
|
50
|
+
* conversations to a lane yet — the vendor's project mechanism
|
|
51
|
+
* (`--new-project`/`--project`, Л-19) is not wired here — so one profile HOME
|
|
52
|
+
* accumulates every thread's vendor state, and conversations are NOT scoped per
|
|
53
|
+
* chat thread.
|
|
54
|
+
*/
|
|
55
|
+
export function agyProfileRunEnv(profileHome, specEnv = {}) {
|
|
56
|
+
const home = canonicalAgyProfileHome(profileHome);
|
|
57
|
+
return {
|
|
58
|
+
...specEnv,
|
|
59
|
+
...providerScrubEnv(),
|
|
60
|
+
HOME: home,
|
|
61
|
+
USERPROFILE: home,
|
|
62
|
+
AGY_CLI_DISABLE_AUTO_UPDATE: "true",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* INV-135 strict profile routing: an agy profile is exactly its
|
|
67
|
+
* `config_dir_login` HOME with a present vendor token file, or a typed
|
|
68
|
+
* refusal. There is NO engine-default agy credential (owner decision Л-4),
|
|
69
|
+
* so no fallback ladder exists to fall into.
|
|
70
|
+
*/
|
|
71
|
+
export function resolveAgyProfileRoute(profile, specEnv = {}) {
|
|
72
|
+
if (profile.credential_kind !== "config_dir_login")
|
|
73
|
+
return {
|
|
74
|
+
refusal: `credential profile "${profile.profile_id}": agy supports only the config_dir_login transport (a named profile HOME)`,
|
|
75
|
+
};
|
|
76
|
+
try {
|
|
77
|
+
const home = canonicalAgyProfileHome(profile.isolation_locator ?? "");
|
|
78
|
+
if (!agyTokenFilePresent(home))
|
|
79
|
+
return {
|
|
80
|
+
refusal: `credential profile "${profile.profile_id}" has no Antigravity login in its profile HOME (run \`claudexor profiles login agy ${profile.profile_id}\` first)`,
|
|
81
|
+
};
|
|
82
|
+
return { home, env: agyProfileRunEnv(home, specEnv) };
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
return { refusal: err instanceof Error ? err.message : String(err) };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Quota-free liveness probe: `agy -p "/model" --output-format json` answers
|
|
90
|
+
* from the CLI without spending a turn (vendor 1.1.11+ print-mode
|
|
91
|
+
* slash-commands). SUCCESS proves the profile's token authenticates in the
|
|
92
|
+
* exact env its runs will spawn with (INV-067); an auth error is an honest
|
|
93
|
+
* logged-out/revoked verdict, and a spawn/parse failure stays `unknown`.
|
|
94
|
+
*/
|
|
95
|
+
export async function defaultAgyModelProbe(env, abortSignal) {
|
|
96
|
+
try {
|
|
97
|
+
const r = await runCapture(AGY_BIN(), ["-p", "/model", "--output-format", "json"], {
|
|
98
|
+
timeoutMs: 30_000,
|
|
99
|
+
env,
|
|
100
|
+
abortSignal,
|
|
101
|
+
cancelSignal: "SIGTERM",
|
|
102
|
+
});
|
|
103
|
+
const parsed = JSON.parse(r.stdout.trim() || "{}");
|
|
104
|
+
if (parsed?.status === "SUCCESS")
|
|
105
|
+
return {
|
|
106
|
+
kind: "authenticated",
|
|
107
|
+
modelId: typeof parsed?.command?.data?.id === "string" ? parsed.command.data.id : null,
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
kind: "unauthenticated",
|
|
111
|
+
detail: redactSecrets(String(parsed?.error ?? "authentication required")).slice(0, 300),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
return {
|
|
116
|
+
kind: "probe_failed",
|
|
117
|
+
detail: redactSecrets(err instanceof Error ? err.message : String(err)).slice(0, 300),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Doctor projection for one agy profile (INV-135): the SAME route resolution
|
|
123
|
+
* the run uses, then the quota-free live probe. A valid profile must admit
|
|
124
|
+
* the route even though agy has no default store at all — the orchestrator
|
|
125
|
+
* consults THIS probe for pinned routing.
|
|
126
|
+
*/
|
|
127
|
+
export async function probeAgyCredentialProfile(profile, deps = { runModelProbe: defaultAgyModelProbe }, abortSignal) {
|
|
128
|
+
const base = { profile_id: profile.profile_id, harness_id: "agy" };
|
|
129
|
+
const route = resolveAgyProfileRoute(profile);
|
|
130
|
+
if ("refusal" in route)
|
|
131
|
+
return CredentialProfileStatusSchema.parse({
|
|
132
|
+
...base,
|
|
133
|
+
availability: "unavailable",
|
|
134
|
+
verification: "not_run",
|
|
135
|
+
detail: route.refusal,
|
|
136
|
+
});
|
|
137
|
+
const probe = await deps.runModelProbe(route.env, abortSignal);
|
|
138
|
+
if (probe.kind === "authenticated")
|
|
139
|
+
return CredentialProfileStatusSchema.parse({
|
|
140
|
+
...base,
|
|
141
|
+
availability: "available",
|
|
142
|
+
verification: "passed",
|
|
143
|
+
detail: `Antigravity login verified in the profile HOME${probe.modelId ? ` (model ${probe.modelId})` : ""}`,
|
|
144
|
+
last_verified_at: nowIso(),
|
|
145
|
+
});
|
|
146
|
+
if (probe.kind === "unauthenticated")
|
|
147
|
+
return CredentialProfileStatusSchema.parse({
|
|
148
|
+
...base,
|
|
149
|
+
availability: "unavailable",
|
|
150
|
+
verification: "failed",
|
|
151
|
+
detail: `Antigravity token present but not accepted: ${probe.detail}`,
|
|
152
|
+
});
|
|
153
|
+
return CredentialProfileStatusSchema.parse({
|
|
154
|
+
...base,
|
|
155
|
+
availability: "unknown",
|
|
156
|
+
verification: "not_run",
|
|
157
|
+
detail: probe.detail,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.js","sourceRoot":"","sources":["../src/profile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PinnedVendorCliVersion } from "@claudexor/util";
|
|
2
|
+
/**
|
|
3
|
+
* The Antigravity CLI (`agy`) version this adapter's recorded fixtures,
|
|
4
|
+
* manifest `known_models` list, and file-token-fallback proof were captured
|
|
5
|
+
* against. Unlike the claude/codex constants this is NOT an npm install pin —
|
|
6
|
+
* agy ships as a closed Google binary with no npm artifact (the installer
|
|
7
|
+
* uses the vendor's official script, cursor-style, `human_observed`). It IS
|
|
8
|
+
* the verification stamp: `known_models_verified_against` reads it, fixture
|
|
9
|
+
* provenance records it, and the doctor discloses drift when the installed
|
|
10
|
+
* binary self-updates past it. The profile file-token fallback (the whole
|
|
11
|
+
* multi-account mechanism) is re-proven per bump of this constant — it is a
|
|
12
|
+
* vendor ERROR path, not a documented mode (PLAN Л-15/R-2').
|
|
13
|
+
*/
|
|
14
|
+
export declare const AGY_VENDOR_CLI_VERSION: PinnedVendorCliVersion;
|
|
15
|
+
//# sourceMappingURL=vendor-cli-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor-cli-version.d.ts","sourceRoot":"","sources":["../src/vendor-cli-version.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAE9D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,EAAE,sBAAiC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Antigravity CLI (`agy`) version this adapter's recorded fixtures,
|
|
3
|
+
* manifest `known_models` list, and file-token-fallback proof were captured
|
|
4
|
+
* against. Unlike the claude/codex constants this is NOT an npm install pin —
|
|
5
|
+
* agy ships as a closed Google binary with no npm artifact (the installer
|
|
6
|
+
* uses the vendor's official script, cursor-style, `human_observed`). It IS
|
|
7
|
+
* the verification stamp: `known_models_verified_against` reads it, fixture
|
|
8
|
+
* provenance records it, and the doctor discloses drift when the installed
|
|
9
|
+
* binary self-updates past it. The profile file-token fallback (the whole
|
|
10
|
+
* multi-account mechanism) is re-proven per bump of this constant — it is a
|
|
11
|
+
* vendor ERROR path, not a documented mode (PLAN Л-15/R-2').
|
|
12
|
+
*/
|
|
13
|
+
export const AGY_VENDOR_CLI_VERSION = "1.1.13";
|
|
14
|
+
//# sourceMappingURL=vendor-cli-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor-cli-version.js","sourceRoot":"","sources":["../src/vendor-cli-version.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAA2B,QAAQ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@claudexor/harness-agy",
|
|
3
|
+
"version": "3.5.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "Google Antigravity CLI adapter (agy -p --output-format stream-json).",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@claudexor/util": "3.5.0",
|
|
20
|
+
"@claudexor/schema": "3.5.0",
|
|
21
|
+
"@claudexor/core": "3.5.0"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/razzant/claudexor.git",
|
|
26
|
+
"directory": "packages/harness-agy"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/razzant/claudexor#readme",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/razzant/claudexor/issues"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20.19"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"yaml": "^2.6.1"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc",
|
|
43
|
+
"typecheck": "tsc --noEmit"
|
|
44
|
+
}
|
|
45
|
+
}
|