@claudexor/control-api 3.1.2 → 3.2.1
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/authorization.d.ts +3 -0
- package/dist/authorization.d.ts.map +1 -0
- package/dist/authorization.js +15 -0
- package/dist/authorization.js.map +1 -0
- package/dist/binary-response.d.ts +5 -0
- package/dist/binary-response.d.ts.map +1 -0
- package/dist/binary-response.js +31 -0
- package/dist/binary-response.js.map +1 -0
- package/dist/catalog-query.d.ts +310 -0
- package/dist/catalog-query.d.ts.map +1 -0
- package/dist/catalog-query.js +36 -0
- package/dist/catalog-query.js.map +1 -0
- package/dist/daemon-server.d.ts +28 -17
- package/dist/daemon-server.d.ts.map +1 -1
- package/dist/daemon-server.js +115 -223
- package/dist/daemon-server.js.map +1 -1
- package/dist/decision-accept-risk.d.ts +36 -0
- package/dist/decision-accept-risk.d.ts.map +1 -0
- package/dist/decision-accept-risk.js +79 -0
- package/dist/decision-accept-risk.js.map +1 -0
- package/dist/decision-rerun.d.ts +2 -1
- package/dist/decision-rerun.d.ts.map +1 -1
- package/dist/decision-rerun.js +72 -48
- package/dist/decision-rerun.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/maintenance-routes.d.ts +2 -2
- package/dist/maintenance-routes.d.ts.map +1 -1
- package/dist/maintenance-routes.js +11 -10
- package/dist/maintenance-routes.js.map +1 -1
- package/dist/operation-catalog.d.ts +9 -9
- package/dist/operation-catalog.d.ts.map +1 -1
- package/dist/operation-catalog.js +22 -79
- package/dist/operation-catalog.js.map +1 -1
- package/dist/operation-draft.d.ts +3 -0
- package/dist/operation-draft.d.ts.map +1 -0
- package/dist/operation-draft.js +2 -0
- package/dist/operation-draft.js.map +1 -0
- package/dist/operation-parameters.d.ts.map +1 -1
- package/dist/operation-summaries.d.ts +3 -0
- package/dist/operation-summaries.d.ts.map +1 -0
- package/dist/operation-summaries.js +75 -0
- package/dist/operation-summaries.js.map +1 -0
- package/dist/primary-output.d.ts +3 -3
- package/dist/primary-output.d.ts.map +1 -1
- package/dist/primary-output.js +70 -19
- package/dist/primary-output.js.map +1 -1
- package/dist/problem-response.d.ts.map +1 -1
- package/dist/problem-response.js +14 -9
- package/dist/problem-response.js.map +1 -1
- package/dist/project-routes.d.ts +21 -13
- package/dist/project-routes.d.ts.map +1 -1
- package/dist/project-routes.js +80 -34
- package/dist/project-routes.js.map +1 -1
- package/dist/remote-operation-descriptors.d.ts +36 -0
- package/dist/remote-operation-descriptors.d.ts.map +1 -0
- package/dist/remote-operation-descriptors.js +35 -0
- package/dist/remote-operation-descriptors.js.map +1 -0
- package/dist/resource-routes.d.ts +4 -3
- package/dist/resource-routes.d.ts.map +1 -1
- package/dist/resource-routes.js +63 -39
- package/dist/resource-routes.js.map +1 -1
- package/dist/route-stages.d.ts +15 -0
- package/dist/route-stages.d.ts.map +1 -0
- package/dist/route-stages.js +24 -0
- package/dist/route-stages.js.map +1 -0
- package/dist/run-facts-projection.d.ts +35 -0
- package/dist/run-facts-projection.d.ts.map +1 -0
- package/dist/run-facts-projection.js +133 -0
- package/dist/run-facts-projection.js.map +1 -0
- package/dist/run-list-fingerprint.d.ts +7 -0
- package/dist/run-list-fingerprint.d.ts.map +1 -0
- package/dist/run-list-fingerprint.js +68 -0
- package/dist/run-list-fingerprint.js.map +1 -0
- package/dist/run-record.d.ts +4 -0
- package/dist/run-record.d.ts.map +1 -1
- package/dist/run-record.js.map +1 -1
- package/dist/run-retry-routes.d.ts +3 -2
- package/dist/run-retry-routes.d.ts.map +1 -1
- package/dist/run-retry-routes.js +103 -47
- package/dist/run-retry-routes.js.map +1 -1
- package/dist/run-start.d.ts +13 -1
- package/dist/run-start.d.ts.map +1 -1
- package/dist/run-start.js +85 -18
- package/dist/run-start.js.map +1 -1
- package/dist/run-timeline.d.ts.map +1 -1
- package/dist/run-timeline.js +16 -9
- package/dist/run-timeline.js.map +1 -1
- package/dist/thread-lifecycle-routes.d.ts +1 -1
- package/dist/thread-lifecycle-routes.d.ts.map +1 -1
- package/dist/thread-lifecycle-routes.js +3 -4
- package/dist/thread-lifecycle-routes.js.map +1 -1
- package/dist/thread-mutation.d.ts +6 -0
- package/dist/thread-mutation.d.ts.map +1 -1
- package/dist/thread-mutation.js +23 -0
- package/dist/thread-mutation.js.map +1 -1
- package/dist/thread-plan-answer.d.ts +16 -0
- package/dist/thread-plan-answer.d.ts.map +1 -0
- package/dist/thread-plan-answer.js +69 -0
- package/dist/thread-plan-answer.js.map +1 -0
- package/dist/thread-projection.d.ts.map +1 -1
- package/dist/thread-projection.js +10 -0
- package/dist/thread-projection.js.map +1 -1
- package/dist/thread-recovery.d.ts +54 -0
- package/dist/thread-recovery.d.ts.map +1 -0
- package/dist/thread-recovery.js +71 -0
- package/dist/thread-recovery.js.map +1 -0
- package/dist/thread-turn-routes.d.ts +23 -9
- package/dist/thread-turn-routes.d.ts.map +1 -1
- package/dist/thread-turn-routes.js +92 -55
- package/dist/thread-turn-routes.js.map +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/** Human one-line summaries keyed by `${method} ${path}`. */
|
|
2
|
+
export const OPERATION_SUMMARIES = {
|
|
3
|
+
"POST /v2/uploads": "Create a single-request streaming upload session for an attachment of the declared size.",
|
|
4
|
+
"PUT /v2/uploads/:id/bytes": "Stream the complete declared byte body in ONE request. The store is single-shot: a short, oversized, or interrupted PUT cancels the upload and discards partial bytes — retry by creating a new upload and resending from byte zero. Not resumable.",
|
|
5
|
+
"GET /v2/uploads/:id": "Read an upload session's status and received byte count (diagnostic on a cancelled upload, not a resumable offset).",
|
|
6
|
+
"DELETE /v2/uploads/:id": "Abort and discard an in-progress upload session.",
|
|
7
|
+
"POST /v2/uploads/:id/finalize": "Finalize an upload into a durable attachment resource.",
|
|
8
|
+
"POST /v2/handshake": "Negotiate the control protocol major before product calls.",
|
|
9
|
+
"GET /v2/operations": "List the implemented operations (this catalog).",
|
|
10
|
+
"POST /v2/maintenance/gc": "Run retention garbage collection over expired run trees.",
|
|
11
|
+
"GET /v2/agent-capabilities": "List the agent capability catalog this engine advertises.",
|
|
12
|
+
"GET /v2/run-applicability": "Project the root-scoped Git prerequisite for every run/workspace shape.",
|
|
13
|
+
"GET /v2/global/events": "Subscribe to the global cross-project event stream (SSE).",
|
|
14
|
+
"GET /v2/quota": "Read cached per-profile harness quota snapshots.",
|
|
15
|
+
"POST /v2/quota": "Refresh and read per-profile harness quota snapshots.",
|
|
16
|
+
"GET /v2/credential-profiles": "List credential profiles per harness.",
|
|
17
|
+
"POST /v2/credential-profiles": "Create a credential profile for a harness.",
|
|
18
|
+
"PATCH /v2/credential-profiles/:harness/:profileId": "Toggle a credential profile's enabled state (the accounts Enabled row).",
|
|
19
|
+
"DELETE /v2/credential-profiles/:harness/:profileId": "Delete a harness credential profile.",
|
|
20
|
+
"GET /v2/harnesses": "List installed harnesses and their availability.",
|
|
21
|
+
"GET /v2/projects": "List registered projects (durable handles).",
|
|
22
|
+
"POST /v2/projects": "Register a project root as a durable handle.",
|
|
23
|
+
"POST /v2/projects/:id/relink": "Relink a registered project to a new root.",
|
|
24
|
+
"DELETE /v2/projects/:id": "Remove a registered project: retire the registry entry and archive its journal partition. Refused (409) while any non-purged thread or live/queued run references it; run artifacts are left to normal GC.",
|
|
25
|
+
"GET /v2/projects/:id/events": "Subscribe to a project's event stream (SSE).",
|
|
26
|
+
"GET /v2/projects/:id/outputs": "List a project's durable outputs (artifacts/).",
|
|
27
|
+
"GET /v2/projects/:id/outputs/<path>": "Fetch one durable output file from a project.",
|
|
28
|
+
"GET /v2/harnesses/:id/models": "List a harness's selectable models.",
|
|
29
|
+
"POST /v2/harnesses/:id/auth-readiness": "Re-check a harness's auth readiness (dry).",
|
|
30
|
+
"GET /v2/runs": "List a bounded, newest-first, keyset-paginated page of durable run summaries visible to the daemon.",
|
|
31
|
+
"POST /v2/runs": "Start a run and return its durable handle.",
|
|
32
|
+
"GET /v2/runs/:id": "Read a run's full detail snapshot.",
|
|
33
|
+
"POST /v2/runs/:id/retry": "Retry a run, returning a new durable handle.",
|
|
34
|
+
"GET /v2/runs/:id/run-again": "Draft a run-again request from a prior run.",
|
|
35
|
+
"POST /v2/runs/:id/apply": "Apply a run's work product to the live tree; replay of an already-delivered run is a typed idempotent no-op.",
|
|
36
|
+
"POST /v2/runs/:id/apply/check": "Dry-check whether a run's patch would apply; an already-delivered run reports the safe already-applied no-op.",
|
|
37
|
+
"GET /v2/runs/:id/artifacts": "List a run tree's technical artifacts.",
|
|
38
|
+
"GET /v2/runs/:id/artifacts/<path>": "Fetch one artifact file from a run tree.",
|
|
39
|
+
"POST /v2/runs/:id/control": "Cancel a queued or running run.",
|
|
40
|
+
"POST /v2/runs/:id/decision": "Record an operator unblock/rerun decision on a run.",
|
|
41
|
+
"GET /v2/runs/:id/events": "Replay + tail a run's event stream (SSE).",
|
|
42
|
+
"POST /v2/runs/:id/interactions/:id/answer": "Answer a run's pending interactive question.",
|
|
43
|
+
"GET /v2/runs/:id/produced": "List a run's produced project outputs.",
|
|
44
|
+
"GET /v2/runs/:id/produced/<path>": "Fetch one produced project-output file from a run.",
|
|
45
|
+
"GET /v2/threads": "List conversation threads.",
|
|
46
|
+
"POST /v2/threads": "Create a conversation thread.",
|
|
47
|
+
"GET /v2/threads/:id": "Read a thread's detail (turns + head).",
|
|
48
|
+
"PATCH /v2/threads/:id": "Update a thread's sticky settings (harness/profile/access).",
|
|
49
|
+
"POST /v2/threads/:id/trash": "Move a thread to trash.",
|
|
50
|
+
"POST /v2/threads/:id/restore": "Restore a thread from trash.",
|
|
51
|
+
"POST /v2/threads/:id/purge": "Permanently purge a trashed thread.",
|
|
52
|
+
"POST /v2/threads/:id/apply": "Apply the thread's latest run work product.",
|
|
53
|
+
"POST /v2/threads/:id/turns": "Enqueue a new turn on a thread.",
|
|
54
|
+
"POST /v2/threads/:id/turns/:id/retry": "Retry a thread turn.",
|
|
55
|
+
"GET /v2/trust": "List protected-path trust state.",
|
|
56
|
+
"POST /v2/trust": "Update protected-path trust state.",
|
|
57
|
+
"GET /v2/settings": "Read the settings snapshot.",
|
|
58
|
+
"POST /v2/settings": "Update settings.",
|
|
59
|
+
"GET /v2/secrets": "List stored secret handles (values never returned).",
|
|
60
|
+
"POST /v2/secrets": "Set a stored secret value.",
|
|
61
|
+
"DELETE /v2/secrets/:id": "Delete a stored secret.",
|
|
62
|
+
"GET /v2/setup/jobs": "List harness setup/login jobs.",
|
|
63
|
+
"POST /v2/setup/jobs": "Start a harness setup/login job.",
|
|
64
|
+
"GET /v2/setup/jobs/:id": "Read a setup job's status.",
|
|
65
|
+
"GET /v2/setup/jobs/:id/snapshot": "Read a setup job's terminal snapshot.",
|
|
66
|
+
"GET /v2/setup/jobs/:id/events": "Tail a setup job's event stream (SSE).",
|
|
67
|
+
"POST /v2/setup/jobs/:id/cancel": "Cancel a setup job.",
|
|
68
|
+
"POST /v2/setup/jobs/:id/reconcile": "Reconcile a setup job's state.",
|
|
69
|
+
"POST /v2/setup/jobs/:id/extend": "Extend a setup job's deadline.",
|
|
70
|
+
"GET /v2/recovery/partitions/:id": "Inspect a journal partition for recovery.",
|
|
71
|
+
"POST /v2/recovery/partitions/:id/validate": "Validate a journal partition (dry).",
|
|
72
|
+
"POST /v2/recovery/partitions/:id/export": "Export a journal partition (dry).",
|
|
73
|
+
"POST /v2/recovery/partitions/:id/quarantine": "Quarantine a corrupt journal partition.",
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=operation-summaries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-summaries.js","sourceRoot":"","sources":["../src/operation-summaries.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,MAAM,CAAC,MAAM,mBAAmB,GAA2B;IACzD,kBAAkB,EAChB,0FAA0F;IAC5F,2BAA2B,EACzB,qPAAqP;IACvP,qBAAqB,EACnB,qHAAqH;IACvH,wBAAwB,EAAE,kDAAkD;IAC5E,+BAA+B,EAAE,wDAAwD;IACzF,oBAAoB,EAAE,4DAA4D;IAClF,oBAAoB,EAAE,iDAAiD;IACvE,yBAAyB,EAAE,0DAA0D;IACrF,4BAA4B,EAAE,2DAA2D;IACzF,2BAA2B,EACzB,yEAAyE;IAC3E,uBAAuB,EAAE,2DAA2D;IACpF,eAAe,EAAE,kDAAkD;IACnE,gBAAgB,EAAE,uDAAuD;IACzE,6BAA6B,EAAE,uCAAuC;IACtE,8BAA8B,EAAE,4CAA4C;IAC5E,mDAAmD,EACjD,yEAAyE;IAC3E,oDAAoD,EAAE,sCAAsC;IAC5F,mBAAmB,EAAE,kDAAkD;IACvE,kBAAkB,EAAE,6CAA6C;IACjE,mBAAmB,EAAE,8CAA8C;IACnE,8BAA8B,EAAE,4CAA4C;IAC5E,yBAAyB,EACvB,4MAA4M;IAC9M,6BAA6B,EAAE,8CAA8C;IAC7E,8BAA8B,EAAE,gDAAgD;IAChF,qCAAqC,EAAE,+CAA+C;IACtF,8BAA8B,EAAE,qCAAqC;IACrE,uCAAuC,EAAE,4CAA4C;IACrF,cAAc,EACZ,qGAAqG;IACvG,eAAe,EAAE,4CAA4C;IAC7D,kBAAkB,EAAE,oCAAoC;IACxD,yBAAyB,EAAE,8CAA8C;IACzE,4BAA4B,EAAE,6CAA6C;IAC3E,yBAAyB,EACvB,8GAA8G;IAChH,+BAA+B,EAC7B,+GAA+G;IACjH,4BAA4B,EAAE,wCAAwC;IACtE,mCAAmC,EAAE,0CAA0C;IAC/E,2BAA2B,EAAE,iCAAiC;IAC9D,4BAA4B,EAAE,qDAAqD;IACnF,yBAAyB,EAAE,2CAA2C;IACtE,2CAA2C,EAAE,8CAA8C;IAC3F,2BAA2B,EAAE,wCAAwC;IACrE,kCAAkC,EAAE,oDAAoD;IACxF,iBAAiB,EAAE,4BAA4B;IAC/C,kBAAkB,EAAE,+BAA+B;IACnD,qBAAqB,EAAE,wCAAwC;IAC/D,uBAAuB,EAAE,6DAA6D;IACtF,4BAA4B,EAAE,yBAAyB;IACvD,8BAA8B,EAAE,8BAA8B;IAC9D,4BAA4B,EAAE,qCAAqC;IACnE,4BAA4B,EAAE,6CAA6C;IAC3E,4BAA4B,EAAE,iCAAiC;IAC/D,sCAAsC,EAAE,sBAAsB;IAC9D,eAAe,EAAE,kCAAkC;IACnD,gBAAgB,EAAE,oCAAoC;IACtD,kBAAkB,EAAE,6BAA6B;IACjD,mBAAmB,EAAE,kBAAkB;IACvC,iBAAiB,EAAE,qDAAqD;IACxE,kBAAkB,EAAE,4BAA4B;IAChD,wBAAwB,EAAE,yBAAyB;IACnD,oBAAoB,EAAE,gCAAgC;IACtD,qBAAqB,EAAE,kCAAkC;IACzD,wBAAwB,EAAE,4BAA4B;IACtD,iCAAiC,EAAE,uCAAuC;IAC1E,+BAA+B,EAAE,wCAAwC;IACzE,gCAAgC,EAAE,qBAAqB;IACvD,mCAAmC,EAAE,gCAAgC;IACrE,gCAAgC,EAAE,gCAAgC;IAClE,iCAAiC,EAAE,2CAA2C;IAC9E,2CAA2C,EAAE,qCAAqC;IAClF,yCAAyC,EAAE,mCAAmC;IAC9E,6CAA6C,EAAE,yCAAyC;CACzF,CAAC"}
|
package/dist/primary-output.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ControlPrimaryOutput, type RunFailure } from "@claudexor/schema";
|
|
1
|
+
import { ControlPrimaryOutput, type RunFacts, type RunFailure } from "@claudexor/schema";
|
|
2
2
|
import type { DaemonRunRecord } from "./daemon-server.js";
|
|
3
3
|
export declare function boundedArtifactText(rec: DaemonRunRecord, relPath: string): string | null;
|
|
4
|
-
export declare function primaryOutput(rec: DaemonRunRecord, mode: string | null | undefined, failure: RunFailure | null): ControlPrimaryOutput | null;
|
|
5
|
-
export declare function outputReadyState(rec: DaemonRunRecord, mode: string | null | undefined, failure: RunFailure | null): "pending" | "finalizing" | "ready" | "diagnostic";
|
|
4
|
+
export declare function primaryOutput(rec: DaemonRunRecord, mode: string | null | undefined, failure: RunFailure | null, runFacts?: RunFacts | null): ControlPrimaryOutput | null;
|
|
5
|
+
export declare function outputReadyState(rec: DaemonRunRecord, mode: string | null | undefined, failure: RunFailure | null, runFacts?: RunFacts | null): "pending" | "finalizing" | "ready" | "diagnostic";
|
|
6
6
|
//# sourceMappingURL=primary-output.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primary-output.d.ts","sourceRoot":"","sources":["../src/primary-output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"primary-output.d.ts","sourceRoot":"","sources":["../src/primary-output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGzF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAwD1D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMxF;AAED,wBAAgB,aAAa,CAC3B,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,OAAO,EAAE,UAAU,GAAG,IAAI,EAC1B,QAAQ,GAAE,QAAQ,GAAG,IAAW,GAC/B,oBAAoB,GAAG,IAAI,CAgE7B;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,OAAO,EAAE,UAAU,GAAG,IAAI,EAC1B,QAAQ,GAAE,QAAQ,GAAG,IAAW,GAC/B,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,YAAY,CAYnD"}
|
package/dist/primary-output.js
CHANGED
|
@@ -2,6 +2,7 @@ import { closeSync, lstatSync, openSync, readSync } from "node:fs";
|
|
|
2
2
|
import { ControlPrimaryOutput } from "@claudexor/schema";
|
|
3
3
|
import { redactSecrets } from "@claudexor/util";
|
|
4
4
|
import { safeArtifactPath } from "./artifact-paths.js";
|
|
5
|
+
import { readRunTombstone } from "./retention.js";
|
|
5
6
|
import { TERMINAL_STATES } from "./sse-shared.js";
|
|
6
7
|
const PRIMARY_OUTPUT_PREVIEW_BYTES = 256 * 1024;
|
|
7
8
|
const REDACTION_OVERLAP_BYTES = 1024;
|
|
@@ -26,25 +27,30 @@ function preview(rec, relPath) {
|
|
|
26
27
|
const path = safeArtifactPath(rec.runDir, relPath);
|
|
27
28
|
if (!path)
|
|
28
29
|
return null;
|
|
29
|
-
const st = lstatSync(path);
|
|
30
|
-
if (st.isSymbolicLink() || st.isDirectory())
|
|
31
|
-
return null;
|
|
32
|
-
const length = Math.min(st.size, PRIMARY_OUTPUT_PREVIEW_BYTES + REDACTION_OVERLAP_BYTES);
|
|
33
|
-
const data = Buffer.alloc(length);
|
|
34
|
-
const fd = openSync(path, "r");
|
|
35
30
|
try {
|
|
36
|
-
|
|
31
|
+
const st = lstatSync(path);
|
|
32
|
+
if (st.isSymbolicLink() || st.isDirectory())
|
|
33
|
+
return null;
|
|
34
|
+
const length = Math.min(st.size, PRIMARY_OUTPUT_PREVIEW_BYTES + REDACTION_OVERLAP_BYTES);
|
|
35
|
+
const data = Buffer.alloc(length);
|
|
36
|
+
const fd = openSync(path, "r");
|
|
37
|
+
try {
|
|
38
|
+
readSync(fd, data, 0, length, 0);
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
closeSync(fd);
|
|
42
|
+
}
|
|
43
|
+
const redacted = redactSecrets(decodeValidUtf8(data));
|
|
44
|
+
return {
|
|
45
|
+
text: truncateUtf8(redacted, PRIMARY_OUTPUT_PREVIEW_BYTES),
|
|
46
|
+
bytes: st.size,
|
|
47
|
+
truncated: st.size > PRIMARY_OUTPUT_PREVIEW_BYTES ||
|
|
48
|
+
Buffer.byteLength(redacted, "utf8") > PRIMARY_OUTPUT_PREVIEW_BYTES,
|
|
49
|
+
};
|
|
37
50
|
}
|
|
38
|
-
|
|
39
|
-
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
40
53
|
}
|
|
41
|
-
const redacted = redactSecrets(decodeValidUtf8(data));
|
|
42
|
-
return {
|
|
43
|
-
text: truncateUtf8(redacted, PRIMARY_OUTPUT_PREVIEW_BYTES),
|
|
44
|
-
bytes: st.size,
|
|
45
|
-
truncated: st.size > PRIMARY_OUTPUT_PREVIEW_BYTES ||
|
|
46
|
-
Buffer.byteLength(redacted, "utf8") > PRIMARY_OUTPUT_PREVIEW_BYTES,
|
|
47
|
-
};
|
|
48
54
|
}
|
|
49
55
|
export function boundedArtifactText(rec, relPath) {
|
|
50
56
|
const output = preview(rec, relPath);
|
|
@@ -54,7 +60,32 @@ export function boundedArtifactText(rec, relPath) {
|
|
|
54
60
|
? `${output.text}\n\n[Inline preview bounded; open ${relPath} for the full artifact.]`
|
|
55
61
|
: output.text;
|
|
56
62
|
}
|
|
57
|
-
export function primaryOutput(rec, mode, failure) {
|
|
63
|
+
export function primaryOutput(rec, mode, failure, runFacts = null) {
|
|
64
|
+
const tombstone = rec.runDir ? readRunTombstone(rec.runDir) : null;
|
|
65
|
+
if (tombstone) {
|
|
66
|
+
const text = "Run artifacts were reclaimed by retention; inspect tombstone.yaml.";
|
|
67
|
+
return ControlPrimaryOutput.parse({
|
|
68
|
+
kind: "diagnostic",
|
|
69
|
+
path: "tombstone.yaml",
|
|
70
|
+
text,
|
|
71
|
+
bytes: Buffer.byteLength(text, "utf8"),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (runFacts?.presentation) {
|
|
75
|
+
const primary = runFacts.presentation.primary;
|
|
76
|
+
if (!primary)
|
|
77
|
+
return null;
|
|
78
|
+
const output = preview(rec, primary.path);
|
|
79
|
+
if (output?.text.trim())
|
|
80
|
+
return ControlPrimaryOutput.parse({ ...primary, ...output });
|
|
81
|
+
const text = `The canonical primary output (${primary.path}) is unavailable; inspect run retention and artifacts.`;
|
|
82
|
+
return ControlPrimaryOutput.parse({
|
|
83
|
+
kind: "diagnostic",
|
|
84
|
+
path: primary.path,
|
|
85
|
+
text,
|
|
86
|
+
bytes: Buffer.byteLength(text, "utf8"),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
58
89
|
const candidates = mode === "ask"
|
|
59
90
|
? [
|
|
60
91
|
{ kind: "structured_output", path: "final/output.json" },
|
|
@@ -74,6 +105,19 @@ export function primaryOutput(rec, mode, failure) {
|
|
|
74
105
|
if (output?.text.trim())
|
|
75
106
|
return ControlPrimaryOutput.parse({ ...candidate, ...output });
|
|
76
107
|
}
|
|
108
|
+
// A cancelled Ask has no answer artifact by design, but its terminal summary
|
|
109
|
+
// contains the actionable cancellation diagnostic. Promote it only for this
|
|
110
|
+
// terminal state; ordinary summaries remain non-primary compatibility text.
|
|
111
|
+
if (mode === "ask" && rec.state === "cancelled") {
|
|
112
|
+
const output = preview(rec, "final/summary.md");
|
|
113
|
+
if (output?.text.trim()) {
|
|
114
|
+
return ControlPrimaryOutput.parse({
|
|
115
|
+
kind: "diagnostic",
|
|
116
|
+
path: "final/summary.md",
|
|
117
|
+
...output,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
77
121
|
return failure
|
|
78
122
|
? ControlPrimaryOutput.parse({
|
|
79
123
|
kind: "diagnostic",
|
|
@@ -83,8 +127,15 @@ export function primaryOutput(rec, mode, failure) {
|
|
|
83
127
|
})
|
|
84
128
|
: null;
|
|
85
129
|
}
|
|
86
|
-
export function outputReadyState(rec, mode, failure) {
|
|
87
|
-
|
|
130
|
+
export function outputReadyState(rec, mode, failure, runFacts = null) {
|
|
131
|
+
if (runFacts?.presentation) {
|
|
132
|
+
if (!runFacts.presentation.primary)
|
|
133
|
+
return runFacts.presentation.state;
|
|
134
|
+
return primaryOutput(rec, mode, failure, runFacts)?.kind === "diagnostic"
|
|
135
|
+
? "diagnostic"
|
|
136
|
+
: runFacts.presentation.state;
|
|
137
|
+
}
|
|
138
|
+
const primary = primaryOutput(rec, mode, failure, null);
|
|
88
139
|
if (primary?.kind === "diagnostic")
|
|
89
140
|
return "diagnostic";
|
|
90
141
|
if (primary?.text?.trim())
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primary-output.js","sourceRoot":"","sources":["../src/primary-output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"primary-output.js","sourceRoot":"","sources":["../src/primary-output.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"problem-response.d.ts","sourceRoot":"","sources":["../src/problem-response.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"problem-response.d.ts","sourceRoot":"","sources":["../src/problem-response.ts"],"names":[],"mappings":"AA8FA;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAkDvE;AAKD;;4EAE4E;AAC5E,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,GAAG,sBAAsB,CAAC;AAEhF;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,UAAU,CAAC,EAAE,mBAAmB,GAC/B;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C,CAsBA;AAaD,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,mBAAmB,CAsBtF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMxD"}
|
package/dist/problem-response.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { redactSecrets } from "@claudexor/util";
|
|
1
|
+
import { redactSecrets, safeProblemContext } from "@claudexor/util";
|
|
2
2
|
/** Bounds for the request-validation projection (QA-053). Redact-first, then
|
|
3
3
|
* truncate; never split a redaction marker; disclose omitted counts. */
|
|
4
4
|
const ZOD_MAX_ISSUES = 25;
|
|
@@ -26,14 +26,16 @@ function structuralZodIssues(error) {
|
|
|
26
26
|
return out;
|
|
27
27
|
}
|
|
28
28
|
function truncateBytes(text, maxBytes) {
|
|
29
|
-
|
|
29
|
+
const bytes = Buffer.from(text, "utf8");
|
|
30
|
+
if (bytes.length <= maxBytes)
|
|
30
31
|
return text;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
let end = maxBytes;
|
|
33
|
+
// If the byte immediately outside the prefix continues a scalar, exclude
|
|
34
|
+
// that scalar's lead byte too. This is bounded to at most three steps for
|
|
35
|
+
// valid UTF-8, regardless of attacker-controlled input length.
|
|
36
|
+
while (end > 0 && (bytes[end] & 0b1100_0000) === 0b1000_0000)
|
|
37
|
+
end -= 1;
|
|
38
|
+
return bytes.subarray(0, end).toString("utf8");
|
|
37
39
|
}
|
|
38
40
|
/** JSON Pointer (RFC 9457-style) for one issue path, without echoing an
|
|
39
41
|
* unrecognized key verbatim when it is unsafe. */
|
|
@@ -183,6 +185,7 @@ const RESERVED_FIELDS = new Set([
|
|
|
183
185
|
"fieldErrors",
|
|
184
186
|
"requiredActions",
|
|
185
187
|
"evidenceRefs",
|
|
188
|
+
"context",
|
|
186
189
|
]);
|
|
187
190
|
export function controlProblemError(status, body) {
|
|
188
191
|
const source = body && typeof body === "object" ? body : {};
|
|
@@ -192,7 +195,9 @@ export function controlProblemError(status, body) {
|
|
|
192
195
|
? source["message"]
|
|
193
196
|
: `request failed with status ${status}`;
|
|
194
197
|
const code = typeof source["code"] === "string" ? source["code"] : `http_${status}`;
|
|
195
|
-
const
|
|
198
|
+
const extras = safeProblemContext(Object.fromEntries(Object.entries(source).filter(([key]) => !RESERVED_FIELDS.has(key))));
|
|
199
|
+
const explicit = safeProblemContext(source["context"]);
|
|
200
|
+
const context = { ...extras, ...explicit };
|
|
196
201
|
return Object.assign(new Error(message), {
|
|
197
202
|
code,
|
|
198
203
|
retryable: source["retryable"] === true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"problem-response.js","sourceRoot":"","sources":["../src/problem-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"problem-response.js","sourceRoot":"","sources":["../src/problem-response.ts"],"names":[],"mappings":"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"}
|
package/dist/project-routes.d.ts
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
export interface ProjectRouteServices {
|
|
3
|
+
listProjects?: () => Promise<{
|
|
4
|
+
projects: unknown[];
|
|
5
|
+
}>;
|
|
6
|
+
registerProject?: (input: {
|
|
7
|
+
root: string;
|
|
8
|
+
idempotencyKey: string;
|
|
9
|
+
clientId: string;
|
|
10
|
+
}) => Promise<unknown>;
|
|
11
|
+
relinkProject?: (id: string, root: string) => Promise<unknown>;
|
|
12
|
+
removeProject?: (id: string) => Promise<unknown>;
|
|
13
|
+
listDirectory?: (path?: string) => Promise<unknown>;
|
|
14
|
+
fetchProjectFile?: (projectId: string, path: string) => Promise<{
|
|
15
|
+
data: Buffer;
|
|
16
|
+
contentType: string;
|
|
17
|
+
fileName: string;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
2
20
|
export interface ProjectRouteContext {
|
|
3
|
-
services?:
|
|
4
|
-
listProjects?: () => Promise<{
|
|
5
|
-
projects: unknown[];
|
|
6
|
-
}>;
|
|
7
|
-
registerProject?: (input: {
|
|
8
|
-
root: string;
|
|
9
|
-
idempotencyKey: string;
|
|
10
|
-
clientId: string;
|
|
11
|
-
}) => Promise<unknown>;
|
|
12
|
-
relinkProject?: (id: string, root: string) => Promise<unknown>;
|
|
13
|
-
removeProject?: (id: string) => Promise<unknown>;
|
|
14
|
-
};
|
|
21
|
+
services?: ProjectRouteServices;
|
|
15
22
|
readBody(req: IncomingMessage): Promise<unknown>;
|
|
16
23
|
json(res: ServerResponse, status: number, body: unknown): void;
|
|
17
|
-
requestError(res: ServerResponse, error: unknown): void;
|
|
24
|
+
requestError(res: ServerResponse, error: unknown, fallbackStatus?: 400 | 500): void;
|
|
25
|
+
binary(res: ServerResponse, status: number, body: Buffer, contentType: string, fileName: string): void;
|
|
18
26
|
}
|
|
19
27
|
export declare function handleProjectRoute(ctx: ProjectRouteContext, method: string, path: string, req: IncomingMessage, res: ServerResponse): Promise<boolean>;
|
|
20
28
|
//# sourceMappingURL=project-routes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-routes.d.ts","sourceRoot":"","sources":["../src/project-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"project-routes.d.ts","sourceRoot":"","sources":["../src/project-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAajE,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC,CAAC;IACtD,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;KAClB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvB,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,gBAAgB,CAAC,EAAE,CACjB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,KACT,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/D,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;IACpF,MAAM,CACJ,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,IAAI,CAAC;CACT;AAED,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,mBAAmB,EACxB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,OAAO,CAAC,CAuHlB"}
|
package/dist/project-routes.js
CHANGED
|
@@ -1,53 +1,100 @@
|
|
|
1
|
-
import { ControlProject, ControlProjectListResponse, ControlProjectRegisterRequest, ControlProjectRelinkRequest, ControlProjectRemoveReceipt, } from "@claudexor/schema";
|
|
1
|
+
import { ControlProject, ControlProjectListResponse, ControlProjectRegisterRequest, ControlProjectRelinkRequest, ControlProjectRemoveReceipt, ControlDirectoryListing, } from "@claudexor/schema";
|
|
2
2
|
import { assertNoInlineSecretValues } from "@claudexor/util";
|
|
3
3
|
import { requiredIdempotencyKey } from "./run-start.js";
|
|
4
|
+
import { routeValue, serviceResponse } from "./route-stages.js";
|
|
4
5
|
export async function handleProjectRoute(ctx, method, path, req, res) {
|
|
6
|
+
if (method === "GET" && path === "/filesystem/directories") {
|
|
7
|
+
const service = ctx.services?.listDirectory;
|
|
8
|
+
if (!service)
|
|
9
|
+
return unsupported(ctx, res);
|
|
10
|
+
const requestedPath = await routeValue(ctx, res, 400, () => {
|
|
11
|
+
const url = new URL(req.url ?? "", "http://localhost");
|
|
12
|
+
for (const key of url.searchParams.keys()) {
|
|
13
|
+
if (key !== "path")
|
|
14
|
+
throw new Error(`unexpected query parameter: ${key}`);
|
|
15
|
+
}
|
|
16
|
+
if (url.searchParams.getAll("path").length > 1) {
|
|
17
|
+
throw new Error("path may be specified only once");
|
|
18
|
+
}
|
|
19
|
+
return url.searchParams.get("path") ?? undefined;
|
|
20
|
+
});
|
|
21
|
+
if (!requestedPath.ok)
|
|
22
|
+
return true;
|
|
23
|
+
const listing = await routeValue(ctx, res, 500, () => service(requestedPath.value));
|
|
24
|
+
if (!listing.ok)
|
|
25
|
+
return true;
|
|
26
|
+
return serviceResponse(ctx, res, "listDirectory", () => ctx.json(res, 200, ControlDirectoryListing.parse(listing.value)));
|
|
27
|
+
}
|
|
5
28
|
if (method === "GET" && path === "/projects") {
|
|
6
29
|
const service = ctx.services?.listProjects;
|
|
7
30
|
if (!service)
|
|
8
31
|
return unsupported(ctx, res);
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
return true;
|
|
32
|
+
const response = await routeValue(ctx, res, 500, service);
|
|
33
|
+
if (!response.ok)
|
|
34
|
+
return true;
|
|
35
|
+
return serviceResponse(ctx, res, "listProjects", () => ctx.json(res, 200, ControlProjectListResponse.parse({
|
|
36
|
+
projects: response.value.projects.map(projectWire),
|
|
37
|
+
})));
|
|
17
38
|
}
|
|
18
39
|
if (method === "POST" && path === "/projects") {
|
|
19
40
|
const service = ctx.services?.registerProject;
|
|
20
41
|
if (!service)
|
|
21
42
|
return unsupported(ctx, res);
|
|
22
|
-
|
|
43
|
+
const input = await routeValue(ctx, res, 400, async () => {
|
|
23
44
|
const idempotencyKey = requiredIdempotencyKey(req);
|
|
24
45
|
const raw = await ctx.readBody(req);
|
|
25
46
|
assertNoInlineSecretValues(raw);
|
|
26
47
|
const body = ControlProjectRegisterRequest.parse(raw);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
48
|
+
return { root: body.root, idempotencyKey, clientId: "control-api" };
|
|
49
|
+
});
|
|
50
|
+
if (!input.ok)
|
|
51
|
+
return true;
|
|
52
|
+
const project = await routeValue(ctx, res, 500, () => service(input.value));
|
|
53
|
+
if (!project.ok)
|
|
54
|
+
return true;
|
|
55
|
+
return serviceResponse(ctx, res, "registerProject", () => ctx.json(res, 200, projectWire(project.value)));
|
|
34
56
|
}
|
|
35
57
|
const projectRelinkMatch = /^\/projects\/([^/]+)\/relink$/.exec(path);
|
|
36
58
|
if (method === "POST" && projectRelinkMatch) {
|
|
37
59
|
const service = ctx.services?.relinkProject;
|
|
38
60
|
if (!service)
|
|
39
61
|
return unsupported(ctx, res);
|
|
40
|
-
|
|
62
|
+
const input = await routeValue(ctx, res, 400, async () => {
|
|
63
|
+
const projectId = decodeURIComponent(projectRelinkMatch[1]);
|
|
41
64
|
const raw = await ctx.readBody(req);
|
|
42
65
|
assertNoInlineSecretValues(raw);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return
|
|
66
|
+
return { projectId, root: ControlProjectRelinkRequest.parse(raw).root };
|
|
67
|
+
});
|
|
68
|
+
if (!input.ok)
|
|
69
|
+
return true;
|
|
70
|
+
const project = await routeValue(ctx, res, 500, () => service(input.value.projectId, input.value.root));
|
|
71
|
+
if (!project.ok)
|
|
72
|
+
return true;
|
|
73
|
+
return serviceResponse(ctx, res, "relinkProject", () => ctx.json(res, 200, projectWire(project.value)));
|
|
74
|
+
}
|
|
75
|
+
const projectFileMatch = /^\/projects\/([^/]+)\/file$/.exec(path);
|
|
76
|
+
if (method === "GET" && projectFileMatch) {
|
|
77
|
+
const service = ctx.services?.fetchProjectFile;
|
|
78
|
+
if (!service)
|
|
79
|
+
return unsupported(ctx, res);
|
|
80
|
+
const input = await routeValue(ctx, res, 400, () => {
|
|
81
|
+
const projectId = decodeURIComponent(projectFileMatch[1]);
|
|
82
|
+
const url = new URL(req.url ?? "", "http://localhost");
|
|
83
|
+
for (const key of url.searchParams.keys()) {
|
|
84
|
+
if (key !== "path")
|
|
85
|
+
throw new Error(`unexpected query parameter: ${key}`);
|
|
86
|
+
}
|
|
87
|
+
if (url.searchParams.getAll("path").length !== 1) {
|
|
88
|
+
throw new Error("one path query parameter is required");
|
|
89
|
+
}
|
|
90
|
+
return { projectId, requestedPath: url.searchParams.get("path") ?? "" };
|
|
91
|
+
});
|
|
92
|
+
if (!input.ok)
|
|
93
|
+
return true;
|
|
94
|
+
const file = await routeValue(ctx, res, 500, () => service(input.value.projectId, input.value.requestedPath));
|
|
95
|
+
if (!file.ok)
|
|
96
|
+
return true;
|
|
97
|
+
return serviceResponse(ctx, res, "fetchProjectFile", () => ctx.binary(res, 200, file.value.data, file.value.contentType, file.value.fileName));
|
|
51
98
|
}
|
|
52
99
|
// QA-049: DELETE /projects/:id — retire a durable project (registry entry +
|
|
53
100
|
// journal-partition archival), typed-fenced against non-purged threads and
|
|
@@ -57,14 +104,13 @@ export async function handleProjectRoute(ctx, method, path, req, res) {
|
|
|
57
104
|
const service = ctx.services?.removeProject;
|
|
58
105
|
if (!service)
|
|
59
106
|
return unsupported(ctx, res);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return true;
|
|
107
|
+
const projectId = await routeValue(ctx, res, 400, () => decodeURIComponent(projectDeleteMatch[1]));
|
|
108
|
+
if (!projectId.ok)
|
|
109
|
+
return true;
|
|
110
|
+
const receipt = await routeValue(ctx, res, 500, () => service(projectId.value));
|
|
111
|
+
if (!receipt.ok)
|
|
112
|
+
return true;
|
|
113
|
+
return serviceResponse(ctx, res, "removeProject", () => ctx.json(res, 200, ControlProjectRemoveReceipt.parse(receipt.value)));
|
|
68
114
|
}
|
|
69
115
|
return false;
|
|
70
116
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-routes.js","sourceRoot":"","sources":["../src/project-routes.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,6BAA6B,EAC7B,2BAA2B,EAC3B,2BAA2B,
|
|
1
|
+
{"version":3,"file":"project-routes.js","sourceRoot":"","sources":["../src/project-routes.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,6BAA6B,EAC7B,2BAA2B,EAC3B,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAgChE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAwB,EACxB,MAAc,EACd,IAAY,EACZ,GAAoB,EACpB,GAAmB;IAEnB,IAAI,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,yBAAyB,EAAE,CAAC;QAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC;QAC5C,IAAI,CAAC,OAAO;YAAE,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,aAAa,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;YACzD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;YACvD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC1C,IAAI,GAAG,KAAK,MAAM;oBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;YAC5E,CAAC;YACD,IAAI,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/C,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACrD,CAAC;YACD,OAAO,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;QACnD,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QACpF,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC7B,OAAO,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,CACrD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,uBAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CACjE,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC9B,OAAO,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,CACpD,GAAG,CAAC,IAAI,CACN,GAAG,EACH,GAAG,EACH,0BAA0B,CAAC,KAAK,CAAC;YAC/B,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC;SACnD,CAAC,CACH,CACF,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,MAAM,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC;QAC9C,IAAI,CAAC,OAAO;YAAE,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,cAAc,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;YACnD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACpC,0BAA0B,CAAC,GAAG,CAAC,CAAC;YAChC,MAAM,IAAI,GAAG,6BAA6B,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACtD,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;QACtE,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5E,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC7B,OAAO,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,CACvD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAC/C,CAAC;IACJ,CAAC;IAED,MAAM,kBAAkB,GAAG,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,IAAI,MAAM,KAAK,MAAM,IAAI,kBAAkB,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC;QAC5C,IAAI,CAAC,OAAO;YAAE,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,SAAS,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,CAAW,CAAC,CAAC;YACtE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACpC,0BAA0B,CAAC,GAAG,CAAC,CAAC;YAChC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1E,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CACnD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CACjD,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC7B,OAAO,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,CACrD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAC/C,CAAC;IACJ,CAAC;IAED,MAAM,gBAAgB,GAAG,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,MAAM,KAAK,KAAK,IAAI,gBAAgB,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,gBAAgB,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;YACjD,MAAM,SAAS,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,CAAC,CAAW,CAAC,CAAC;YACpE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;YACvD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC1C,IAAI,GAAG,KAAK,MAAM;oBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;YAC5E,CAAC;YACD,IAAI,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjD,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAC1D,CAAC;YACD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1E,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAChD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAC1D,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC1B,OAAO,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,CACxD,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CACnF,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,2EAA2E;IAC3E,uEAAuE;IACvE,MAAM,kBAAkB,GAAG,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9D,IAAI,MAAM,KAAK,QAAQ,IAAI,kBAAkB,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC;QAC5C,IAAI,CAAC,OAAO;YAAE,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CACrD,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,CAAW,CAAC,CACpD,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAChF,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC7B,OAAO,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,CACrD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,2BAA2B,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CACrE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,GAAwB,EAAE,GAAmB;IAChE,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,0CAA0C,EAAE,CAAC,CAAC;IAC1E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,MAAM,OAAO,GAAG,KAAgC,CAAC;IACjD,OAAO,cAAc,CAAC,KAAK,CAAC;QAC1B,aAAa,EAAE,OAAO,CAAC,gBAAgB,CAAC;QACxC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC;QACjB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC;QACrB,SAAS,EAAE,OAAO,CAAC,YAAY,CAAC;QAChC,SAAS,EAAE,OAAO,CAAC,YAAY,CAAC;QAChC,4EAA4E;QAC5E,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE;KAClC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare const REMOTE_OPERATION_DRAFTS: readonly [{
|
|
2
|
+
readonly method: "GET";
|
|
3
|
+
readonly path: "/v2/filesystem/directories";
|
|
4
|
+
readonly mutability: "read_only";
|
|
5
|
+
readonly requestSchema: null;
|
|
6
|
+
readonly responseSchema: "ControlDirectoryListing";
|
|
7
|
+
readonly responseKind: "json";
|
|
8
|
+
readonly summary: "List the visible subdirectories of a directory contained by the server user's home; served only by the remote runtime (a local daemon answers 501).";
|
|
9
|
+
readonly parameters: [{
|
|
10
|
+
name: string;
|
|
11
|
+
location: "header" | "query";
|
|
12
|
+
required: boolean;
|
|
13
|
+
repeatable: boolean;
|
|
14
|
+
enum: string[] | null;
|
|
15
|
+
schemaRef: string | null;
|
|
16
|
+
description: string;
|
|
17
|
+
}];
|
|
18
|
+
}, {
|
|
19
|
+
readonly method: "GET";
|
|
20
|
+
readonly path: "/v2/projects/:id/file";
|
|
21
|
+
readonly mutability: "read_only";
|
|
22
|
+
readonly requestSchema: null;
|
|
23
|
+
readonly responseSchema: null;
|
|
24
|
+
readonly responseKind: "binary";
|
|
25
|
+
readonly summary: "Fetch one bounded raster image contained by a registered project; served only by the remote runtime (a local daemon answers 501).";
|
|
26
|
+
readonly parameters: [{
|
|
27
|
+
name: string;
|
|
28
|
+
location: "header" | "query";
|
|
29
|
+
required: boolean;
|
|
30
|
+
repeatable: boolean;
|
|
31
|
+
enum: string[] | null;
|
|
32
|
+
schemaRef: string | null;
|
|
33
|
+
description: string;
|
|
34
|
+
}];
|
|
35
|
+
}];
|
|
36
|
+
//# sourceMappingURL=remote-operation-descriptors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-operation-descriptors.d.ts","sourceRoot":"","sources":["../src/remote-operation-descriptors.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,uBAAuB;qBAExB,KAAK;mBACP,4BAA4B;yBACtB,WAAW;;6BAEP,yBAAyB;2BAC3B,MAAM;sBAElB,qJAAqJ;;;;;;;;;;;qBAU/I,KAAK;mBACP,uBAAuB;yBACjB,WAAW;;;2BAGT,QAAQ;sBAEpB,mIAAmI;;;;;;;;;;EAU3F,CAAC"}
|