workspai 0.50.0 → 0.51.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 (91) hide show
  1. package/README.md +126 -497
  2. package/contracts/create-planner-capabilities.v1.json +10 -1
  3. package/contracts/extension-cli-compatibility.v1.json +1 -1
  4. package/dist/analyze-4H33PAUB.js +1 -0
  5. package/dist/{artifact-remediation-plan-ICN3KOFG.js → artifact-remediation-plan-TQ6KTTXD.js} +1 -1
  6. package/dist/autopilot-release-BHZYM5KX.js +1 -0
  7. package/dist/chunk-3D2PAIRH.js +3 -0
  8. package/dist/{chunk-C35UXTDM.js → chunk-4WJC5QCD.js} +1 -1
  9. package/dist/{chunk-MV7KF75Q.js → chunk-6HLPTJZ3.js} +1 -1
  10. package/dist/{chunk-CV5HKU4P.js → chunk-7T4TSV5C.js} +1 -1
  11. package/dist/chunk-BBGNDMRU.js +2 -0
  12. package/dist/{chunk-VKTUWUS6.js → chunk-BG4FWJJ3.js} +1 -1
  13. package/dist/chunk-BYTFXQ6G.js +1 -0
  14. package/dist/chunk-DLM6C7FU.js +8 -0
  15. package/dist/chunk-E3CT7TYT.js +1 -0
  16. package/dist/chunk-EPVFKJF4.js +1 -0
  17. package/dist/{chunk-5EXZBCAZ.js → chunk-FKWB66NQ.js} +1 -1
  18. package/dist/{chunk-RTVRZFIJ.js → chunk-FZ76CF2W.js} +1 -1
  19. package/dist/{chunk-C3FLCDRN.js → chunk-GBAO4GSW.js} +1 -1
  20. package/dist/{chunk-AL2A7Q4X.js → chunk-GQRWRHSR.js} +31 -31
  21. package/dist/{chunk-BQGBU2Y3.js → chunk-HE4PUMU4.js} +1 -1
  22. package/dist/{chunk-KXG6E5VK.js → chunk-HMGPELXS.js} +1 -1
  23. package/dist/chunk-HSZCINFX.js +2 -0
  24. package/dist/chunk-L2E2Z4OE.js +5 -0
  25. package/dist/chunk-MAF3LLGK.js +691 -0
  26. package/dist/chunk-PS5F4DCT.js +1 -0
  27. package/dist/{chunk-LZQUZGXB.js → chunk-Q6TKQVKQ.js} +1 -1
  28. package/dist/chunk-TROHVI2V.js +2 -0
  29. package/dist/{chunk-IPJ5URDF.js → chunk-U2LR73E2.js} +1 -1
  30. package/dist/chunk-U2QL5733.js +36 -0
  31. package/dist/{chunk-DDQ3XK3H.js → chunk-VCW5HSPC.js} +2 -2
  32. package/dist/{chunk-6UTM5AJI.js → chunk-VU2BKKMB.js} +1 -1
  33. package/dist/chunk-WJVB6SSD.js +16 -0
  34. package/dist/{chunk-SS2VV3D5.js → chunk-XBM2P45G.js} +2 -2
  35. package/dist/{create-I23DC7SN.js → create-SBFBFXKN.js} +1 -1
  36. package/dist/{doctor-DOOMYLIH.js → doctor-OPCMTBJB.js} +1 -1
  37. package/dist/index.js +229 -229
  38. package/dist/{pipeline-U77HSINC.js → pipeline-7BUXAFS2.js} +1 -1
  39. package/dist/{project-test-coverage-4TEHZJFC.js → project-test-coverage-BALEHHTT.js} +1 -1
  40. package/dist/{workspace-ZEYUVR26.js → workspace-U6ZQLELX.js} +1 -1
  41. package/dist/{workspace-agent-sync-DKYJLUDP.js → workspace-agent-sync-L4SY7B4Q.js} +1 -1
  42. package/dist/workspace-context-KOBSLZTI.js +1 -0
  43. package/dist/{workspace-contract-PVLGPBBV.js → workspace-contract-SOD3OOVF.js} +1 -1
  44. package/dist/{workspace-explain-64HNKAHO.js → workspace-explain-2CTMW2YW.js} +1 -1
  45. package/dist/{workspace-feedback-RATRXFUC.js → workspace-feedback-ZZ4HPW2T.js} +1 -1
  46. package/dist/{workspace-foundation-D33LJLGT.js → workspace-foundation-PUIYBQUF.js} +1 -1
  47. package/dist/{workspace-graph-stream-THNG2T7R.js → workspace-graph-stream-BLKIC7VN.js} +1 -1
  48. package/dist/workspace-graph-token-efficiency-5FNH4JZ5.js +1 -0
  49. package/dist/{workspace-history-EWFPT74O.js → workspace-history-SPKNRHIX.js} +1 -1
  50. package/dist/{workspace-intelligence-MCNSWWDV.js → workspace-intelligence-I3ABOH2F.js} +1 -1
  51. package/dist/workspace-intelligence-runner-Q2XSR3ZL.js +1 -0
  52. package/dist/{workspace-knowledge-graph-2EYR7N56.js → workspace-knowledge-graph-5MKEI4Z5.js} +1 -1
  53. package/dist/{workspace-knowledge-graph-query-VOSPPH4W.js → workspace-knowledge-graph-query-EKHIE3E2.js} +1 -1
  54. package/dist/{workspace-mcp-serve-FLAVKWYW.js → workspace-mcp-serve-ETNUA72W.js} +1 -1
  55. package/dist/{workspace-model-FMFYLHE4.js → workspace-model-HHA37SNH.js} +1 -1
  56. package/dist/{workspace-onboarding-MYROZDI2.js → workspace-onboarding-ELHZABJE.js} +1 -1
  57. package/dist/workspace-readme-HGGZ4AZB.js +77 -0
  58. package/dist/{workspace-registry-summary-6VXIAQLX.js → workspace-registry-summary-D2QM5JF6.js} +1 -1
  59. package/dist/workspace-run-DAAZBCN7.js +1 -0
  60. package/dist/{workspace-verify-FKYI65UQ.js → workspace-verify-4WJTLXRA.js} +1 -1
  61. package/dist/{workspace-watch-RP5KMVP2.js → workspace-watch-2PIFTQ6B.js} +1 -1
  62. package/docs/README_CONTENT_CONTRACT.md +98 -124
  63. package/docs/ci-workflows.md +13 -4
  64. package/docs/commands-reference.md +4 -2
  65. package/docs/workspace-knowledge-graph.md +39 -0
  66. package/docs/workspace-operations.md +9 -6
  67. package/package.json +6 -3
  68. package/scripts/enterprise-package-smoke.mjs +11 -0
  69. package/templates/kits/fastapi-ddd/README.md.j2 +1 -1
  70. package/templates/kits/fastapi-standard/README.md.j2 +1 -1
  71. package/templates/kits/nestjs-standard/Dockerfile.j2 +1 -1
  72. package/templates/kits/nestjs-standard/README.md.j2 +1 -1
  73. package/templates/kits/nestjs-standard/package.json.j2 +11 -2
  74. package/dist/analyze-ZFQWTCJQ.js +0 -1
  75. package/dist/autopilot-release-VKXQ7BS7.js +0 -1
  76. package/dist/chunk-2AXEGYPL.js +0 -1
  77. package/dist/chunk-GNQRYISX.js +0 -5
  78. package/dist/chunk-I42F552T.js +0 -2
  79. package/dist/chunk-IDQKVJUF.js +0 -2
  80. package/dist/chunk-JFUD73OZ.js +0 -933
  81. package/dist/chunk-KKAOTTYO.js +0 -8
  82. package/dist/chunk-KMLPHFLD.js +0 -2
  83. package/dist/chunk-L2YK5RV2.js +0 -1
  84. package/dist/chunk-LAJM2SBP.js +0 -15
  85. package/dist/chunk-UETZ7USY.js +0 -36
  86. package/dist/chunk-WDKNMTJQ.js +0 -1
  87. package/dist/chunk-YPKNQCLK.js +0 -2
  88. package/dist/workspace-context-IHUFMZT3.js +0 -1
  89. package/dist/workspace-graph-token-efficiency-CFGFCJ5V.js +0 -1
  90. package/dist/workspace-intelligence-runner-TG2VLHNZ.js +0 -1
  91. package/dist/workspace-run-2ZI5UMJ2.js +0 -1
