workspai 0.70.0 → 0.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +43 -80
  2. package/contracts/workspace-intelligence/goal-lifecycle-result.v1.json +19 -0
  3. package/dist/analyze-4YQ67OCK.js +1 -0
  4. package/dist/autopilot-release-V3A3YCDD.js +1 -0
  5. package/dist/{chunk-UT57IFS4.js → chunk-26VNCHVV.js} +6 -6
  6. package/dist/{chunk-Z7JIUA6I.js → chunk-2KJNASF3.js} +1 -1
  7. package/dist/{chunk-IET57ZKN.js → chunk-4CE3GI4Y.js} +1 -1
  8. package/dist/{chunk-WUXJCSYO.js → chunk-554W2TXP.js} +1 -1
  9. package/dist/{chunk-DNZHKBQ3.js → chunk-5HURQABR.js} +1 -1
  10. package/dist/{chunk-S2TOSHQW.js → chunk-7V3YDKMG.js} +1 -1
  11. package/dist/{chunk-LE2I2E6R.js → chunk-ACCWXKZW.js} +2 -2
  12. package/dist/{chunk-TLMP2MGH.js → chunk-AUQLOQ2S.js} +1 -1
  13. package/dist/{chunk-N6FJZ62B.js → chunk-AUVWD3WV.js} +1 -1
  14. package/dist/{chunk-S42KDOGG.js → chunk-C563KVBD.js} +1 -1
  15. package/dist/{chunk-4R7STECB.js → chunk-CX6PAQTQ.js} +1 -1
  16. package/dist/{chunk-AGZWDYMF.js → chunk-FFE2JZZJ.js} +8 -8
  17. package/dist/{chunk-LU6CYDLN.js → chunk-H64KAPJJ.js} +1 -1
  18. package/dist/{chunk-QZODGRAI.js → chunk-HMKDU7OU.js} +1 -1
  19. package/dist/{chunk-IBJEQHJR.js → chunk-HV6EQMUJ.js} +24 -7
  20. package/dist/{chunk-IFHM2SI6.js → chunk-IOKEF3DE.js} +1 -1
  21. package/dist/{chunk-ZLCLGIM6.js → chunk-K2LKJBQ4.js} +1 -1
  22. package/dist/{chunk-GED7JURY.js → chunk-L5IV2SI4.js} +1 -1
  23. package/dist/{chunk-3S2U7WRM.js → chunk-LOXR5QUX.js} +1 -1
  24. package/dist/{chunk-KFTJVVJR.js → chunk-M2R6UXJB.js} +1 -1
  25. package/dist/{chunk-ZPOZ6MDX.js → chunk-QHHSSIMZ.js} +1 -1
  26. package/dist/chunk-RMGSMDJW.js +5 -0
  27. package/dist/{chunk-TEMFNVO2.js → chunk-TD5TQZEG.js} +1 -1
  28. package/dist/{chunk-QNHKUSBH.js → chunk-XY537LCX.js} +1 -1
  29. package/dist/{chunk-EP6Q2QBU.js → chunk-YC676TPF.js} +1 -1
  30. package/dist/{chunk-PTSEDZIV.js → chunk-YS34N35Y.js} +1 -1
  31. package/dist/{chunk-IHKG5C6G.js → chunk-ZOE43SGQ.js} +1 -1
  32. package/dist/{create-BBALBC3U.js → create-HSHAZYAK.js} +1 -1
  33. package/dist/{doctor-WWVY7NB6.js → doctor-VZ2MZ7EI.js} +1 -1
  34. package/dist/{dotnet-webapi-clean-XL4IBUQV.js → dotnet-webapi-clean-VJX6SGGP.js} +39 -33
  35. package/dist/{goal-lifecycle-CEUTKUNV.js → goal-lifecycle-NKSCALES.js} +1 -1
  36. package/dist/{goal-pack-JQL3YOKT.js → goal-pack-MPKW4K6F.js} +1 -1
  37. package/dist/{gofiber-standard-OHHMCNMJ.js → gofiber-standard-I6ASLOEE.js} +77 -66
  38. package/dist/{gogin-standard-BAZXPOKL.js → gogin-standard-U2LSRLIP.js} +78 -67
  39. package/dist/index.js +100 -100
  40. package/dist/{pipeline-V46WWMP4.js → pipeline-RIA5UXUC.js} +1 -1
  41. package/dist/{project-agent-entry-MRAYG7QD.js → project-agent-entry-GQAPCSOT.js} +1 -1
  42. package/dist/{project-intelligence-lens-4BKPN4PE.js → project-intelligence-lens-5I2GQBWC.js} +1 -1
  43. package/dist/{proof-carrying-change-B7ONTBYO.js → proof-carrying-change-T33C2SSD.js} +1 -1
  44. package/dist/{rust-axum-CCJ6UCBW.js → rust-axum-JMV7UPO7.js} +25 -20
  45. package/dist/{springboot-standard-M5JQEJML.js → springboot-standard-OC2RS3KC.js} +41 -39
  46. package/dist/verified-goal-MK5MXGRY.js +1 -0
  47. package/dist/{workspace-FJ6JRYWA.js → workspace-AZKZPG45.js} +1 -1
  48. package/dist/{workspace-agent-sync-V33UGII3.js → workspace-agent-sync-CGK44F3O.js} +1 -1
  49. package/dist/{workspace-context-O6UBCBEA.js → workspace-context-S6ZWRUFZ.js} +1 -1
  50. package/dist/{workspace-contract-S2JYDA4K.js → workspace-contract-Y7WRHLYR.js} +1 -1
  51. package/dist/{workspace-explain-RP6VJ6QM.js → workspace-explain-CSJL3GJR.js} +1 -1
  52. package/dist/{workspace-foundation-7QXEJJKZ.js → workspace-foundation-LLND2WIF.js} +1 -1
  53. package/dist/{workspace-graph-stream-YY65R5EC.js → workspace-graph-stream-PHFO2J2E.js} +1 -1
  54. package/dist/{workspace-intelligence-LMR42ICR.js → workspace-intelligence-ND2N3B2A.js} +1 -1
  55. package/dist/{workspace-intelligence-runner-FXFSTCHC.js → workspace-intelligence-runner-LHHJM2AT.js} +1 -1
  56. package/dist/{workspace-knowledge-graph-3564KQXT.js → workspace-knowledge-graph-NOGGGENE.js} +1 -1
  57. package/dist/workspace-knowledge-graph-snapshot-7XHZNRFK.js +1 -0
  58. package/dist/{workspace-mcp-serve-ZK46EZUD.js → workspace-mcp-serve-6NVF7AS6.js} +1 -1
  59. package/dist/{workspace-model-6UMQAGUK.js → workspace-model-VOQOEDVU.js} +1 -1
  60. package/dist/{workspace-onboarding-C57OQ7XZ.js → workspace-onboarding-ZRLUMBLE.js} +1 -1
  61. package/dist/{workspace-registry-summary-GLQO4ZUF.js → workspace-registry-summary-NWZK5IKS.js} +1 -1
  62. package/dist/{workspace-repair-engine-5ZSSF3T5.js → workspace-repair-engine-VUOCH66O.js} +1 -1
  63. package/dist/workspace-run-3YZTVOU6.js +1 -0
  64. package/dist/{workspace-verify-LQHXBH2D.js → workspace-verify-4EQI3MCW.js} +1 -1
  65. package/dist/{workspace-watch-Z32443UP.js → workspace-watch-BPRU2X7K.js} +1 -1
  66. package/docs/README.md +5 -2
  67. package/docs/README_CONTENT_CONTRACT.md +14 -9
  68. package/docs/ci-workflows.md +1 -1
  69. package/docs/commands-reference.md +37 -32
  70. package/docs/native-kit-baselines.md +82 -0
  71. package/docs/workspace-knowledge-graph.md +6 -2
  72. package/docs/workspace-run.md +16 -0
  73. package/package.json +1 -1
  74. package/dist/analyze-OGWDSPXQ.js +0 -1
  75. package/dist/autopilot-release-QQDFEPT7.js +0 -1
  76. package/dist/chunk-XSSNM4F5.js +0 -5
  77. package/dist/verified-goal-YNSBL7L3.js +0 -1
  78. package/dist/workspace-knowledge-graph-snapshot-P27RPMV5.js +0 -1
  79. package/dist/workspace-run-UGWGT3K2.js +0 -1
package/docs/README.md CHANGED
@@ -21,8 +21,8 @@ npx workspai adopt .
21
21
  # Step 2: Build the full workspace intelligence
22
22
  npx workspai workspace intelligence run --for-agent generic --strict --json
23
23
 
24
- # Step 3: Check what agents will see
25
- cat .workspai/reports/workspace-context-agent.json | head -30
24
+ # Step 3: Validate the canonical agent entry
25
+ npx workspai agent bootstrap --for-agent generic --strict --json
26
26
  ```
27
27
 
28
28
  That is it. Your project now has:
@@ -86,6 +86,7 @@ or use `import` to copy or clone one into the workspace.
86
86
  | Prove what an agent changed and why | [Proof-Carrying Change](./proof-carrying-change.md) | A Goal-bound, effect-receipted, independently verified change capsule |
87
87
  | Ground an agent before broad source discovery | [Canonical-first agent entry](./agent-entry.md) | A portable receipt for host discovery, evidence integrity, and freshness |
88
88
  | Repair a blocker through an approved transaction | [Workspace Repair Engine](./workspace-repair-engine.md) | Checkpointed execution, validation, canonical verify, and safe rollback |
89
+ | Observe current CLI and Studio activity | [Workspai Live](./workspace-live-activity.md) | One bounded activity projection for terminal, IDE, replay, and capture |
89
90
  | Set a release, security, or coverage outcome | [Verified engineering goals](./workspace-intelligence-runner.md#verified-engineering-goals) | A durable success contract with a current evidence-backed verdict |
90
91
  | Ask an architecture or dependency question | [Workspace Knowledge Graph](./workspace-knowledge-graph.md) | A bounded answer with proof references rather than the whole graph |
91
92
  | Measure agent token, cost, and outcome efficiency | [Workspace Intelligence Evaluation](./workspace-intelligence-evaluation.md) | A live, provenance-aware report suitable for CLI, IDE, and CI |
@@ -110,6 +111,7 @@ with [AI Quickstart](./AI_QUICKSTART.md) only when that is your goal.
110
111
  | [commands-reference.md](./commands-reference.md) | Full CLI syntax, profiles, and policy keys |
111
112
  | [workspace-operations.md](./workspace-operations.md) | Import, adopt, snapshots, archives, contracts, infra |
112
113
  | [workspace-run.md](./workspace-run.md) | Polyglot fleet orchestration (`workspace run`) |
114
+ | [workspace-live-activity.md](./workspace-live-activity.md) | Unified CLI/Studio activity, Board projection, replay, accessibility, and SVG capture |
113
115
  | [workspace-intelligence-runner.md](./workspace-intelligence-runner.md) | Canonical unified runner, execution envelope, report schema, exit codes, failure propagation, and CI consumption |
114
116
  | [workspace-repair-engine.md](./workspace-repair-engine.md) | CLI-owned plan, approval, checkpoint, execution, verification, decision, and rollback state machine |
115
117
  | [goal-packs.md](./goal-packs.md) | Plain-language intent compilation, scope/evidence binding, agent handoff, and mutation boundary |
@@ -122,6 +124,7 @@ with [AI Quickstart](./AI_QUICKSTART.md) only when that is your goal.
122
124
  | [GLOSSARY.md](./GLOSSARY.md) | Plain-language definitions for workspace, model, graph, evidence, gates, and AI integrations |
123
125
  | [README_CONTENT_CONTRACT.md](./README_CONTENT_CONTRACT.md) | Required root README journey, architecture statements, claim policy, and drift guard |
124
126
  | [create-planner-capabilities.md](./create-planner-capabilities.md) | Native create, official, and existing lanes |
127
+ | [native-kit-baselines.md](./native-kit-baselines.md) | Owned Go, Java, .NET, and Rust generator baselines, upgrade policy, and validation contract |
125
128
  | [../contracts/project-entry-capability.v1.json](../contracts/project-entry-capability.v1.json) | Contract: any readable project can enter through adopt/import when it can be registered |
126
129
  | [from-code-to-shared-understanding.md](./from-code-to-shared-understanding.md) | GitHub-rendered Workspace Intelligence diagram |
127
130
  | [OPEN_SOURCE_USER_SCENARIOS.md](./OPEN_SOURCE_USER_SCENARIOS.md) | Role-based workflows (junior → enterprise) |
@@ -21,11 +21,12 @@ The root README keeps this order:
21
21
  1. a problem-first product promise, slogan, and copyable first run;
22
22
  2. product category and three durable outcomes;
23
23
  3. one copyable path for existing software and one guided path for new software;
24
- 4. one plain-language Goal path with explicit scope and verification ownership;
25
- 5. a short outcome-oriented view of what Workspai provides;
26
- 6. the canonical Model → derived Graph boundary and intelligence chain;
27
- 7. consumer surfaces and goal-based documentation links;
28
- 8. package, contributor, community, and license routes.
24
+ 4. one plain-language Goal path and the Goal-bound path to independently
25
+ verified source change;
26
+ 5. the canonical Model → derived Graph boundary and intelligence chain;
27
+ 6. consumer surfaces, including observational Live activity, and goal-based
28
+ documentation links;
29
+ 7. package, contributor, community, and license routes.
29
30
 
30
31
  The CLI README keeps this order:
31
32
 
@@ -33,10 +34,11 @@ The CLI README keeps this order:
33
34
  2. product category and durable value;
34
35
  3. a two-minute existing-project path and the guided create path;
35
36
  4. one plain-language Goal path with explicit scope and verification ownership;
36
- 5. the small set of durable outputs a user should recognize;
37
- 6. the canonical Model → derived Graph boundary and intelligence chain;
38
- 7. everyday workflows grouped by goal;
39
- 8. outputs, requirements, documentation, troubleshooting, and contribution.
37
+ 5. the Goal-bound Proof-Carrying Change path for source mutation;
38
+ 6. the small set of durable outputs a user should recognize;
39
+ 7. the canonical Model → derived Graph boundary and intelligence chain;
40
+ 8. everyday workflows grouped by goal;
41
+ 9. outputs, requirements, documentation, troubleshooting, and contribution.
40
42
 
41
43
  ## What does not belong in a main README
42
44
 
@@ -104,6 +106,9 @@ task-success claim.
104
106
  - The main path uses the complete contract-backed intelligence runner.
105
107
  - The Goal path states that it prepares bounded work and does not itself edit
106
108
  source or claim completion.
109
+ - The source-changing path distinguishes prediction, authorization, observed
110
+ effects, and independent verification.
111
+ - Live activity is presented as observation and correlation, never proof.
107
112
  - A partial command sequence must not be presented as a replacement loop.
108
113
  - Exhaustive syntax belongs in `docs/commands-reference.md`.
109
114
 
@@ -63,7 +63,7 @@ Validate or preview the current CLI announcement locally:
63
63
  npm --workspace workspai run check:release-announcement
64
64
  npm --workspace workspai run release:announcement -- \
65
65
  --product workspai-cli \
66
- --tag v0.70.0 \
66
+ --tag v0.71.0 \
67
67
  --markdown-output /tmp/workspai-discord-announcement.md
68
68
  ```
