@stackwright-pro/launch-stackwright-pro 0.4.0-alpha.6 → 0.4.0-alpha.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,10 +21,14 @@ to automatically wire up Pro features:
21
21
  ## Quick Start
22
22
 
23
23
  ```bash
24
- pnpx @stackwright-pro/launch-stackwright-pro my-app -y
24
+ # Works — project created in $cwd/my-app
25
+ pnpx @stackwright-pro/launch-stackwright-pro --name my-app -y
25
26
  # Dependencies install automatically (~7s)
26
27
  cd my-app
27
- uvx stackwright-pro-raft # Start the otter raft
28
+ npx @stackwright-pro/raft # Start the otter raft
29
+
30
+ # Equivalent explicit form
31
+ pnpx @stackwright-pro/launch-stackwright-pro my-app --name my-app -y
28
32
  ```
29
33
 
30
34
  ### With an OpenAPI Spec
@@ -72,7 +76,7 @@ Options:
72
76
  --force Overwrite existing directory
73
77
  --skip-otters Skip otter raft setup
74
78
  -y, --yes Skip prompts, use defaults
75
- --spec <path> Path to an OpenAPI spec (YAML or JSON)
79
+ --spec <paths...> Paths to OpenAPI specs (can be specified multiple times)
76
80
  --spec-name <name> Name for the API integration (default: derived from filename)
77
81
  -V, --version Output the version number
78
82
  -h, --help Display help
@@ -120,17 +124,11 @@ for architecture details, auth deep-dives, and deployment guides.
120
124
 
121
125
  ## Starting the Otter Raft
122
126
 
123
- The otter raft is a Python state machine — **not** a code-puppy interactive session. Start it with:
124
-
125
127
  ```bash
126
- uvx stackwright-pro-raft
128
+ cd my-app
129
+ npx @stackwright-pro/raft
127
130
  ```
128
131
 
129
- For local development (before PyPI publish):
130
-
131
- ```bash
132
- pip install -e ./python[tui]
133
- python -m stackwright_pro.raft.cli foreman
134
- ```
132
+ The raft verifies otter integrity, loads project context from `.stackwright/init-context.json`, and spawns code-puppy in foreman mode. Tell the foreman about your specs in natural language — it coordinates the API, auth, data, and page otters to build your app.
135
133
 
