pi-amq 0.1.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/CHANGELOG.md +66 -0
- package/LICENSE +21 -0
- package/README.md +92 -0
- package/THIRD_PARTY_NOTICES.md +33 -0
- package/dist/extension/guidance.d.ts +25 -0
- package/dist/extension/guidance.d.ts.map +1 -0
- package/dist/extension/guidance.js +121 -0
- package/dist/extension/guidance.js.map +1 -0
- package/dist/extension/guide.d.ts +30 -0
- package/dist/extension/guide.d.ts.map +1 -0
- package/dist/extension/guide.js +128 -0
- package/dist/extension/guide.js.map +1 -0
- package/dist/extension/index.d.ts +4 -0
- package/dist/extension/index.d.ts.map +1 -0
- package/dist/extension/index.js +6 -0
- package/dist/extension/index.js.map +1 -0
- package/dist/extension/runtime.d.ts +48 -0
- package/dist/extension/runtime.d.ts.map +1 -0
- package/dist/extension/runtime.js +1095 -0
- package/dist/extension/runtime.js.map +1 -0
- package/dist/extension/tools.d.ts +12 -0
- package/dist/extension/tools.d.ts.map +1 -0
- package/dist/extension/tools.js +198 -0
- package/dist/extension/tools.js.map +1 -0
- package/dist/extension/worker-runtime.d.ts +34 -0
- package/dist/extension/worker-runtime.d.ts.map +1 -0
- package/dist/extension/worker-runtime.js +974 -0
- package/dist/extension/worker-runtime.js.map +1 -0
- package/dist/extension/worker-tools.d.ts +140 -0
- package/dist/extension/worker-tools.d.ts.map +1 -0
- package/dist/extension/worker-tools.js +217 -0
- package/dist/extension/worker-tools.js.map +1 -0
- package/dist/integration/confirmed-bind-onboarding.d.ts +44 -0
- package/dist/integration/confirmed-bind-onboarding.d.ts.map +1 -0
- package/dist/integration/confirmed-bind-onboarding.js +199 -0
- package/dist/integration/confirmed-bind-onboarding.js.map +1 -0
- package/dist/integration/fleet-view.d.ts +66 -0
- package/dist/integration/fleet-view.d.ts.map +1 -0
- package/dist/integration/fleet-view.js +238 -0
- package/dist/integration/fleet-view.js.map +1 -0
- package/dist/integration/fresh-session-dispatcher.d.ts +66 -0
- package/dist/integration/fresh-session-dispatcher.d.ts.map +1 -0
- package/dist/integration/fresh-session-dispatcher.js +103 -0
- package/dist/integration/fresh-session-dispatcher.js.map +1 -0
- package/dist/integration/launch-preview.d.ts +31 -0
- package/dist/integration/launch-preview.d.ts.map +1 -0
- package/dist/integration/launch-preview.js +325 -0
- package/dist/integration/launch-preview.js.map +1 -0
- package/dist/integration/transport-port.d.ts +39 -0
- package/dist/integration/transport-port.d.ts.map +1 -0
- package/dist/integration/transport-port.js +2 -0
- package/dist/integration/transport-port.js.map +1 -0
- package/dist/integration/worker-completion-notifier.d.ts +22 -0
- package/dist/integration/worker-completion-notifier.d.ts.map +1 -0
- package/dist/integration/worker-completion-notifier.js +81 -0
- package/dist/integration/worker-completion-notifier.js.map +1 -0
- package/dist/transport/amq-cli-adapter.d.ts +41 -0
- package/dist/transport/amq-cli-adapter.d.ts.map +1 -0
- package/dist/transport/amq-cli-adapter.js +291 -0
- package/dist/transport/amq-cli-adapter.js.map +1 -0
- package/dist/transport/amq-message.d.ts +47 -0
- package/dist/transport/amq-message.d.ts.map +1 -0
- package/dist/transport/amq-message.js +173 -0
- package/dist/transport/amq-message.js.map +1 -0
- package/dist/transport/amq-operations.d.ts +105 -0
- package/dist/transport/amq-operations.d.ts.map +1 -0
- package/dist/transport/amq-operations.js +320 -0
- package/dist/transport/amq-operations.js.map +1 -0
- package/dist/transport/atomic-json.d.ts +18 -0
- package/dist/transport/atomic-json.d.ts.map +1 -0
- package/dist/transport/atomic-json.js +90 -0
- package/dist/transport/atomic-json.js.map +1 -0
- package/dist/transport/binding-resolver.d.ts +46 -0
- package/dist/transport/binding-resolver.d.ts.map +1 -0
- package/dist/transport/binding-resolver.js +389 -0
- package/dist/transport/binding-resolver.js.map +1 -0
- package/dist/transport/bridge-journal.d.ts +100 -0
- package/dist/transport/bridge-journal.d.ts.map +1 -0
- package/dist/transport/bridge-journal.js +459 -0
- package/dist/transport/bridge-journal.js.map +1 -0
- package/dist/transport/dlq-retry-audit.d.ts +28 -0
- package/dist/transport/dlq-retry-audit.d.ts.map +1 -0
- package/dist/transport/dlq-retry-audit.js +66 -0
- package/dist/transport/dlq-retry-audit.js.map +1 -0
- package/dist/transport/inbox-pump.d.ts +81 -0
- package/dist/transport/inbox-pump.d.ts.map +1 -0
- package/dist/transport/inbox-pump.js +558 -0
- package/dist/transport/inbox-pump.js.map +1 -0
- package/dist/transport/index.d.ts +12 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +12 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/presence-projector.d.ts +29 -0
- package/dist/transport/presence-projector.d.ts.map +1 -0
- package/dist/transport/presence-projector.js +73 -0
- package/dist/transport/presence-projector.js.map +1 -0
- package/dist/transport/priority-delivery-scheduler.d.ts +85 -0
- package/dist/transport/priority-delivery-scheduler.d.ts.map +1 -0
- package/dist/transport/priority-delivery-scheduler.js +210 -0
- package/dist/transport/priority-delivery-scheduler.js.map +1 -0
- package/dist/transport/receiver-lease.d.ts +102 -0
- package/dist/transport/receiver-lease.d.ts.map +1 -0
- package/dist/transport/receiver-lease.js +778 -0
- package/dist/transport/receiver-lease.js.map +1 -0
- package/dist/transport/runtime-status.d.ts +48 -0
- package/dist/transport/runtime-status.d.ts.map +1 -0
- package/dist/transport/runtime-status.js +71 -0
- package/dist/transport/runtime-status.js.map +1 -0
- package/dist/workflow/atomic-storage.d.ts +12 -0
- package/dist/workflow/atomic-storage.d.ts.map +1 -0
- package/dist/workflow/atomic-storage.js +104 -0
- package/dist/workflow/atomic-storage.js.map +1 -0
- package/dist/workflow/budget.d.ts +18 -0
- package/dist/workflow/budget.d.ts.map +1 -0
- package/dist/workflow/budget.js +74 -0
- package/dist/workflow/budget.js.map +1 -0
- package/dist/workflow/index.d.ts +17 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +17 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/lifecycle-projection.d.ts +18 -0
- package/dist/workflow/lifecycle-projection.d.ts.map +1 -0
- package/dist/workflow/lifecycle-projection.js +22 -0
- package/dist/workflow/lifecycle-projection.js.map +1 -0
- package/dist/workflow/model-fallback.d.ts +2 -0
- package/dist/workflow/model-fallback.d.ts.map +1 -0
- package/dist/workflow/model-fallback.js +17 -0
- package/dist/workflow/model-fallback.js.map +1 -0
- package/dist/workflow/pi-session-fork.d.ts +18 -0
- package/dist/workflow/pi-session-fork.d.ts.map +1 -0
- package/dist/workflow/pi-session-fork.js +80 -0
- package/dist/workflow/pi-session-fork.js.map +1 -0
- package/dist/workflow/run-artifacts.d.ts +5 -0
- package/dist/workflow/run-artifacts.d.ts.map +1 -0
- package/dist/workflow/run-artifacts.js +25 -0
- package/dist/workflow/run-artifacts.js.map +1 -0
- package/dist/workflow/run-cleanup.d.ts +70 -0
- package/dist/workflow/run-cleanup.d.ts.map +1 -0
- package/dist/workflow/run-cleanup.js +222 -0
- package/dist/workflow/run-cleanup.js.map +1 -0
- package/dist/workflow/run-gate.d.ts +43 -0
- package/dist/workflow/run-gate.d.ts.map +1 -0
- package/dist/workflow/run-gate.js +70 -0
- package/dist/workflow/run-gate.js.map +1 -0
- package/dist/workflow/run-store.d.ts +208 -0
- package/dist/workflow/run-store.d.ts.map +1 -0
- package/dist/workflow/run-store.js +2965 -0
- package/dist/workflow/run-store.js.map +1 -0
- package/dist/workflow/spawn-confirmation.d.ts +44 -0
- package/dist/workflow/spawn-confirmation.d.ts.map +1 -0
- package/dist/workflow/spawn-confirmation.js +228 -0
- package/dist/workflow/spawn-confirmation.js.map +1 -0
- package/dist/workflow/system-process-inspector.d.ts +9 -0
- package/dist/workflow/system-process-inspector.d.ts.map +1 -0
- package/dist/workflow/system-process-inspector.js +129 -0
- package/dist/workflow/system-process-inspector.js.map +1 -0
- package/dist/workflow/worker-child-extension.d.ts +3 -0
- package/dist/workflow/worker-child-extension.d.ts.map +1 -0
- package/dist/workflow/worker-child-extension.js +182 -0
- package/dist/workflow/worker-child-extension.js.map +1 -0
- package/dist/workflow/worker-gate.d.ts +74 -0
- package/dist/workflow/worker-gate.d.ts.map +1 -0
- package/dist/workflow/worker-gate.js +165 -0
- package/dist/workflow/worker-gate.js.map +1 -0
- package/dist/workflow/worker-launch.d.ts +65 -0
- package/dist/workflow/worker-launch.d.ts.map +1 -0
- package/dist/workflow/worker-launch.js +338 -0
- package/dist/workflow/worker-launch.js.map +1 -0
- package/dist/workflow/worker-model-catalog.d.ts +36 -0
- package/dist/workflow/worker-model-catalog.d.ts.map +1 -0
- package/dist/workflow/worker-model-catalog.js +105 -0
- package/dist/workflow/worker-model-catalog.js.map +1 -0
- package/dist/workflow/worker-process-supervisor.d.ts +110 -0
- package/dist/workflow/worker-process-supervisor.d.ts.map +1 -0
- package/dist/workflow/worker-process-supervisor.js +1188 -0
- package/dist/workflow/worker-process-supervisor.js.map +1 -0
- package/dist/workflow/worker-prompt-capsule.d.ts +32 -0
- package/dist/workflow/worker-prompt-capsule.d.ts.map +1 -0
- package/dist/workflow/worker-prompt-capsule.js +52 -0
- package/dist/workflow/worker-prompt-capsule.js.map +1 -0
- package/dist/workflow/worker-role-presets.d.ts +38 -0
- package/dist/workflow/worker-role-presets.d.ts.map +1 -0
- package/dist/workflow/worker-role-presets.js +201 -0
- package/dist/workflow/worker-role-presets.js.map +1 -0
- package/dist/workflow/workflow-doctor.d.ts +57 -0
- package/dist/workflow/workflow-doctor.d.ts.map +1 -0
- package/dist/workflow/workflow-doctor.js +289 -0
- package/dist/workflow/workflow-doctor.js.map +1 -0
- package/dist/workflow/workflow-lease.d.ts +125 -0
- package/dist/workflow/workflow-lease.d.ts.map +1 -0
- package/dist/workflow/workflow-lease.js +689 -0
- package/dist/workflow/workflow-lease.js.map +1 -0
- package/dist/workflow/workflow-types.d.ts +335 -0
- package/dist/workflow/workflow-types.d.ts.map +1 -0
- package/dist/workflow/workflow-types.js +11 -0
- package/dist/workflow/workflow-types.js.map +1 -0
- package/dist/workflow/workspace-paths.d.ts +4 -0
- package/dist/workflow/workspace-paths.d.ts.map +1 -0
- package/dist/workflow/workspace-paths.js +22 -0
- package/dist/workflow/workspace-paths.js.map +1 -0
- package/docs/conformance.md +116 -0
- package/docs/demo-transcript.md +34 -0
- package/docs/design.md +1481 -0
- package/docs/operator-guide.md +100 -0
- package/extension/guidance.ts +162 -0
- package/extension/guide.ts +155 -0
- package/extension/index.ts +8 -0
- package/extension/runtime.ts +1224 -0
- package/extension/tools.ts +221 -0
- package/extension/worker-runtime.ts +1150 -0
- package/extension/worker-tools.ts +276 -0
- package/integration/confirmed-bind-onboarding.ts +296 -0
- package/integration/fleet-view.ts +286 -0
- package/integration/fresh-session-dispatcher.ts +166 -0
- package/integration/launch-preview.ts +396 -0
- package/integration/transport-port.ts +29 -0
- package/integration/worker-completion-notifier.ts +98 -0
- package/package.json +55 -0
- package/roles/oracle.md +9 -0
- package/roles/researcher.md +8 -0
- package/roles/reviewer.md +9 -0
- package/roles/scout.md +8 -0
- package/roles/worker.md +10 -0
- package/scripts/demo-two-terminal.sh +59 -0
- package/skills/coordination-patterns/SKILL.md +41 -0
- package/skills/coordination-patterns/references/supervised-worker-fan-out.md +12 -0
- package/skills/coordination-patterns/references/today-mail-team.md +36 -0
- package/transport/amq-cli-adapter.ts +381 -0
- package/transport/amq-message.ts +218 -0
- package/transport/amq-operations.ts +482 -0
- package/transport/atomic-json.ts +115 -0
- package/transport/binding-resolver.ts +565 -0
- package/transport/bridge-journal.ts +588 -0
- package/transport/dlq-retry-audit.ts +97 -0
- package/transport/inbox-pump.ts +729 -0
- package/transport/index.ts +11 -0
- package/transport/presence-projector.ts +104 -0
- package/transport/priority-delivery-scheduler.ts +328 -0
- package/transport/receiver-lease.ts +945 -0
- package/transport/runtime-status.ts +112 -0
- package/workflow/.gitkeep +1 -0
- package/workflow/atomic-storage.ts +120 -0
- package/workflow/budget.ts +90 -0
- package/workflow/index.ts +16 -0
- package/workflow/lifecycle-projection.ts +37 -0
- package/workflow/model-fallback.ts +17 -0
- package/workflow/pi-session-fork.ts +96 -0
- package/workflow/run-artifacts.ts +36 -0
- package/workflow/run-cleanup.ts +315 -0
- package/workflow/run-gate.ts +122 -0
- package/workflow/run-store.ts +3890 -0
- package/workflow/spawn-confirmation.ts +305 -0
- package/workflow/system-process-inspector.ts +142 -0
- package/workflow/worker-child-extension.ts +193 -0
- package/workflow/worker-gate.ts +238 -0
- package/workflow/worker-launch.ts +485 -0
- package/workflow/worker-model-catalog.ts +165 -0
- package/workflow/worker-process-supervisor.ts +1504 -0
- package/workflow/worker-prompt-capsule.ts +81 -0
- package/workflow/worker-role-presets.ts +241 -0
- package/workflow/workflow-doctor.ts +400 -0
- package/workflow/workflow-lease.ts +905 -0
- package/workflow/workflow-types.ts +367 -0
- package/workflow/workspace-paths.ts +32 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export class WorkerCompletionNotifier {
|
|
2
|
+
#publish;
|
|
3
|
+
#timers;
|
|
4
|
+
#windowMs;
|
|
5
|
+
#states = new Map();
|
|
6
|
+
#successful = new Set();
|
|
7
|
+
#flush;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.#publish = options.publish;
|
|
10
|
+
this.#timers = options.timers ?? new NodeCompletionTimers();
|
|
11
|
+
this.#windowMs = options.windowMs ?? 350;
|
|
12
|
+
}
|
|
13
|
+
baseline(run) {
|
|
14
|
+
for (const worker of Object.values(run.workers)) {
|
|
15
|
+
this.#states.set(worker.workerId, worker.state);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
observe(run) {
|
|
19
|
+
for (const worker of Object.values(run.workers)) {
|
|
20
|
+
const previous = this.#states.get(worker.workerId);
|
|
21
|
+
this.#states.set(worker.workerId, worker.state);
|
|
22
|
+
if (previous === undefined || previous === worker.state)
|
|
23
|
+
continue;
|
|
24
|
+
switch (worker.state) {
|
|
25
|
+
case "done":
|
|
26
|
+
this.#successful.add(worker.workerId);
|
|
27
|
+
this.#scheduleSuccessFlush();
|
|
28
|
+
break;
|
|
29
|
+
case "failed":
|
|
30
|
+
this.#emit({ level: "error", message: `Worker ${worker.workerId} failed.` });
|
|
31
|
+
break;
|
|
32
|
+
case "blocked":
|
|
33
|
+
this.#emit({ level: "warning", message: `Worker ${worker.workerId} paused for typed input.` });
|
|
34
|
+
break;
|
|
35
|
+
case "ambiguous":
|
|
36
|
+
this.#emit({ level: "warning", message: `Worker ${worker.workerId} requires reconciliation.` });
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
dispose() {
|
|
44
|
+
this.#flush?.cancel();
|
|
45
|
+
this.#flush = undefined;
|
|
46
|
+
this.#successful.clear();
|
|
47
|
+
}
|
|
48
|
+
#scheduleSuccessFlush() {
|
|
49
|
+
if (this.#flush)
|
|
50
|
+
return;
|
|
51
|
+
this.#flush = this.#timers.schedule(this.#windowMs, () => {
|
|
52
|
+
this.#flush = undefined;
|
|
53
|
+
const ids = [...this.#successful].sort();
|
|
54
|
+
this.#successful.clear();
|
|
55
|
+
if (ids.length === 0)
|
|
56
|
+
return;
|
|
57
|
+
this.#emit({
|
|
58
|
+
level: "info",
|
|
59
|
+
message: ids.length === 1
|
|
60
|
+
? `Worker ${ids[0]} completed.`
|
|
61
|
+
: `Workers completed: ${ids.join(", ")}.`,
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
#emit(notice) {
|
|
66
|
+
try {
|
|
67
|
+
this.#publish(notice);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// UI delivery is advisory and cannot invalidate committed ledger truth.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
class NodeCompletionTimers {
|
|
75
|
+
schedule(delayMs, callback) {
|
|
76
|
+
const timer = setTimeout(callback, Math.max(0, delayMs));
|
|
77
|
+
timer.unref();
|
|
78
|
+
return { cancel: () => clearTimeout(timer) };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=worker-completion-notifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-completion-notifier.js","sourceRoot":"","sources":["../../integration/worker-completion-notifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type AmqExitCategory = "success" | "error" | "usage" | "not-found" | "timeout" | "context-mismatch" | "invalid-json" | "output-limit" | "cancelled" | "spawn-error" | "process-crash" | "cleanup-failed";
|
|
2
|
+
export interface AmqCliAdapterOptions {
|
|
3
|
+
readonly binaryPath: string;
|
|
4
|
+
readonly maxStdoutBytes?: number;
|
|
5
|
+
readonly maxStderrBytes?: number;
|
|
6
|
+
readonly bodyFileThresholdBytes?: number;
|
|
7
|
+
readonly tempDirectory?: string;
|
|
8
|
+
readonly env?: Readonly<NodeJS.ProcessEnv>;
|
|
9
|
+
}
|
|
10
|
+
export interface AmqRunOptions<T> {
|
|
11
|
+
readonly cwd?: string;
|
|
12
|
+
readonly env?: Readonly<NodeJS.ProcessEnv>;
|
|
13
|
+
readonly signal?: AbortSignal;
|
|
14
|
+
readonly parse?: (value: unknown) => T;
|
|
15
|
+
}
|
|
16
|
+
export interface AmqCommandResult<T> {
|
|
17
|
+
readonly ok: boolean;
|
|
18
|
+
readonly category: AmqExitCategory;
|
|
19
|
+
readonly exitCode: number | null;
|
|
20
|
+
readonly signal: NodeJS.Signals | null;
|
|
21
|
+
readonly stdout: string;
|
|
22
|
+
readonly stderr: string;
|
|
23
|
+
readonly stdoutTruncated: boolean;
|
|
24
|
+
readonly stderrTruncated: boolean;
|
|
25
|
+
readonly json?: T;
|
|
26
|
+
readonly jsonError?: Error;
|
|
27
|
+
readonly processError?: Error;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The sole process boundary for AMQ commands.
|
|
31
|
+
*
|
|
32
|
+
* It never invokes a shell, never infers routing identity, and always preserves
|
|
33
|
+
* bounded stdout for callers to inspect even when AMQ exits nonzero.
|
|
34
|
+
*/
|
|
35
|
+
export declare class AmqCliAdapter {
|
|
36
|
+
#private;
|
|
37
|
+
constructor(options: AmqCliAdapterOptions);
|
|
38
|
+
runJson<T = unknown>(argv: readonly string[], options?: AmqRunOptions<T>): Promise<AmqCommandResult<T>>;
|
|
39
|
+
runJsonWithBody<T = unknown>(argv: readonly string[], body: string, options?: AmqRunOptions<T>): Promise<AmqCommandResult<T>>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=amq-cli-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amq-cli-adapter.d.ts","sourceRoot":"","sources":["../../transport/amq-cli-adapter.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,OAAO,GACP,OAAO,GACP,WAAW,GACX,SAAS,GACT,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,WAAW,GACX,aAAa,GACb,eAAe,GACf,gBAAgB,CAAC;AAErB,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC;CAC/B;AAkBD;;;;;GAKG;AACH,qBAAa,aAAa;;gBAQZ,OAAO,EAAE,oBAAoB;IAqBnC,OAAO,CAAC,CAAC,GAAG,OAAO,EACvB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,GAAE,aAAa,CAAC,CAAC,CAAM,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAOzB,eAAe,CAAC,CAAC,GAAG,OAAO,EAC/B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,aAAa,CAAC,CAAC,CAAM,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;CA2GhC"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { chmod, mkdtemp, open, rmdir, unlink } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { isAbsolute, join } from "node:path";
|
|
5
|
+
const DEFAULT_OUTPUT_BOUND = 1024 * 1024;
|
|
6
|
+
const DEFAULT_BODY_FILE_THRESHOLD = 8 * 1024;
|
|
7
|
+
/**
|
|
8
|
+
* The sole process boundary for AMQ commands.
|
|
9
|
+
*
|
|
10
|
+
* It never invokes a shell, never infers routing identity, and always preserves
|
|
11
|
+
* bounded stdout for callers to inspect even when AMQ exits nonzero.
|
|
12
|
+
*/
|
|
13
|
+
export class AmqCliAdapter {
|
|
14
|
+
#binaryPath;
|
|
15
|
+
#maxStdoutBytes;
|
|
16
|
+
#maxStderrBytes;
|
|
17
|
+
#bodyFileThresholdBytes;
|
|
18
|
+
#tempDirectory;
|
|
19
|
+
#env;
|
|
20
|
+
constructor(options) {
|
|
21
|
+
if (!isAbsolute(options.binaryPath)) {
|
|
22
|
+
throw new TypeError("AMQ binary path must be absolute");
|
|
23
|
+
}
|
|
24
|
+
this.#binaryPath = options.binaryPath;
|
|
25
|
+
this.#maxStdoutBytes = positiveInteger(options.maxStdoutBytes ?? DEFAULT_OUTPUT_BOUND, "maxStdoutBytes");
|
|
26
|
+
this.#maxStderrBytes = positiveInteger(options.maxStderrBytes ?? DEFAULT_OUTPUT_BOUND, "maxStderrBytes");
|
|
27
|
+
this.#bodyFileThresholdBytes = nonNegativeInteger(options.bodyFileThresholdBytes ?? DEFAULT_BODY_FILE_THRESHOLD, "bodyFileThresholdBytes");
|
|
28
|
+
this.#tempDirectory = options.tempDirectory ?? tmpdir();
|
|
29
|
+
this.#env = { ...process.env, ...options.env };
|
|
30
|
+
}
|
|
31
|
+
async runJson(argv, options = {}) {
|
|
32
|
+
validateArgv(argv);
|
|
33
|
+
const jsonArgv = argv.includes("--json") ? [...argv] : [...argv, "--json"];
|
|
34
|
+
const capture = await this.#execute(jsonArgv, options);
|
|
35
|
+
return parseJsonCapture(capture, options.parse);
|
|
36
|
+
}
|
|
37
|
+
async runJsonWithBody(argv, body, options = {}) {
|
|
38
|
+
validateArgv(argv);
|
|
39
|
+
const requiresFile = body.includes("\0") || Buffer.byteLength(body) > this.#bodyFileThresholdBytes;
|
|
40
|
+
if (!requiresFile) {
|
|
41
|
+
return this.runJson([...argv, "--body", body], options);
|
|
42
|
+
}
|
|
43
|
+
const temporary = await createTemporaryBody(this.#tempDirectory, body);
|
|
44
|
+
let result;
|
|
45
|
+
let executionError;
|
|
46
|
+
try {
|
|
47
|
+
result = await this.runJson([...argv, "--body", `@${temporary.path}`], options);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
executionError = toError(error);
|
|
51
|
+
}
|
|
52
|
+
const cleanupError = await cleanupTemporaryBody(temporary);
|
|
53
|
+
if (executionError) {
|
|
54
|
+
if (cleanupError) {
|
|
55
|
+
throw new AggregateError([executionError, cleanupError], "AMQ command and temporary body cleanup both failed");
|
|
56
|
+
}
|
|
57
|
+
throw executionError;
|
|
58
|
+
}
|
|
59
|
+
if (!result)
|
|
60
|
+
throw new Error("AMQ command completed without a result");
|
|
61
|
+
if (!cleanupError)
|
|
62
|
+
return result;
|
|
63
|
+
return {
|
|
64
|
+
...result,
|
|
65
|
+
ok: false,
|
|
66
|
+
category: "cleanup-failed",
|
|
67
|
+
processError: cleanupError,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
async #execute(argv, options) {
|
|
71
|
+
if (options.signal?.aborted) {
|
|
72
|
+
return emptyCapture(true);
|
|
73
|
+
}
|
|
74
|
+
return new Promise((resolve) => {
|
|
75
|
+
const stdout = new BoundedCapture(this.#maxStdoutBytes);
|
|
76
|
+
const stderr = new BoundedCapture(this.#maxStderrBytes);
|
|
77
|
+
let child;
|
|
78
|
+
try {
|
|
79
|
+
child = spawn(this.#binaryPath, argv, {
|
|
80
|
+
cwd: options.cwd,
|
|
81
|
+
env: { ...this.#env, ...options.env },
|
|
82
|
+
shell: false,
|
|
83
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
84
|
+
windowsHide: true,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
resolve({ ...emptyCapture(false), processError: toError(error) });
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
let settled = false;
|
|
92
|
+
let aborted = false;
|
|
93
|
+
let processError;
|
|
94
|
+
let outputLimitExceeded = false;
|
|
95
|
+
const stopForOutputLimit = () => {
|
|
96
|
+
if (outputLimitExceeded)
|
|
97
|
+
return;
|
|
98
|
+
outputLimitExceeded = true;
|
|
99
|
+
child.kill("SIGKILL");
|
|
100
|
+
};
|
|
101
|
+
child.stdout.on("data", (chunk) => {
|
|
102
|
+
if (stdout.append(chunk))
|
|
103
|
+
stopForOutputLimit();
|
|
104
|
+
});
|
|
105
|
+
child.stderr.on("data", (chunk) => {
|
|
106
|
+
if (stderr.append(chunk))
|
|
107
|
+
stopForOutputLimit();
|
|
108
|
+
});
|
|
109
|
+
const onAbort = () => {
|
|
110
|
+
aborted = true;
|
|
111
|
+
child.kill("SIGTERM");
|
|
112
|
+
};
|
|
113
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
114
|
+
const settle = (exitCode, signal) => {
|
|
115
|
+
if (settled)
|
|
116
|
+
return;
|
|
117
|
+
settled = true;
|
|
118
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
119
|
+
resolve({
|
|
120
|
+
exitCode,
|
|
121
|
+
signal,
|
|
122
|
+
stdout: stdout.value(),
|
|
123
|
+
stderr: stderr.value(),
|
|
124
|
+
stdoutTruncated: stdout.truncated,
|
|
125
|
+
stderrTruncated: stderr.truncated,
|
|
126
|
+
aborted,
|
|
127
|
+
...(processError ? { processError } : {}),
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
child.once("error", (error) => {
|
|
131
|
+
processError = error;
|
|
132
|
+
});
|
|
133
|
+
child.once("close", settle);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
class BoundedCapture {
|
|
138
|
+
#limit;
|
|
139
|
+
#chunks = [];
|
|
140
|
+
#capturedBytes = 0;
|
|
141
|
+
truncated = false;
|
|
142
|
+
constructor(limit) {
|
|
143
|
+
this.#limit = limit;
|
|
144
|
+
}
|
|
145
|
+
append(chunk) {
|
|
146
|
+
const remaining = this.#limit - this.#capturedBytes;
|
|
147
|
+
if (remaining > 0) {
|
|
148
|
+
const captured = chunk.length <= remaining ? chunk : chunk.subarray(0, remaining);
|
|
149
|
+
this.#chunks.push(Buffer.from(captured));
|
|
150
|
+
this.#capturedBytes += captured.length;
|
|
151
|
+
}
|
|
152
|
+
if (chunk.length > remaining)
|
|
153
|
+
this.truncated = true;
|
|
154
|
+
return this.truncated;
|
|
155
|
+
}
|
|
156
|
+
value() {
|
|
157
|
+
return Buffer.concat(this.#chunks, this.#capturedBytes).toString("utf8");
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function parseJsonCapture(capture, parser) {
|
|
161
|
+
let json;
|
|
162
|
+
let jsonError;
|
|
163
|
+
try {
|
|
164
|
+
const raw = capture.stdout.trim();
|
|
165
|
+
if (raw.length === 0)
|
|
166
|
+
throw new Error("AMQ returned empty JSON stdout");
|
|
167
|
+
const value = JSON.parse(raw);
|
|
168
|
+
json = parser ? parser(value) : value;
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
jsonError = toError(error);
|
|
172
|
+
}
|
|
173
|
+
const category = categorize(capture, jsonError);
|
|
174
|
+
return {
|
|
175
|
+
ok: category === "success",
|
|
176
|
+
category,
|
|
177
|
+
exitCode: capture.exitCode,
|
|
178
|
+
signal: capture.signal,
|
|
179
|
+
stdout: capture.stdout,
|
|
180
|
+
stderr: capture.stderr,
|
|
181
|
+
stdoutTruncated: capture.stdoutTruncated,
|
|
182
|
+
stderrTruncated: capture.stderrTruncated,
|
|
183
|
+
...(json === undefined ? {} : { json }),
|
|
184
|
+
...(jsonError ? { jsonError } : {}),
|
|
185
|
+
...(capture.processError ? { processError: capture.processError } : {}),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function categorize(capture, jsonError) {
|
|
189
|
+
if (capture.aborted)
|
|
190
|
+
return "cancelled";
|
|
191
|
+
if (capture.stdoutTruncated || capture.stderrTruncated)
|
|
192
|
+
return "output-limit";
|
|
193
|
+
if (capture.processError)
|
|
194
|
+
return "spawn-error";
|
|
195
|
+
if (capture.exitCode === null)
|
|
196
|
+
return "process-crash";
|
|
197
|
+
switch (capture.exitCode) {
|
|
198
|
+
case 0:
|
|
199
|
+
return jsonError ? "invalid-json" : "success";
|
|
200
|
+
case 1:
|
|
201
|
+
return "error";
|
|
202
|
+
case 2:
|
|
203
|
+
return "usage";
|
|
204
|
+
case 3:
|
|
205
|
+
return "not-found";
|
|
206
|
+
case 4:
|
|
207
|
+
return "timeout";
|
|
208
|
+
case 5:
|
|
209
|
+
return "context-mismatch";
|
|
210
|
+
default:
|
|
211
|
+
return "error";
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
async function createTemporaryBody(parent, body) {
|
|
215
|
+
const directory = await mkdtemp(join(parent, "pi-amq-body-"));
|
|
216
|
+
await chmod(directory, 0o700);
|
|
217
|
+
const path = join(directory, "body");
|
|
218
|
+
try {
|
|
219
|
+
const handle = await open(path, "wx", 0o600);
|
|
220
|
+
try {
|
|
221
|
+
await handle.writeFile(body, "utf8");
|
|
222
|
+
}
|
|
223
|
+
finally {
|
|
224
|
+
await handle.close();
|
|
225
|
+
}
|
|
226
|
+
await chmod(path, 0o600);
|
|
227
|
+
return { directory, path };
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
await cleanupTemporaryBody({ directory, path });
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
async function cleanupTemporaryBody(temporary) {
|
|
235
|
+
const errors = [];
|
|
236
|
+
try {
|
|
237
|
+
await unlink(temporary.path);
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
if (!isMissing(error))
|
|
241
|
+
errors.push(toError(error));
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
await rmdir(temporary.directory);
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
if (!isMissing(error))
|
|
248
|
+
errors.push(toError(error));
|
|
249
|
+
}
|
|
250
|
+
if (errors.length === 0)
|
|
251
|
+
return undefined;
|
|
252
|
+
return errors.length === 1 ? errors[0] : new AggregateError(errors, "temporary AMQ body cleanup failed");
|
|
253
|
+
}
|
|
254
|
+
function validateArgv(argv) {
|
|
255
|
+
if (argv.length === 0)
|
|
256
|
+
throw new TypeError("AMQ argv must include a command");
|
|
257
|
+
for (const argument of argv) {
|
|
258
|
+
if (argument.includes("\0"))
|
|
259
|
+
throw new TypeError("AMQ argv cannot contain NUL bytes");
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function positiveInteger(value, name) {
|
|
263
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
264
|
+
throw new TypeError(`${name} must be a positive safe integer`);
|
|
265
|
+
}
|
|
266
|
+
return value;
|
|
267
|
+
}
|
|
268
|
+
function nonNegativeInteger(value, name) {
|
|
269
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
270
|
+
throw new TypeError(`${name} must be a non-negative safe integer`);
|
|
271
|
+
}
|
|
272
|
+
return value;
|
|
273
|
+
}
|
|
274
|
+
function emptyCapture(aborted) {
|
|
275
|
+
return {
|
|
276
|
+
exitCode: null,
|
|
277
|
+
signal: null,
|
|
278
|
+
stdout: "",
|
|
279
|
+
stderr: "",
|
|
280
|
+
stdoutTruncated: false,
|
|
281
|
+
stderrTruncated: false,
|
|
282
|
+
aborted,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function isMissing(error) {
|
|
286
|
+
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
287
|
+
}
|
|
288
|
+
function toError(error) {
|
|
289
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=amq-cli-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amq-cli-adapter.js","sourceRoot":"","sources":["../../transport/amq-cli-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type AmqPriority = "urgent" | "normal" | "low";
|
|
2
|
+
export interface AmqHeaderV1 {
|
|
3
|
+
readonly schema: 1;
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly from: string;
|
|
6
|
+
readonly to: readonly string[];
|
|
7
|
+
readonly thread: string;
|
|
8
|
+
readonly subject: string;
|
|
9
|
+
readonly created: string;
|
|
10
|
+
readonly priority: AmqPriority;
|
|
11
|
+
readonly kind: string;
|
|
12
|
+
readonly labels: readonly string[];
|
|
13
|
+
readonly context: Readonly<Record<string, unknown>>;
|
|
14
|
+
readonly replyTo: string;
|
|
15
|
+
readonly replyProject: string;
|
|
16
|
+
readonly fromProject: string;
|
|
17
|
+
}
|
|
18
|
+
export interface AmqMessage {
|
|
19
|
+
readonly header: AmqHeaderV1;
|
|
20
|
+
readonly body: string;
|
|
21
|
+
}
|
|
22
|
+
export interface WatchCandidate {
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly priority: AmqPriority;
|
|
25
|
+
readonly created: string;
|
|
26
|
+
readonly parseError?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface WatchCohort {
|
|
29
|
+
readonly event: "existing" | "new_message" | "timeout";
|
|
30
|
+
readonly messages: readonly WatchCandidate[];
|
|
31
|
+
}
|
|
32
|
+
export type AmqReadOutcome = {
|
|
33
|
+
readonly kind: "message";
|
|
34
|
+
readonly message: AmqMessage;
|
|
35
|
+
} | {
|
|
36
|
+
readonly kind: "dlq";
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly diagnostic: string;
|
|
39
|
+
};
|
|
40
|
+
export declare function parseWatchCohort(value: unknown): WatchCohort;
|
|
41
|
+
export declare function parseMessageList(value: unknown): readonly WatchCandidate[];
|
|
42
|
+
export declare function parseWatchCandidate(value: unknown): WatchCandidate;
|
|
43
|
+
export declare function parseAmqReadOutcome(value: unknown): AmqReadOutcome;
|
|
44
|
+
export declare function parseAmqHeaderV1(value: unknown): AmqHeaderV1;
|
|
45
|
+
export declare function sortAndDeduplicateCandidates(candidates: readonly WatchCandidate[]): readonly WatchCandidate[];
|
|
46
|
+
export declare function sortMessages(messages: readonly AmqMessage[]): readonly AmqMessage[];
|
|
47
|
+
//# sourceMappingURL=amq-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amq-message.d.ts","sourceRoot":"","sources":["../../transport/amq-message.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;CAC9C;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAoB/E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAY5D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,cAAc,EAAE,CAG1E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAalE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAalE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAyB5D;AAED,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,SAAS,cAAc,EAAE,GACpC,SAAS,cAAc,EAAE,CAQ3B;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,GAAG,SAAS,UAAU,EAAE,CAKnF"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
const PRIORITY_RANK = {
|
|
2
|
+
urgent: 0,
|
|
3
|
+
normal: 1,
|
|
4
|
+
low: 2,
|
|
5
|
+
};
|
|
6
|
+
const VALID_KINDS = new Set([
|
|
7
|
+
"",
|
|
8
|
+
"brainstorm",
|
|
9
|
+
"review_request",
|
|
10
|
+
"review_response",
|
|
11
|
+
"question",
|
|
12
|
+
"answer",
|
|
13
|
+
"decision",
|
|
14
|
+
"status",
|
|
15
|
+
"todo",
|
|
16
|
+
]);
|
|
17
|
+
export function parseWatchCohort(value) {
|
|
18
|
+
const object = record(value, "amq watch --json");
|
|
19
|
+
const event = object.event;
|
|
20
|
+
if (event !== "existing" && event !== "new_message" && event !== "timeout") {
|
|
21
|
+
throw new Error("amq watch event is invalid");
|
|
22
|
+
}
|
|
23
|
+
const rawMessages = object.messages ?? [];
|
|
24
|
+
if (!Array.isArray(rawMessages))
|
|
25
|
+
throw new Error("amq watch messages must be an array");
|
|
26
|
+
return {
|
|
27
|
+
event,
|
|
28
|
+
messages: rawMessages.map(parseWatchCandidate),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function parseMessageList(value) {
|
|
32
|
+
if (!Array.isArray(value))
|
|
33
|
+
throw new Error("amq list --json must return an array");
|
|
34
|
+
return value.map(parseWatchCandidate);
|
|
35
|
+
}
|
|
36
|
+
export function parseWatchCandidate(value) {
|
|
37
|
+
const object = record(value, "AMQ message header projection");
|
|
38
|
+
const id = messageId(object.id);
|
|
39
|
+
const parseError = optionalString(object.parse_error, "parse_error");
|
|
40
|
+
const created = stringOrEmpty(object.created, "created");
|
|
41
|
+
const rawPriority = stringOrEmpty(object.priority, "priority");
|
|
42
|
+
if (!parseError)
|
|
43
|
+
requireIso(created, "created");
|
|
44
|
+
return {
|
|
45
|
+
id,
|
|
46
|
+
priority: parsePriority(rawPriority),
|
|
47
|
+
created,
|
|
48
|
+
...(parseError ? { parseError } : {}),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function parseAmqReadOutcome(value) {
|
|
52
|
+
const object = record(value, "amq read --json");
|
|
53
|
+
if (object.moved_to_dlq === true) {
|
|
54
|
+
return {
|
|
55
|
+
kind: "dlq",
|
|
56
|
+
id: messageId(object.id),
|
|
57
|
+
diagnostic: requiredString(object.parse_error, "parse_error"),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const header = parseAmqHeaderV1(object.header);
|
|
61
|
+
const body = object.body;
|
|
62
|
+
if (typeof body !== "string")
|
|
63
|
+
throw new Error("amq read body must be a string");
|
|
64
|
+
return { kind: "message", message: { header, body } };
|
|
65
|
+
}
|
|
66
|
+
export function parseAmqHeaderV1(value) {
|
|
67
|
+
const object = record(value, "AMQ header");
|
|
68
|
+
if (number(object.schema, "schema") !== 1)
|
|
69
|
+
throw new Error("AMQ header schema must be 1");
|
|
70
|
+
const kind = stringOrEmpty(object.kind, "kind");
|
|
71
|
+
if (!VALID_KINDS.has(kind))
|
|
72
|
+
throw new Error(`AMQ header kind is invalid: ${kind}`);
|
|
73
|
+
const context = object.context === undefined
|
|
74
|
+
? {}
|
|
75
|
+
: record(object.context, "AMQ header context");
|
|
76
|
+
const header = {
|
|
77
|
+
schema: 1,
|
|
78
|
+
id: messageId(object.id),
|
|
79
|
+
from: requiredString(object.from, "from"),
|
|
80
|
+
to: stringArray(object.to, "to", false),
|
|
81
|
+
thread: requiredString(object.thread, "thread"),
|
|
82
|
+
subject: stringOrEmpty(object.subject, "subject"),
|
|
83
|
+
created: requireIso(requiredString(object.created, "created"), "created"),
|
|
84
|
+
priority: parsePriority(stringOrEmpty(object.priority, "priority")),
|
|
85
|
+
kind,
|
|
86
|
+
labels: stringArray(object.labels ?? [], "labels", true),
|
|
87
|
+
context,
|
|
88
|
+
replyTo: stringOrEmpty(object.reply_to, "reply_to"),
|
|
89
|
+
replyProject: stringOrEmpty(object.reply_project, "reply_project"),
|
|
90
|
+
fromProject: stringOrEmpty(object.from_project, "from_project"),
|
|
91
|
+
};
|
|
92
|
+
return header;
|
|
93
|
+
}
|
|
94
|
+
export function sortAndDeduplicateCandidates(candidates) {
|
|
95
|
+
const sorted = [...candidates].sort(compareIncoming);
|
|
96
|
+
const seen = new Set();
|
|
97
|
+
return sorted.filter((candidate) => {
|
|
98
|
+
if (seen.has(candidate.id))
|
|
99
|
+
return false;
|
|
100
|
+
seen.add(candidate.id);
|
|
101
|
+
return true;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
export function sortMessages(messages) {
|
|
105
|
+
return [...messages].sort((left, right) => compareIncoming({ id: left.header.id, priority: left.header.priority, created: left.header.created }, { id: right.header.id, priority: right.header.priority, created: right.header.created }));
|
|
106
|
+
}
|
|
107
|
+
function compareIncoming(left, right) {
|
|
108
|
+
const invalidOrder = Number(Boolean(right.parseError)) - Number(Boolean(left.parseError));
|
|
109
|
+
if (invalidOrder !== 0)
|
|
110
|
+
return invalidOrder;
|
|
111
|
+
const priorityOrder = PRIORITY_RANK[left.priority] - PRIORITY_RANK[right.priority];
|
|
112
|
+
if (priorityOrder !== 0)
|
|
113
|
+
return priorityOrder;
|
|
114
|
+
const createdOrder = left.created.localeCompare(right.created);
|
|
115
|
+
return createdOrder !== 0 ? createdOrder : left.id.localeCompare(right.id);
|
|
116
|
+
}
|
|
117
|
+
function parsePriority(value) {
|
|
118
|
+
if (value === "" || value === "normal")
|
|
119
|
+
return "normal";
|
|
120
|
+
if (value === "urgent" || value === "low")
|
|
121
|
+
return value;
|
|
122
|
+
throw new Error(`AMQ priority is invalid: ${value}`);
|
|
123
|
+
}
|
|
124
|
+
function messageId(value) {
|
|
125
|
+
const id = requiredString(value, "id");
|
|
126
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,254}$/.test(id)) {
|
|
127
|
+
throw new Error("AMQ message ID is not safe for the extension namespace");
|
|
128
|
+
}
|
|
129
|
+
return id;
|
|
130
|
+
}
|
|
131
|
+
function record(value, name) {
|
|
132
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
133
|
+
throw new Error(`${name} must be an object`);
|
|
134
|
+
}
|
|
135
|
+
return value;
|
|
136
|
+
}
|
|
137
|
+
function requiredString(value, name) {
|
|
138
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
139
|
+
throw new Error(`${name} must be a non-empty string`);
|
|
140
|
+
}
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
function optionalString(value, name) {
|
|
144
|
+
if (value === undefined || value === "")
|
|
145
|
+
return undefined;
|
|
146
|
+
if (typeof value !== "string")
|
|
147
|
+
throw new Error(`${name} must be a string`);
|
|
148
|
+
return value;
|
|
149
|
+
}
|
|
150
|
+
function stringOrEmpty(value, name) {
|
|
151
|
+
if (value === undefined)
|
|
152
|
+
return "";
|
|
153
|
+
if (typeof value !== "string")
|
|
154
|
+
throw new Error(`${name} must be a string`);
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
function stringArray(value, name, allowEmpty) {
|
|
158
|
+
if (!Array.isArray(value) || (!allowEmpty && value.length === 0)) {
|
|
159
|
+
throw new Error(`${name} must be ${allowEmpty ? "an" : "a non-empty"} array`);
|
|
160
|
+
}
|
|
161
|
+
return value.map((item, index) => requiredString(item, `${name}[${index}]`));
|
|
162
|
+
}
|
|
163
|
+
function number(value, name) {
|
|
164
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
165
|
+
throw new Error(`${name} must be a number`);
|
|
166
|
+
return value;
|
|
167
|
+
}
|
|
168
|
+
function requireIso(value, name) {
|
|
169
|
+
if (!Number.isFinite(Date.parse(value)))
|
|
170
|
+
throw new Error(`${name} must be an ISO timestamp`);
|
|
171
|
+
return value;
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=amq-message.js.map
|