workspai 0.73.0 → 0.75.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 (163) hide show
  1. package/contracts/agent-framework-capabilities.v1.json +454 -0
  2. package/contracts/cli-runtime-command-inventory.v1.snapshot.json +166 -0
  3. package/contracts/create-planner-capabilities.v1.json +24 -0
  4. package/contracts/extension-cli-compatibility.v1.json +6 -0
  5. package/contracts/published-contract-catalog.v1.json +30 -0
  6. package/contracts/runtime-command-surface.v1.json +78 -4
  7. package/contracts/workspace-intelligence/agent-framework-adapter-manifest.v1.json +2127 -0
  8. package/contracts/workspace-intelligence/agent-framework-admission-candidate.v1.json +193 -0
  9. package/contracts/workspace-intelligence/agent-framework-change-plan.v1.json +280 -0
  10. package/contracts/workspace-intelligence/agent-framework-conformance-report.v1.json +269 -0
  11. package/contracts/workspace-intelligence/agent-framework-ownership-receipt.v1.json +147 -0
  12. package/contracts/workspace-intelligence/workspace-model.v1.json +4 -0
  13. package/contracts/workspace-intelligence-architecture.v1.json +28 -2
  14. package/dist/analyze-FRQVJ3VJ.js +1 -0
  15. package/dist/{artifact-remediation-plan-WDK5ISRU.js → artifact-remediation-plan-HD5K52UJ.js} +1 -1
  16. package/dist/autopilot-release-D3UES53H.js +1 -0
  17. package/dist/capabilities-command-VK3LQLP2.js +1 -0
  18. package/dist/chunk-252EKOR6.js +2 -0
  19. package/dist/chunk-36VNERGC.js +1 -0
  20. package/dist/{chunk-TZK2R6RD.js → chunk-4DX4HBG3.js} +1 -1
  21. package/dist/chunk-4KEZQLBU.js +2 -0
  22. package/dist/{chunk-PKKSRXUS.js → chunk-6B7L4NZE.js} +1 -1
  23. package/dist/chunk-7NKM6EHE.js +7 -0
  24. package/dist/{chunk-FE5R6EUV.js → chunk-BLEIUQL6.js} +1 -1
  25. package/dist/{chunk-37SWTS2B.js → chunk-BR6QIYQS.js} +1 -1
  26. package/dist/chunk-CGNMS32W.js +97 -0
  27. package/dist/{chunk-3GO7BJ5J.js → chunk-CK73SQFF.js} +1 -1
  28. package/dist/chunk-CMLLERGG.js +418 -0
  29. package/dist/{chunk-MGL6DBOR.js → chunk-COOVCORC.js} +1 -1
  30. package/dist/chunk-D4AMCZJU.js +7 -0
  31. package/dist/chunk-DFREJHG7.js +1 -0
  32. package/dist/{chunk-OIGI7MP6.js → chunk-DJH2CH42.js} +1 -1
  33. package/dist/chunk-DT3LRKZQ.js +1 -0
  34. package/dist/{chunk-D3N2WFDV.js → chunk-FS3WLRQ4.js} +1 -1
  35. package/dist/chunk-G3ZC5W4U.js +1 -0
  36. package/dist/{chunk-TIZCESKY.js → chunk-GE46XKD2.js} +1 -1
  37. package/dist/chunk-GIFAGOMK.js +2 -0
  38. package/dist/{chunk-FRH7AIGY.js → chunk-HLSOZOL3.js} +3 -3
  39. package/dist/chunk-J4J3RYCL.js +4 -0
  40. package/dist/{chunk-JK6XEF7K.js → chunk-JKAAKE4Z.js} +1 -1
  41. package/dist/chunk-LMOTDLJF.js +2 -0
  42. package/dist/{chunk-DNKELRK6.js → chunk-MXI2DWLL.js} +1 -1
  43. package/dist/chunk-NFWUAEVQ.js +12 -0
  44. package/dist/chunk-NGU7RYXA.js +9 -0
  45. package/dist/{chunk-3WHE7V4M.js → chunk-NLRZFIC6.js} +1 -1
  46. package/dist/chunk-O2CFT2A3.js +1 -0
  47. package/dist/{chunk-EBQS5T7Q.js → chunk-OA2YJN22.js} +1 -1
  48. package/dist/chunk-OH6LV5JP.js +6 -0
  49. package/dist/{chunk-J44PN2FX.js → chunk-P5RZO5BY.js} +18 -18
  50. package/dist/{chunk-TSYDTKXO.js → chunk-RPM67N7A.js} +1 -1
  51. package/dist/{chunk-XVTN5DDV.js → chunk-RU3UT7GJ.js} +1 -1
  52. package/dist/{chunk-IPZT6WKM.js → chunk-RX3U7JKF.js} +4 -4
  53. package/dist/chunk-SRCZX2KC.js +13 -0
  54. package/dist/chunk-TXVMHEJS.js +1 -0
  55. package/dist/chunk-V5WVGPOP.js +1 -0
  56. package/dist/{chunk-FY4X2VOE.js → chunk-VHMDWRDG.js} +2 -2
  57. package/dist/chunk-W7I65IXY.js +3 -0
  58. package/dist/chunk-WOPZX56J.js +2 -0
  59. package/dist/chunk-XF65LQ6M.js +1 -0
  60. package/dist/chunk-YP436V7Q.js +2 -0
  61. package/dist/{chunk-HAZGSAKP.js → chunk-ZI54C2AO.js} +1 -1
  62. package/dist/chunk-ZKYH44ER.js +1 -0
  63. package/dist/chunk-ZS7JHATN.js +1 -0
  64. package/dist/{chunk-NSMRQOWP.js → chunk-ZW4QV6SB.js} +1 -1
  65. package/dist/{create-XYKXS3JB.js → create-7UENFCJK.js} +1 -1
  66. package/dist/{demo-kit-RKTHTXHJ.js → demo-kit-ALW6OSQV.js} +1 -1
  67. package/dist/doctor-KGADT4PI.js +1 -0
  68. package/dist/{dotnet-webapi-clean-VJX6SGGP.js → dotnet-webapi-clean-6Z4EXEJY.js} +1 -1
  69. package/dist/{goal-lifecycle-BIX2JVNO.js → goal-lifecycle-HIQGDEEP.js} +1 -1
  70. package/dist/goal-pack-63PEP2ND.js +1 -0
  71. package/dist/{gofiber-standard-I6ASLOEE.js → gofiber-standard-TDJQIVQZ.js} +1 -1
  72. package/dist/{gogin-standard-U2LSRLIP.js → gogin-standard-UEF3IHSJ.js} +1 -1
  73. package/dist/index.d.ts +18 -0
  74. package/dist/index.js +266 -248
  75. package/dist/pipeline-VFI35PR4.js +5 -0
  76. package/dist/{project-agent-entry-Y3NEHZED.js → project-agent-entry-Z3OY3S7T.js} +1 -1
  77. package/dist/{project-intelligence-lens-6Q6XSUDJ.js → project-intelligence-lens-YWICXW6P.js} +1 -1
  78. package/dist/{project-test-coverage-5PXAHBYQ.js → project-test-coverage-3P5FH6E5.js} +1 -1
  79. package/dist/proof-carrying-change-BAP2C3KV.js +1 -0
  80. package/dist/{pythonRapidkitExec-44ORGQ4R.js → pythonRapidkitExec-UMFLDIYR.js} +1 -1
  81. package/dist/{rust-axum-JMV7UPO7.js → rust-axum-4TRVPFMB.js} +1 -1
  82. package/dist/{springboot-standard-OC2RS3KC.js → springboot-standard-COWL75GT.js} +1 -1
  83. package/dist/verified-goal-A6WOMNTU.js +1 -0
  84. package/dist/{workspace-ROUEA3RT.js → workspace-PAXTJCMH.js} +1 -1
  85. package/dist/{workspace-agent-sync-6UYG33EQ.js → workspace-agent-sync-MGCEF4ON.js} +1 -1
  86. package/dist/{workspace-archive-OSMU3CK6.js → workspace-archive-3AURTMYA.js} +1 -1
  87. package/dist/{workspace-context-H7ZXR6VI.js → workspace-context-2G6QZ6D3.js} +1 -1
  88. package/dist/{workspace-contract-2V2BI6A3.js → workspace-contract-VWPOIYHJ.js} +1 -1
  89. package/dist/{workspace-explain-IBMTRUSF.js → workspace-explain-HLEBUK4K.js} +1 -1
  90. package/dist/{workspace-feedback-D6HJLKBQ.js → workspace-feedback-FF34CSJE.js} +1 -1
  91. package/dist/{workspace-foundation-H5B3TTZD.js → workspace-foundation-X7LOGTS3.js} +1 -1
  92. package/dist/{workspace-graph-stream-YDEET5LK.js → workspace-graph-stream-XGSRDRLI.js} +1 -1
  93. package/dist/workspace-graph-token-efficiency-YHXFGH3Z.js +1 -0
  94. package/dist/{workspace-history-WWPS4U7H.js → workspace-history-EQG5UBKW.js} +1 -1
  95. package/dist/{workspace-intelligence-DXKQXTTM.js → workspace-intelligence-GFJKIWBX.js} +1 -1
  96. package/dist/{workspace-intelligence-benchmark-L46EGZZM.js → workspace-intelligence-benchmark-R5MEGJQS.js} +1 -1
  97. package/dist/{workspace-intelligence-evaluation-QDSOOUHH.js → workspace-intelligence-evaluation-4AB4BBRP.js} +1 -1
  98. package/dist/{workspace-intelligence-runner-SCB44IXU.js → workspace-intelligence-runner-BU6JKNUD.js} +1 -1
  99. package/dist/{workspace-knowledge-graph-BNEVFEOW.js → workspace-knowledge-graph-OUTCLYS2.js} +1 -1
  100. package/dist/{workspace-knowledge-graph-query-GOC365ZR.js → workspace-knowledge-graph-query-TT2KK3SF.js} +1 -1
  101. package/dist/workspace-knowledge-graph-snapshot-XWJRUMAC.js +1 -0
  102. package/dist/workspace-marker-7U3NYRPJ.js +1 -0
  103. package/dist/workspace-mcp-serve-JYUKX3YS.js +3 -0
  104. package/dist/workspace-model-DUGPW5IB.js +1 -0
  105. package/dist/{workspace-onboarding-IRBVZTT4.js → workspace-onboarding-C4CKWTJ3.js} +1 -1
  106. package/dist/{workspace-python-engine-state-BE4A3BL5.js → workspace-python-engine-state-VCOLSEWV.js} +2 -2
  107. package/dist/{workspace-readme-HA6XLDME.js → workspace-readme-4FCKAQME.js} +1 -1
  108. package/dist/{workspace-registry-summary-CBZDSG6I.js → workspace-registry-summary-4KX4QD55.js} +1 -1
  109. package/dist/workspace-repair-engine-OVW4J3DI.js +3 -0
  110. package/dist/workspace-run-NVQGRZYO.js +1 -0
  111. package/dist/{workspace-verify-QTRY7WW3.js → workspace-verify-B7HEFYO6.js} +1 -1
  112. package/dist/workspace-watch-TQYAMLIV.js +1 -0
  113. package/docs/README.md +4 -1
  114. package/docs/agent-framework-adapters.md +279 -0
  115. package/docs/ci-workflows.md +1 -1
  116. package/docs/commands-reference.md +16 -0
  117. package/docs/contracts/COMMAND_OWNERSHIP_MATRIX.md +5 -0
  118. package/docs/creating-workspaces-and-projects.md +18 -4
  119. package/package.json +7 -1
  120. package/scripts/enterprise-package-smoke.mjs +98 -0
  121. package/dist/analyze-WC2TY5AT.js +0 -1
  122. package/dist/autopilot-release-LJDRECFW.js +0 -1
  123. package/dist/capabilities-command-NFGX42CH.js +0 -1
  124. package/dist/chunk-2BCECNIW.js +0 -1
  125. package/dist/chunk-2LIVMG5C.js +0 -2
  126. package/dist/chunk-3SNP6M4M.js +0 -2
  127. package/dist/chunk-46QH3ZVI.js +0 -105
  128. package/dist/chunk-4HQU2GQM.js +0 -1
  129. package/dist/chunk-4JAURS76.js +0 -13
  130. package/dist/chunk-7O7P4MRD.js +0 -1
  131. package/dist/chunk-AQNU5RXV.js +0 -2
  132. package/dist/chunk-CQBM6BBP.js +0 -2
  133. package/dist/chunk-CY4QZ3PE.js +0 -3
  134. package/dist/chunk-EDDGQ6LM.js +0 -2
  135. package/dist/chunk-F6CTGVJA.js +0 -9
  136. package/dist/chunk-K3O3HENC.js +0 -5
  137. package/dist/chunk-LDJAUIAG.js +0 -1
  138. package/dist/chunk-LGC4CRUF.js +0 -3
  139. package/dist/chunk-ND5YAC4T.js +0 -1
  140. package/dist/chunk-NNQE4DS2.js +0 -2
  141. package/dist/chunk-NSH7TTSV.js +0 -1
  142. package/dist/chunk-R5OJD5K2.js +0 -1
  143. package/dist/chunk-SO4CGS35.js +0 -4
  144. package/dist/chunk-T5NBSCVX.js +0 -97
  145. package/dist/chunk-UCNIXOTL.js +0 -2
  146. package/dist/chunk-UNXG3ZFV.js +0 -1
  147. package/dist/chunk-VBMWFT7Q.js +0 -1
  148. package/dist/chunk-YYELANJO.js +0 -7
  149. package/dist/chunk-ZZWGD3X3.js +0 -12
  150. package/dist/doctor-LQ7FT6AZ.js +0 -1
  151. package/dist/goal-pack-SUWH6K7U.js +0 -1
  152. package/dist/pipeline-NSPPWD7U.js +0 -5
  153. package/dist/proof-carrying-change-456TYEDW.js +0 -1
  154. package/dist/verified-goal-GRH5UOJR.js +0 -1
  155. package/dist/workspace-graph-token-efficiency-XM3LYFUC.js +0 -1
  156. package/dist/workspace-knowledge-graph-snapshot-2NMV7LEJ.js +0 -1
  157. package/dist/workspace-marker-XGAWZZDX.js +0 -1
  158. package/dist/workspace-mcp-serve-JLZTTEVG.js +0 -3
  159. package/dist/workspace-model-XSNLDUI2.js +0 -1
  160. package/dist/workspace-repair-engine-TDUNQSFJ.js +0 -3
  161. package/dist/workspace-run-I2W5PIPK.js +0 -1
  162. package/dist/workspace-watch-PDQKYBYQ.js +0 -1
  163. /package/dist/{chunk-K33JJVQZ.js → chunk-VN2MKTQO.js} +0 -0
