@claudexor/cli 3.0.3 → 3.1.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 +1 -1
- package/dist/about-command.d.ts +32 -0
- package/dist/about-command.d.ts.map +1 -0
- package/dist/about-command.js +40 -0
- package/dist/about-command.js.map +1 -0
- package/dist/acp-surface-runner.d.ts +12 -0
- package/dist/acp-surface-runner.d.ts.map +1 -1
- package/dist/acp-surface-runner.js +113 -11
- package/dist/acp-surface-runner.js.map +1 -1
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +2 -1
- package/dist/capabilities.js.map +1 -1
- package/dist/claudexord.d.ts +21 -0
- package/dist/claudexord.d.ts.map +1 -1
- package/dist/claudexord.js +96 -8
- package/dist/claudexord.js.map +1 -1
- package/dist/cli-error.d.ts +97 -0
- package/dist/cli-error.d.ts.map +1 -0
- package/dist/cli-error.js +308 -0
- package/dist/cli-error.js.map +1 -0
- package/dist/cli-io.d.ts +9 -0
- package/dist/cli-io.d.ts.map +1 -1
- package/dist/cli-io.js +10 -1
- package/dist/cli-io.js.map +1 -1
- package/dist/cli.js +105 -110
- package/dist/cli.js.map +1 -1
- package/dist/codex-device-login.d.ts +117 -0
- package/dist/codex-device-login.d.ts.map +1 -0
- package/dist/codex-device-login.js +227 -0
- package/dist/codex-device-login.js.map +1 -0
- package/dist/command-flags.d.ts.map +1 -1
- package/dist/command-flags.js +4 -3
- package/dist/command-flags.js.map +1 -1
- package/dist/command-help.d.ts +46 -0
- package/dist/command-help.d.ts.map +1 -0
- package/dist/command-help.js +92 -0
- package/dist/command-help.js.map +1 -0
- package/dist/command-registry.d.ts +2 -0
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +11 -4
- package/dist/command-registry.js.map +1 -1
- package/dist/control-services.d.ts +45 -18
- package/dist/control-services.d.ts.map +1 -1
- package/dist/control-services.js +56 -30
- package/dist/control-services.js.map +1 -1
- package/dist/credential-commands.d.ts.map +1 -1
- package/dist/credential-commands.js +44 -1
- package/dist/credential-commands.js.map +1 -1
- package/dist/daemon-outcome.d.ts +24 -0
- package/dist/daemon-outcome.d.ts.map +1 -0
- package/dist/daemon-outcome.js +59 -0
- package/dist/daemon-outcome.js.map +1 -0
- package/dist/daemon-run.d.ts +23 -4
- package/dist/daemon-run.d.ts.map +1 -1
- package/dist/daemon-run.js +66 -27
- package/dist/daemon-run.js.map +1 -1
- package/dist/delegation-belt-descriptor.d.ts +31 -13
- package/dist/delegation-belt-descriptor.d.ts.map +1 -1
- package/dist/delegation-belt-descriptor.js +43 -15
- package/dist/delegation-belt-descriptor.js.map +1 -1
- package/dist/live.d.ts +13 -1
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +56 -7
- package/dist/live.js.map +1 -1
- package/dist/mcp-runner.d.ts.map +1 -1
- package/dist/mcp-runner.js +60 -6
- package/dist/mcp-runner.js.map +1 -1
- package/dist/native-login.d.ts +10 -1
- package/dist/native-login.d.ts.map +1 -1
- package/dist/native-login.js +32 -10
- package/dist/native-login.js.map +1 -1
- package/dist/ops-commands.d.ts.map +1 -1
- package/dist/ops-commands.js +42 -51
- package/dist/ops-commands.js.map +1 -1
- package/dist/plan-implement-readiness.d.ts +32 -0
- package/dist/plan-implement-readiness.d.ts.map +1 -0
- package/dist/plan-implement-readiness.js +51 -0
- package/dist/plan-implement-readiness.js.map +1 -0
- package/dist/plugins.d.ts.map +1 -1
- package/dist/plugins.js +73 -20
- package/dist/plugins.js.map +1 -1
- package/dist/project-command.d.ts +15 -0
- package/dist/project-command.d.ts.map +1 -1
- package/dist/project-command.js +75 -20
- package/dist/project-command.js.map +1 -1
- package/dist/quota-command.d.ts.map +1 -1
- package/dist/quota-command.js +2 -6
- package/dist/quota-command.js.map +1 -1
- package/dist/release-command.d.ts.map +1 -1
- package/dist/release-command.js +31 -6
- package/dist/release-command.js.map +1 -1
- package/dist/release.d.ts +41 -10
- package/dist/release.d.ts.map +1 -1
- package/dist/release.js +70 -48
- package/dist/release.js.map +1 -1
- package/dist/repo-asset-authority.d.ts +93 -0
- package/dist/repo-asset-authority.d.ts.map +1 -0
- package/dist/repo-asset-authority.js +178 -0
- package/dist/repo-asset-authority.js.map +1 -0
- package/dist/review-command.d.ts.map +1 -1
- package/dist/review-command.js +2 -6
- package/dist/review-command.js.map +1 -1
- package/dist/settings-command.d.ts.map +1 -1
- package/dist/settings-command.js +2 -6
- package/dist/settings-command.js.map +1 -1
- package/dist/settings-service.d.ts +51 -2
- package/dist/settings-service.d.ts.map +1 -1
- package/dist/settings-service.js +126 -2
- package/dist/settings-service.js.map +1 -1
- package/dist/setup-job-store.d.ts +14 -3
- package/dist/setup-job-store.d.ts.map +1 -1
- package/dist/setup-job-store.js +24 -4
- package/dist/setup-job-store.js.map +1 -1
- package/dist/setup-jobs.d.ts +14 -4
- package/dist/setup-jobs.d.ts.map +1 -1
- package/dist/setup-jobs.js +204 -23
- package/dist/setup-jobs.js.map +1 -1
- package/dist/setup-login-inline.d.ts +69 -0
- package/dist/setup-login-inline.d.ts.map +1 -0
- package/dist/setup-login-inline.js +206 -0
- package/dist/setup-login-inline.js.map +1 -0
- package/dist/setup-login-protocol.d.ts +3 -2
- package/dist/setup-login-protocol.d.ts.map +1 -1
- package/dist/setup-login-protocol.js +16 -1
- package/dist/setup-login-protocol.js.map +1 -1
- package/dist/setup-login-runner.d.ts +9 -0
- package/dist/setup-login-runner.d.ts.map +1 -1
- package/dist/setup-login-runner.js +212 -5
- package/dist/setup-login-runner.js.map +1 -1
- package/dist/thread-delivery.d.ts.map +1 -1
- package/dist/thread-delivery.js +3 -1
- package/dist/thread-delivery.js.map +1 -1
- package/package.json +23 -23
package/dist/project-command.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { ControlProject, ControlProjectListResponse, ControlProjectOutputsResponse, } from "@claudexor/schema";
|
|
1
|
+
import { ControlProject, ControlProjectListResponse, ControlProjectOutputsResponse, ControlProjectRemoveReceipt, } from "@claudexor/schema";
|
|
2
2
|
import { print, printJson, printUsageError } from "./cli-io.js";
|
|
3
|
+
import { controlProblemError, renderCliFailure } from "./cli-error.js";
|
|
3
4
|
import { ensureDaemon } from "./daemon-run.js";
|
|
4
5
|
import { controlApiFetch } from "./live.js";
|
|
5
6
|
export async function projectCommand(args, json) {
|
|
@@ -39,6 +40,30 @@ export async function projectCommand(args, json) {
|
|
|
39
40
|
}
|
|
40
41
|
return mutateProject(json, `/projects/${encodeURIComponent(id)}/relink`, { root });
|
|
41
42
|
}
|
|
43
|
+
if (action === "remove") {
|
|
44
|
+
const id = args._[2];
|
|
45
|
+
if (!id || args._.length !== 3) {
|
|
46
|
+
return printUsageError(json, "usage: claudexor project remove <project-id>");
|
|
47
|
+
}
|
|
48
|
+
const { addr } = await ensureDaemon();
|
|
49
|
+
const response = await controlApiFetch(addr, `/projects/${encodeURIComponent(id)}`, {
|
|
50
|
+
method: "DELETE",
|
|
51
|
+
});
|
|
52
|
+
const data = await responseJson(response);
|
|
53
|
+
if (!response.ok)
|
|
54
|
+
return failure(json, response.status, data);
|
|
55
|
+
const receipt = ControlProjectRemoveReceipt.parse(data);
|
|
56
|
+
if (json)
|
|
57
|
+
printJson(receipt);
|
|
58
|
+
else {
|
|
59
|
+
print(`Removed project ${receipt.projectId} (${receipt.root}).`);
|
|
60
|
+
print(receipt.journalPartitionArchived
|
|
61
|
+
? ` Journal partition archived to ${receipt.archivedPartitionPath}.`
|
|
62
|
+
: " No journal partition to archive.");
|
|
63
|
+
print(" Run artifacts left in place for normal garbage collection.");
|
|
64
|
+
}
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
42
67
|
if (action === "outputs") {
|
|
43
68
|
const id = args._[2];
|
|
44
69
|
if (!id || args._.length > 4) {
|
|
@@ -63,25 +88,40 @@ export async function projectCommand(args, json) {
|
|
|
63
88
|
print(`${artifact.path}${artifact.kind === "directory" ? "/" : ""}${typeof artifact.bytes === "number" ? ` ${artifact.bytes}B` : ""}`);
|
|
64
89
|
return 0;
|
|
65
90
|
}
|
|
66
|
-
// Fetch a single durable output file
|
|
91
|
+
// Fetch a single durable output file. Text mode streams the raw bytes to
|
|
92
|
+
// stdout; `--json` mode must keep the exactly-one-JSON-object contract, so
|
|
93
|
+
// the bytes ride as base64 inside a self-contained envelope rather than
|
|
94
|
+
// corrupting stdout with raw (possibly binary) content (QA-060).
|
|
67
95
|
const response = await controlApiFetch(addr, `${base}/${encodeURIComponentPath(outputPath)}`);
|
|
68
96
|
if (!response.ok) {
|
|
69
97
|
const data = await responseJson(response);
|
|
70
98
|
return failure(json, response.status, data);
|
|
71
99
|
}
|
|
72
100
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
73
|
-
|
|
101
|
+
if (json) {
|
|
102
|
+
printJson({
|
|
103
|
+
ok: true,
|
|
104
|
+
projectId: id,
|
|
105
|
+
path: outputPath,
|
|
106
|
+
encoding: "base64",
|
|
107
|
+
byteLength: bytes.length,
|
|
108
|
+
content: bytes.toString("base64"),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
process.stdout.write(bytes);
|
|
113
|
+
}
|
|
74
114
|
return 0;
|
|
75
115
|
}
|
|
76
|
-
return printUsageError(json, "usage: claudexor project list|register|relink|outputs");
|
|
116
|
+
return printUsageError(json, "usage: claudexor project list|register|relink|remove|outputs");
|
|
77
117
|
}
|
|
78
118
|
catch (error) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
119
|
+
// Transport / bootstrap throwables are operational (exit 1); render them
|
|
120
|
+
// through the SAME D-7 projector so the envelope shape stays uniform.
|
|
121
|
+
return renderCliFailure(json, error, {
|
|
122
|
+
defaultCategory: "operational",
|
|
123
|
+
messagePrefix: "claudexor project:",
|
|
124
|
+
});
|
|
85
125
|
}
|
|
86
126
|
}
|
|
87
127
|
async function mutateProject(json, path, body) {
|
|
@@ -101,8 +141,19 @@ async function mutateProject(json, path, body) {
|
|
|
101
141
|
printProject(project);
|
|
102
142
|
return 0;
|
|
103
143
|
}
|
|
144
|
+
/** Human `project list` lines for one project: the id/root row plus a disclosed
|
|
145
|
+
* (never refused) nesting line per overlap with another registered project, so
|
|
146
|
+
* the operator is not confused by two projects whose files overlap (QA-072). */
|
|
147
|
+
export function projectListLines(project) {
|
|
148
|
+
const lines = [`${project.id} ${project.root}`];
|
|
149
|
+
for (const n of project.nesting) {
|
|
150
|
+
lines.push(` ${n.relation === "inside" ? "nested inside" : "contains"} ${n.root} (${n.projectId})`);
|
|
151
|
+
}
|
|
152
|
+
return lines;
|
|
153
|
+
}
|
|
104
154
|
function printProject(project) {
|
|
105
|
-
|
|
155
|
+
for (const line of projectListLines(project))
|
|
156
|
+
print(line);
|
|
106
157
|
}
|
|
107
158
|
/** Percent-encode each path segment while preserving the `/` separators the
|
|
108
159
|
* server splits on (it decodeURIComponent's the whole remainder). */
|
|
@@ -113,14 +164,18 @@ async function responseJson(response) {
|
|
|
113
164
|
const text = await response.text();
|
|
114
165
|
return text ? JSON.parse(text) : {};
|
|
115
166
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
167
|
+
/**
|
|
168
|
+
* Project-route failure envelope, aligned to the central D-7 contract
|
|
169
|
+
* (cli-error.ts): a typed `ControlProblem` body is preserved intact
|
|
170
|
+
* (code/message/retryable/fieldErrors/requiredActions/context), the exit code
|
|
171
|
+
* comes from the ONE category→exit table via `controlProblemError` (400/422 =
|
|
172
|
+
* usage 2; everything else, incl. a 409 remove conflict on a fenced id =
|
|
173
|
+
* operational 1), and the JSON envelope carries `exitCode` + `message` with the
|
|
174
|
+
* legacy `error` alias. Exported for the failure-envelope test.
|
|
175
|
+
*/
|
|
176
|
+
export function failure(json, status, data) {
|
|
177
|
+
return renderCliFailure(json, controlProblemError(status, data, `HTTP ${status}`), {
|
|
178
|
+
messagePrefix: "claudexor project:",
|
|
179
|
+
});
|
|
124
180
|
}
|
|
125
|
-
import process from "node:process";
|
|
126
181
|
//# sourceMappingURL=project-command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-command.js","sourceRoot":"","sources":["../src/project-command.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,6BAA6B,
|
|
1
|
+
{"version":3,"file":"project-command.js","sourceRoot":"","sources":["../src/project-command.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,6BAA6B,EAC7B,2BAA2B,GAE5B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAgB,EAAE,IAAa;IAClE,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IACnC,IAAI,CAAC;QACH,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/C,OAAO,eAAe,CAAC,IAAI,EAAE,+BAA+B,CAAC,CAAC;YAChE,CAAC;YACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC1D,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,OAAO,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,0BAA0B,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACtD,IAAI,IAAI;gBAAE,SAAS,CAAC,MAAM,CAAC,CAAC;iBACvB,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC;;gBACnE,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ;oBAAE,YAAY,CAAC,OAAO,CAAC,CAAC;YAClE,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjC,OAAO,eAAe,CAAC,IAAI,EAAE,mDAAmD,CAAC,CAAC;YACpF,CAAC;YACD,OAAO,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxC,OAAO,eAAe,CACpB,IAAI,EACJ,8DAA8D,CAC/D,CAAC;YACJ,CAAC;YACD,OAAO,aAAa,CAAC,IAAI,EAAE,aAAa,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACrF,CAAC;QACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrB,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,OAAO,eAAe,CAAC,IAAI,EAAE,8CAA8C,CAAC,CAAC;YAC/E,CAAC;YACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,aAAa,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE;gBAClF,MAAM,EAAE,QAAQ;aACjB,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,OAAO,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC9D,MAAM,OAAO,GAAG,2BAA2B,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACxD,IAAI,IAAI;gBAAE,SAAS,CAAC,OAAO,CAAC,CAAC;iBACxB,CAAC;gBACJ,KAAK,CAAC,mBAAmB,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;gBACjE,KAAK,CACH,OAAO,CAAC,wBAAwB;oBAC9B,CAAC,CAAC,mCAAmC,OAAO,CAAC,qBAAqB,GAAG;oBACrE,CAAC,CAAC,oCAAoC,CACzC,CAAC;gBACF,KAAK,CAAC,8DAA8D,CAAC,CAAC;YACxE,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrB,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,OAAO,eAAe,CAAC,IAAI,EAAE,6DAA6D,CAAC,CAAC;YAC9F,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,aAAa,kBAAkB,CAAC,EAAE,CAAC,UAAU,CAAC;YAC3D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,sCAAsC;gBACtC,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACnD,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC1C,IAAI,CAAC,QAAQ,CAAC,EAAE;oBAAE,OAAO,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBAC9D,MAAM,MAAM,GAAG,6BAA6B,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzD,IAAI,IAAI;oBAAE,SAAS,CAAC,MAAM,CAAC,CAAC;qBACvB,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;oBAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC;;oBAEnE,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS;wBACrC,KAAK,CACH,GAAG,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GACzD,OAAO,QAAQ,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAChE,EAAE,CACH,CAAC;gBACN,OAAO,CAAC,CAAC;YACX,CAAC;YACD,yEAAyE;YACzE,2EAA2E;YAC3E,wEAAwE;YACxE,iEAAiE;YACjE,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,sBAAsB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAC9F,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC1C,OAAO,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC9C,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;YACxD,IAAI,IAAI,EAAE,CAAC;gBACT,SAAS,CAAC;oBACR,EAAE,EAAE,IAAI;oBACR,SAAS,EAAE,EAAE;oBACb,IAAI,EAAE,UAAU;oBAChB,QAAQ,EAAE,QAAQ;oBAClB,UAAU,EAAE,KAAK,CAAC,MAAM;oBACxB,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;iBAClC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,eAAe,CAAC,IAAI,EAAE,8DAA8D,CAAC,CAAC;IAC/F,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yEAAyE;QACzE,sEAAsE;QACtE,OAAO,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE;YACnC,eAAe,EAAE,aAAa;YAC9B,aAAa,EAAE,oBAAoB;SACpC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,IAAa,EAAE,IAAY,EAAE,IAAa;IACrE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE;QACjD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,OAAO,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,IAAI;QAAE,SAAS,CAAC,OAAO,CAAC,CAAC;;QACxB,YAAY,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;gFAEgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,OAA2B;IAC1D,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CACR,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,SAAS,GAAG,CAC5F,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,OAA2B;IAC/C,KAAK,MAAM,IAAI,IAAI,gBAAgB,CAAC,OAAO,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,CAAC;AAC5D,CAAC;AAED;sEACsE;AACtE,SAAS,sBAAsB,CAAC,OAAe;IAC7C,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,QAAkB;IAC5C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CAAC,IAAa,EAAE,MAAc,EAAE,IAAa;IAClE,OAAO,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,MAAM,EAAE,CAAC,EAAE;QACjF,aAAa,EAAE,oBAAoB;KACpC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota-command.d.ts","sourceRoot":"","sources":["../src/quota-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"quota-command.d.ts","sourceRoot":"","sources":["../src/quota-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAW5C,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BnF"}
|
package/dist/quota-command.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ControlProblem, ControlQuotaResponse } from "@claudexor/schema";
|
|
2
2
|
import { flagBool } from "./args.js";
|
|
3
3
|
import { print, printJson } from "./cli-io.js";
|
|
4
|
+
import { renderCliFailure } from "./cli-error.js";
|
|
4
5
|
import { ensureDaemon } from "./daemon-run.js";
|
|
5
6
|
import { controlApiFetch } from "./live.js";
|
|
6
7
|
import { CLAUDE_STATUSLINE_MANAGED_ARG, runClaudeStatuslineCollector, } from "./claude-statusline.js";
|
|
@@ -35,12 +36,7 @@ export async function quotaCommand(args, json) {
|
|
|
35
36
|
return 0;
|
|
36
37
|
}
|
|
37
38
|
catch (error) {
|
|
38
|
-
|
|
39
|
-
if (json)
|
|
40
|
-
printJson({ ok: false, exitCode: 1, error: message });
|
|
41
|
-
else
|
|
42
|
-
process.stderr.write(`${message}\n`);
|
|
43
|
-
return 1;
|
|
39
|
+
return renderCliFailure(json, error, { messagePrefix: "claudexor quota:" });
|
|
44
40
|
}
|
|
45
41
|
}
|
|
46
42
|
function printQuota(value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota-command.js","sourceRoot":"","sources":["../src/quota-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAgB,EAAE,IAAa;IAChE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,0BAA0B,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,6BAA6B,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACzE,MAAM,4BAA4B,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE;YACrD,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;YAChC,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE,EAAE;SACnD,CAAC,CAAC;QACH,MAAM,OAAO,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,IAAI;YAAE,SAAS,CAAC,KAAK,CAAC,CAAC;;YACtB,UAAU,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,
|
|
1
|
+
{"version":3,"file":"quota-command.js","sourceRoot":"","sources":["../src/quota-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAgB,EAAE,IAAa;IAChE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,0BAA0B,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,6BAA6B,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACzE,MAAM,4BAA4B,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE;YACrD,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;YAChC,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE,EAAE;SACnD,CAAC,CAAC;QACH,MAAM,OAAO,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,IAAI;YAAE,SAAS,CAAC,KAAK,CAAC,CAAC;;YACtB,UAAU,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,aAAa,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAoD;IACtE,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChE,KAAK,CAAC,qDAAqD,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IACD,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACvC,KAAK,CACH,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,YAAY,QAAQ,CAAC,MAAM,cAAc,QAAQ,CAAC,SAAS,aAAa,QAAQ,CAAC,WAAW,EAAE,CAC1H,CAAC;QACF,KAAK,MAAM,UAAU,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC9C,MAAM,IAAI,GACR,UAAU,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;YAC9F,KAAK,CACH,KAAK,UAAU,CAAC,KAAK,UAAU,IAAI,UAAU,UAAU,CAAC,SAAS,IAAI,SAAS,aAAa,UAAU,CAAC,cAAc,IAAI,MAAM,EAAE,CACjI,CAAC;QACJ,CAAC;IACH,CAAC;IACD,8EAA8E;IAC9E,2EAA2E;IAC3E,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,SAAS,EAAE,CAAC;QACxF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,KAAK,CAAC,GAAG,OAAO,mBAAmB,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-command.d.ts","sourceRoot":"","sources":["../src/release-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"release-command.d.ts","sourceRoot":"","sources":["../src/release-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAuB5C;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA6DrF"}
|
package/dist/release-command.js
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import { print, printJson, printUsageError } from "./cli-io.js";
|
|
2
2
|
import { checkName, checkRuntimeUpdate, releaseStats } from "./release.js";
|
|
3
|
+
import { connectDaemonIfRunning } from "./daemon-run.js";
|
|
4
|
+
import { handshakeControlApi } from "./live.js";
|
|
5
|
+
/**
|
|
6
|
+
* The AUTHORITATIVE running-engine version for `release check` (QA-033a): the
|
|
7
|
+
* live daemon handshake identity. A read-only check must NEVER boot a daemon,
|
|
8
|
+
* so a stopped daemon returns null (engine unknown) rather than being silently
|
|
9
|
+
* replaced by the CLI package version.
|
|
10
|
+
*/
|
|
11
|
+
async function resolveRunningEngineVersion() {
|
|
12
|
+
try {
|
|
13
|
+
const conn = await connectDaemonIfRunning();
|
|
14
|
+
if (!conn)
|
|
15
|
+
return null;
|
|
16
|
+
const { engineVersion } = await handshakeControlApi(conn.addr);
|
|
17
|
+
return engineVersion;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
3
23
|
/**
|
|
4
24
|
* `claudexor release <sub>` dispatch, kept out of cli.ts so the top-level
|
|
5
25
|
* switch stays thin (complexity ratchet). Three read-only subcommands:
|
|
@@ -31,7 +51,8 @@ export async function releaseCommand(args, json) {
|
|
|
31
51
|
return 0;
|
|
32
52
|
}
|
|
33
53
|
if (sub === "check") {
|
|
34
|
-
const
|
|
54
|
+
const runningEngineVersion = await resolveRunningEngineVersion();
|
|
55
|
+
const check = await checkRuntimeUpdate({ runningEngineVersion });
|
|
35
56
|
if (json) {
|
|
36
57
|
printJson(check);
|
|
37
58
|
}
|
|
@@ -39,14 +60,17 @@ export async function releaseCommand(args, json) {
|
|
|
39
60
|
print(`engine runtime update check unavailable: ${check.detail}`);
|
|
40
61
|
}
|
|
41
62
|
else if (check.updateAvailable) {
|
|
42
|
-
print(`engine runtime ${check.latestVersion} available
|
|
63
|
+
print(`engine runtime ${check.latestVersion} available. ${check.detail}.`);
|
|
43
64
|
if (check.notes)
|
|
44
65
|
print(` notes: ${check.notes}`);
|
|
45
|
-
|
|
46
|
-
|
|
66
|
+
// QA-033c: honest to what 3.1.0 ships. The macOS app offers an in-app
|
|
67
|
+
// update flow; npm users update the CLI package themselves. No copy
|
|
68
|
+
// claims a silent auto-install the running engine cannot perform.
|
|
69
|
+
print(" The macOS app offers an engine update flow (Settings → check for updates).");
|
|
70
|
+
print(" npm users update the CLI with `npm install -g claudexor@latest`.");
|
|
47
71
|
}
|
|
48
72
|
else {
|
|
49
|
-
print(
|
|
73
|
+
print(`${check.detail}.`);
|
|
50
74
|
}
|
|
51
75
|
return 0;
|
|
52
76
|
}
|
|
@@ -59,7 +83,8 @@ export async function releaseCommand(args, json) {
|
|
|
59
83
|
print("install counter (owner-facing; no telemetry):");
|
|
60
84
|
print(` GitHub: ${stats.github.detail}`);
|
|
61
85
|
for (const asset of stats.github.perAsset) {
|
|
62
|
-
|
|
86
|
+
const tag = asset.appInstaller ? "install" : "tooling";
|
|
87
|
+
print(` ${asset.downloads}\t${asset.name}\t(${tag})`);
|
|
63
88
|
}
|
|
64
89
|
print(` npm: ${stats.npm.detail}`);
|
|
65
90
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-command.js","sourceRoot":"","sources":["../src/release-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"release-command.js","sourceRoot":"","sources":["../src/release-command.ts"],"names":[],"mappings":"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"}
|
package/dist/release.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RuntimeUpdateAuthority, type SignedRuntimeManifest } from "@claudexor/util";
|
|
1
2
|
export type NameAvailability = "free" | "taken" | "unknown";
|
|
2
3
|
export interface NameCheck {
|
|
3
4
|
registry: string;
|
|
@@ -18,16 +19,26 @@ export declare const NPM_PACKAGE = "claudexor";
|
|
|
18
19
|
/** Injectable fetch so the commands are honestly testable with no live network
|
|
19
20
|
* (tests pass a stub; production defaults to the global fetch). */
|
|
20
21
|
export type FetchLike = typeof fetch;
|
|
21
|
-
/** The runtime manifest published beside the closure tarball on each release
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
notes: string | null;
|
|
28
|
-
}
|
|
22
|
+
/** The runtime manifest published beside the closure tarball on each release is
|
|
23
|
+
* the SIGNED contract from @claudexor/util (D-2). `claudexor release check`
|
|
24
|
+
* verifies it FAIL-CLOSED against the pinned runtime-update authority: an
|
|
25
|
+
* unsigned/unknown-key/tampered/malformed manifest degrades to
|
|
26
|
+
* `source: "unavailable"`, never a false "update available". */
|
|
27
|
+
export type RuntimeManifest = SignedRuntimeManifest;
|
|
29
28
|
export interface RuntimeUpdateCheck {
|
|
29
|
+
/** The version the update decision compares against: the RUNNING engine when a
|
|
30
|
+
* daemon handshake resolved it, else the CLI package version (QA-033a). Its
|
|
31
|
+
* source is disclosed in `runningEngineSource`. */
|
|
30
32
|
currentVersion: string;
|
|
33
|
+
/** The executing CLI package version — always the `@claudexor/cli` constant,
|
|
34
|
+
* never relabelled as the running engine. */
|
|
35
|
+
cliVersion: string;
|
|
36
|
+
/** The live daemon engine version from the handshake; null when no daemon was
|
|
37
|
+
* reachable (npm-only user or a stopped daemon). */
|
|
38
|
+
runningEngineVersion: string | null;
|
|
39
|
+
/** Where `runningEngineVersion` came from: "handshake" (authoritative live
|
|
40
|
+
* process identity) or "unavailable" (no daemon reached). */
|
|
41
|
+
runningEngineSource: "handshake" | "unavailable";
|
|
31
42
|
latestVersion: string | null;
|
|
32
43
|
updateAvailable: boolean;
|
|
33
44
|
minAppVersion: string | null;
|
|
@@ -44,14 +55,31 @@ export interface RuntimeUpdateCheck {
|
|
|
44
55
|
*/
|
|
45
56
|
export declare function checkRuntimeUpdate(opts?: {
|
|
46
57
|
fetchImpl?: FetchLike;
|
|
58
|
+
/** Legacy alias for the resolved running engine version (kept for callers/
|
|
59
|
+
* tests that pass the running version directly). */
|
|
47
60
|
currentVersion?: string;
|
|
61
|
+
/** The running engine version resolved from a live daemon handshake; null
|
|
62
|
+
* means no daemon was reachable. Wins over `currentVersion` when provided. */
|
|
63
|
+
runningEngineVersion?: string | null;
|
|
64
|
+
/** TEST-ONLY seam: the pinned runtime-update authority to verify against.
|
|
65
|
+
* Production callers never pass this — the fail-closed check is always pinned
|
|
66
|
+
* to RUNTIME_UPDATE_AUTHORITY; tests inject a fixture authority. */
|
|
67
|
+
authority?: RuntimeUpdateAuthority;
|
|
48
68
|
}): Promise<RuntimeUpdateCheck>;
|
|
49
69
|
export interface AssetDownloads {
|
|
50
70
|
name: string;
|
|
51
71
|
downloads: number;
|
|
72
|
+
/** Whether this asset counts as an app install under the shared allowlist. */
|
|
73
|
+
appInstaller: boolean;
|
|
52
74
|
}
|
|
53
75
|
export interface InstallStats {
|
|
54
76
|
github: {
|
|
77
|
+
/** Honest install count: the app-installer (DMG/ZIP) allowlist sum. This is
|
|
78
|
+
* the figure the README badge and the metrics workflow also report — the
|
|
79
|
+
* single shared asset authority (D-15/A-6). */
|
|
80
|
+
appInstallerDownloads: number | null;
|
|
81
|
+
/** Raw sum across ALL release assets (installers + tooling). Diagnostic
|
|
82
|
+
* only; kept so the owner can still see runtime-tarball/SBOM pulls. */
|
|
55
83
|
totalDownloads: number | null;
|
|
56
84
|
perAsset: AssetDownloads[];
|
|
57
85
|
releases: number | null;
|
|
@@ -63,8 +91,11 @@ export interface InstallStats {
|
|
|
63
91
|
};
|
|
64
92
|
}
|
|
65
93
|
/**
|
|
66
|
-
* Owner-facing install counter (D23): GitHub asset
|
|
67
|
-
*
|
|
94
|
+
* Owner-facing install counter (D23): GitHub release-asset downloads + the npm
|
|
95
|
+
* last-month downloads point. Read-only, no infra, no ping. The GitHub side runs
|
|
96
|
+
* through the shared asset authority (packages/cli/src/repo-asset-authority),
|
|
97
|
+
* so the app-installer figure here is byte-for-byte the same policy the daily
|
|
98
|
+
* metrics workflow uses — one allowlist, no drift (D-15 reuse-lock, audit A-6).
|
|
68
99
|
* A failed source reports null + a reason — never a fabricated zero.
|
|
69
100
|
*/
|
|
70
101
|
export declare function releaseStats(opts?: {
|
package/dist/release.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAC;AAGzB,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAC5D,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAWD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAkClE;AAoBD,mEAAmE;AACnE,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAChD,uEAAuE;AACvE,eAAO,MAAM,WAAW,cAAc,CAAC;AAEvC;mEACmE;AACnE,MAAM,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC;AAErC;;;;gEAIgE;AAChE,MAAM,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC;;uDAEmD;IACnD,cAAc,EAAE,MAAM,CAAC;IACvB;iDAC6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB;wDACoD;IACpD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;iEAC6D;IAC7D,mBAAmB,EAAE,WAAW,GAAG,aAAa,CAAC;IACjD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;kFAC8E;IAC9E,MAAM,EAAE,QAAQ,GAAG,aAAa,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAoCD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,CAAC,EAAE;IAC9C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;wDACoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;kFAC8E;IAC9E,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;wEAEoE;IACpE,SAAS,CAAC,EAAE,sBAAsB,CAAC;CACpC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4F9B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE;QACN;;uDAE+C;QAC/C,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;QACrC;+EACuE;QACvE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,QAAQ,EAAE,cAAc,EAAE,CAAC;QAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,GAAG,EAAE;QACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAuD1F"}
|
package/dist/release.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { CLAUDEXOR_VERSION } from "@claudexor/util";
|
|
1
|
+
import { CLAUDEXOR_VERSION, RUNTIME_MANIFEST_ASSET_NAME, RUNTIME_UPDATE_AUTHORITY, verifyRuntimeManifest, } from "@claudexor/util";
|
|
2
|
+
import { computeReleaseAssetTotals } from "./repo-asset-authority.js";
|
|
2
3
|
async function head(url) {
|
|
3
4
|
try {
|
|
4
5
|
const res = await fetch(url, { method: "GET" });
|
|
@@ -79,23 +80,18 @@ function compareSemver(a, b) {
|
|
|
79
80
|
return pa[i] - pb[i];
|
|
80
81
|
return 0;
|
|
81
82
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
sha256: record.sha256,
|
|
95
|
-
minAppVersion: record.minAppVersion,
|
|
96
|
-
signature: typeof record.signature === "string" ? record.signature : null,
|
|
97
|
-
notes: typeof record.notes === "string" ? record.notes : null,
|
|
98
|
-
};
|
|
83
|
+
/** Fail-closed parse: a manifest is trusted ONLY when its Ed25519 signature
|
|
84
|
+
* verifies against the pinned runtime-update authority (D-2). The second return
|
|
85
|
+
* value is an honest refusal reason for the "unavailable" detail. */
|
|
86
|
+
function parseRuntimeManifest(value, authority) {
|
|
87
|
+
const verdict = verifyRuntimeManifest(value, authority);
|
|
88
|
+
if (!verdict.ok) {
|
|
89
|
+
return {
|
|
90
|
+
manifest: null,
|
|
91
|
+
reason: `signature/shape check failed: ${verdict.reasons.join("; ")}`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return { manifest: value, reason: "" };
|
|
99
95
|
}
|
|
100
96
|
/**
|
|
101
97
|
* Read the latest release's `runtime-manifest.json` and compare it to the
|
|
@@ -104,9 +100,25 @@ function parseRuntimeManifest(value) {
|
|
|
104
100
|
*/
|
|
105
101
|
export async function checkRuntimeUpdate(opts) {
|
|
106
102
|
const fetchImpl = opts?.fetchImpl ?? fetch;
|
|
107
|
-
const
|
|
103
|
+
const authority = opts?.authority ?? RUNTIME_UPDATE_AUTHORITY;
|
|
104
|
+
const cliVersion = CLAUDEXOR_VERSION;
|
|
105
|
+
// The RUNNING engine identity is authoritative (QA-033a): an explicit
|
|
106
|
+
// handshake result wins; the legacy `currentVersion` opt is treated as the
|
|
107
|
+
// running version; absent both, the engine is unknown (no daemon reached).
|
|
108
|
+
const runningEngineVersion = opts?.runningEngineVersion !== undefined
|
|
109
|
+
? opts.runningEngineVersion
|
|
110
|
+
: (opts?.currentVersion ?? null);
|
|
111
|
+
const runningEngineSource = runningEngineVersion !== null ? "handshake" : "unavailable";
|
|
112
|
+
// The comparison never invents a running engine: when the daemon is
|
|
113
|
+
// unreachable we compare the CLI package (the honest npm-user signal) and
|
|
114
|
+
// label it as such, never as "running ... is current".
|
|
115
|
+
const comparisonVersion = runningEngineVersion ?? cliVersion;
|
|
116
|
+
const currentVersion = comparisonVersion;
|
|
108
117
|
const unavailable = (detail) => ({
|
|
109
118
|
currentVersion,
|
|
119
|
+
cliVersion,
|
|
120
|
+
runningEngineVersion,
|
|
121
|
+
runningEngineSource,
|
|
110
122
|
latestVersion: null,
|
|
111
123
|
updateAvailable: false,
|
|
112
124
|
minAppVersion: null,
|
|
@@ -122,9 +134,9 @@ export async function checkRuntimeUpdate(opts) {
|
|
|
122
134
|
if (!res.ok)
|
|
123
135
|
return unavailable(`GitHub releases API returned HTTP ${res.status}`);
|
|
124
136
|
const body = (await res.json());
|
|
125
|
-
const asset = (body.assets ?? []).find((a) => a.name ===
|
|
137
|
+
const asset = (body.assets ?? []).find((a) => a.name === RUNTIME_MANIFEST_ASSET_NAME);
|
|
126
138
|
if (!asset?.browser_download_url) {
|
|
127
|
-
return unavailable(
|
|
139
|
+
return unavailable(`latest release has no ${RUNTIME_MANIFEST_ASSET_NAME} asset yet`);
|
|
128
140
|
}
|
|
129
141
|
manifestUrl = asset.browser_download_url;
|
|
130
142
|
}
|
|
@@ -136,36 +148,54 @@ export async function checkRuntimeUpdate(opts) {
|
|
|
136
148
|
const res = await fetchImpl(manifestUrl, {
|
|
137
149
|
headers: { "User-Agent": GH_HEADERS["User-Agent"] },
|
|
138
150
|
});
|
|
139
|
-
if (!res.ok)
|
|
140
|
-
return unavailable(
|
|
141
|
-
|
|
151
|
+
if (!res.ok) {
|
|
152
|
+
return unavailable(`${RUNTIME_MANIFEST_ASSET_NAME} download returned HTTP ${res.status}`);
|
|
153
|
+
}
|
|
154
|
+
const parsed = parseRuntimeManifest(await res.json(), authority);
|
|
155
|
+
// FAIL-CLOSED (D-2): an unverified manifest is never an "available update".
|
|
156
|
+
if (!parsed.manifest)
|
|
157
|
+
return unavailable(`${RUNTIME_MANIFEST_ASSET_NAME} ${parsed.reason}`);
|
|
158
|
+
manifest = parsed.manifest;
|
|
142
159
|
}
|
|
143
160
|
catch (error) {
|
|
144
|
-
return unavailable(`could not download
|
|
161
|
+
return unavailable(`could not download ${RUNTIME_MANIFEST_ASSET_NAME} (${describeError(error)})`);
|
|
145
162
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
163
|
+
const updateAvailable = isSemver(comparisonVersion) && compareSemver(manifest.version, comparisonVersion) > 0;
|
|
164
|
+
// Honest copy that never calls the CLI package the running engine (QA-033a):
|
|
165
|
+
// when the daemon is reachable the verdict is about the running engine; when
|
|
166
|
+
// it is not, it is explicitly about the CLI package, engine unknown.
|
|
167
|
+
const detail = runningEngineVersion !== null
|
|
168
|
+
? updateAvailable
|
|
169
|
+
? `engine runtime ${manifest.version} is available (running ${runningEngineVersion}; CLI ${cliVersion})`
|
|
170
|
+
: `running engine runtime ${runningEngineVersion} is current`
|
|
171
|
+
: updateAvailable
|
|
172
|
+
? `engine runtime ${manifest.version} is available (engine not running; CLI package ${cliVersion})`
|
|
173
|
+
: `CLI package ${cliVersion} matches the latest engine runtime (engine not running)`;
|
|
149
174
|
return {
|
|
150
175
|
currentVersion,
|
|
176
|
+
cliVersion,
|
|
177
|
+
runningEngineVersion,
|
|
178
|
+
runningEngineSource,
|
|
151
179
|
latestVersion: manifest.version,
|
|
152
180
|
updateAvailable,
|
|
153
181
|
minAppVersion: manifest.minAppVersion,
|
|
154
182
|
notes: manifest.notes,
|
|
155
183
|
source: "github",
|
|
156
|
-
detail
|
|
157
|
-
? `engine runtime ${manifest.version} is available (running ${currentVersion})`
|
|
158
|
-
: `running engine runtime ${currentVersion} is current`,
|
|
184
|
+
detail,
|
|
159
185
|
};
|
|
160
186
|
}
|
|
161
187
|
/**
|
|
162
|
-
* Owner-facing install counter (D23): GitHub asset
|
|
163
|
-
*
|
|
188
|
+
* Owner-facing install counter (D23): GitHub release-asset downloads + the npm
|
|
189
|
+
* last-month downloads point. Read-only, no infra, no ping. The GitHub side runs
|
|
190
|
+
* through the shared asset authority (packages/cli/src/repo-asset-authority),
|
|
191
|
+
* so the app-installer figure here is byte-for-byte the same policy the daily
|
|
192
|
+
* metrics workflow uses — one allowlist, no drift (D-15 reuse-lock, audit A-6).
|
|
164
193
|
* A failed source reports null + a reason — never a fabricated zero.
|
|
165
194
|
*/
|
|
166
195
|
export async function releaseStats(opts) {
|
|
167
196
|
const fetchImpl = opts?.fetchImpl ?? fetch;
|
|
168
197
|
const github = {
|
|
198
|
+
appInstallerDownloads: null,
|
|
169
199
|
totalDownloads: null,
|
|
170
200
|
perAsset: [],
|
|
171
201
|
releases: null,
|
|
@@ -180,22 +210,14 @@ export async function releaseStats(opts) {
|
|
|
180
210
|
}
|
|
181
211
|
else {
|
|
182
212
|
const releases = (await res.json());
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
for (const asset of release.assets ?? []) {
|
|
187
|
-
const count = typeof asset.download_count === "number" ? asset.download_count : 0;
|
|
188
|
-
const name = typeof asset.name === "string" ? asset.name : "(unnamed)";
|
|
189
|
-
perAsset.set(name, (perAsset.get(name) ?? 0) + count);
|
|
190
|
-
total += count;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
github.totalDownloads = total;
|
|
213
|
+
const totals = computeReleaseAssetTotals(releases);
|
|
214
|
+
github.appInstallerDownloads = totals.appInstallerDownloads;
|
|
215
|
+
github.totalDownloads = totals.rawTotalDownloads;
|
|
194
216
|
github.releases = releases.length;
|
|
195
|
-
github.perAsset =
|
|
196
|
-
|
|
197
|
-
.
|
|
198
|
-
|
|
217
|
+
github.perAsset = totals.perAsset;
|
|
218
|
+
github.detail =
|
|
219
|
+
`${totals.appInstallerDownloads} app-installer downloads ` +
|
|
220
|
+
`(${totals.rawTotalDownloads} raw across all assets) in ${releases.length} releases`;
|
|
199
221
|
}
|
|
200
222
|
}
|
|
201
223
|
catch (error) {
|