@@ -0,0 +1,691 @@
1
+ import {f,e as e$1,g as g$1}from'./chunk-4WJC5QCD.js';import {b as b$2}from'./chunk-KVSYBHUR.js';import {b as b$6,a as a$3}from'./chunk-THIOE2PB.js';import {b as b$3}from'./chunk-E3CT7TYT.js';import {a as a$2}from'./chunk-U2LR73E2.js';import {e,g,f as f$2,b as b$5,c as c$2,d as d$2}from'./chunk-WJVB6SSD.js';import {d,b as b$1}from'./chunk-Y5YAP4F3.js';import {g as g$2}from'./chunk-BBGNDMRU.js';import {i,f as f$1,c as c$1,e as e$2}from'./chunk-VRW6KXNK.js';import {a as a$1}from'./chunk-TQEMLBAG.js';import {b,a,c,d as d$1}from'./chunk-MOSXTVPU.js';import {b as b$4,k,j,m,i as i$1,t,s,q as q$1}from'./chunk-RJIYCDVC.js';import {promises}from'fs';import*as P from'fs-extra';import p from'path';import r from'chalk';import {execa}from'execa';function st(e){let n=e.projectCount??0,t=n===1?"project":"projects",a=e.pythonEngine==="installed"?`Python ${e.pythonVersion||"3.10+"} \xB7 ${e.installMethod||"local environment"}`:e.pythonEngine==="skipped"?"Python engine not installed":"Runtime-neutral foundation";return ["","\u2713 Workspace ready",`${e.workspaceName} \xB7 ${e.profile} \xB7 ${n} registered ${t}`,`Location ${e.workspacePath}`,`Runtime ${a}`,...e.note?[`Note ${e.note}`]:[],"","Workspace Intelligence"," \u2713 Contract and project registry"," \u2713 Canonical model and proof-backed graph"," \u2713 Agent context, grounding, and evidence index","","Next",` ${g$1(e.workspacePath)}`," npx workspai create"," npx workspai workspace intelligence run --for-agent generic --strict --json","","Evidence .workspai/reports/INDEX.json","Guide README.md",""]}function q(e){let n=st(e);for(let t of n)t==="\u2713 Workspace ready"?console.log(r.green.bold(t)):t==="Workspace Intelligence"||t==="Next"?console.log(r.cyan.bold(t)):t.startsWith(" \u2713")?console.log(r.green(t)):t.startsWith("Location")||t.startsWith("Runtime")?console.log(r.gray(t)):console.log(t);}function M(){return i$1()}var lt="transactions";function ct(){return p.join(q$1(),lt)}async function Ve(){let e=ct();return await b$6(e),a$3({journalDirectory:e})}async function Ge(e){for(let n of s())await e.captureFile(n);}async function ae(e){let n=await Ve();try{return await Ge(n),await n.captureOwnedTree(e),n}catch(t){return K(n,t)}}async function pt(e){let n=await Ve();try{await Ge(n),await n.captureOwnedTree(p.join(e,a)),await n.captureOwnedTree(p.join(e,".venv"));let t=[c,".gitignore",p.join(a,"workspace.json"),p.join(a,"toolchain.lock"),p.join(a,"policies.yml"),p.join(a,"cache-config.yml"),g$2,a$2,"pyproject.toml","poetry.toml","poetry.lock","rapidkit","rapidkit.cmd","README.md",".rapidkit-global"];for(let a of t)await n.captureFile(p.join(e,a));return n}catch(t){return K(n,t)}}async function z(e){await e.commit(),e.journalPath&&await promises.rm(p.dirname(e.journalPath),{recursive:true,force:true}).catch(n=>f$1.debug(`Could not remove committed lifecycle journal: ${n}`));}async function K(e,n){try{await e.rollback();}catch(t){throw new AggregateError([n,t],"Workspace lifecycle failed and rollback was incomplete.")}throw n}async function B(e,n,t,a,s){let l=d(n,i(),t,s?.pythonEngine?{coreStatus:s.pythonEngine,...s.pythonEngineReason?{coreReason:s.pythonEngineReason}:{},...a?{pythonVersion:a}:{}}:void 0);a&&!s?.pythonEngine&&(l.metadata||(l.metadata={}),l.metadata.python={pythonVersion:a}),await b$1(e,l);}async function G(e){await P.outputFile(p.join(e,".gitignore"),`.venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .env
5
+ ${d$1}
6
+ ${b}/
7
+
8
+ `,"utf-8");}async function He(e){try{let n=await execa("git",["rev-parse","--show-toplevel"],{cwd:e,env:a$1()});return n.stdout.trim()?p.resolve(e,n.stdout.trim()):null}catch{return null}}async function J(e,n,t){if(await He(e)){n.warn("Git initialization skipped because target is already inside a git worktree");return}n.start("Initializing git repository");try{await execa("git",["init"],{cwd:e,env:a$1()}),await execa("git",["add","."],{cwd:e,env:a$1()}),await execa("git",["-c","user.name=Workspai","-c","user.email=workspai@localhost","commit","-m",t],{cwd:e,env:a$1()}),n.succeed("Git repository initialized");}catch{n.warn("Could not initialize git repository");}}async function Ue(e,n){let t=n.replace(/[^a-z0-9-]/gi,"-").toLowerCase();await P.outputFile(p.join(e,"poetry.toml"),`[virtualenvs]
9
+ in-project = true
10
+ `,"utf-8"),await P.outputFile(p.join(e,"pyproject.toml"),`[tool.poetry]
11
+ name = "${t}"
12
+ version = "0.1.0"
13
+ description = "Workspai workspace"
14
+ authors = []
15
+ package-mode = false
16
+
17
+ [tool.poetry.dependencies]
18
+ python = "^3.10"
19
+ rapidkit-core = "*"
20
+
21
+ [build-system]
22
+ requires = ["poetry-core"]
23
+ build-backend = "poetry.core.masonry.api"
24
+ `,"utf-8");}function Ye(e,n,t,a,s){return JSON.stringify({schema_version:"1.0",workspace_name:e,workspai_version:i(),rapidkit_version:i(),created_at:new Date().toISOString(),created_by:"workspai",profile:a||"minimal",...s?.profileRequested?{profile_requested:s.profileRequested}:{},...s?.bootstrapNote?{bootstrap_note:s.bootstrapNote}:{},engine:{install_method:n,python_version:t||null,...s?.pythonEngine?{python_core:{status:s.pythonEngine,...s.pythonEngineReason?{reason:s.pythonEngineReason}:{}}}:{}}},null,2)}function qe(e,n,t,a,s,l){return JSON.stringify({schema_version:"1.0",generated_by:"workspai",generated_at:new Date().toISOString(),runtime:{python:{version:n||null,install_method:e,...l?.pythonEngine?{core:{status:l.pythonEngine,...l.pythonEngineReason?{reason:l.pythonEngineReason}:{}}}:{}},node:{version:t||process.version},go:{version:a||null},java:{version:null,build_tool:null,build_tool_version:null},dotnet:{version:s||null,sdk:s||null}}},null,2)}function ze(){return `version: "1.0"
25
+ mode: warn # "warn" or "strict"
26
+ dependency_sharing_mode: isolated # "isolated" or "shared-runtime-caches" or "shared-node-deps"
27
+ # change profile (recommended): npx workspai bootstrap --profile polyglot
28
+ # change mode/dependency manually: edit this file and rerun npx workspai init
29
+ rules:
30
+ enforce_workspace_marker: true
31
+ enforce_toolchain_lock: false
32
+ disallow_untrusted_tool_sources: false
33
+ `}function Be(){return `version: "1.0"
34
+ cache:
35
+ strategy: shared # "shared" or "on-demand"
36
+ prune_on_bootstrap: false
37
+ self_heal: true
38
+ verify_integrity: false
39
+ `}async function Je(){try{let{stdout:e}=await execa("go",["version"],{timeout:3e3,stdio:"pipe"}),n=e.match(/go(\d+\.\d+(?:\.\d+)?)/i);return n?n[1]:void 0}catch{return}}async function Qe(){try{let{stdout:e}=await execa("dotnet",["--version"],{timeout:3e3,stdio:"pipe"}),n=e.trim();return n.length>0?n:void 0}catch{return}}async function Q(e,n,t,a$1,s,l){let[d,y]=await Promise.all([Je(),Qe()]),c=[{fileName:"workspace.json",content:Ye(n,t,a$1,s,l)},{fileName:"toolchain.lock",content:qe(t,a$1,process.version,d,y,l)},{fileName:"policies.yml",content:ze()},{fileName:"cache-config.yml",content:Be()}];for(let g of c)await P.outputFile(p.join(e,a,g.fileName),g.content,"utf-8");}async function Xt(e,n){let{workspaceName:t=p.basename(e),installMethod:a$1="venv",pythonVersion:s,profile:l,writeMarker:d$1=true,writeGitignore:y=true,onlyIfMissing:c$1=true}=n||{},g=[],[m,h]=await Promise.all([Je(),Qe()]),i$1=[{relPath:p.join(a,"workspace.json"),legacyRelPath:p.join(b,"workspace.json"),content:Ye(t,a$1,s,l)},{relPath:p.join(a,"toolchain.lock"),legacyRelPath:p.join(b,"toolchain.lock"),content:qe(a$1,s,process.version,m,h)},{relPath:p.join(a,"policies.yml"),legacyRelPath:p.join(b,"policies.yml"),content:ze()},{relPath:p.join(a,"cache-config.yml"),legacyRelPath:p.join(b,"cache-config.yml"),content:Be()}];for(let o of i$1){let w=p.join(e,o.relPath),k=p.join(e,o.legacyRelPath),S=await P.pathExists(w),I=await P.pathExists(k);c$1&&S||(c$1&&I?(await P.copy(k,w),g.push(o.relPath)):(await P.outputFile(w,o.content,"utf-8"),g.push(o.relPath)));}if(d$1&&(!await P.pathExists(p.join(e,c))||!c$1)){let w=d(t,i(),a$1);s&&(w.metadata||(w.metadata={}),w.metadata.python={pythonVersion:s}),await b$1(e,w),g.push(c);}if(y){let o=p.join(e,".gitignore");(!c$1||!await P.pathExists(o))&&(await G(e),g.push(".gitignore"));}return g}var Xe=new Set(["go-only","java-only","dotnet-only","node-only","minimal"]),dt={"python-only":"minimal",polyglot:"node-only",enterprise:"polyglot"};function ut(e){let n=e,t=new Set;for(;!Xe.has(n);){if(t.has(n))return "minimal";t.add(n);let a=dt[n];if(!a)return "minimal";n=a;}return n}var V="3.10",Ze=["3.10","3.11","3.12"];async function We(e){try{let{stdout:n}=await execa(e,["--version"],{timeout:3e3}),t=n.match(/Python (\d+\.\d+\.\d+)/);if(t)return t[1]}catch{}return null}async function mt(e,n){try{await promises.writeFile(p.join(e,".python-version"),`${n}
40
+ `,"utf-8"),f$1.debug(`Created .python-version with ${n}`);}catch(t){f$1.warn(`Failed to create .python-version: ${t}`);}}function Z(){let t$1=[...(process.env.PATH||"").split(p.delimiter).filter(Boolean)];for(let a of t())t$1.includes(a)||t$1.unshift(a);process.env.PATH=t$1.join(p.delimiter);}async function me(e,n){Z(),e.start("Checking pipx installation");try{return await execa("pipx",["--version"]),e.succeed("pipx found"),{kind:"binary"}}catch{}let t=M();try{return await execa(t,["-m","pipx","--version"]),e.succeed("pipx found"),{kind:"python-module",pythonCmd:t}}catch{}if(n)throw new d$2;e.stop?.();let{installPipx:a}=await b$2([{type:"confirm",name:"installPipx",message:"pipx is not installed. Install it now (user install via python -m pip)?",default:true}]);if(!a)throw new d$2;e.start("Installing pipx (user install)");try{try{await execa(t,["-m","pip","install","--user","--upgrade","pip"]);}catch{}await execa(t,["-m","pip","install","--user","--upgrade","pipx"]);}catch(s){let l=s,d=String(l?.stderr||l?.shortMessage||l?.message||"");throw new f$2("Install pipx with python -m pip",s instanceof Error?s:new Error(d))}e.succeed("pipx installed"),Z();try{return await execa(t,["-m","pipx","--version"]),{kind:"python-module",pythonCmd:t}}catch(s){let l=s,d=String(l?.stderr||l?.shortMessage||l?.message||"pipx not runnable after install");throw new f$2("Verify pipx after install",new Error(`${d}
41
+
42
+ Try reopening your terminal or run: ${t} -m pipx ensurepath`))}}async function H(e,n){return e.kind==="binary"?execa("pipx",n):execa(e.pythonCmd,["-m","pipx",...n])}function yt(e){let n=e.match(/^(\d+)\.(\d+)/);return n?`${n[1]}.${n[2]}`:null}function Le(e){if(!e)return null;let n=e.match(/Python\s+(\d+)\.(\d+)(?:\.\d+)?/i);return n?`${n[1]}.${n[2]}`:null}function be(e,n){let[t,a]=e.split(".").map(d=>Number(d)),[s,l]=n.split(".").map(d=>Number(d));return t!==s?t-s:a-l}function X(e,n){return be(e,n)>=0}async function gt(e){let n=new Set,t=k(14,10);for(let h of t)try{let i=await execa(h.command,h.args,{timeout:2500}),o=Le(`${i.stdout||""}
43
+ ${i.stderr||""}`);o&&X(o,V)&&n.add(o);}catch{}let a=null;try{let h=await execa(M(),["--version"],{timeout:2500}),i=Le(`${h.stdout||""}
44
+ ${h.stderr||""}`);i&&X(i,V)&&(a=i,n.add(i));}catch{}let s=Ze.filter(h=>X(h,V)),l=new Set([...s,...n]),d=Array.from(l).sort((h,i)=>be(i,h)),y=e?yt(e):null,c=y&&X(y,V)?y:a||d[0]||V;return l.has(c)||l.add(c),{choices:Array.from(l).sort((h,i)=>be(i,h)).map(h=>{let i=[];return h===a&&i.push("current system"),h===V&&i.push("minimum supported"),n.has(h)&&h!==a&&i.push("detected"),{name:i.length>0?`${h} (${i.join(", ")})`:h,value:h}}),defaultValue:c}}async function ht(){Z();let e=false,n=false;try{await execa("poetry",["--version"],{timeout:2500}),e=true;}catch{e=false;}try{await execa("pipx",["--version"],{timeout:2500}),n=true;}catch{let t=i$1();try{await execa(t,["-m","pipx","--version"],{timeout:2500}),n=true;}catch{n=false;}}return {poetry:e,pipx:n}}async function et(){Z();try{return await execa("poetry",["--version"],{timeout:2500}),true}catch{return false}}function ft(e,n){return e==="poetry"&&n.poetry?"poetry":e==="pipx"&&n.pipx?"pipx":e==="venv"?"venv":n.poetry?"poetry":"venv"}async function wt(e,n){Z(),e.start("Checking Poetry installation");try{await execa("poetry",["--version"]),e.succeed("Poetry found");return}catch{}if(n)throw new c$2;let{installPoetry:t}=await b$2([{type:"confirm",name:"installPoetry",message:"Poetry is not installed. Install it now using pipx?",default:true}]);if(!t)throw new c$2;let a=await me(e,n);e.start("Installing Poetry with pipx");try{await H(a,["install","poetry"]);}catch(s){let l=s,d=String(l?.stderr||l?.shortMessage||l?.message||"");if(/already\s+installed|already\s+seems\s+to\s+be\s+installed|exists/i.test(d))try{await H(a,["upgrade","poetry"]);}catch{}else throw new f$2("Install Poetry with pipx",s instanceof Error?s:new Error(d))}e.succeed("Poetry installed"),Z();try{await execa("poetry",["--version"]);}catch(s){let l=s,d=String(l?.stderr||l?.shortMessage||l?.message||"Poetry not found on PATH");throw new f$2("Verify Poetry after pipx install",new Error(`${d}
45
+
46
+ Poetry may be installed but not on PATH yet. Try reopening your terminal or run: pipx ensurepath`))}}function vt(e,n={}){let t=e==="poetry",a=n.pythonEngineSkipped?`echo "- Python engine installation was intentionally skipped for this workspace." 1>&2
47
+ echo "- For npm-owned workspace commands, run: npx workspai <command>" 1>&2
48
+ echo "- To install the local Python engine later, create a RapidKit Core module-enabled project, then run: npx workspai workspace run init" 1>&2
49
+ `:`echo "- If you used venv: ensure .venv exists (or re-run the installer)." 1>&2
50
+ `;return `#!/usr/bin/env sh
51
+ set -eu
52
+
53
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
54
+
55
+ VENV_RAPIDKIT="$SCRIPT_DIR/.venv/bin/rapidkit"
56
+ if [ -x "$VENV_RAPIDKIT" ]; then
57
+ exec "$VENV_RAPIDKIT" "$@"
58
+ fi
59
+
60
+ ${t?`if command -v poetry >/dev/null 2>&1 && [ -f "$SCRIPT_DIR/pyproject.toml" ]; then
61
+ exec poetry run rapidkit "$@"
62
+ fi
63
+
64
+ `:""}if command -v rapidkit >/dev/null 2>&1; then
65
+ RAPIDKIT_CMD=$(command -v rapidkit)
66
+ if [ "$RAPIDKIT_CMD" != "$SCRIPT_DIR/rapidkit" ] && [ "$RAPIDKIT_CMD" != "$SCRIPT_DIR/.workspai/rapidkit" ] && [ "$RAPIDKIT_CMD" != "$SCRIPT_DIR/.rapidkit/rapidkit" ]; then
67
+ RAPIDKIT_LOCAL_LAUNCHER_BYPASS=1 exec "$RAPIDKIT_CMD" "$@"
68
+ fi
69
+ fi
70
+
71
+ for RAPIDKIT_CORE in "$HOME/.local/bin/rapidkit" "$HOME/Library/Python/3.14/bin/rapidkit" "$HOME/Library/Python/3.13/bin/rapidkit" "$HOME/Library/Python/3.12/bin/rapidkit" "$HOME/Library/Python/3.11/bin/rapidkit" "$HOME/Library/Python/3.10/bin/rapidkit"; do
72
+ if [ -x "$RAPIDKIT_CORE" ]; then
73
+ exec "$RAPIDKIT_CORE" "$@"
74
+ fi
75
+ done
76
+
77
+ echo "RapidKit launcher could not find a local Python CLI." 1>&2
78
+ ${a}${n.pythonEngineSkipped?"":t?`echo "- If you used Poetry: run 'poetry install' and retry, or activate the env." 1>&2
79
+ `:""}${n.pythonEngineSkipped?`echo "Tip: use 'npx workspai workspace model --json' for Workspace Intelligence without the Python engine." 1>&2
80
+ `:`echo "Tip: you can also run: ./.venv/bin/rapidkit --help" 1>&2
81
+ `}exit 1
82
+ `}function kt(e,n={}){let t=e==="poetry",a=n.pythonEngineSkipped?`echo - Python engine installation was intentionally skipped for this workspace. 1>&2
83
+ echo - For npm-owned workspace commands, run: npx workspai ^<command^> 1>&2
84
+ echo - To install the local Python engine later, create a RapidKit Core module-enabled project, then run: npx workspai workspace run init 1>&2
85
+ `:`echo Tip: run .venv\\Scripts\\rapidkit.exe --help 1>&2
86
+ `;return `@echo off
87
+ setlocal
88
+
89
+ set "SCRIPT_DIR=%~dp0"
90
+
91
+ if exist "%SCRIPT_DIR%\\.venv\\Scripts\\rapidkit.exe" (
92
+ "%SCRIPT_DIR%\\.venv\\Scripts\\rapidkit.exe" %*
93
+ exit /b %ERRORLEVEL%
94
+ )
95
+
96
+ ${t?`where poetry >nul 2>nul
97
+ if %ERRORLEVEL%==0 if exist "%SCRIPT_DIR%\\pyproject.toml" (
98
+ poetry run rapidkit %*
99
+ exit /b %ERRORLEVEL%
100
+ )
101
+
102
+ `:""}:rapidkit_npm_wrapper_fallback
103
+ for /f "delims=" %%R in ('where rapidkit.cmd 2^>nul') do (
104
+ if /I not "%%~fR"=="%SCRIPT_DIR%rapidkit.cmd" if /I not "%%~fR"=="%SCRIPT_DIR%.workspai\\rapidkit.cmd" if /I not "%%~fR"=="%SCRIPT_DIR%.rapidkit\\rapidkit.cmd" (
105
+ set "RAPIDKIT_LOCAL_LAUNCHER_BYPASS=1"
106
+ "%%~fR" %*
107
+ exit /b %ERRORLEVEL%
108
+ )
109
+ )
110
+
111
+ :rapidkit_core_fallback
112
+ for %%R in ("%USERPROFILE%\\.local\\bin\\rapidkit.exe" "%APPDATA%\\Python\\Scripts\\rapidkit.exe" "%LOCALAPPDATA%\\Programs\\Python\\Scripts\\rapidkit.exe") do (
113
+ if exist "%%~R" (
114
+ "%%~R" %*
115
+ exit /b %ERRORLEVEL%
116
+ )
117
+ )
118
+
119
+ echo RapidKit launcher could not find a local Python CLI. 1>&2
120
+ ${a}echo Tip: for npm-owned workspace commands, run npx --yes --package workspai workspai %* from a shell where npm is on PATH. 1>&2
121
+ exit /b 1
122
+ `}async function ue(e,n,t={}){await P.outputFile(p.join(e,"rapidkit"),vt(n,t),{encoding:"utf-8",mode:493}),await P.outputFile(p.join(e,"rapidkit.cmd"),kt(n,t),"utf-8");}async function Zt(e$1,n){let{skipGit:t=false,skipPythonEngine:a=false,testMode:s=false,demoMode:l=false,dryRun:d=false,yes:y=false,userConfig:c={},installMethod:g,profile:m,parentDirectory:h}=n,i=e$1||"rapidkit",o=h?p.resolve(h,i):p.resolve(process.cwd(),i);if(await P.pathExists(o))throw new e(i);if(await f(o),d){let f=m||(y?"minimal":void 0),_=g||c.defaultInstallMethod||"poetry",R=c.pythonVersion||"3.10";await bt(o,i,l,c,f,_,R,t,a);return}if(l){await Pt(o,i,t);return}let w=new Set(["python-only","polyglot","enterprise"]),k=m||"";if(!y&&!m){let{selectedProfile:f}=await b$2([{type:"rawlist",name:"selectedProfile",message:"Select workspace profile:",choices:[{name:"minimal \u2014 Foundation files only (fastest bootstrap, mixed projects)",value:"minimal"},{name:"java-only \u2014 Java runtime (Spring Boot services)",value:"java-only"},{name:"python-only \u2014 Python + Poetry (FastAPI, Django, ML pipelines)",value:"python-only"},{name:"node-only \u2014 Node.js runtime (NestJS, Express, Next.js)",value:"node-only"},{name:"go-only \u2014 Go runtime (Fiber, Gin, gRPC, microservices)",value:"go-only"},{name:"dotnet-only \u2014 .NET runtime (ASP.NET Core services)",value:"dotnet-only"},{name:"polyglot \u2014 Python + Node.js + Go + Java + .NET multi-runtime workspace",value:"polyglot"},{name:"enterprise \u2014 Polyglot + governance + Sigstore verification",value:"enterprise"}],default:1}]);k=f;}else k||(k="minimal");let S=!y&&w.has(k),I=w.has(k)?a?"skip":S?(await b$2([{type:"confirm",name:"installPythonEngine",message:"Install the optional RapidKit Python engine now? (needed for Python-backed kits/modules)",default:true}])).installPythonEngine!==false?"install":"skip":"install":"skip",U=S&&I==="install",ye=typeof c.pythonVersion=="string"&&c.pythonVersion.trim().length>0?c.pythonVersion.trim():void 0,it=g||c.defaultInstallMethod||"poetry",ge=U?await ht():{poetry:true,pipx:true},Ie=U?await gt(ye):{choices:Ze.map(f=>({name:f,value:f})),defaultValue:V},at=ft(it,ge),rt=[{name:ge.poetry?"\u{1F3AF} Poetry (Recommended - includes virtual env + dependency mgmt)":"\u{1F3AF} Poetry (Recommended) \u2014 not detected (we can install it)",value:"poetry"},{name:"\u{1F4E6} pip with venv (Standard, zero extra tools)",value:"venv"},{name:ge.pipx?"\u{1F527} pipx (Global isolated - RapidKit Core only, no local venv)":"\u{1F527} pipx (Global isolated) \u2014 not detected (we can install it)",value:"pipx"}],x=U?await b$2([{type:"rawlist",name:"pythonVersion",message:"Select Python version for RapidKit:",choices:Ie.choices,default:Ie.defaultValue},{type:"rawlist",name:"installMethod",message:"How would you like to manage the workspace environment?",choices:rt,default:at}]):await(async()=>{if(I==="skip")return {pythonVersion:c.pythonVersion||"3.10",installMethod:"venv"};let f=g||c.defaultInstallMethod||await(async()=>{try{return await execa("poetry",["--version"],{timeout:3e3}),"poetry"}catch{return f$1.warn("Poetry not found \u2014 auto-selecting venv. Pass --install-method poetry to override."),"venv"}})();return {pythonVersion:c.pythonVersion||"3.10",installMethod:f}})(),he=Xe;if(he.has(k)){let f=c$1("Creating workspace",{component:"create",phase:"workspace.python-free"}),_=await ae(o);try{await P.ensureDir(o),f.succeed("Directory created"),await B(o,i,"venv",void 0),await Q(o,i,"venv",void 0,k),await G(o);let R=await b$3(o,{workspaceName:i,silent:true});await z(_),t||await J(o,f,"Initial commit: Workspai workspace"),q({workspaceName:i,workspacePath:o,profile:k,projectCount:R?.projectCount??0});}catch(R){return f.fail("Failed to create workspace"),console.error(r.red(`
123
+ \u274C Error:`),R),K(_,R)}return}if(w.has(k)&&I==="skip"){let f=c$1("Creating workspace",{component:"create",phase:"workspace.python-engine-skipped"}),_=await ae(o);try{await P.ensureDir(o),f.succeed("Directory created");let R={bootstrapNote:"python-engine-skipped",pythonEngine:"skipped",pythonEngineReason:"user-opted-out"};await B(o,i,"venv",void 0,R),await Q(o,i,"venv",void 0,k,R),await G(o),await ue(o,"venv",{pythonEngineSkipped:true});let b=await b$3(o,{workspaceName:i,silent:true});await z(_),t||await J(o,f,`Initial commit: Workspai workspace (${k})`),q({workspaceName:i,workspacePath:o,profile:k,projectCount:b?.projectCount??0,pythonEngine:"skipped",note:"Install the optional Python engine later only when a Python-backed kit needs it."});return}catch(R){return f.fail("Failed to create workspace"),console.error(r.red(`
124
+ \u274C Error:`),R),K(_,R)}}{let f=M(),_=false;try{await execa(f,["--version"],{timeout:5e3}),_=true;}catch{try{await execa("python",["--version"],{timeout:5e3}),_=true;}catch{_=false;}}if(!_){let R=k,b=ut(k);if(S&&!y){console.log(r.yellow(`
125
+ \u26A0\uFE0F Python 3.10+ is not detected on this system.
126
+ `)),console.log(r.cyan(`You have 3 options:
127
+ `));let{pythonAction:T}=await b$2([{type:"rawlist",name:"pythonAction",message:"What would you like to do?",choices:[{name:"\u{1F4E5} Install Python now (I'll show you the command for your OS)",value:"install"},{name:`\u{1F504} Switch to "${b}" profile (no Python required)`,value:"fallback"},{name:"\u274C Cancel and install Python manually",value:"cancel"}]}]);if(T==="cancel"&&(console.log(r.cyan(`
128
+ \u{1F4A1} How to install Python:
129
+ `)),console.log(r.white(" Ubuntu / Debian: sudo apt install python3.10")),console.log(r.white(" macOS (Homebrew): brew install python@3.10")),console.log(r.white(` Windows: https://python.org/downloads
130
+ `)),console.log(r.gray(` After installing Python, run: npx workspai ${i}
131
+ `)),process.exit(1)),T==="install"){console.log(r.cyan(`
132
+ \u{1F4A1} Install Python on your system:
133
+ `));let A=process.platform;A==="linux"?console.log(r.white(` sudo apt update && sudo apt install python3.10 python3.10-venv
134
+ `)):A==="darwin"?console.log(r.white(` brew install python@3.10
135
+ `)):A==="win32"&&(console.log(r.white(` Download: https://python.org/downloads
136
+ `)),console.log(r.white(` Run the installer and check "Add Python to PATH"
137
+ `))),console.log(r.gray(` After installing, run: npx workspai ${i}
138
+ `)),process.exit(0);}if(T==="fallback"&&(console.log(r.green(`
139
+ \u2705 Switching to "${b}" profile (no Python required).
140
+ `)),k=b,he.has(b))){let A=c$1("Creating workspace",{component:"create",phase:"workspace.python-free"}),F=await ae(o);try{await P.ensureDir(o),A.succeed("Directory created"),await B(o,i,"venv",void 0),await Q(o,i,"venv",void 0,b,{profileRequested:R,bootstrapNote:"python-free-fallback"}),await G(o);let re=await b$3(o,{workspaceName:i,silent:true});await z(F),t||await J(o,A,`Initial commit: Workspai workspace (${b} profile)`),q({workspaceName:i,workspacePath:o,profile:b,projectCount:re?.projectCount??0,note:`Requested ${R}; used ${b} because Python was unavailable.`});return}catch(re){return A.fail("Failed to create workspace"),console.error(r.red(`
141
+ \u274C Error:`),re),K(F,re)}}}else if(console.log(r.yellow(`
142
+ \u26A0\uFE0F Python not detected. Auto-switching to "${b}" profile (no Python required).
143
+ `)),k=b,he.has(b)){let T=c$1("Creating workspace",{component:"create",phase:"workspace.python-free"}),A=await ae(o);try{await P.ensureDir(o),T.succeed("Directory created"),await B(o,i,"venv",void 0),await Q(o,i,"venv",void 0,b,{profileRequested:R,bootstrapNote:"python-free-fallback"}),await G(o);let F=await b$3(o,{workspaceName:i,silent:true});await z(A),t||await J(o,T,`Initial commit: Workspai workspace (${b})`),q({workspaceName:i,workspacePath:o,profile:b,projectCount:F?.projectCount??0,note:`Requested ${R}; used ${b} because Python was unavailable.`});return}catch(F){return T.fail("Failed to create workspace"),console.error(r.red(`
144
+ \u274C Error:`),F),K(A,F)}}}}let E=c$1("Creating directory",{component:"create",phase:"workspace.directory"}),xe=await ae(o);try{await P.ensureDir(o),E.succeed("Directory created"),E.start("Detecting Python version");let f=null,_=await tt(x.pythonVersion);if(_)f=await We(_),f?(f$1.info(` Detected Python ${f}`),E.succeed(`Python ${f} detected`)):E.warn("Could not detect exact Python version");else {let b=M();f=await We(b),f?E.succeed(`Python ${f} detected`):E.warn("Could not detect Python version, proceeding with defaults");}if(x.installMethod==="poetry"&&!await et()&&(E.warn("Poetry not found \u2014 auto-fallback to pip + venv"),x.installMethod="venv"),await B(o,i,x.installMethod,f||void 0),f&&await mt(o,f),await Q(o,i,x.installMethod,f||x.pythonVersion,k||m),await G(o),await Ue(o,i),x.installMethod==="poetry")try{await nt(o,x.pythonVersion,E,s,c,y);}catch(b){let ee=b?.details||b?.message||String(b);if(ee.includes("pyenv")||ee.includes("exit status 127")||ee.includes("returned non-zero exit status 127")){E.warn("Poetry encountered Python discovery issues, trying venv method"),f$1.debug(`Poetry error (attempting venv fallback): ${ee}`);try{await Re(o,x.pythonVersion,E,s,c),x.installMethod="venv";}catch(A){throw A}}else throw b}else x.installMethod==="venv"?await Re(o,x.pythonVersion,E,s,c):await ot(o,E,s,c,y);await ue(o,x.installMethod),E.succeed("Workspai environment ready!");let R=await b$3(o,{workspaceName:i,silent:true});await z(xe),n.skipGit||await J(o,E,"Initial commit: Workspai environment"),q({workspaceName:i,workspacePath:o,profile:k,projectCount:R?.projectCount??0,pythonEngine:"installed",pythonVersion:x.pythonVersion,installMethod:x.installMethod});}catch(f){return E.fail("Failed to create Workspai environment"),console.error(r.red(`
145
+ \u274C Error:`),f),K(xe,f)}}async function tt(e){let n=[];if(!b$4())try{let{stdout:l}=await execa("pyenv",["which","python"]),d=l.trim();d&&n.push(d);}catch{}let t=Number(e.split(".")[1]),a=k(t,10).map(l=>l.command).filter(Boolean);n.push(`python${e}`,...a,...j());let s=[...new Set(n)];for(let l of s)try{let d=l==="py"?["-3","--version"]:["--version"],y=l==="py"?["-3","-c","import sys; sys.exit(0)"]:["-c","import sys; sys.exit(0)"],{stdout:c}=await execa(l,d,{timeout:2e3}),g=c.match(/Python (\d+\.\d+)/)?.[1];if(g&&X(g,e))return await execa(l,y,{timeout:2e3}),l}catch{continue}return null}async function nt(e,n,t,a,s,l=false){await wt(t,l),t.start("Finding Python interpreter");let d=await tt(n);d?(f$1.debug(`Found working Python: ${d}`),t.succeed("Python found")):t.warn("Could not verify Python path, proceeding with default"),t.start("Initializing Poetry project");let y=p.join(e,"pyproject.toml"),g$1=(await P.pathExists(y)?await promises.readFile(y,"utf-8"):"").includes("rapidkit-core");if(g$1)t.succeed("Poetry project initialized");else {await execa("poetry",["init","--no-interaction","--python",`^${n}`],{cwd:e}),t.succeed("Poetry project initialized");let o=await promises.readFile(y,"utf-8");o.includes("[tool.poetry]")?o=o.replace("[tool.poetry]",`[tool.poetry]
146
+ package-mode = false`):o.includes("[project]")&&(o.includes("[build-system]")?o=o.replace("[build-system]",`
147
+ [tool.poetry]
148
+ package-mode = false
149
+
150
+ [build-system]`):o+=`
151
+
152
+ [tool.poetry]
153
+ package-mode = false
154
+ `),await promises.writeFile(y,o,"utf-8");}t.start("Configuring Poetry");try{await execa("poetry",["config","virtualenvs.in-project","true","--local"],{cwd:e}),t.succeed("Poetry configured");}catch{t.warn("Could not configure Poetry virtualenvs.in-project");}t.start("Creating virtualenv");let m$1=d||M(),h=m(p.join(e,".venv"));try{await execa(m$1,["-m","venv",".venv"],{cwd:e,timeout:6e4}),t.succeed("Virtualenv created");}catch(i){f$1.debug(`python -m venv failed: ${i}`),t.warn("Could not pre-create virtualenv, Poetry will try"),h=d||M();}try{await execa("poetry",["env","use",h||M()],{cwd:e}),f$1.debug(`Poetry env set to: ${h}`);}catch(i){f$1.debug(`Could not set Poetry env: ${i}`);}if(t.start("Installing RapidKit"),g$1&&!a){let i=e$1(s||{}),o=i?await P.pathExists(i):false,w=o&&i?i:"rapidkit-core";i&&!o&&f$1.warn(`WORKSPAI_DEV_PATH/RAPIDKIT_DEV_PATH points to a path that does not exist: ${i}. Falling back to PyPI.`),t.text=o?"Installing RapidKit from local path":"Installing RapidKit from PyPI";let k=false,S=null;for(let I=1;I<=3;I++)try{o||e$2({status:"started",message:"Installing RapidKit from PyPI",installMethod:"poetry",attempt:I,maxAttempts:3}),await execa(h,["-m","pip","install",w,"--quiet"],{cwd:e,timeout:18e4}),k=true,o||e$2({status:"succeeded",message:"RapidKit installed from PyPI",installMethod:"poetry",attempt:I,maxAttempts:3});break}catch(U){S=U,f$1.debug(`pip install rapidkit-core attempt ${I} failed: ${U}`),I<3&&(t.text=`Retrying installation (attempt ${I+1}/3)`,await new Promise(ye=>setTimeout(ye,2e3)));}if(!k){let I=S?.stderr||S?.message||"Unknown error";throw f$1.debug(`All pip install attempts failed. Last error: ${I}`),I.includes("Could not find")||I.includes("No matching distribution")?new g:new f$2("Install rapidkit-core with pip",new Error(`Failed to install rapidkit-core after 3 attempts.
155
+ Error: ${I}
156
+
157
+ Possible solutions:
158
+ 1. Check your internet connection
159
+ 2. Try installing manually: cd ${p.basename(e)} && poetry add rapidkit-core
160
+ 3. Use venv method instead: npx workspai ${p.basename(e)} --install-method=venv`))}}else {t.text="Syncing Poetry environment";try{await execa("poetry",["install","--no-root"],{cwd:e,timeout:12e4}),t.succeed("Poetry environment synced");}catch(i){f$1.debug(`poetry install --no-root failed: ${i}`),t.warn("Could not sync Poetry environment, proceeding with add command");}if(t.start("Installing RapidKit"),a){let i=e$1(s||{});if(!i)throw new f$2("Test mode installation",new Error("No local RapidKit path configured. Set WORKSPAI_DEV_PATH (or legacy RAPIDKIT_DEV_PATH)."));f$1.debug(`Installing from local path: ${i}`),t.text="Installing RapidKit from local path (test mode)",await execa("poetry",["add",i],{cwd:e});}else {t.text="Installing RapidKit from PyPI";let i=false,o=null;for(let w=1;w<=3;w++)try{e$2({status:"started",message:"Installing RapidKit from PyPI",installMethod:"poetry",attempt:w,maxAttempts:3}),await execa("poetry",["add","rapidkit-core"],{cwd:e,timeout:6e4*w}),i=true,e$2({status:"succeeded",message:"RapidKit installed from PyPI",installMethod:"poetry",attempt:w,maxAttempts:3});break}catch(k){o=k,f$1.debug(`Poetry add attempt ${w} failed: ${k}`),w<3&&(t.text=`Retrying installation (attempt ${w+1}/3)`,await new Promise(S=>setTimeout(S,2e3)));}if(!i){let w=o?.stderr||o?.message||"Unknown error";throw f$1.debug(`All Poetry install attempts failed. Last error: ${w}`),w.includes("Could not find")||w.includes("No matching distribution")?new g:new f$2("Install rapidkit-core with Poetry",new Error(`Failed to install rapidkit-core after 3 attempts.
161
+ Error: ${w}
162
+
163
+ Possible solutions:
164
+ 1. Check your internet connection
165
+ 2. Try installing manually: cd ${p.basename(e)} && poetry add rapidkit-core
166
+ 3. Use venv method instead: npx workspai ${p.basename(e)} --install-method=venv`))}}}t.succeed("RapidKit installed in project virtualenv");try{let{checkRapidkitCoreAvailable:i}=await import('./pythonRapidkitExec-YR7P5LWG.js');if(!await i()&&!a){t.start("Checking optional global pipx installation");let w=await me(t,true);try{t.start("Installing RapidKit globally with pipx for CLI access"),await H(w,["install","rapidkit-core"]),t.succeed("RapidKit installed globally");}catch(k){t.warn("Could not install globally (non-fatal, project virtualenv has RapidKit)"),f$1.debug(`pipx install failed: ${k}`);}}}catch(i){t.succeed("Skipped optional global pipx installation"),f$1.debug(`Global install check skipped: ${i}`);}}async function Re(e,n,t,a,s,l=false){t.start(`Checking Python ${n}`);let d=M();try{let{stdout:c}=await execa(d,["--version"]),g=c.match(/Python (\d+\.\d+)/)?.[1];if(g&&!X(g,n))throw new b$5(n,g);t.succeed(`Python ${g} found`);}catch(c){throw c instanceof b$5?c:new b$5(n)}t.start("Creating virtual environment");try{await execa(d,["-m","venv",".venv"],{cwd:e}),t.succeed("Virtual environment created");}catch(c){if(t.fail("Failed to create virtual environment"),(m=>typeof m=="object"&&m!==null&&"stdout"in m&&typeof m.stdout=="string")(c)&&c.stdout.includes("ensurepip is not")){let m=c.stdout.match(/apt install (python[\d.]+-venv)/),h=m?m[1]:"python3-venv";throw new f$2("Python venv module not available",new Error(`Virtual environment creation failed.
167
+
168
+ On Debian/Ubuntu systems, install the venv package:
169
+ sudo apt install ${h}
170
+
171
+ Or use Poetry instead (recommended):
172
+ npx workspai create workspace ${p.basename(e)} --yes --install-method poetry`))}throw new f$2("Virtual environment creation",c instanceof Error?c:new Error(String(c)))}t.start("Installing RapidKit");let y=m(p.join(e,".venv"));if(await execa(y,["-m","pip","install","--upgrade","pip"],{cwd:e}),a){let c=e$1(s||{});if(!c)throw new f$2("Test mode installation",new Error("No local RapidKit path configured. Set WORKSPAI_DEV_PATH (or legacy RAPIDKIT_DEV_PATH)."));f$1.debug(`Installing from local path: ${c}`),t.text="Installing RapidKit from local path (test mode)",await execa(y,["-m","pip","install","-e",c],{cwd:e});}else {t.text="Installing RapidKit from PyPI";let c=false,g$1=null;for(let m=1;m<=3;m++)try{e$2({status:"started",message:"Installing RapidKit from PyPI",installMethod:"venv",attempt:m,maxAttempts:3}),await execa(y,["-m","pip","install","rapidkit-core"],{cwd:e,timeout:6e4*m}),c=true,e$2({status:"succeeded",message:"RapidKit installed from PyPI",installMethod:"venv",attempt:m,maxAttempts:3});break}catch(h){g$1=h,f$1.debug(`pip install attempt ${m} failed: ${h}`),m<3&&(t.text=`Retrying installation (attempt ${m+1}/3)`,await new Promise(i=>setTimeout(i,2e3)));}if(!c){let m$1=g$1?.stderr||g$1?.message||"Unknown error";throw f$1.debug(`All pip install attempts failed. Last error: ${m$1}`),m$1.includes("Could not find")||m$1.includes("No matching distribution")?new g:new f$2("Install rapidkit-core with pip",new Error(`Failed to install rapidkit-core after 3 attempts.
173
+ Error: ${m$1}
174
+
175
+ Possible solutions:
176
+ 1. Check your internet connection
177
+ 2. Try installing manually: cd ${p.basename(e)} && ${m(".venv")} -m pip install rapidkit-core
178
+ 3. Use Poetry instead: npx workspai ${p.basename(e)} --install-method=poetry`))}}t.succeed("RapidKit installed in project virtualenv");try{let{checkRapidkitCoreAvailable:c}=await import('./pythonRapidkitExec-YR7P5LWG.js');if(!await c()&&!a){t.start("Checking optional global pipx installation");let m=await me(t,true);try{t.start("Installing RapidKit globally with pipx for CLI access"),await H(m,["install","rapidkit-core"]),t.succeed("RapidKit installed globally");}catch(h){t.warn("Could not install globally (non-fatal, project virtualenv has RapidKit)"),f$1.debug(`pipx install failed: ${h}`);}}}catch(c){t.succeed("Skipped optional global pipx installation"),f$1.debug(`Global install check skipped: ${c}`);}}async function ot(e,n,t,a,s=false){if(!t)try{let{checkRapidkitCoreVersionCompatible:d}=await import('./pythonRapidkitExec-YR7P5LWG.js'),y=await d();if(y.isCompatible){n.succeed(`RapidKit ${y.installedVersion??""} already compatible globally; skipping pipx installation`),await P.outputFile(p.join(e,".rapidkit-global"),`RapidKit already available globally (version ${y.installedVersion??"unknown"}) and satisfies expected constraint ${y.expectedConstraint??"n/a"}; workspace will reuse the existing installation
179
+ `,"utf-8");return}y.reason==="constraint-missing"?n.warn('Version-aware global reuse skipped: no explicit rapidkit-core version constraint found. Set RAPIDKIT_CORE_PYTHON_PACKAGE (example: RAPIDKIT_CORE_PYTHON_PACKAGE="rapidkit-core>=0.4.0,<0.9.0") to enable version-aware reuse. Proceeding with pipx install/upgrade.'):y.reason==="constraint-unsupported"&&n.warn('Version-aware global reuse skipped: RAPIDKIT_CORE_PYTHON_PACKAGE uses an unsupported spec (path/url/git). Use a version range instead (example: RAPIDKIT_CORE_PYTHON_PACKAGE="rapidkit-core==0.4.0" or "rapidkit-core>=0.4.0,<0.9.0"). Proceeding with pipx install/upgrade.'),f$1.debug(`Global RapidKit install is not reusable via version-aware policy (reason=${y.reason}, installed=${y.installedVersion??"unknown"}, expected=${y.expectedConstraint??"none"}). Proceeding with pipx install/upgrade.`);}catch(d){f$1.debug(`Global RapidKit version-aware check failed before pipx install: ${d}`);}let l=await me(n,s);if(n.start("Installing RapidKit globally with pipx"),t){let d=e$1(a||{});if(!d)throw new f$2("Test mode installation",new Error("No local RapidKit path configured. Set WORKSPAI_DEV_PATH (or legacy RAPIDKIT_DEV_PATH)."));f$1.debug(`Installing from local path: ${d}`),n.text="Installing RapidKit from local path (test mode)",await H(l,["install","-e",d]);}else {n.text="Installing RapidKit from PyPI",e$2({status:"started",message:"Installing RapidKit from PyPI",installMethod:"pipx"});try{await H(l,["install","rapidkit-core"]),e$2({status:"succeeded",message:"RapidKit installed from PyPI",installMethod:"pipx"});}catch(d){try{n.text="RapidKit already installed globally, upgrading to match expected version",await H(l,["upgrade","rapidkit-core"]),e$2({status:"succeeded",message:"RapidKit upgraded from PyPI",installMethod:"pipx"});}catch(y){throw f$1.debug(`pipx install/upgrade failed: install=${d}, upgrade=${y}`),new g}}}n.succeed("RapidKit installed globally"),await P.outputFile(p.join(e,".rapidkit-global"),`RapidKit installed globally with pipx
180
+ `,"utf-8");}async function en(e,n){let{skipGit:t=false,installPythonEngine:a=false,testMode:s=false,userConfig:l={},yes:d=false,installMethod:y,pythonVersion:c="3.10"}=n||{},g="venv";if(a){let i=y||l.defaultInstallMethod||await(async()=>{try{return await execa("poetry",["--version"],{timeout:3e3}),"poetry"}catch{return f$1.warn("Poetry not found \u2014 auto-selecting venv. Pass --install-method poetry to override."),"venv"}})();g=i==="poetry"&&!await et()?"venv":i;}let m=c$1("Registering workspace",{component:"create",phase:"workspace.register"}),h=await pt(e);try{let i=p.basename(e),o=a?void 0:{bootstrapNote:"python-engine-skipped",pythonEngine:"skipped",pythonEngineReason:"project-workspace-foundation"};await B(e,i,g,a?c:void 0,o),await G(e),await Q(e,i,g,a?c:void 0,n?.profile??"minimal",o),a?g==="poetry"?(await Ue(e,i),await nt(e,c,m,s,l,d)):g==="venv"?await Re(e,c,m,s,l):await ot(e,m,s,l,d):await ue(e,g,{pythonEngineSkipped:true}),a&&await ue(e,g),m.succeed(a?"Workspace registered":"Workspace registered (Python engine skipped)"),await b$3(e,{workspaceName:p.basename(e),silent:s}),await z(h),t||await J(e,m,"Initial commit: Workspai workspace");}catch(i){return m.fail("Failed to register workspace"),K(h,i)}}async function Pt(e,n,t){let a=c$1("Creating demo workspace",{component:"create",phase:"workspace.demo"});try{await P.ensureDir(e),a.succeed("Directory created"),a.start("Setting up demo kit generator");let s=JSON.stringify({name:`${n}-workspace`,version:"1.0.0",private:true,description:"Workspai demo workspace",scripts:{generate:"node generate-demo.js"}},null,2);await promises.writeFile(p.join(e,"package.json"),s,"utf-8"),await promises.writeFile(p.join(e,"generate-demo.js"),`#!/usr/bin/env node
181
+ /**
182
+ * Demo Kit Generator - Create FastAPI demo projects
183
+ *
184
+ * This workspace contains bundled Workspai templates that you can use
185
+ * to generate demo projects without installing Python RapidKit Core.
186
+ *
187
+ * Usage:
188
+ * npm run generate <project-name>
189
+ * node generate-demo.js <project-name>
190
+ *
191
+ * Example:
192
+ * npm run generate my-api
193
+ */
194
+
195
+ const fs = require('fs');
196
+ const path = require('path');
197
+ const readline = require('readline');
198
+
199
+ const projectName = process.argv[2];
200
+
201
+ if (!projectName) {
202
+ console.error('\\n\u274C Please provide a project name');
203
+ console.log('\\nUsage: npm run generate <project-name>\\n');
204
+ console.log('Example: npm run generate my-api\\n');
205
+ process.exit(1);
206
+ }
207
+
208
+ const rl = readline.createInterface({
209
+ input: process.stdin,
210
+ output: process.stdout
211
+ });
212
+
213
+ function ask(question, defaultValue) {
214
+ return new Promise((resolve) => {
215
+ rl.question(\`\${question} (\${defaultValue}): \`, (answer) => {
216
+ resolve(answer || defaultValue);
217
+ });
218
+ });
219
+ }
220
+
221
+ async function main() {
222
+ const targetPath = path.join(process.cwd(), projectName);
223
+
224
+ if (fs.existsSync(targetPath)) {
225
+ console.error(\`\\n\u274C Directory "\${projectName}" already exists\\n\`);
226
+ process.exit(1);
227
+ }
228
+
229
+ console.log(\`\\n\u{1F680} Creating FastAPI project: \${projectName}\\n\`);
230
+
231
+ const snakeName = projectName.replace(/-/g, '_').toLowerCase();
232
+ const project_name = await ask('Project name (snake_case)', snakeName);
233
+ const author = await ask('Author name', process.env.USER || 'Workspai User');
234
+ const description = await ask('Description', 'FastAPI service generated with Workspai');
235
+
236
+ rl.close();
237
+
238
+ // Create project structure
239
+ const dirs = [
240
+ '',
241
+ 'src',
242
+ 'src/routing',
243
+ 'src/modules',
244
+ 'tests',
245
+ '.workspai'
246
+ ];
247
+
248
+ for (const dir of dirs) {
249
+ fs.mkdirSync(path.join(targetPath, dir), { recursive: true });
250
+ }
251
+
252
+ // Template files with content
253
+ const files = {
254
+ 'src/__init__.py': '"""' + project_name + ' package."""\\n',
255
+ 'src/modules/__init__.py': '"""Modules package."""\\n',
256
+ 'tests/__init__.py': '"""Tests package."""\\n',
257
+ 'src/main.py': \`"""\${project_name} application entrypoint."""
258
+
259
+ from __future__ import annotations
260
+
261
+ from contextlib import asynccontextmanager
262
+ from typing import AsyncIterator
263
+
264
+ from fastapi import FastAPI
265
+ from fastapi.middleware.cors import CORSMiddleware
266
+
267
+ from .routing import api_router
268
+
269
+
270
+ @asynccontextmanager
271
+ async def lifespan(app: FastAPI) -> AsyncIterator[None]:
272
+ """Application lifespan context manager for startup/shutdown events."""
273
+ yield
274
+
275
+
276
+ app = FastAPI(
277
+ title="\${project_name}",
278
+ description="\${description}",
279
+ version="0.1.0",
280
+ docs_url="/docs",
281
+ redoc_url="/redoc",
282
+ lifespan=lifespan,
283
+ )
284
+
285
+ app.add_middleware(
286
+ CORSMiddleware,
287
+ allow_origins=["*"],
288
+ allow_credentials=True,
289
+ allow_methods=["*"],
290
+ allow_headers=["*"],
291
+ )
292
+
293
+ app.include_router(api_router, prefix="/api")
294
+
295
+
296
+ if __name__ == "__main__":
297
+ import uvicorn
298
+ uvicorn.run("src.main:app", host="0.0.0.0", port=8001, reload=True)
299
+ \`,
300
+ 'src/routing/__init__.py': \`"""API routing configuration."""
301
+
302
+ from fastapi import APIRouter
303
+
304
+ from .health import router as health_router
305
+
306
+ api_router = APIRouter()
307
+
308
+ api_router.include_router(health_router)
309
+ \`,
310
+ 'src/routing/health.py': \`"""Health check endpoints."""
311
+
312
+ from __future__ import annotations
313
+
314
+ from fastapi import APIRouter
315
+
316
+ router = APIRouter(prefix="/health", tags=["health"])
317
+
318
+
319
+ @router.get("/", summary="Health check")
320
+ async def heartbeat() -> dict[str, str]:
321
+ """Return basic service heartbeat."""
322
+ return {"status": "ok"}
323
+ \`,
324
+ 'src/cli.py': \`"""CLI commands for \${project_name}."""
325
+
326
+ import subprocess
327
+ import sys
328
+ from pathlib import Path
329
+
330
+
331
+ def dev():
332
+ """Start development server with hot reload."""
333
+ print("\u{1F680} Starting development server...")
334
+ subprocess.run([
335
+ sys.executable, "-m", "uvicorn",
336
+ "src.main:app", "--reload",
337
+ "--host", "0.0.0.0", "--port", "8000"
338
+ ])
339
+
340
+
341
+ def start():
342
+ """Start production server."""
343
+ print("\u26A1 Starting production server...")
344
+ subprocess.run([
345
+ sys.executable, "-m", "uvicorn",
346
+ "src.main:app",
347
+ "--host", "0.0.0.0", "--port", "8000"
348
+ ])
349
+
350
+
351
+ def test():
352
+ """Run tests."""
353
+ print("\u{1F9EA} Running tests...")
354
+ subprocess.run([sys.executable, "-m", "pytest", "-q"])
355
+
356
+
357
+ if __name__ == "__main__":
358
+ if len(sys.argv) < 2:
359
+ print("Usage: python -m src.cli <command>")
360
+ print("Commands: dev, start, test")
361
+ sys.exit(1)
362
+
363
+ cmd = sys.argv[1]
364
+ if cmd == "dev":
365
+ dev()
366
+ elif cmd == "start":
367
+ start()
368
+ elif cmd == "test":
369
+ test()
370
+ else:
371
+ print(f"Unknown command: {cmd}")
372
+ sys.exit(1)
373
+ \`,
374
+ 'pyproject.toml': \`[tool.poetry]
375
+ name = "\${project_name}"
376
+ version = "0.1.0"
377
+ description = "\${description}"
378
+ authors = ["\${author}"]
379
+ license = "MIT"
380
+ readme = "README.md"
381
+ package-mode = false
382
+
383
+ [tool.poetry.dependencies]
384
+ python = "^3.10"
385
+ fastapi = "^0.128.0"
386
+ uvicorn = {extras = ["standard"], version = "^0.40.0"}
387
+ pydantic = "^2.12.5"
388
+ pydantic-settings = "^2.12.0"
389
+
390
+ [tool.poetry.group.dev.dependencies]
391
+ pytest = "^9.0.2"
392
+ pytest-asyncio = "^1.3.0"
393
+ pytest-cov = "^7.0.0"
394
+ httpx = "^0.28.1"
395
+ black = "^25.12.0"
396
+ ruff = "^0.14.10"
397
+ mypy = "^1.19.1"
398
+
399
+ [tool.poetry.scripts]
400
+ dev = "src.cli:dev"
401
+ start = "src.cli:start"
402
+ test = "src.cli:test"
403
+
404
+ [build-system]
405
+ requires = ["poetry-core"]
406
+ build-backend = "poetry.core.masonry.api"
407
+
408
+ [tool.pytest.ini_options]
409
+ asyncio_mode = "auto"
410
+ testpaths = ["tests"]
411
+
412
+ [tool.ruff]
413
+ line-length = 100
414
+ target-version = "py311"
415
+
416
+ [tool.black]
417
+ line-length = 100
418
+ target-version = ["py311"]
419
+ \`,
420
+ 'README.md': \`# \${project_name}
421
+
422
+ \${description}
423
+
424
+ ## Quick start
425
+
426
+ \\\`\\\`\\\`bash
427
+ npx workspai init # Install dependencies
428
+ npx workspai dev # Start dev server
429
+ \\\`\\\`\\\`
430
+
431
+ ## Available commands
432
+
433
+ \\\`\\\`\\\`bash
434
+ npx workspai init # \u{1F527} Install dependencies
435
+ npx workspai dev # \u{1F680} Start development server with hot reload
436
+ npx workspai start # \u26A1 Start production server
437
+ npx workspai test # \u{1F9EA} Run tests
438
+ npx workspai help # \u{1F4DA} Show available commands
439
+ \\\`\\\`\\\`
440
+
441
+ ## Project layout
442
+
443
+ \\\`\\\`\\\`
444
+ \${project_name}/
445
+ \u251C\u2500\u2500 src/
446
+ \u2502 \u251C\u2500\u2500 main.py # FastAPI application
447
+ \u2502 \u251C\u2500\u2500 cli.py # CLI commands
448
+ \u2502 \u251C\u2500\u2500 routing/ # API routes
449
+ \u2502 \u2514\u2500\u2500 modules/ # Module system
450
+ \u251C\u2500\u2500 tests/ # Test suite
451
+ \u251C\u2500\u2500 pyproject.toml # Poetry configuration
452
+ \u2514\u2500\u2500 README.md
453
+ \\\`\\\`\\\`
454
+ \`,
455
+ '.workspai/project.json': JSON.stringify({
456
+ kit_name: "fastapi.standard",
457
+ profile: "fastapi/standard",
458
+ created_at: new Date().toISOString(),
459
+ created_by: "workspai-cli-fallback",
460
+ workspai_version: "npm-demo",
461
+ rapidkit_version: "npm-demo"
462
+ }, null, 2),
463
+ '.workspai/cli.py': \`#!/usr/bin/env python3
464
+ """RapidKit Core wrapper for demo projects."""
465
+
466
+ import subprocess
467
+ import sys
468
+ from pathlib import Path
469
+
470
+
471
+ def dev(port=8000, host="0.0.0.0"):
472
+ """Start development server."""
473
+ print("\u{1F680} Starting development server with hot reload...")
474
+ subprocess.run([
475
+ sys.executable, "-m", "uvicorn",
476
+ "src.main:app", "--reload",
477
+ "--host", host, "--port", str(port)
478
+ ])
479
+
480
+
481
+ def start(port=8000, host="0.0.0.0"):
482
+ """Start production server."""
483
+ print("\u26A1 Starting production server...")
484
+ subprocess.run([
485
+ sys.executable, "-m", "uvicorn",
486
+ "src.main:app",
487
+ "--host", host, "--port", str(port)
488
+ ])
489
+
490
+
491
+ def init():
492
+ """Install dependencies."""
493
+ print("\u{1F4E6} Installing dependencies...")
494
+ subprocess.run(["poetry", "install"])
495
+
496
+
497
+ def test():
498
+ """Run tests."""
499
+ print("\u{1F9EA} Running tests...")
500
+ subprocess.run([sys.executable, "-m", "pytest", "-q"])
501
+
502
+
503
+ def help_cmd():
504
+ """Show help."""
505
+ print("\u{1F4DA} Available commands:")
506
+ print(" init - Install dependencies")
507
+ print(" dev - Start dev server")
508
+ print(" start - Start production server")
509
+ print(" test - Run tests")
510
+
511
+
512
+ if __name__ == "__main__":
513
+ cmd = sys.argv[1] if len(sys.argv) > 1 else "help"
514
+ cmds = {"dev": dev, "start": start, "init": init, "test": test, "help": help_cmd}
515
+ cmds.get(cmd, help_cmd)()
516
+ \`,
517
+ '.workspai/rapidkit': '#!/usr/bin/env bash\\n# Local RapidKit Core launcher for demo projects\\nset -euo pipefail\\nSCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"\\nROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"\\ncd "$ROOT_DIR"\\n\\nif [ -f "pyproject.toml" ]; then\\n if command -v poetry >/dev/null 2>&1; then\\n exec poetry run python "$SCRIPT_DIR/cli.py" "$@"\\n fi\\nfi\\n\\necho "Poetry not found. Install with: pip install poetry"\\nexit 1\\n',
518
+ '.gitignore': \`# Python
519
+ __pycache__/
520
+ *.py[cod]
521
+ *.so
522
+ .Python
523
+ build/
524
+ dist/
525
+ *.egg-info/
526
+
527
+ # Virtual environments
528
+ .venv/
529
+ venv/
530
+
531
+ # IDEs
532
+ .vscode/
533
+ .idea/
534
+
535
+ # OS
536
+ .DS_Store
537
+
538
+ # Project
539
+ .env
540
+ .env.local
541
+ \`
542
+ };
543
+
544
+ for (const [filePath, content] of Object.entries(files)) {
545
+ fs.writeFileSync(path.join(targetPath, filePath), content);
546
+ }
547
+
548
+ // Make scripts executable
549
+ try {
550
+ fs.chmodSync(path.join(targetPath, '.workspai/cli.py'), 0o755);
551
+ fs.chmodSync(path.join(targetPath, '.workspai/rapidkit'), 0o755);
552
+ } catch (e) {
553
+ // Ignore on Windows
554
+ }
555
+
556
+ console.log(\`
557
+ \u2728 Demo project created successfully!
558
+
559
+ \u{1F4C2} Project: \${targetPath}
560
+
561
+ \u{1F680} Get started:
562
+ cd \${projectName}
563
+ npx workspai init # Install dependencies
564
+ npx workspai dev # Start dev server
565
+
566
+ \u{1F4DA} Available commands:
567
+ npx workspai init # \u{1F527} Install dependencies
568
+ npx workspai dev # \u{1F680} Start dev server with hot reload
569
+ npx workspai start # \u26A1 Start production server
570
+ npx workspai test # \u{1F9EA} Run tests
571
+ npx workspai help # \u{1F4DA} Show help
572
+
573
+ \u{1F4A1} For Python engine features: pipx install rapidkit-core
574
+ \`);
575
+ }
576
+
577
+ main().catch(console.error);
578
+ `,"utf-8");try{await execa("chmod",["+x",p.join(e,"generate-demo.js")]);}catch{}let d=`# Workspai Demo Workspace
579
+
580
+ Welcome to your Workspai demo workspace! This environment lets you generate FastAPI demo projects using bundled Workspai templates, without needing to install Python RapidKit Core.
581
+
582
+ ## \u{1F680} Quick Start
583
+
584
+ ### Generate Your First Demo Project
585
+
586
+ \`\`\`bash
587
+ # Generate a demo project:
588
+ node generate-demo.js my-api
589
+
590
+ # Navigate to the project:
591
+ cd my-api
592
+
593
+ # Install dependencies:
594
+ workspai init
595
+
596
+ # Run the development server:
597
+ workspai dev
598
+ \`\`\`
599
+
600
+ Your API will be available at \`http://localhost:8000\`
601
+
602
+ ## \u{1F4E6} Generate Multiple Projects
603
+
604
+ You can create multiple demo projects in this workspace:
605
+
606
+ \`\`\`bash
607
+ node generate-demo.js api-service
608
+ node generate-demo.js auth-service
609
+ node generate-demo.js data-service
610
+ \`\`\`
611
+
612
+ Each project is independent and has its own dependencies.
613
+
614
+ ## \u{1F3AF} What's Included
615
+
616
+ Each generated demo project contains:
617
+
618
+ - **FastAPI Application** - Modern async web framework
619
+ - **Routing System** - Organized API routes
620
+ - **Module System** - Extensible module architecture
621
+ - **CLI Commands** - Built-in command system
622
+ - **Testing Setup** - pytest configuration
623
+ - **Poetry Configuration** - Dependency management
624
+
625
+ ## \u{1F4DA} Next Steps
626
+
627
+ 1. **Explore the Generated Code** - Check out \`src/main.py\` and \`src/routing/\`
628
+ 2. **Add Routes** - Create new endpoints in \`src/routing/\`
629
+ 3. **Install RapidKit Core** - For Python engine features: \`pipx install rapidkit-core\`
630
+ 4. **Read the Documentation** - Visit [Workspai Docs](https://workspai.dev/docs)
631
+
632
+ ## \u26A0\uFE0F Demo Mode Limitations
633
+
634
+ This is a demo workspace with:
635
+ - \u2705 Pre-built FastAPI templates
636
+ - \u2705 Project generation without Python RapidKit Core
637
+ - \u274C No Python RapidKit Core module commands (\`rapidkit add module\`)
638
+ - \u274C No interactive module system
639
+
640
+ For Python engine features, install RapidKit Core:
641
+
642
+ \`\`\`bash
643
+ pipx install rapidkit-core
644
+ \`\`\`
645
+
646
+ ## \u{1F6E0}\uFE0F Workspace Structure
647
+
648
+ \`\`\`
649
+ ${n}/
650
+ \u251C\u2500\u2500 generate-demo.js # Demo project generator
651
+ \u251C\u2500\u2500 README.md # This file
652
+ \u2514\u2500\u2500 my-api/ # Your generated projects go here
653
+ \`\`\`
654
+
655
+ ## \u{1F4A1} Tips
656
+
657
+ - Run \`node generate-demo.js --help\` for more options (coming soon)
658
+ - Each project can have different configurations
659
+ - Demo projects are production-ready FastAPI applications
660
+ - You can copy and modify templates as needed
661
+
662
+ ---
663
+
664
+ **Generated with Workspai** | [GitHub](https://github.com/chistiq/workspai)
665
+ `;if(await promises.writeFile(p.join(e,"README.md"),d,"utf-8"),a.succeed("Demo workspace setup complete"),!t)if(await He(e))a.warn("Git initialization skipped because target is already inside a git worktree");else {a.start("Initializing git repository");try{await execa("git",["init"],{cwd:e,env:a$1()}),await P.outputFile(p.join(e,".gitignore"),`# Dependencies
666
+ node_modules/
667
+
668
+ # Generated projects
669
+ */
670
+ !generate-demo.js
671
+ !README.md
672
+
673
+ # Python
674
+ __pycache__/
675
+ *.pyc
676
+ .venv/
677
+ .env
678
+ `,"utf-8"),await execa("git",["add","."],{cwd:e,env:a$1()}),await execa("git",["commit","-m","Initial commit: Demo workspace"],{cwd:e,env:a$1()}),a.succeed("Git repository initialized");}catch{a.warn("Could not initialize git repository");}}console.log(r.green(`
679
+ \u2728 Demo workspace created successfully!
680
+ `)),console.log(r.cyan("\u{1F4C2} Location:"),r.white(e)),console.log(r.cyan(`\u{1F680} Get started:
681
+ `)),console.log(r.white(` ${g$1(e)}`)),console.log(r.white(" node generate-demo.js my-api")),console.log(r.white(" cd my-api")),console.log(r.white(" workspai init")),console.log(r.white(" workspai dev")),console.log(),console.log(r.yellow("\u{1F4A1} Note:"),"This is a demo workspace. For Python engine features:"),console.log(r.cyan(" pipx install rapidkit-core")),console.log();}catch(s){throw a.fail("Failed to create demo workspace"),s}}async function bt(e,n,t,a,s,l,d,y=false,c=false){if(console.log(r.cyan(`
682
+ \u{1F50D} Dry-run mode - what would be created:
683
+ `)),console.log(r.white("\u{1F4C2} Workspace path:"),e),console.log(r.white("\u{1F4DB} Name:"),r.cyan(n)),t)console.log(r.white("\u{1F4E6} Type:"),"Demo environment"),console.log(r.white(`
684
+ \u{1F4DD} Files to create:`)),console.log(r.gray(" - package.json")),console.log(r.gray(" - generate-demo.js (project generator)")),console.log(r.gray(" - README.md")),console.log(r.gray(" - .gitignore")),console.log(r.white(`
685
+ \u{1F3AF} Capabilities:`)),console.log(r.gray(" - Generate FastAPI/NestJS demo projects")),console.log(r.gray(" - No Python RapidKit installation required")),console.log(r.gray(" - Bundled templates"));else {let g=s||"minimal",m=l,h=d,o=new Set(["python-only","polyglot","enterprise"]).has(g);console.log(r.white("\u{1F4E6} Profile:"),r.cyan(g)),console.log(r.white("\u{1F4DD} Configuration:")),o?(console.log(r.gray(` - Python version: ${h}`)),console.log(r.gray(` - Python engine: ${c?"Skipped":`Install with ${m}`}`)),console.log(r.gray(` - Git init: ${y?"No":"Yes"}`))):(console.log(r.gray(" - Python-free profile (no Python needed)")),console.log(r.gray(` - Git init: ${y?"No":"Yes"}`))),console.log(r.white(`
686
+ \u{1F4CB} Files to create:`)),console.log(r.gray(" - .workspai-workspace (workspace marker)")),console.log(r.gray(" - .workspai/ (workspace config directory)")),console.log(r.gray(" - README.md")),console.log(r.gray(" - .gitignore")),o&&!c&&console.log(r.gray(` - ${m==="poetry"?"pyproject.toml + poetry.lock":".venv/ (virtual environment)"}`)),console.log(r.white(`
687
+ \u2699\uFE0F Environment setup:`)),o&&c?console.log(r.gray(" - Python engine setup skipped")):o&&console.log(m==="poetry"?r.gray(" - Poetry virtual environment created (recommended, includes dependency management)"):m==="venv"?r.gray(" - Python venv created in .venv/ (standard, zero extra tools)"):r.gray(" - Global pipx install (isolated, not local to workspace)")),console.log(r.white(`
688
+ \u{1F680} Next steps:`)),console.log(r.gray(` 1. ${g$1(e)}`)),console.log(r.gray(" 2. npx workspai create project")),console.log(r.gray(" 3. npx workspai init")),console.log(r.gray(" 4. npx workspai dev")),console.log(r.white(`
689
+ \u{1F4A1} Learn more:`)),console.log(r.gray(" \u2022 Change profile later: workspai bootstrap --profile <profile>")),console.log(r.gray(" \u2022 Profile options: minimal|java-only|python-only|node-only|go-only|dotnet-only|polyglot|enterprise")),console.log(r.gray(" \u2022 Help: npx workspai --help"));}console.log(r.white(`
690
+ \u2728 To proceed: remove --dry-run flag
691
+ `));}export{Ye as a,Xt as b,Xe as c,ut as d,ue as e,Zt as f,en as g};