@@ -81,6 +81,10 @@ npx workspai change abort --change <change-id> --reason <text> [--actor <identit
81
81
  npx workspai change capsule validate --change <change-id> [--workspace <path>] [--json]
82
82
  npx workspai change capsule export --change <change-id> --output <path> [--workspace <path>] [--json]
83
83
  npx workspai agent bootstrap [--project <path>] [--for-agent <host>] [--no-live-inputs] [--strict] [--json]
84
+ npx workspai agent framework list [--json]
85
+ npx workspai agent framework plan --project <name> --runtime <python|dotnet> --name <agent> [--goal <goal-id>] [--workspace <path>] [--json]
86
+ npx workspai agent framework attach --project <name> --runtime <python|dotnet> --name <agent> [-y] [--granted-by <identity>] [--workspace <path>] [--json]
87
+ npx workspai agent framework apply --change <change-id> --project <name> --runtime <python|dotnet> [--workspace <path>] [--json]
84
88
  ```
85
89
 
86
90
  Recommended CI:
@@ -262,6 +266,18 @@ the same receipt and can audit every supported host with `--for-agent all`.
262
266
  Blocked receipts exit `2`; strict mode also maps degraded evidence to exit `2`.
263
267
  See [Canonical-first agent entry](./agent-entry.md).
264
268
 
269
+ `agent framework` is the governed bridge between Workspai evidence and an
270
+ agent runtime. `list` exposes only exact release-admitted baselines. `plan`
271
+ creates or reuses a scoped Goal, begins a Proof-Carrying Change, and attaches a
272
+ hash-bound file plan without writing project files. `attach` shows that plan
273
+ and requires an interactive confirmation or explicit `--yes` before granting
274
+ the filesystem effect and writing an isolated `agents/<name>` directory.
275
+ Dependency installation, credentials, generated-code execution, and model
276
+ provider calls are never implied by that approval. `apply` is the automation
277
+ counterpart for a plan that was separately authorized with `change authorize`.
278
+ Any adapter, version, manifest, runtime, or platform drift invalidates its
279
+ bundled release admission until the complete conformance matrix passes again.
280
+
265
281
  `workspace feedback record` is a non-interactive machine interface. It requires
266
282
  exactly one JSON object on stdin and `--json`; an empty stdin or interactive TTY
267
283
  is rejected. Required fields are `actionId`, `summary`, and `outcome`. The
@@ -78,6 +78,11 @@ These nested Commander commands are implemented and orchestrated by Workspai CLI
78
78
  - `product manifest create`
79
79
  - `product plan`
80
80
  - `agent bootstrap`
81
+ - `agent framework`
82
+ - `agent framework list`
83
+ - `agent framework plan`
84
+ - `agent framework attach`
85
+ - `agent framework apply`
81
86
  - `project agent-entry`
82
87
  - `project commands`
83
88
  - `project coverage`
@@ -307,8 +307,8 @@ npx workspai create
307
307
  If you choose project creation, the same project flow is used.
308
308
 
309
309
  When the terminal is interactive and the current directory is not inside a
310
- workspace, **every supported backend, frontend, desktop, and extension kit** shows the workspace
311
- management question before scaffolding:
310
+ workspace, **every supported backend, frontend, desktop, agent, and extension kit** shows the
311
+ workspace management question before scaffolding:
312
312
 
313
313
  ```text
314
314
  This project is outside a Workspai workspace. How should it be managed?
@@ -338,6 +338,8 @@ npx workspai create project frontend.nextjs dashboard
338
338
  npx workspai create project desktop.tauri desktop-app
339
339
  npx workspai create project desktop.electron admin-console
340
340
  npx workspai create project extension.vscode editor-tools
341
+ npx workspai create project agent.microsoft.python support-agent
342
+ npx workspai create project agent.microsoft.dotnet operations-agent
341
343
  npx workspai create project php.laravel customer-api
342
344
  ```
343
345
 
@@ -384,6 +386,18 @@ Workspai has official-generator paths for:
384
386
  The ecosystem's official generator creates the application. Workspai then adds
385
387
  project metadata and performs the selected workspace registration.
386
388
 
389
+ ## Agent Framework kits
390
+
391
+ | Kit | Runtime | Framework baseline | Behavior |
392
+ | ------------------------ | ------- | ------------------ | ------------------------------------------ |
393
+ | `agent.microsoft.python` | Python | Release-admitted | Goal + PCC + owned isolated agent scaffold |
394
+ | `agent.microsoft.dotnet` | .NET | Release-admitted | Goal + PCC + owned isolated agent scaffold |
395
+
396
+ Agent kits require Workspace governance and therefore do not accept
397
+ `--no-workspace`. They do not install dependencies, call a model, or store
398
+ credentials. Their exact framework versions are promoted only after the full
399
+ Linux, macOS, and Windows conformance matrix passes.
400
+
387
401
  ## Desktop, extension, and additional backend generators
388
402
 
389
403
  | Category | Project | Kit | Creation owner |
@@ -394,8 +408,8 @@ project metadata and performs the selected workspace registration.
394
408
  | Desktop | Electron Forge | `desktop.electron` | create-electron-app |
395
409
  | Extension | VS Code Extension | `extension.vscode` | generator-code |
396
410
 
397
- Every generated project receives a canonical `kind` and `category`. The four
398
- user-facing categories are `backend`, `frontend`, `desktop`, and `extension`;
411
+ Every generated project receives a canonical `kind` and `category`. The five
412
+ user-facing creation categories are `backend`, `frontend`, `desktop`, `agent`, and `extension`;
399
413
  they remain visible in the Workspace Model and Knowledge Graph so consumers do
400
414
  not have to guess a project’s role from its runtime.
401
415
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workspai",
3
- "version": "0.73.0",
3
+ "version": "0.75.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": [
@@ -113,6 +113,12 @@
113
113
  "test:scenarios:docker": "bash scripts/scenario-matrix.sh",
114
114
  "test:runtime-matrix": "node scripts/runtime-acceptance-matrix.mjs",
115
115
  "test:runtime-contract": "node scripts/runtime-acceptance-matrix.mjs --contract-only",
116
+ "test:agent-framework:python": "tsx scripts/smoke-microsoft-agent-framework-adapter.ts --runtime python",
117
+ "test:agent-framework:dotnet": "tsx scripts/smoke-microsoft-agent-framework-adapter.ts --runtime dotnet",
118
+ "verify:agent-framework:matrix": "tsx scripts/verify-agent-framework-conformance.ts --reports test-results/agent-framework-conformance",
119
+ "discover:agent-framework:versions": "tsx scripts/discover-agent-framework-versions.ts",
120
+ "propose:agent-framework:versions": "tsx scripts/propose-agent-framework-version-update.ts",
121
+ "promote:agent-framework:admission": "tsx scripts/promote-agent-framework-release-admission.ts",
116
122
  "prepush:test:runtime-contract": "node scripts/run-cached-prepush-gate.mjs runtime-contract",
117
123
  "test:runtime-matrix:full": "node scripts/runtime-acceptance-matrix.mjs --full",
118
124
  "test:real-world": "node scripts/real-world-qualification.mjs",
@@ -207,6 +207,8 @@ const REQUIRED_PACKAGE_FILES = [
207
207
  'contracts/workspace-intelligence/workspace-repair-transaction.v1.json',
208
208
  'contracts/workspace-intelligence/project-agent-entry.v1.json',
209
209
  'contracts/workspace-intelligence/agent-bootstrap-receipt.v1.json',
210
+ 'contracts/workspace-intelligence/agent-framework-change-plan.v1.json',
211
+ 'contracts/workspace-intelligence/agent-framework-ownership-receipt.v1.json',
210
212
  'contracts/extension-cli-compatibility.v1.json',
211
213
  'data/modules-embeddings.json',
212
214
  'templates/kits/fastapi-standard/README.md.j2',
@@ -345,9 +347,104 @@ function assertCliContracts() {
345
347
  }
346
348
  }
347
349
 
350
+ const frameworks = parseTrailingJson(runCli(['agent', 'framework', 'list', '--json']));
351
+ if (
352
+ frameworks.schemaVersion !== 'workspai.agent-framework-list.v1' ||
353
+ frameworks.adapters?.length !== 2 ||
354
+ frameworks.adapters.some((adapter) => adapter.status !== 'admitted')
355
+ ) {
356
+ fail('published CLI does not expose the two exact release-admitted framework adapters');
357
+ }
358
+
348
359
  log(`verified CLI contract surfaces for v${version.version}`);
349
360
  }
350
361
 
362
+ function smokeCreateAgentFrameworkKits() {
363
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'workspai-agent-kit-smoke-'));
364
+ const workspaceName = 'agent-kit-workspace';
365
+ const workspacePath = path.join(tempDir, workspaceName);
366
+ const createWorkspace = spawnSync(
367
+ process.execPath,
368
+ [
369
+ cliPath,
370
+ 'create',
371
+ 'workspace',
372
+ workspaceName,
373
+ '--output',
374
+ tempDir,
375
+ '--profile',
376
+ 'minimal',
377
+ '--skip-python-engine',
378
+ '--skip-git',
379
+ '--yes',
380
+ ],
381
+ { cwd: tempDir, encoding: 'utf8', env: cliEnv(), stdio: ['ignore', 'pipe', 'pipe'] }
382
+ );
383
+ if (createWorkspace.status !== 0) {
384
+ fail(
385
+ `agent kit workspace creation failed with exit ${createWorkspace.status}\n${createWorkspace.stdout}\n${createWorkspace.stderr}`
386
+ );
387
+ }
388
+
389
+ const scenarios = [
390
+ {
391
+ kit: 'agent.microsoft.python',
392
+ name: 'python-agent',
393
+ expectedFiles: [
394
+ 'README.md',
395
+ '.workspai/project.json',
396
+ '.workspai/agent-frameworks/microsoft-agent-framework-python/primary.json',
397
+ 'agents/primary/main.py',
398
+ 'agents/primary/pyproject.toml',
399
+ 'agents/primary/tests/test_context.py',
400
+ 'agents/primary/.env.example',
401
+ 'agents/primary/README.md',
402
+ ],
403
+ },
404
+ {
405
+ kit: 'agent.microsoft.dotnet',
406
+ name: 'dotnet-agent',
407
+ expectedFiles: [
408
+ 'README.md',
409
+ '.workspai/project.json',
410
+ '.workspai/agent-frameworks/microsoft-agent-framework-dotnet/primary.json',
411
+ 'agents/primary/Program.cs',
412
+ 'agents/primary/WorkspaiContext.cs',
413
+ 'agents/primary/Primary.csproj',
414
+ 'agents/primary/tests/Primary.Tests.csproj',
415
+ 'agents/primary/tests/WorkspaiContextTests.cs',
416
+ 'agents/primary/.env.example',
417
+ 'agents/primary/README.md',
418
+ ],
419
+ },
420
+ ];
421
+ try {
422
+ for (const scenario of scenarios) {
423
+ const result = spawnSync(
424
+ process.execPath,
425
+ [cliPath, 'create', 'project', scenario.kit, scenario.name, '--skip-git', '--yes'],
426
+ {
427
+ cwd: workspacePath,
428
+ encoding: 'utf8',
429
+ env: cliEnv(),
430
+ stdio: ['ignore', 'pipe', 'pipe'],
431
+ }
432
+ );
433
+ if (result.status !== 0) {
434
+ fail(
435
+ `${scenario.kit} governed create failed with exit ${result.status}\n${result.stdout}\n${result.stderr}`
436
+ );
437
+ }
438
+ assertGeneratedProject(path.join(workspacePath, scenario.name), scenario.expectedFiles);
439
+ }
440
+ const ownershipRoot = path.join(workspacePath, '.workspai', 'agent-frameworks', 'ownership');
441
+ if (!fs.existsSync(ownershipRoot)) fail('agent kit smoke did not record ownership receipts');
442
+ } finally {
443
+ fs.rmSync(tempDir, { recursive: true, force: true });
444
+ }
445
+ log(`verified ${scenarios.length} governed agent framework create scenarios`);
446
+ }
447
+
351
448
  function assertGeneratedProject(projectPath, expectedFiles) {
352
449
  for (const relativePath of expectedFiles) {
353
450
  const absolutePath = path.join(projectPath, relativePath);
@@ -532,6 +629,7 @@ for (const relativePath of [
532
629
  assertPackContents();
533
630
  assertCliContracts();
534
631
  smokeCreateNpmBackedKits();
632
+ smokeCreateAgentFrameworkKits();
535
633
  smokeCreateOfflineFallbackKits();
536
634
 
537
635
  log('enterprise package smoke passed');
@@ -1 +0,0 @@
1
- export{b as printAnalyzeReport,a as runAnalyze}from'./chunk-F6CTGVJA.js';
@@ -1 +0,0 @@
1
- export{b as AUTOPILOT_RELEASE_ALIAS_FILENAME,a as AUTOPILOT_RELEASE_LAST_RUN_FILENAME,c as runAutopilotRelease}from'./chunk-3GO7BJ5J.js';
@@ -1 +0,0 @@
1
- export{b as runDoctorCapabilities}from'./chunk-JK6XEF7K.js';
@@ -1 +0,0 @@
1
- import {a as a$2}from'./chunk-TZK2R6RD.js';import {j,l as l$1}from'./chunk-IPZT6WKM.js';import {g}from'./chunk-FRH7AIGY.js';import {u}from'./chunk-T5NBSCVX.js';import {j as j$1,e}from'./chunk-XVTN5DDV.js';import {b,c as c$1}from'./chunk-4JAURS76.js';import {c,d}from'./chunk-UCNIXOTL.js';import {a}from'./chunk-COICGD62.js';import {f as f$1,g as g$1,h as h$2}from'./chunk-R5OJD5K2.js';import {k,l,h as h$1,m,n as n$1,p as p$1,q as q$2}from'./chunk-3SNP6M4M.js';import {a as a$3}from'./chunk-D3N2WFDV.js';import {a as a$1}from'./chunk-F6CTGVJA.js';import {n,q as q$1,t}from'./chunk-4HQU2GQM.js';import {o,r as r$1,s}from'./chunk-NNQE4DS2.js';import {f,h}from'./chunk-FE5R6EUV.js';import {b as b$1}from'./chunk-K33JJVQZ.js';import {p,q,z,A,y,x}from'./chunk-ODK4LCEL.js';import {c as c$2}from'./chunk-PKKSRXUS.js';import ge from'path';import pe from'fs-extra';function r(t,s){if(!t)throw new Error(`Workspace Intelligence run semantic violation: ${s}`)}function de(t,s){return t.length===s.length&&t.every((m,u)=>m===s[u])}function ue(t){b$1(p.intelligenceRun,t,"Workspace Intelligence run report"),r(t.chainSchemaVersion===a,`chainSchemaVersion must be ${a}`),r(t.artifactPath===p.intelligenceRun,`artifactPath must be ${p.intelligenceRun}`),r(t.preflight.length===y.length,`preflight must contain exactly ${y.length} entries`);for(let[d,n]of y.entries()){let a=t.preflight[d];r(a?.id===n,`preflight[${d}].id must be ${n}`),r(de(a.artifacts,z[n]),`${n} preflight artifacts must match the runtime registry`),n==="sync"?r(a.status==="passed"&&a.result==="synchronized"||a.status==="failed"&&a.result==="failed","sync preflight status and result are incoherent"):r(a.status==="passed"&&(a.result==="created"||a.result==="reused")||a.status==="failed"&&a.result==="failed"||a.status==="skipped"&&a.result==="skipped","baseline preflight status and result are incoherent");}let s=t.preflight[1];r(t.baselineCreated===(s?.result==="created"),"baselineCreated must match the baseline preflight result"),r(t.stages.length===x.length,`stages must contain exactly ${x.length} canonical steps`);let m=t.preflight[0],u=m?.status==="failed";for(let[d,n]of x.entries()){let a=t.stages[d];r(a?.id===n,`stages[${d}].id must be ${n}`),r(de(a.artifacts,A[n].produces),`${n} artifacts must match the runtime registry`),u&&r(a.status==="skipped",`${n} must be skipped after a hard failure`),a.status==="passed"?r(a.exitCode===0,`${n} passed stage must have exitCode 0`):a.status==="blocked"?r(a.exitCode!==0,`${n} blocked stage must have a non-zero exitCode`):a.status==="failed"?(r(a.exitCode===1,`${n} failed stage must have exitCode 1`),u=true):(r(a.exitCode===0,`${n} skipped stage must have exitCode 0`),r(a.durationMs===0,`${n} skipped stage must have durationMs 0`)),d===0&&((m?.status==="failed"||a.status==="failed")&&r(s?.status==="skipped","baseline must be skipped when sync or model fails"),s?.status==="skipped"&&r(m?.status==="failed"||a.status==="failed"||a.status==="skipped","baseline may be skipped only after an upstream failure"),s?.status!=="passed"&&(u=true));}let h=t.preflight.some(d=>d.status==="failed")||t.stages.some(d=>d.status==="failed"),y$1=t.stages.some(d=>d.status==="blocked"),l=h?"failed":y$1?"blocked":"passed",p$1=l==="failed"?1:l==="blocked"?2:0;r(t.status===l,`status must be ${l}`),r(t.exitCode===p$1,`exitCode must be ${p$1}`);}var we=p.intelligenceRun,Ee=q.intelligenceRun,L=we;function I(t){c$2({action:"intelligence",status:t.status==="started"?"started":t.status==="passed"?"succeeded":t.status==="failed"?"failed":"warn",message:t.message,metadata:{phase:`workspace.intelligence.${t.kind}.${t.id}`,intelligenceMilestoneId:t.id,intelligenceMilestoneKind:t.kind,intelligenceMilestoneStatus:t.status}});}async function Ue(t){let s=ge.resolve(t.workspacePath);return f(s,L,()=>ye({...t,workspacePath:s}),{timeoutMs:15*6e4,staleAfterMs:3e4})}async function ye(t$1){let s$1=t$1.workspacePath,m$1=[],u$1=[],h$3=false,y=async(e,o)=>{let c=[...z[e]];if(h$3){I({id:e,kind:"preflight",status:"skipped",message:`${e} prerequisite skipped after an upstream failure`}),m$1.push({id:e,status:"skipped",result:"skipped",durationMs:0,artifacts:c,message:"skipped because a required upstream operation failed"});return}let k=Date.now();I({id:e,kind:"preflight",status:"started",message:`${e} prerequisite started`});try{let i=await o();I({id:e,kind:"preflight",status:"passed",message:i.message}),m$1.push({id:e,status:"passed",result:i.result,durationMs:Date.now()-k,artifacts:c,message:i.message});}catch(i){h$3=true;let f=i instanceof Error?i.message:String(i);I({id:e,kind:"preflight",status:"failed",message:f}),m$1.push({id:e,status:"failed",result:"failed",durationMs:Date.now()-k,artifacts:c,message:f});}},l$2=async(e,o)=>{let c=[...A[e].produces];if(h$3){I({id:e,kind:"stage",status:"skipped",message:`${e} skipped after an upstream failure`}),u$1.push({id:e,status:"skipped",durationMs:0,artifacts:c,exitCode:0,message:"skipped because a required upstream stage failed"});return}let k=Date.now();I({id:e,kind:"stage",status:"started",message:`${e} started`});try{let i=await o(),f=i.exitCode??0,w=i.blocked||f!==0?"blocked":"passed";I({id:e,kind:"stage",status:w,message:i.message}),u$1.push({id:e,status:w,durationMs:Date.now()-k,artifacts:c,exitCode:f,message:i.message});}catch(i){h$3=true;let f=i instanceof Error?i.message:String(i);I({id:e,kind:"stage",status:"failed",message:f}),u$1.push({id:e,status:"failed",durationMs:Date.now()-k,artifacts:c,exitCode:1,message:f});}};await y("sync",async()=>{let e=await g(s$1,true),o$1=await o({workspacePath:s$1});return {result:"synchronized",message:`registry ${e.added.length} added/${e.skipped} existing; contract ${o$1.contract.projects.length} projects`}});let p$2,d$1=()=>{if(!p$2)throw new Error("canonical workspace model is unavailable");return p$2};await l$2("model",async()=>(p$2={...await q$1({workspacePath:s$1,includeEvidence:true}),build:n({mode:"full",engineStatus:"disabled"})},await t(p$2,s$1),{message:`${p$2.summary.projectCount} projects modeled`}));let n$2=ge.join(s$1,p.snapshot),a$4=false;await y("baseline",async()=>{if(!await pe.pathExists(n$2)){let c=await k({workspacePath:s$1,model:d$1()});return await l(c,s$1),a$4=true,{result:"created",message:"initial structural baseline created"}}let e=await pe.readJson(n$2),o=h$1(e);return o?(await l(o,s$1),{result:"reused",message:"legacy structural baseline migrated and reused"}):{result:"reused",message:"existing structural baseline reused"}}),await l$2("diff",async()=>{let e=await m({workspacePath:s$1,fromPath:p.snapshot,model:d$1()});return await n$1(e,s$1),{message:e.summary.changed?"workspace changes detected":"no workspace changes"}}),await l$2("impact",async()=>{let e=await p$1({workspacePath:s$1,fromPath:p.diff});return await q$2(e,s$1),{message:`${e.summary.risk} risk; ${e.summary.affectedProjects} affected`}}),await l$2("doctor-evidence",async()=>{let e=await u({workspace:s$1,json:true,quiet:true,profile:t$1.strict===true?"enterprise-strict":"local"});return {exitCode:e,blocked:e!==0,message:`doctor exit ${e}`}}),await l$2("contract-evidence",async()=>{let e=await r$1({workspacePath:s$1,strict:true});return await s({workspacePath:s$1,result:e}),{exitCode:e.status==="passed"?0:1,blocked:e.status!=="passed",message:`contract ${e.status}`}}),await l$2("analyze-evidence",async()=>{let e=await a$1({workspacePath:s$1,json:true,strict:t$1.strict===true});return {blocked:e.summary.verdict==="blocked"||t$1.strict===true&&e.summary.verdict==="needs-attention",exitCode:e.summary.verdict==="blocked"||t$1.strict===true&&e.summary.verdict==="needs-attention"?1:0,message:`analyze ${e.summary.verdict} (${e.summary.score}/100)`}}),await l$2("readiness-evidence",async()=>{let e=await a$2({startPath:s$1,writeReport:true,skipVerify:true});return {blocked:e.overallStatus==="fail"||t$1.strict===true&&e.overallStatus==="warn",exitCode:e.overallStatus==="fail"||t$1.strict===true&&e.overallStatus==="warn"?1:0,message:`pre-verify readiness ${e.overallStatus}`}}),await l$2("verify",async()=>{let e$1=await f$1({workspacePath:s$1,fromImpactPath:p.impact});await g$1(e$1,s$1);let o=h$2(e$1,{strict:t$1.strict===true});return await j$1(s$1,e(e$1,o.passed)),{blocked:!o.passed,exitCode:o.exitCode,message:`${e$1.summary.verdict}; gate ${o.passed?"passed":"blocked"}`}}),await l$2("context",async()=>{let e=await c({workspacePath:s$1,model:d$1(),agent:t$1.agent??"generic",includeEvidence:true});return await d(e,s$1),{message:`context grounded for ${e.agent}`}}),await l$2("agent-sync",async()=>{let e=await l$1({workspacePath:s$1,agent:t$1.agent??"generic",targets:["all"],write:true,refreshContext:false,strict:t$1.strict===true,preset:"enterprise"}),o=false,c$1=await a$3(s$1);if(c$1.status==="miss"){if(c$1.reason!=="live-input-mismatch")throw new Error(`Agent grounding left canonical evidence invalid (${c$1.reason}).`);p$2={...await q$1({workspacePath:s$1,includeEvidence:true}),build:n({mode:"full",engineStatus:"disabled"})},await t(p$2,s$1);let f=await c({workspacePath:s$1,model:p$2,agent:t$1.agent??"generic",includeEvidence:true});await d(f,s$1);let w=await l$1({workspacePath:s$1,agent:t$1.agent??"generic",targets:["all"],write:true,refreshContext:false,strict:t$1.strict===true,preset:"enterprise"});e={...w,writtenFiles:[...new Set([...e.writtenFiles,...w.writtenFiles])].sort(),strictViolations:[...new Set([...e.strictViolations??[],...w.strictViolations??[]])].sort()};let O=await a$3(s$1);if(O.status==="miss")throw new Error(`Agent grounding reconciliation did not produce fresh canonical evidence (${O.reason}).`);o=true;}let k=e.strictViolations??[],i=t$1.strict===true&&k.length>0;return {blocked:i,exitCode:i?2:0,message:i?`${e.writtenFiles.length} grounding files written; ${k.length} strict grounding violation(s): ${k.join("; ")}`:`${e.writtenFiles.length} grounding files written; portable entry surfaces prepared for all supported hosts${o?"; canonical Model/Graph freshness sealed":""}`}}),await l$2("explain",async()=>{let e=await b({workspacePath:s$1,target:{kind:"release-blocked"}});await c$1(e,s$1);let o=t$1.strict===true?u$1.filter(c=>c.status==="blocked").map(c=>c.id):[];return {message:o.length>0&&e.blocking!==true?`Strict policy blocked advisory or incomplete evidence in ${o.join(", ")}. ${e.summary}`:e.summary}});let me=u$1.some(e=>e.status==="blocked"),G=h$3?"failed":me?"blocked":"passed",fe=h$3?1:G==="blocked"?2:0,b$1={schemaVersion:Ee,chainSchemaVersion:a,generatedAt:new Date().toISOString(),workspacePath:s$1,baselineCreated:a$4,preflight:m$1,status:G,exitCode:fe,stages:u$1,artifactPath:L};ue(b$1),await h(s$1,L,b$1);let ke=await j({workspacePath:s$1});return await h(s$1,p.agentIndex,ke),b$1}export{we as a,Ee as b,Ue as c};
@@ -1,2 +0,0 @@
1
- import {r,s}from'./chunk-VQZ5PI5J.js';import o from'fs-extra';async function i(a){for(let t of [r(a),s(a)])try{if(await o.pathExists(t))return await o.readJson(t)}catch{}return null}async function c(a,t){let e=await i(a);e?.metadata&&(t.metadata={...e.metadata,...t.metadata});let r$1=JSON.stringify(t,null,2)+`
2
- `;await o.outputFile(r(a),r$1,"utf-8");}async function m(a,t){let e=await i(a);return e?(e.metadata={...e.metadata,...t,vscode:t.vscode?{...e.metadata?.vscode,...t.vscode}:e.metadata?.vscode,npm:t.npm?{...e.metadata?.npm,...t.npm}:e.metadata?.npm,python:t.python?{...e.metadata?.python,...t.python}:e.metadata?.python},await c(a,e),true):false}function u(a,t,e,r){return {signature:"RAPIDKIT_WORKSPACE",createdBy:"workspai-cli",version:t,createdAt:new Date().toISOString(),name:a,metadata:{npm:{packageVersion:t,installMethod:e,lastUsedAt:new Date().toISOString()},...r?{python:r}:{}}}}function f(a){if(!a||typeof a!="object")return false;let t=a;return t.signature==="RAPIDKIT_WORKSPACE"&&typeof t.createdBy=="string"&&typeof t.version=="string"&&typeof t.createdAt=="string"&&typeof t.name=="string"}export{i as a,c as b,m as c,u as d,f as e};
@@ -1,2 +0,0 @@
1
- import {q as q$1,l,m,k as k$1}from'./chunk-4HQU2GQM.js';import {a}from'./chunk-HTYMXMQM.js';import {c}from'./chunk-S5KTATOU.js';import {d as d$1}from'./chunk-NNQE4DS2.js';import {h as h$1}from'./chunk-FE5R6EUV.js';import {a as a$1}from'./chunk-AFIFZTOY.js';import {e,d,b as b$1}from'./chunk-EWZZUQBR.js';import {q,p}from'./chunk-ODK4LCEL.js';import k from'path';import V from'fs-extra';import {spawnSync}from'child_process';function ue(){let e={...process.env};return delete e.GIT_DIR,delete e.GIT_WORK_TREE,delete e.GIT_INDEX_FILE,delete e.GIT_PREFIX,e}function $(e,t,a){let r=spawnSync("git",t,{cwd:e,env:ue(),encoding:"utf8",stdio:["ignore","pipe","ignore"]});if(r.status!==0)return {ok:false,stdout:""};let i=r.stdout??"";return {ok:true,stdout:a?.preserveWhitespace?i:i.trim()}}function ge(e){let t=e.replace(/\\/g,"/").replace(/^\.\//,"");return t===".workspai/AGENT-GROUNDING.md"?true:[".workspai/reports/",".workspai/cache/",".rapidkit/reports/",".rapidkit/cache/"].some(a=>t.startsWith(a))}function ke(e){let t=[],a=[],r=[];for(let i of e.split(`
2
- `)){if(!i.trim())continue;let n=i.slice(0,2),c=i.slice(3).trim();if(c&&!ge(c)){if(n==="??"){a.push(c);continue}n.includes("D")&&r.push(c),t.push(c);}}return {changedFiles:[...new Set(t)].sort(),untrackedFiles:[...new Set(a)].sort(),deletedFiles:[...new Set(r)].sort()}}function Q(e,t){let a={available:false,dirty:false,changedFiles:[],untrackedFiles:[],deletedFiles:[]},r=$(e,["rev-parse","--is-inside-work-tree"]);if(!r.ok||r.stdout!=="true")return a;let i=$(e,["rev-parse","--abbrev-ref","HEAD"]),n=$(e,["rev-parse","HEAD"]),c=$(e,["status","--porcelain=v1","--untracked-files=all"],{preserveWhitespace:true}),p=ke(c.stdout),m=p.changedFiles.length>0||p.untrackedFiles.length>0||p.deletedFiles.length>0;return {available:true,branch:i.ok?i.stdout:void 0,commit:n.ok?n.stdout:void 0,ref:t?.ref,dirty:m,changedFiles:p.changedFiles,untrackedFiles:p.untrackedFiles,deletedFiles:p.deletedFiles}}var oe=q.snapshot,L=q.diff,_=p.snapshot,ae=p.diff,he=q.impact,we=p.impact;function ye(e$1){if(e$1.model.projectTopology||!e$1.model.graph||e$1.modelHash!==e(e$1.model))return null;let t={...e$1.model,projectTopology:e$1.model.graph,graph:e$1.model.graph};return {...e$1,modelHash:d(t),model:t}}function ne(e){let t=e.trim().toLowerCase();return t==="git"||t.startsWith("git:")}function We(e){let t=e.trim();return t.toLowerCase()==="git"?"HEAD":t.toLowerCase().startsWith("git:")&&t.slice(4).trim()||"HEAD"}function se(e,t){return k.isAbsolute(t)?t:k.join(e,t)}async function be(e){let t=await V.readJson(e);if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`Workspace model input is not a JSON object: ${e}`);let a=t;if(a.schemaVersion===oe){a$1(t,"contracts/workspace-intelligence/workspace-model-snapshot.v1.json",`Workspace model snapshot ${e}`);let r=a;if(!r.model||r.model.schemaVersion!==k$1)throw new Error(`Invalid workspace model snapshot: ${e}`);let i=d(r.model);if(r.modelHash!==i){let n=ye(r);if(!n)throw new Error(`Workspace model snapshot hash mismatch: ${e}`);return {model:n.model,hash:n.modelHash}}return {model:r.model,hash:r.modelHash}}if(a.schemaVersion===k$1){a$1(t,"contracts/workspace-intelligence/workspace-model.v1.json",`Workspace model ${e}`);let r=a;return {model:r,hash:d(r)}}throw a.schemaVersion===L?new Error(`workspace diff --from received a diff report (${k.basename(e)}). Use a workspace model snapshot or model report as baseline, e.g. ${_}. To analyze an existing diff report, run: npx workspai workspace impact --from ${k.basename(e)} --json`):new Error(`Unsupported workspace model input schema: ${String(a.schemaVersion)}`)}async function ve(e){let t=await V.readJson(e);if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`Workspace diff input is not a JSON object: ${e}`);let a=t;if(a.schemaVersion!==L)return null;a$1(t,"contracts/workspace-intelligence/workspace-model-diff.v1.json",`Workspace model diff ${e}`);let r=a;if(!r.currentModel||r.currentModel.schemaVersion!==k$1||!r.summary||!Array.isArray(r.changes))throw new Error(`Invalid workspace model diff report: ${e}`);if(r.toHash!==d(r.currentModel))throw new Error(`Workspace model diff current-model hash mismatch: ${e}`);return r}async function Ye(e){let t=e.model??await q$1({workspacePath:e.workspacePath,includeAbsolutePaths:e.includeAbsolutePaths,includeEvidence:e.includeEvidence,observableScanDepth:e.observableScanDepth,now:e.now});return {schemaVersion:oe,generatedAt:(e.now??new Date).toISOString(),modelHash:d(t),modelRef:l,model:t}}async function Qe(e,t){return h$1(t,_,d$1(e))}function x(e){return {name:e.name,path:e.path,kind:e.kind,category:e.category,runtime:e.runtime,framework:e.framework,generator:e.generator,supportTier:e.supportTier,commands:e.commands,importantFiles:e.importantFiles}}function h(e,t){e.push(t);}function Me(e,t){let a=[],r=["name","profile","type"],i=["workspaceType","surfaces","runtimeFamilies","businessCapabilities"];for(let n of r){let c=e.workspace[n],p=t.workspace[n];b$1(c)!==b$1(p)&&h(a,{type:"workspace.changed",severity:"info",target:`workspace.${n}`,message:`Workspace metadata field changed: ${String(n)}`,before:c,after:p});}for(let n of i){let c=e.identity[n],p=t.identity[n];b$1(c)!==b$1(p)&&h(a,{type:"workspace.changed",severity:"info",target:`identity.${n}`,message:`Workspace identity field changed: ${String(n)}`,before:c,after:p});}return b$1(e.policies)!==b$1(t.policies)&&h(a,{type:"workspace.changed",severity:"warning",target:"policies",message:"Workspace policy summary changed.",before:e.policies,after:t.policies}),b$1(e.discovery)!==b$1(t.discovery)&&h(a,{type:"workspace.changed",severity:"info",target:"discovery",message:"Workspace discovery settings changed.",before:e.discovery,after:t.discovery}),e.contracts.exists!==t.contracts.exists&&h(a,{type:"workspace.changed",severity:t.contracts.exists?"info":"warning",target:t.contracts.workspaceContractPath,message:"Workspace contract presence changed.",before:e.contracts.exists,after:t.contracts.exists}),a}function je(e,t){let a=e.validation??null,r=t.validation??null;return b$1(a)===b$1(r)?[]:[{type:"validation.changed",severity:r?.status==="failed"?"critical":"warning",target:"validation",message:"Workspace model validation changed.",before:a,after:r}]}function Ie(e,t){let a=[],r=new Map(e.projects.map(n=>[n.path,n])),i=new Map(t.projects.map(n=>[n.path,n]));for(let[n,c]of i.entries()){let p=r.get(n);if(!p){h(a,{type:"project.added",severity:"info",target:n,message:`Project added: ${c.name}`,after:x(c)});continue}let m=x(p),l=x(c);if(b$1(m)!==b$1(l)){let u=p.runtime!==c.runtime||p.framework!==c.framework;h(a,{type:"project.changed",severity:u?"warning":"info",target:n,message:`Project changed: ${c.name}`,before:m,after:l});}}for(let[n,c]of r.entries())i.has(n)||h(a,{type:"project.removed",severity:"warning",target:n,message:`Project removed: ${c.name}`,before:x(c)});return a.sort((n,c)=>`${n.type}:${n.target}`.localeCompare(`${c.type}:${c.target}`))}async function Pe(e){let t=k.resolve(e.workspacePath),a=ne(e.fromPath),r=a?We(e.fromPath):void 0,i=e.fromPath;if(a){let f=k.join(t,_);if(!await V.pathExists(f))throw new Error("Git-aware workspace diff requires an existing snapshot at .workspai/reports/workspace-model-snapshot.json. Run: npx workspai workspace snapshot --json");i=_;}let n=se(t,i),c=await be(n),p=e.model??await q$1({workspacePath:t,includeAbsolutePaths:e.includeAbsolutePaths,includeEvidence:e.includeEvidence,observableScanDepth:e.observableScanDepth,now:e.now}),m=d(p),l$1=[...Me(c.model,p),...Ie(c.model,p),...je(c.model,p)],u;e.includeGitObservation!==false&&(u=e.gitObservation??Q(t,{ref:r}),u.available&&Ee(l$1,u,p));let v=l$1.filter(f=>f.type.startsWith("git.")).length,R=c.hash!==m,w=a?`git:${r??"HEAD"}`:k.relative(t,n).split(k.sep).join("/");return {schemaVersion:L,generatedAt:(e.now??new Date).toISOString(),fromRef:w,toRef:l,fromHash:c.hash,toHash:m,summary:{changed:R||v>0,addedProjects:l$1.filter(f=>f.type==="project.added").length,removedProjects:l$1.filter(f=>f.type==="project.removed").length,changedProjects:l$1.filter(f=>f.type==="project.changed").length,workspaceChanges:l$1.filter(f=>f.type==="workspace.changed").length,validationChanges:l$1.filter(f=>f.type==="validation.changed").length,gitChangedFiles:v},git:u?.available?Oe(u,r):{available:false,dirty:false,changedFiles:0,untrackedFiles:0,deletedFiles:0},changes:l$1,currentModel:p}}async function Ze(e,t){return h$1(t,ae,d$1(e))}function I(e){return {none:0,low:1,medium:2,high:3,critical:4}[e]}function Z(e){return e.reduce((t,a)=>I(a)>I(t)?a:t,"none")}var N=["none","low","medium","high","critical"];function Re(e){let t=Math.max(1,I(e)-1);return N[t]}function Ce(e){let t=Math.min(N.length-1,I(e)+1);return N[t]}function ee(e){return e.join(" ")}function b(e,t,a,r){return {id:e,label:t,scope:r.scope,project:r.project,display:ee(["npx","workspai",...a]),execute:ee(["npx","--yes","--package","workspai","workspai",...a]),required:r.required!==false}}function te(e){let t=`project:${e.name}`,a=e.commands.fleetStages,r={init:`Run init for ${e.name}`,test:`Run tests for ${e.name}`,build:`Run build for ${e.name}`,start:`Run start for ${e.name}`};return ["init","test","build","start"].filter(i=>a.includes(i)).map(i=>b(`project.${e.name}.${i}`,r[i],["workspace","run",i,"--scope",t,"--json"],{scope:"project",project:e.name}))}function T(){return [b("workspace.doctor","Run workspace doctor",["doctor","workspace","--json"],{scope:"workspace"}),b("workspace.contract.verify","Verify workspace contract",["workspace","contract","verify","--json"],{scope:"workspace"}),b("workspace.readiness","Run release readiness",["readiness","--json"],{scope:"workspace"}),b("workspace.analyze","Run workspace analyze",["analyze","--json"],{scope:"workspace",required:false}),b("workspace.pipeline","Run governance pipeline",["pipeline","--json"],{scope:"workspace",required:false}),b("workspace.doctor-fix","Verify doctor fix result",["doctor","workspace","--fix","--json"],{scope:"workspace",required:false})]}function Se(e,t){let a=t.split(k.sep).join("/");return e.projects.filter(i=>{let n=i.path.split(k.sep).join("/");return a===n||a.startsWith(`${n}/`)}).sort((i,n)=>n.path.length-i.path.length)[0]}function Ee(e,t,a){let r=new Set(e.map(n=>n.target)),i=(n,c)=>{let p=c.split(k.sep).join("/"),m=`git:${p}`;if(r.has(m))return;let l=Se(a,p),u=l?`${l.name} (${l.path})`:"workspace";h(e,{type:n,severity:n==="git.deleted"?"warning":"info",target:m,message:`Git ${n==="git.untracked"?"untracked":n==="git.deleted"?"deleted":"changed"} file affects ${u}: ${p}`,after:{path:p,project:l?.name,projectPath:l?.path}}),r.add(m);};for(let n of t.changedFiles)i("git.file.changed",n);for(let n of t.untrackedFiles)i("git.untracked",n);for(let n of t.deletedFiles)i("git.deleted",n);}function Oe(e,t){return {available:true,ref:t??e.ref,branch:e.branch,commit:e.commit,dirty:e.dirty,changedFiles:e.changedFiles.length,untrackedFiles:e.untrackedFiles.length,deletedFiles:e.deletedFiles.length}}function Ae(e){let t=new Set,a=[];for(let r of e){let i=`${r.scope}:${r.project??""}:${r.display}`;t.has(i)||(t.add(i),a.push(r));}return a}function De(e){return e.type==="project.removed"?"high":e.severity==="critical"?"critical":e.severity==="warning"?"high":("medium")}function Fe(e,t){return e.severity==="critical"?"critical":e.target==="policies"||e.target.includes("contract")?"high":e.type==="validation.changed"?(t?.projectCount??0)===0?"low":"high":e.target==="evidence"?"low":e.severity==="warning"?"medium":"low"}function $e(e){return e.affectedProjects>0||e.projectCount>0||!e.changes.every(a=>a.severity==="critical"?false:a.type.startsWith("git.")||a.type==="validation.changed")?e.risk:I(e.risk)>=I("high")||e.risk==="medium"?"low":e.risk}function re(e,t){if(!e||e==="workspace")return true;let a=(e.startsWith("project:")?e.slice(8):e).trim().toLowerCase();return [t.name,t.path,k.basename(t.path),t.absolutePath].filter(r=>typeof r=="string"&&r.trim().length>0).map(r=>r.trim().toLowerCase()).includes(a)}function xe(e){if(!e.changed)return {headline:"No workspace model impact detected.",bullets:["The current workspace model matches the provided snapshot/report."],unsafeAssumptions:["Do not claim runtime verification passed unless a report exists."]};let t=e.affectedProjects.map(a=>a.project?.name??a.target);return {headline:`Workspace impact risk: ${e.risk}.`,bullets:[`Affected projects: ${t.length?t.join(", "):"none"}.`,`Workspace-level items: ${e.workspaceImpact.length}.`,"Use the verification plan before recommending apply, rollback, or release actions."],unsafeAssumptions:["Do not infer test/build success from impact alone.","Do not apply fixes without project scope and verification evidence.","Use display commands for users and execute commands for automation."]}}async function et(e){let t=k.resolve(e.workspacePath),a$1=ne(e.fromPath),r=e.diff;if(!r&&!a$1){let o=se(t,e.fromPath);r=await ve(o)??void 0;}r||(r=await Pe({workspacePath:t,fromPath:e.fromPath,includeAbsolutePaths:e.includeAbsolutePaths,includeEvidence:e.includeEvidence,includeGitObservation:e.includeGitObservation,gitObservation:e.gitObservation,now:e.now,model:e.model}));let i=new Map(r.currentModel.projects.map(o=>[o.path,o])),n=new Map(r.currentModel.projects.map(o=>[o.name,o])),c$1=r.changes.filter(o=>o.type.startsWith("project.")),p=new Map;for(let o of c$1){let d=(i.get(o.target)??(typeof o.before?.name=="string"?n.get(o.before.name):void 0))?.path??o.target,y=p.get(d)??[];y.push(o),p.set(d,y);}let m$1=[];for(let[o,s]of p.entries()){let d=i.get(o);if(d&&!re(e.scope,d))continue;let y=Z(s.map(De)),C=d?.name??(typeof s[0]?.before?.name=="string"?String(s[0].before.name):o);m$1.push({id:`project:${C}`,scope:"project",target:o,title:`Project impact: ${C}`,summary:s.map(M=>M.message).join(" "),risk:y,reasons:s.map(M=>`${M.type}: ${M.message}`),project:d?{name:d.name,path:d.path,kind:d.kind,runtime:d.runtime,framework:d.framework,supportTier:d.supportTier,...d.generator?{generator:d.generator}:{}}:void 0,verification:d?te(d):T()});}let l=m(r.currentModel),u=l?a(l):void 0,v=new Set(m$1.map(o=>o.project?.name).filter(o=>typeof o=="string")),R=new Map;for(let o of m$1)if(o.project?.name){let s=u?.byId.get(o.project.name);s&&(o.centrality={fanIn:s.fanIn,fanOut:s.fanOut,reach:s.reach,betweenness:s.betweenness,isHotspot:s.isHotspot},s.isHotspot&&(o.risk=Ce(o.risk),o.reasons=[...o.reasons,`graph.hotspot: critical-path project with ${s.reach} transitive dependent(s); risk escalated.`])),o.origin="direct",o.distance=0,R.set(o.project.name,o.risk);}let w=[],f=0;if(l&&v.size>0){let o=c(l,v);for(let s of o.values()){if(s.distance===0||v.has(s.id))continue;let d=n.get(s.id);if(d&&!re(e.scope,d))continue;let y=s.path[0],C=s.path[s.path.length-2]??y,M=R.get(y)??"medium",de=Re(M),j=u?.byId.get(s.id);f=Math.max(f,s.distance),w.push({id:`transitive:${s.id}`,scope:"project",target:d?.path??s.id,title:`Transitive impact: ${s.id}`,summary:`Depends on changed project ${y}${s.via?` via ${s.via}`:""} (distance ${s.distance}).`,risk:de,reasons:[`graph.dependent: depends on ${C}${s.via?` via ${s.via}`:""} (path ${s.path.join(" -> ")})`],project:d?{name:d.name,path:d.path,kind:d.kind,runtime:d.runtime,framework:d.framework,supportTier:d.supportTier,...d.generator?{generator:d.generator}:{}}:void 0,verification:d?te(d):T(),origin:"transitive",distance:s.distance,path:s.path,via:s.via,...j?{centrality:{fanIn:j.fanIn,fanOut:j.fanOut,reach:j.reach,betweenness:j.betweenness,isHotspot:j.isHotspot}}:{}});}}w.sort((o,s)=>o.target.localeCompare(s.target));let ie=u?u.hotspots.flatMap(o=>{let s=u.byId.get(o);return s?[{project:o,fanIn:s.fanIn,fanOut:s.fanOut,reach:s.reach,betweenness:s.betweenness}]:[]}):[],ce=r.changes.filter(o=>!o.type.startsWith("project.")),K=r.currentModel.summary?.projectCount??r.currentModel.projects.length,P=ce.map(o=>({id:`workspace:${o.target}`,scope:"workspace",target:o.target,title:`Workspace impact: ${o.target}`,summary:o.message,risk:Fe(o,{projectCount:K}),reasons:[`${o.type}: ${o.message}`],verification:T()})),B=Ae([...m$1.flatMap(o=>o.verification),...w.flatMap(o=>o.verification),...P.flatMap(o=>o.verification),...r.summary.changed?T():[]]).filter(o=>o.required),pe=Z([...m$1.map(o=>o.risk),...w.map(o=>o.risk),...P.map(o=>o.risk)]),z=$e({risk:pe,affectedProjects:m$1.length,projectCount:K,changes:r.changes}),q={changed:r.summary.changed,risk:z,affectedProjects:m$1.length,workspaceItems:P.length,recommendedCommands:B.length,blastRadius:{directlyAffected:m$1.length,transitivelyAffected:w.length,maxDistance:f,graphEdges:l?.edges.length??0}};return {schemaVersion:he,generatedAt:(e.now??new Date).toISOString(),fromRef:r.fromRef,diffRef:ae,workspace:{name:r.currentModel.workspace.name,profile:r.currentModel.workspace.profile,type:r.currentModel.workspace.type},summary:q,affectedProjects:m$1.sort((o,s)=>o.target.localeCompare(s.target)),transitiveImpact:w,criticalPathHotspots:ie,workspaceImpact:P.sort((o,s)=>o.target.localeCompare(s.target)),verificationPlan:B,agentBrief:xe({changed:q.changed,risk:z,affectedProjects:m$1,workspaceImpact:P}),diff:r}}async function tt(e,t){return h$1(t,we,d$1(e))}export{Q as a,oe as b,L as c,_ as d,ae as e,he as f,we as g,ye as h,ne as i,We as j,Ye as k,Qe as l,Pe as m,Ze as n,T as o,et as p,tt as q};
@@ -1,105 +0,0 @@
1
- import {h}from'./chunk-PKKSRXUS.js';import {b,a}from'./chunk-TQEMLBAG.js';import {e,h as h$1,c}from'./chunk-RGNCL5OB.js';import {v}from'./chunk-VQZ5PI5J.js';import ae from'validate-npm-package-name';import x from'path';import {spawn}from'child_process';import d from'chalk';import u from'fs-extra';function oe(e,t){return t==="win32"?`Install Python ${e}+ with Windows Package Manager:
2
- winget install --exact --id Python.Python.${e}
3
-
4
- Or use the official installer and enable "Add Python to PATH":
5
- https://www.python.org/downloads/windows/`:t==="darwin"?`Install Python ${e}+ with Homebrew:
6
- brew install python@${e}
7
-
8
- Official installers:
9
- https://www.python.org/downloads/macos/`:`Install Python and its environment tooling for your Linux distribution:
10
- Debian/Ubuntu: sudo apt update && sudo apt install python3 python3-venv python3-pip
11
- Fedora/RHEL: sudo dnf install python3 python3-pip
12
- Arch: sudo pacman -S python python-pip
13
- Alpine: sudo apk add python3 py3-pip py3-virtualenv
14
-
15
- Official installers:
16
- https://www.python.org/downloads/`}function re(e){return e==="win32"?`Option 1 - install Poetry with pipx:
17
- py -m pip install --user pipx
18
- py -m pipx ensurepath
19
- py -m pipx install poetry
20
-
21
- Option 2 - use the official Poetry installer in PowerShell:
22
- (Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
23
-
24
- Official installation guide:
25
- https://python-poetry.org/docs/#installation`:e==="darwin"?`Option 1 - install Poetry with Homebrew:
26
- brew install poetry
27
-
28
- Option 2 - install Poetry with pipx:
29
- brew install pipx
30
- pipx ensurepath
31
- pipx install poetry
32
-
33
- Official installation guide:
34
- https://python-poetry.org/docs/#installation`:`Option 1 - install Poetry with pipx:
35
- Debian/Ubuntu: sudo apt update && sudo apt install pipx
36
- Fedora/RHEL: sudo dnf install pipx
37
- Arch: sudo pacman -S python-pipx
38
- Alpine: sudo apk add pipx
39
- Then run: pipx ensurepath
40
- pipx install poetry
41
-
42
- Option 2 - use the official Poetry installer:
43
- curl -sSL https://install.python-poetry.org | python3 -
44
-
45
- Official installation guide:
46
- https://python-poetry.org/docs/#installation`}function B(e){return e==="win32"?`Install pipx:
47
- py -m pip install --user pipx
48
- py -m pipx ensurepath
49
-
50
- Official installation guide:
51
- https://pipx.pypa.io/stable/installation/`:e==="darwin"?`Install pipx with Homebrew:
52
- brew install pipx
53
- pipx ensurepath
54
-
55
- Official installation guide:
56
- https://pipx.pypa.io/stable/installation/`:`Install pipx for your Linux distribution:
57
- Debian/Ubuntu: sudo apt update && sudo apt install pipx
58
- Fedora/RHEL: sudo dnf install pipx
59
- Arch: sudo pacman -S python-pipx
60
- Alpine: sudo apk add pipx
61
- Then run: pipx ensurepath
62
-
63
- Official installation guide:
64
- https://pipx.pypa.io/stable/installation/`}function ie(e,t){let n=e.match(/(\d+\.\d+)/)?.[1]||"3.13";return t==="win32"?`Repair or reinstall Python and ensure pip is selected:
65
- winget install --exact --id Python.Python.${n}
66
-
67
- Then verify:
68
- py -m venv --help`:t==="darwin"?`Reinstall the Homebrew Python runtime:
69
- brew reinstall python
70
-
71
- Then verify:
72
- python3 -m venv --help`:`Install virtual-environment support for your Linux distribution:
73
- Debian/Ubuntu: sudo apt update && sudo apt install ${e}
74
- Fedora/RHEL: sudo dnf install python3 python3-pip
75
- Arch: sudo pacman -S python python-pip
76
- Alpine: sudo apk add python3 py3-pip py3-virtualenv
77
-
78
- Then verify:
79
- python3 -m venv --help`}var f=class extends Error{constructor(n,o,i){super(n);this.code=o;this.details=i;this.name="RapidKitError",Error.captureStackTrace(this,this.constructor);}code;details},L=class extends f{constructor(t,n,o=process.platform){let i=n?`Python ${t}+ required, found ${n}`:`Python ${t}+ not found`;super(i,"PYTHON_NOT_FOUND",oe(t,o));}},q=class extends f{constructor(t=process.platform){super("Poetry is not installed","POETRY_NOT_FOUND",re(t));}},J=class extends f{constructor(t=process.platform){super("pipx is not installed","PIPX_NOT_FOUND",B(t));}},V=class extends f{constructor(t){super(`Directory "${t}" already exists`,"DIRECTORY_EXISTS","Please choose a different name or remove the existing directory");}},g=class extends f{constructor(t,n){super(`Invalid project name: "${t}"`,"INVALID_PROJECT_NAME",n);}},M=class extends f{constructor(t,n){let o=`Installation failed at: ${t}`,i=`${n.message}
80
-
81
- Troubleshooting:
82
- - Check your internet connection
83
- - Verify Python/Poetry installation
84
- - Try running with --debug flag for more details`;super(o,"INSTALLATION_ERROR",i);}},U=class extends f{constructor(t,n,o=process.platform){super("Python virtual environment support is not installed","PYTHON_VENV_UNAVAILABLE",`${ie(t,o)}
85
-
86
- Or create the workspace without the optional Python engine:
87
- npx workspai create workspace ${n} --skip-python-engine`);}},W=class extends f{constructor(t=process.platform){super("Python package installation support is not available","PYTHON_PIP_UNAVAILABLE",`pipx cannot be installed through the selected Python because pip is unavailable.
88
-
89
- `+B(t)+`
90
-
91
- Alternatively, restore pip and retry:
92
- `+(t==="win32"?" py -m ensurepip --upgrade":t==="darwin"?" brew reinstall python":` Debian/Ubuntu: sudo apt install python3-pip
93
- Fedora/RHEL: sudo dnf install python3-pip
94
- Arch: sudo pacman -S python-pip
95
- Alpine: sudo apk add py3-pip`));}},H=class extends f{constructor(){super("RapidKit Python package is not yet available on PyPI","RAPIDKIT_NOT_AVAILABLE",`Available options:
96
- 1. Install Python 3.10+ and retry the same command
97
- 2. Use the core workflow: npx workspai create workspace <name>
98
- 3. Offline fallback (limited): npx workspai create project fastapi.standard <name> --output .
99
-
100
- Legacy: set RAPIDKIT_SHOW_LEGACY=1 to reveal template-mode flags in help.`);}};function R(e){let t=ae(e);if(!t.validForNewPackages){let o=t.errors||[],i=t.warnings||[],r=[...o,...i];throw new g(e,`NPM validation failed: ${r.join(", ")}`)}if(!/^[a-z][a-z0-9_-]*$/.test(e))throw new g(e,"Must start with a lowercase letter and contain only lowercase letters, numbers, hyphens, and underscores");if(["test","tests","src","dist","build","lib","python","pip","poetry","node","npm","rapidkit","rapidkit"].includes(e.toLowerCase()))throw new g(e,`"${e}" is a reserved name. Please choose a different name.`);if(e.length<2)throw new g(e,"Name must be at least 2 characters long");if(e.length>214)throw new g(e,"Name must be less than 214 characters");return true}async function O(e,t){let n={},o={};return await se(e,n,o),await ce(e,n,o),{policy:"latest-stable",requested_channel:t,host:{node:process.versions.node,platform:process.platform,arch:process.arch},declared:K(n),resolved:K(o)}}async function se(e,t,n){let o=x.join(e,"package.json");if(!await u.pathExists(o))return;let i=await u.readJson(o);for(let l of ["dependencies","devDependencies","peerDependencies"]){let s=S(i[l]);for(let[m,v]of Object.entries(s))t[`npm:${m}`]=v;}for(let[l,s]of Object.entries(S(i.engines)))t[`engine:${l}`]=s;let r=x.join(e,"package-lock.json");if(!await u.pathExists(r))return;let a=await u.readJson(r),c=T(a.packages);for(let l of Object.keys(t).filter(s=>s.startsWith("npm:")).map(s=>s.slice(4))){let s=T(c[`node_modules/${l}`]);typeof s.version=="string"&&(n[`npm:${l}`]=s.version);}}async function ce(e,t,n){let o=x.join(e,"composer.json");if(!await u.pathExists(o))return;let i=await u.readJson(o);for(let c of ["require","require-dev"])for(let[l,s]of Object.entries(S(i[c])))t[`composer:${l}`]=s;let r=x.join(e,"composer.lock");if(!await u.pathExists(r))return;let a=await u.readJson(r);for(let c of ["packages","packages-dev"]){let l=Array.isArray(a[c])?a[c]:[];for(let s of l){let m=T(s);typeof m.name=="string"&&typeof m.version=="string"&&(n[`composer:${m.name}`]=m.version);}}}function S(e){return !e||typeof e!="object"||Array.isArray(e)?{}:Object.fromEntries(Object.entries(e).filter(t=>typeof t[1]=="string"))}function T(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function K(e){return Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)))}var Y=[{id:"nextjs",kitId:"frontend.nextjs",aliases:["frontend.nextjs","next","nextjs","next.js"],displayName:"Next.js",framework:"nextjs",defaultPort:3e3,versionPolicy:"latest-stable",commandDisplay:e=>`npx create-next-app@latest ${e}`,commandExec:(e,t)=>({command:"npx",args:["--yes","create-next-app@latest",e,"--yes",...t.skipGit?["--disable-git"]:[],...t.skipInstall?["--skip-install"]:[]]})},{id:"remix",kitId:"frontend.remix",aliases:["frontend.remix","remix","remix-run","react-router"],displayName:"React Router",framework:"remix",defaultPort:5173,versionPolicy:"latest-stable",minNodeVersion:"22.22.0",minNodeMessage:"The latest stable React Router generator requires Node.js 22.22.0 or newer. Upgrade Node.js, then retry.",commandDisplay:e=>`npx create-react-router@latest ${e}`,commandExec:(e,t)=>({command:"npx",args:["--yes","create-react-router@latest",e,"--yes",...t.skipInstall?["--no-install"]:["--install"],"--no-git-init"]})},{id:"vite-react",kitId:"frontend.vite-react",aliases:["frontend.vite-react","vite-react","react","vite.react"],displayName:"React + Vite",framework:"react",defaultPort:5173,versionPolicy:"latest-stable",commandDisplay:e=>`npm create vite@latest ${e} -- --template react-ts`,commandExec:e=>({command:"npm",args:["create","vite@latest",e,"--","--template","react-ts","--no-interactive"]})},{id:"vite-vue",kitId:"frontend.vite-vue",aliases:["frontend.vite-vue","vite-vue","vue","vite.vue"],displayName:"Vue + Vite",framework:"vue",defaultPort:5173,versionPolicy:"latest-stable",commandDisplay:e=>`npm create vite@latest ${e} -- --template vue-ts`,commandExec:e=>({command:"npm",args:["create","vite@latest",e,"--","--template","vue-ts","--no-interactive"]})},{id:"vite-svelte",kitId:"frontend.vite-svelte",aliases:["frontend.vite-svelte","vite-svelte","svelte","vite.svelte"],displayName:"Svelte + Vite",framework:"svelte",defaultPort:5173,versionPolicy:"latest-stable",commandDisplay:e=>`npm create vite@latest ${e} -- --template svelte-ts`,commandExec:e=>({command:"npm",args:["create","vite@latest",e,"--","--template","svelte-ts","--no-interactive"]})},{id:"vite-solid",kitId:"frontend.vite-solid",aliases:["frontend.vite-solid","vite-solid","solid","solidjs","vite.solid"],displayName:"Solid + Vite",framework:"solid",defaultPort:5173,versionPolicy:"latest-stable",commandDisplay:e=>`npm create vite@latest ${e} -- --template solid-ts`,commandExec:e=>({command:"npm",args:["create","vite@latest",e,"--","--template","solid-ts","--no-interactive"]})},{id:"vite-vanilla",kitId:"frontend.vite-vanilla",aliases:["frontend.vite-vanilla","vite","vanilla","vite-vanilla"],displayName:"Vite",framework:"vite",defaultPort:5173,versionPolicy:"latest-stable",commandDisplay:e=>`npm create vite@latest ${e} -- --template vanilla-ts`,commandExec:e=>({command:"npm",args:["create","vite@latest",e,"--","--template","vanilla-ts","--no-interactive"]})},{id:"nuxt",kitId:"frontend.nuxt",aliases:["frontend.nuxt","nuxt","nuxtjs","nuxt.js"],displayName:"Nuxt",framework:"nuxt",defaultPort:3e3,versionPolicy:"latest-stable",commandDisplay:(e,t)=>`npx create-nuxt@latest ${e} --template minimal --packageManager npm --gitInit ${t?.skipGit?"false":"true"}${t?.skipInstall?" --no-install":""}`,commandExec:(e,t)=>({command:"npx",args:["--yes","create-nuxt@latest",e,"--template","minimal","--packageManager","npm","--gitInit",t.skipGit?"false":"true",...t.skipInstall?["--no-install"]:[]]})},{id:"angular",kitId:"frontend.angular",aliases:["frontend.angular","angular","ng"],displayName:"Angular",framework:"angular",defaultPort:4200,versionPolicy:"latest-stable",minNodeMajor:20,minNodeMessage:"The latest stable Angular CLI requires a modern Node.js runtime. Upgrade to Node.js 20.19+ (or a newer supported LTS), then retry.",commandDisplay:e=>`npx @angular/cli@latest new ${e}`,commandExec:(e,t)=>({command:"npx",args:["--yes","@angular/cli@latest","new",e,"--defaults","--skip-git",...t.skipInstall?["--skip-install"]:[]]})},{id:"astro",kitId:"frontend.astro",aliases:["frontend.astro","astro"],displayName:"Astro",framework:"astro",defaultPort:4321,versionPolicy:"latest-stable",commandDisplay:e=>`npm create astro@latest ${e}`,commandExec:(e,t)=>({command:"npm",args:["create","astro@latest",e,"--","--yes",...t.skipInstall?["--no-install"]:[],...t.skipGit?["--no-git"]:[]]})},{id:"sveltekit",kitId:"frontend.sveltekit",aliases:["frontend.sveltekit","sveltekit","svelte-kit"],displayName:"SvelteKit",framework:"sveltekit",defaultPort:5173,versionPolicy:"latest-stable",commandDisplay:e=>`npx sv@latest create ${e}`,commandExec:(e,t)=>({command:"npx",args:["--yes","sv@latest","create",e,"--template","minimal","--types","ts","--no-add-ons",...t.skipInstall?["--no-install"]:["--install","npm"]]})}],D=new Map;for(let e of Y){D.set(e.id,e),D.set(e.kitId,e);for(let t of e.aliases)D.set(t.toLowerCase(),e);}function Ke(){return [...Y]}function j(e){return e?D.get(e.trim().toLowerCase())??null:null}function Ye(e){return !!j(e)}function ze(e){if(e[0]!=="create"||e[1]!=="frontend")return null;let t=e[2],n=e[3],o=e.slice(4),i=j(t);return i?["create","project",i.kitId,n??"",...o].filter(Boolean):["create","project",`frontend.${t??""}`,n??"",...o].filter(Boolean)}function z(e,t){return `workspai create project ${j(e)?.id??e.replace(/^frontend\./,"")} ${t}`}function X(e,t){return `npx ${z(e,t)}`}function de(e){let t=j(e);return t?`${z(t.id,"<name>")} [--output <dir>] [--skip-install] [--dry-run]`:"workspai create project <nextjs|remix|vite-react|vite-vue|vite-svelte|vite-solid|vite-vanilla|nuxt|angular|astro|sveltekit> <name> [--output <dir>] [--skip-install] [--dry-run]"}async function Xe(e){let t=e.args;if(t[0]!=="create"||t[1]!=="project")throw new Error("Frontend create expects normalized args: create project <frontend.kit> <name>");let n=j(t[2]);if(!n)throw new Error(`Unknown frontend generator: ${t[2]??"(missing)"}`);let o=t[3];if(!o)throw new Error(`Usage: ${de(n.id)}`);R(o);let i=ve(t,"--output")||process.cwd(),r=x.resolve(i,o),a=e.dryRun===true||t.includes("--dry-run"),c=t.includes("--skip-install"),l=t.includes("--skip-git")||t.includes("--no-git"),s=n.commandExec(o,{skipGit:l,skipInstall:c}),m=n.commandDisplay(o,{skipGit:l,skipInstall:c});if(await u.pathExists(r))throw new Error(`Directory "${r}" already exists`);if(a)return me({definition:n,projectName:o,projectPath:r,commandPlan:s}),{definition:n,projectName:o,projectPath:r,dryRun:a,commandDisplay:m,commandExec:[s.command,...s.args]};ue(n),await u.ensureDir(x.dirname(r));try{let v=await Q(s.command,s.args,x.dirname(r)),ne=await ye(r);if(v!==0)throw new Error(`Official ${n.displayName} generator failed with exit code ${v}`);if(!ne)throw new Error(`Official ${n.displayName} generator did not produce a valid package.json`);l||await ke(r),await pe({definition:n,projectName:o,projectPath:r,commandDisplay:m,commandExec:[s.command,...s.args],skipGit:l,skipInstall:c});}catch(v){throw await u.remove(r),v}return console.log(d.green(`\u2705 ${n.displayName} project created at ${r}`)),console.log(d.gray(` Display command: ${X(n.id,o)}`)),console.log(d.gray(" Next: cd "+o+" && npx workspai dev")),{definition:n,projectName:o,projectPath:r,dryRun:a,commandDisplay:m,commandExec:[s.command,...s.args]}}async function pe(e){let t=new Date().toISOString(),n=await h(),o=await O(e.projectPath,"latest"),i={schema_version:"1.0",name:e.projectName,slug:e.projectName,kind:"frontend",project_type:"frontend",category:"frontend",runtime:"node",framework:e.definition.framework,framework_display_name:e.definition.displayName,kit_name:e.definition.kitId,kit:e.definition.kitId,engine:"npm",support_tier:"extended",module_support:false,modules:[],workspai_version:n,rapidkit_version:n,generated_by:"workspai",generated_at:t,frontend:{generator:e.definition.id,official_generator:true,version_policy:e.definition.versionPolicy,version_evidence:o,default_port:e.definition.defaultPort,command_display:e.commandDisplay,command_exec:e.commandExec,skip_install:e.skipInstall,skip_git:e.skipGit},contracts:{owns:[],apis:[],publishes:[],consumes:[],dependsOn:[],env:[]}},r={project:e.projectName,runtime:"node",framework:e.definition.framework,kind:"frontend",category:"frontend",source:"official-generator"},a={kind:"workspai.frontend_create",schema_version:"1.0",generated_at:t,project:{name:e.projectName,path:e.projectPath,kind:"frontend",category:"frontend",runtime:"node",framework:e.definition.framework,framework_display_name:e.definition.displayName,kit_name:e.definition.kitId},generator:{id:e.definition.id,version_policy:e.definition.versionPolicy,version_evidence:o,command_display:e.commandDisplay,command_exec:e.commandExec}};for(let[c,l]of [["project.json",i],["context.json",r],["frontend-create.json",a]]){let s=v(e.projectPath,c);await u.ensureDir(x.dirname(s)),await u.writeJson(s,l,{spaces:2});}}function me(e){console.log(d.bold(`
101
- Workspai frontend create plan: ${e.definition.displayName}`)),console.log(d.gray(`Project: ${e.projectName}`)),console.log(d.gray(`Target: ${e.projectPath}`)),console.log(d.gray(`Show: ${X(e.definition.id,e.projectName)}`)),console.log(d.gray(`Run: ${[e.commandPlan.command,...e.commandPlan.args].join(" ")}`)),console.log(d.gray(`Default: http://localhost:${e.definition.defaultPort}`));}function fe(){let e=Number.parseInt(process.versions.node.split(".")[0]??"",10);return Number.isFinite(e)?e:0}function ue(e){if(!e.minNodeVersion&&!e.minNodeMajor||(e.minNodeVersion?ge(process.versions.node,e.minNodeVersion)>=0:fe()>=(e.minNodeMajor??0)))return;let n=e.minNodeVersion??`${e.minNodeMajor}+`;throw new Error(e.minNodeMessage??`${e.displayName} requires Node.js ${n} (current: ${process.versions.node}).`)}function ge(e,t){let n=e.split(".").map(r=>Number.parseInt(r,10)||0),o=t.split(".").map(r=>Number.parseInt(r,10)||0),i=Math.max(n.length,o.length);for(let r=0;r<i;r+=1){let a=(n[r]??0)-(o[r]??0);if(a!==0)return a}return 0}async function ye(e){if(!await u.pathExists(e))return false;let t=x.join(e,"package.json");if(!await u.pathExists(t))return false;try{let n=await u.readJson(t);return n!==null&&typeof n=="object"&&!Array.isArray(n)}catch{return false}}async function ke(e){let t=x.join(e,".git");if(await u.pathExists(t))return;if(await b(e)){console.log(d.gray(" Git initialization skipped; target is inside an existing git worktree."));return}if(await Q("git",["init"],e)===0){console.log(d.gray(" Git repository initialized."));return}console.log(d.yellow("\u26A0\uFE0F Git initialization was skipped or failed. You can run `git init` manually inside the project."));}async function Q(e$1,t,n){let o=e(e$1);return await new Promise(i=>{let r=spawn(o.command,[...o.prefixArgs,...t],{cwd:n,stdio:"inherit",shell:false,env:e$1==="git"?a(h$1()):h$1()});r.on("close",a=>i(a??1)),r.on("error",()=>i(1));})}function ve(e,t){let n=e.indexOf(t);if(n>=0&&n+1<e.length)return e[n+1];let o=e.find(i=>i.startsWith(`${t}=`));return o?o.slice(t.length+1):void 0}var te=[{id:"tauri",kitId:"desktop.tauri",aliases:["desktop.tauri","tauri","tauri-app"],displayName:"Tauri",category:"desktop",kind:"desktop",runtime:"node",runtimeCandidates:["node","rust"],framework:"tauri",supportTier:"extended",versionPolicy:"latest-stable",defaultPort:1420,officialSource:"create-tauri-app",supportsSkipInstall:true,requiredTools:[{command:"rustc",args:["--version"],label:"Rust toolchain",guidance:"Install the current stable Rust toolchain from https://rustup.rs/ and retry."},{command:"cargo",args:["--version"],label:"Cargo",guidance:"Install Cargo through the current stable Rust toolchain and retry."}],commandDisplay:e=>`npm create tauri-app@latest ${e} -- --manager npm --template vanilla-ts --yes`,commandExec:e=>({command:"npm",args:["create","tauri-app@latest",e,"--","--manager","npm","--template","vanilla-ts","--yes"]}),requiredArtifacts:["package.json","src-tauri/Cargo.toml","src-tauri/tauri.conf.json"]},{id:"electron",kitId:"desktop.electron",aliases:["desktop.electron","electron","electron-forge"],displayName:"Electron Forge",category:"desktop",kind:"desktop",runtime:"node",runtimeCandidates:["node"],framework:"electron",supportTier:"extended",versionPolicy:"latest-stable",officialSource:"create-electron-app",supportsSkipInstall:false,requiredTools:[{command:"git",args:["--version"],label:"Git",guidance:"Install Git and make it available on PATH, then retry."}],commandDisplay:e=>`npx create-electron-app@latest ${e} --template=vite-typescript`,commandExec:e=>({command:"npx",args:["--yes","create-electron-app@latest",e,"--template=vite-typescript"]}),requiredArtifacts:["package.json"]},{id:"vscode-extension",kitId:"extension.vscode",aliases:["extension.vscode","vscode","vscode-extension","visual-studio-code-extension"],displayName:"VS Code Extension",category:"extension",kind:"extension",runtime:"node",runtimeCandidates:["node"],framework:"vscode-extension",supportTier:"extended",versionPolicy:"latest-stable",officialSource:"generator-code",supportsSkipInstall:false,nodeSupport:{requirement:"^22.22.2 || ^24.15.0 || >=26.0.0",ranges:[{major:22,minVersion:"22.22.2"},{major:24,minVersion:"24.15.0"},{minVersion:"26.0.0"}],guidance:"Install Node.js 22.22.2+, 24.15.0+, or 26+ before running the latest stable VS Code Extension generator."},requiredTools:[{command:"git",args:["--version"],label:"Git",guidance:"Install Git to initialize source control, or create the project with --skip-git."}],commandDisplay:e=>`npx --package yo@latest --package generator-code@latest -- yo code ${e} --quick --extensionType ts --pkgManager npm --bundle esbuild`,commandExec:(e,t)=>({command:"npx",args:["--yes","--package","yo@latest","--package","generator-code@latest","--","yo","code",e,"--quick","--extensionType","ts","--extensionId",e,"--pkgManager","npm","--bundle","esbuild",`--gitInit=${t.skipGit?"false":"true"}`]}),requiredArtifacts:["package.json","src/extension.ts"]},{id:"laravel",kitId:"php.laravel",aliases:["php.laravel","laravel","php-laravel"],displayName:"Laravel",category:"backend",kind:"backend",runtime:"php",runtimeCandidates:["php","node"],framework:"laravel",supportTier:"extended",versionPolicy:"latest-stable",defaultPort:8e3,officialSource:"composer-create-project",supportsSkipInstall:false,requiredTools:[{command:"php",args:["--version"],label:"PHP",guidance:"Install a PHP version supported by the latest stable Laravel release and retry."},{command:"composer",args:["--version"],label:"Composer",guidance:"Install the latest stable Composer release and retry."}],recommendedTools:[{command:"npm",args:["--version"],label:"npm",guidance:"Install a supported Node.js LTS runtime when you want to build Laravel frontend assets."}],commandDisplay:e=>`composer create-project --no-interaction --prefer-dist --stability=stable laravel/laravel ${e}`,commandExec:e=>({command:"composer",args:["create-project","--no-interaction","--prefer-dist","--stability=stable","laravel/laravel",e]}),requiredArtifacts:["composer.json","artisan"]}],G=new Map;for(let e of te){G.set(e.id,e),G.set(e.kitId,e);for(let t of e.aliases)G.set(t.toLowerCase(),e);}function dt(){return [...te]}function C(e){return e?G.get(e.trim().toLowerCase())??null:null}function pt(e){return C(e)!==null}function he(e){return `workspai create project ${C(e)?.kitId??"<desktop.tauri|desktop.electron|extension.vscode|php.laravel>"} <name> [--output <dir>] [--skip-git] [--skip-install] [--dry-run]`}async function mt(e){if(e[0]!=="create"||e[1]!=="project")throw new Error("Official project create expects: create project <official.kit> <project-name>");let t=C(e[2]);if(!t)throw new Error(`Unknown official project generator: ${e[2]??"(missing)"}`);let n=e[3];if(!n)throw new Error(`Usage: ${he(t.kitId)}`);R(n);let o=Ee(e,"--output")||process.cwd(),i=x.resolve(o,n),r=e.includes("--dry-run"),a={skipGit:e.includes("--skip-git")||e.includes("--no-git"),skipInstall:e.includes("--skip-install")};if(a.skipInstall&&!t.supportsSkipInstall)throw new Error(`${t.displayName}'s official generator does not support --skip-install. Remove the flag so Workspai can verify the official scaffold.`);let c=t.commandExec(n,a),l=t.commandDisplay(n,a);if(await u.pathExists(i))throw new Error(`Directory "${i}" already exists`);if(r)return Ie(t,i,l,c),{definition:t,projectName:n,projectPath:i,dryRun:r,commandDisplay:l,commandExec:[c.command,...c.args]};be(t),await je(t,a),await u.ensureDir(x.dirname(i));try{let s=await Pe(c,x.dirname(i));if(s!==0)throw new Error(`Official ${t.displayName} generator failed with exit code ${s}`);await xe(t,i),a.skipGit&&await u.remove(x.join(i,".git")),await we({definition:t,projectName:n,projectPath:i,commandDisplay:l,commandExec:[c.command,...c.args],flags:a});}catch(s){throw await u.remove(i).catch(()=>{}),s}return console.log(d.green(`
102
- \u2713 ${t.displayName} scaffold ready`)),console.log(d.gray(` Location ${i}`)),console.log(d.gray(` Generator ${t.officialSource} \xB7 ${t.versionPolicy}`)),console.log(d.green(" \u2713 Required scaffold files verified")),console.log(d.green(" \u2713 Generator and version evidence recorded in .workspai/")),t.id==="vscode-extension"&&console.log(d.yellow(" Note Dependency warnings above come from the official generated project; Workspai keeps them visible for Doctor and CI.")),console.log(d.gray(` Next cd ${n} && npx workspai doctor project`)),{definition:t,projectName:n,projectPath:i,dryRun:r,commandDisplay:l,commandExec:[c.command,...c.args]}}async function xe(e,t){let n=[];for(let o of e.requiredArtifacts)await u.pathExists(x.join(t,o))||n.push(o);if(n.length>0)throw new Error(`Official ${e.displayName} generator did not produce required artifacts: ${n.join(", ")}`)}async function we(e){let t=new Date().toISOString(),n=h(),o=await O(e.projectPath,e.definition.id==="laravel"?"stable":"latest"),i={schema_version:"1.0",name:e.projectName,slug:e.projectName,kind:e.definition.kind,project_type:e.definition.category,category:e.definition.category,runtime:e.definition.runtime,runtime_candidates:e.definition.runtimeCandidates,framework:e.definition.framework,framework_display_name:e.definition.displayName,kit_name:e.definition.kitId,kit:e.definition.kitId,engine:"npm",support_tier:e.definition.supportTier,version_policy:e.definition.versionPolicy,module_support:false,modules:[],workspai_version:n,rapidkit_version:n,generated_by:"workspai",generated_at:t,generator:{id:e.definition.id,source:e.definition.officialSource,official:true,version_policy:e.definition.versionPolicy,version_evidence:o,command_display:e.commandDisplay,command_exec:e.commandExec,skip_install:e.flags.skipInstall,skip_git:e.flags.skipGit},...e.definition.defaultPort?{ports:[{name:"http",port:e.definition.defaultPort,protocol:"http"}]}:{},contracts:{owns:[],apis:[],publishes:[],consumes:[],dependsOn:[],env:[]}},r={engine:"npm",project:e.projectName,kind:e.definition.kind,category:e.definition.category,runtime:e.definition.runtime,runtimeCandidates:e.definition.runtimeCandidates,framework:e.definition.framework,source:"official-generator",versionPolicy:e.definition.versionPolicy},a={schema_version:"1.0",kind:"workspai.official_project_create",generated_at:t,project:{name:e.projectName,path:e.projectPath,kind:e.definition.kind,category:e.definition.category,runtime:e.definition.runtime,runtime_candidates:e.definition.runtimeCandidates,framework:e.definition.framework,kit_name:e.definition.kitId},generator:i.generator,verified_artifacts:e.definition.requiredArtifacts};for(let[c,l]of [["project.json",i],["context.json",r],["official-create.json",a]]){let s=v(e.projectPath,c);await u.ensureDir(x.dirname(s)),await u.writeJson(s,l,{spaces:2});}}async function Pe(e$1,t){let n=e(e$1.command);return await new Promise(o=>{let i=h$1(),r=spawn(n.command,[...n.prefixArgs,...e$1.args],{cwd:t,stdio:"inherit",shell:c()&&n.command===e$1.command&&n.prefixArgs.length===0,env:e$1.command==="git"?a({...i,...e$1.env}):{...i,...e$1.env}});r.on("close",a=>o(a??1)),r.on("error",()=>o(1));})}async function je(e,t){let n=e.id==="vscode-extension"&&t.skipGit?[]:[...e.requiredTools],o=e.id==="vscode-extension"&&t.skipGit?[]:e.recommendedTools??[],i=[],r=[];for(let a of n)await Z(a)||i.push(a);for(let a of o)await Z(a)||r.push(a);if(i.length>0){let a=i.map(c=>`- ${c.label}: ${c.guidance}`).join(`
103
- `);throw new Error(`${e.displayName} cannot use its latest stable official generator because required local tools are unavailable:
104
- ${a}`)}for(let a of r)console.warn(d.yellow(`\u26A0 ${a.label} was not found. ${a.guidance}`));}function be(e,t=process.versions.node){let n=e.nodeSupport;if(!n)return;let o=Number.parseInt(t.split(".")[0]??"",10);if(!n.ranges.some(r=>(r.major===void 0||r.major===o)&&Ne(t,r.minVersion)>=0))throw new Error(`${e.displayName} requires Node.js ${n.requirement} (current: ${t}). ${n.guidance}`)}function Ne(e,t){let n=e.split(".").map(r=>Number.parseInt(r,10)||0),o=t.split(".").map(r=>Number.parseInt(r,10)||0),i=Math.max(n.length,o.length);for(let r=0;r<i;r+=1){let a=(n[r]??0)-(o[r]??0);if(a!==0)return a}return 0}async function Z(e$1){let t=e(e$1.command);return await new Promise(n=>{let o=spawn(t.command,[...t.prefixArgs,...e$1.args],{stdio:"ignore",shell:c()&&t.command===e$1.command&&t.prefixArgs.length===0,env:h$1()}),i=false,r=setTimeout(()=>{i||(i=true,o.kill(),n(false));},5e3);o.on("close",a=>{i||(i=true,clearTimeout(r),n(a===0));}),o.on("error",()=>{i||(i=true,clearTimeout(r),n(false));});})}function Ie(e,t,n,o){console.log(d.bold(`
105
- Workspai ${e.category} create plan: ${e.displayName}`)),console.log(d.gray(`Category: ${e.category}`)),console.log(d.gray(`Runtime: ${e.runtimeCandidates.join(" + ")}`)),console.log(d.gray(`Version: ${e.versionPolicy}`)),console.log(d.gray(`Target: ${t}`)),console.log(d.gray(`Official: ${n}`)),console.log(d.gray(`Execute: ${[o.command,...o.args].join(" ")}`)),console.log(d.gray("Dry run: no files or workspace state will be changed."));}function Ee(e,t){let n=e.indexOf(t);if(n>=0&&n+1<e.length)return e[n+1];let o=e.find(i=>i.startsWith(`${t}=`));return o?o.slice(t.length+1):void 0}export{f as a,L as b,q as c,J as d,V as e,M as f,U as g,W as h,H as i,R as j,Ke as k,j as l,Ye as m,ze as n,de as o,Xe as p,dt as q,C as r,pt as s,he as t,mt as u};