launch-stackwright 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Per Aspera Sapientia LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # 🚢 launch-stackwright
2
+
3
+ The fastest way to get started with Stackwright — launch a new project with the otter raft ready to build.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npx launch-stackwright my-awesome-site
9
+ cd my-awesome-site
10
+ pnpm install
11
+ pnpm dev
12
+ ```
13
+
14
+ ## What You Get
15
+
16
+ When you run `launch-stackwright`, you get:
17
+
18
+ - ✅ A fully configured Next.js + Stackwright project
19
+ - ✅ Theme configuration (`stackwright.yml`)
20
+ - ✅ Example pages in YAML
21
+ - ✅ **The Otter Raft** 🦦🦦🦦🦦 — AI agents ready to build your site
22
+
23
+ ## Using the Otter Raft
24
+
25
+ After launching your project, invoke the Foreman Otter to orchestrate your entire site build:
26
+
27
+ ```bash
28
+ code-puppy invoke stackwright-foreman-otter
29
+ ```
30
+
31
+ Then say: **"Build me a [law firm / wellness startup / SaaS marketing] website"**
32
+
33
+ The raft includes four specialized otters:
34
+ - 🦦🏗️ **Foreman Otter** — Coordinates the entire build
35
+ - 🦦🎨 **Brand Otter** — Discovers your brand through conversation
36
+ - 🦦🌈 **Theme Otter** — Designs your visual theme
37
+ - 🦦📄 **Page Otter** — Builds your content pages
38
+
39
+ ## CLI Options
40
+
41
+ ```bash
42
+ launch-stackwright [directory] [options]
43
+
44
+ Options:
45
+ --name <name> Project name (used in package.json)
46
+ --title <title> Site title shown in app bar and browser tab
47
+ --theme <themeId> Theme ID (corporate, creative, minimal, etc.)
48
+ --force Launch even if directory is not empty
49
+ --skip-otters Skip copying otter raft configs
50
+ -y, --yes Skip all prompts, use defaults
51
+ -V, --version Output version number
52
+ -h, --help Display help
53
+ ```
54
+
55
+ ## Examples
56
+
57
+ ```bash
58
+ # Interactive mode (default)
59
+ npx launch-stackwright my-site
60
+
61
+ # Specify everything upfront
62
+ npx launch-stackwright my-site --name "my-awesome-app" --title "My Awesome Site" --theme corporate
63
+
64
+ # Quick start with defaults
65
+ npx launch-stackwright my-site --yes
66
+
67
+ # Skip otter setup (just scaffold the project)
68
+ npx launch-stackwright my-site --skip-otters
69
+ ```
70
+
71
+ ## What Gets Created
72
+
73
+ ```
74
+ my-awesome-site/
75
+ ├── .code-puppy.json # Code Puppy + MCP auto-config
76
+ ├── .stackwright/
77
+ │ └── otters/ # The otter raft configs
78
+ │ ├── stackwright-foreman-otter.json
79
+ │ ├── stackwright-brand-otter.json
80
+ │ ├── stackwright-theme-otter.json
81
+ │ └── stackwright-page-otter.json
82
+ ├── pages/
83
+ │ ├── content.yml # Home page
84
+ │ ├── about/content.yml # About page
85
+ │ ├── [...slug].tsx # Dynamic page router
86
+ │ └── _app.tsx # Next.js app wrapper
87
+ ├── stackwright.yml # Theme configuration
88
+ ├── next.config.js # Next.js config
89
+ ├── package.json # Dependencies
90
+ └── tsconfig.json # TypeScript config
91
+ ```
92
+
93
+ ## Prerequisites
94
+
95
+ - **Node.js** 18+ and **pnpm**
96
+ - **Code Puppy CLI** (optional, for otter raft features)
97
+
98
+ Install Code Puppy:
99
+ ```bash
100
+ npm install -g @peraspera/code-puppy
101
+ ```
102
+
103
+ ## Learn More
104
+
105
+ - [Stackwright Documentation](https://github.com/Per-Aspera-LLC/stackwright)
106
+ - [Otter Raft Architecture](https://github.com/Per-Aspera-LLC/stackwright/blob/main/OTTER_ARCHITECTURE.md)
107
+ - [Code Puppy](https://github.com/Per-Aspera-LLC/code-puppy)
108
+
109
+ ## License
110
+
111
+ MIT
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJS = (cb, mod) => function __require() {
10
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+
29
+ // package.json
30
+ var require_package = __commonJS({
31
+ "package.json"(exports2, module2) {
32
+ module2.exports = {
33
+ name: "launch-stackwright",
34
+ version: "0.1.0",
35
+ description: "Launch a new Stackwright project with the otter raft ready to build",
36
+ license: "MIT",
37
+ repository: {
38
+ type: "git",
39
+ url: "https://github.com/Per-Aspera-LLC/stackwright"
40
+ },
41
+ keywords: [
42
+ "stackwright",
43
+ "scaffolding",
44
+ "website-builder",
45
+ "otters",
46
+ "ai-agents"
47
+ ],
48
+ files: [
49
+ "dist",
50
+ "templates"
51
+ ],
52
+ bin: {
53
+ "launch-stackwright": "dist/index.js"
54
+ },
55
+ scripts: {
56
+ build: "tsup",
57
+ dev: "tsup --watch",
58
+ test: "vitest run"
59
+ },
60
+ dependencies: {
61
+ "@stackwright/cli": "workspace:*",
62
+ chalk: "^5.6.2",
63
+ commander: "^14.0.3",
64
+ "fs-extra": "^11.3",
65
+ prompts: "^2.4.2"
66
+ },
67
+ devDependencies: {
68
+ "@types/fs-extra": "^11.0",
69
+ "@types/node": "^25.4",
70
+ "@types/prompts": "^2.4.9",
71
+ typescript: "^5.0",
72
+ tsup: "^8.5",
73
+ vitest: "^4.0.18"
74
+ }
75
+ };
76
+ }
77
+ });
78
+
79
+ // src/index.ts
80
+ var import_commander = require("commander");
81
+ var import_path = __toESM(require("path"));
82
+ var import_fs_extra = __toESM(require("fs-extra"));
83
+ var import_chalk = __toESM(require("chalk"));
84
+ var import_cli = require("@stackwright/cli");
85
+ var { version } = require_package();
86
+ async function copyOtterRaft(targetDir) {
87
+ const ottersSourceDir = import_path.default.resolve(__dirname, "../templates/otters");
88
+ const ottersTargetDir = import_path.default.join(targetDir, ".stackwright", "otters");
89
+ if (!import_fs_extra.default.existsSync(ottersSourceDir)) {
90
+ console.warn(
91
+ import_chalk.default.yellow(
92
+ "\n\u26A0\uFE0F Could not find otter raft configs. Skipping otter setup.\n You can add them later from: https://github.com/Per-Aspera-LLC/stackwright/tree/main/otters"
93
+ )
94
+ );
95
+ return;
96
+ }
97
+ await import_fs_extra.default.ensureDir(ottersTargetDir);
98
+ const otterFiles = (await import_fs_extra.default.readdir(ottersSourceDir)).filter((f) => f.endsWith(".json"));
99
+ for (const file of otterFiles) {
100
+ await import_fs_extra.default.copy(import_path.default.join(ottersSourceDir, file), import_path.default.join(ottersTargetDir, file));
101
+ }
102
+ const codePuppyConfig = {
103
+ mcp_servers: {
104
+ stackwright: {
105
+ command: "node",
106
+ args: [import_path.default.join(targetDir, "node_modules", "@stackwright", "mcp", "dist", "server.js")],
107
+ env: {
108
+ NODE_ENV: "development"
109
+ }
110
+ }
111
+ },
112
+ agents_path: ".stackwright/otters"
113
+ };
114
+ await import_fs_extra.default.writeFile(
115
+ import_path.default.join(targetDir, ".code-puppy.json"),
116
+ JSON.stringify(codePuppyConfig, null, 2)
117
+ );
118
+ console.log(import_chalk.default.green("\u2705 Otter raft ready! \u{1F9A6}\u{1F9A6}\u{1F9A6}\u{1F9A6}"));
119
+ console.log(import_chalk.default.dim(` Configs copied to: ${import_path.default.relative(process.cwd(), ottersTargetDir)}`));
120
+ }
121
+ async function launch(targetDir, options) {
122
+ const dirName = import_path.default.basename(targetDir);
123
+ console.log(import_chalk.default.cyan.bold("\n\u{1F6A2} Launching Stackwright...\n"));
124
+ const scaffoldOptions = {
125
+ name: options.name || dirName,
126
+ title: options.title,
127
+ theme: options.theme,
128
+ force: options.force,
129
+ noInteractive: options.yes
130
+ };
131
+ try {
132
+ const result = await (0, import_cli.scaffold)(targetDir, scaffoldOptions);
133
+ console.log(import_chalk.default.green(`
134
+ \u2705 Project scaffolded successfully!`));
135
+ console.log(import_chalk.default.dim(` Location: ${result.path}`));
136
+ console.log(import_chalk.default.dim(` Theme: ${result.theme}`));
137
+ console.log(import_chalk.default.dim(` Pages: ${result.pages.join(", ")}`));
138
+ if (!options.skipOtters) {
139
+ console.log(import_chalk.default.cyan("\n\u{1F9A6} Setting up the otter raft...\n"));
140
+ await copyOtterRaft(targetDir);
141
+ }
142
+ console.log(import_chalk.default.cyan.bold("\n\u{1F389} All set! Here's what to do next:\n"));
143
+ console.log(import_chalk.default.white(` 1. cd ${import_path.default.relative(process.cwd(), targetDir) || "."}`));
144
+ console.log(import_chalk.default.white(` 2. pnpm install`));
145
+ console.log(import_chalk.default.white(` 3. pnpm dev`));
146
+ if (!options.skipOtters) {
147
+ console.log(
148
+ import_chalk.default.cyan.bold("\n\u{1F9A6} Want the otter raft to build your site for you?\n")
149
+ );
150
+ console.log(import_chalk.default.white(` code-puppy invoke stackwright-foreman-otter`));
151
+ console.log(import_chalk.default.dim(` Then say: "Build me a [type] website for [name]"
152
+ `));
153
+ }
154
+ } catch (err) {
155
+ console.error(import_chalk.default.red("\n\u274C Launch failed:"), err);
156
+ process.exit(1);
157
+ }
158
+ }
159
+ async function main() {
160
+ const program = new import_commander.Command();
161
+ program.name("launch-stackwright").description("\u{1F6A2} Launch a new Stackwright project with the otter raft ready to build").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").action(async (directory, options) => {
162
+ const targetDir = import_path.default.resolve(directory);
163
+ await launch(targetDir, options);
164
+ });
165
+ await program.parseAsync(process.argv);
166
+ }
167
+ main().catch((err) => {
168
+ console.error(import_chalk.default.red("Internal error:"), err);
169
+ process.exit(2);
170
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env node
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __commonJS = (cb, mod) => function __require() {
4
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
5
+ };
6
+
7
+ // package.json
8
+ var require_package = __commonJS({
9
+ "package.json"(exports, module) {
10
+ module.exports = {
11
+ name: "launch-stackwright",
12
+ version: "0.1.0",
13
+ description: "Launch a new Stackwright project with the otter raft ready to build",
14
+ license: "MIT",
15
+ repository: {
16
+ type: "git",
17
+ url: "https://github.com/Per-Aspera-LLC/stackwright"
18
+ },
19
+ keywords: [
20
+ "stackwright",
21
+ "scaffolding",
22
+ "website-builder",
23
+ "otters",
24
+ "ai-agents"
25
+ ],
26
+ files: [
27
+ "dist",
28
+ "templates"
29
+ ],
30
+ bin: {
31
+ "launch-stackwright": "dist/index.js"
32
+ },
33
+ scripts: {
34
+ build: "tsup",
35
+ dev: "tsup --watch",
36
+ test: "vitest run"
37
+ },
38
+ dependencies: {
39
+ "@stackwright/cli": "workspace:*",
40
+ chalk: "^5.6.2",
41
+ commander: "^14.0.3",
42
+ "fs-extra": "^11.3",
43
+ prompts: "^2.4.2"
44
+ },
45
+ devDependencies: {
46
+ "@types/fs-extra": "^11.0",
47
+ "@types/node": "^25.4",
48
+ "@types/prompts": "^2.4.9",
49
+ typescript: "^5.0",
50
+ tsup: "^8.5",
51
+ vitest: "^4.0.18"
52
+ }
53
+ };
54
+ }
55
+ });
56
+
57
+ // src/index.ts
58
+ import { Command } from "commander";
59
+ import path from "path";
60
+ import fs from "fs-extra";
61
+ import chalk from "chalk";
62
+ import { scaffold } from "@stackwright/cli";
63
+ var { version } = require_package();
64
+ async function copyOtterRaft(targetDir) {
65
+ const ottersSourceDir = path.resolve(__dirname, "../templates/otters");
66
+ const ottersTargetDir = path.join(targetDir, ".stackwright", "otters");
67
+ if (!fs.existsSync(ottersSourceDir)) {
68
+ console.warn(
69
+ chalk.yellow(
70
+ "\n\u26A0\uFE0F Could not find otter raft configs. Skipping otter setup.\n You can add them later from: https://github.com/Per-Aspera-LLC/stackwright/tree/main/otters"
71
+ )
72
+ );
73
+ return;
74
+ }
75
+ await fs.ensureDir(ottersTargetDir);
76
+ const otterFiles = (await fs.readdir(ottersSourceDir)).filter((f) => f.endsWith(".json"));
77
+ for (const file of otterFiles) {
78
+ await fs.copy(path.join(ottersSourceDir, file), path.join(ottersTargetDir, file));
79
+ }
80
+ const codePuppyConfig = {
81
+ mcp_servers: {
82
+ stackwright: {
83
+ command: "node",
84
+ args: [path.join(targetDir, "node_modules", "@stackwright", "mcp", "dist", "server.js")],
85
+ env: {
86
+ NODE_ENV: "development"
87
+ }
88
+ }
89
+ },
90
+ agents_path: ".stackwright/otters"
91
+ };
92
+ await fs.writeFile(
93
+ path.join(targetDir, ".code-puppy.json"),
94
+ JSON.stringify(codePuppyConfig, null, 2)
95
+ );
96
+ console.log(chalk.green("\u2705 Otter raft ready! \u{1F9A6}\u{1F9A6}\u{1F9A6}\u{1F9A6}"));
97
+ console.log(chalk.dim(` Configs copied to: ${path.relative(process.cwd(), ottersTargetDir)}`));
98
+ }
99
+ async function launch(targetDir, options) {
100
+ const dirName = path.basename(targetDir);
101
+ console.log(chalk.cyan.bold("\n\u{1F6A2} Launching Stackwright...\n"));
102
+ const scaffoldOptions = {
103
+ name: options.name || dirName,
104
+ title: options.title,
105
+ theme: options.theme,
106
+ force: options.force,
107
+ noInteractive: options.yes
108
+ };
109
+ try {
110
+ const result = await scaffold(targetDir, scaffoldOptions);
111
+ console.log(chalk.green(`
112
+ \u2705 Project scaffolded successfully!`));
113
+ console.log(chalk.dim(` Location: ${result.path}`));
114
+ console.log(chalk.dim(` Theme: ${result.theme}`));
115
+ console.log(chalk.dim(` Pages: ${result.pages.join(", ")}`));
116
+ if (!options.skipOtters) {
117
+ console.log(chalk.cyan("\n\u{1F9A6} Setting up the otter raft...\n"));
118
+ await copyOtterRaft(targetDir);
119
+ }
120
+ console.log(chalk.cyan.bold("\n\u{1F389} All set! Here's what to do next:\n"));
121
+ console.log(chalk.white(` 1. cd ${path.relative(process.cwd(), targetDir) || "."}`));
122
+ console.log(chalk.white(` 2. pnpm install`));
123
+ console.log(chalk.white(` 3. pnpm dev`));
124
+ if (!options.skipOtters) {
125
+ console.log(
126
+ chalk.cyan.bold("\n\u{1F9A6} Want the otter raft to build your site for you?\n")
127
+ );
128
+ console.log(chalk.white(` code-puppy invoke stackwright-foreman-otter`));
129
+ console.log(chalk.dim(` Then say: "Build me a [type] website for [name]"
130
+ `));
131
+ }
132
+ } catch (err) {
133
+ console.error(chalk.red("\n\u274C Launch failed:"), err);
134
+ process.exit(1);
135
+ }
136
+ }
137
+ async function main() {
138
+ const program = new Command();
139
+ program.name("launch-stackwright").description("\u{1F6A2} Launch a new Stackwright project with the otter raft ready to build").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").action(async (directory, options) => {
140
+ const targetDir = path.resolve(directory);
141
+ await launch(targetDir, options);
142
+ });
143
+ await program.parseAsync(process.argv);
144
+ }
145
+ main().catch((err) => {
146
+ console.error(chalk.red("Internal error:"), err);
147
+ process.exit(2);
148
+ });
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "launch-stackwright",
3
+ "version": "0.1.0",
4
+ "description": "Launch a new Stackwright project with the otter raft ready to build",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/Per-Aspera-LLC/stackwright"
9
+ },
10
+ "keywords": [
11
+ "stackwright",
12
+ "scaffolding",
13
+ "website-builder",
14
+ "otters",
15
+ "ai-agents"
16
+ ],
17
+ "files": [
18
+ "dist",
19
+ "templates"
20
+ ],
21
+ "bin": {
22
+ "launch-stackwright": "dist/index.js"
23
+ },
24
+ "dependencies": {
25
+ "chalk": "^5.6.2",
26
+ "commander": "^14.0.3",
27
+ "fs-extra": "^11.3",
28
+ "prompts": "^2.4.2",
29
+ "@stackwright/cli": "0.7.0-alpha.3"
30
+ },
31
+ "devDependencies": {
32
+ "@types/fs-extra": "^11.0",
33
+ "@types/node": "^25.4",
34
+ "@types/prompts": "^2.4.9",
35
+ "typescript": "^5.0",
36
+ "tsup": "^8.5",
37
+ "vitest": "^4.0.18"
38
+ },
39
+ "scripts": {
40
+ "build": "tsup",
41
+ "dev": "tsup --watch",
42
+ "test": "vitest run"
43
+ }
44
+ }