@zeroxyz/cli 1.5.0 → 1.6.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/index.js +238 -31
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import * as nc from 'crypto';
|
|
|
6
6
|
import nc__default, { randomUUID, randomBytes as randomBytes$1, createHash } from 'crypto';
|
|
7
7
|
import os, { homedir } from 'os';
|
|
8
8
|
import y2, { stdin, stdout } from 'process';
|
|
9
|
-
import childProcess, { execFile as execFile$1 } from 'child_process';
|
|
9
|
+
import childProcess, { execFile as execFile$1, spawnSync } from 'child_process';
|
|
10
10
|
import fs5, { constants } from 'fs/promises';
|
|
11
11
|
import util2, { promisify } from 'util';
|
|
12
12
|
import fs3, { createReadStream, existsSync, readFileSync, mkdirSync, writeFileSync, chmodSync, lstatSync, readlinkSync, rmSync, readdirSync } from 'fs';
|
|
@@ -76582,7 +76582,7 @@ init_esm_shims();
|
|
|
76582
76582
|
|
|
76583
76583
|
// package.json
|
|
76584
76584
|
var package_default = {
|
|
76585
|
-
version: "1.
|
|
76585
|
+
version: "1.6.0"};
|
|
76586
76586
|
|
|
76587
76587
|
// src/app.ts
|
|
76588
76588
|
init_esm_shims();
|
|
@@ -77563,6 +77563,18 @@ var authExchangeCommand = (appContext) => new Command("exchange").description(
|
|
|
77563
77563
|
process.exitCode = 1;
|
|
77564
77564
|
}
|
|
77565
77565
|
});
|
|
77566
|
+
var ensureAuthenticated = async (client, shouldOpen = true) => {
|
|
77567
|
+
const session4 = readConfig(getConfigPath()).session;
|
|
77568
|
+
if (session4) return;
|
|
77569
|
+
process.stdout.write(
|
|
77570
|
+
"\nZero requires authentication before handing off to Claude.\n\n"
|
|
77571
|
+
);
|
|
77572
|
+
await runInteractive(client, shouldOpen);
|
|
77573
|
+
if (!readConfig(getConfigPath()).session) {
|
|
77574
|
+
process.exitCode = 1;
|
|
77575
|
+
process.exit(1);
|
|
77576
|
+
}
|
|
77577
|
+
};
|
|
77566
77578
|
var authCommand = (appContext) => {
|
|
77567
77579
|
const cmd = new Command("auth").description("Authentication commands");
|
|
77568
77580
|
cmd.addCommand(authLoginCommand(appContext));
|
|
@@ -77578,7 +77590,7 @@ init_esm_shims();
|
|
|
77578
77590
|
// ../sdk/dist/index.js
|
|
77579
77591
|
init_esm_shims();
|
|
77580
77592
|
|
|
77581
|
-
// ../sdk/dist/chunk-
|
|
77593
|
+
// ../sdk/dist/chunk-RY3VFSIE.js
|
|
77582
77594
|
init_esm_shims();
|
|
77583
77595
|
|
|
77584
77596
|
// ../../node_modules/.pnpm/viem@2.52.2_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6_zod@4.3.6/node_modules/viem/_esm/index.js
|
|
@@ -144080,7 +144092,7 @@ var Payments = class {
|
|
|
144080
144092
|
};
|
|
144081
144093
|
};
|
|
144082
144094
|
var package_default2 = {
|
|
144083
|
-
version: "0.
|
|
144095
|
+
version: "0.5.0"
|
|
144084
144096
|
};
|
|
144085
144097
|
var SDK_VERSION2 = package_default2.version;
|
|
144086
144098
|
var userWalletDtoSchema = external_exports3.object({
|
|
@@ -144726,6 +144738,11 @@ var capabilityResponseSchema = external_exports3.object({
|
|
|
144726
144738
|
lastUsedAt: external_exports3.string().nullable().optional(),
|
|
144727
144739
|
lastSuccessfullyRanAt: external_exports3.string().nullable().optional()
|
|
144728
144740
|
});
|
|
144741
|
+
var resolveCapabilityResponseSchema = external_exports3.object({
|
|
144742
|
+
capabilityId: external_exports3.string(),
|
|
144743
|
+
capabilitySlug: external_exports3.string(),
|
|
144744
|
+
matchedVia: external_exports3.enum(["exact", "template"])
|
|
144745
|
+
});
|
|
144729
144746
|
var Capabilities = class {
|
|
144730
144747
|
constructor(client) {
|
|
144731
144748
|
this.client = client;
|
|
@@ -144740,6 +144757,31 @@ var Capabilities = class {
|
|
|
144740
144757
|
},
|
|
144741
144758
|
capabilityResponseSchema
|
|
144742
144759
|
);
|
|
144760
|
+
// Resolve a raw endpoint URL + method back to the capability that owns it,
|
|
144761
|
+
// for the `zero fetch <url>` case where the client has no local search
|
|
144762
|
+
// context to match against (a memoized/cross-session URL). Returns null on
|
|
144763
|
+
// 404 — i.e. no match or an ambiguous multi-match, both of which the server
|
|
144764
|
+
// reports as 404 (resolveByUrl fails closed rather than mis-attribute).
|
|
144765
|
+
// The URL travels in the POST body so it stays out of access logs and is
|
|
144766
|
+
// never stored; the caller uses the returned capabilityId to record an
|
|
144767
|
+
// attributed run without the URL ever touching the run row (ZERO-335).
|
|
144768
|
+
resolveByUrl = async (url4, method, opts = {}) => {
|
|
144769
|
+
try {
|
|
144770
|
+
return await request2(
|
|
144771
|
+
this.client,
|
|
144772
|
+
{
|
|
144773
|
+
method: "POST",
|
|
144774
|
+
path: "/v1/capabilities/resolve",
|
|
144775
|
+
body: { url: url4, method },
|
|
144776
|
+
signal: opts.signal
|
|
144777
|
+
},
|
|
144778
|
+
resolveCapabilityResponseSchema
|
|
144779
|
+
);
|
|
144780
|
+
} catch (err) {
|
|
144781
|
+
if (err instanceof ZeroApiError && err.status === 404) return null;
|
|
144782
|
+
throw err;
|
|
144783
|
+
}
|
|
144784
|
+
};
|
|
144743
144785
|
};
|
|
144744
144786
|
var createRunResponseSchema = external_exports3.object({
|
|
144745
144787
|
runId: external_exports3.string()
|
|
@@ -145312,14 +145354,17 @@ var resolveRecordingClient = (client, opts) => {
|
|
|
145312
145354
|
const canRecord = opts.account !== void 0 || credentials.kind === "account" || credentials.kind === "session";
|
|
145313
145355
|
return { recordingClient, canRecord };
|
|
145314
145356
|
};
|
|
145315
|
-
var recordErrorFetchRun = async (client, opts, result) => {
|
|
145316
|
-
|
|
145357
|
+
var recordErrorFetchRun = async (client, opts, result, capabilityIdOverride) => {
|
|
145358
|
+
const effectiveCapId = opts.capabilityId;
|
|
145359
|
+
if (effectiveCapId === void 0) return;
|
|
145317
145360
|
const { recordingClient, canRecord } = resolveRecordingClient(client, opts);
|
|
145318
145361
|
if (!canRecord) return;
|
|
145362
|
+
const fetchOriginForRecord = opts.capabilityId === void 0 ? "direct_url" : opts.fetchOrigin;
|
|
145319
145363
|
try {
|
|
145320
145364
|
const created = await recordingClient.runs.create({
|
|
145321
|
-
capabilityId:
|
|
145365
|
+
capabilityId: effectiveCapId,
|
|
145322
145366
|
...opts.searchId && { searchId: opts.searchId },
|
|
145367
|
+
...fetchOriginForRecord && { fetchOrigin: fetchOriginForRecord },
|
|
145323
145368
|
...result.status !== null && { status: result.status },
|
|
145324
145369
|
latencyMs: result.latencyMs,
|
|
145325
145370
|
...opts.requestSchema && { requestSchema: opts.requestSchema }
|
|
@@ -145329,7 +145374,7 @@ var recordErrorFetchRun = async (client, opts, result) => {
|
|
|
145329
145374
|
} catch {
|
|
145330
145375
|
}
|
|
145331
145376
|
};
|
|
145332
|
-
var recordTimeoutRun = async (client, opts, err, startedAt, capabilityIdRequested) => {
|
|
145377
|
+
var recordTimeoutRun = async (client, opts, err, startedAt, capabilityIdRequested, capabilityIdOverride) => {
|
|
145333
145378
|
const result = errorFetchResult(
|
|
145334
145379
|
startedAt,
|
|
145335
145380
|
err.message,
|
|
@@ -145366,6 +145411,11 @@ var clientFetch = async (client, url4, opts = {}) => {
|
|
|
145366
145411
|
const startedAt = Date.now();
|
|
145367
145412
|
const capabilityIdRequested = opts.capabilityId !== void 0;
|
|
145368
145413
|
const method = opts.method ?? (opts.body !== void 0 ? "POST" : "GET");
|
|
145414
|
+
const { canRecord: canRecordForResolve } = resolveRecordingClient(
|
|
145415
|
+
client,
|
|
145416
|
+
opts
|
|
145417
|
+
);
|
|
145418
|
+
const resolvePromise = !capabilityIdRequested && canRecordForResolve ? client.capabilities.resolveByUrl(redactUrl2(url4), method).catch(() => null) : Promise.resolve(null);
|
|
145369
145419
|
const probeHeaders = withDefaultContentType(opts.headers, opts.body);
|
|
145370
145420
|
const requestInit = {
|
|
145371
145421
|
method,
|
|
@@ -145557,7 +145607,15 @@ var clientFetch = async (client, url4, opts = {}) => {
|
|
|
145557
145607
|
else if (closeFailed)
|
|
145558
145608
|
skipReasons.push(FETCH_SKIP_REASONS.mppSessionCloseFailedNotRecorded);
|
|
145559
145609
|
}
|
|
145560
|
-
|
|
145610
|
+
const resolvedCap = await resolvePromise;
|
|
145611
|
+
const effectiveCapabilityId = opts.capabilityId ?? resolvedCap?.capabilityId;
|
|
145612
|
+
const capabilityResolution = !capabilityIdRequested && canRecordForResolve ? resolvedCap !== null ? {
|
|
145613
|
+
resolved: true,
|
|
145614
|
+
capabilityId: resolvedCap.capabilityId,
|
|
145615
|
+
capabilitySlug: resolvedCap.capabilitySlug,
|
|
145616
|
+
matchedVia: resolvedCap.matchedVia
|
|
145617
|
+
} : { resolved: false } : void 0;
|
|
145618
|
+
if (effectiveCapabilityId !== void 0 && !paidButStill402 && !closeFailed) {
|
|
145561
145619
|
const { recordingClient, canRecord } = resolveRecordingClient(client, opts);
|
|
145562
145620
|
if (!canRecord) {
|
|
145563
145621
|
skipReasons.push("no_credentials");
|
|
@@ -145577,8 +145635,11 @@ var clientFetch = async (client, url4, opts = {}) => {
|
|
|
145577
145635
|
}
|
|
145578
145636
|
}
|
|
145579
145637
|
const result2 = await recordingClient.runs.create({
|
|
145580
|
-
capabilityId:
|
|
145638
|
+
capabilityId: effectiveCapabilityId,
|
|
145581
145639
|
searchId: opts.searchId,
|
|
145640
|
+
// Auto-resolved runs are always direct_url — they only fire when
|
|
145641
|
+
// no capabilityId was supplied (the direct_url path by definition).
|
|
145642
|
+
...opts.capabilityId === void 0 ? { fetchOrigin: "direct_url" } : opts.fetchOrigin && { fetchOrigin: opts.fetchOrigin },
|
|
145582
145643
|
status: response.status,
|
|
145583
145644
|
latencyMs,
|
|
145584
145645
|
...opts.requestSchema && { requestSchema: opts.requestSchema },
|
|
@@ -145611,7 +145672,7 @@ var clientFetch = async (client, url4, opts = {}) => {
|
|
|
145611
145672
|
message: "Failed to record run for fetch",
|
|
145612
145673
|
meta: {
|
|
145613
145674
|
url: redactUrl2(url4),
|
|
145614
|
-
capabilityId:
|
|
145675
|
+
capabilityId: effectiveCapabilityId,
|
|
145615
145676
|
error: errorMessage22,
|
|
145616
145677
|
errorCode: code
|
|
145617
145678
|
}
|
|
@@ -145639,6 +145700,8 @@ var clientFetch = async (client, url4, opts = {}) => {
|
|
|
145639
145700
|
result.runTrackingSkipped = skipReasons;
|
|
145640
145701
|
}
|
|
145641
145702
|
if (warnings.length > 0) result.warnings = warnings;
|
|
145703
|
+
if (capabilityResolution !== void 0)
|
|
145704
|
+
result.capabilityResolution = capabilityResolution;
|
|
145642
145705
|
return result;
|
|
145643
145706
|
};
|
|
145644
145707
|
var searchResultSchema = external_exports3.object({
|
|
@@ -146595,8 +146658,8 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
146595
146658
|
});
|
|
146596
146659
|
const matchCtx = explicitCapabilityCtx ?? urlCtx;
|
|
146597
146660
|
const capabilityId = options.capability ?? matchCtx?.capabilityId ?? null;
|
|
146598
|
-
|
|
146599
|
-
|
|
146661
|
+
let capabilityUid = matchCtx?.capabilityUid ?? null;
|
|
146662
|
+
let capabilitySlug = matchCtx?.capabilitySlug ?? null;
|
|
146600
146663
|
const searchId = matchCtx?.searchId;
|
|
146601
146664
|
const resultRank = matchCtx?.resultRank;
|
|
146602
146665
|
const fetchOrigin = matchCtx ? "from_search" : options.capability ? "direct_slug" : "direct_url";
|
|
@@ -146607,23 +146670,10 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
146607
146670
|
"no wallet configured (run `zero auth login`, or `zero wallet set <key>` / set ZERO_PRIVATE_KEY)"
|
|
146608
146671
|
);
|
|
146609
146672
|
}
|
|
146610
|
-
if (!capabilityId) {
|
|
146673
|
+
if (!capabilityId && !walletAddress) {
|
|
146611
146674
|
cliSkipReasons.push(
|
|
146612
146675
|
"no capability resolved \u2014 pass --capability <uid|slug> or run `zero search` first so the URL can be matched"
|
|
146613
146676
|
);
|
|
146614
|
-
if (!options.capability) {
|
|
146615
|
-
const lastSearch = stateService.loadLastSearch();
|
|
146616
|
-
const cached2 = lastSearch?.capabilities ?? [];
|
|
146617
|
-
analyticsService.capture("capability_resolution_missed", {
|
|
146618
|
-
url: redactUrl(resolvedUrl),
|
|
146619
|
-
method,
|
|
146620
|
-
hasLastSearch: lastSearch !== null,
|
|
146621
|
-
lastSearchSize: cached2.length,
|
|
146622
|
-
lastSearchHasTemplates: cached2.some(
|
|
146623
|
-
(c) => Boolean(c.urlTemplate)
|
|
146624
|
-
)
|
|
146625
|
-
});
|
|
146626
|
-
}
|
|
146627
146677
|
}
|
|
146628
146678
|
let requestSchema;
|
|
146629
146679
|
if (typeof resolvedBody === "string") {
|
|
@@ -146659,6 +146709,11 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
146659
146709
|
// and omitting here keeps result.runTrackingSkipped clean.
|
|
146660
146710
|
...capabilityId && walletAddress && { capabilityId },
|
|
146661
146711
|
...searchId && { searchId },
|
|
146712
|
+
// Stamp how the agent arrived (from_search | direct_slug |
|
|
146713
|
+
// direct_url) onto the run's metadata so direct execution is
|
|
146714
|
+
// distinguishable from search-driven runs server-side. Only
|
|
146715
|
+
// when a run is actually recorded (capabilityId + wallet).
|
|
146716
|
+
...capabilityId && walletAddress && { fetchOrigin },
|
|
146662
146717
|
...requestSchema && { requestSchema },
|
|
146663
146718
|
deriveRunMetadata: ({ bodyRaw: bodyRaw2, bodyEncoding: bodyEncoding2 }) => {
|
|
146664
146719
|
if (bodyRaw2 && bodyEncoding2 !== "base64") {
|
|
@@ -146693,7 +146748,8 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
146693
146748
|
upstreamError,
|
|
146694
146749
|
warnings: sdkWarnings,
|
|
146695
146750
|
runTrackingSkipped: sdkSkipReasons,
|
|
146696
|
-
error: resultError
|
|
146751
|
+
error: resultError,
|
|
146752
|
+
capabilityResolution
|
|
146697
146753
|
} = result;
|
|
146698
146754
|
const isBinary = bodyEncoding === "base64";
|
|
146699
146755
|
const bodyBytes = isBinary && bodyRaw ? Buffer.from(bodyRaw, "base64") : void 0;
|
|
@@ -146765,6 +146821,36 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
146765
146821
|
log2(`Warning: ${w2}`);
|
|
146766
146822
|
}
|
|
146767
146823
|
}
|
|
146824
|
+
if (fetchOrigin === "direct_url") {
|
|
146825
|
+
if (capabilityResolution?.resolved) {
|
|
146826
|
+
capabilityUid = capabilityResolution.capabilityId ?? capabilityUid;
|
|
146827
|
+
capabilitySlug = capabilityResolution.capabilitySlug ?? capabilitySlug;
|
|
146828
|
+
analyticsService.capture("capability_resolution_recovered", {
|
|
146829
|
+
url: redactUrl(resolvedUrl),
|
|
146830
|
+
method,
|
|
146831
|
+
capabilityUid: capabilityResolution.capabilityId,
|
|
146832
|
+
capabilitySlug: capabilityResolution.capabilitySlug,
|
|
146833
|
+
matchedVia: capabilityResolution.matchedVia
|
|
146834
|
+
});
|
|
146835
|
+
} else {
|
|
146836
|
+
if (walletAddress && !runId) {
|
|
146837
|
+
cliSkipReasons.push(
|
|
146838
|
+
"no capability resolved \u2014 pass --capability <uid|slug> or run `zero search` first so the URL can be matched"
|
|
146839
|
+
);
|
|
146840
|
+
}
|
|
146841
|
+
const lastSearch = stateService.loadLastSearch();
|
|
146842
|
+
const cached2 = lastSearch?.capabilities ?? [];
|
|
146843
|
+
analyticsService.capture("capability_resolution_missed", {
|
|
146844
|
+
url: redactUrl(resolvedUrl),
|
|
146845
|
+
method,
|
|
146846
|
+
hasLastSearch: lastSearch !== null,
|
|
146847
|
+
lastSearchSize: cached2.length,
|
|
146848
|
+
lastSearchHasTemplates: cached2.some(
|
|
146849
|
+
(c) => Boolean(c.urlTemplate)
|
|
146850
|
+
)
|
|
146851
|
+
});
|
|
146852
|
+
}
|
|
146853
|
+
}
|
|
146768
146854
|
analyticsService.capture("fetch_executed", {
|
|
146769
146855
|
url: redactUrl(resolvedUrl),
|
|
146770
146856
|
status: status ?? void 0,
|
|
@@ -146897,6 +146983,8 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
146897
146983
|
` --value 1-5 Was it worth the price? (1 = overpriced, 5 = great deal)`,
|
|
146898
146984
|
` --reliability 1-5 Did it respond quickly and without errors? (1 = flaky, 5 = rock solid)`,
|
|
146899
146985
|
` --content Free-text is optional but helps other agents pick the best capability.`,
|
|
146986
|
+
` Published publicly \u2014 do not include personal or identifying`,
|
|
146987
|
+
` information (names, emails, phone numbers, addresses, keys, SSNs).`,
|
|
146900
146988
|
``
|
|
146901
146989
|
].join("\n")
|
|
146902
146990
|
);
|
|
@@ -147203,10 +147291,22 @@ var buildResponseSection = (capability) => {
|
|
|
147203
147291
|
}
|
|
147204
147292
|
return [];
|
|
147205
147293
|
};
|
|
147294
|
+
var unwrapTransportEnvelope = (req) => {
|
|
147295
|
+
const input = asNode(asNode(req)?.input);
|
|
147296
|
+
if (!input || input.type !== "http") return req;
|
|
147297
|
+
const body = input.body;
|
|
147298
|
+
const hasBody = body !== void 0 && body !== null && !(typeof body === "object" && Object.keys(body).length === 0);
|
|
147299
|
+
if (hasBody) return body;
|
|
147300
|
+
const qp = asNode(input.queryParams);
|
|
147301
|
+
if (qp && Object.keys(qp).length > 0) return qp;
|
|
147302
|
+
return null;
|
|
147303
|
+
};
|
|
147206
147304
|
var buildVerifiedExampleSection = (capability) => {
|
|
147207
147305
|
const req = capability.example?.request;
|
|
147208
147306
|
if (req === void 0 || req === null) return [];
|
|
147209
|
-
const
|
|
147307
|
+
const shown = unwrapTransportEnvelope(req);
|
|
147308
|
+
if (shown === void 0 || shown === null) return [];
|
|
147309
|
+
const json3 = typeof shown === "string" ? shown : JSON.stringify(shown);
|
|
147210
147310
|
const truncated = json3.length > 600 ? `${json3.slice(0, 600)}\u2026` : json3;
|
|
147211
147311
|
return ["", "Verified example (request):", ` ${truncated}`];
|
|
147212
147312
|
};
|
|
@@ -147293,7 +147393,7 @@ var getCommand = (appContext) => new Command("get").description(
|
|
|
147293
147393
|
).argument(
|
|
147294
147394
|
"<identifier>",
|
|
147295
147395
|
"Position number from search results, or a capability slug"
|
|
147296
|
-
).option("--formatted", "Output formatted capability details").option(
|
|
147396
|
+
).option("--formatted", "Output formatted capability details").option("--json", "Output raw JSON to stdout (default)").option(
|
|
147297
147397
|
"--agent <name>",
|
|
147298
147398
|
"Identify your agent host for this invocation. Overrides auto-detect for this call only."
|
|
147299
147399
|
).action(async (identifier, options) => {
|
|
@@ -147330,7 +147430,7 @@ var getCommand = (appContext) => new Command("get").description(
|
|
|
147330
147430
|
const capability = await client.capabilities.get(capabilityId, {
|
|
147331
147431
|
searchId
|
|
147332
147432
|
});
|
|
147333
|
-
if (options.formatted) {
|
|
147433
|
+
if (options.formatted && !options.json) {
|
|
147334
147434
|
console.log(formatCapability(capability));
|
|
147335
147435
|
} else {
|
|
147336
147436
|
console.log(JSON.stringify(capability, null, 2));
|
|
@@ -147665,6 +147765,8 @@ Tips for a great review:
|
|
|
147665
147765
|
--value 1-5 Was it worth the price? (1 = overpriced, 5 = great deal)
|
|
147666
147766
|
--reliability 1-5 Did it respond quickly and without errors? (1 = flaky, 5 = rock solid)
|
|
147667
147767
|
--content Free-text is optional but helps other agents pick the best capability.
|
|
147768
|
+
Published publicly \u2014 do not include personal or identifying information
|
|
147769
|
+
(names, emails, phone numbers, addresses, keys, SSNs).
|
|
147668
147770
|
|
|
147669
147771
|
Examples:
|
|
147670
147772
|
zero review run_abc123 --success --accuracy 5 --value 4 --reliability 5 --content "Fast, accurate translation"
|
|
@@ -147834,6 +147936,109 @@ Bulk review complete: ${ok} ok, ${failed} failed`);
|
|
|
147834
147936
|
}
|
|
147835
147937
|
);
|
|
147836
147938
|
|
|
147939
|
+
// src/commands/run-command.ts
|
|
147940
|
+
init_esm_shims();
|
|
147941
|
+
var readSkillMd = async (webBase) => {
|
|
147942
|
+
const home = homedir();
|
|
147943
|
+
for (const dir of SKILL_DIRS) {
|
|
147944
|
+
const path3 = join(home, dir, "zero", "SKILL.md");
|
|
147945
|
+
if (existsSync(path3)) return readFileSync(path3, "utf8");
|
|
147946
|
+
}
|
|
147947
|
+
const res = await fetch(`${webBase}/SKILL.md`);
|
|
147948
|
+
if (!res.ok) throw new Error(`Failed to fetch SKILL.md: ${res.status}`);
|
|
147949
|
+
return res.text();
|
|
147950
|
+
};
|
|
147951
|
+
var installCodexSkill = (skill) => {
|
|
147952
|
+
const dir = join(homedir(), ".codex", "skills", "zero");
|
|
147953
|
+
mkdirSync(dir, { recursive: true });
|
|
147954
|
+
writeFileSync(join(dir, "SKILL.md"), skill, "utf8");
|
|
147955
|
+
};
|
|
147956
|
+
var resolveZeroBinary = () => {
|
|
147957
|
+
const runner = process.env.ZERO_RUNNER;
|
|
147958
|
+
if (runner && existsSync(runner)) return runner;
|
|
147959
|
+
const fallback2 = join(homedir(), ".zero", "runtime", "bin", "zero");
|
|
147960
|
+
if (existsSync(fallback2)) return fallback2;
|
|
147961
|
+
return "zero";
|
|
147962
|
+
};
|
|
147963
|
+
var prepareHandoff = async (appContext, opts) => {
|
|
147964
|
+
const { client } = appContext.services;
|
|
147965
|
+
const webBase = appContext.env.ZERO_WEB_URL;
|
|
147966
|
+
const apiUrl = appContext.env.ZERO_API_URL;
|
|
147967
|
+
await ensureAuthenticated(client, opts.open);
|
|
147968
|
+
const skill = await readSkillMd(webBase);
|
|
147969
|
+
const zeroBin = resolveZeroBinary();
|
|
147970
|
+
const { ZERO_ENV: _drop, ...parentEnv } = process.env;
|
|
147971
|
+
const childEnv = { ...parentEnv };
|
|
147972
|
+
childEnv.ZERO_RUNNER = zeroBin !== "zero" ? zeroBin : childEnv.ZERO_RUNNER ?? "zero";
|
|
147973
|
+
if (zeroBin !== "zero") {
|
|
147974
|
+
childEnv.PATH = `${dirname(zeroBin)}:${process.env.PATH ?? ""}`;
|
|
147975
|
+
}
|
|
147976
|
+
for (let i = 0; i < 20; i++) {
|
|
147977
|
+
try {
|
|
147978
|
+
const res = await fetch(`${apiUrl}/health`, {
|
|
147979
|
+
signal: AbortSignal.timeout(2e3)
|
|
147980
|
+
});
|
|
147981
|
+
if (res.ok) break;
|
|
147982
|
+
} catch {
|
|
147983
|
+
await new Promise((r2) => setTimeout(r2, 500));
|
|
147984
|
+
}
|
|
147985
|
+
}
|
|
147986
|
+
return { skill, childEnv };
|
|
147987
|
+
};
|
|
147988
|
+
var claudeCommand = (appContext) => new Command("claude").description(
|
|
147989
|
+
"Open Claude Code with Zero capabilities pre-loaded \u2014 authenticate if needed, then hand off"
|
|
147990
|
+
).argument(
|
|
147991
|
+
"[task...]",
|
|
147992
|
+
"Initial task for Claude Code (starts an interactive session with this as the first message)"
|
|
147993
|
+
).option("--no-open", "Do not open the browser if sign-in is required").action(async (taskParts, opts) => {
|
|
147994
|
+
const { skill, childEnv } = await prepareHandoff(appContext, opts);
|
|
147995
|
+
const claudeArgs = ["--append-system-prompt", skill];
|
|
147996
|
+
const task = taskParts.join(" ").trim();
|
|
147997
|
+
if (task) claudeArgs.push(task);
|
|
147998
|
+
const result = spawnSync("claude", claudeArgs, {
|
|
147999
|
+
stdio: "inherit",
|
|
148000
|
+
env: childEnv
|
|
148001
|
+
});
|
|
148002
|
+
if (result.error) {
|
|
148003
|
+
process.stderr.write(
|
|
148004
|
+
`
|
|
148005
|
+
Failed to launch Claude Code: ${result.error.message}
|
|
148006
|
+
Make sure it is installed: https://claude.ai/download
|
|
148007
|
+
`
|
|
148008
|
+
);
|
|
148009
|
+
process.exitCode = 1;
|
|
148010
|
+
return;
|
|
148011
|
+
}
|
|
148012
|
+
if (result.status !== null) process.exitCode = result.status;
|
|
148013
|
+
});
|
|
148014
|
+
var codexCommand = (appContext) => new Command("codex").description(
|
|
148015
|
+
"Open Codex CLI with Zero capabilities pre-loaded \u2014 authenticate if needed, then hand off"
|
|
148016
|
+
).argument(
|
|
148017
|
+
"[task...]",
|
|
148018
|
+
"Initial task for Codex (starts an interactive session with this as the first message)"
|
|
148019
|
+
).option("--no-open", "Do not open the browser if sign-in is required").action(async (taskParts, opts) => {
|
|
148020
|
+
const { skill, childEnv } = await prepareHandoff(appContext, opts);
|
|
148021
|
+
installCodexSkill(skill);
|
|
148022
|
+
const codexArgs = [];
|
|
148023
|
+
const task = taskParts.join(" ").trim();
|
|
148024
|
+
if (task) codexArgs.push(task);
|
|
148025
|
+
const result = spawnSync("codex", codexArgs, {
|
|
148026
|
+
stdio: "inherit",
|
|
148027
|
+
env: childEnv
|
|
148028
|
+
});
|
|
148029
|
+
if (result.error) {
|
|
148030
|
+
process.stderr.write(
|
|
148031
|
+
`
|
|
148032
|
+
Failed to launch Codex: ${result.error.message}
|
|
148033
|
+
Make sure it is installed: https://openai.com/codex
|
|
148034
|
+
`
|
|
148035
|
+
);
|
|
148036
|
+
process.exitCode = 1;
|
|
148037
|
+
return;
|
|
148038
|
+
}
|
|
148039
|
+
if (result.status !== null) process.exitCode = result.status;
|
|
148040
|
+
});
|
|
148041
|
+
|
|
147837
148042
|
// src/commands/runs-command.ts
|
|
147838
148043
|
init_esm_shims();
|
|
147839
148044
|
var USD_ASSETS = /* @__PURE__ */ new Set(["USD", "USDC"]);
|
|
@@ -149234,6 +149439,8 @@ var createApp = (appContext) => {
|
|
|
149234
149439
|
program2.addCommand(configCommand());
|
|
149235
149440
|
program2.addCommand(termsCommand());
|
|
149236
149441
|
program2.addCommand(authCommand(appContext));
|
|
149442
|
+
program2.addCommand(claudeCommand(appContext));
|
|
149443
|
+
program2.addCommand(codexCommand(appContext));
|
|
149237
149444
|
return program2;
|
|
149238
149445
|
};
|
|
149239
149446
|
|