69
69
 
@@ -1,34 +1,5 @@
1
1
  # Commands Reference
2
2
 
3
- ## Live cross-terminal activity
4
-
5
- ```bash
6
- workspai live [target]
7
- workspai live --global [--max-scopes <count>]
8
- workspai live --run <run-id>
9
- workspai live --once --json
10
- workspai live --once --json --projection monitor|board
11
- workspai live --no-motion --no-color
12
- workspai live --ascii|--accessible|--classic
13
- workspai live --capture <file.svg> [--capture-preset github|linkedin|x|square|wide]
14
- workspai live --replay <run-id> [--replay-speed <0.25..64>]
15
- ```
16
-
17
- `workspai live` observes versioned run/block/activity journals emitted by every
18
- Workspai CLI command in the same project or workspace. It works without
19
- `adopt`; adoption adds workspace correlation and cross-project intelligence.
20
- Its default TTY surface is a bounded interactive Flow Board with live block and
21
- edge state, durable per-block retry attempts, semantic phase rails, an adaptive
22
- Inspector, a deduplicated multi-workspace Fleet Cockpit, deterministic
23
- redacted-by-default SVG capture, durable replay, responsive compaction and
24
- changed-row rendering. Use `--accessible` for stable screen-reader output or
25
- `--classic` for the compatibility line view.
26
- `--projection board` exposes the same bounded renderer-neutral run/node/edge
27
- model used by the terminal and SVG adapters, so IDE and web consumers do not
28
- need to reconstruct topology from raw events. The default `monitor` projection
29
- is backward compatible.
30
- See [Workspai Live Activity](./workspace-live-activity.md).
31
-
32
3
  Human-readable CLI syntax for the Workspai CLI. The machine-complete command,
33
4
  argument, option, alias, ownership, and integrity inventory is available through
34
5
  `workspai commands --json` and
@@ -51,6 +22,38 @@ project`, and a complete ownership-grouped command map. Scoped help carries
51
22
  exact flags and examples. `commands --json` remains the machine-complete
52
23
  inventory used to prevent the human map from drifting.
53
24
 
25
+ ## Start with the core loop
26
+
27
+ ```bash
28
+ npx workspai adopt .
29
+ npx workspai workspace intelligence run --for-agent generic --strict --json
30
+ npx workspai goal "Describe the required outcome" --for-agent generic
31
+ npx workspai agent bootstrap --for-agent generic --strict --json
32
+ ```
33
+
34
+ For source-changing work, continue through `change begin`, bounded
35
+ authorization, effect receipts, independent verification, and capsule
36
+ validation. For exact syntax, see the lifecycle section below.
37
+
38
+ ## Live cross-terminal activity
39
+
40
+ ```bash
41
+ workspai live [target]
42
+ workspai live --global [--max-scopes <count>]
43
+ workspai live --run <run-id>
44
+ workspai live --once --json --projection monitor|board
45
+ workspai live --ascii|--accessible|--classic
46
+ workspai live --capture <file.svg> [--capture-preset github|linkedin|x|square|wide]
47
+ workspai live --replay <run-id> [--replay-speed <0.25..64>]
48
+ ```
49
+
50
+ `workspai live` observes versioned activity emitted by CLI and Studio without
51
+ changing command outcomes or upgrading telemetry into verification proof. The
52
+ default TTY is an interactive Flow Board; the `board` JSON projection is the
53
+ shared renderer-neutral surface for IDE, web, replay, and capture consumers.
54
+ Use `--accessible` for stable screen-reader output and `--classic` for the
55
+ compatibility view. See [Workspai Live Activity](./workspace-live-activity.md).
56
+
54
57
  ## Workspace lifecycle
55
58
 
56
59
  ```bash
