From 94587aa1e343e8f63d453633b6b04ad3ef19eab3 Mon Sep 17 00:00:00 2001 From: GDS K S Date: Tue, 5 May 2026 19:16:08 -0500 Subject: [PATCH 1/4] fix(npm): use PowerShell Expand-Archive on Windows Windows lacks the unzip command, so the postinstall extraction silently failed and stacklit.exe never landed in npm/bin/. Switch to Expand-Archive (ships with Windows 10+) for .zip on win32, surface extraction output via stdio inherit, and fail loudly when the binary is missing after extraction. Closes #32 --- npm/install.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/npm/install.js b/npm/install.js index d4b2b90..4f15532 100644 --- a/npm/install.js +++ b/npm/install.js @@ -78,10 +78,22 @@ async function install() { } // Extract - if (archivePath.endsWith('.zip') || url.endsWith('.zip')) { - execSync(`unzip -o "${archivePath}" stacklit.exe -d "${binDir}"`, { stdio: 'ignore' }); + if (url.endsWith('.zip')) { + if (os.platform() === 'win32') { + // Windows has no `unzip`. PowerShell Expand-Archive ships with Windows 10+. + execSync( + `powershell -NoProfile -ExecutionPolicy Bypass -Command "Expand-Archive -Force -Path '${archivePath}' -DestinationPath '${binDir}'"`, + { stdio: 'inherit' } + ); + } else { + execSync(`unzip -o "${archivePath}" stacklit.exe -d "${binDir}"`, { stdio: 'inherit' }); + } } else { - execSync(`tar -xzf "${archivePath}" -C "${binDir}" stacklit`, { stdio: 'ignore' }); + execSync(`tar -xzf "${archivePath}" -C "${binDir}" stacklit`, { stdio: 'inherit' }); + } + + if (!fs.existsSync(binPath)) { + throw new Error(`extraction completed but ${binPath} is missing`); } // Make executable From 1f2868dc2034f05933f16669ee4cba7cd4dab303 Mon Sep 17 00:00:00 2001 From: GDS K S Date: Tue, 5 May 2026 19:16:39 -0500 Subject: [PATCH 2/4] docs: align config docs with .stacklitrc.json The README and USAGE guide showed a TOML schema, but the loader in internal/config reads .stacklitrc.json. Update both docs to JSON so the example matches the file the tool actually loads. Closes #34 --- README.md | 20 +++++++++++--------- USAGE.md | 34 +++++++++++++++------------------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 325cc2d..d0f759d 100644 --- a/README.md +++ b/README.md @@ -267,16 +267,18 @@ stacklit setup cursor # configure Cursor + MCP ```
-Configuration (stacklit.toml) +Configuration (.stacklitrc.json) -```toml -ignore = ["vendor/", "generated/"] -max_depth = 3 - -[output] -json = "stacklit.json" -mermaid = "DEPENDENCIES.md" -html = "stacklit.html" +```json +{ + "ignore": ["vendor/", "generated/"], + "max_depth": 3, + "output": { + "json": "stacklit.json", + "mermaid": "DEPENDENCIES.md", + "html": "stacklit.html" + } +} ```
diff --git a/USAGE.md b/USAGE.md index 4524ca4..762cde8 100644 --- a/USAGE.md +++ b/USAGE.md @@ -152,28 +152,24 @@ The server auto-reloads when `stacklit.json` changes on disk. ## Configuration -Create `stacklit.toml` in your project root (optional): +Create `.stacklitrc.json` in your project root (optional): -```toml -# Paths to ignore on top of .gitignore -ignore = ["vendor/", "generated/", "*.pb.go"] - -# Module detection depth (default: 4) -max_depth = 3 - -# Max modules before collapsing (default: 200) -max_modules = 150 - -# Max exports per module (default: 10) -max_exports = 15 - -# Output file names -[output] -json = "stacklit.json" -mermaid = "DEPENDENCIES.md" -html = "stacklit.html" +```json +{ + "ignore": ["vendor/", "generated/", "*.pb.go"], + "max_depth": 3, + "max_modules": 150, + "max_exports": 15, + "output": { + "json": "stacklit.json", + "mermaid": "DEPENDENCIES.md", + "html": "stacklit.html" + } +} ``` +Keys: `ignore` (extra paths on top of `.gitignore`), `max_depth` (module detection depth, default 4), `max_modules` (collapse threshold, default 200), `max_exports` (per module, default 10), and `output` (override generated file names). + --- ## Reading stacklit.json From 0f0a7a0443fbc58a0ac1be1e980abe6d88c5de3e Mon Sep 17 00:00:00 2001 From: GDS K S Date: Tue, 5 May 2026 19:21:38 -0500 Subject: [PATCH 3/4] fix(npm): harden Windows install against quoting and silent failures Address PR review feedback from Copilot: - Use execFileSync instead of execSync for all extraction commands so paths are passed as args, never interpolated into a shell string. The original PowerShell command wrapped paths in single quotes inside a double-quoted string, so a single quote in __dirname (e.g. C:\\Users\\O'Connor\\...) would have broken parsing or altered the command. - On Windows, hand the archive and bin paths to PowerShell via env vars ($env:STACKLIT_ARCHIVE / $env:STACKLIT_BINDIR) and use -LiteralPath so the script body has no string interpolation at all. - Move archive.tmp cleanup into a finally so a failed extraction doesn't leave the temp file behind. - Set process.exitCode = 1 in the top-level catch so npm postinstall reports a non-zero status when extraction fails or the binary is missing afterward. Download failures still return silently, matching the existing 'let the bin script show a helpful error' behavior. --- npm/install.js | 65 ++++++++++++++-------- stacklit.json | 148 ++++++++++++++++++++++++------------------------- 2 files changed, 117 insertions(+), 96 deletions(-) diff --git a/npm/install.js b/npm/install.js index 4f15532..db849ad 100644 --- a/npm/install.js +++ b/npm/install.js @@ -2,7 +2,7 @@ const os = require('os'); const fs = require('fs'); const path = require('path'); const https = require('https'); -const { execSync } = require('child_process'); +const { execFileSync } = require('child_process'); const VERSION = '0.3.0'; const REPO = 'glincker/stacklit'; @@ -77,37 +77,58 @@ async function install() { return; } - // Extract - if (url.endsWith('.zip')) { - if (os.platform() === 'win32') { - // Windows has no `unzip`. PowerShell Expand-Archive ships with Windows 10+. - execSync( - `powershell -NoProfile -ExecutionPolicy Bypass -Command "Expand-Archive -Force -Path '${archivePath}' -DestinationPath '${binDir}'"`, - { stdio: 'inherit' } - ); + try { + // Extract. execFileSync passes args directly to the binary, so no shell + // quoting of paths is needed. On Windows we hand paths to PowerShell via + // env vars so a single quote in __dirname (e.g. C:\Users\O'Connor\...) + // cannot terminate the script string. + if (url.endsWith('.zip')) { + if (os.platform() === 'win32') { + execFileSync( + 'powershell', + [ + '-NoProfile', + '-ExecutionPolicy', 'Bypass', + '-Command', + 'Expand-Archive -Force -LiteralPath $env:STACKLIT_ARCHIVE -DestinationPath $env:STACKLIT_BINDIR', + ], + { + stdio: 'inherit', + env: { ...process.env, STACKLIT_ARCHIVE: archivePath, STACKLIT_BINDIR: binDir }, + } + ); + } else { + execFileSync('unzip', ['-o', archivePath, 'stacklit.exe', '-d', binDir], { stdio: 'inherit' }); + } } else { - execSync(`unzip -o "${archivePath}" stacklit.exe -d "${binDir}"`, { stdio: 'inherit' }); + execFileSync('tar', ['-xzf', archivePath, '-C', binDir, 'stacklit'], { stdio: 'inherit' }); } - } else { - execSync(`tar -xzf "${archivePath}" -C "${binDir}" stacklit`, { stdio: 'inherit' }); - } - if (!fs.existsSync(binPath)) { - throw new Error(`extraction completed but ${binPath} is missing`); - } + if (!fs.existsSync(binPath)) { + throw new Error(`extraction completed but ${binPath} is missing`); + } - // Make executable - if (os.platform() !== 'win32') { - fs.chmodSync(binPath, 0o755); + if (os.platform() !== 'win32') { + fs.chmodSync(binPath, 0o755); + } + } finally { + if (fs.existsSync(archivePath)) { + try { + fs.unlinkSync(archivePath); + } catch (cleanupErr) { + // best-effort cleanup; warn but don't mask the original failure + console.warn(`Could not remove ${archivePath}: ${cleanupErr.message}`); + } + } } - // Cleanup - fs.unlinkSync(archivePath); - console.log('stacklit installed successfully.'); } install().catch((err) => { console.error('Installation failed:', err.message); console.error('You can install manually: go install github.com/glincker/stacklit/cmd/stacklit@latest'); + // Surface the failure to npm so postinstall doesn't appear to succeed when + // the binary is actually missing or extraction broke. + process.exitCode = 1; }); diff --git a/stacklit.json b/stacklit.json index 51b3b10..a6eecfa 100644 --- a/stacklit.json +++ b/stacklit.json @@ -1,9 +1,9 @@ { "$schema": "https://stacklit.dev/schema/v1.json", "version": "1", - "generated_at": "2026-05-04T13:24:15Z", + "generated_at": "2026-05-06T00:16:39Z", "stacklit_version": "dev", - "merkle_hash": "df2f2e019587fbc890d82a2dae0012908afc29c3cc3fea42bb2ab90b73c11e89", + "merkle_hash": "8fab1ccd73b505f70b9ded06c6503f57b46b463a6f5b511345c164ef1118ad5b", "project": { "name": "stacklit", "root": ".", @@ -22,7 +22,7 @@ }, "javascript": { "files": 3, - "lines": 127 + "lines": 139 }, "python": { "files": 1, @@ -47,7 +47,7 @@ "cmd/stacklit/main.go" ], "total_files": 75, - "total_lines": 8927 + "total_lines": 8939 }, "modules": { "assets": { @@ -66,7 +66,7 @@ "depended_by": [ "internal/renderer" ], - "activity": "low" + "activity": "high" }, "cmd/stacklit": { "purpose": "Stacklit", @@ -114,7 +114,7 @@ "depended_by": [ "cmd/stacklit" ], - "activity": "low" + "activity": "medium" }, "internal/config": { "purpose": "Configuration management", @@ -140,7 +140,7 @@ "internal/cli", "internal/engine" ], - "activity": "low" + "activity": "medium" }, "internal/derive": { "purpose": "Derive", @@ -228,7 +228,7 @@ "depended_by": [ "internal/cli" ], - "activity": "low" + "activity": "high" }, "internal/git": { "purpose": "Git integration", @@ -290,7 +290,7 @@ "depended_by": [ "internal/engine" ], - "activity": "low" + "activity": "medium" }, "internal/mcp": { "purpose": "MCP server for AI agents", @@ -407,7 +407,7 @@ "internal/cli", "internal/engine" ], - "activity": "low" + "activity": "medium" }, "internal/schema": { "purpose": "Data schema definitions", @@ -431,15 +431,15 @@ ], "type_defs": { "Architecture": "Pattern string, Summary string", - "Dependencies": "Edges [][]string, Entrypoints []string, MostDepended []string, Isolated []string", "FrameworkPattern": "Name string, Config []string, Routes string, API string, Middleware string, Models string, Entry string", "GitInfo": "HotFiles []HotFile, Recent []string, Stable []string", "Hints": "AddFeature string, TestCmd string, EnvVars []string, DoNotTouch []string", "HotFile": "Path string, Commits90d int", "Index": "Schema string, Version string, GeneratedAt string, StacklitVersion string, MerkleHash string, Project Project, Tech Tech, Structure Structure, Modules map[string]ModuleInfo, Dependencies Dependenci...", "LangStats": "Files int, Lines int", - "ModuleInfo": "Purpose string, Language string, Files int, Lines int, FileList []string, Exports []string, TypeDefs map[string]string, DependsOn []string, DependedBy []string, Activity string", - "MultiIndex": "Schema string, Version string, Type string, GeneratedAt string, TotalFiles int, TotalLines int, TotalModules int, Repos []RepoSummary" + "MultiIndex": "Schema string, Version string, Type string, GeneratedAt string, TotalFiles int, TotalLines int, TotalModules int, Repos []RepoSummary", + "Project": "Name string, Root string, Type string, Workspaces []string", + "Structure": "Entrypoints []string, TotalFiles int, TotalLines int, KeyDirectories map[string]string" }, "depended_by": [ "internal/cli", @@ -450,7 +450,7 @@ "internal/setup", "internal/summary" ], - "activity": "low" + "activity": "medium" }, "internal/setup": { "purpose": "Setup", @@ -522,11 +522,11 @@ "purpose": "Npm", "language": "javascript", "files": 1, - "lines": 101, + "lines": 113, "file_list": [ "install.js" ], - "activity": "low" + "activity": "medium" }, "npm/bin": { "purpose": "Bin", @@ -677,109 +677,109 @@ "git": { "hot_files": [ { - "path": ".github/workflows/ci.yml", - "commits_90d": 1 + "path": "stacklit.json", + "commits_90d": 31 }, { - "path": ".github/workflows/release.yml", - "commits_90d": 1 + "path": "README.md", + "commits_90d": 17 }, { - "path": ".github/workflows/stacklit-index.yml", - "commits_90d": 1 + "path": "internal/engine/engine.go", + "commits_90d": 17 }, { - "path": ".gitignore", - "commits_90d": 1 + "path": "stacklit.mmd", + "commits_90d": 14 }, { - "path": ".goreleaser.yml", - "commits_90d": 1 + "path": "assets/template.html", + "commits_90d": 11 }, { - "path": "COMPARISON.md", - "commits_90d": 1 + "path": "internal/graph/graph.go", + "commits_90d": 9 }, { - "path": "DEPENDENCIES.md", - "commits_90d": 1 + "path": "internal/schema/schema.go", + "commits_90d": 8 }, { - "path": "LICENSE", - "commits_90d": 1 + "path": "internal/renderer/mermaid.go", + "commits_90d": 7 }, { - "path": "Makefile", - "commits_90d": 1 + "path": "go.mod", + "commits_90d": 6 }, { - "path": "README.md", - "commits_90d": 1 + "path": "internal/graph/graph_test.go", + "commits_90d": 6 }, { - "path": "SKILL.md", - "commits_90d": 1 + "path": "npm/package.json", + "commits_90d": 6 }, { - "path": "USAGE.md", - "commits_90d": 1 + "path": ".github/workflows/release.yml", + "commits_90d": 5 }, { - "path": "action/action.yml", - "commits_90d": 1 + "path": "DEPENDENCIES.md", + "commits_90d": 5 }, { - "path": "assets/embed.go", - "commits_90d": 1 + "path": "go.sum", + "commits_90d": 5 }, { - "path": "assets/lang-icons.js", - "commits_90d": 1 + "path": "internal/cli/init.go", + "commits_90d": 5 }, { - "path": "assets/template.html", - "commits_90d": 1 + "path": "internal/renderer/mermaid_test.go", + "commits_90d": 5 }, { - "path": "cmd/stacklit/main.go", - "commits_90d": 1 + "path": "internal/cli/diff.go", + "commits_90d": 4 }, { - "path": "demo.gif", - "commits_90d": 1 + "path": "internal/cli/root.go", + "commits_90d": 4 }, { - "path": "demo.tape", - "commits_90d": 1 + "path": "internal/config/config.go", + "commits_90d": 4 }, { - "path": "docs/superpowers/plans/2026-04-12-growth-package.md", - "commits_90d": 1 + "path": "internal/config/config_test.go", + "commits_90d": 4 } ], "recent": [ - ".github/workflows/ci.yml", - ".github/workflows/release.yml", - ".github/workflows/stacklit-index.yml", - ".gitignore", - ".goreleaser.yml", - "COMPARISON.md", + "README.md", + "USAGE.md", + "npm/install.js", "DEPENDENCIES.md", - "LICENSE", - "Makefile", - "README.md" + "stacklit.json", + "internal/engine/engine.go", + "internal/summary/cli.go", + "internal/engine/engine_test.go", + "COMPARISON.md", + ".github/workflows/stacklit-index.yml" ], "stable": [ - ".github/workflows/ci.yml", - ".github/workflows/release.yml", - ".github/workflows/stacklit-index.yml", - ".gitignore", - ".goreleaser.yml", - "COMPARISON.md", - "DEPENDENCIES.md", "LICENSE", - "Makefile", - "README.md" + "assets/lang-icons.js", + "docs/superpowers/plans/2026-04-12-growth-package.md", + "docs/superpowers/specs/2026-04-12-growth-package-design.md", + "examples/axum/DEPENDENCIES.md", + "examples/axum/stacklit.json", + "examples/express/DEPENDENCIES.md", + "examples/express/stacklit.json", + "examples/fastapi/DEPENDENCIES.md", + "examples/fastapi/stacklit.json" ] }, "hints": { From 56772cdb3bcd1a5324e48cb25cf2054608264a8a Mon Sep 17 00:00:00 2001 From: GDS K S Date: Tue, 5 May 2026 19:24:12 -0500 Subject: [PATCH 4/4] chore: revert unintended stacklit.json regeneration The post-commit hook regenerated stacklit.json (new merkle hash and timestamp) when committing the npm fix. That regeneration is unrelated to this PR's scope, so revert it to keep the diff focused on npm/install.js. --- stacklit.json | 148 +++++++++++++++++++++++++------------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/stacklit.json b/stacklit.json index a6eecfa..51b3b10 100644 --- a/stacklit.json +++ b/stacklit.json @@ -1,9 +1,9 @@ { "$schema": "https://stacklit.dev/schema/v1.json", "version": "1", - "generated_at": "2026-05-06T00:16:39Z", + "generated_at": "2026-05-04T13:24:15Z", "stacklit_version": "dev", - "merkle_hash": "8fab1ccd73b505f70b9ded06c6503f57b46b463a6f5b511345c164ef1118ad5b", + "merkle_hash": "df2f2e019587fbc890d82a2dae0012908afc29c3cc3fea42bb2ab90b73c11e89", "project": { "name": "stacklit", "root": ".", @@ -22,7 +22,7 @@ }, "javascript": { "files": 3, - "lines": 139 + "lines": 127 }, "python": { "files": 1, @@ -47,7 +47,7 @@ "cmd/stacklit/main.go" ], "total_files": 75, - "total_lines": 8939 + "total_lines": 8927 }, "modules": { "assets": { @@ -66,7 +66,7 @@ "depended_by": [ "internal/renderer" ], - "activity": "high" + "activity": "low" }, "cmd/stacklit": { "purpose": "Stacklit", @@ -114,7 +114,7 @@ "depended_by": [ "cmd/stacklit" ], - "activity": "medium" + "activity": "low" }, "internal/config": { "purpose": "Configuration management", @@ -140,7 +140,7 @@ "internal/cli", "internal/engine" ], - "activity": "medium" + "activity": "low" }, "internal/derive": { "purpose": "Derive", @@ -228,7 +228,7 @@ "depended_by": [ "internal/cli" ], - "activity": "high" + "activity": "low" }, "internal/git": { "purpose": "Git integration", @@ -290,7 +290,7 @@ "depended_by": [ "internal/engine" ], - "activity": "medium" + "activity": "low" }, "internal/mcp": { "purpose": "MCP server for AI agents", @@ -407,7 +407,7 @@ "internal/cli", "internal/engine" ], - "activity": "medium" + "activity": "low" }, "internal/schema": { "purpose": "Data schema definitions", @@ -431,15 +431,15 @@ ], "type_defs": { "Architecture": "Pattern string, Summary string", + "Dependencies": "Edges [][]string, Entrypoints []string, MostDepended []string, Isolated []string", "FrameworkPattern": "Name string, Config []string, Routes string, API string, Middleware string, Models string, Entry string", "GitInfo": "HotFiles []HotFile, Recent []string, Stable []string", "Hints": "AddFeature string, TestCmd string, EnvVars []string, DoNotTouch []string", "HotFile": "Path string, Commits90d int", "Index": "Schema string, Version string, GeneratedAt string, StacklitVersion string, MerkleHash string, Project Project, Tech Tech, Structure Structure, Modules map[string]ModuleInfo, Dependencies Dependenci...", "LangStats": "Files int, Lines int", - "MultiIndex": "Schema string, Version string, Type string, GeneratedAt string, TotalFiles int, TotalLines int, TotalModules int, Repos []RepoSummary", - "Project": "Name string, Root string, Type string, Workspaces []string", - "Structure": "Entrypoints []string, TotalFiles int, TotalLines int, KeyDirectories map[string]string" + "ModuleInfo": "Purpose string, Language string, Files int, Lines int, FileList []string, Exports []string, TypeDefs map[string]string, DependsOn []string, DependedBy []string, Activity string", + "MultiIndex": "Schema string, Version string, Type string, GeneratedAt string, TotalFiles int, TotalLines int, TotalModules int, Repos []RepoSummary" }, "depended_by": [ "internal/cli", @@ -450,7 +450,7 @@ "internal/setup", "internal/summary" ], - "activity": "medium" + "activity": "low" }, "internal/setup": { "purpose": "Setup", @@ -522,11 +522,11 @@ "purpose": "Npm", "language": "javascript", "files": 1, - "lines": 113, + "lines": 101, "file_list": [ "install.js" ], - "activity": "medium" + "activity": "low" }, "npm/bin": { "purpose": "Bin", @@ -677,109 +677,109 @@ "git": { "hot_files": [ { - "path": "stacklit.json", - "commits_90d": 31 + "path": ".github/workflows/ci.yml", + "commits_90d": 1 }, { - "path": "README.md", - "commits_90d": 17 + "path": ".github/workflows/release.yml", + "commits_90d": 1 }, { - "path": "internal/engine/engine.go", - "commits_90d": 17 + "path": ".github/workflows/stacklit-index.yml", + "commits_90d": 1 }, { - "path": "stacklit.mmd", - "commits_90d": 14 + "path": ".gitignore", + "commits_90d": 1 }, { - "path": "assets/template.html", - "commits_90d": 11 + "path": ".goreleaser.yml", + "commits_90d": 1 }, { - "path": "internal/graph/graph.go", - "commits_90d": 9 + "path": "COMPARISON.md", + "commits_90d": 1 }, { - "path": "internal/schema/schema.go", - "commits_90d": 8 + "path": "DEPENDENCIES.md", + "commits_90d": 1 }, { - "path": "internal/renderer/mermaid.go", - "commits_90d": 7 + "path": "LICENSE", + "commits_90d": 1 }, { - "path": "go.mod", - "commits_90d": 6 + "path": "Makefile", + "commits_90d": 1 }, { - "path": "internal/graph/graph_test.go", - "commits_90d": 6 + "path": "README.md", + "commits_90d": 1 }, { - "path": "npm/package.json", - "commits_90d": 6 + "path": "SKILL.md", + "commits_90d": 1 }, { - "path": ".github/workflows/release.yml", - "commits_90d": 5 + "path": "USAGE.md", + "commits_90d": 1 }, { - "path": "DEPENDENCIES.md", - "commits_90d": 5 + "path": "action/action.yml", + "commits_90d": 1 }, { - "path": "go.sum", - "commits_90d": 5 + "path": "assets/embed.go", + "commits_90d": 1 }, { - "path": "internal/cli/init.go", - "commits_90d": 5 + "path": "assets/lang-icons.js", + "commits_90d": 1 }, { - "path": "internal/renderer/mermaid_test.go", - "commits_90d": 5 + "path": "assets/template.html", + "commits_90d": 1 }, { - "path": "internal/cli/diff.go", - "commits_90d": 4 + "path": "cmd/stacklit/main.go", + "commits_90d": 1 }, { - "path": "internal/cli/root.go", - "commits_90d": 4 + "path": "demo.gif", + "commits_90d": 1 }, { - "path": "internal/config/config.go", - "commits_90d": 4 + "path": "demo.tape", + "commits_90d": 1 }, { - "path": "internal/config/config_test.go", - "commits_90d": 4 + "path": "docs/superpowers/plans/2026-04-12-growth-package.md", + "commits_90d": 1 } ], "recent": [ - "README.md", - "USAGE.md", - "npm/install.js", - "DEPENDENCIES.md", - "stacklit.json", - "internal/engine/engine.go", - "internal/summary/cli.go", - "internal/engine/engine_test.go", + ".github/workflows/ci.yml", + ".github/workflows/release.yml", + ".github/workflows/stacklit-index.yml", + ".gitignore", + ".goreleaser.yml", "COMPARISON.md", - ".github/workflows/stacklit-index.yml" + "DEPENDENCIES.md", + "LICENSE", + "Makefile", + "README.md" ], "stable": [ + ".github/workflows/ci.yml", + ".github/workflows/release.yml", + ".github/workflows/stacklit-index.yml", + ".gitignore", + ".goreleaser.yml", + "COMPARISON.md", + "DEPENDENCIES.md", "LICENSE", - "assets/lang-icons.js", - "docs/superpowers/plans/2026-04-12-growth-package.md", - "docs/superpowers/specs/2026-04-12-growth-package-design.md", - "examples/axum/DEPENDENCIES.md", - "examples/axum/stacklit.json", - "examples/express/DEPENDENCIES.md", - "examples/express/stacklit.json", - "examples/fastapi/DEPENDENCIES.md", - "examples/fastapi/stacklit.json" + "Makefile", + "README.md" ] }, "hints": {