wicked-crew 0.7.39 → 0.7.45
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/api/audit.d.ts +3 -0
- package/dist/api/audit.d.ts.map +1 -1
- package/dist/api/audit.js +2 -0
- package/dist/api/audit.js.map +1 -1
- package/dist/api/capture.d.ts +149 -0
- package/dist/api/capture.d.ts.map +1 -0
- package/dist/api/capture.js +330 -0
- package/dist/api/capture.js.map +1 -0
- package/dist/api/chat-citations.d.ts +174 -0
- package/dist/api/chat-citations.d.ts.map +1 -0
- package/dist/api/chat-citations.js +528 -0
- package/dist/api/chat-citations.js.map +1 -0
- package/dist/api/chat-scope.d.ts +37 -1
- package/dist/api/chat-scope.d.ts.map +1 -1
- package/dist/api/chat-scope.js +131 -7
- package/dist/api/chat-scope.js.map +1 -1
- package/dist/api/chat-transcripts.d.ts +20 -1
- package/dist/api/chat-transcripts.d.ts.map +1 -1
- package/dist/api/chat-transcripts.js +29 -0
- package/dist/api/chat-transcripts.js.map +1 -1
- package/dist/api/delivery-cache.d.ts +2 -2
- package/dist/api/delivery-freeze.d.ts +66 -0
- package/dist/api/delivery-freeze.d.ts.map +1 -0
- package/dist/api/delivery-freeze.js +104 -0
- package/dist/api/delivery-freeze.js.map +1 -0
- package/dist/api/delivery-index.d.ts +53 -9
- package/dist/api/delivery-index.d.ts.map +1 -1
- package/dist/api/delivery-index.js +115 -22
- package/dist/api/delivery-index.js.map +1 -1
- package/dist/api/demo.d.ts +90 -0
- package/dist/api/demo.d.ts.map +1 -0
- package/dist/api/demo.js +492 -0
- package/dist/api/demo.js.map +1 -0
- package/dist/api/diagnostics.d.ts +64 -1
- package/dist/api/diagnostics.d.ts.map +1 -1
- package/dist/api/diagnostics.js +129 -1
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/api/eval-sample.d.ts +6 -6
- package/dist/api/governance-steering.d.ts +2 -2
- package/dist/api/mcp.d.ts +282 -0
- package/dist/api/mcp.d.ts.map +1 -0
- package/dist/api/mcp.js +521 -0
- package/dist/api/mcp.js.map +1 -0
- package/dist/api/plan-schema.d.ts +56 -0
- package/dist/api/plan-schema.d.ts.map +1 -0
- package/dist/api/plan-schema.js +26 -0
- package/dist/api/plan-schema.js.map +1 -0
- package/dist/api/roster-standing.d.ts +15 -2
- package/dist/api/roster-standing.d.ts.map +1 -1
- package/dist/api/roster-standing.js +55 -3
- package/dist/api/roster-standing.js.map +1 -1
- package/dist/api/routes.d.ts +647 -59
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +906 -146
- package/dist/api/routes.js.map +1 -1
- package/dist/api/run-files.d.ts.map +1 -1
- package/dist/api/run-files.js +31 -2
- package/dist/api/run-files.js.map +1 -1
- package/dist/api/run-liveness.d.ts +41 -0
- package/dist/api/run-liveness.d.ts.map +1 -0
- package/dist/api/run-liveness.js +166 -0
- package/dist/api/run-liveness.js.map +1 -0
- package/dist/api/run-timing-index.d.ts +10 -0
- package/dist/api/run-timing-index.d.ts.map +1 -1
- package/dist/api/run-timing-index.js +24 -0
- package/dist/api/run-timing-index.js.map +1 -1
- package/dist/api/seat-health.d.ts.map +1 -1
- package/dist/api/seat-health.js +20 -4
- package/dist/api/seat-health.js.map +1 -1
- package/dist/api/seat-probe.d.ts +141 -0
- package/dist/api/seat-probe.d.ts.map +1 -0
- package/dist/api/seat-probe.js +257 -0
- package/dist/api/seat-probe.js.map +1 -0
- package/dist/api/seat-record.d.ts +40 -0
- package/dist/api/seat-record.d.ts.map +1 -0
- package/dist/api/seat-record.js +218 -0
- package/dist/api/seat-record.js.map +1 -0
- package/dist/api/seat-signin.d.ts.map +1 -1
- package/dist/api/seat-signin.js +3 -1
- package/dist/api/seat-signin.js.map +1 -1
- package/dist/api/seat-standing.d.ts +24 -4
- package/dist/api/seat-standing.d.ts.map +1 -1
- package/dist/api/seat-standing.js +50 -3
- package/dist/api/seat-standing.js.map +1 -1
- package/dist/api/server.d.ts +34 -48
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +316 -116
- package/dist/api/server.js.map +1 -1
- package/dist/api/skills.d.ts +3 -1
- package/dist/api/skills.d.ts.map +1 -1
- package/dist/api/skills.js +7 -2
- package/dist/api/skills.js.map +1 -1
- package/dist/api/stall-watchdog.d.ts +34 -3
- package/dist/api/stall-watchdog.d.ts.map +1 -1
- package/dist/api/stall-watchdog.js +107 -8
- package/dist/api/stall-watchdog.js.map +1 -1
- package/dist/api/steering-landing.d.ts +6 -6
- package/dist/api/steering-landing.d.ts.map +1 -1
- package/dist/api/steering-landing.js +7 -9
- package/dist/api/steering-landing.js.map +1 -1
- package/dist/api/testing.d.ts +6 -4
- package/dist/api/testing.d.ts.map +1 -1
- package/dist/api/testing.js +82 -47
- package/dist/api/testing.js.map +1 -1
- package/dist/campaign/boot-resume.d.ts +34 -0
- package/dist/campaign/boot-resume.d.ts.map +1 -0
- package/dist/campaign/boot-resume.js +45 -0
- package/dist/campaign/boot-resume.js.map +1 -0
- package/dist/campaigns/rollup.d.ts +4 -1
- package/dist/campaigns/rollup.d.ts.map +1 -1
- package/dist/campaigns/rollup.js +6 -1
- package/dist/campaigns/rollup.js.map +1 -1
- package/dist/campaigns/routes.d.ts +2 -2
- package/dist/cli/bearer.d.ts +27 -1
- package/dist/cli/bearer.d.ts.map +1 -1
- package/dist/cli/bearer.js +62 -2
- package/dist/cli/bearer.js.map +1 -1
- package/dist/cli/governance.d.ts +11 -0
- package/dist/cli/governance.d.ts.map +1 -1
- package/dist/cli/governance.js +8 -2
- package/dist/cli/governance.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +140 -75
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp.d.ts +11 -0
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +40 -9
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/service.d.ts +78 -0
- package/dist/cli/service.d.ts.map +1 -0
- package/dist/cli/service.js +334 -0
- package/dist/cli/service.js.map +1 -0
- package/dist/core/adapter.d.ts +247 -14
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +638 -161
- package/dist/core/adapter.js.map +1 -1
- package/dist/core/bridge-reaper.d.ts +4 -1
- package/dist/core/bridge-reaper.d.ts.map +1 -1
- package/dist/core/bridge-reaper.js +15 -1
- package/dist/core/bridge-reaper.js.map +1 -1
- package/dist/core/bus-notice.d.ts +27 -0
- package/dist/core/bus-notice.d.ts.map +1 -0
- package/dist/core/bus-notice.js +24 -0
- package/dist/core/bus-notice.js.map +1 -0
- package/dist/core/bus.d.ts +99 -0
- package/dist/core/bus.d.ts.map +1 -0
- package/dist/core/bus.js +176 -0
- package/dist/core/bus.js.map +1 -0
- package/dist/core/deliver-exclusions.d.ts +71 -0
- package/dist/core/deliver-exclusions.d.ts.map +1 -0
- package/dist/core/deliver-exclusions.js +110 -0
- package/dist/core/deliver-exclusions.js.map +1 -0
- package/dist/core/deliver-text.d.ts +61 -14
- package/dist/core/deliver-text.d.ts.map +1 -1
- package/dist/core/deliver-text.js +178 -30
- package/dist/core/deliver-text.js.map +1 -1
- package/dist/core/deliver-triage.d.ts +11 -2
- package/dist/core/deliver-triage.d.ts.map +1 -1
- package/dist/core/deliver-triage.js +19 -1
- package/dist/core/deliver-triage.js.map +1 -1
- package/dist/core/deliver.d.ts +161 -3
- package/dist/core/deliver.d.ts.map +1 -1
- package/dist/core/deliver.js +463 -25
- package/dist/core/deliver.js.map +1 -1
- package/dist/core/deliverable-floor.d.ts.map +1 -1
- package/dist/core/deliverable-floor.js +5 -7
- package/dist/core/deliverable-floor.js.map +1 -1
- package/dist/core/engine-bus.d.ts +40 -0
- package/dist/core/engine-bus.d.ts.map +1 -0
- package/dist/core/engine-bus.js +27 -0
- package/dist/core/engine-bus.js.map +1 -0
- package/dist/core/estate-mcp-client.d.ts +87 -5
- package/dist/core/estate-mcp-client.d.ts.map +1 -1
- package/dist/core/estate-mcp-client.js +90 -11
- package/dist/core/estate-mcp-client.js.map +1 -1
- package/dist/core/linked-issues.d.ts +46 -0
- package/dist/core/linked-issues.d.ts.map +1 -0
- package/dist/core/linked-issues.js +123 -0
- package/dist/core/linked-issues.js.map +1 -0
- package/dist/core/run-identity.d.ts +100 -0
- package/dist/core/run-identity.d.ts.map +1 -0
- package/dist/core/run-identity.js +178 -0
- package/dist/core/run-identity.js.map +1 -0
- package/dist/core/shutdown.d.ts +16 -0
- package/dist/core/shutdown.d.ts.map +1 -0
- package/dist/core/shutdown.js +39 -0
- package/dist/core/shutdown.js.map +1 -0
- package/dist/core/types.d.ts +15 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +4 -0
- package/dist/core/types.js.map +1 -1
- package/dist/interactive/bridge-pool.d.ts +67 -3
- package/dist/interactive/bridge-pool.d.ts.map +1 -1
- package/dist/interactive/bridge-pool.js +129 -13
- package/dist/interactive/bridge-pool.js.map +1 -1
- package/dist/interactive/bridge-root.d.ts +9 -0
- package/dist/interactive/bridge-root.d.ts.map +1 -1
- package/dist/interactive/bridge-root.js +11 -4
- package/dist/interactive/bridge-root.js.map +1 -1
- package/dist/interactive/chat-events.d.ts +14 -9
- package/dist/interactive/chat-events.d.ts.map +1 -1
- package/dist/interactive/chat-events.js +55 -57
- package/dist/interactive/chat-events.js.map +1 -1
- package/dist/interactive/council-outcome.d.ts +1 -0
- package/dist/interactive/council-outcome.d.ts.map +1 -1
- package/dist/interactive/council-outcome.js +33 -0
- package/dist/interactive/council-outcome.js.map +1 -1
- package/dist/interactive/draft-events.d.ts +36 -17
- package/dist/interactive/draft-events.d.ts.map +1 -1
- package/dist/interactive/draft-events.js +121 -92
- package/dist/interactive/draft-events.js.map +1 -1
- package/dist/interactive/draft-skill.d.ts +59 -0
- package/dist/interactive/draft-skill.d.ts.map +1 -1
- package/dist/interactive/draft-skill.js +233 -0
- package/dist/interactive/draft-skill.js.map +1 -1
- package/dist/interactive/edit-events.d.ts +1 -14
- package/dist/interactive/edit-events.d.ts.map +1 -1
- package/dist/interactive/edit-events.js +37 -70
- package/dist/interactive/edit-events.js.map +1 -1
- package/dist/interactive/proxy-routes.d.ts +2 -2
- package/dist/interactive/proxy-routes.d.ts.map +1 -1
- package/dist/interactive/proxy-routes.js +4 -13
- package/dist/interactive/proxy-routes.js.map +1 -1
- package/dist/interactive/ws-relay.d.ts +9 -10
- package/dist/interactive/ws-relay.d.ts.map +1 -1
- package/dist/interactive/ws-relay.js +23 -50
- package/dist/interactive/ws-relay.js.map +1 -1
- package/dist/mcp/broker.d.ts +88 -0
- package/dist/mcp/broker.d.ts.map +1 -0
- package/dist/mcp/broker.js +307 -0
- package/dist/mcp/broker.js.map +1 -0
- package/dist/mcp/call-records.d.ts +61 -0
- package/dist/mcp/call-records.d.ts.map +1 -0
- package/dist/mcp/call-records.js +135 -0
- package/dist/mcp/call-records.js.map +1 -0
- package/dist/mcp/classify.d.ts +45 -0
- package/dist/mcp/classify.d.ts.map +1 -0
- package/dist/mcp/classify.js +83 -0
- package/dist/mcp/classify.js.map +1 -0
- package/dist/mcp/discovery.d.ts +24 -0
- package/dist/mcp/discovery.d.ts.map +1 -0
- package/dist/mcp/discovery.js +78 -0
- package/dist/mcp/discovery.js.map +1 -0
- package/dist/mcp/invoke.d.ts +36 -0
- package/dist/mcp/invoke.d.ts.map +1 -0
- package/dist/mcp/invoke.js +80 -0
- package/dist/mcp/invoke.js.map +1 -0
- package/dist/mcp/policies.d.ts +110 -0
- package/dist/mcp/policies.d.ts.map +1 -0
- package/dist/mcp/policies.js +400 -0
- package/dist/mcp/policies.js.map +1 -0
- package/dist/mcp/probe.d.ts +66 -0
- package/dist/mcp/probe.d.ts.map +1 -0
- package/dist/mcp/probe.js +116 -0
- package/dist/mcp/probe.js.map +1 -0
- package/dist/mcp/redact.d.ts +34 -0
- package/dist/mcp/redact.d.ts.map +1 -0
- package/dist/mcp/redact.js +84 -0
- package/dist/mcp/redact.js.map +1 -0
- package/dist/mcp/registry-store.d.ts +69 -0
- package/dist/mcp/registry-store.d.ts.map +1 -0
- package/dist/mcp/registry-store.js +82 -0
- package/dist/mcp/registry-store.js.map +1 -0
- package/dist/mcp/registry.d.ts +147 -0
- package/dist/mcp/registry.d.ts.map +1 -0
- package/dist/mcp/registry.js +509 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/rest.d.ts +111 -0
- package/dist/mcp/rest.d.ts.map +1 -0
- package/dist/mcp/rest.js +606 -0
- package/dist/mcp/rest.js.map +1 -0
- package/dist/mcp/secrets.d.ts +66 -0
- package/dist/mcp/secrets.d.ts.map +1 -0
- package/dist/mcp/secrets.js +180 -0
- package/dist/mcp/secrets.js.map +1 -0
- package/dist/mcp/tool-list.d.ts +25 -0
- package/dist/mcp/tool-list.d.ts.map +1 -0
- package/dist/mcp/tool-list.js +62 -0
- package/dist/mcp/tool-list.js.map +1 -0
- package/dist/mcp/upstream-error.d.ts +12 -0
- package/dist/mcp/upstream-error.d.ts.map +1 -0
- package/dist/mcp/upstream-error.js +14 -0
- package/dist/mcp/upstream-error.js.map +1 -0
- package/dist/mcp/usage.d.ts +31 -0
- package/dist/mcp/usage.d.ts.map +1 -0
- package/dist/mcp/usage.js +159 -0
- package/dist/mcp/usage.js.map +1 -0
- package/dist/presets/routes.d.ts +53 -0
- package/dist/presets/routes.d.ts.map +1 -0
- package/dist/presets/routes.js +115 -0
- package/dist/presets/routes.js.map +1 -0
- package/dist/projects/activity.d.ts +6 -18
- package/dist/projects/activity.d.ts.map +1 -1
- package/dist/projects/activity.js +17 -60
- package/dist/projects/activity.js.map +1 -1
- package/dist/projects/events.d.ts +6 -5
- package/dist/projects/events.d.ts.map +1 -1
- package/dist/projects/events.js +33 -58
- package/dist/projects/events.js.map +1 -1
- package/dist/projects/graph.d.ts +11 -0
- package/dist/projects/graph.d.ts.map +1 -1
- package/dist/projects/graph.js +12 -0
- package/dist/projects/graph.js.map +1 -1
- package/dist/projects/routes.d.ts.map +1 -1
- package/dist/projects/routes.js +19 -0
- package/dist/projects/routes.js.map +1 -1
- package/dist/projects/state-home-preflight.d.ts.map +1 -1
- package/dist/projects/state-home-preflight.js +7 -0
- package/dist/projects/state-home-preflight.js.map +1 -1
- package/dist/projects/state-home-registry.d.ts.map +1 -1
- package/dist/projects/state-home-registry.js +9 -1
- package/dist/projects/state-home-registry.js.map +1 -1
- package/dist/qe/acceptance.d.ts +28 -28
- package/dist/qe/acceptance.d.ts.map +1 -1
- package/dist/qe/acceptance.js +60 -61
- package/dist/qe/acceptance.js.map +1 -1
- package/dist/qe/test-sets.d.ts +3 -5
- package/dist/qe/test-sets.d.ts.map +1 -1
- package/dist/qe/test-sets.js +5 -7
- package/dist/qe/test-sets.js.map +1 -1
- package/dist/skills/installed.d.ts +51 -0
- package/dist/skills/installed.d.ts.map +1 -0
- package/dist/skills/installed.js +46 -0
- package/dist/skills/installed.js.map +1 -0
- package/dist/skills/phase-skill-gaps.d.ts +108 -0
- package/dist/skills/phase-skill-gaps.d.ts.map +1 -0
- package/dist/skills/phase-skill-gaps.js +199 -0
- package/dist/skills/phase-skill-gaps.js.map +1 -0
- package/dist/skills/runtime.d.ts +1 -1
- package/dist/skills/runtime.d.ts.map +1 -1
- package/dist/skills/runtime.js +2 -1
- package/dist/skills/runtime.js.map +1 -1
- package/dist/standing-orders/evaluator.d.ts +113 -0
- package/dist/standing-orders/evaluator.d.ts.map +1 -0
- package/dist/standing-orders/evaluator.js +225 -0
- package/dist/standing-orders/evaluator.js.map +1 -0
- package/dist/standing-orders/history.d.ts +58 -0
- package/dist/standing-orders/history.d.ts.map +1 -0
- package/dist/standing-orders/history.js +117 -0
- package/dist/standing-orders/history.js.map +1 -0
- package/dist/standing-orders/parse.d.ts +19 -0
- package/dist/standing-orders/parse.d.ts.map +1 -0
- package/dist/standing-orders/parse.js +75 -0
- package/dist/standing-orders/parse.js.map +1 -0
- package/dist/standing-orders/routes.d.ts +180 -0
- package/dist/standing-orders/routes.d.ts.map +1 -0
- package/dist/standing-orders/routes.js +95 -0
- package/dist/standing-orders/routes.js.map +1 -0
- package/dist/standing-orders/store.d.ts +154 -0
- package/dist/standing-orders/store.d.ts.map +1 -0
- package/dist/standing-orders/store.js +189 -0
- package/dist/standing-orders/store.js.map +1 -0
- package/dist/studio/assets/index-CvV5qITf.css +32 -0
- package/dist/studio/assets/index-jCOy6Ns7.js +568 -0
- package/dist/studio/index.html +3 -3
- package/dist/studio/testid-inventory.json +3307 -897
- package/dist/team/key.d.ts +5 -0
- package/dist/team/key.d.ts.map +1 -0
- package/dist/team/key.js +21 -0
- package/dist/team/key.js.map +1 -0
- package/dist/team/routes.d.ts +196 -0
- package/dist/team/routes.d.ts.map +1 -0
- package/dist/team/routes.js +274 -0
- package/dist/team/routes.js.map +1 -0
- package/dist/team/ws-relay.d.ts +39 -0
- package/dist/team/ws-relay.d.ts.map +1 -0
- package/dist/team/ws-relay.js +63 -0
- package/dist/team/ws-relay.js.map +1 -0
- package/endpoint-manifest.json +502 -6
- package/package.json +6 -6
- package/dist/interactive/demo-events.d.ts +0 -367
- package/dist/interactive/demo-events.d.ts.map +0 -1
- package/dist/interactive/demo-events.js +0 -1293
- package/dist/interactive/demo-events.js.map +0 -1
- package/dist/qe/gate-events.d.ts +0 -113
- package/dist/qe/gate-events.d.ts.map +0 -1
- package/dist/qe/gate-events.js +0 -172
- package/dist/qe/gate-events.js.map +0 -1
- package/dist/studio/assets/index-BRDAN35i.js +0 -548
- package/dist/studio/assets/index-Drfcsy8b.css +0 -32
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** `deterministic_key(parts)`: 32 lowercase hex characters. */
|
|
2
|
+
export declare function deterministicKey(parts: readonly string[]): string;
|
|
3
|
+
/** A team event's key: `deterministic_key(["team", eventType, runId, ...parts])` (DES-002 §6.1). */
|
|
4
|
+
export declare function teamKey(eventType: string, runId: string, parts?: readonly string[]): string;
|
|
5
|
+
//# sourceMappingURL=key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../src/team/key.ts"],"names":[],"mappings":"AASA,+DAA+D;AAC/D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAOjE;AAED,oGAAoG;AACpG,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,CAE/F"}
|
package/dist/team/key.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// The team idempotency key, byte for byte as wicked-core's `crate::bus::deterministic_key`
|
|
2
|
+
// computes it (DES-TEAMING-002 §4.1): SHA-256 over every part's UTF-8 bytes followed by one 0x00
|
|
3
|
+
// byte (the last part is NUL-terminated too; this is not a `\0`-join), the first 16 bytes of the
|
|
4
|
+
// digest as lowercase hex. Crew publishes no team event (DES-002 §7); this exists so a crew-side
|
|
5
|
+
// reader can recompute a row's key, and so `tests/team-events.test.ts` pins the two
|
|
6
|
+
// implementations to the same vectors.
|
|
7
|
+
import { createHash } from 'node:crypto';
|
|
8
|
+
/** `deterministic_key(parts)`: 32 lowercase hex characters. */
|
|
9
|
+
export function deterministicKey(parts) {
|
|
10
|
+
const h = createHash('sha256');
|
|
11
|
+
for (const p of parts) {
|
|
12
|
+
h.update(Buffer.from(p, 'utf8'));
|
|
13
|
+
h.update(Buffer.from([0]));
|
|
14
|
+
}
|
|
15
|
+
return h.digest().subarray(0, 16).toString('hex');
|
|
16
|
+
}
|
|
17
|
+
/** A team event's key: `deterministic_key(["team", eventType, runId, ...parts])` (DES-002 §6.1). */
|
|
18
|
+
export function teamKey(eventType, runId, parts = []) {
|
|
19
|
+
return deterministicKey(['team', eventType, runId, ...parts]);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/team/key.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,iGAAiG;AACjG,iGAAiG;AACjG,iGAAiG;AACjG,oFAAoF;AACpF,uCAAuC;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,+DAA+D;AAC/D,MAAM,UAAU,gBAAgB,CAAC,KAAwB;IACvD,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACpD,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,OAAO,CAAC,SAAiB,EAAE,KAAa,EAAE,QAA2B,EAAE;IACrF,OAAO,gBAAgB,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The crew team surface (DES-TEAMING-002 T8): reads and commands over the engine. Commands go
|
|
3
|
+
* through the API, facts go on the bus (§4.0); crew publishes no team row.
|
|
4
|
+
*
|
|
5
|
+
* GET /runs/:id/team the engine's persisted team state (`Core.runTeam`) joined with the
|
|
6
|
+
* run's `wicked.team.*` bus rows and the folded ledger each gate read
|
|
7
|
+
* POST /runs/:id/plan a plan edit: at a `plan_approval` gate the gate answer
|
|
8
|
+
* (`confirmGate … edit_plan`), otherwise a mid-run edit (`Core.proposePlan`)
|
|
9
|
+
* POST /team/outbox/replay `Core.replayTeamOutbox`: the team outbox onto the bus
|
|
10
|
+
* GET /catalog the engine's phase catalog
|
|
11
|
+
* POST /plans/preview the launch's decision over a draft plan (`Core.previewPlan`)
|
|
12
|
+
*
|
|
13
|
+
* The live stream is the relay (`team/ws-relay.ts`). An addon without a binding answers 501.
|
|
14
|
+
*/
|
|
15
|
+
import type { FastifyInstance } from 'fastify';
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
import type { CoreAdapter } from '../core/adapter.js';
|
|
18
|
+
import type { RunTeamResponse, RunTeamView, TeamRow } from '../core/types.js';
|
|
19
|
+
import { AuditLog } from '../api/audit.js';
|
|
20
|
+
export declare const EditPlanSchema: z.ZodObject<{
|
|
21
|
+
plan: z.ZodObject<{
|
|
22
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
23
|
+
catalog: z.ZodString;
|
|
24
|
+
id: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
26
|
+
catalog: z.ZodString;
|
|
27
|
+
id: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
29
|
+
catalog: z.ZodString;
|
|
30
|
+
id: z.ZodOptional<z.ZodString>;
|
|
31
|
+
}, z.ZodTypeAny, "passthrough">>, "many">;
|
|
32
|
+
touch: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
33
|
+
override: z.ZodOptional<z.ZodObject<{
|
|
34
|
+
remove: z.ZodArray<z.ZodString, "many">;
|
|
35
|
+
reason: z.ZodString;
|
|
36
|
+
}, "strict", z.ZodTypeAny, {
|
|
37
|
+
reason: string;
|
|
38
|
+
remove: string[];
|
|
39
|
+
}, {
|
|
40
|
+
reason: string;
|
|
41
|
+
remove: string[];
|
|
42
|
+
}>>;
|
|
43
|
+
}, "strict", z.ZodTypeAny, {
|
|
44
|
+
steps: z.objectOutputType<{
|
|
45
|
+
catalog: z.ZodString;
|
|
46
|
+
id: z.ZodOptional<z.ZodString>;
|
|
47
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
48
|
+
override?: {
|
|
49
|
+
reason: string;
|
|
50
|
+
remove: string[];
|
|
51
|
+
} | undefined;
|
|
52
|
+
touch?: string[] | undefined;
|
|
53
|
+
}, {
|
|
54
|
+
steps: z.objectInputType<{
|
|
55
|
+
catalog: z.ZodString;
|
|
56
|
+
id: z.ZodOptional<z.ZodString>;
|
|
57
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
58
|
+
override?: {
|
|
59
|
+
reason: string;
|
|
60
|
+
remove: string[];
|
|
61
|
+
} | undefined;
|
|
62
|
+
touch?: string[] | undefined;
|
|
63
|
+
}>;
|
|
64
|
+
requestId: z.ZodOptional<z.ZodString>;
|
|
65
|
+
}, "strict", z.ZodTypeAny, {
|
|
66
|
+
plan: {
|
|
67
|
+
steps: z.objectOutputType<{
|
|
68
|
+
catalog: z.ZodString;
|
|
69
|
+
id: z.ZodOptional<z.ZodString>;
|
|
70
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
71
|
+
override?: {
|
|
72
|
+
reason: string;
|
|
73
|
+
remove: string[];
|
|
74
|
+
} | undefined;
|
|
75
|
+
touch?: string[] | undefined;
|
|
76
|
+
};
|
|
77
|
+
requestId?: string | undefined;
|
|
78
|
+
}, {
|
|
79
|
+
plan: {
|
|
80
|
+
steps: z.objectInputType<{
|
|
81
|
+
catalog: z.ZodString;
|
|
82
|
+
id: z.ZodOptional<z.ZodString>;
|
|
83
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
84
|
+
override?: {
|
|
85
|
+
reason: string;
|
|
86
|
+
remove: string[];
|
|
87
|
+
} | undefined;
|
|
88
|
+
touch?: string[] | undefined;
|
|
89
|
+
};
|
|
90
|
+
requestId?: string | undefined;
|
|
91
|
+
}>;
|
|
92
|
+
export declare const PlanPreviewSchema: z.ZodObject<{
|
|
93
|
+
plan: z.ZodObject<{
|
|
94
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
95
|
+
catalog: z.ZodString;
|
|
96
|
+
id: z.ZodOptional<z.ZodString>;
|
|
97
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
98
|
+
catalog: z.ZodString;
|
|
99
|
+
id: z.ZodOptional<z.ZodString>;
|
|
100
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
101
|
+
catalog: z.ZodString;
|
|
102
|
+
id: z.ZodOptional<z.ZodString>;
|
|
103
|
+
}, z.ZodTypeAny, "passthrough">>, "many">;
|
|
104
|
+
touch: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
105
|
+
override: z.ZodOptional<z.ZodObject<{
|
|
106
|
+
remove: z.ZodArray<z.ZodString, "many">;
|
|
107
|
+
reason: z.ZodString;
|
|
108
|
+
}, "strict", z.ZodTypeAny, {
|
|
109
|
+
reason: string;
|
|
110
|
+
remove: string[];
|
|
111
|
+
}, {
|
|
112
|
+
reason: string;
|
|
113
|
+
remove: string[];
|
|
114
|
+
}>>;
|
|
115
|
+
}, "strict", z.ZodTypeAny, {
|
|
116
|
+
steps: z.objectOutputType<{
|
|
117
|
+
catalog: z.ZodString;
|
|
118
|
+
id: z.ZodOptional<z.ZodString>;
|
|
119
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
120
|
+
override?: {
|
|
121
|
+
reason: string;
|
|
122
|
+
remove: string[];
|
|
123
|
+
} | undefined;
|
|
124
|
+
touch?: string[] | undefined;
|
|
125
|
+
}, {
|
|
126
|
+
steps: z.objectInputType<{
|
|
127
|
+
catalog: z.ZodString;
|
|
128
|
+
id: z.ZodOptional<z.ZodString>;
|
|
129
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
130
|
+
override?: {
|
|
131
|
+
reason: string;
|
|
132
|
+
remove: string[];
|
|
133
|
+
} | undefined;
|
|
134
|
+
touch?: string[] | undefined;
|
|
135
|
+
}>;
|
|
136
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
137
|
+
humanConfirm: z.ZodOptional<z.ZodString>;
|
|
138
|
+
repoRef: z.ZodOptional<z.ZodString>;
|
|
139
|
+
deliver: z.ZodOptional<z.ZodEnum<["pr", "none"]>>;
|
|
140
|
+
}, "strict", z.ZodTypeAny, {
|
|
141
|
+
plan: {
|
|
142
|
+
steps: z.objectOutputType<{
|
|
143
|
+
catalog: z.ZodString;
|
|
144
|
+
id: z.ZodOptional<z.ZodString>;
|
|
145
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
146
|
+
override?: {
|
|
147
|
+
reason: string;
|
|
148
|
+
remove: string[];
|
|
149
|
+
} | undefined;
|
|
150
|
+
touch?: string[] | undefined;
|
|
151
|
+
};
|
|
152
|
+
deliver?: "pr" | "none" | undefined;
|
|
153
|
+
projectId?: string | undefined;
|
|
154
|
+
repoRef?: string | undefined;
|
|
155
|
+
humanConfirm?: string | undefined;
|
|
156
|
+
}, {
|
|
157
|
+
plan: {
|
|
158
|
+
steps: z.objectInputType<{
|
|
159
|
+
catalog: z.ZodString;
|
|
160
|
+
id: z.ZodOptional<z.ZodString>;
|
|
161
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
162
|
+
override?: {
|
|
163
|
+
reason: string;
|
|
164
|
+
remove: string[];
|
|
165
|
+
} | undefined;
|
|
166
|
+
touch?: string[] | undefined;
|
|
167
|
+
};
|
|
168
|
+
deliver?: "pr" | "none" | undefined;
|
|
169
|
+
projectId?: string | undefined;
|
|
170
|
+
repoRef?: string | undefined;
|
|
171
|
+
humanConfirm?: string | undefined;
|
|
172
|
+
}>;
|
|
173
|
+
/** The run's `wicked.team.*` rows, by `event_id`, read through the engine that holds the bus
|
|
174
|
+
* (core/bus.ts); `[]` when the bus is absent or unreadable. */
|
|
175
|
+
export declare function busRows(busDbPath: string | undefined, runId: string): Promise<TeamRow[]>;
|
|
176
|
+
/**
|
|
177
|
+
* The OPEN plan gate's own reading of the plan it holds: the newest `gate.opened{kind:"plan_approval"}`
|
|
178
|
+
* no `gate.decided` answered, with its `band` and `high_risk` (brainstorm idea 13 — a plan-approval
|
|
179
|
+
* trust order re-reads these before it answers). `undefined` when no plan gate is open or the row
|
|
180
|
+
* does not state both its band and a boolean `high_risk`: the caller fails closed.
|
|
181
|
+
*/
|
|
182
|
+
export declare function openPlanGateRisk(rows: readonly TeamRow[]): {
|
|
183
|
+
band: string;
|
|
184
|
+
highRisk: boolean;
|
|
185
|
+
} | undefined;
|
|
186
|
+
/**
|
|
187
|
+
* Join the bus rows onto the engine's snapshot. Rows with `ord: null` are the run's; the rest go
|
|
188
|
+
* to their unit. `gate.opened{kind:"unit_review"}.ledger_ref` is the only authority on which
|
|
189
|
+
* ledger a gate read: the `ledger.folded` row it names is the unit's `ledger`, and a fold for an
|
|
190
|
+
* attempt whose gate named another ledger is labelled `unused`.
|
|
191
|
+
*/
|
|
192
|
+
export declare function joinTeam(view: RunTeamView, rows: TeamRow[]): RunTeamResponse;
|
|
193
|
+
export declare function registerTeamRoutes(app: FastifyInstance, adapter: CoreAdapter, security?: {
|
|
194
|
+
audit: AuditLog;
|
|
195
|
+
}): void;
|
|
196
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/team/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,KAAK,EAKV,eAAe,EAEf,WAAW,EAEX,OAAO,EACR,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAO3C,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEhB,CAAC;AAKZ,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQnB,CAAC;AAwBZ;gEACgE;AAChE,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAoB9F;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAgB1G;AAID;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,eAAe,CAsB5E;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,WAAW,EAEpB,QAAQ,GAAE;IAAE,KAAK,EAAE,QAAQ,CAAA;CAA+B,GACzD,IAAI,CA2JN"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The crew team surface (DES-TEAMING-002 T8): reads and commands over the engine. Commands go
|
|
3
|
+
* through the API, facts go on the bus (§4.0); crew publishes no team row.
|
|
4
|
+
*
|
|
5
|
+
* GET /runs/:id/team the engine's persisted team state (`Core.runTeam`) joined with the
|
|
6
|
+
* run's `wicked.team.*` bus rows and the folded ledger each gate read
|
|
7
|
+
* POST /runs/:id/plan a plan edit: at a `plan_approval` gate the gate answer
|
|
8
|
+
* (`confirmGate … edit_plan`), otherwise a mid-run edit (`Core.proposePlan`)
|
|
9
|
+
* POST /team/outbox/replay `Core.replayTeamOutbox`: the team outbox onto the bus
|
|
10
|
+
* GET /catalog the engine's phase catalog
|
|
11
|
+
* POST /plans/preview the launch's decision over a draft plan (`Core.previewPlan`)
|
|
12
|
+
*
|
|
13
|
+
* The live stream is the relay (`team/ws-relay.ts`). An addon without a binding answers 501.
|
|
14
|
+
*/
|
|
15
|
+
import { randomUUID } from 'node:crypto';
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
import { PlanLaunchUnsupportedError, TeamUnsupportedError } from '../core/adapter.js';
|
|
18
|
+
import { readBus } from '../core/bus.js';
|
|
19
|
+
import { API_PREFIX } from '../api/api-prefix.js';
|
|
20
|
+
import { AuditLog } from '../api/audit.js';
|
|
21
|
+
import { LOCAL_ACTOR } from '../api/auth.js';
|
|
22
|
+
import { PlanSchema, toLaunchPlan } from '../api/plan-schema.js';
|
|
23
|
+
const V = API_PREFIX;
|
|
24
|
+
// Exported for tests/wire-contract.test.ts (the request-direction drift guard).
|
|
25
|
+
export const EditPlanSchema = z
|
|
26
|
+
.object({ plan: PlanSchema, requestId: z.string().min(1).max(128).optional() })
|
|
27
|
+
.strict();
|
|
28
|
+
/** The engine's refusal of a gate edit when the paused run's open gate is not a plan approval:
|
|
29
|
+
* the run is paused at another gate, so the edit is a mid-run one. */
|
|
30
|
+
const NO_PLAN_GATE = /no plan_approval gate open/;
|
|
31
|
+
export const PlanPreviewSchema = z
|
|
32
|
+
.object({
|
|
33
|
+
plan: PlanSchema,
|
|
34
|
+
projectId: z.string().min(1).optional(),
|
|
35
|
+
humanConfirm: z.string().min(1).optional(),
|
|
36
|
+
repoRef: z.string().min(1).optional(),
|
|
37
|
+
deliver: z.enum(['pr', 'none']).optional(),
|
|
38
|
+
})
|
|
39
|
+
.strict();
|
|
40
|
+
function message(err) {
|
|
41
|
+
return err instanceof Error ? err.message : String(err);
|
|
42
|
+
}
|
|
43
|
+
const TERMINAL = new Set(['completed', 'cancelled', 'failed']);
|
|
44
|
+
/** A run that is not a team run: no transport at all (not the "none" fallback), nothing to join. */
|
|
45
|
+
function unteamed(runId, status) {
|
|
46
|
+
return {
|
|
47
|
+
runId,
|
|
48
|
+
teamed: false,
|
|
49
|
+
transport: null,
|
|
50
|
+
reason: null,
|
|
51
|
+
streamFloor: null,
|
|
52
|
+
planRev: null,
|
|
53
|
+
pending: null,
|
|
54
|
+
ended: TERMINAL.has(status),
|
|
55
|
+
units: [],
|
|
56
|
+
rows: [],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** The run's `wicked.team.*` rows, by `event_id`, read through the engine that holds the bus
|
|
60
|
+
* (core/bus.ts); `[]` when the bus is absent or unreadable. */
|
|
61
|
+
export async function busRows(busDbPath, runId) {
|
|
62
|
+
if (busDbPath === undefined)
|
|
63
|
+
return [];
|
|
64
|
+
try {
|
|
65
|
+
// History: a finished run's rows stay readable past the bus TTL (nothing sweeps the daemon's bus).
|
|
66
|
+
const rows = await readBus(busDbPath, 'wicked.team.', { history: true });
|
|
67
|
+
return rows
|
|
68
|
+
.filter((r) => r.payload?.run_id === runId)
|
|
69
|
+
.map((r) => ({
|
|
70
|
+
event_id: r.event_id,
|
|
71
|
+
event_type: r.event_type,
|
|
72
|
+
payload: r.payload,
|
|
73
|
+
emitted_at: r.emitted_at,
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// No engine bus / an unreadable one: the engine's snapshot still answers.
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The OPEN plan gate's own reading of the plan it holds: the newest `gate.opened{kind:"plan_approval"}`
|
|
83
|
+
* no `gate.decided` answered, with its `band` and `high_risk` (brainstorm idea 13 — a plan-approval
|
|
84
|
+
* trust order re-reads these before it answers). `undefined` when no plan gate is open or the row
|
|
85
|
+
* does not state both its band and a boolean `high_risk`: the caller fails closed.
|
|
86
|
+
*/
|
|
87
|
+
export function openPlanGateRisk(rows) {
|
|
88
|
+
const sorted = [...rows].sort((a, b) => a.event_id - b.event_id);
|
|
89
|
+
const payload = (r) => (r.payload ?? {});
|
|
90
|
+
const decided = new Set(sorted.filter((r) => r.event_type === 'wicked.team.gate.decided').map((r) => payload(r)['gate_id']));
|
|
91
|
+
const open = sorted
|
|
92
|
+
.filter((r) => r.event_type === 'wicked.team.gate.opened' && payload(r)['kind'] === 'plan_approval')
|
|
93
|
+
.filter((r) => !decided.has(payload(r)['gate_id']))
|
|
94
|
+
.pop();
|
|
95
|
+
if (open === undefined)
|
|
96
|
+
return undefined;
|
|
97
|
+
const band = payload(open)['band'];
|
|
98
|
+
const highRisk = payload(open)['high_risk'];
|
|
99
|
+
// Fail closed: a row that does not SAY its band and its risk is not a reading of them.
|
|
100
|
+
if (typeof band !== 'string' || band === '' || typeof highRisk !== 'boolean')
|
|
101
|
+
return undefined;
|
|
102
|
+
return { band, highRisk };
|
|
103
|
+
}
|
|
104
|
+
const fold = (ord, attempt) => `ledger.folded#${String(ord)}:${String(attempt)}`;
|
|
105
|
+
/**
|
|
106
|
+
* Join the bus rows onto the engine's snapshot. Rows with `ord: null` are the run's; the rest go
|
|
107
|
+
* to their unit. `gate.opened{kind:"unit_review"}.ledger_ref` is the only authority on which
|
|
108
|
+
* ledger a gate read: the `ledger.folded` row it names is the unit's `ledger`, and a fold for an
|
|
109
|
+
* attempt whose gate named another ledger is labelled `unused`.
|
|
110
|
+
*/
|
|
111
|
+
export function joinTeam(view, rows) {
|
|
112
|
+
const read = new Map(); // "<ord>:<attempt>" → the ledger_ref its gate read
|
|
113
|
+
for (const r of rows) {
|
|
114
|
+
if (r.event_type === 'wicked.team.gate.opened' && r.payload.kind === 'unit_review') {
|
|
115
|
+
read.set(`${String(r.payload.ord)}:${String(r.payload.attempt)}`, r.payload.ledger_ref);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const labelled = rows.map((r) => {
|
|
119
|
+
if (r.event_type !== 'wicked.team.ledger.folded')
|
|
120
|
+
return r;
|
|
121
|
+
const key = `${String(r.payload.ord)}:${String(r.payload.attempt)}`;
|
|
122
|
+
return read.has(key) && read.get(key) !== fold(r.payload.ord, r.payload.attempt) ? { ...r, unused: true } : r;
|
|
123
|
+
});
|
|
124
|
+
const units = view.units.map((u) => {
|
|
125
|
+
const own = labelled.filter((r) => r.payload.ord === u.ord);
|
|
126
|
+
const used = own.find((r) => r.event_type === 'wicked.team.ledger.folded' && fold(r.payload.ord, r.payload.attempt) === u.ledgerRef);
|
|
127
|
+
const ledger = used !== undefined && used.event_type === 'wicked.team.ledger.folded' ? used.payload.ledger : null;
|
|
128
|
+
return { ...u, rows: own, ledger };
|
|
129
|
+
});
|
|
130
|
+
return { ...view, teamed: true, units, rows: labelled.filter((r) => r.payload.ord === null) };
|
|
131
|
+
}
|
|
132
|
+
export function registerTeamRoutes(app, adapter,
|
|
133
|
+
// Defaulted to a NOOP trail so a directly-driven route set never writes the real audit log.
|
|
134
|
+
security = { audit: AuditLog.noop() }) {
|
|
135
|
+
const { audit } = security;
|
|
136
|
+
const actorOf = (req) => req.actor ?? LOCAL_ACTOR;
|
|
137
|
+
const unsupported = (err) => err instanceof TeamUnsupportedError || err instanceof PlanLaunchUnsupportedError;
|
|
138
|
+
const findRun = async (id) => (await adapter.sessionsDetail()).find((v) => v.session.id === id);
|
|
139
|
+
app.get(`${V}/runs/:id/team`, { config: { manifest: { responseType: 'RunTeamResponse', statusCodes: [200, 404, 501] } } }, async (req, reply) => {
|
|
140
|
+
const { id } = req.params;
|
|
141
|
+
try {
|
|
142
|
+
const run = await findRun(id);
|
|
143
|
+
if (run === undefined)
|
|
144
|
+
return reply.code(404).send({ error: 'Run not found' });
|
|
145
|
+
const view = await adapter.runTeam(id);
|
|
146
|
+
if (view === null)
|
|
147
|
+
return unteamed(id, run.session.status);
|
|
148
|
+
return joinTeam(view, await busRows(adapter.busDbPath, id));
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
return reply.code(unsupported(err) ? 501 : 500).send({ error: message(err) });
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
app.post(`${V}/runs/:id/plan`, {
|
|
155
|
+
config: {
|
|
156
|
+
manifest: {
|
|
157
|
+
requestType: 'EditPlanBody',
|
|
158
|
+
responseType: 'EditPlanResponse',
|
|
159
|
+
// 409: the engine refused the edit (its reason); 501: the addon lacks the gate edit or
|
|
160
|
+
// Core.proposePlan.
|
|
161
|
+
statusCodes: [200, 400, 404, 409, 501],
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
}, async (req, reply) => {
|
|
165
|
+
const { id } = req.params;
|
|
166
|
+
const parsed = EditPlanSchema.safeParse(req.body);
|
|
167
|
+
if (!parsed.success) {
|
|
168
|
+
return reply.code(400).send({ error: 'Invalid request body', details: parsed.error.issues });
|
|
169
|
+
}
|
|
170
|
+
const run = await findRun(id);
|
|
171
|
+
if (run === undefined)
|
|
172
|
+
return reply.code(404).send({ error: 'Run not found' });
|
|
173
|
+
const plan = toLaunchPlan(parsed.data.plan);
|
|
174
|
+
if (run.session.status === 'awaiting_human') {
|
|
175
|
+
try {
|
|
176
|
+
// The edit IS the gate answer (T3): the engine proposes it (`plan.proposed{by:"human",
|
|
177
|
+
// kind:"edit"}`), floor-fills and accepts it, or refuses it and re-opens the gate.
|
|
178
|
+
const status = await adapter.confirmGate(id, true, undefined, 'edit_plan', undefined, plan);
|
|
179
|
+
// WHO answered the gate, like every other gate answer (POST /runs/:id/gate).
|
|
180
|
+
audit.record('gate.decided', actorOf(req), {
|
|
181
|
+
runId: id,
|
|
182
|
+
detail: { approve: true, action: 'edit_plan', planSteps: parsed.data.plan.steps.length, status },
|
|
183
|
+
});
|
|
184
|
+
// confirmGate resolves the engine's status token, a SessionStatus spelling.
|
|
185
|
+
const body = { status: status };
|
|
186
|
+
return body;
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
// Paused at another gate (a unit gate, a team pause): no plan gate to answer, so the edit
|
|
190
|
+
// is a mid-run one, below. Every other refusal is the answer.
|
|
191
|
+
if (!NO_PLAN_GATE.test(message(err))) {
|
|
192
|
+
return reply.code(unsupported(err) ? 501 : 409).send({ error: message(err) });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// T8 (c): a mid-run edit. The engine holds it for the run's next step boundary (ratchet and
|
|
197
|
+
// floor fill apply) and its author approved it, so no gate opens; the proposal says what it
|
|
198
|
+
// does to the run (band, high risk, the floor steps it adds). Idempotent by requestId: a body
|
|
199
|
+
// without one gets a fresh id minted for this POST, so only a caller-sent id makes a retry
|
|
200
|
+
// safe. The engine refuses a plan awaiting approval (edit it at the gate), a started deliver
|
|
201
|
+
// step, and a finished or unplanned run: each is a 409 carrying its reason.
|
|
202
|
+
const requestId = parsed.data.requestId ?? randomUUID();
|
|
203
|
+
try {
|
|
204
|
+
const proposal = await adapter.proposePlan(id, plan, requestId);
|
|
205
|
+
audit.record('plan.edit.proposed', actorOf(req), {
|
|
206
|
+
runId: id,
|
|
207
|
+
detail: {
|
|
208
|
+
requestId,
|
|
209
|
+
proposalId: proposal.proposal_id,
|
|
210
|
+
duplicate: proposal.duplicate,
|
|
211
|
+
planSteps: parsed.data.plan.steps.length,
|
|
212
|
+
band: proposal.band,
|
|
213
|
+
highRisk: proposal.high_risk,
|
|
214
|
+
floorAdded: proposal.floor_added,
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
const body = proposal;
|
|
218
|
+
return body;
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
return reply.code(unsupported(err) ? 501 : 409).send({ error: message(err) });
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
app.post(`${V}/team/outbox/replay`, { config: { manifest: { responseType: 'TeamOutboxReplayReport', statusCodes: [200, 409, 501] } } }, async (req, reply) => {
|
|
225
|
+
try {
|
|
226
|
+
const report = await adapter.replayTeamOutbox();
|
|
227
|
+
audit.record('team.outbox.replayed', actorOf(req), {
|
|
228
|
+
detail: { published: report.published.length, remaining: report.remaining },
|
|
229
|
+
});
|
|
230
|
+
return report;
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
// The engine refuses when it has no bus or no state home: a state, not a bad request.
|
|
234
|
+
return reply.code(unsupported(err) ? 501 : 409).send({ error: message(err) });
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
app.get(`${V}/catalog`, { config: { manifest: { responseType: 'CatalogResponse', statusCodes: [200, 501] } } }, async (_req, reply) => {
|
|
238
|
+
try {
|
|
239
|
+
const body = { entries: await adapter.catalog() };
|
|
240
|
+
return body;
|
|
241
|
+
}
|
|
242
|
+
catch (err) {
|
|
243
|
+
return reply.code(unsupported(err) ? 501 : 500).send({ error: message(err) });
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
app.post(`${V}/plans/preview`, {
|
|
247
|
+
config: {
|
|
248
|
+
manifest: { requestType: 'PlanPreviewBody', responseType: 'PlanPreviewResponse', statusCodes: [200, 400, 501] },
|
|
249
|
+
},
|
|
250
|
+
}, async (req, reply) => {
|
|
251
|
+
const parsed = PlanPreviewSchema.safeParse(req.body);
|
|
252
|
+
if (!parsed.success) {
|
|
253
|
+
return reply.code(400).send({ error: 'Invalid request body', details: parsed.error.issues });
|
|
254
|
+
}
|
|
255
|
+
try {
|
|
256
|
+
// The preview is the launch's own decision, so it takes what the launch would: the repo
|
|
257
|
+
// (its graph scores the touch set) and, for a delivering launch, the deliver step. A plan
|
|
258
|
+
// launch delivers only on an explicit `deliver: "pr"` (POST /runs defaults a plan to none).
|
|
259
|
+
const d = parsed.data;
|
|
260
|
+
return await adapter.previewPlan(toLaunchPlan(d.plan), {
|
|
261
|
+
...(d.projectId !== undefined ? { projectId: d.projectId } : {}),
|
|
262
|
+
...(d.humanConfirm !== undefined ? { humanConfirm: d.humanConfirm } : {}),
|
|
263
|
+
...(d.repoRef !== undefined ? { repoRef: d.repoRef } : {}),
|
|
264
|
+
deliver: d.deliver === 'pr',
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
catch (err) {
|
|
268
|
+
// The engine's refusal of the draft (compose, the override in auto mode, an unregistered
|
|
269
|
+
// repo, …) is the answer.
|
|
270
|
+
return reply.code(unsupported(err) ? 501 : 400).send({ error: message(err) });
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/team/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DES-TEAMING-002 §4.5 (seam T8) — the `wicked.team.*` → `/ws` relay.
|
|
3
|
+
*
|
|
4
|
+
* The engine publishes every team fact on the bus (§4.0, one owner per type, §7). This relay puts
|
|
5
|
+
* each new team row on the SAME `/ws` socket the studio already holds, as
|
|
6
|
+
* `{ type: 'teamEvent', event: <the bus row> }`, tagged `project_id` when the run's membership
|
|
7
|
+
* files it, as every CoreEvent frame is. No CoreEvent variant carries a team event, and crew never
|
|
8
|
+
* puts a team row on the bus (tests/team-no-publish.test.ts).
|
|
9
|
+
*
|
|
10
|
+
* READ-ONLY. The bus file is the engine's (T0), and crew reads it through the engine that holds it
|
|
11
|
+
* (`Core.busRead`, wicked-core#631, core/bus.ts) — crew opens no SQLite of its own. The relay is a
|
|
12
|
+
* tap with its cursor in memory, starting at the newest row (`latest`). Nothing is lost that
|
|
13
|
+
* matters: the bus is the durable record and `GET /runs/:id/team` reads it back, so a restart needs
|
|
14
|
+
* no stored cursor.
|
|
15
|
+
*
|
|
16
|
+
* Posture: loud, non-fatal. A bus no engine holds → one log line and `null`; `/ws` then
|
|
17
|
+
* carries no team frames. A read that fails (the engine mid-checkpoint) is logged and retried on
|
|
18
|
+
* the next poll.
|
|
19
|
+
*/
|
|
20
|
+
import type { CoreEvent } from '../core/types.js';
|
|
21
|
+
/** The ONE envelope type this relay puts on `/ws` (api-types `TeamEventFrame`). */
|
|
22
|
+
export declare const TEAM_EVENT_FRAME = "teamEvent";
|
|
23
|
+
export interface TeamRelay {
|
|
24
|
+
stop(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export interface TeamRelayOptions {
|
|
27
|
+
/** The bus db the engine publishes on (the adapter's `busDbPath`). */
|
|
28
|
+
dbPath: string;
|
|
29
|
+
/** The project a run is filed under, if any. */
|
|
30
|
+
projectOf: (runId: string) => string | undefined;
|
|
31
|
+
/** Poll cadence, ms (tests shorten it). */
|
|
32
|
+
pollIntervalMs?: number;
|
|
33
|
+
/** Where frames go; defaults to every `/ws` client (tests capture them). */
|
|
34
|
+
broadcast?: (frame: CoreEvent) => void;
|
|
35
|
+
log?: (msg: string) => void;
|
|
36
|
+
}
|
|
37
|
+
/** Arm the relay; `null` (logged) when the bus cannot be opened. */
|
|
38
|
+
export declare function startTeamWsRelay(opts: TeamRelayOptions): Promise<TeamRelay | null>;
|
|
39
|
+
//# sourceMappingURL=ws-relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-relay.d.ts","sourceRoot":"","sources":["../../src/team/ws-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAKlD,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,cAAc,CAAC;AAE5C,MAAM,WAAW,SAAS;IACxB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACjD,2CAA2C;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACvC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,oEAAoE;AACpE,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CA8BxF"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DES-TEAMING-002 §4.5 (seam T8) — the `wicked.team.*` → `/ws` relay.
|
|
3
|
+
*
|
|
4
|
+
* The engine publishes every team fact on the bus (§4.0, one owner per type, §7). This relay puts
|
|
5
|
+
* each new team row on the SAME `/ws` socket the studio already holds, as
|
|
6
|
+
* `{ type: 'teamEvent', event: <the bus row> }`, tagged `project_id` when the run's membership
|
|
7
|
+
* files it, as every CoreEvent frame is. No CoreEvent variant carries a team event, and crew never
|
|
8
|
+
* puts a team row on the bus (tests/team-no-publish.test.ts).
|
|
9
|
+
*
|
|
10
|
+
* READ-ONLY. The bus file is the engine's (T0), and crew reads it through the engine that holds it
|
|
11
|
+
* (`Core.busRead`, wicked-core#631, core/bus.ts) — crew opens no SQLite of its own. The relay is a
|
|
12
|
+
* tap with its cursor in memory, starting at the newest row (`latest`). Nothing is lost that
|
|
13
|
+
* matters: the bus is the durable record and `GET /runs/:id/team` reads it back, so a restart needs
|
|
14
|
+
* no stored cursor.
|
|
15
|
+
*
|
|
16
|
+
* Posture: loud, non-fatal. A bus no engine holds → one log line and `null`; `/ws` then
|
|
17
|
+
* carries no team frames. A read that fails (the engine mid-checkpoint) is logged and retried on
|
|
18
|
+
* the next poll.
|
|
19
|
+
*/
|
|
20
|
+
import { tapBus } from '../core/bus.js';
|
|
21
|
+
import { broadcast as broadcastToWs } from '../events/bus.js';
|
|
22
|
+
/** The scope guard: only team rows are relayed. */
|
|
23
|
+
const RELAY_FILTER = 'wicked.team.**';
|
|
24
|
+
/** The ONE envelope type this relay puts on `/ws` (api-types `TeamEventFrame`). */
|
|
25
|
+
export const TEAM_EVENT_FRAME = 'teamEvent';
|
|
26
|
+
/** Arm the relay; `null` (logged) when the bus cannot be opened. */
|
|
27
|
+
export async function startTeamWsRelay(opts) {
|
|
28
|
+
const log = opts.log ?? (() => undefined);
|
|
29
|
+
const send = opts.broadcast ?? broadcastToWs;
|
|
30
|
+
let lastError = null;
|
|
31
|
+
try {
|
|
32
|
+
return await tapBus({
|
|
33
|
+
dbPath: opts.dbPath,
|
|
34
|
+
filter: RELAY_FILTER,
|
|
35
|
+
pollIntervalMs: opts.pollIntervalMs ?? 2000,
|
|
36
|
+
handler: (event) => {
|
|
37
|
+
lastError = null;
|
|
38
|
+
const runId = event.payload?.run_id;
|
|
39
|
+
const projectId = typeof runId === 'string' ? opts.projectOf(runId) : undefined;
|
|
40
|
+
send({
|
|
41
|
+
type: TEAM_EVENT_FRAME,
|
|
42
|
+
event,
|
|
43
|
+
...(projectId !== undefined ? { project_id: projectId } : {}),
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
// A failed read (the engine mid-checkpoint) is retried on the next poll; said once per
|
|
47
|
+
// distinct failure, not once per poll.
|
|
48
|
+
onError: (err) => {
|
|
49
|
+
if (message(err) !== lastError)
|
|
50
|
+
log(`[team-relay] bus read failed (retrying): ${message(err)}`);
|
|
51
|
+
lastError = message(err);
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
log(`[team-relay] cannot read the bus at ${opts.dbPath} — /ws carries no teamEvent frames: ${message(err)}`);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function message(err) {
|
|
61
|
+
return err instanceof Error ? err.message : String(err);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=ws-relay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-relay.js","sourceRoot":"","sources":["../../src/team/ws-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAG9D,mDAAmD;AACnD,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAEtC,mFAAmF;AACnF,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAkB5C,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAsB;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAS,EAAE,CAAC,SAAS,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,aAAa,CAAC;IAC7C,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC;YAClB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,YAAY;YACpB,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,IAAI;YAC3C,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACjB,SAAS,GAAG,IAAI,CAAC;gBACjB,MAAM,KAAK,GAAI,KAAK,CAAC,OAAuC,EAAE,MAAM,CAAC;gBACrE,MAAM,SAAS,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAChF,IAAI,CAAC;oBACH,IAAI,EAAE,gBAAgB;oBACtB,KAAK;oBACL,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACjD,CAAC,CAAC;YAClB,CAAC;YACD,uFAAuF;YACvF,uCAAuC;YACvC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACf,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS;oBAAE,GAAG,CAAC,4CAA4C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChG,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,uCAAuC,IAAI,CAAC,MAAM,uCAAuC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7G,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,GAAY;IAC3B,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC"}
|