136
- The raft uses a Rich terminal UI for all user interaction and calls code-puppy as a one-shot subprocess for creative LLM tasks. It reads otter configs from `node_modules/@stackwright-pro/otters/`. Note: `server` starts the passive Clarification Protocol HTTP listener (for agentic/remote use). `cli foreman` is the interactive entry point that runs the full otter orchestration pipeline.
134
+ All state lives in `.stackwright/` you can interrupt and resume at any time.
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ var require_package = __commonJS({
31
31
  "package.json"(exports2, module2) {
32
32
  module2.exports = {
33
33
  name: "@stackwright-pro/launch-stackwright-pro",
34
- version: "0.4.0-alpha.5",
34
+ version: "0.4.0-alpha.60",
35
35
  description: "Launch a new Stackwright Pro project with OpenAPI integration, auth, and the otter raft",
36
36
  license: "MIT",
37
37
  publishConfig: {
@@ -57,14 +57,20 @@ var require_package = __commonJS({
57
57
  "launch-stackwright-pro": "dist/index.js"
58
58
  },
59
59
  scripts: {
60
- build: "tsup",
60
+ build: "node ../../scripts/sync-versions.mjs && tsup",
61
+ "sync-versions": "node ../../scripts/sync-versions.mjs",
61
62
  dev: "tsup --watch",
62
63
  test: "vitest run",
63
64
  "test:coverage": "vitest run --coverage"
64
65
  },
65
66
  dependencies: {
66
- "@stackwright-pro/scaffold-hooks": "workspace:*",
67
- "@stackwright/cli": "^0.7.0",
67
+ "@stackwright-pro/auth": "workspace:*",
68
+ "@stackwright-pro/auth-nextjs": "workspace:*",
69
+ "@stackwright-pro/mcp": "workspace:*",
70
+ "@stackwright-pro/openapi": "workspace:*",
71
+ "@stackwright-pro/otters": "workspace:*",
72
+ "@stackwright-pro/scaffold-hooks": "latest",
73
+ "@stackwright/cli": "^0.7.1-alpha.0",
68
74
  "@stackwright/scaffold-core": "^0.1.0",
69
75
  chalk: "^5.6.2",
70
76
  commander: "^14.0.3",
@@ -94,6 +100,30 @@ var import_child_process = require("child_process");
94
100
  var import_cli = require("@stackwright/cli");
95
101
  var import_scaffold_core = require("@stackwright/scaffold-core");
96
102
  var import_scaffold_hooks = require("@stackwright-pro/scaffold-hooks");
103
+
104
+ // src/generated/workspace-versions.ts
105
+ var PRO_VERSIONS = {
106
+ "@stackwright-pro/auth": "0.2.0-alpha.4",
107
+ "@stackwright-pro/auth-nextjs": "0.2.0-alpha.4",
108
+ "@stackwright-pro/display-components": "0.2.0-alpha.5",
109
+ "@stackwright-pro/mcp": "0.2.0-alpha.32",
110
+ "@stackwright-pro/openapi": "0.3.0-alpha.12",
111
+ "@stackwright-pro/otters": "1.0.0-alpha.31",
112
+ "@stackwright-pro/pulse": "0.3.0-alpha.7",
113
+ "@stackwright-pro/workflow": "0.1.0-alpha.8",
114
+ "@stackwright-pro/workflow-components": "0.1.0-alpha.10"
115
+ };
116
+ var OSS_VERSIONS = {
117
+ "@stackwright/build-scripts": "^0.7.0",
118
+ "@stackwright/core": "^0.8.2",
119
+ "@stackwright/icons": "^0.5.2",
120
+ "@stackwright/mcp": "^0.4.5",
121
+ "@stackwright/nextjs": "^0.5.3",
122
+ "@stackwright/otters": "^0.2.0",
123
+ "@stackwright/ui-shadcn": "^0.1.0"
124
+ };
125
+
126
+ // src/index.ts
97
127
  (0, import_scaffold_hooks.registerProScaffoldHooks)();
98
128
  var { version } = require_package();
99
129
  async function copyProTemplate(templateName, destPath) {
@@ -103,25 +133,90 @@ async function copyProTemplate(templateName, destPath) {
103
133
  async function addAuthToStackwrightYml(targetDir) {
104
134
  const ymlPath = import_path.default.join(targetDir, "stackwright.yml");
105
135
  const content = await import_fs_extra.default.readFile(ymlPath, "utf-8");
106
- const config = import_js_yaml.default.load(content);
107
- config.auth = {
108
- type: "pki",
109
- profile: "dod_cac",
110
- source: "gateway_headers",
111
- roles: [
112
- { name: "ADMIN", permissions: ["*"] },
113
- { name: "ANALYST", permissions: ["data:read", "data:write"] },
114
- { name: "VIEWER", permissions: ["data:read"] }
115
- ],
116
- protected_routes: [{ path: "/*", roles: ["VIEWER", "ANALYST", "ADMIN"] }],
117
- public_routes: ["/", "/getting-started"]
118
- };
136
+ const config = import_js_yaml.default.load(content, { schema: import_js_yaml.default.CORE_SCHEMA });
137
+ config.auth = {};
119
138
  await import_fs_extra.default.writeFile(ymlPath, import_js_yaml.default.dump(config, { lineWidth: 120 }));
120
139
  }
140
+ async function addProDepsToPackageJson(targetDir) {
141
+ const pkgPath = import_path.default.join(targetDir, "package.json");
142
+ const content = await import_fs_extra.default.readFile(pkgPath, "utf-8");
143
+ const pkg = JSON.parse(content);
144
+ const dependencies = pkg.dependencies || {};
145
+ const devDependencies = pkg.devDependencies || {};
146
+ const scripts = pkg.scripts || {};
147
+ for (const [pkgName, pinnedVersion] of Object.entries(OSS_VERSIONS)) {
148
+ if (pkgName in dependencies) {
149
+ dependencies[pkgName] = pinnedVersion;
150
+ }
151
+ if (pkgName in devDependencies) {
152
+ devDependencies[pkgName] = pinnedVersion;
153
+ }
154
+ }
155
+ Object.assign(dependencies, {
156
+ "@stackwright-pro/display-components": PRO_VERSIONS["@stackwright-pro/display-components"],
157
+ "@stackwright-pro/mcp": PRO_VERSIONS["@stackwright-pro/mcp"],
158
+ "@stackwright-pro/otters": PRO_VERSIONS["@stackwright-pro/otters"],
159
+ "@stackwright-pro/openapi": PRO_VERSIONS["@stackwright-pro/openapi"],
160
+ "@stackwright-pro/auth": PRO_VERSIONS["@stackwright-pro/auth"],
161
+ "@stackwright-pro/auth-nextjs": PRO_VERSIONS["@stackwright-pro/auth-nextjs"],
162
+ "@stackwright-pro/pulse": PRO_VERSIONS["@stackwright-pro/pulse"],
163
+ "@stackwright-pro/workflow-components": PRO_VERSIONS["@stackwright-pro/workflow-components"],
164
+ "@stackwright-pro/workflow": PRO_VERSIONS["@stackwright-pro/workflow"],
165
+ "@stackwright/build-scripts": OSS_VERSIONS["@stackwright/build-scripts"],
166
+ zod: "^4.0.0"
167
+ });
168
+ Object.assign(devDependencies, {
169
+ "@stoplight/prism-cli": "^5.14.2"
170
+ });
171
+ Object.assign(scripts, {
172
+ "dev:admin": "MOCK_USER=admin next dev",
173
+ "dev:analyst": "MOCK_USER=analyst next dev",
174
+ "dev:viewer": "MOCK_USER=viewer next dev",
175
+ prebuild: "node scripts/prebuild.js",
176
+ predev: "node scripts/prebuild.js"
177
+ });
178
+ pkg.dependencies = dependencies;
179
+ pkg.devDependencies = devDependencies;
180
+ pkg.scripts = scripts;
181
+ await import_fs_extra.default.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
182
+ }
183
+ async function scaffoldWorkspaceConfig(targetDir) {
184
+ const workspaceDir = import_path.default.join(targetDir, ".code-puppy");
185
+ await import_fs_extra.default.ensureDir(workspaceDir);
186
+ await import_fs_extra.default.ensureDir(import_path.default.join(workspaceDir, "agents"));
187
+ const configPath = import_path.default.join(workspaceDir, "config.json");
188
+ let existingConfig = {};
189
+ if (import_fs_extra.default.existsSync(configPath)) {
190
+ try {
191
+ existingConfig = JSON.parse(await import_fs_extra.default.readFile(configPath, "utf-8"));
192
+ } catch {
193
+ }
194
+ }
195
+ await import_fs_extra.default.writeFile(
196
+ configPath,
197
+ JSON.stringify({ ...existingConfig, projectOnly: true }, null, 2) + "\n",
198
+ "utf-8"
199
+ );
200
+ const mcpServersPath = import_path.default.join(workspaceDir, "mcp_servers.json");
201
+ if (!import_fs_extra.default.existsSync(mcpServersPath)) {
202
+ const mcpConfig = {
203
+ mcp_servers: {
204
+ "stackwright-pro-mcp": {
205
+ type: "stdio",
206
+ command: "pnpm",
207
+ args: ["exec", "stackwright-pro-mcp"],
208
+ enabled: true,
209
+ cwd: "${PROJECT_ROOT}"
210
+ }
211
+ }
212
+ };
213
+ await import_fs_extra.default.writeFile(mcpServersPath, JSON.stringify(mcpConfig, null, 2) + "\n", "utf-8");
214
+ }
215
+ }
121
216
  async function addIntegrationToStackwrightYml(targetDir, specName, specFilename, mockUrl) {
122
217
  const ymlPath = import_path.default.join(targetDir, "stackwright.yml");
123
218
  const content = await import_fs_extra.default.readFile(ymlPath, "utf-8");
124
- const config = import_js_yaml.default.load(content);
219
+ const config = import_js_yaml.default.load(content, { schema: import_js_yaml.default.CORE_SCHEMA });
125
220
  const integration = {
126
221
  type: "openapi",
127
222
  name: specName,
@@ -131,7 +226,10 @@ async function addIntegrationToStackwrightYml(targetDir, specName, specFilename,
131
226
  if (mockUrl) {
132
227
  integration.mockUrl = mockUrl;
133
228
  }
134
- config.integrations = [integration];
229
+ config.integrations = [
230
+ ...Array.isArray(config.integrations) ? config.integrations : [],
231
+ integration
232
+ ];
135
233
  await import_fs_extra.default.writeFile(ymlPath, import_js_yaml.default.dump(config, { lineWidth: 120 }));
136
234
  }
137
235
  async function handleSpec(targetDir, specPath, specName) {
@@ -219,12 +317,10 @@ Your project includes **SIX specialized AI agents** in \`node_modules/@stackwrig
219
317
  **Start the otter raft:**
220
318
 
221
319
  \`\`\`bash
222
- uvx stackwright-pro-raft
320
+ npx @stackwright-pro/raft
223
321
  \`\`\`
224
322
 
225
- > **Local dev (before PyPI publish):** \`python -m stackwright_pro.raft.cli_adapter foreman\`
226
-
227
- The raft is a Python state machine with a Rich terminal UI \u2014 it asks questions about your brand, auth, and data preferences, then coordinates specialist otters to build your app. All user interaction happens in the terminal; code-puppy is called as a one-shot subprocess for creative tasks only.
323
+ The raft verifies otter integrity, writes project context, and spawns code-puppy in foreman mode. The foreman asks questions about your brand, auth, and data preferences, then coordinates specialist otters to build your app. All state lives in \`.stackwright/\` \u2014 interrupt and resume anytime.
228
324
 
229
325
  **Example session prompt:**
230
326
 
@@ -407,6 +503,8 @@ async function launch(targetDir, options) {
407
503
  console.log(import_chalk.default.cyan.bold("\n\u{1F6A2} Launching Stackwright Pro...\n"));
408
504
  const scaffoldOpts = {
409
505
  name: options.name || dirName,
506
+ standalone: true,
507
+ // prevents `workspace:*` refs when CLI runs inside the Pro monorepo
410
508
  ...options.title !== void 0 && { title: options.title },
411
509
  ...options.theme !== void 0 && { theme: options.theme },
412
510
  ...options.force !== void 0 && { force: options.force },
@@ -414,13 +512,41 @@ async function launch(targetDir, options) {
414
512
  };
415
513
  await (0, import_cli.scaffold)(targetDir, scaffoldOpts);
416
514
  console.log(import_chalk.default.green("\u2705 Base project scaffolded (hooks added Pro deps + MCP config)"));
515
+ await addProDepsToPackageJson(targetDir);
516
+ console.log(import_chalk.default.green("\u{1F9A6} Pro packages added to package.json"));
517
+ const verifyPkg = JSON.parse(
518
+ await import_fs_extra.default.readFile(import_path.default.join(targetDir, "package.json"), "utf-8")
519
+ );
520
+ const proDepCount = Object.keys(verifyPkg.dependencies || {}).filter(
521
+ (k) => k.startsWith("@stackwright-pro")
522
+ ).length;
523
+ console.log(import_chalk.default.dim(` \u2192 package.json verified: ${proDepCount} @stackwright-pro/* deps ready`));
417
524
  console.log(import_chalk.default.cyan("\n\u{1F4E6} Installing dependencies (this takes a moment)..."));
418
525
  if (!options.skipInstall) {
419
526
  try {
420
- (0, import_child_process.execSync)("pnpm install", { cwd: targetDir, stdio: "inherit", timeout: 12e4 });
527
+ (0, import_child_process.execSync)("pnpm install --ignore-workspace", {
528
+ cwd: targetDir,
529
+ stdio: "inherit",
530
+ timeout: 12e4
531
+ });
421
532
  console.log(import_chalk.default.green("\u2705 Dependencies installed"));
422
- } catch {
423
- console.warn(import_chalk.default.yellow("\u26A0\uFE0F pnpm install failed \u2014 run it manually: pnpm install"));
533
+ } catch (err) {
534
+ const isTimeout = err instanceof Error && (err.message.includes("ETIMEDOUT") || err.message.includes("timeout"));
535
+ console.error(
536
+ import_chalk.default.red("\n\u274C pnpm install failed. Auth and Pro packages are NOT installed.")
537
+ );
538
+ console.error(
539
+ import_chalk.default.red(" Your project is in an incomplete state \u2014 do NOT run or deploy it.")
540
+ );
541
+ if (isTimeout) {
542
+ console.error(
543
+ import_chalk.default.yellow(" The install timed out (>2 min). Check your network connection.")
544
+ );
545
+ }
546
+ console.error(
547
+ import_chalk.default.yellow(` Fix the error above, then run: pnpm install --ignore-workspace`)
548
+ );
549
+ process.exit(1);
424
550
  }
425
551
  } else {
426
552
  console.log(import_chalk.default.dim("\u2139\uFE0F Skipping install (--skip-install). Run: pnpm install"));
@@ -442,19 +568,25 @@ async function launch(targetDir, options) {
442
568
  await copyProTemplate("yaml.d.ts", import_path.default.join(targetDir, "yaml.d.ts"));
443
569
  await import_fs_extra.default.ensureDir(import_path.default.join(targetDir, "scripts"));
444
570
  await copyProTemplate("prebuild.js", import_path.default.join(targetDir, "scripts", "prebuild.js"));
571
+ await copyProTemplate(
572
+ "scripts/pro-content-plugin.js",
573
+ import_path.default.join(targetDir, "scripts", "pro-content-plugin.js")
574
+ );
445
575
  console.log(import_chalk.default.green("\u{1F510} Auth integration added (RBAC with 3 roles)"));
446
576
  await addAuthToStackwrightYml(targetDir);
447
577
  let specInfo = null;
448
578
  const MOCK_URL = "http://localhost:4010";
449
- if (options.spec) {
450
- specInfo = await handleSpec(targetDir, options.spec, options.specName);
451
- await addIntegrationToStackwrightYml(
452
- targetDir,
453
- specInfo.derivedName,
454
- specInfo.specFilename,
455
- options.mock ? MOCK_URL : void 0
456
- );
457
- console.log(import_chalk.default.green("\u{1F4E1} OpenAPI integration wired up"));
579
+ if (options.spec && options.spec.length > 0) {
580
+ for (const specPath of options.spec) {
581
+ specInfo = await handleSpec(targetDir, specPath, options.specName);
582
+ await addIntegrationToStackwrightYml(
583
+ targetDir,
584
+ specInfo.derivedName,
585
+ specInfo.specFilename,
586
+ options.mock ? MOCK_URL : void 0
587
+ );
588
+ }
589
+ console.log(import_chalk.default.green(`\u{1F4E1} ${options.spec.length} OpenAPI integration(s) wired up`));
458
590
  if (options.mock) {
459
591
  console.log(import_chalk.default.green("\u{1F3AD} Prism mock server configured"));
460
592
  }
@@ -487,11 +619,31 @@ async function launch(targetDir, options) {
487
619
  });
488
620
  await import_fs_extra.default.writeFile(import_path.default.join(targetDir, "README.md"), readmeContent);
489
621
  console.log(import_chalk.default.green("\u{1F4C4} README.md created"));
622
+ const initContext = {
623
+ projectRoot: targetDir,
624
+ projectName: options.name || dirName,
625
+ generatedBy: "launch-stackwright-pro",
626
+ version: "1.0"
627
+ };
628
+ if (specInfo) {
629
+ initContext.specPath = `specs/${specInfo.specFilename}`;
630
+ initContext.specName = specInfo.derivedName;
631
+ }
632
+ initContext.theme = options.theme || "corporate";
633
+ const stackwrightDir = import_path.default.join(targetDir, ".stackwright");
634
+ await import_fs_extra.default.ensureDir(stackwrightDir);
635
+ await import_fs_extra.default.writeFile(
636
+ import_path.default.join(stackwrightDir, "init-context.json"),
637
+ JSON.stringify(initContext, null, 2) + "\n",
638
+ "utf-8"
639
+ );
640
+ await scaffoldWorkspaceConfig(targetDir);
641
+ console.log(import_chalk.default.green("\u{1F43E} .code-puppy/ workspace scaffolded (projectOnly: true)"));
490
642
  const relDir = import_path.default.relative(process.cwd(), targetDir) || ".";
491
643
  console.log(import_chalk.default.cyan.bold("\n\u{1F389} All set! Here's what to do next:\n"));
492
644
  console.log(import_chalk.default.white(` 1. cd ${relDir}`));
493
- console.log(import_chalk.default.white(" 2. uvx stackwright-pro-raft"));
494
- console.log(import_chalk.default.dim(" (local dev: python -m stackwright_pro.raft.cli_adapter foreman)"));
645
+ console.log(import_chalk.default.white(" 2. npx @stackwright-pro/raft"));
646
+ console.log(import_chalk.default.dim(" (use --verbose for troubleshooting)"));
495
647
  if (specInfo) {
496
648
  console.log(import_chalk.default.cyan(`
497
649
  \u{1F4E1} Your API spec was copied to specs/${specInfo.specFilename}`));
@@ -509,8 +661,8 @@ async function launch(targetDir, options) {
509
661
  async function main() {
510
662
  const program = new import_commander.Command();
511
663
  program.name("launch-stackwright-pro").description("\u{1F6A2} Launch a new Stackwright Pro project with auth, OpenAPI, and the otter raft").version(version).argument("[directory]", "Project directory", ".").option("--name <name>", "Project name (used in package.json)").option("--title <title>", "Site title shown in the app bar and browser tab").option("--theme <themeId>", "Theme ID (e.g., corporate, creative, minimal)").option("--force", "Launch even if the target directory is not empty").option("--skip-otters", "Skip copying otter raft configs").option("-y, --yes", "Skip all prompts, use defaults").option("--mock", "Configure Prism mock server for API development (runs on port 4010)").option(
512
- "--spec <path>",
513
- "Path to an OpenAPI spec (YAML or JSON) \u2014 copies into project and wires up integration"
664
+ "--spec <paths...>",
665
+ "Paths to OpenAPI specs (YAML or JSON) \u2014 copies into project and wires up integrations (can be specified multiple times)"
514
666
  ).option(
515
667
  "--spec-name <name>",
516
668
  "Name for the API integration (default: derived from spec filename)"
@@ -519,7 +671,7 @@ async function main() {
519
671
  "Skip automatic pnpm install (useful in CI or when using a different package manager)"
520
672
  ).action(async (directory, options) => {
521
673
  const homeDir = import_os.default.homedir();
522
- const targetDir = import_path.default.resolve(directory);
674
+ const targetDir = directory !== "." ? import_path.default.resolve(process.cwd(), directory) : options.name ? import_path.default.resolve(process.cwd(), options.name) : process.cwd();
523
675
  if (!targetDir.startsWith(homeDir + import_path.default.sep) && targetDir !== homeDir) {
524
676
  console.warn(import_chalk.default.yellow(`\u26A0\uFE0F Scaffolding outside your home directory: ${targetDir}`));
525
677
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@stackwright-pro/launch-stackwright-pro\",\n \"version\": \"0.4.0-alpha.5\",\n \"description\": \"Launch a new Stackwright Pro project with OpenAPI integration, auth, and the otter raft\",\n \"license\": \"MIT\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/Per-Aspera-LLC/stackwright-pro\"\n },\n \"keywords\": [\n \"stackwright\",\n \"stackwright-pro\",\n \"scaffolding\",\n \"openapi\",\n \"government\",\n \"hackathon\"\n ],\n \"files\": [\n \"dist\",\n \"templates\"\n ],\n \"bin\": {\n \"launch-stackwright-pro\": \"dist/index.js\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:coverage\": \"vitest run --coverage\"\n },\n \"dependencies\": {\n \"@stackwright-pro/scaffold-hooks\": \"workspace:*\",\n \"@stackwright/cli\": \"^0.7.0\",\n \"@stackwright/scaffold-core\": \"^0.1.0\",\n \"chalk\": \"^5.6.2\",\n \"commander\": \"^14.0.3\",\n \"fs-extra\": \"^11.3\",\n \"js-yaml\": \"^4.1.0\"\n },\n \"devDependencies\": {\n \"@types/fs-extra\": \"^11.0\",\n \"@types/js-yaml\": \"^4.0.9\",\n \"@types/node\": \"^24.0.0\",\n \"typescript\": \"^5.0\",\n \"tsup\": \"^8.5\",\n \"vitest\": \"^4.0.18\"\n }\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport os from 'os';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\nimport yaml from 'js-yaml';\nimport { execSync } from 'child_process';\n\nimport { scaffold, ScaffoldOptions } from '@stackwright/cli';\nimport { runScaffoldHooks } from '@stackwright/scaffold-core';\nimport { registerProScaffoldHooks } from '@stackwright-pro/scaffold-hooks';\n// Register Pro hooks (adds deps, MCP config, etc.)\n// Must be called before scaffold() to ensure hooks run in the CLI's scaffold-core context\nregisterProScaffoldHooks();\n\nconst { version } = require('../package.json') as { version: string };\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface LaunchProOptions {\n name?: string;\n title?: string;\n theme?: string;\n force?: boolean;\n skipOtters?: boolean;\n skipInstall?: boolean;\n yes?: boolean;\n spec?: string;\n specName?: string;\n mock?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Template copying (Pro-specific - hooks can't handle these)\n// ---------------------------------------------------------------------------\n\nasync function copyProTemplate(templateName: string, destPath: string): Promise<void> {\n const src = path.resolve(__dirname, '..', 'templates', 'pro', templateName);\n await fs.copy(src, destPath);\n}\n\n// ---------------------------------------------------------------------------\n// Auth config (Pro-specific - hooks can't handle these)\n// ---------------------------------------------------------------------------\n\nasync function addAuthToStackwrightYml(targetDir: string): Promise<void> {\n const ymlPath = path.join(targetDir, 'stackwright.yml');\n const content = await fs.readFile(ymlPath, 'utf-8');\n const config = yaml.load(content) as Record<string, unknown>;\n\n config.auth = {\n type: 'pki',\n profile: 'dod_cac',\n source: 'gateway_headers',\n roles: [\n { name: 'ADMIN', permissions: ['*'] },\n { name: 'ANALYST', permissions: ['data:read', 'data:write'] },\n { name: 'VIEWER', permissions: ['data:read'] },\n ],\n protected_routes: [{ path: '/*', roles: ['VIEWER', 'ANALYST', 'ADMIN'] }],\n public_routes: ['/', '/getting-started'],\n };\n\n await fs.writeFile(ymlPath, yaml.dump(config, { lineWidth: 120 }));\n}\n\nasync function addIntegrationToStackwrightYml(\n targetDir: string,\n specName: string,\n specFilename: string,\n mockUrl?: string\n): Promise<void> {\n const ymlPath = path.join(targetDir, 'stackwright.yml');\n const content = await fs.readFile(ymlPath, 'utf-8');\n const config = yaml.load(content) as Record<string, unknown>;\n\n const integration: Record<string, unknown> = {\n type: 'openapi',\n name: specName,\n spec: `./specs/${specFilename}`,\n collections: [],\n };\n\n if (mockUrl) {\n integration.mockUrl = mockUrl;\n }\n\n config.integrations = [integration];\n\n await fs.writeFile(ymlPath, yaml.dump(config, { lineWidth: 120 }));\n}\n\n// ---------------------------------------------------------------------------\n// Spec handling (Pro-specific - hooks can't handle these)\n// ---------------------------------------------------------------------------\n\nasync function handleSpec(\n targetDir: string,\n specPath: string,\n specName?: string\n): Promise<{ specFilename: string; derivedName: string }> {\n const resolvedSpec = path.resolve(specPath);\n\n if (!fs.existsSync(resolvedSpec)) {\n throw new Error(`Spec file not found: ${resolvedSpec}`);\n }\n\n const specFilename = path.basename(resolvedSpec);\n const derivedName = specName || path.basename(specFilename, path.extname(specFilename));\n\n const specsDir = path.join(targetDir, 'specs');\n await fs.ensureDir(specsDir);\n await fs.copy(resolvedSpec, path.join(specsDir, specFilename));\n\n return { specFilename, derivedName };\n}\n\n// ---------------------------------------------------------------------------\n// README generator (Pro-specific - hooks can't handle these)\n// ---------------------------------------------------------------------------\n\nfunction generateReadme(options: {\n projectName: string;\n hasSpec: boolean;\n specName?: string;\n specFilename?: string;\n hasOtters: boolean;\n hasMock: boolean;\n}): string {\n const { projectName, hasSpec, specName, specFilename, hasOtters, hasMock } = options;\n\n // Build API Integration section if spec is present\n const apiIntegrationSection = hasSpec\n ? `## 📡 API Integration\n\nYour OpenAPI spec was copied to \\`specs/${specFilename}\\` and wired up in \\`stackwright.yml\\`.\n\n**What gets generated:**\n\n\\`\\`\\`typescript\n// src/generated/${specName}/schemas.ts\nexport const EquipmentSchema = z.object({\n id: z.string(),\n name: z.string(),\n status: z.enum(['operational', 'maintenance', 'retired']),\n // ... Zod validation for runtime safety\n});\n\n// src/generated/${specName}/types.ts\nexport type Equipment = z.infer<typeof EquipmentSchema>;\n\n// src/generated/${specName}/client.ts\nexport class ${specName!.charAt(0).toUpperCase() + specName!.slice(1)}Client {\n async getEquipment(id: string): Promise<Equipment> {\n // Auto-wired with auth, validation, error handling\n }\n}\n\\`\\`\\`\n\n**How it works:**\n1. The \\`predev\\` script in \\`package.json\\` runs \\`prebuild.js\\` before every \\`pnpm dev\\`\n2. Prebuild reads your spec and generates type-safe code\n3. You import and use it:\n\n\\`\\`\\`typescript\nimport { ${specName!.charAt(0).toUpperCase() + specName!.slice(1)}Client } from '@/generated/${specName}/client';\nimport type { Equipment } from '@/generated/${specName}/types';\n\nconst client = new ${specName!.charAt(0).toUpperCase() + specName!.slice(1)}Client();\nconst gear: Equipment = await client.getEquipment('123');\n\\`\\`\\`\n\nNo manual typing. No drift. No runtime surprises.\n\n`\n : '';\n\n // Build mock server section if enabled\n const mockSection = hasMock\n ? `## 🎭 Mock Server\n\nPrism mock server is configured to serve your API at **http://localhost:4010**.\n\n\\`\\`\\`bash\npnpm dev:mock # Starts Prism + Next.js together\n\\`\\`\\`\n\nThis starts:\n1. Prism mock server on port 4010 (serves your OpenAPI spec)\n2. Next.js dev server on port 3000\n\nThe generated API client is automatically configured to use the mock server.\n\n`\n : '';\n\n // Build AI Agents section if otters are present\n const aiAgentsSection = hasOtters\n ? `## 🦦 AI Agents (The Otter Raft)\n\nYour project includes **SIX specialized AI agents** in \\`node_modules/@stackwright-pro/otters/\\`:\n\n- \\`stackwright-pro-foreman-otter\\` - Master coordinator that orchestrates all specialist otters\n- \\`stackwright-pro-api-otter\\` - Discovers entities from OpenAPI specs\n- \\`stackwright-pro-auth-otter\\` - Configures CAC/OIDC auth, RBAC rules, and audit middleware\n- \\`stackwright-pro-data-otter\\` - Configures endpoint filters & ISR revalidation\n- \\`stackwright-pro-page-otter\\` - Generates pages auto-wired with data, theme, and auth\n- \\`stackwright-pro-dashboard-otter\\` - Builds live data dashboards\n\n**Start the otter raft:**\n\n\\`\\`\\`bash\nuvx stackwright-pro-raft\n\\`\\`\\`\n\n> **Local dev (before PyPI publish):** \\`python -m stackwright_pro.raft.cli_adapter foreman\\`\n\nThe raft is a Python state machine with a Rich terminal UI — it asks questions about your brand, auth, and data preferences, then coordinates specialist otters to build your app. All user interaction happens in the terminal; code-puppy is called as a one-shot subprocess for creative tasks only.\n\n**Example session prompt:**\n\n\"Build me a logistics dashboard from our OpenAPI spec. Connect to /equipment and /supplies endpoints.\"\n\n`\n : '';\n\n return `# ${projectName}\n\nA Stackwright Pro application with role-based auth, OpenAPI integration, and intelligent AI agents.\n\n## 🚀 Quick Start\n\n\\`\\`\\`bash\n# Start development server\npnpm dev\n\n# Open your browser\nopen http://localhost:3000\n\\`\\`\\`\n\n## 👥 Role-Based Development\n\nStackwright Pro includes **mock authentication** for local development with three pre-configured roles:\n\n\\`\\`\\`bash\npnpm dev:admin # Full permissions (*)\npnpm dev:analyst # Read & write data\npnpm dev:viewer # Read-only access\n\\`\\`\\`\n\n**How it works:**\n- Each script sets the \\`MOCK_USER\\` environment variable\n- \\`lib/mock-auth.ts\\` intercepts requests and injects the appropriate user context\n- Your pages & API routes respect the RBAC rules in \\`stackwright.yml\\`\n- No backend required for testing auth flows! 🎉\n\n**Pro tip:** Test your UI for all three roles to ensure proper permissions enforcement.\n\n${mockSection}## 📁 Project Structure\n\n\\`\\`\\`\n.\n├── pages/\n│ ├── _app.tsx # Pro version with AuthProvider + shadcn\n│ ├── index.tsx # Home page (auto-generated by Stackwright)\n│ ├── about/\n│ │ └── content.yml # Page content in YAML\n│ └── ...\n├── lib/\n│ └── mock-auth.ts # Dev-only auth mocking (no backend needed)\n├── scripts/\n│ └── prebuild.js # Auto-generates code from OpenAPI specs\n├── specs/ # OpenAPI spec files (if --spec was used)\n├── src/\n│ └── generated/ # Auto-generated types & clients\n│ └── {specName}/\n│ ├── schemas.ts # Zod schemas for runtime validation\n│ ├── types.ts # TypeScript types\n│ ├── client.ts # API client with auth\n│ └── provider.ts # CollectionProvider for Stackwright\n├── .stackwright/\n│ └── otters/ # AI agent configs (4 specialized otters)\n├── stackwright.yml # Theme, auth, API integrations\n└── package.json\n\\`\\`\\`\n\n**Key Files:**\n- \\`pages/_app.tsx\\` - Wraps your app with \\`AuthProvider\\` for RBAC\n- \\`stackwright.yml\\` - Single source of truth for theme, auth roles, and API wiring\n- \\`lib/mock-auth.ts\\` - Mocks CAC/PIV headers locally so you can test auth flows\n- \\`scripts/prebuild.js\\` - Runs before dev/build to generate types from your OpenAPI spec\n\n## 📄 Adding Pages\n\nStackwright uses **YAML for content**, so you never touch JSX unless you want to.\n\n**Example:** Create \\`pages/about/content.yml\\`:\n\n\\`\\`\\`yaml\ntitle: About Us\ndescription: Learn more about our mission\n\nsections:\n - type: main\n heading: Who We Are\n body: |\n We build mission-critical logistics systems for the Marine Corps.\n\n - type: feature_list\n title: Our Capabilities\n features:\n - icon: Security\n title: Zero Trust\n description: PKI-based auth with CAC/PIV\n - icon: Api\n title: Real-time Data\n description: OpenAPI-backed, Zod-validated\n\\`\\`\\`\n\nThat's it. Navigate to \\`/about\\` and it just works. No routing config, no React components.\n\n${apiIntegrationSection}## 🎨 Customizing Theme\n\nEdit \\`stackwright.yml\\` to change colors, fonts, spacing — applies everywhere instantly.\n\n\\`\\`\\`yaml\ntheme:\n id: my-theme\n name: My Custom Theme\n colors:\n primary: \"#C41E3A\" # Marine Corps red\n background: \"#FFFFFF\"\n text: \"#1A1A1A\"\n accent: \"#FFD700\" # Gold\n typography:\n fontFamily: \"'Inter', sans-serif\"\n h1Size: \"2.5rem\"\n spacing:\n unit: 8\n\\`\\`\\`\n\nNo CSS files. No theme provider boilerplate. Just YAML. Stackwright handles the rest.\n\n## 🔐 Auth Configuration\n\nStackwright Pro comes with **3 pre-configured roles** in \\`stackwright.yml\\`:\n\n\\`\\`\\`yaml\nauth:\n roles:\n - name: ADMIN\n permissions: ['*'] # Full access\n - name: ANALYST \n permissions: ['data:read', 'data:write'] # Read/write data\n - name: VIEWER\n permissions: ['data:read'] # Read-only\n\\`\\`\\`\n\n**Gate content in your YAML:**\n\n\\`\\`\\`yaml\nsections:\n - type: button\n label: Delete Equipment\n action: /api/equipment/delete\n auth:\n required_roles: [ADMIN]\n fallback: hide # Options: hide, disable, show_message\n\\`\\`\\`\n\nOnly admins see the button. Analysts and viewers? Button doesn't exist in the DOM.\n\n**Route protection:**\n\n\\`\\`\\`yaml\nauth:\n protected_routes:\n - path: /admin/*\n roles: [ADMIN]\n - path: /equipment/* \n roles: [ANALYST, ADMIN]\n public_routes:\n - /\n - /about\n\\`\\`\\`\n\nNo middleware to write. No useAuth hooks to remember. RBAC is declarative.\n\n${aiAgentsSection}## 📚 Learn More\n\n- **Stackwright Docs:** [https://stackwright.dev](https://stackwright.dev)\n- **OSS Repo:** [https://github.com/Per-Aspera-LLC/stackwright](https://github.com/Per-Aspera-LLC/stackwright)\n- **Pro Repo:** [https://github.com/Per-Aspera-LLC/stackwright-pro](https://github.com/Per-Aspera-LLC/stackwright-pro)\n\n**Questions?** File an issue or ping us in the discussions. We're here to help you ship faster.\n`;\n}\n\n// ---------------------------------------------------------------------------\n// Main launch flow\n// ---------------------------------------------------------------------------\n\nasync function launch(targetDir: string, options: LaunchProOptions): Promise<void> {\n const dirName = path.basename(targetDir);\n\n console.log(chalk.cyan.bold('\\n🚢 Launching Stackwright Pro...\\n'));\n\n // ------------------------------------------------------------------\n // 1. Scaffold base OSS project via @stackwright/cli\n // Hooks auto-handle: Pro deps, MCP config, role-based scripts\n // ------------------------------------------------------------------\n\n const scaffoldOpts: ScaffoldOptions = {\n name: options.name || dirName,\n ...(options.title !== undefined && { title: options.title }),\n ...(options.theme !== undefined && { theme: options.theme }),\n ...(options.force !== undefined && { force: options.force }),\n ...(options.yes !== undefined && { noInteractive: options.yes }),\n };\n\n await scaffold(targetDir, scaffoldOpts);\n console.log(chalk.green('✅ Base project scaffolded (hooks added Pro deps + MCP config)'));\n\n // ------------------------------------------------------------------\n // 1b. Run pnpm install — citizen devs shouldn't need to know this step exists\n // ------------------------------------------------------------------\n\n console.log(chalk.cyan('\\n📦 Installing dependencies (this takes a moment)...'));\n if (!options.skipInstall) {\n try {\n execSync('pnpm install', { cwd: targetDir, stdio: 'inherit', timeout: 120_000 });\n console.log(chalk.green('✅ Dependencies installed'));\n } catch {\n console.warn(chalk.yellow('⚠️ pnpm install failed — run it manually: pnpm install'));\n }\n } else {\n console.log(chalk.dim('ℹ️ Skipping install (--skip-install). Run: pnpm install'));\n }\n\n // Fire postInstall hooks now that install has run\n const dependencyMode: 'workspace' | 'standalone' = 'standalone';\n await runScaffoldHooks('postInstall', {\n targetDir,\n projectName: options.name || path.basename(targetDir),\n siteTitle: options.title || options.name || path.basename(targetDir),\n themeId: options.theme || 'corporate',\n packageJson: {},\n dependencyMode,\n });\n\n // ------------------------------------------------------------------\n // 2. Copy Pro templates (hooks can't handle these)\n // ------------------------------------------------------------------\n\n // Replace _app.tsx with Pro version (AuthProvider, shadcn, etc.)\n await copyProTemplate('_app.tsx', path.join(targetDir, 'pages', '_app.tsx'));\n\n // Add root content.yml for the home page\n await copyProTemplate('content.yml', path.join(targetDir, 'pages', 'content.yml'));\n\n // Replace next.config.js with Pro version (transpile pro pkgs)\n await copyProTemplate('next.config.js', path.join(targetDir, 'next.config.js'));\n\n // Add lib/mock-auth.ts\n await fs.ensureDir(path.join(targetDir, 'lib'));\n await copyProTemplate('mock-auth.ts', path.join(targetDir, 'lib', 'mock-auth.ts'));\n\n // Add yaml.d.ts for TypeScript support\n await copyProTemplate('yaml.d.ts', path.join(targetDir, 'yaml.d.ts'));\n\n // Add scripts/prebuild.js\n await fs.ensureDir(path.join(targetDir, 'scripts'));\n await copyProTemplate('prebuild.js', path.join(targetDir, 'scripts', 'prebuild.js'));\n\n console.log(chalk.green('🔐 Auth integration added (RBAC with 3 roles)'));\n\n // ------------------------------------------------------------------\n // 3. Add auth section to stackwright.yml\n // ------------------------------------------------------------------\n\n await addAuthToStackwrightYml(targetDir);\n\n // ------------------------------------------------------------------\n // 4. Handle --spec if provided\n // ------------------------------------------------------------------\n\n let specInfo: { specFilename: string; derivedName: string } | null = null;\n const MOCK_URL = 'http://localhost:4010';\n\n if (options.spec) {\n specInfo = await handleSpec(targetDir, options.spec, options.specName);\n\n // Pass mockUrl if --mock flag is set\n await addIntegrationToStackwrightYml(\n targetDir,\n specInfo.derivedName,\n specInfo.specFilename,\n options.mock ? MOCK_URL : undefined\n );\n console.log(chalk.green('📡 OpenAPI integration wired up'));\n\n if (options.mock) {\n console.log(chalk.green('🎭 Prism mock server configured'));\n }\n } else if (options.mock) {\n // --mock without --spec: use sample Petstore spec for demo\n console.log(\n chalk.yellow(\n '⚠️ No spec provided with --mock. Using sample Petstore spec for demo. Replace with your API spec.'\n )\n );\n\n const specsDir = path.join(targetDir, 'specs');\n await fs.ensureDir(specsDir);\n await copyProTemplate('petstore.yaml', path.join(specsDir, 'petstore.yaml'));\n\n specInfo = { specFilename: 'petstore.yaml', derivedName: 'petstore' };\n\n await addIntegrationToStackwrightYml(\n targetDir,\n specInfo.derivedName,\n specInfo.specFilename,\n MOCK_URL\n );\n console.log(chalk.green('📡 Sample Petstore spec wired up'));\n console.log(chalk.green('🎭 Prism mock server configured'));\n }\n\n // ------------------------------------------------------------------\n // 5. Generate README\n // ------------------------------------------------------------------\n\n const readmeContent = generateReadme({\n projectName: options.name || dirName,\n hasSpec: !!specInfo,\n ...(specInfo?.derivedName !== undefined && { specName: specInfo.derivedName }),\n ...(specInfo?.specFilename !== undefined && { specFilename: specInfo.specFilename }),\n hasOtters: !options.skipOtters,\n hasMock: !!options.mock,\n });\n\n await fs.writeFile(path.join(targetDir, 'README.md'), readmeContent);\n console.log(chalk.green('📄 README.md created'));\n\n // ------------------------------------------------------------------\n // 6. Print next steps\n // ------------------------------------------------------------------\n\n const relDir = path.relative(process.cwd(), targetDir) || '.';\n\n console.log(chalk.cyan.bold(\"\\n🎉 All set! Here's what to do next:\\n\"));\n console.log(chalk.white(` 1. cd ${relDir}`));\n console.log(chalk.white(' 2. uvx stackwright-pro-raft'));\n console.log(chalk.dim(' (local dev: python -m stackwright_pro.raft.cli_adapter foreman)'));\n\n if (specInfo) {\n console.log(chalk.cyan(`\\n📡 Your API spec was copied to specs/${specInfo.specFilename}`));\n console.log(chalk.dim(' The prebuild will generate types & client on first `pnpm dev`.'));\n }\n\n if (options.mock) {\n console.log(chalk.cyan('\\n🎭 Run with mock server:'));\n console.log(chalk.white(' pnpm dev:mock # Starts Prism + Next.js'));\n }\n\n if (!options.skipOtters) {\n console.log(chalk.cyan.bold('\\n🦦 The otter raft is ready to build your site!'));\n console.log(chalk.dim(' Run the command above to get started.\\n'));\n }\n}\n\n// ---------------------------------------------------------------------------\n// CLI definition\n// ---------------------------------------------------------------------------\n\nasync function main(): Promise<void> {\n const program = new Command();\n\n program\n .name('launch-stackwright-pro')\n .description('🚢 Launch a new Stackwright Pro project with auth, OpenAPI, and the otter raft')\n .version(version)\n .argument('[directory]', 'Project directory', '.')\n .option('--name <name>', 'Project name (used in package.json)')\n .option('--title <title>', 'Site title shown in the app bar and browser tab')\n .option('--theme <themeId>', 'Theme ID (e.g., corporate, creative, minimal)')\n .option('--force', 'Launch even if the target directory is not empty')\n .option('--skip-otters', 'Skip copying otter raft configs')\n .option('-y, --yes', 'Skip all prompts, use defaults')\n .option('--mock', 'Configure Prism mock server for API development (runs on port 4010)')\n .option(\n '--spec <path>',\n 'Path to an OpenAPI spec (YAML or JSON) — copies into project and wires up integration'\n )\n .option(\n '--spec-name <name>',\n 'Name for the API integration (default: derived from spec filename)'\n )\n .option(\n '--skip-install',\n 'Skip automatic pnpm install (useful in CI or when using a different package manager)'\n )\n .action(async (directory: string, options: LaunchProOptions) => {\n const homeDir = os.homedir();\n const targetDir = path.resolve(directory);\n\n // Warn (don't block) when scaffolding outside home dir — unusual for a user-facing CLI\n if (!targetDir.startsWith(homeDir + path.sep) && targetDir !== homeDir) {\n console.warn(chalk.yellow(`⚠️ Scaffolding outside your home directory: ${targetDir}`));\n }\n\n await launch(targetDir, options);\n });\n\n await program.parseAsync(process.argv);\n}\n\nmain().catch((err: unknown) => {\n console.error(chalk.red('\\n❌ Launch failed:'), err);\n process.exit(1);\n});\n"],"mappings":"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","names":["exports","module","path","fs","yaml","chalk","os"]}
1
+ {"version":3,"sources":["../package.json","../src/index.ts","../src/generated/workspace-versions.ts"],"sourcesContent":["{\n \"name\": \"@stackwright-pro/launch-stackwright-pro\",\n \"version\": \"0.4.0-alpha.60\",\n \"description\": \"Launch a new Stackwright Pro project with OpenAPI integration, auth, and the otter raft\",\n \"license\": \"MIT\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/Per-Aspera-LLC/stackwright-pro\"\n },\n \"keywords\": [\n \"stackwright\",\n \"stackwright-pro\",\n \"scaffolding\",\n \"openapi\",\n \"government\",\n \"hackathon\"\n ],\n \"files\": [\n \"dist\",\n \"templates\"\n ],\n \"bin\": {\n \"launch-stackwright-pro\": \"dist/index.js\"\n },\n \"scripts\": {\n \"build\": \"node ../../scripts/sync-versions.mjs && tsup\",\n \"sync-versions\": \"node ../../scripts/sync-versions.mjs\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:coverage\": \"vitest run --coverage\"\n },\n \"dependencies\": {\n \"@stackwright-pro/auth\": \"workspace:*\",\n \"@stackwright-pro/auth-nextjs\": \"workspace:*\",\n \"@stackwright-pro/mcp\": \"workspace:*\",\n \"@stackwright-pro/openapi\": \"workspace:*\",\n \"@stackwright-pro/otters\": \"workspace:*\",\n \"@stackwright-pro/scaffold-hooks\": \"latest\",\n \"@stackwright/cli\": \"^0.7.1-alpha.0\",\n \"@stackwright/scaffold-core\": \"^0.1.0\",\n \"chalk\": \"^5.6.2\",\n \"commander\": \"^14.0.3\",\n \"fs-extra\": \"^11.3\",\n \"js-yaml\": \"^4.1.0\"\n },\n \"devDependencies\": {\n \"@types/fs-extra\": \"^11.0\",\n \"@types/js-yaml\": \"^4.0.9\",\n \"@types/node\": \"^24.0.0\",\n \"typescript\": \"^5.0\",\n \"tsup\": \"^8.5\",\n \"vitest\": \"^4.0.18\"\n }\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport os from 'os';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\nimport yaml from 'js-yaml';\nimport { execSync } from 'child_process';\n\nimport { scaffold, ScaffoldOptions } from '@stackwright/cli';\nimport { runScaffoldHooks } from '@stackwright/scaffold-core';\nimport { registerProScaffoldHooks } from '@stackwright-pro/scaffold-hooks';\nimport { PRO_VERSIONS, OSS_VERSIONS } from './generated/workspace-versions';\n// Register Pro hooks (adds deps, MCP config, etc.)\n// Must be called before scaffold() to ensure hooks run in the CLI's scaffold-core context\nregisterProScaffoldHooks();\n\nconst { version } = require('../package.json') as { version: string };\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface LaunchProOptions {\n name?: string;\n title?: string;\n theme?: string;\n force?: boolean;\n skipOtters?: boolean;\n skipInstall?: boolean;\n yes?: boolean;\n spec?: string[];\n specName?: string;\n mock?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Template copying (Pro-specific - hooks can't handle these)\n// ---------------------------------------------------------------------------\n\nasync function copyProTemplate(templateName: string, destPath: string): Promise<void> {\n const src = path.resolve(__dirname, '..', 'templates', 'pro', templateName);\n await fs.copy(src, destPath);\n}\n\n// ---------------------------------------------------------------------------\n// Auth config (Pro-specific - hooks can't handle these)\n// ---------------------------------------------------------------------------\n\nasync function addAuthToStackwrightYml(targetDir: string): Promise<void> {\n const ymlPath = path.join(targetDir, 'stackwright.yml');\n const content = await fs.readFile(ymlPath, 'utf-8');\n const config = yaml.load(content, { schema: yaml.CORE_SCHEMA }) as Record<string, unknown>;\n\n config.auth = {};\n\n await fs.writeFile(ymlPath, yaml.dump(config, { lineWidth: 120 }));\n}\n\nasync function addProDepsToPackageJson(targetDir: string): Promise<void> {\n const pkgPath = path.join(targetDir, 'package.json');\n const content = await fs.readFile(pkgPath, 'utf-8');\n const pkg = JSON.parse(content) as Record<string, any>;\n\n const dependencies = (pkg.dependencies as Record<string, string>) || {};\n const devDependencies = (pkg.devDependencies as Record<string, string>) || {};\n const scripts = (pkg.scripts as Record<string, string>) || {};\n\n // Enforce OSS version floors — replace workspace:* refs AND upgrade any stale version\n // pinned by the OSS scaffold template to our tested minimum.\n // OSS_VERSIONS = \"minimum tested versions\" — we always want them to win.\n for (const [pkgName, pinnedVersion] of Object.entries(OSS_VERSIONS)) {\n if (pkgName in dependencies) {\n dependencies[pkgName] = pinnedVersion;\n }\n if (pkgName in devDependencies) {\n devDependencies[pkgName] = pinnedVersion;\n }\n }\n\n // Pro runtime dependencies — exact versions from workspace at build time\n Object.assign(dependencies, {\n '@stackwright-pro/display-components': PRO_VERSIONS['@stackwright-pro/display-components'],\n '@stackwright-pro/mcp': PRO_VERSIONS['@stackwright-pro/mcp'],\n '@stackwright-pro/otters': PRO_VERSIONS['@stackwright-pro/otters'],\n '@stackwright-pro/openapi': PRO_VERSIONS['@stackwright-pro/openapi'],\n '@stackwright-pro/auth': PRO_VERSIONS['@stackwright-pro/auth'],\n '@stackwright-pro/auth-nextjs': PRO_VERSIONS['@stackwright-pro/auth-nextjs'],\n '@stackwright-pro/pulse': PRO_VERSIONS['@stackwright-pro/pulse'],\n '@stackwright-pro/workflow-components': PRO_VERSIONS['@stackwright-pro/workflow-components'],\n '@stackwright-pro/workflow': PRO_VERSIONS['@stackwright-pro/workflow'],\n '@stackwright/build-scripts': OSS_VERSIONS['@stackwright/build-scripts'],\n zod: '^4.0.0',\n });\n\n // Pro dev dependencies\n Object.assign(devDependencies, {\n '@stoplight/prism-cli': '^5.14.2',\n });\n\n // Role-based dev scripts\n Object.assign(scripts, {\n 'dev:admin': 'MOCK_USER=admin next dev',\n 'dev:analyst': 'MOCK_USER=analyst next dev',\n 'dev:viewer': 'MOCK_USER=viewer next dev',\n prebuild: 'node scripts/prebuild.js',\n predev: 'node scripts/prebuild.js',\n });\n\n pkg.dependencies = dependencies;\n pkg.devDependencies = devDependencies;\n pkg.scripts = scripts;\n\n await fs.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\\n', 'utf-8');\n}\n\n// ---------------------------------------------------------------------------\n// Workspace config scaffolding (.code-puppy/ directory)\n// ---------------------------------------------------------------------------\n\nasync function scaffoldWorkspaceConfig(targetDir: string): Promise<void> {\n const workspaceDir = path.join(targetDir, '.code-puppy');\n await fs.ensureDir(workspaceDir);\n await fs.ensureDir(path.join(workspaceDir, 'agents'));\n\n // config.json — projectOnly: true\n // Merge with existing so we don't clobber user customizations on re-scaffold\n const configPath = path.join(workspaceDir, 'config.json');\n let existingConfig: Record<string, unknown> = {};\n if (fs.existsSync(configPath)) {\n try {\n existingConfig = JSON.parse(await fs.readFile(configPath, 'utf-8')) as Record<\n string,\n unknown\n >;\n } catch {\n // Malformed — start fresh\n }\n }\n await fs.writeFile(\n configPath,\n JSON.stringify({ ...existingConfig, projectOnly: true }, null, 2) + '\\n',\n 'utf-8'\n );\n\n // mcp_servers.json — pnpm-based stackwright-pro-mcp server\n // ${PROJECT_ROOT} is a literal — raft-puppy expands it at runtime to the\n // directory containing .code-puppy/ (walk-up discovery root).\n const mcpServersPath = path.join(workspaceDir, 'mcp_servers.json');\n if (!fs.existsSync(mcpServersPath)) {\n const mcpConfig = {\n mcp_servers: {\n 'stackwright-pro-mcp': {\n type: 'stdio',\n command: 'pnpm',\n args: ['exec', 'stackwright-pro-mcp'],\n enabled: true,\n cwd: '${PROJECT_ROOT}',\n },\n },\n };\n await fs.writeFile(mcpServersPath, JSON.stringify(mcpConfig, null, 2) + '\\n', 'utf-8');\n }\n}\n\nasync function addIntegrationToStackwrightYml(\n targetDir: string,\n specName: string,\n specFilename: string,\n mockUrl?: string\n): Promise<void> {\n const ymlPath = path.join(targetDir, 'stackwright.yml');\n const content = await fs.readFile(ymlPath, 'utf-8');\n const config = yaml.load(content, { schema: yaml.CORE_SCHEMA }) as Record<string, unknown>;\n\n const integration: Record<string, unknown> = {\n type: 'openapi',\n name: specName,\n spec: `./specs/${specFilename}`,\n collections: [],\n };\n\n if (mockUrl) {\n integration.mockUrl = mockUrl;\n }\n\n config.integrations = [\n ...(Array.isArray(config.integrations) ? config.integrations : []),\n integration,\n ];\n\n await fs.writeFile(ymlPath, yaml.dump(config, { lineWidth: 120 }));\n}\n\n// ---------------------------------------------------------------------------\n// Spec handling (Pro-specific - hooks can't handle these)\n// ---------------------------------------------------------------------------\n\nasync function handleSpec(\n targetDir: string,\n specPath: string,\n specName?: string\n): Promise<{ specFilename: string; derivedName: string }> {\n const resolvedSpec = path.resolve(specPath);\n\n if (!fs.existsSync(resolvedSpec)) {\n throw new Error(`Spec file not found: ${resolvedSpec}`);\n }\n\n const specFilename = path.basename(resolvedSpec);\n const derivedName = specName || path.basename(specFilename, path.extname(specFilename));\n\n const specsDir = path.join(targetDir, 'specs');\n await fs.ensureDir(specsDir);\n await fs.copy(resolvedSpec, path.join(specsDir, specFilename));\n\n return { specFilename, derivedName };\n}\n\n// ---------------------------------------------------------------------------\n// README generator (Pro-specific - hooks can't handle these)\n// ---------------------------------------------------------------------------\n\nfunction generateReadme(options: {\n projectName: string;\n hasSpec: boolean;\n specName?: string;\n specFilename?: string;\n hasOtters: boolean;\n hasMock: boolean;\n}): string {\n const { projectName, hasSpec, specName, specFilename, hasOtters, hasMock } = options;\n\n // Build API Integration section if spec is present\n const apiIntegrationSection = hasSpec\n ? `## 📡 API Integration\n\nYour OpenAPI spec was copied to \\`specs/${specFilename}\\` and wired up in \\`stackwright.yml\\`.\n\n**What gets generated:**\n\n\\`\\`\\`typescript\n// src/generated/${specName}/schemas.ts\nexport const EquipmentSchema = z.object({\n id: z.string(),\n name: z.string(),\n status: z.enum(['operational', 'maintenance', 'retired']),\n // ... Zod validation for runtime safety\n});\n\n// src/generated/${specName}/types.ts\nexport type Equipment = z.infer<typeof EquipmentSchema>;\n\n// src/generated/${specName}/client.ts\nexport class ${specName!.charAt(0).toUpperCase() + specName!.slice(1)}Client {\n async getEquipment(id: string): Promise<Equipment> {\n // Auto-wired with auth, validation, error handling\n }\n}\n\\`\\`\\`\n\n**How it works:**\n1. The \\`predev\\` script in \\`package.json\\` runs \\`prebuild.js\\` before every \\`pnpm dev\\`\n2. Prebuild reads your spec and generates type-safe code\n3. You import and use it:\n\n\\`\\`\\`typescript\nimport { ${specName!.charAt(0).toUpperCase() + specName!.slice(1)}Client } from '@/generated/${specName}/client';\nimport type { Equipment } from '@/generated/${specName}/types';\n\nconst client = new ${specName!.charAt(0).toUpperCase() + specName!.slice(1)}Client();\nconst gear: Equipment = await client.getEquipment('123');\n\\`\\`\\`\n\nNo manual typing. No drift. No runtime surprises.\n\n`\n : '';\n\n // Build mock server section if enabled\n const mockSection = hasMock\n ? `## 🎭 Mock Server\n\nPrism mock server is configured to serve your API at **http://localhost:4010**.\n\n\\`\\`\\`bash\npnpm dev:mock # Starts Prism + Next.js together\n\\`\\`\\`\n\nThis starts:\n1. Prism mock server on port 4010 (serves your OpenAPI spec)\n2. Next.js dev server on port 3000\n\nThe generated API client is automatically configured to use the mock server.\n\n`\n : '';\n\n // Build AI Agents section if otters are present\n const aiAgentsSection = hasOtters\n ? `## 🦦 AI Agents (The Otter Raft)\n\nYour project includes **SIX specialized AI agents** in \\`node_modules/@stackwright-pro/otters/\\`:\n\n- \\`stackwright-pro-foreman-otter\\` - Master coordinator that orchestrates all specialist otters\n- \\`stackwright-pro-api-otter\\` - Discovers entities from OpenAPI specs\n- \\`stackwright-pro-auth-otter\\` - Configures CAC/OIDC auth, RBAC rules, and audit middleware\n- \\`stackwright-pro-data-otter\\` - Configures endpoint filters & ISR revalidation\n- \\`stackwright-pro-page-otter\\` - Generates pages auto-wired with data, theme, and auth\n- \\`stackwright-pro-dashboard-otter\\` - Builds live data dashboards\n\n**Start the otter raft:**\n\n\\`\\`\\`bash\nnpx @stackwright-pro/raft\n\\`\\`\\`\n\nThe raft verifies otter integrity, writes project context, and spawns code-puppy in foreman mode. The foreman asks questions about your brand, auth, and data preferences, then coordinates specialist otters to build your app. All state lives in \\`.stackwright/\\` — interrupt and resume anytime.\n\n**Example session prompt:**\n\n\"Build me a logistics dashboard from our OpenAPI spec. Connect to /equipment and /supplies endpoints.\"\n\n`\n : '';\n\n return `# ${projectName}\n\nA Stackwright Pro application with role-based auth, OpenAPI integration, and intelligent AI agents.\n\n## 🚀 Quick Start\n\n\\`\\`\\`bash\n# Start development server\npnpm dev\n\n# Open your browser\nopen http://localhost:3000\n\\`\\`\\`\n\n## 👥 Role-Based Development\n\nStackwright Pro includes **mock authentication** for local development with three pre-configured roles:\n\n\\`\\`\\`bash\npnpm dev:admin # Full permissions (*)\npnpm dev:analyst # Read & write data\npnpm dev:viewer # Read-only access\n\\`\\`\\`\n\n**How it works:**\n- Each script sets the \\`MOCK_USER\\` environment variable\n- \\`lib/mock-auth.ts\\` intercepts requests and injects the appropriate user context\n- Your pages & API routes respect the RBAC rules in \\`stackwright.yml\\`\n- No backend required for testing auth flows! 🎉\n\n**Pro tip:** Test your UI for all three roles to ensure proper permissions enforcement.\n\n${mockSection}## 📁 Project Structure\n\n\\`\\`\\`\n.\n├── pages/\n│ ├── _app.tsx # Pro version with AuthProvider + shadcn\n│ ├── index.tsx # Home page (auto-generated by Stackwright)\n│ ├── about/\n│ │ └── content.yml # Page content in YAML\n│ └── ...\n├── lib/\n│ └── mock-auth.ts # Dev-only auth mocking (no backend needed)\n├── scripts/\n│ └── prebuild.js # Auto-generates code from OpenAPI specs\n├── specs/ # OpenAPI spec files (if --spec was used)\n├── src/\n│ └── generated/ # Auto-generated types & clients\n│ └── {specName}/\n│ ├── schemas.ts # Zod schemas for runtime validation\n│ ├── types.ts # TypeScript types\n│ ├── client.ts # API client with auth\n│ └── provider.ts # CollectionProvider for Stackwright\n├── .stackwright/\n│ └── otters/ # AI agent configs (4 specialized otters)\n├── stackwright.yml # Theme, auth, API integrations\n└── package.json\n\\`\\`\\`\n\n**Key Files:**\n- \\`pages/_app.tsx\\` - Wraps your app with \\`AuthProvider\\` for RBAC\n- \\`stackwright.yml\\` - Single source of truth for theme, auth roles, and API wiring\n- \\`lib/mock-auth.ts\\` - Mocks CAC/PIV headers locally so you can test auth flows\n- \\`scripts/prebuild.js\\` - Runs before dev/build to generate types from your OpenAPI spec\n\n## 📄 Adding Pages\n\nStackwright uses **YAML for content**, so you never touch JSX unless you want to.\n\n**Example:** Create \\`pages/about/content.yml\\`:\n\n\\`\\`\\`yaml\ntitle: About Us\ndescription: Learn more about our mission\n\nsections:\n - type: main\n heading: Who We Are\n body: |\n We build mission-critical logistics systems for the Marine Corps.\n\n - type: feature_list\n title: Our Capabilities\n features:\n - icon: Security\n title: Zero Trust\n description: PKI-based auth with CAC/PIV\n - icon: Api\n title: Real-time Data\n description: OpenAPI-backed, Zod-validated\n\\`\\`\\`\n\nThat's it. Navigate to \\`/about\\` and it just works. No routing config, no React components.\n\n${apiIntegrationSection}## 🎨 Customizing Theme\n\nEdit \\`stackwright.yml\\` to change colors, fonts, spacing — applies everywhere instantly.\n\n\\`\\`\\`yaml\ntheme:\n id: my-theme\n name: My Custom Theme\n colors:\n primary: \"#C41E3A\" # Marine Corps red\n background: \"#FFFFFF\"\n text: \"#1A1A1A\"\n accent: \"#FFD700\" # Gold\n typography:\n fontFamily: \"'Inter', sans-serif\"\n h1Size: \"2.5rem\"\n spacing:\n unit: 8\n\\`\\`\\`\n\nNo CSS files. No theme provider boilerplate. Just YAML. Stackwright handles the rest.\n\n## 🔐 Auth Configuration\n\nStackwright Pro comes with **3 pre-configured roles** in \\`stackwright.yml\\`:\n\n\\`\\`\\`yaml\nauth:\n roles:\n - name: ADMIN\n permissions: ['*'] # Full access\n - name: ANALYST \n permissions: ['data:read', 'data:write'] # Read/write data\n - name: VIEWER\n permissions: ['data:read'] # Read-only\n\\`\\`\\`\n\n**Gate content in your YAML:**\n\n\\`\\`\\`yaml\nsections:\n - type: button\n label: Delete Equipment\n action: /api/equipment/delete\n auth:\n required_roles: [ADMIN]\n fallback: hide # Options: hide, disable, show_message\n\\`\\`\\`\n\nOnly admins see the button. Analysts and viewers? Button doesn't exist in the DOM.\n\n**Route protection:**\n\n\\`\\`\\`yaml\nauth:\n protected_routes:\n - path: /admin/*\n roles: [ADMIN]\n - path: /equipment/* \n roles: [ANALYST, ADMIN]\n public_routes:\n - /\n - /about\n\\`\\`\\`\n\nNo middleware to write. No useAuth hooks to remember. RBAC is declarative.\n\n${aiAgentsSection}## 📚 Learn More\n\n- **Stackwright Docs:** [https://stackwright.dev](https://stackwright.dev)\n- **OSS Repo:** [https://github.com/Per-Aspera-LLC/stackwright](https://github.com/Per-Aspera-LLC/stackwright)\n- **Pro Repo:** [https://github.com/Per-Aspera-LLC/stackwright-pro](https://github.com/Per-Aspera-LLC/stackwright-pro)\n\n**Questions?** File an issue or ping us in the discussions. We're here to help you ship faster.\n`;\n}\n\n// ---------------------------------------------------------------------------\n// Main launch flow\n// ---------------------------------------------------------------------------\n\nasync function launch(targetDir: string, options: LaunchProOptions): Promise<void> {\n const dirName = path.basename(targetDir);\n\n console.log(chalk.cyan.bold('\\n🚢 Launching Stackwright Pro...\\n'));\n\n // ------------------------------------------------------------------\n // 1. Scaffold base OSS project via @stackwright/cli\n // Hooks auto-handle: Pro deps, MCP config, role-based scripts\n // ------------------------------------------------------------------\n\n const scaffoldOpts: ScaffoldOptions = {\n name: options.name || dirName,\n standalone: true, // prevents `workspace:*` refs when CLI runs inside the Pro monorepo\n ...(options.title !== undefined && { title: options.title }),\n ...(options.theme !== undefined && { theme: options.theme }),\n ...(options.force !== undefined && { force: options.force }),\n ...(options.yes !== undefined && { noInteractive: options.yes }),\n };\n\n await scaffold(targetDir, scaffoldOpts);\n console.log(chalk.green('✅ Base project scaffolded (hooks added Pro deps + MCP config)'));\n\n // ------------------------------------------------------------------\n // 1b. Run pnpm install — citizen devs shouldn't need to know this step exists\n // ------------------------------------------------------------------\n\n // Patch Pro packages directly into package.json before install.\n // This bypasses the scaffold hooks system (which has a known version-resolution\n // issue) and guarantees pro deps land regardless of hook execution order.\n await addProDepsToPackageJson(targetDir);\n console.log(chalk.green('🦦 Pro packages added to package.json'));\n\n // Verify package.json has Pro deps before installing\n const verifyPkg = JSON.parse(\n await fs.readFile(path.join(targetDir, 'package.json'), 'utf-8')\n ) as Record<string, any>;\n const proDepCount = Object.keys((verifyPkg.dependencies as Record<string, string>) || {}).filter(\n (k) => k.startsWith('@stackwright-pro')\n ).length;\n console.log(chalk.dim(` → package.json verified: ${proDepCount} @stackwright-pro/* deps ready`));\n\n console.log(chalk.cyan('\\n📦 Installing dependencies (this takes a moment)...'));\n if (!options.skipInstall) {\n try {\n execSync('pnpm install --ignore-workspace', {\n cwd: targetDir,\n stdio: 'inherit',\n timeout: 120_000,\n });\n console.log(chalk.green('✅ Dependencies installed'));\n } catch (err: unknown) {\n const isTimeout =\n err instanceof Error &&\n (err.message.includes('ETIMEDOUT') || err.message.includes('timeout'));\n console.error(\n chalk.red('\\n❌ pnpm install failed. Auth and Pro packages are NOT installed.')\n );\n console.error(\n chalk.red(' Your project is in an incomplete state — do NOT run or deploy it.')\n );\n if (isTimeout) {\n console.error(\n chalk.yellow(' The install timed out (>2 min). Check your network connection.')\n );\n }\n console.error(\n chalk.yellow(` Fix the error above, then run: pnpm install --ignore-workspace`)\n );\n process.exit(1);\n }\n } else {\n console.log(chalk.dim('ℹ️ Skipping install (--skip-install). Run: pnpm install'));\n }\n\n // Fire postInstall hooks now that install has run\n const dependencyMode: 'workspace' | 'standalone' = 'standalone';\n await runScaffoldHooks('postInstall', {\n targetDir,\n projectName: options.name || path.basename(targetDir),\n siteTitle: options.title || options.name || path.basename(targetDir),\n themeId: options.theme || 'corporate',\n packageJson: {},\n dependencyMode,\n });\n\n // ------------------------------------------------------------------\n // 2. Copy Pro templates (hooks can't handle these)\n // ------------------------------------------------------------------\n\n // Replace _app.tsx with Pro version (AuthProvider, shadcn, etc.)\n await copyProTemplate('_app.tsx', path.join(targetDir, 'pages', '_app.tsx'));\n\n // Add root content.yml for the home page\n await copyProTemplate('content.yml', path.join(targetDir, 'pages', 'content.yml'));\n\n // Replace next.config.js with Pro version (transpile pro pkgs)\n await copyProTemplate('next.config.js', path.join(targetDir, 'next.config.js'));\n\n // Add lib/mock-auth.ts\n await fs.ensureDir(path.join(targetDir, 'lib'));\n await copyProTemplate('mock-auth.ts', path.join(targetDir, 'lib', 'mock-auth.ts'));\n\n // Add yaml.d.ts for TypeScript support\n await copyProTemplate('yaml.d.ts', path.join(targetDir, 'yaml.d.ts'));\n\n // Add scripts/prebuild.js + scripts/pro-content-plugin.js\n await fs.ensureDir(path.join(targetDir, 'scripts'));\n await copyProTemplate('prebuild.js', path.join(targetDir, 'scripts', 'prebuild.js'));\n await copyProTemplate(\n 'scripts/pro-content-plugin.js',\n path.join(targetDir, 'scripts', 'pro-content-plugin.js')\n );\n\n console.log(chalk.green('🔐 Auth integration added (RBAC with 3 roles)'));\n\n // ------------------------------------------------------------------\n // 3. Add auth section to stackwright.yml\n // ------------------------------------------------------------------\n\n await addAuthToStackwrightYml(targetDir);\n\n // ------------------------------------------------------------------\n // 4. Handle --spec if provided\n // ------------------------------------------------------------------\n\n let specInfo: { specFilename: string; derivedName: string } | null = null;\n const MOCK_URL = 'http://localhost:4010';\n\n if (options.spec && options.spec.length > 0) {\n for (const specPath of options.spec) {\n specInfo = await handleSpec(targetDir, specPath, options.specName);\n await addIntegrationToStackwrightYml(\n targetDir,\n specInfo.derivedName,\n specInfo.specFilename,\n options.mock ? MOCK_URL : undefined\n );\n }\n console.log(chalk.green(`📡 ${options.spec.length} OpenAPI integration(s) wired up`));\n if (options.mock) {\n console.log(chalk.green('🎭 Prism mock server configured'));\n }\n } else if (options.mock) {\n // --mock without --spec: use sample Petstore spec for demo\n console.log(\n chalk.yellow(\n '⚠️ No spec provided with --mock. Using sample Petstore spec for demo. Replace with your API spec.'\n )\n );\n\n const specsDir = path.join(targetDir, 'specs');\n await fs.ensureDir(specsDir);\n await copyProTemplate('petstore.yaml', path.join(specsDir, 'petstore.yaml'));\n\n specInfo = { specFilename: 'petstore.yaml', derivedName: 'petstore' };\n\n await addIntegrationToStackwrightYml(\n targetDir,\n specInfo.derivedName,\n specInfo.specFilename,\n MOCK_URL\n );\n console.log(chalk.green('📡 Sample Petstore spec wired up'));\n console.log(chalk.green('🎭 Prism mock server configured'));\n }\n\n // ------------------------------------------------------------------\n // 5. Generate README\n // ------------------------------------------------------------------\n\n const readmeContent = generateReadme({\n projectName: options.name || dirName,\n hasSpec: !!specInfo,\n ...(specInfo?.derivedName !== undefined && { specName: specInfo.derivedName }),\n ...(specInfo?.specFilename !== undefined && { specFilename: specInfo.specFilename }),\n hasOtters: !options.skipOtters,\n hasMock: !!options.mock,\n });\n\n await fs.writeFile(path.join(targetDir, 'README.md'), readmeContent);\n console.log(chalk.green('📄 README.md created'));\n\n // ------------------------------------------------------------------\n // 5b. Write init-context.json for raft launcher\n // ------------------------------------------------------------------\n\n const initContext: Record<string, unknown> = {\n projectRoot: targetDir,\n projectName: options.name || dirName,\n generatedBy: 'launch-stackwright-pro',\n version: '1.0',\n };\n\n if (specInfo) {\n initContext.specPath = `specs/${specInfo.specFilename}`;\n initContext.specName = specInfo.derivedName;\n }\n\n initContext.theme = options.theme || 'corporate';\n\n const stackwrightDir = path.join(targetDir, '.stackwright');\n await fs.ensureDir(stackwrightDir);\n await fs.writeFile(\n path.join(stackwrightDir, 'init-context.json'),\n JSON.stringify(initContext, null, 2) + '\\n',\n 'utf-8'\n );\n\n // ------------------------------------------------------------------\n // 5c. Scaffold .code-puppy/ workspace directory\n // Creates config.json (projectOnly: true), mcp_servers.json,\n // and agents/ dir. raft-puppy discovers this via walk-up from cwd\n // on first startup — no CLI flags needed.\n // ------------------------------------------------------------------\n\n await scaffoldWorkspaceConfig(targetDir);\n console.log(chalk.green('🐾 .code-puppy/ workspace scaffolded (projectOnly: true)'));\n\n // ------------------------------------------------------------------\n // 6. Print next steps\n // ------------------------------------------------------------------\n\n const relDir = path.relative(process.cwd(), targetDir) || '.';\n\n console.log(chalk.cyan.bold(\"\\n🎉 All set! Here's what to do next:\\n\"));\n console.log(chalk.white(` 1. cd ${relDir}`));\n console.log(chalk.white(' 2. npx @stackwright-pro/raft'));\n console.log(chalk.dim(' (use --verbose for troubleshooting)'));\n\n if (specInfo) {\n console.log(chalk.cyan(`\\n📡 Your API spec was copied to specs/${specInfo.specFilename}`));\n console.log(chalk.dim(' The prebuild will generate types & client on first `pnpm dev`.'));\n }\n\n if (options.mock) {\n console.log(chalk.cyan('\\n🎭 Run with mock server:'));\n console.log(chalk.white(' pnpm dev:mock # Starts Prism + Next.js'));\n }\n\n if (!options.skipOtters) {\n console.log(chalk.cyan.bold('\\n🦦 The otter raft is ready to build your site!'));\n console.log(chalk.dim(' Run the command above to get started.\\n'));\n }\n}\n\n// ---------------------------------------------------------------------------\n// CLI definition\n// ---------------------------------------------------------------------------\n\nasync function main(): Promise<void> {\n const program = new Command();\n\n program\n .name('launch-stackwright-pro')\n .description('🚢 Launch a new Stackwright Pro project with auth, OpenAPI, and the otter raft')\n .version(version)\n .argument('[directory]', 'Project directory', '.')\n .option('--name <name>', 'Project name (used in package.json)')\n .option('--title <title>', 'Site title shown in the app bar and browser tab')\n .option('--theme <themeId>', 'Theme ID (e.g., corporate, creative, minimal)')\n .option('--force', 'Launch even if the target directory is not empty')\n .option('--skip-otters', 'Skip copying otter raft configs')\n .option('-y, --yes', 'Skip all prompts, use defaults')\n .option('--mock', 'Configure Prism mock server for API development (runs on port 4010)')\n .option(\n '--spec <paths...>',\n 'Paths to OpenAPI specs (YAML or JSON) — copies into project and wires up integrations (can be specified multiple times)'\n )\n .option(\n '--spec-name <name>',\n 'Name for the API integration (default: derived from spec filename)'\n )\n .option(\n '--skip-install',\n 'Skip automatic pnpm install (useful in CI or when using a different package manager)'\n )\n .action(async (directory: string, options: LaunchProOptions) => {\n const homeDir = os.homedir();\n const targetDir =\n directory !== '.'\n ? path.resolve(process.cwd(), directory)\n : options.name\n ? path.resolve(process.cwd(), options.name)\n : process.cwd(); // last resort — same as old behaviour, only hit if neither arg nor --name\n\n // Warn (don't block) when scaffolding outside home dir — unusual for a user-facing CLI\n if (!targetDir.startsWith(homeDir + path.sep) && targetDir !== homeDir) {\n console.warn(chalk.yellow(`⚠️ Scaffolding outside your home directory: ${targetDir}`));\n }\n\n await launch(targetDir, options);\n });\n\n await program.parseAsync(process.argv);\n}\n\nmain().catch((err: unknown) => {\n console.error(chalk.red('\\n❌ Launch failed:'), err);\n process.exit(1);\n});\n","// AUTO-GENERATED — do not edit manually.\n// Run `pnpm sync-versions` or `pnpm build` to regenerate.\n//\n// PRO_VERSIONS: exact versions of @stackwright-pro/* packages in this workspace.\n// OSS_VERSIONS: minimum tested versions of @stackwright/* OSS packages (caret range).\n\n/**\n * Exact versions of every @stackwright-pro/* package currently in the workspace.\n * Used by launch-stackwright-pro and scaffold-hooks to pin deps in scaffolded projects.\n * Updated automatically on every build — never edit this file by hand.\n */\nexport const PRO_VERSIONS = {\n '@stackwright-pro/auth': '0.2.0-alpha.4',\n '@stackwright-pro/auth-nextjs': '0.2.0-alpha.4',\n '@stackwright-pro/display-components': '0.2.0-alpha.5',\n '@stackwright-pro/mcp': '0.2.0-alpha.32',\n '@stackwright-pro/openapi': '0.3.0-alpha.12',\n '@stackwright-pro/otters': '1.0.0-alpha.31',\n '@stackwright-pro/pulse': '0.3.0-alpha.7',\n '@stackwright-pro/workflow': '0.1.0-alpha.8',\n '@stackwright-pro/workflow-components': '0.1.0-alpha.10',\n} as const satisfies Record<string, string>;\n\n/**\n * Minimum tested versions of @stackwright/* OSS packages.\n * Caret ranges anchored to the last version resolved in pnpm-lock.yaml.\n * Updated automatically on every build.\n */\nexport const OSS_VERSIONS = {\n '@stackwright/build-scripts': '^0.7.0',\n '@stackwright/core': '^0.8.2',\n '@stackwright/icons': '^0.5.2',\n '@stackwright/mcp': '^0.4.5',\n '@stackwright/nextjs': '^0.5.3',\n '@stackwright/otters': '^0.2.0',\n '@stackwright/ui-shadcn': '^0.1.0',\n} as const satisfies Record<string, string>;\n"],"mappings":"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","names":["exports","module","path","fs","yaml","chalk","os"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackwright-pro/launch-stackwright-pro",
3
- "version": "0.4.0-alpha.6",
3
+ "version": "0.4.0-alpha.60",
4
4
  "description": "Launch a new Stackwright Pro project with OpenAPI integration, auth, and the otter raft",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -26,13 +26,18 @@
26
26
  "launch-stackwright-pro": "dist/index.js"
27
27
  },
28
28
  "dependencies": {
29
- "@stackwright/cli": "^0.7.0",
29
+ "@stackwright-pro/scaffold-hooks": "latest",
30
+ "@stackwright/cli": "^0.7.1-alpha.0",
30
31
  "@stackwright/scaffold-core": "^0.1.0",
31
32
  "chalk": "^5.6.2",
32
33
  "commander": "^14.0.3",
33
34
  "fs-extra": "^11.3",
34
35
  "js-yaml": "^4.1.0",
35
- "@stackwright-pro/scaffold-hooks": "1.0.0-alpha.2"
36
+ "@stackwright-pro/auth": "0.2.0-alpha.4",
37
+ "@stackwright-pro/mcp": "0.2.0-alpha.32",
38
+ "@stackwright-pro/openapi": "0.3.0-alpha.12",
39
+ "@stackwright-pro/auth-nextjs": "0.2.0-alpha.4",
40
+ "@stackwright-pro/otters": "1.0.0-alpha.31"
36
41
  },
37
42
  "devDependencies": {
38
43
  "@types/fs-extra": "^11.0",
@@ -43,7 +48,8 @@
43
48
  "vitest": "^4.0.18"
44
49
  },
45
50
  "scripts": {
46
- "build": "tsup",
51
+ "build": "node ../../scripts/sync-versions.mjs && tsup",
52
+ "sync-versions": "node ../../scripts/sync-versions.mjs",
47
53
  "dev": "tsup --watch",
48
54
  "test": "vitest run",
49
55
  "test:coverage": "vitest run --coverage"
@@ -6,7 +6,17 @@ import { registerDisplayComponents } from '@stackwright-pro/display-components';
6
6
  import { registerPulseComponents } from '@stackwright-pro/pulse';
7
7
  import { AuthProvider } from '@stackwright-pro/auth';
8
8
  import '@stackwright/ui-shadcn/styles.css';
9
- import authConfig from '../src/auth-config.json'; // Generated at build time by prebuild.js
9
+ import authConfigRaw from '../src/auth-config.json'; // Generated at build time by prebuild.js
10
+
11
+ // auth-config.json is written from stackwright.yml `auth:` section — it may be
12
+ // sparse (e.g. `{}`) when roles haven't been configured yet, so we cast to the
13
+ // full shape and use || fallbacks below.
14
+ type AuthConfigShape = {
15
+ roles?: Array<{ name: string; permissions?: string[] }>;
16
+ protected_routes?: Array<{ path: string; roles: string[] }>;
17
+ public_routes?: string[];
18
+ };
19
+ const authConfig = authConfigRaw as AuthConfigShape;
10
20
 
11
21
  // Register Stackwright components
12
22
  registerNextJSComponents();
@@ -24,9 +34,9 @@ export default function App({ Component, pageProps }: AppProps) {
24
34
  user={user}
25
35
  session={session}
26
36
  rbacConfig={{
27
- roles: authConfig.roles || [],
28
- protected_routes: authConfig.protected_routes || [],
29
- public_routes: authConfig.public_routes || [],
37
+ roles: authConfig.roles ?? [],
38
+ protected_routes: authConfig.protected_routes ?? [],
39
+ public_routes: authConfig.public_routes ?? [],
30
40
  }}
31
41
  >
32
42
  <Component {...pageProps} />
@@ -1,105 +1,82 @@
1
1
  /**
2
2
  * Stackwright Pro prebuild script
3
3
  *
4
- * Runs stackwright-prebuild to generate content JSON files from YAML,
5
- * then runs the OpenAPI plugin to generate API client code.
6
- * Also extracts auth config and generates auth-config.json for client-side use.
4
+ * Uses runPrebuild() from @stackwright/build-scripts directly with the pro
5
+ * content plugin, enabling pro content types to pass schema validation
6
+ * alongside OSS content types.
7
+ *
8
+ * Also runs the OpenAPI plugin for API client generation and extracts
9
+ * auth config for client-side use.
10
+ *
11
+ * Requires @stackwright/build-scripts >= 0.7.0
7
12
  */
8
13
 
9
- const { spawn } = require('child_process');
14
+ 'use strict';
15
+
10
16
  const fs = require('fs');
11
17
  const path = require('path');
12
18
  const yaml = require('js-yaml');
13
- const { createOpenAPIPlugin } = require('@stackwright-pro/openapi');
14
-
15
- /**
16
- * Run stackwright-prebuild to generate _root.json, _site.json, etc.
17
- */
18
- async function runStackwrightPrebuild(projectRoot) {
19
- return new Promise((resolve, reject) => {
20
- // Use pnpm exec to ensure we use the correct package manager
21
- const proc = spawn(process.platform === 'win32' ? 'pnpm.cmd' : 'pnpm', ['exec', 'stackwright-prebuild'], {
22
- cwd: projectRoot,
23
- stdio: 'inherit',
24
- shell: true,
25
- });
26
- proc.on('close', (code) => {
27
- if (code === 0) {
28
- resolve();
29
- } else {
30
- reject(new Error(`stackwright-prebuild exited with code ${code}`));
31
- }
32
- });
33
- proc.on('error', reject);
34
- });
35
- }
19
+ const { runPrebuild } = require('@stackwright/build-scripts');
20
+ const { createWorkflowPlugin } = require('@stackwright-pro/workflow');
21
+ const { proContentPlugin } = require('./pro-content-plugin');
36
22
 
37
23
  /**
38
24
  * Parse full stackwright.yml using js-yaml for complete config parsing
39
25
  */
40
26
  function parseStackwrightYml(content) {
41
- return yaml.load(content);
27
+ return yaml.load(content, { schema: yaml.CORE_SCHEMA });
42
28
  }
43
29
 
44
30
  async function main() {
45
- try {
46
- const projectRoot = path.resolve(__dirname, '..');
47
-
48
- const configPath = path.join(projectRoot, 'stackwright.yml');
49
- if (!fs.existsSync(configPath)) {
50
- console.log('No stackwright.yml found — skipping prebuild.');
51
- return;
52
- }
31
+ const projectRoot = path.resolve(__dirname, '..');
53
32
 
54
- // Run stackwright-prebuild first to generate content JSON files
55
- console.log('Generating content files...');
56
- await runStackwrightPrebuild(projectRoot);
57
-
58
- const configContent = fs.readFileSync(configPath, 'utf-8');
59
- const fullConfig = parseStackwrightYml(configContent);
60
-
61
- // Extract auth config and write as JSON for client-side use
62
- if (fullConfig.auth) {
63
- const authConfig = fullConfig.auth;
64
- const srcDir = path.join(projectRoot, 'src');
65
-
66
- if (!fs.existsSync(srcDir)) {
67
- fs.mkdirSync(srcDir, { recursive: true });
68
- }
69
-
70
- fs.writeFileSync(
71
- path.join(srcDir, 'auth-config.json'),
72
- JSON.stringify(authConfig, null, 2)
73
- );
74
- console.log('✓ Generated src/auth-config.json');
75
- }
33
+ const configPath = path.join(projectRoot, 'stackwright.yml');
34
+ if (!fs.existsSync(configPath)) {
35
+ console.log('No stackwright.yml found — skipping prebuild.');
36
+ return;
37
+ }
76
38
 
77
- // Extract integrations for OpenAPI plugin
78
- const siteConfig = { integrations: fullConfig.integrations || [] };
39
+ const configContent = fs.readFileSync(configPath, 'utf-8');
40
+ const fullConfig = parseStackwrightYml(configContent);
79
41
 
80
- if (!siteConfig.integrations.length) {
81
- console.log('No integrations in stackwright.yml — skipping OpenAPI plugin.');
82
- console.log('✓ Prebuild complete!');
83
- return;
84
- }
42
+ // Assemble plugins
43
+ const workflowPlugin = createWorkflowPlugin();
44
+ const plugins = [proContentPlugin, workflowPlugin];
85
45
 
86
- console.log(`Found ${siteConfig.integrations.length} integration(s). Running OpenAPI plugin...`);
46
+ const integrations = fullConfig.integrations || [];
47
+ if (integrations.length > 0) {
48
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
49
+ const { createOpenAPIPlugin } = require('@stackwright-pro/openapi');
50
+ plugins.push(createOpenAPIPlugin());
51
+ console.log(` OpenAPI plugin: loaded (${integrations.length} integrations)`);
52
+ }
87
53
 
88
- const plugin = createOpenAPIPlugin();
54
+ // Run prebuild with all plugins
55
+ console.log('Generating content files...');
56
+ await runPrebuild({
57
+ projectRoot,
58
+ plugins,
59
+ unknownContentTypes: 'warn', // log warnings for unknown types instead of failing build
60
+ });
89
61
 
90
- if (plugin.beforeBuild) {
91
- await plugin.beforeBuild({
92
- siteConfig,
93
- projectRoot,
94
- });
62
+ // Extract auth config and write as JSON for client-side use
63
+ if (fullConfig.auth) {
64
+ const srcDir = path.join(projectRoot, 'src');
65
+ if (!fs.existsSync(srcDir)) {
66
+ fs.mkdirSync(srcDir, { recursive: true });
95
67
  }
96
-
97
- console.log('✓ Prebuild complete!');
98
- } catch (error) {
99
- console.error('Prebuild failed:', error.message);
100
- console.error(error.stack);
101
- process.exit(1);
68
+ fs.writeFileSync(
69
+ path.join(srcDir, 'auth-config.json'),
70
+ JSON.stringify(fullConfig.auth, null, 2)
71
+ );
72
+ console.log('✓ Generated src/auth-config.json');
102
73
  }
74
+
75
+ console.log('✓ Prebuild complete!');
103
76
  }
104
77
 
105
- main();
78
+ main().catch((err) => {
79
+ console.error('Prebuild failed:', err.message);
80
+ console.error(err.stack);
81
+ process.exit(1);
82
+ });
@@ -0,0 +1,75 @@
1
+ // packages/launch-stackwright-pro/templates/pro/scripts/pro-content-plugin.js
2
+ //
3
+ // Pro content type plugin for @stackwright/build-scripts.
4
+ //
5
+ // CONFIRMED CASE B (@stackwright/build-scripts@0.5.0-alpha.0 / types@1.2.0-alpha.0):
6
+ // The currently shipped version of build-scripts does NOT read
7
+ // `contentItemSchemas` or `knownContentTypeKeys` from plugin objects.
8
+ // Those fields first appear in @stackwright/types@1.4.0+ and will be
9
+ // consumed by build-scripts@0.7.0 when that release ships.
10
+ //
11
+ // CURRENT BEHAVIOUR (pre-0.7.0):
12
+ // `unknownContentTypes: 'warn'` in prebuild.js already prevents hard failures
13
+ // for unrecognised content types. The `beforeBuild` stub below ensures this
14
+ // plugin is a syntactically valid, callable plugin (not silently ignored by
15
+ // the plugin runner) even though there is no side-effect to execute yet.
16
+ //
17
+ // TODO(@stackwright/build-scripts@0.7.0): Once 0.7.0 is the resolved floor,
18
+ // remove the `beforeBuild` stub — `contentItemSchemas` and
19
+ // `knownContentTypeKeys` will be consumed natively by the runtime and the
20
+ // plugin will suppress "unknown content type" warnings automatically.
21
+
22
+ 'use strict';
23
+
24
+ const { z } = require('zod');
25
+
26
+ const PRO_CONTENT_TYPE_KEYS = [
27
+ // @stackwright-pro/display-components
28
+ 'metric_card',
29
+ 'status_badge',
30
+ 'stat_bar',
31
+ 'sparkline',
32
+ 'activity_feed',
33
+ 'dashboard_grid',
34
+ 'data_table',
35
+ 'json_viewer',
36
+ 'action_bar',
37
+ 'section',
38
+ 'collection_listing',
39
+ // @stackwright-pro/pulse
40
+ 'pulse_provider',
41
+ 'metric_card_pulse',
42
+ 'data_table_pulse',
43
+ 'status_badge_pulse',
44
+ 'stats_grid',
45
+ 'alert_banner',
46
+ // @stackwright-pro/workflow-components
47
+ 'workflow_mount',
48
+ ];
49
+
50
+ const proContentPlugin = {
51
+ name: 'pro-content',
52
+
53
+ // --- Fields read by build-scripts@0.7.0+ (types@1.4.0+) ---
54
+ // Passthrough schemas — let each component handle its own prop validation
55
+ // at runtime. Registered here so the prebuild content-item validator
56
+ // accepts pro types without errors.
57
+ contentItemSchemas: PRO_CONTENT_TYPE_KEYS.map((type) =>
58
+ z.object({ type: z.literal(type) }).passthrough()
59
+ ),
60
+ // String keys so the prebuild skips "unknown content type" warnings.
61
+ knownContentTypeKeys: PRO_CONTENT_TYPE_KEYS,
62
+
63
+ // --- Stub lifecycle hook (required for build-scripts@0.5.x / types@1.2.x) ---
64
+ // build-scripts@0.5.x only calls plugins that have beforeBuild or afterBuild.
65
+ // Without this stub the plugin object is accepted but never invoked, making
66
+ // the whole registration a silent no-op. The stub has no side-effects; its
67
+ // only purpose is to keep the plugin in the active lifecycle.
68
+ //
69
+ // Remove this stub when build-scripts@0.7.0 is the resolved floor (the
70
+ // 0.7.x runner calls plugins purely for their schema/key registration,
71
+ // not via beforeBuild/afterBuild).
72
+ beforeBuild: () => {},
73
+ };
74
+
75
+ module.exports = { proContentPlugin };