@@ -71,10 +74,12 @@ npx workspai change authorize --change <change-id> --effects <classes> [--grante
71
74
  npx workspai change effect record --change <change-id> --file <effect-receipt.json> [--workspace <path>] [--json]
72
75
  npx workspai change verify --change <change-id> [--strict] [--no-refresh] [--workspace <path>] [--json]
73
76
  npx workspai change verification record --change <change-id> --file <verification-receipt.json> [--workspace <path>] [--json]
74
- npx workspai change <status|explain> --change <change-id> [--workspace <path>] [--json]
77
+ npx workspai change status --change <change-id> [--workspace <path>] [--json]
78
+ npx workspai change explain --change <change-id> [--workspace <path>] [--json]
75
79
  npx workspai change resume --change <change-id> --to <authorized|executing|verifying> --reason <text> [--actor <identity>] [--json]
76
80
  npx workspai change abort --change <change-id> --reason <text> [--actor <identity>] [--json]
77
- npx workspai change capsule <validate|export> --change <change-id> [--output <path>] [--json]
81
+ npx workspai change capsule validate --change <change-id> [--workspace <path>] [--json]
82
+ npx workspai change capsule export --change <change-id> --output <path> [--workspace <path>] [--json]
78
83
  npx workspai agent bootstrap [--project <path>] [--for-agent <host>] [--no-live-inputs] [--strict] [--json]
79
84
  ```
80
85
 
@@ -135,7 +140,7 @@ npx workspai workspace snapshot [--workspace <path>] [--json] [--include-paths]
135
140
  npx workspai workspace diff --from <snapshot-or-model|git[:ref]> [--workspace <path>] [--json] [--include-paths] [--include-evidence] [--scan-depth <count>] [--strict]
136
141
  npx workspai workspace impact --from <workspace-diff-report> [--workspace <path>] [--scope project:<name>] [--json] [--include-paths] [--include-evidence] [--scan-depth <count>] [--strict]
137
142
  npx workspai workspace verify [--from-impact <file>] [--workspace <path>] [--scope project:<name>] [--strict] [--json] [--include-paths] [--include-evidence] [--scan-depth <count>]
138
- npx workspai workspace graph [emit|explain|search|benchmark|entities|evidence|path|overlay|dot|mermaid|jsonld|graphml|gexf] [key] [value] [--from <graph.json>] [--output <file>] [--limit <1..100>] [--kind <entity-kind>] [--workspace <path>] [--scope project:<name>] [--refresh-graph] [--graph-inventory-limit <count>] [--graph-semantic-budget <count>] [--graph-deep-budget <count>] [--graph-source-budget <count>] [--json] [--include-paths] [--include-evidence] [--scan-depth <count>]
143
+ npx workspai workspace graph [emit|explain|search|benchmark|benchmark-suite|entities|evidence|path|overlay|dot|mermaid|jsonld|graphml|gexf] [key] [value] [--from <graph.json>] [--output <file>] [--limit <1..100>] [--kind <entity-kind>] [--workspace <path>] [--scope project:<name>] [--refresh-graph] [--graph-inventory-limit <count>] [--graph-semantic-budget <count>] [--graph-deep-budget <count>] [--graph-source-budget <count>] [--json] [--include-paths] [--include-evidence] [--scan-depth <count>]
139
144
  npx workspai workspace eval [init <task> [strategy]|record|status|report|compare --from <report>] [--workspace <path>] [--output <file>] [--json]
140
145
  npx workspai workspace watch [--workspace <path>] [--json] [--graph-stream] [--once] [--scan-depth <count>]
141
146
  npx workspai workspace explain <target> [--workspace <path>] [--json] [--write]
@@ -0,0 +1,82 @@
1
+ # Native Kit Baselines
2
+
3
+ Workspai owns the generated source, build, container, and CI contract for these
4
+ native kits:
5
+
6
+ - `gofiber.standard`
7
+ - `gogin.standard`
8
+ - `springboot.standard`
9
+ - `dotnet.webapi.clean`
10
+ - `rust.axum`
11
+
12
+ This policy does not cover FastAPI or NestJS kits owned by the RapidKit Python
13
+ engine. It also does not cover generators delegated to an upstream official
14
+ CLI, such as Next.js, Astro, Angular, Vue, Svelte, Nuxt, or React Native.
15
+
16
+ ## Current tested baseline
17
+
18
+ Reviewed: August 31, 2026
19
+
20
+ | Kit | Runtime baseline | Framework baseline | Compatibility policy |
21
+ | ------------ | ------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------- |
22
+ | Go/Fiber | Go 1.26 | Fiber 2.52.15 | Stay on the maintained v2 line until a separately qualified v3 migration is complete. |
23
+ | Go/Gin | Go 1.26 | Gin 1.12.0 | Generate and test against the same supported Go baseline. |
24
+ | Spring Boot | Java 21 | Spring Boot 3.5.16, springdoc 2.9.0 | Build on Java 21 and verify the generated project on Java 21 and 25. |
25
+ | .NET Web API | .NET 10 LTS | ASP.NET Core 10.0.11 | Use `net10.0` consistently across source, tests, containers, and CI. |
26
+ | Rust/Axum | Rust 1.98.0, edition 2024 | Axum 0.8.9 | Pin the toolchain so local, CI, and container builds use one compiler contract. |
27
+
28
+ The executable source of truth is
29
+ [`native-kit-baselines.ts`](../src/generators/native-kit-baselines.ts). A
30
+ baseline review changes that file and the affected generator tests together so
31
+ templates cannot silently drift apart.
32
+
33
+ ## Enterprise generation contract
34
+
35
+ Every owned native kit must generate:
36
+
37
+ - deterministic runtime and framework versions rather than `latest`;
38
+ - health/readiness endpoints and runtime smoke tests;
39
+ - a multi-stage container with a non-root runtime user;
40
+ - CI with explicit read-only permissions and pinned action major versions;
41
+ - formatting, linting, build, and test gates appropriate to the ecosystem;
42
+ - automated dependency and GitHub Actions update discovery through Dependabot;
43
+ - portable Workspai metadata and lifecycle launchers.
44
+
45
+ The Spring kit additionally emits an OWASP dependency scan and CycloneDX SBOM.
46
+ The .NET kit uses the SDK's transitive vulnerability audit. Go and Rust security
47
+ scanner adoption remains gated on selecting and qualifying a pinned scanner
48
+ contract; a floating install is not an acceptable substitute.
49
+
50
+ ## Upgrade rules
51
+
52
+ 1. Prefer a supported, mature runtime line over a release published only days
53
+ before the Workspai release.
54
+ 2. Treat framework major upgrades as migrations, not version bumps. They need
55
+ generated-source compatibility, runtime smoke, Docker, and cross-platform CI
56
+ evidence.
57
+ 3. Keep runtime, package, container, CI, documentation, and warning text on the
58
+ same baseline.
59
+ 4. Never use floating tool versions in generated CI.
60
+ 5. Run generator golden tests without host runtimes, then qualify generated
61
+ projects with their real runtime before promoting a preview kit to stable.
62
+ 6. Review baselines for every Workspai minor release and immediately after a
63
+ relevant security or end-of-support announcement.
64
+
65
+ ## Validation
66
+
67
+ The local generator contract is network-free:
68
+
69
+ ```bash
70
+ npm --workspace workspai run typecheck
71
+ npm --workspace workspai run test:no-build -- \
72
+ src/__tests__/generators/gofiber-standard.test.ts \
73
+ src/__tests__/generators/gogin-standard.test.ts \
74
+ src/__tests__/generators/springboot-standard.test.ts \
75
+ src/__tests__/generators/dotnet-webapi-clean.test.ts \
76
+ src/__tests__/project-taxonomy-and-new-kits.test.ts
77
+ ```
78
+
79
+ Release qualification must also generate every owned kit in an isolated
80
+ workspace and run its native restore, format/lint, build, test, and container
81
+ checks on supported CI hosts. A machine without Go, .NET, or Rust can validate
82
+ the scaffold contract, but it cannot provide runtime qualification evidence.
@@ -203,8 +203,12 @@ canonical per-project storage boundary.
203
203
 
204
204
  Workspai-generated agent entry projections are downstream consumers and are
205
205
  excluded from Graph inventory and Git diff hashing. Regenerating `AGENTS.md`,
206
- adapter entry files, or the Amazon Q entry rule therefore cannot invalidate the
207
- Graph that produced them or become circular architecture evidence.
206
+ adapter entry files, GitHub agent definitions, or the Amazon Q entry rule
207
+ therefore cannot invalidate the Graph that produced them or become circular
208
+ architecture evidence. The reserved `.workspai-workspace` marker is excluded
209
+ for the same ownership reason: its extension/CLI usage telemetry and other
210
+ operational metadata describe Workspai activity, not source architecture. Real
211
+ repository and workspace source changes remain part of the live fingerprint.
208
212
 
209
213
  ## Pick the command by question
210
214
 
@@ -47,6 +47,22 @@ The authoritative scaffold/import/lifecycle tiers are in
47
47
  Inspect one project's effective surface with
48
48
  `npx workspai project commands --json` before orchestration.
49
49
 
50
+ ## Cold initialization and progress
51
+
52
+ Dependency initialization uses a longer bounded budget than ordinary test or
53
+ build stages. Python, JVM, .NET, and Rust cold starts receive up to ten minutes;
54
+ other runtimes receive up to five. An explicit
55
+ `RAPIDKIT_WORKSPACE_RUN_STAGE_TIMEOUT_MS` value always takes precedence.
56
+
57
+ Human-readable runs stream child progress so a slow package restore does not
58
+ look frozen. JSON mode keeps stdout machine-readable. The final report records
59
+ the command that actually ran, status, exit code, duration, diagnostic, and
60
+ runtime unit instead of repeating only the planned command.
61
+
62
+ Full workspace `init` continues after a project failure so one run reports every
63
+ missing runtime or failed dependency bootstrap. Each failure remains explicit,
64
+ and the overall run still fails when any project fails.
65
+
50
66
  ## Enterprise configuration
51
67
 
52
68
  Override stage commands per project via `.workspai/context.json`:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workspai",
3
- "version": "0.70.0",
3
+ "version": "0.71.0",
4
4
  "type": "module",
5
5
  "description": "Open-source workspace intelligence CLI for software systems: create, adopt, govern, verify, and align polyglot workspaces for humans, CI, IDEs, and AI agents.",
6
6
  "keywords": [
@@ -1 +0,0 @@
1
- export{b as printAnalyzeReport,a as runAnalyze}from'./chunk-WUXJCSYO.js';
@@ -1 +0,0 @@
1
- export{b as AUTOPILOT_RELEASE_ALIAS_FILENAME,a as AUTOPILOT_RELEASE_LAST_RUN_FILENAME,c as runAutopilotRelease}from'./chunk-UT57IFS4.js';
@@ -1,5 +0,0 @@
1
- import {c as c$1,b as b$1}from'./chunk-WCJU3CFG.js';import {d,b,e}from'./chunk-37SWTS2B.js';import {a}from'./chunk-TKXRP2B4.js';import {d as d$2}from'./chunk-S5KTATOU.js';import {a as a$1}from'./chunk-NMXGSVMD.js';import {q as q$1,z as z$1,u as u$1}from'./chunk-KFTJVVJR.js';import {k,m,g as g$1,f}from'./chunk-U5ENEDJA.js';import {g}from'./chunk-FE5R6EUV.js';import {p,t}from'./chunk-ODK4LCEL.js';import {a as a$2}from'./chunk-TQEMLBAG.js';import {c,d as d$1}from'./chunk-25AWHAB5.js';import {e as e$1,g as g$2}from'./chunk-RGNCL5OB.js';import {u,q,t as t$1}from'./chunk-VQZ5PI5J.js';import J from'fs';import w from'path';import T from'chalk';import {execa}from'execa';var ct={"python-fastapi":{runtime:"python",framework:"FastAPI",markers:["pyproject.toml","fastapi"],commands:{init:"python -m pip install -e .",test:"pytest",build:"python -m build",start:"uvicorn main:app --reload"},errorPatterns:{setup:["ModuleNotFoundError","No module named","pip: command not found"],"test-failure":["FAILED","ERROR","test session started"],dependency:["ImportError","missing.*dependency"],runtime:["TypeError","AttributeError","ValueError"],timeout:["timeout","Timeout","timed out"],unknown:[]},healthCheck:{stage:"start",type:"http",value:"http://localhost:8000/docs"},validation:{command:"python -m pip list | grep fastapi",error:"FastAPI not installed"}},"python-django":{runtime:"python",framework:"Django",markers:["manage.py","django"],commands:{init:"python manage.py migrate",test:"python manage.py test",build:"python manage.py collectstatic --noinput",start:"python manage.py runserver 0.0.0.0:8000"},errorPatterns:{setup:["ModuleNotFoundError","ProgrammingError.*migrate"],"test-failure":["FAILED","ERROR","Ran.*test"],dependency:["ImportError","missing.*dependency"],runtime:["DatabaseError","ImproperlyConfigured"],timeout:["timeout","Timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:8e3},dependencies:["init"]},"node-nestjs":{runtime:"node",framework:"NestJS",markers:["package.json","@nestjs/core"],commands:{init:"npm install",test:"npm run test",build:"npm run build",start:"npm run start"},errorPatterns:{setup:["npm ERR!","ENOENT","not found"],"test-failure":["Tests.*failed","FAIL","fail.*test"],dependency:["Cannot find module","ERR_MODULE_NOT_FOUND"],runtime:["TypeError","Error: ","ReferenceError"],timeout:["timeout","TIMEOUT"],unknown:[]},healthCheck:{stage:"start",type:"port",value:3e3}},"node-express":{runtime:"node",framework:"Express",markers:["package.json","express"],commands:{init:"npm install",test:"npm run test",build:"npm run build",start:"npm start"},errorPatterns:{setup:["npm ERR!","ENOENT"],"test-failure":["failed","FAIL"],dependency:["Cannot find module"],runtime:["Error","TypeError"],timeout:["timeout"],unknown:[]}},"go-fiber":{runtime:"go",framework:"Fiber",markers:["go.mod","fiber"],commands:{init:"go mod download && go mod tidy",test:"go test ./...",build:"go build -o app .",start:"./app"},errorPatterns:{setup:["go: .*not found","cannot find","go mod tidy"],"test-failure":["FAIL","--- FAIL"],dependency:["missing.*module"],runtime:["panic","fatal","Error"],timeout:["timeout","context deadline"],unknown:[]},dependencies:["init"]},"go-gin":{runtime:"go",framework:"Gin",markers:["go.mod","gin-gonic"],commands:{init:"go mod download && go mod tidy",test:"go test ./...",build:"go build -o app .",start:"./app"},errorPatterns:{setup:["go: .*not found"],"test-failure":["FAIL"],dependency:["missing.*module"],runtime:["panic"],timeout:["timeout"],unknown:[]}},"java-springboot":{runtime:"java",framework:"Spring Boot",markers:["pom.xml","build.gradle","spring-boot"],commands:{init:"mvn dependency:go-offline",test:"mvn test",build:"mvn package -DskipTests",start:"mvn spring-boot:run"},errorPatterns:{setup:["\\[ERROR\\]","BUILD FAILURE","missing dependencies"],"test-failure":["\\[ERROR\\] Tests run:","BUILD FAILURE"],dependency:["missing.*dependency"],runtime:["Exception","Error","NullPointerException"],timeout:["timeout","Timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:8080}},"php-laravel":{runtime:"php",framework:"Laravel",markers:["composer.json","artisan","app/Models"],commands:{init:"composer install && php artisan migrate:fresh --seed",test:"php artisan test",build:"php artisan config:cache && php artisan route:cache && php artisan view:cache",start:"php artisan serve --host=0.0.0.0 --port=8000"},errorPatterns:{setup:["Composer.*lock","Fatal error","Class.*not found"],"test-failure":["FAILED","Tests.*failed"],dependency:["Class.*not found","require.*failed"],runtime:["Fatal error","Exception","Error"],timeout:["timeout","Timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:8e3},dependencies:["init"]},"php-symfony":{runtime:"php",framework:"Symfony",markers:["composer.json","symfony.lock","bin/console"],commands:{init:"composer install && php bin/console doctrine:database:create",test:"php bin/phpunit",build:"php bin/console cache:clear --env=prod",start:"symfony serve --no-tls"},errorPatterns:{setup:["Composer.*error","Fatal error"],"test-failure":["FAILED","failure"],dependency:["Class.*not found"],runtime:["Fatal error","Exception"],timeout:["timeout"],unknown:[]},dependencies:["init"]},"rust-actix":{runtime:"rust",framework:"Actix-web",markers:["Cargo.toml","actix"],commands:{init:"cargo fetch",test:"cargo test",build:"cargo build --release",start:"cargo run --release"},errorPatterns:{setup:["error: .*could not find","failed.*download"],"test-failure":["test result:","FAILED"],dependency:["can.t find.*crate"],runtime:["error\\[E","thread.*panicked"],timeout:["timeout"],unknown:[]},validation:{command:"cargo --version",error:"Rust/Cargo not installed"}},"rust-axum":{runtime:"rust",framework:"Axum",markers:["Cargo.toml","axum"],commands:{init:"cargo fetch",test:"cargo test",build:"cargo build --release",start:"cargo run --release"},errorPatterns:{setup:["error: .*could not find"],"test-failure":["test result:","FAILED"],dependency:["can.t find.*crate"],runtime:["error\\[E"],timeout:["timeout"],unknown:[]}},"rust-rocket":{runtime:"rust",framework:"Rocket",markers:["Cargo.toml","rocket"],commands:{init:"cargo fetch",test:"cargo test",build:"cargo build --release",start:"cargo run --release"},errorPatterns:{setup:["error: .*could not find"],"test-failure":["FAILED"],dependency:["can.t find"],runtime:["error\\[E"],timeout:["timeout"],unknown:[]}},"dotnet-aspnetcore":{runtime:"dotnet",framework:"ASP.NET Core",markers:[".csproj",".sln","Program.cs"],commands:{init:"dotnet restore",test:"dotnet test",build:"dotnet build -c Release",start:"dotnet run"},errorPatterns:{setup:["error CS","CSPROJ.*not found","NuGet.*restore"],"test-failure":["Failed:.*test","FAILED"],dependency:["error NU1101"],runtime:["error CS","Exception"],timeout:["timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:5e3}},"elixir-phoenix":{runtime:"elixir",framework:"Phoenix",markers:["mix.exs","phoenix"],commands:{init:"mix setup",test:"mix test",build:"mix compile --all-warnings",start:"mix phx.server"},errorPatterns:{setup:["\\*\\* \\(.*Error\\)","Mix.InstallError"],"test-failure":["\\d+\\sfailed","FAILED"],dependency:["dependencies are not available"],runtime:["\\*\\* \\(","RuntimeError"],timeout:["timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:4e3},dependencies:["init"]},"ruby-rails":{runtime:"ruby",framework:"Rails",markers:["Gemfile","config/application.rb","bin/rails"],commands:{init:"bundle install && rails db:prepare",test:"rails test",build:"rails assets:precompile",start:"rails server --binding=0.0.0.0 --port=3000"},errorPatterns:{setup:["Bundler::.*Error","Gem::.*Error"],"test-failure":["failures,","error,","FAILED"],dependency:["Could not find.*gem"],runtime:["Error","Exception","NoMethodError"],timeout:["timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:3e3},dependencies:["init"]},"ruby-sinatra":{runtime:"ruby",framework:"Sinatra",markers:["Gemfile","app.rb","sinatra"],commands:{init:"bundle install",test:"rspec",build:`echo "Sinatra apps don't require build"`,start:"ruby app.rb"},errorPatterns:{setup:["Bundler.*Error","Gem.*Error"],"test-failure":["failure","FAILED"],dependency:["Could not find.*gem"],runtime:["Error","NoMethodError"],timeout:["timeout"],unknown:[]}}},dt={init:{python:["pip install -e .","poetry install","pip install -r requirements.txt"],node:["npm install","pnpm install","yarn install"],go:["go mod download && go mod tidy","go get ./..."],java:["mvn dependency:go-offline","gradle dependencies"],php:["composer install"],rust:["cargo fetch"],dotnet:["dotnet restore"],c:["cmake -S . -B build"],cpp:["cmake -S . -B build"],elixir:["mix deps.get"],ruby:["bundle install"],clojure:["clojure -P"],scala:["sbt update"],kotlin:["./gradlew dependencies","gradle dependencies"],deno:[],bun:["bun install"],"jvm-generic":["mvn dependency:go-offline","gradle dependencies"],unknown:[]},test:{python:["pytest","python -m unittest","python -m pytest"],node:["npm test","npm run test"],go:["go test ./...","make test"],java:["mvn test","gradle test"],php:["php artisan test","phpunit","pest"],rust:["cargo test"],dotnet:["dotnet test"],c:["ctest --test-dir build --output-on-failure"],cpp:["ctest --test-dir build --output-on-failure"],elixir:["mix test"],ruby:["rspec","ruby -m minitest"],clojure:["clojure -X:test"],scala:["sbt test"],kotlin:["./gradlew test","gradle test"],deno:["deno task test","deno test"],bun:["bun test","bun run test"],"jvm-generic":["mvn test","gradle test"],unknown:[]},build:{python:["python -m build","python setup.py build"],node:["npm run build"],go:["go build -o app .","go build ./..."],java:["mvn package -DskipTests","gradle build -x test"],php:['echo "PHP build: typically no build step"'],rust:["cargo build --release"],dotnet:["dotnet build -c Release"],c:["cmake --build build"],cpp:["cmake --build build"],elixir:["mix compile"],ruby:["gem build *.gemspec"],clojure:[],scala:["sbt compile"],kotlin:["./gradlew build","gradle build"],deno:["deno task build"],bun:["bun run build"],"jvm-generic":["mvn package -DskipTests","gradle build"],unknown:[]},start:{python:["python app.py","python main.py","uvicorn main:app --reload"],node:["npm start","node index.js","node src/index.js"],go:["./app","go run main.go","go run ./..."],java:["mvn spring-boot:run","gradle bootRun","java -jar target/*.jar"],php:["php -S 0.0.0.0:8000","php artisan serve"],rust:["cargo run --release","./target/release/app"],dotnet:["dotnet run"],c:[],cpp:[],elixir:["mix phx.server","iex -S mix"],ruby:["rails server","ruby app.rb","bundle exec puma"],clojure:["clojure -M:run"],scala:["sbt run"],kotlin:["./gradlew run","gradle run"],deno:["deno task start","deno task dev"],bun:["bun run start","bun run dev"],"jvm-generic":["java -jar *.jar","gradle run"],unknown:[]}};function oe(e,r){if(r){let t=r.trim().toLowerCase().replace(/[_.\s]+/g,"-"),n=f(r),s=`${e}-${n==="gofiber"?"fiber":n==="gogin"?"gin":n==="dotnet"?"aspnetcore":n!=="unknown"?n:t==="fiber"?"fiber":t==="aspnetcore"||t==="asp-net-core"?"aspnetcore":t}`;return ct[s]}}function Be(e,r,t){if(r){let n=oe(e,r);if(n&&n.commands[t])return n.commands[t]}if(["init","test","build","start"].includes(t)){let n=dt[t]?.[e]??[];return n.length>0?n[0]:void 0}}var lt={test:"test",build:"build",start:"start"};function fe(e){if(e.stage==="init")return e.runtime==="node"?c$1(e.projectPath):Be(e.runtime,e.framework,e.stage);if(e.runtime==="node"){let r=lt[e.stage];if(r){let t=u$1(e.projectPath,r,{framework:e.framework});if(t)return b$1(e.projectPath,t.scriptName)}}return Be(e.runtime,e.framework,e.stage)}function pt(e){let r=k(e).map(t=>t==="python"?"python":t==="node"||t==="bun"?"node":t==="go"?"go":t==="java"?"java":t==="php"?"php":t==="rust"?"rust":t==="dotnet"?"dotnet":t==="elixir"?"elixir":t==="ruby"?"ruby":t==="clojure"||t==="scala"||t==="kotlin"?"jvm-generic":null).filter(t=>t!==null).filter((t,n,o)=>o.indexOf(t)===n);return {primary:r.length>0?r[0]:"unknown",secondary:r.slice(1)}}function ze(e){return pt(e).primary}function ge(e,r){if(!e)return "unknown";r||(r={setup:["ModuleNotFoundError","No module named","npm ERR!","error:","not found"],"test-failure":["FAILED","FAIL","failed"],dependency:["cannot find module","import.*error"],runtime:["Exception","Error:","panic","TypeError"],timeout:["timeout","Timeout","deadline exceeded"],unknown:[]});for(let[t,n]of Object.entries(r))for(let o of n)if(new RegExp(o,"i").test(e))return t;return "unknown"}async function se(e,r){let t=e.split(/[&|;]\s*/)[0].trim().split(/\s+/)[0];if(["echo","cd","pwd","test","true","false","exit"].includes(t))return {valid:true};if(t.includes("/")||t.includes("\\")){let o=w.isAbsolute(t)?t:w.resolve(r??process.cwd(),t);try{return await J.promises.access(o,process.platform==="win32"?J.constants.F_OK:J.constants.X_OK),{valid:true}}catch{return {valid:false,reason:`Command '${t}' not found or not executable in '${r??process.cwd()}'`}}}try{let o=process.platform==="win32"?"where":"which";if((await execa(o,[t],{reject:false})).exitCode===0)return {valid:true}}catch{}return {valid:false,reason:`Command '${t}' not found or not executable`}}function Ve(e,r,t){if(!r)return e;let n=typeof r=="object"&&!Array.isArray(r)&&("dev"in r||"staging"in r||"prod"in r||"default"in r)&&!Object.keys(r).some(o=>["init","test","build","start"].includes(o))?r:{};return t&&typeof n[t]=="string"?n[t]:typeof n.default=="string"?n.default:e}async function Je(e,r){if(!e)return {healthy:true};switch(e.type){case "port":{let t=e.value;try{let n=await import('net');return new Promise(o=>{let s=new n.Socket,u=5e3;s.setTimeout(u),s.on("connect",()=>{s.destroy(),o({healthy:true,reason:`Port ${t} is listening`});}),s.on("timeout",()=>{s.destroy(),o({healthy:false,reason:`Port ${t} timeout after ${u}ms`});}),s.on("error",c=>{s.destroy(),o({healthy:false,reason:`Port ${t} error: ${String(c)}`});}),s.connect(t,"localhost");})}catch(n){return {healthy:false,reason:`Port check error: ${n instanceof Error?n.message:String(n)}`}}}case "http":{let t=e.value,n;try{let o=new AbortController;n=setTimeout(()=>o.abort(),5e3);let s=await fetch(t,{method:"GET",signal:o.signal});return {healthy:s.status===200,reason:`HTTP ${s.status}`,metadata:{status:s.status}}}catch(o){return {healthy:false,reason:`HTTP check error: ${o instanceof Error?o.message:String(o)}`}}finally{n&&clearTimeout(n);}}case "log":{let t=e.value;if(!r)return {healthy:true};try{let n=[w.join(r,".workspai","last-run.log"),w.join(r,".rapidkit","last-run.log")].find(o=>J.existsSync(o));if(n){let o=J.readFileSync(n,"utf-8"),s=new RegExp(t,"i");return {healthy:s.test(o),reason:s.test(o)?"Log pattern found":"Log pattern not found"}}return {healthy:true,reason:"No log file to check"}}catch(n){return {healthy:false,reason:`Log check error: ${n instanceof Error?n.message:String(n)}`}}}case "command":{let t=e.value;try{let n=await execa(t,[],{cwd:r,reject:false,shell:true});return {healthy:n.exitCode===0,reason:n.exitCode===0?"Health check passed":"Health check failed",metadata:{exitCode:n.exitCode}}}catch(n){return {healthy:false,reason:`Command check error: ${n instanceof Error?n.message:String(n)}`}}}default:return {healthy:true}}}var qe={init:"init",test:"test",build:"build",start:"start"};function mt(e){return e in qe?qe[e]:null}function ft(e,r){let n=q$1(e)?.contextJson?.commands;if(!n||typeof n!="object"||Array.isArray(n))return;let o=n[r];if(typeof o=="string"&&o.trim().length>0)return o.trim();if(o&&typeof o=="object"&&!Array.isArray(o)){let s=o,u=s.default??s.dev;if(typeof u=="string"&&u.trim().length>0)return u.trim()}}function Ye(e,r,t=z$1(e)){let n=mt(r);if(!n)return ft(e,r)?{supported:true}:{supported:false,reason:`Workspace stage "${r}" is not part of the Workspai fleet contract.`};if(!t.projectRoot)return {supported:false,reason:"No Workspai project metadata was detected for this target."};let o=t.commandMap[n];if(!o||o.status!=="supported"){let s=t.runtimeSupportTier==="observed"||t.frameworkSupportTier==="observed";return {supported:false,reason:o?.reason??`Command "${n}" is not supported for this project runtime/framework.`,shouldFail:!s}}return {supported:true}}var gt=new Set(["init","test","build","start"]),yt=new Set([".git","node_modules",".workspai",".rapidkit",".venv","dist","build","coverage","htmlcov"]);async function z(e){try{return await J.promises.access(e,J.constants.F_OK),true}catch{return false}}async function ht(e){for(let r of e)if(await z(r))return true;return false}async function kt(e,r,t){if(r==="python"){let o=[w.join(e,".workspai","cli.py"),w.join(e,".rapidkit","cli.py")];for(let s of o)if(await z(s))return {valid:true};return {valid:false,reason:"Project-local .workspai/cli.py is missing. Run `workspai init` in this project first."}}let n=t.trim().split(/\s+/)[0];if(n&&["npm","npx","pnpm","yarn"].includes(n)){let o=e$1(n);if((await execa(o.command,[...o.prefixArgs,"--version"],{reject:false,env:g$2()})).exitCode===0)return {valid:true}}return se(t,e)}async function ae(e){let r=await J.promises.readFile(e,"utf-8");return JSON.parse(r)}function I(e){return e.replace(/\\/g,"/")}function bt(e){let r=e?.trim();return r?r.startsWith("project:")?r.slice(8).trim()||null:r:null}async function wt(e){let r=w.join(e,p.model);if(await z(r))try{let n=((await ae(r)).projects??[]).map(o=>typeof o.path=="string"?w.resolve(e,o.path):null).filter(o=>!!o).filter((o,s,u)=>u.indexOf(o)===s).filter(o=>J.existsSync(o));if(n.length>0)return n.sort()}catch{}return a$1(e,{skipDirs:yt,includeHiddenDirs:false,descendIntoMatchedProjects:false,isProjectDir:async(t,n)=>await ht([...u(t,"context.json"),...u(t,"project.json")])?true:w.resolve(t)===w.resolve(n)?false:k(t).length>0})}async function rt(e){for(let r of [w.join(".workspai","project.json"),w.join(".workspai","context.json"),w.join(".rapidkit","project.json"),w.join(".rapidkit","context.json")]){let t=w.join(e,r);if(await z(t))try{let n=await ae(t),o=n.name??n.projectName??n.slug;if(typeof o=="string"&&o.trim())return o.trim()}catch{}}return null}async function xt(e,r,t){let n=bt(t);if(!n)return {projects:r,normalizedScope:null};let o=I(n).toLowerCase(),s=[];for(let u of r){let c=I(w.relative(e,u)),m=w.basename(u),f=await rt(u);[c,m,f].filter(i=>typeof i=="string"&&i.length>0).map(i=>I(i).toLowerCase()).includes(o)&&s.push(u);}if(s.length===0)throw new Error(`Workspace run scope did not match any project: ${t}`);return {projects:s,normalizedScope:n}}async function vt(e,r,t){let n=await execa("git",["diff","--name-only",`${t}...HEAD`],{cwd:e,reject:false,env:a$2()});if(n.exitCode!==0)return new Set(r);let o=n.stdout.split(/\r?\n/).map(u=>u.trim()).filter(u=>u.length>0).map(u=>I(u));if(o.length===0)return new Set;let s=new Set;for(let u of r){let c=I(w.relative(e,u));if(!c||c===".")continue;let m=`${c}/`;o.some(f=>f===c||f.startsWith(m))&&s.add(u);}return s}async function Rt(e,r,t$1){let n=await g(e,t.workspaceContract)??q(e,"workspace.contract.json");if(await z(n))try{let d=await St(e,r,t$1,n);if(d.graphStatus!=="missing")return d}catch{return {expanded:t$1,graphStatus:"invalid",expansionDepth:0}}let o=await g(e,".workspai/workspace-dependency-graph.json")??q(e,"workspace-dependency-graph.json");if(!await z(o))return {expanded:t$1,graphStatus:"missing",expansionDepth:0};let s;try{s=await ae(o);}catch{return {expanded:t$1,graphStatus:"invalid",expansionDepth:0}}let u=new Set(r.map(d=>w.resolve(d))),c=new Map;if(!s||typeof s!="object"||Array.isArray(s))return {expanded:t$1,graphStatus:"invalid",expansionDepth:0};let m=Array.isArray(s.projects)?s.projects:[];for(let d of m){if(!d||typeof d!="object"||Array.isArray(d))continue;let i=d,l=typeof i.path=="string"?i.path:"",h=w.resolve(e,l);if(!u.has(h))continue;let k=Array.isArray(i.dependsOn)?i.dependsOn.filter(S=>typeof S=="string"):[];for(let S of k){let g=w.resolve(e,S);u.has(g)&&(c.has(g)||c.set(g,new Set),c.get(g)?.add(h));}}let f=d$2(c,t$1);return {expanded:f.reached,graphStatus:"loaded",expansionDepth:f.added}}async function St(e,r,t,n){let o=await ae(n);if(!o||typeof o!="object"||Array.isArray(o))return {expanded:t,graphStatus:"invalid",expansionDepth:0};let s=o,u=Array.isArray(s.projects)?s.projects:null;if(!u)return {expanded:t,graphStatus:"invalid",expansionDepth:0};let c=new Map,m=new Map;for(let h of r){let k=I(w.relative(e,h));m.set(k,w.resolve(h));}let f=new Map,d=new Map,i=new Map;for(let h of u){if(!h||typeof h!="object"||Array.isArray(h))continue;let k=h,S=typeof k.slug=="string"?k.slug:"",g=typeof k.relativePath=="string"?I(k.relativePath):S,y=m.get(g);!S||!y||c.set(S,y);}for(let h of u){if(!h||typeof h!="object"||Array.isArray(h))continue;let k=h,S=typeof k.slug=="string"?k.slug:"",g=c.get(S);if(!g)continue;let y=k.contracts&&typeof k.contracts=="object"&&!Array.isArray(k.contracts)?k.contracts:{},P=Array.isArray(y.dependsOn)?y.dependsOn.filter(R=>typeof R=="string"):[],$=Array.isArray(y.publishes)?y.publishes.filter(R=>typeof R=="string"):[],L=Array.isArray(y.consumes)?y.consumes.filter(R=>typeof R=="string"):[];for(let R of P){let E=c.get(R);E&&(i.has(E)||i.set(E,new Set),i.get(E)?.add(g));}for(let R of $)f.has(R)||f.set(R,new Set),f.get(R)?.add(g);for(let R of L)d.has(R)||d.set(R,new Set),d.get(R)?.add(g);}for(let[h,k]of f.entries()){let S=d.get(h);if(S)for(let g of k){i.has(g)||i.set(g,new Set);for(let y of S)y!==g&&i.get(g)?.add(y);}}let l=d$2(i,t);return {expanded:l.reached,graphStatus:"loaded",expansionDepth:l.added}}async function Ct(e,r){if(typeof r=="boolean")return r;let t=t$1(e,"policies.yml").find(s=>J.existsSync(s))??q(e,"policies.yml");if(!await z(t))return true;let n="";try{n=await J.promises.readFile(t,"utf-8");}catch{return true}let o=n.match(/^[\t ]*rules\.enforce_workspace_run_gates:\s*(true|false)\s*(?:#.*)?$/m);return o?o[1]==="true":true}function Et(e){let r=process.env.RAPIDKIT_WORKSPACE_RUN_STAGE_TIMEOUT_MS;if(r){let t=Number.parseInt(r,10);if(Number.isFinite(t)&&t>0)return t}return e==="init"?12e4:9e4}function jt(e){let r=e.trim();if(!/^\.\.?[\\/]/.test(r)||/[&|;<>()$`"']/.test(r))return null;let[t,...n]=r.split(/\s+/);return t?{file:t,args:n}:null}function Xe(e,r){let t=Number.parseInt(process.env[e]??"",10);return Number.isFinite(t)&&t>0?t:r}function ye(e){return new Promise(r=>setTimeout(r,e))}async function Pt(e){let r=process.argv[1];if(e.useRapidkitWrapper&&!r)return {exitCode:1,stdout:"",stderr:"Workspai entrypoint is unavailable for startup verification.",healthStatus:{healthy:false,reason:"Workspai entrypoint is unavailable."}};let t=e.useRapidkitWrapper&&r?execa(process.execPath,[r,"start"],{cwd:e.projectPath,reject:false,timeout:e.timeoutMs,env:{...process.env,RAPIDKIT_WORKSPACE_RUN_CHILD:"1"}}):execa(e.finalCommand,[],{cwd:e.projectPath,reject:false,shell:true,timeout:e.timeoutMs}),n=Promise.resolve(t).then(d=>({kind:"exit",result:d}),d=>({kind:"error",error:d})),o=Xe("WORKSPAI_WORKSPACE_RUN_STARTUP_GRACE_MS",2e3),s=await Promise.race([n,ye(o).then(()=>({kind:"alive"}))]);if(s.kind==="error"){let d=typeof s.error=="object"&&s.error!==null&&"timedOut"in s.error&&!!s.error.timedOut;return {exitCode:d?124:1,stdout:"",stderr:s.error instanceof Error?s.error.message:String(s.error),timedOut:d,healthStatus:{healthy:false,reason:"The start command failed before readiness."}}}if(s.kind==="exit"){let d=Number(s.result.exitCode??0);return {exitCode:d,stdout:String(s.result.stdout??""),stderr:String(s.result.stderr??""),healthStatus:{healthy:d===0,reason:d===0?"The start command completed successfully.":`The start command exited with code ${d} before readiness.`}}}let u=oe(e.runtime,e.framework)?.healthCheck,c=u?{healthy:false,reason:"The configured health check has not passed yet."}:{healthy:true,reason:`The service remained alive for ${o}ms (bounded startup smoke).`};if(u){let d=Xe("WORKSPAI_WORKSPACE_RUN_STARTUP_HEALTH_TIMEOUT_MS",15e3),i=Date.now()+d;for(;Date.now()<i;){let l=await Je(u,e.projectPath);if(c={healthy:l.healthy,reason:l.reason},l.healthy)break;if((await Promise.race([n,ye(350).then(()=>({kind:"alive"}))])).kind!=="alive"){c={healthy:false,reason:"The service exited before its configured health check passed."};break}}}try{t.kill?.("SIGTERM",{forceKillAfterDelay:1e3});}catch{try{t.kill?.();}catch{}}let m=await Promise.race([n,ye(2e3).then(()=>({kind:"alive"}))]),f=m.kind==="exit"?m.result:void 0;return {exitCode:c.healthy?0:1,stdout:String(f?.stdout??""),stderr:String(f?.stderr??""),healthStatus:c}}async function he(e,r,t){let n=process.argv[1];if(!n)return {exitCode:1,stdout:"",stderr:"RapidKit entrypoint is unavailable for nested workspace-run execution."};try{let o=await execa(process.execPath,[n,...e],{cwd:r,reject:false,timeout:t,env:{...process.env,RAPIDKIT_WORKSPACE_RUN_CHILD:"1"}});return {exitCode:Number(o.exitCode??1),stdout:o.stdout,stderr:o.stderr}}catch(o){return {exitCode:typeof o=="object"&&o!==null&&"timedOut"in o&&!!o.timedOut?124:1,stdout:typeof o=="object"&&o!==null&&"stdout"in o?String(o.stdout??""):"",stderr:typeof o=="object"&&o!==null&&"stderr"in o?String(o.stderr??""):o instanceof Error?o.message:String(o)}}}function At(e){return e==="node"||e==="go"||e==="java"||e==="python"||e==="dotnet"||e==="rust"||e==="php"}function Ft(){return process.env.VITEST==="true"||process.env.VITEST==="1"||process.env.NODE_ENV==="test"}function Ot(e,r=8){if(e.length<=r)return e.join(`
2
- `);let t=3;return [...e.slice(0,t),...e.slice(-(r-t))].join(`
3
- `)}function Dt(e){let r=/(?:\bnot found\b|\bno such\b|\bmissing\b|\bfailed\b|\berror\b|\bexception\b|\bcannot\b|\bdenied\b|\btimeout\b|\btimed out\b|\benoent\b|\beacces\b|\beperm\b)/i;return [...e].reverse().find(t=>r.test(t))??e.at(-1)}async function Tt(e){let r=process.cwd();try{process.chdir(e);let{handleInitCommand:t}=await import('./index.js');return {exitCode:await t(["init"]),stdout:"",stderr:""}}finally{process.chdir(r);}}async function Qe(e){let r=i=>{let l=g$1(i);return l==="node"||l==="bun"?"node":l==="python"?"python":l==="go"?"go":l==="java"?"java":l==="php"?"php":l==="ruby"?"ruby":l==="rust"?"rust":l==="dotnet"?"dotnet":l==="elixir"?"elixir":l==="clojure"||l==="scala"||l==="kotlin"?"jvm-generic":ze(e)},t=i=>{if(!i)return;let l=f(i);if(new Set(["fastapi","django","flask","nestjs","express","fastify","koa","gofiber","gogin","echo","springboot","laravel","symfony","rails","sinatra","dotnet","actix","axum","rocket","phoenix"]).has(l))return l},n=q$1(e),o=n?.detection??m(e,n?.projectJson??null),s=n?.contextJson,u=r(o.runtime),c=t(o.key),m$1={},f$1=new Set(["init","test","build","start"]);if(s?.commands&&typeof s.commands=="object")for(let[i,l]of Object.entries(s.commands))typeof l=="string"&&f$1.has(i)&&(m$1[i]=l);let d;if(s?.commandEnvironments&&typeof s.commandEnvironments=="object"){let i=s.commandEnvironments;d={dev:typeof i.dev=="string"?i.dev:void 0,staging:typeof i.staging=="string"?i.staging:void 0,prod:typeof i.prod=="string"?i.prod:void 0,default:typeof i.default=="string"?i.default:void 0};}return {runtime:u,framework:c,commandOverrides:Object.keys(m$1).length>0?m$1:void 0,environmentCommandVariants:d,environment:typeof s?.environment=="string"?s.environment:void 0}}async function Ze(e,r,t,n,o,s,u){let c=!o?.[r]&&At(t),m;if(o&&o[r]?m=o[r]:c?m=`rapidkit ${r}`:m=fe({projectPath:e,runtime:t,framework:n,stage:r}),!m)return {exitCode:127,command:`<stage not supported for ${t}>`,message:`No stage command found for runtime '${t}' and framework '${n||"unknown"}'`,errorCategory:"runtime"};let f=Ve(m,s,u);if(!f)return {exitCode:127,command:m,message:"Failed to resolve stage command",errorCategory:"runtime"};let d=fe({projectPath:e,runtime:t,framework:n,stage:r});if(c){if(d){let v=c?await kt(e,t,d):await se(d,e);if(!v.valid)return {exitCode:127,command:f,message:v.reason||"Command not available",errorCategory:"setup"}}}else {let v=await se(f,e);if(!v.valid)return {exitCode:127,command:f,message:v.reason||"Command not available",errorCategory:"setup"}}let i=0,l="",h="",k,S,g=Et(r),y=Date.now();try{let v=r==="start"?await Pt({projectPath:e,finalCommand:f,useRapidkitWrapper:c,runtime:t,framework:n,timeoutMs:g}):c?r==="init"&&Ft()?await Tt(e):await he([r],e,g):await(async()=>{let A=jt(f);return A?execa(A.file,A.args,{cwd:e,reject:false,timeout:g,forceKillAfterDelay:1e3}):execa(f,[],{cwd:e,reject:false,shell:true,timeout:g,forceKillAfterDelay:1e3})})();if(i=Number(v.exitCode??0),l=v.stdout,h=v.stderr,S=r==="start"?v.healthStatus:void 0,i!==0){let A=`${l}
4
- ${h}`,G=Date.now()-y;k=i===124||ge(A)==="timeout"||i===143&&G>=Math.floor(g*.8)?"timeout":ge(A);}}catch(v){let A=typeof v=="object"&&v!==null&&"timedOut"in v&&!!v.timedOut;return {exitCode:A?124:1,command:f,message:A?`Stage timed out after ${g}ms`:v instanceof Error?v.message:"Command execution failed",errorCategory:A?"timeout":"runtime"}}let P=`${l}
5
- ${h}`.split(/\r?\n/).map(v=>v.trim()).filter(Boolean),$=Ot(P),L=Dt(P),R=Date.now()-y,E=i===124||k==="timeout"||i===143&&R>=Math.floor(g*.8),O=i===0?void 0:E?"timeout":k,M=i===0||!O?void 0:{category:O,exitCode:i,command:f,timedOut:E,timeoutMs:g,...$?{outputExcerpt:$}:{}};return {exitCode:i,command:f,errorCategory:O,healthStatus:S,failureDiagnostic:M,message:E?`Stage timed out after ${g}ms`:i!==0?L?`Stage failed with exit code ${i}: ${L}`:`Stage failed with exit code ${i}`:void 0}}function et(e){try{return JSON.parse(e)}catch{return null}}function Wt(e){switch(e){case "dotnet":return "Install .NET 8+ SDK, then rerun `npx workspai setup dotnet` or `npx workspai init`.";case "go":return "Install Go 1.21+, then rerun `npx workspai setup go` or `npx workspai init`.";case "java":case "jvm-generic":return "Install Java 21+ and Maven/Gradle, then rerun `npx workspai setup java` or `npx workspai init`.";case "node":return "Install Node.js LTS and npm/pnpm/yarn, then rerun `npx workspai setup node` or `npx workspai init`.";case "python":return "Install Python 3.10+ and pip/Poetry, then rerun `npx workspai setup python` or `npx workspai init`.";default:return null}}async function It(e){let r=[],t=await he(["doctor","workspace","--json"],e);if(t.exitCode!==0)r.push({gate:"doctor-workspace",status:"fail",summary:"doctor workspace command failed"});else {let s=et(t.stdout)?.healthScore,u=Number(s?.errors??0);Number.isFinite(u)&&u>0?r.push({gate:"doctor-workspace",status:"fail",summary:`doctor workspace reports ${u} error(s)`}):r.push({gate:"doctor-workspace",status:"pass",summary:"doctor workspace passed"});}let n=await he(["readiness","--json"],e);if(n.exitCode!==0)r.push({gate:"readiness",status:"fail",summary:"readiness command failed"});else {let o=et(n.stdout),s=String(o?.overallStatus??"").toLowerCase();s==="fail"?r.push({gate:"readiness",status:"fail",summary:"readiness overall status is fail"}):s==="warn"?r.push({gate:"readiness",status:"warn",summary:"readiness overall status is warn"}):r.push({gate:"readiness",status:"pass",summary:"readiness overall status is pass"});}return r}var $t=new Set(["dev","stop"]);function Mt(e){let r=e.trim();return !r||$t.has(r.toLowerCase())?false:gt.has(r)?true:/^[a-z][a-z0-9_-]*$/i.test(r)}function tt(e,r,t){let n=I(w.relative(t,r));return (Array.isArray(e.projects)?e.projects:[]).some(s=>{if(!s||typeof s!="object")return false;let u=s,c=[u.relativePath,u.path].filter(m=>typeof m=="string"&&m.length>0).map(m=>I(m));return u.status==="passed"&&(c.includes(n)||c.some(m=>m.endsWith(`/${n}`)))})}function Nt(e,r){return oe(e,r)?.dependencies??[]}function _t(e,r){let t=Math.max(1,Math.min(4,r)),n=Number(e??t);return Number.isFinite(n)?Math.max(1,Math.min(16,Math.trunc(n))):t}async function br(e$1){if(!Mt(e$1.stage))throw new Error(`Unsupported workspace run stage: ${e$1.stage}`);let r=Date.now(),t=w.resolve(e$1.workspacePath);c({blockId:"workspace.run.resolve",status:"running",message:"Resolving workspace project fleet",component:"workspace-run"});let n=await d(t),o=await wt(t),{projects:s,normalizedScope:u}=await xt(t,o,e$1.scope),c$1=e$1.affected===true,m=e$1.blastRadius===true,f=e$1.since?.trim()||"HEAD~1",d$2=c$1?await vt(t,s,f):new Set(s),i,l="not-applicable",h=0,k="all";if(c$1&&m){let p=await Rt(t,o,d$2);i=p.expanded,l=p.graphStatus,h=p.expansionDepth,k="affected+blast-radius";}else c$1?(i=d$2,k="affected"):(i=d$2,k="all");c({blockId:"workspace.run.resolve",status:"succeeded",message:`Resolved ${s.length} project(s)`,component:"workspace-run",attributes:{projects:s.length,selectionMode:k}}),c({blockId:"workspace.run.gates",status:"running",message:"Evaluating workspace run gates",component:"workspace-run"});let S=e$1.stage==="init"||e$1.planOnly===true?false:await Ct(t,e$1.enforceGates),g=S?await It(t):[{gate:"doctor-workspace",status:"skipped",summary:"workspace run gates disabled"},{gate:"readiness",status:"skipped",summary:"workspace run gates disabled"}],y=g.find(p=>p.status==="fail");c({blockId:"workspace.run.gates",status:y?"blocked":"succeeded",message:y?`Blocked by ${y.gate}`:"Workspace run gates passed",component:"workspace-run",attributes:{gates:g}});let P=s.filter(p=>i.has(p)),$=e$1.continueOnError===true||e$1.stage==="init",L=e$1.parallel===true,R=_t(e$1.maxWorkers,P.length),E=P.length,O=0;c({blockId:"workspace.run.execute",status:y?"blocked":"running",message:y?`Execution blocked by ${y.gate}`:`Executing ${e$1.stage} across ${E} project(s)`,component:"workspace-run",progress:{completed:0,total:E},attributes:{stage:e$1.stage,parallel:L,maxWorkers:R}}),e$1.json||console.log(T.gray(`Workspace run (${e$1.stage}) started: ${E} target(s), ${L?`parallel x${R}`:"sequential"}`));let M=new Map;for(let p of o){let b=I(w.relative(t,p)),a=await rt(p),N=s.includes(p),j=N&&i.has(p);M.set(p,{path:p,relativePath:b,projectName:a??(w.basename(b)||w.basename(p)),selected:j,affected:j,status:"skipped",exitCode:null,durationMs:0,reason:j?void 0:N?"not affected":"outside scope",framework:void 0,runtimeDetected:void 0,executionCommand:void 0});}if(y)for(let p of P){let b=M.get(p);b&&(b.status="skipped",b.reason=`blocked by ${y.gate}`);}else {let p=async b=>{let a$1=M.get(b);if(!a$1)return;let N=I(w.relative(t,b));e$1.json||console.log(T.gray(`\u23F3 [${O}/${E}] ${e$1.stage} ${N}`)),a$1.selected=true,a$1.affected=true;let j=Date.now(),W=a(b),D=e$1.runtime?.trim().toLowerCase(),B=W.units.filter(x=>!D||x.runtime===D).map(x=>({unit:x,stage:x.stages.find(F=>F.stage===e$1.stage)})).filter(x=>!!x.stage),Y=B.map(({unit:x,stage:F})=>({unitId:x.id,runtime:x.runtime,role:x.role,root:x.root,manifest:x.manifest,stage:F.stage,command:F.command,status:"planned",exitCode:null,durationMs:0}));if(a$1.runtimeExecutions=Y,e$1.planOnly){a$1.runtimeDetected=B[0]?.unit.runtime,a$1.status="skipped",a$1.reason=B.length>0?`plan only: ${B.length} runtime unit(s)`:D?`no ${D} runtime unit supports stage "${e$1.stage}"`:`no runtime unit supports stage "${e$1.stage}"`,a$1.durationMs=Date.now()-j,O+=1;return}if(W.polyglot||D){if(B.length===0){a$1.status="failed",a$1.reason=D?`No ${D} runtime unit supports stage "${e$1.stage}"`:`No runtime unit supports stage "${e$1.stage}"`,a$1.errorCategory="setup",a$1.errorMessage=a$1.reason,a$1.exitCode=127,a$1.durationMs=Date.now()-j,O+=1;return}let x;for(let C=0;C<B.length;C+=1){let{unit:xe,stage:ve}=B[C],V=Y[C],Re=w.resolve(b,xe.root),ut=Date.now(),de=await Qe(Re),U=await Ze(Re,e$1.stage,xe.runtime,de.framework,{[e$1.stage]:ve.command},de.environmentCommandVariants,de.environment);if(V.durationMs=Date.now()-ut,V.exitCode=U.exitCode,V.status=U.exitCode===0?"passed":"failed",V.reason=U.message,V.errorCategory=U.errorCategory,V.failureDiagnostic=U.failureDiagnostic,U.exitCode!==0&&!x&&(x=U.message??ve.command),U.exitCode!==0&&!$){for(let Se of Y.slice(C+1))Se.status="skipped",Se.reason="stopped after runtime-unit failure";break}}let F=Y.find(C=>C.status==="failed");a$1.runtimeDetected=B[0]?.unit.runtime,a$1.executionCommand=Y.filter(C=>C.status!=="skipped").map(C=>`[${C.runtime}:${C.root}] ${C.command}`).join(" && "),a$1.durationMs=Date.now()-j,a$1.exitCode=F?.exitCode??0,a$1.status=F?"failed":"passed",a$1.reason=F?x??"runtime-unit stage failed":void 0,a$1.errorCategory=F?F.errorCategory??"runtime":void 0,a$1.errorMessage=a$1.reason,a$1.failureDiagnostic=F?.failureDiagnostic,O+=1;return}let{runtime:ie,framework:ue,commandOverrides:st,environmentCommandVariants:at,environment:it}=await Qe(b);a$1.runtimeDetected=ie,a$1.framework=ue;let ce=Ye(b,e$1.stage);if(!ce.supported){a$1.status=ce.shouldFail===false?"skipped":"failed",a$1.reason=ce.reason??`stage "${e$1.stage}" unsupported for project`,a$1.durationMs=Date.now()-j,a$1.exitCode=a$1.status==="failed"?127:null,a$1.status==="failed"&&(a$1.errorCategory="setup",a$1.errorMessage=a$1.reason),O+=1;return}if(e$1.reusePassed&&n){let x=n.stages[e$1.stage]??n.stages[e$1.stage];if(x&&tt(x,b,t)){a$1.status="passed",a$1.reason="reused passed result from workspace-run-last.json",a$1.durationMs=Date.now()-j,a$1.exitCode=0,O+=1,e$1.json||console.log(T.gray(`\u21BA reused passed cache for ${N}`));return}}let we=Nt(ie,ue).filter(x=>x!==e$1.stage);if(we.length>0&&n){let x=we.find(F=>{let C=n.stages[F];return !C||!tt(C,b,t)});if(x){a$1.status="skipped",a$1.reason=`dependency stage "${x}" not satisfied in workspace-run-last.json`,a$1.durationMs=Date.now()-j,a$1.exitCode=null,O+=1;return}}let K=await Ze(b,e$1.stage,ie,ue,st,at,it);if(a$1.executionCommand=K.command,a$1.errorCategory=K.errorCategory,a$1.healthStatus=K.healthStatus,a$1.failureDiagnostic=K.failureDiagnostic,a$1.durationMs=Date.now()-j,a$1.exitCode=K.exitCode,K.exitCode===0?(a$1.status="passed",a$1.reason=void 0):(a$1.status="failed",a$1.reason=K.message||"stage command failed",a$1.errorMessage=K.message),O+=1,!e$1.json){let x=E>0?Math.round(O/E*100):100,F=a$1.status==="passed"?T.green("\u2705"):T.red("\u274C");if(console.log(T.gray(`${F} [${O}/${E}] (${x}%) ${N} ${a$1.durationMs}ms`)),a$1.status==="failed"){a$1.reason&&console.log(T.red(` Reason: ${a$1.reason}`)),a$1.executionCommand&&console.log(T.gray(` Command: ${a$1.executionCommand}`));let C=Wt(a$1.runtimeDetected);C&&a$1.errorCategory==="setup"&&console.log(T.gray(` Hint: ${C}`));}}};if(L&&P.length>1){let b=0,a=false,N=new Array(R).fill(null).map(async()=>{for(;b<P.length;){if(a&&!$)return;let j=b;b+=1;let W=P[j];await p(W),M.get(W)?.status==="failed"&&(a=true);}});if(await Promise.all(N),!$&&a){let j=false;for(let W of P){let D=M.get(W);if(D){if(D.status==="failed"){j=true;continue}j&&D.status==="skipped"&&(D.reason=D.reason||"stopped after failure");}}}}else for(let b of P){await p(b);let a=M.get(b);if(!$&&a?.status==="failed"){let N=P.slice(P.indexOf(b)+1);for(let j of N){let W=M.get(j);W&&(W.status="skipped",W.reason="stopped after failure");}break}}}let v=[];for(let p of o){let b=M.get(p);b&&v.push(b);}let A=v.filter(p=>p.status==="passed").length,G=v.filter(p=>p.status==="failed").length,q=v.filter(p=>p.status==="skipped").length;c({blockId:"workspace.run.execute",status:G>0?"failed":y?"blocked":"succeeded",message:`Workspace run finished: ${A} passed, ${G} failed, ${q} skipped`,component:"workspace-run",progress:{completed:E,total:E,percent:100},attributes:{passed:A,failed:G,skipped:q,stage:e$1.stage}});let ke=e$1.strict===true,nt=G>0||ke&&g.some(p=>p.status==="fail"||p.status==="warn")?1:0,be={schemaVersion:"1.0",workspacePath:t,stage:e$1.stage,generatedAt:new Date().toISOString(),durationMs:Date.now()-r,options:{affected:c$1,blastRadius:m,since:c$1?f:null,parallel:L,maxWorkers:R,continueOnError:$,strict:ke,enforceGates:S,scope:u,reusePassed:e$1.reusePassed===true,planOnly:e$1.planOnly===true,runtime:e$1.runtime?.trim()||null},selection:{mode:k,since:c$1?f:null,scope:u,graphStatus:l,expansionDepth:h},gates:{enforced:S,results:g,blocked:!!y,blockingGate:y?.gate},summary:{projectCount:o.length,selectedCount:P.length,passed:A,failed:G,skipped:q,exitCode:nt},projects:v,enterpriseControls:{jsonReady:true,evidencePath:b}},ot=w.join(t,b);c({blockId:"workspace.run.publish",status:"running",message:"Publishing workspace run evidence",component:"workspace.run"});try{await e(t,be),c({blockId:"workspace.run.publish",status:"succeeded",message:"Workspace run evidence published",component:"workspace.run"}),d$1({workspacePath:t,relativePath:b,blockId:"workspace.run.publish"});}catch(p){throw c({blockId:"workspace.run.publish",status:"failed",message:p instanceof Error?p.message:"Workspace run evidence publish failed",component:"workspace.run"}),p}return e$1.json||(y&&(console.log(T.red(`\u274C Workspace run blocked by ${y.gate}`)),console.log(T.gray(` ${y.summary}`))),console.log(T.cyan(`Workspace run (${e$1.stage}) => passed: ${A}, failed: ${G}, skipped: ${q}`)),console.log(T.gray(`Report: ${ot}`))),be}export{br as a};
@@ -1 +0,0 @@
1
- import {d}from'./chunk-GL3KLNIG.js';import {a as a$2}from'./chunk-XSSNM4F5.js';import {c}from'./chunk-ZLCLGIM6.js';import {a as a$1}from'./chunk-ZPOZ6MDX.js';import {q as q$2}from'./chunk-IHKG5C6G.js';import {a as a$3}from'./chunk-GR6442P7.js';import {h,g}from'./chunk-FE5R6EUV.js';import {a}from'./chunk-AFIFZTOY.js';import {p,q as q$1}from'./chunk-ODK4LCEL.js';import {createHash}from'crypto';import u from'path';import v from'fs-extra';var W="workspai.verified-goal.v1",A=q$1.verifiedGoalStatus,V=p.verifiedGoalStatus,J="contracts/workspace-intelligence/verified-goal.v1.json",$="contracts/workspace-intelligence/verified-goal-status.v1.json";function H(e,t,a){if(t.kind==="workspace")return true;let r=u.resolve(e,a.path);return t.kind==="project"?a.name===t.projectName||r===u.resolve(t.projectPath):t.projects.some(i=>i.projectName===a.name||u.resolve(i.projectPath)===r)}function x(e){return Array.isArray(e)?`[${e.map(x).join(",")}]`:e&&typeof e=="object"?`{${Object.entries(e).sort(([t],[a])=>t.localeCompare(a)).map(([t,a])=>`${JSON.stringify(t)}:${x(a)}`).join(",")}}`:JSON.stringify(e)}function K(e){return createHash("sha256").update(x(e)).digest("hex")}var ae=["package.json","package-lock.json","npm-shrinkwrap.json","pnpm-lock.yaml","yarn.lock","bun.lock","bun.lockb","pyproject.toml","requirements.txt","Pipfile","Pipfile.lock","poetry.lock","uv.lock","go.mod","go.sum","Cargo.toml","Cargo.lock","pom.xml","build.gradle","build.gradle.kts","gradle.lockfile","packages.lock.json","Directory.Packages.props","composer.json","composer.lock","Gemfile","Gemfile.lock","mix.exs","mix.lock","deps.edn","project.clj","build.sbt"],re=new Set(ae.map(e=>e.toLowerCase())),se=new Set([".git",".hg",".svn",".workspai",".venv","venv",".tox",".mypy_cache",".pytest_cache","__pycache__","node_modules","vendor","pods","dist","build","out","target","bin","obj","coverage",".coverage",".next",".nuxt",".svelte-kit"]),F=1e5;function ne(e){return re.has(e.toLowerCase())||/\.(?:csproj|fsproj|vbproj)$/i.test(e)}async function ie(e){let t=[e],a=[],r=0;for(;t.length>0;){let i=t.shift();if(i===void 0)break;let o=await v.readdir(i,{withFileTypes:true});if(o.sort((n,s)=>n.name.localeCompare(s.name)),r+=o.length,r>F)throw new Error(`Dependency safety baseline exceeded ${F} filesystem entries under ${e}. Narrow the project boundary before creating this goal.`);for(let n of o){let s=u.join(i,n.name);if(n.isDirectory()){!se.has(n.name.toLowerCase())&&!a$3(n.name)&&t.push(s);continue}n.isFile()&&ne(n.name)&&a.push(s);}}return a}function oe(e){return /^(?:package\.json|package-lock\.json|npm-shrinkwrap\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?)$/i.test(e)?"node":/^(?:pyproject\.toml|requirements\.txt|Pipfile(?:\.lock)?|poetry\.lock|uv\.lock)$/i.test(e)?"python":/^go\.(?:mod|sum)$/i.test(e)?"go":/^Cargo\.(?:toml|lock)$/i.test(e)?"rust":/^(?:pom\.xml|build\.gradle(?:\.kts)?|gradle\.lockfile)$/i.test(e)?"jvm":/^(?:Directory\.Packages\.props|packages\.lock\.json)$/i.test(e)?"dotnet":/^composer\.(?:json|lock)$/i.test(e)?"php":/^Gemfile(?:\.lock)?$/i.test(e)?"ruby":/^mix\.(?:exs|lock)$/i.test(e)?"elixir":/^(?:deps\.edn|project\.clj)$/i.test(e)?"clojure":/^build\.sbt$/i.test(e)?"scala":/\.(?:csproj|fsproj|vbproj)$/i.test(e)?"dotnet":"unknown"}function z(e){try{let t=JSON.parse(e),a={};for(let r of ["dependencies","devDependencies","peerDependencies","optionalDependencies"]){let i=t[r];if(!(!i||typeof i!="object"||Array.isArray(i)))for(let[o,n]of Object.entries(i))typeof n=="string"&&(a[`${r}:${o}`]=n);}return a}catch{return}}async function U(e,t){let r=(await q$2({workspacePath:e,includeAbsolutePaths:true})).projects.filter(o=>H(e,t,o)),i=new Map;for(let o of r){let n=u.resolve(e,o.path),s=await ie(n);for(let c of s){let g=u.basename(c),f=await v.readFile(c,"utf8"),p=u.relative(e,c).split(u.sep).join("/");i.set(p,{path:p,ecosystem:oe(g),sha256:createHash("sha256").update(f).digest("hex"),...g==="package.json"?{dependencies:z(f)??{}}:{}});}}return {manifests:[...i.values()].sort((o,n)=>o.path.localeCompare(n.path))}}function O(e){let a=e.replace(/^(?:workspace:|npm:[^@]+@)/,"").match(/(?:^|[^\d])(\d+)(?:\.\d+)?(?:\.\d+)?/);return a?Number(a[1]):null}function S(e){return /(?:^|\/)(?:package-lock\.json|npm-shrinkwrap\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?|poetry\.lock|uv\.lock|Pipfile\.lock|go\.sum|Cargo\.lock|gradle\.lockfile|packages\.lock\.json|composer\.lock|Gemfile\.lock|mix\.lock)$/i.test(e)}async function ce(e){let t=e.dependencySafetyBaseline;if(!t)return k({id:"change-policy",label:"Change safety policy",status:"missing",expected:"dependency manifest safety baseline",actual:"baseline unavailable"});let a=[],r=await U(e.workspace.path,e.scope),i=new Map(r.manifests.map(s=>[s.path,s])),o=new Map(t.manifests.map(s=>[s.path,s])),n=new Set;for(let s of t.manifests){let c=i.get(s.path);(!c||c.sha256!==s.sha256)&&n.add(s.path);}for(let s of r.manifests)o.has(s.path)||n.add(s.path);for(let s of r.manifests)!o.has(s.path)&&!S(s.path)&&a.push(`${s.path} was added after the safety baseline`);for(let s of t.manifests){let c=i.get(s.path);if(!c){a.push(`${s.path} was removed`);continue}if(c.sha256===s.sha256)continue;if(s.dependencies){let p=await v.readFile(u.join(e.workspace.path,s.path),"utf8"),m=z(p);if(!m){a.push(`${s.path} is not valid dependency JSON`);continue}for(let[d,l]of Object.entries(s.dependencies)){let h=m[d];if(!h){a.push(`${d.replace(/^[^:]+:/,"")} was removed`);continue}if(h===l)continue;let G=O(l),R=O(h);(G===null||R===null||G!==R||/(?:latest|\*)/i.test(h))&&a.push(`${d.replace(/^[^:]+:/,"")} changed outside its proven major range (${l} \u2192 ${h})`);}continue}if(S(s.path))continue;let g=u.posix.dirname(s.path);[...i.values()].some(p=>{let m=u.posix.dirname(p.path);return p.ecosystem===s.ecosystem&&(m===g||g.startsWith(`${m}/`))&&S(p.path)&&n.has(p.path)})||a.push(`${s.path} changed without a matching reconciled ${s.ecosystem} lockfile`);}return k({id:"change-policy",label:"Change safety policy",status:a.length===0?"passed":"blocked",expected:"no force, removal, unbounded, or major dependency changes",actual:a.length===0?"manifest changes are within proven bounds":a.join("; ")})}function E(e,t){if(!/^[a-z0-9][a-z0-9._-]{7,95}$/i.test(t))throw new Error(`Invalid verified goal id: ${t}`);let a=u.join(e,".workspai","goals",t);return {directory:a,goal:u.join(a,"goal.json"),status:u.join(a,"status.json"),latestReport:u.join(e,V)}}function le(e){return {workspacePath:u.resolve(e.workspace.path),kind:e.kind,scope:e.scope,target:e.criteria.kind==="test-coverage"?e.criteria.minimumPercent:null,...e.criteria.kind==="test-coverage"&&e.criteria.runtime?{runtime:e.criteria.runtime}:{},constraints:e.constraints}}async function C(e,t){await v.ensureDir(u.dirname(e));let a=`${e}.${process.pid}.${Date.now()}.tmp`;await v.writeJson(a,t,{spaces:2}),await v.rename(a,e);}async function ue(e,t){let a=t?.trim();if(!a||a==="workspace")return {scope:{kind:"workspace"}};let r=a.startsWith("projects:")?"projects:":a.startsWith("project:")&&a.slice(8).includes(",")?"project:":null,i=a.startsWith("project:")?a.slice(8).trim():r?a.slice(r.length).trim():a;if(!i)throw new Error("Project goal scope must name a project.");let o=await q$2({workspacePath:e,includeAbsolutePaths:true});if(r){let g=i.split(",").map(p=>p.trim()).filter(Boolean);if(g.length<2||new Set(g).size!==g.length)throw new Error("A project-set goal scope must name at least two unique projects.");return {scope:{kind:"project-set",projects:g.map(p=>{let m=o.projects.filter(d=>d.name===p||d.path===p);if(m.length!==1)throw new Error(m.length===0?`Project goal scope was not found: ${p}`:`Project goal scope is ambiguous: ${p}`);return m[0]}).map(p=>({projectName:p.name,projectPath:u.resolve(e,p.path)})).sort((p,m)=>p.projectName.localeCompare(m.projectName))}}}let n=o.projects.filter(g=>{let f=u.resolve(e,g.path);return g.name===i||g.path===i||f===u.resolve(i)});if(n.length!==1)throw new Error(n.length===0?`Project goal scope was not found: ${i}`:`Project goal scope is ambiguous: ${i}`);let s=n[0],c=u.resolve(e,s.path);return {project:s,scope:{kind:"project",projectName:s.name,projectPath:c}}}function Y(e,t,a){return e===null?"unavailable":a==="minimum"?e>=t?"satisfied":"unsatisfied":e<=t?"satisfied":"unsatisfied"}async function X(e){if(!e)return null;try{let t=await v.readJson(e);return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}function de(e){return Array.isArray(e.projects)?e.projects.filter(t=>!!t&&typeof t=="object"&&!Array.isArray(t)):e.project&&typeof e.project=="object"&&!Array.isArray(e.project)?[e.project]:[]}function pe(e){let t=e.dependencyAudit;return t&&typeof t=="object"&&!Array.isArray(t)?t:null}async function Q(e,t){let a=await g(e,p.doctor),r=await X(a);if(!r)return {measuredAt:new Date().toISOString(),value:null,target:0,unit:"blocking-vulnerabilities",status:"unavailable",evidencePaths:[],message:"Fresh Doctor dependency evidence is not available."};let i=de(r).filter(c=>{if(t.kind==="workspace")return true;let g=typeof c.name=="string"?c.name:typeof c.projectName=="string"?c.projectName:"",f=typeof c.path=="string"?u.resolve(c.path):typeof c.projectPath=="string"?u.resolve(c.projectPath):"";return t.kind==="project"?g===t.projectName||f===u.resolve(t.projectPath):t.projects.some(p=>p.projectName===g||u.resolve(p.projectPath)===f)}),o=i.map(pe).filter(c=>c!==null),n=o.map(c=>c.blockingFindingCount).filter(c=>Number.isInteger(c)&&Number(c)>=0),s=i.length>0&&n.length===i.length?n.reduce((c,g)=>c+g,0):null;return {measuredAt:(()=>{let c=o.map(g=>g.generatedAt).filter(g=>typeof g=="string").sort();return c[c.length-1]??new Date().toISOString()})(),value:s,target:0,unit:"blocking-vulnerabilities",status:Y(s,0,"maximum"),evidencePaths:a?[a]:[],message:s===null?"Doctor did not publish complete dependency audit counts for the selected scope.":`${s} blocking dependency vulnerability finding(s) remain.`}}async function Z(e){let t=await a$1({startPath:e,writeReport:false}),a=t.gates.filter(i=>i.status==="pass").length,r=t.gates.length;return {measuredAt:t.generatedAt,value:a,target:r,unit:"gates",status:t.overallStatus==="pass"?"satisfied":"unsatisfied",evidencePaths:[...new Set(t.gates.map(i=>i.evidencePath).filter(i=>typeof i=="string"))],message:t.overallStatus==="pass"?"All release readiness gates pass.":`${r-a} release readiness gate(s) still require work.`}}async function B(e){let t=await d({projectPath:e.projectPath,target:e.target,run:e.run,runtime:e.runtime}),r=t.metrics[t.target.metric]?.percent??null;return {executionStatus:t.status,measurement:{measuredAt:t.generatedAt,value:r,target:e.target,unit:"percent",status:Y(r,e.target,"minimum"),evidencePaths:[t.artifactPaths.project],message:t.status==="failed"?"The runtime-native coverage test command failed.":r===null?"Machine-readable coverage evidence is unavailable.":`${t.target.metric} coverage is ${r}% (target ${e.target}%).`}}}async function ee(e){if(e.scope.kind==="project"){if(!e.scope.projectPath)throw new Error("Coverage goal project scope does not have a project path.");return B({projectPath:e.scope.projectPath,target:e.target,run:e.run,runtime:e.runtime})}let t=await q$2({workspacePath:e.workspacePath,includeAbsolutePaths:true});if(t.projects.length===0)return {executionStatus:"unavailable",measurement:{measuredAt:new Date().toISOString(),value:null,target:e.target,unit:"percent",status:"unavailable",evidencePaths:[],message:"The workspace does not contain a registered project to measure."}};let a=t.projects.filter(l=>H(e.workspacePath,e.scope,l)),r=e.runtime,i=r?a.filter(l=>l.runtimeCandidates.includes(r)):a;if(i.length===0)return {executionStatus:"unavailable",measurement:{measuredAt:new Date().toISOString(),value:null,target:e.target,unit:"percent",status:"unavailable",evidencePaths:[],message:`The selected scope does not contain the ${e.runtime} coverage runtime.`}};let o=[];for(let l of i)o.push({projectName:l.name,result:await B({projectPath:u.resolve(e.workspacePath,l.path),target:e.target,run:e.run,runtime:e.runtime})});let n=o.filter(l=>l.result.executionStatus==="failed"),s=o.filter(l=>l.result.measurement.status==="unavailable"),c=o.filter(l=>l.result.measurement.status==="unsatisfied"),g=o.map(l=>l.result.measurement.value).filter(l=>l!==null),f=g.length===o.length&&g.length>0?Math.min(...g):null,p=n.length>0?"failed":s.length>0?"unavailable":c.length>0?"below-target":"passed",m=o.map(l=>l.result.measurement.measuredAt).sort(),d=[...n.map(l=>`${l.projectName}: coverage command failed`),...s.map(l=>`${l.projectName}: coverage unavailable`),...c.map(l=>`${l.projectName}: ${l.result.measurement.value??"unknown"}%`)];return {executionStatus:p,measurement:{measuredAt:m[m.length-1]??new Date().toISOString(),value:f,target:e.target,unit:"percent",status:p==="passed"?"satisfied":p==="below-target"?"unsatisfied":"unavailable",evidencePaths:[...new Set(o.flatMap(l=>l.result.measurement.evidencePaths))],message:p==="passed"?`Every registered project has at least ${e.target}% test coverage.`:`Workspace coverage is not verified: ${d.join("; ")}.`}}}function ge(e){let t=e.scope.kind==="project"?`project ${e.scope.projectName??"selected project"}`:e.scope.kind==="project-set"?`projects ${e.scope.projects.map(a=>a.projectName).join(", ")}`:"workspace";return e.kind==="release-readiness"?`Prepare the ${t} for release.`:e.kind==="dependency-security"?`Resolve blocking dependency vulnerabilities in the ${t} without unsafe changes.`:`Raise ${e.runtime?`${e.runtime} `:""}${t} test coverage to ${e.target??80}% without breaking its build.`}function me(e,t,a){return e==="release-readiness"?{kind:e,readiness:"pass",workspaceVerify:"ready"}:e==="dependency-security"?{kind:e,maximumBlockingVulnerabilities:0,requireFreshAudit:true}:{kind:e,metric:"auto",minimumPercent:t,...a?{runtime:a}:{}}}async function fe(e){return e.kind==="release-readiness"?Z(e.workspacePath):e.kind==="dependency-security"?Q(e.workspacePath,e.scope):(await ee({workspacePath:e.workspacePath,scope:e.scope,target:e.target,run:false,runtime:e.runtime})).measurement}async function Ee(e){let t=u.resolve(e.workspacePath),a$1=Math.max(0,Math.min(100,Math.round(e.target??80))),{scope:r}=await ue(t,e.scope),i={workspacePath:u.resolve(t),kind:e.kind,scope:r,target:e.kind==="test-coverage"?a$1:null,...e.kind==="test-coverage"&&e.runtime?{runtime:e.runtime}:{},constraints:{allowBreakingChanges:e.allowBreakingChanges===true,allowForce:e.allowForce===true,requireBuild:e.requireBuild!==false,requireTests:e.requireTests!==false}},o=K(i),n=`goal-${e.kind}-${o.slice(0,16)}`,s=E(t,n);if(await v.pathExists(s.goal)){let{goal:m,status:d}=await te(t,n);if(m.fingerprint===o)return {goal:m,status:d,resumed:d.state!=="verified"}}let c=new Date().toISOString(),g=await fe({workspacePath:t,kind:e.kind,scope:r,target:a$1,runtime:e.runtime}),f={schemaVersion:W,id:n,fingerprint:o,createdAt:c,updatedAt:c,workspace:{name:u.basename(t),path:t},scope:r,kind:e.kind,summary:ge({kind:e.kind,scope:r,target:a$1,runtime:e.runtime}),constraints:i.constraints,criteria:me(e.kind,a$1,e.runtime),baseline:g,...e.kind==="dependency-security"?{dependencySafetyBaseline:await U(t,r)}:{},artifactPaths:{goal:s.goal,status:s.status,latestReport:s.latestReport}},p={schemaVersion:A,goalId:n,goalFingerprint:o,workspacePath:t,updatedAt:c,state:"planned",attempt:0,progress:g,checks:[],blockingReasons:[],evidencePaths:g.evidencePaths,nextActions:e.kind==="test-coverage"?["Add focused tests for the lowest-coverage source paths.","Run verified goal checks."]:e.kind==="dependency-security"?["Inspect the fresh project dependency audit.","Apply only compatible non-force dependency repairs.","Reconcile the lockfile, test, build, and verify again."]:["Inspect the current remediation plan and failing release gates.","Repair the next causal blocker, then verify again."],artifactPath:s.status};return a(f,J,"Verified goal"),a(p,$,"Verified goal status"),await C(s.goal,f),await C(s.status,p),await h(t,V,p),{goal:f,status:p,resumed:false}}async function te(e,t){let a$1=E(u.resolve(e),t),r=await v.readJson(a$1.goal),i=await v.readJson(a$1.status);a(r,J,"Verified goal"),a(i,$,"Verified goal status");let o=u.resolve(e),n=u.resolve(r.artifactPaths.goal)===u.resolve(a$1.goal)&&u.resolve(r.artifactPaths.status)===u.resolve(a$1.status)&&u.resolve(r.artifactPaths.latestReport)===u.resolve(a$1.latestReport);if(r.schemaVersion!==W||i.schemaVersion!==A||r.id!==i.goalId||r.fingerprint!==i.goalFingerprint||r.fingerprint!==K(le(r))||u.resolve(r.workspace.path)!==o||u.resolve(i.workspacePath)!==o||!n)throw new Error(`Verified goal artifacts are inconsistent: ${t}`);return {goal:r,status:i}}function k(e){return {...e,message:e.message??`${e.label}: ${e.actual}; expected ${e.expected}.`}}async function q(e){let t=[],a=e.goal.scope.kind==="project"?[`project:${e.goal.scope.projectName}`]:e.goal.scope.kind==="project-set"?e.goal.scope.projects.map(r=>`project:${r.projectName}`):[void 0];for(let r of ["test","build"]){if(r==="test"&&e.includeTests===false)continue;if(!(r==="test"?e.goal.constraints.requireTests:e.goal.constraints.requireBuild)){t.push(k({id:r,label:`${r} validation`,status:"skipped",expected:"not required",actual:"skipped by goal contract"}));continue}if(!e.run){t.push(k({id:r,label:`${r} validation`,status:"missing",expected:"fresh passed evidence",actual:"execution disabled"}));continue}let o=false;for(let n of a){let s=await a$2({workspacePath:e.goal.workspace.path,stage:r,scope:n,parallel:false,continueOnError:false,strict:true,json:true,enforceGates:false}),c=n?.replace(/^project:/,"");if(t.push(k({id:c?`${r}:${c}`:r,label:c?`${r} validation \xB7 ${c}`:`${r} validation`,status:s.summary.exitCode===0?"passed":"failed",expected:"exit 0",actual:`exit ${s.summary.exitCode}`,evidencePath:u.join(e.goal.workspace.path,".workspai","reports","workspace-run-last.json")})),s.summary.exitCode!==0){o=true;break}}if(o)break}return t}async function Ge(e){let t=u.resolve(e.workspacePath),{goal:a$1,status:r}=await te(t,e.goalId),i=e.run!==false,o=[],n;if(i&&e.runIntelligence!==false){let d=await c({workspacePath:t,strict:true,agent:"generic"}),l=d.exitCode===0||d.exitCode===2,h=a$1.kind==="release-readiness";o.push(k({id:"workspace-intelligence-chain",label:"Workspace Intelligence chain",status:d.exitCode===0||d.exitCode===2&&!h?"passed":d.exitCode===2?"blocked":"failed",expected:"passed",actual:d.exitCode===2&&l&&!h?`${d.status}; canonical evidence refreshed for goal-scoped verification`:d.status,evidencePath:u.join(t,p.intelligenceRun)}));}if(a$1.kind==="release-readiness"){n=await Z(t),o.push(k({id:"release-readiness",label:"Release readiness",status:n.status==="satisfied"?"passed":"blocked",expected:"all gates pass",actual:n.message,evidencePath:u.join(t,p.readiness)}));let d=await g(t,p.verify),l=await X(d),h=l?.summary&&typeof l.summary=="object"&&!Array.isArray(l.summary)?String(l.summary.verdict??"missing"):"missing";o.push(k({id:"workspace-verify",label:"Workspace verification",status:h==="ready"?"passed":h==="missing"?"missing":"blocked",expected:"ready",actual:h,evidencePath:u.join(t,p.verify)}));}else if(a$1.kind==="dependency-security")n=await Q(t,a$1.scope),o.push(k({id:"dependency-audit",label:"Dependency security audit",status:n.status==="satisfied"?"passed":n.status==="unavailable"?"missing":"blocked",expected:"0 blocking vulnerabilities",actual:n.message,evidencePath:n.evidencePaths[0]})),o.push(a$1.constraints.allowBreakingChanges||a$1.constraints.allowForce?k({id:"change-policy",label:"Change safety policy",status:"blocked",expected:"breaking and force changes disabled",actual:`allowBreakingChanges=${a$1.constraints.allowBreakingChanges}, allowForce=${a$1.constraints.allowForce}`}):await ce(a$1)),n.status==="satisfied"&&o.push(...await q({goal:a$1,run:i}));else {let d=a$1.criteria.kind==="test-coverage"?a$1.criteria.minimumPercent:a$1.baseline.target;if(d===null)throw new Error("Coverage goal does not have a valid target.");let l=await ee({workspacePath:t,scope:a$1.scope,target:d,run:i,runtime:a$1.criteria.kind==="test-coverage"?a$1.criteria.runtime:void 0});n=l.measurement,o.push(k({id:"coverage",label:"Test coverage",status:n.status==="satisfied"?"passed":n.status==="unavailable"?"missing":"blocked",expected:`at least ${d}%`,actual:n.message,evidencePath:n.evidencePaths[0]})),o.push(k({id:"test",label:"Coverage test execution",status:l.executionStatus==="failed"?"failed":l.executionStatus==="unavailable"?"missing":"passed",expected:"runtime-native coverage test command completed",actual:l.executionStatus==="failed"?"coverage test command failed":l.executionStatus==="unavailable"?"coverage execution evidence unavailable":"coverage evidence produced by the test runner",evidencePath:n.evidencePaths[0]})),n.status==="satisfied"&&o.push(...await q({goal:a$1,run:i,includeTests:false}));}let s=o.filter(d=>d.status==="blocked"||d.status==="failed"||d.status==="missing").map(d=>d.message),c$1=[...new Set([...n.evidencePaths,...o.map(d=>d.evidencePath).filter(d=>typeof d=="string")])],g$1=n.status==="satisfied"&&o.every(d=>d.status==="passed"||d.status==="skipped"),f=E(t,a$1.id),p$1=g$1?[]:a$1.kind==="test-coverage"?["Inspect low-coverage files from the coverage artifact.","Add focused tests and verify again."]:a$1.kind==="dependency-security"?["Use fresh audit candidates and compatible package-manager repairs.","Reconcile lockfiles before running verified goal checks again."]:["Repair the first blocking readiness gate and verify the goal again."],m={schemaVersion:A,goalId:a$1.id,goalFingerprint:a$1.fingerprint,workspacePath:t,updatedAt:new Date().toISOString(),state:g$1?"verified":o.some(d=>d.status==="failed")?"failed":"blocked",attempt:r.attempt+1,progress:n,checks:o,blockingReasons:s,evidencePaths:c$1,nextActions:p$1,artifactPath:f.status};return a(m,$,"Verified goal status"),await C(f.status,m),await h(t,V,m),m}export{V as VERIFIED_GOAL_LAST_RUN_REPORT_PATH,W as VERIFIED_GOAL_SCHEMA_VERSION,A as VERIFIED_GOAL_STATUS_SCHEMA_VERSION,Ee as planVerifiedGoal,te as readVerifiedGoal,Ge as verifyVerifiedGoal};
@@ -1 +0,0 @@
1
- export{a as readWorkspaceKnowledgeGraphSnapshot}from'./chunk-QNHKUSBH.js';
@@ -1 +0,0 @@
1
- export{a as runWorkspaceStage}from'./chunk-XSSNM4F5.js';export{a as WORKSPACE_RUN_LAST_REPORT_FILENAME}from'./chunk-37SWTS2B.js';