@launchsecure/launch-kit 0.0.33 → 0.0.34
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/dist/server/chart-serve.js +167 -2
- package/dist/server/cli.js +249 -41
- package/dist/server/council-entry.js +0 -0
- package/dist/server/course-entry.js +1 -1
- package/dist/server/fb-wizard.js +0 -0
- package/dist/server/graph-mcp-entry.js +180 -4
- package/dist/server/init-entry.js +438 -43
- package/dist/server/launch-radar-entry.js +45 -0
- package/dist/server/parse-worker-entry.js +167 -2
- package/dist/server/radar-docker-init-entry.js +444 -39
- package/dist/server/radar-entrypoint-entry.js +0 -0
- package/dist/server/radar-teardown-entry.js +23 -22
- package/dist/server/rover-entry.js +20122 -0
- package/package.json +28 -25
- package/scaffolds/ls-marketplace/plugins/kit/commands/standup.md +6 -6
- package/scaffolds/ls-marketplace/plugins/kit/skills/analyse/SKILL.md +6 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/brief/SKILL.md +40 -48
- package/scaffolds/ls-marketplace/plugins/kit/skills/debug/SKILL.md +45 -20
- package/scaffolds/ls-marketplace/plugins/kit/skills/deploy-check/SKILL.md +76 -67
- package/scaffolds/ls-marketplace/plugins/kit/skills/handoff/SKILL.md +132 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/ship/SKILL.md +149 -133
- package/scaffolds/migrate-safety/scripts/migrate-with-backup.sh +0 -0
- package/scaffolds/recall-hook/scripts/ensure-recall.sh +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@launchsecure/launch-kit",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "LaunchSecure toolkit — launch-
|
|
3
|
+
"version": "0.0.34",
|
|
4
|
+
"description": "LaunchSecure toolkit — launch-sequencer (pipeline runner + terminal bridge), launch-radar (feedback webhook receiver), launch-chart (project graph MCP), launch-deck (visual playground MCP), launch-kit-beacon (feedback Web Component), launch-recall (file-watcher backup). launch-pod is the container image these run inside.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "LaunchSecure - AutomateWithUs",
|
|
7
7
|
"homepage": "https://automatewith.us",
|
|
@@ -48,13 +48,33 @@
|
|
|
48
48
|
},
|
|
49
49
|
"bin": {
|
|
50
50
|
"launch-kit": "./dist/server/init-entry.js",
|
|
51
|
-
"launch-
|
|
51
|
+
"launch-sequencer": "./dist/server/cli.js",
|
|
52
|
+
"launch-radar": "./dist/server/launch-radar-entry.js",
|
|
52
53
|
"launch-chart": "./dist/server/graph-mcp-entry.js",
|
|
53
54
|
"launch-deck": "./dist/server/deck-mcp-entry.js",
|
|
54
55
|
"launch-recall": "./dist/server/recall-entry.js",
|
|
55
56
|
"launch-orbit": "./dist/server/orbit-entry.js",
|
|
56
57
|
"launch-course": "./dist/server/course-entry.js",
|
|
57
|
-
"launch-beacon": "./dist/server/beacon-monitor-entry.js"
|
|
58
|
+
"launch-beacon": "./dist/server/beacon-monitor-entry.js",
|
|
59
|
+
"launch-rover": "./dist/server/rover-entry.js"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "pnpm build:client && pnpm build:chart-client && pnpm build:deck-client && pnpm build:council-client && pnpm build:beacon && pnpm build:server",
|
|
63
|
+
"build:beacon": "vite build --config vite.beacon.config.ts && tsc -p tsconfig.beacon.json --emitDeclarationOnly --outDir dist/beacon/types",
|
|
64
|
+
"test:beacon": "vitest run --config vite.beacon.config.ts",
|
|
65
|
+
"test:radar": "vitest run --config vite.radar.config.ts",
|
|
66
|
+
"test:chart": "vitest run --config vite.chart.test.config.ts",
|
|
67
|
+
"build:deck-client": "vite build --config vite.deck.config.ts",
|
|
68
|
+
"build:council-client": "vite build --config vite.council.config.ts",
|
|
69
|
+
"build:client": "vite build",
|
|
70
|
+
"build:chart-client": "vite build --config vite.chart.config.ts",
|
|
71
|
+
"build:server": "esbuild src/server/cli.ts src/server/fb-wizard.ts src/server/graph-mcp-entry.ts src/server/chart-serve.ts src/server/deck-mcp-entry.ts src/server/deck-serve.ts src/server/council-entry.ts src/server/council-serve.ts src/server/recall-entry.ts src/server/init-entry.ts src/server/orbit-entry.ts src/server/course-entry.ts src/server/beacon-monitor-entry.ts src/server/parse-worker-entry.ts src/server/radar-teardown-entry.ts src/server/radar-docker-init-entry.ts src/server/launch-radar-entry.ts src/server/rover-entry.ts --bundle --platform=node --target=node18 --outdir=dist/server --external:node-pty --external:ws --external:typescript --external:web-tree-sitter --external:tree-sitter-typescript --external:cloudflared --external:pg --external:pg-native --external:pgsql-parser --external:libpg-query && rm -rf dist/server/public && cp -r ../claude-code-web/src/public dist/server/public && rm -rf dist/server/graph/queries && mkdir -p dist/server/graph && cp -r src/server/graph/queries dist/server/graph/queries",
|
|
72
|
+
"dev:client": "vite",
|
|
73
|
+
"dev:deck-serve": "cd ../.. && tsx watch packages/cli/src/server/deck-mcp-entry.ts serve",
|
|
74
|
+
"dev:chart": "pnpm build:server && pnpm build:chart-client && node dist/server/graph-mcp-entry.js serve",
|
|
75
|
+
"dev:server": "pnpm build:server && node dist/server/cli.js",
|
|
76
|
+
"dev": "pnpm build:server && concurrently -k -n client,server -c cyan,magenta \"vite\" \"node dist/server/cli.js\"",
|
|
77
|
+
"prepublishOnly": "pnpm build"
|
|
58
78
|
},
|
|
59
79
|
"files": [
|
|
60
80
|
"dist",
|
|
@@ -76,6 +96,8 @@
|
|
|
76
96
|
"ws": "^8.18.0"
|
|
77
97
|
},
|
|
78
98
|
"devDependencies": {
|
|
99
|
+
"@launchsecure/claude-code-web": "workspace:*",
|
|
100
|
+
"@launchsecure/ui": "workspace:*",
|
|
79
101
|
"@types/node": "^20.0.0",
|
|
80
102
|
"@types/pg": "^8.11.10",
|
|
81
103
|
"@types/react": "^18.3.12",
|
|
@@ -99,25 +121,6 @@
|
|
|
99
121
|
"react-router-dom": "^6.28.0",
|
|
100
122
|
"tailwindcss": "^3.4.19",
|
|
101
123
|
"vite": "^5.4.11",
|
|
102
|
-
"vitest": "^1.6.0"
|
|
103
|
-
"@launchsecure/claude-code-web": "0.0.1",
|
|
104
|
-
"@launchsecure/ui": "0.0.1"
|
|
105
|
-
},
|
|
106
|
-
"scripts": {
|
|
107
|
-
"build": "pnpm build:client && pnpm build:chart-client && pnpm build:deck-client && pnpm build:council-client && pnpm build:beacon && pnpm build:server",
|
|
108
|
-
"build:beacon": "vite build --config vite.beacon.config.ts && tsc -p tsconfig.beacon.json --emitDeclarationOnly --outDir dist/beacon/types",
|
|
109
|
-
"test:beacon": "vitest run --config vite.beacon.config.ts",
|
|
110
|
-
"test:radar": "vitest run --config vite.radar.config.ts",
|
|
111
|
-
"test:chart": "vitest run --config vite.chart.test.config.ts",
|
|
112
|
-
"build:deck-client": "vite build --config vite.deck.config.ts",
|
|
113
|
-
"build:council-client": "vite build --config vite.council.config.ts",
|
|
114
|
-
"build:client": "vite build",
|
|
115
|
-
"build:chart-client": "vite build --config vite.chart.config.ts",
|
|
116
|
-
"build:server": "esbuild src/server/cli.ts src/server/fb-wizard.ts src/server/graph-mcp-entry.ts src/server/chart-serve.ts src/server/deck-mcp-entry.ts src/server/deck-serve.ts src/server/council-entry.ts src/server/council-serve.ts src/server/recall-entry.ts src/server/init-entry.ts src/server/orbit-entry.ts src/server/course-entry.ts src/server/beacon-monitor-entry.ts src/server/parse-worker-entry.ts src/server/radar-teardown-entry.ts src/server/radar-docker-init-entry.ts --bundle --platform=node --target=node18 --outdir=dist/server --external:node-pty --external:ws --external:typescript --external:web-tree-sitter --external:tree-sitter-typescript --external:cloudflared --external:pg --external:pg-native --external:pgsql-parser --external:libpg-query && rm -rf dist/server/public && cp -r ../claude-code-web/src/public dist/server/public && rm -rf dist/server/graph/queries && mkdir -p dist/server/graph && cp -r src/server/graph/queries dist/server/graph/queries",
|
|
117
|
-
"dev:client": "vite",
|
|
118
|
-
"dev:deck-serve": "cd ../.. && tsx watch packages/cli/src/server/deck-mcp-entry.ts serve",
|
|
119
|
-
"dev:chart": "pnpm build:server && pnpm build:chart-client && node dist/server/graph-mcp-entry.js serve",
|
|
120
|
-
"dev:server": "pnpm build:server && node dist/server/cli.js",
|
|
121
|
-
"dev": "pnpm build:server && concurrently -k -n client,server -c cyan,magenta \"vite\" \"node dist/server/cli.js\""
|
|
124
|
+
"vitest": "^1.6.0"
|
|
122
125
|
}
|
|
123
|
-
}
|
|
126
|
+
}
|
|
@@ -63,11 +63,11 @@ Skip this step if no handles were found in commit messages — don't pull the fu
|
|
|
63
63
|
|
|
64
64
|
### 6. Release detection
|
|
65
65
|
|
|
66
|
-
A commit qualifies the post for the `release` tag if ANY of the following are true:
|
|
67
|
-
- `package.json` `version`
|
|
68
|
-
- A migration file under `prisma/migrations
|
|
69
|
-
- A deploy/publish was mentioned in commit subjects (regex: `\b(publish|release|deploy|bump)\b`)
|
|
70
|
-
- A new
|
|
66
|
+
A commit qualifies the post for the `release` tag if ANY of the following are true. These signals are **stack-detected**, not hardcoded — match against whatever the project actually uses, and a signal that doesn't apply to this stack simply doesn't fire:
|
|
67
|
+
- The project's **version** changed — detect from the stack's version source: `package.json` `version` (Node), `pyproject.toml`/`setup.py`/`__version__` (Python), `Cargo.toml` `version` (Rust), `<Version>` in a `*.csproj` (.NET), a gemspec/`version.rb` (Ruby), `version` in `pubspec.yaml` (Dart), or a new `vX.Y.Z` git tag pushed in this window (language-agnostic). Diff the relevant file over `@{push}..HEAD`.
|
|
68
|
+
- A **migration** was added — any file under the project's migrations directory (detected as in `/kit:ship`: `prisma/migrations/`, `supabase/migrations/`, `db/migrate/`, `alembic/versions/`, `drizzle/`, `src/main/resources/db/migration/`, etc.), or the schema/DDL source changed. Skip this signal when the project has no migrations.
|
|
69
|
+
- A deploy/publish was mentioned in commit subjects (regex: `\b(publish|release|deploy|bump)\b`).
|
|
70
|
+
- A new **public entry point** was added — a bin/CLI command, package export, or exported library symbol (e.g. a new `bin`/`exports` entry in `package.json`, a new console-script in `pyproject.toml`, a new exported package in Go, etc.).
|
|
71
71
|
|
|
72
72
|
If any are true, set `addReleaseTag = true`. Otherwise `false`.
|
|
73
73
|
|
|
@@ -102,7 +102,7 @@ Pending / in-progress:
|
|
|
102
102
|
|
|
103
103
|
----
|
|
104
104
|
|
|
105
|
-
<one-line PSA or deploy-safety note. Examples: "
|
|
105
|
+
<one-line PSA or deploy-safety note, phrased for the project's stack. Examples: "Typecheck clean, no schema/migration changes, safe to deploy." or "Includes a <migration-tool> migration <name> — take a DB backup before deploy." or "Bumps to vX.Y.Z — publishes on merge.">
|
|
106
106
|
|
|
107
107
|
Thanks
|
|
108
108
|
```
|
|
@@ -22,6 +22,12 @@ allowed-tools:
|
|
|
22
22
|
|
|
23
23
|
Source-code analysis using launch-chart as the default tool. The chart indexes ~1,200 typed nodes across 4 layers (ui / api / db / static) with cross-layer edges and AST-level deep fields — almost everything grep/glob/Read would surface is queryable here, faster and cheaper in tokens.
|
|
24
24
|
|
|
25
|
+
## Input
|
|
26
|
+
|
|
27
|
+
Run the analysis for the user query → **$ARGUMENTS**
|
|
28
|
+
|
|
29
|
+
This is the target to analyse — a question, a node name (file / table / route / hook), or a module. Route it through the chart tools below. If `$ARGUMENTS` is empty, the user invoked the skill bare; ask them what they want analysed (or infer it from the surrounding conversation) before querying.
|
|
30
|
+
|
|
25
31
|
## Discipline (non-negotiable)
|
|
26
32
|
|
|
27
33
|
1. **Chart-first.** Default to launch-chart MCP for any code-structure or behavior query. Do NOT reach for grep / glob / Read first.
|
|
@@ -1,50 +1,48 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Create or update a repo-backed Brief
|
|
2
|
+
description: Create or update a repo-backed Brief — a long-form idea document committed as a markdown file under doc/ideas/. NOT a Comm Hub / CapCom comment. Use to capture an idea in the repo before promoting it to an Epic.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# /kit:brief
|
|
6
6
|
|
|
7
|
-
A **Brief** is
|
|
7
|
+
A **Brief** is a repo-backed idea document: a long-form description of a problem/opportunity written as a **markdown file committed to the repo** under `doc/ideas/<slug>.md`. It is the structured alternative to a free-form thought when the idea has enough shape to write down. Briefs get promoted to Epics on the Roadmap once they're DECIDED.
|
|
8
|
+
|
|
9
|
+
**A Brief is a FILE, not a comment.** Do NOT post Briefs to the LaunchSecure Comm Hub / CapCom via `communication_write`. Briefs live in the repo and travel through git like any other source artefact. (An earlier version of this skill posted Briefs as Comm Hub comments — that was wrong; Briefs are file commits.)
|
|
8
10
|
|
|
9
11
|
Parse `$ARGUMENTS`:
|
|
10
12
|
- **subcommand** (required) — `new` | `update` | `list` | `show`.
|
|
11
|
-
- For **new**: `<title>` (required), `--from=discussion:<id>` to seed body from an existing discussion thread, `--
|
|
12
|
-
- For **update**: `<
|
|
13
|
-
- For **list**: `[--
|
|
14
|
-
- For **show**: `<
|
|
13
|
+
- For **new**: `<title>` (required), `--from=discussion:<id>` to seed body from an existing discussion thread, `--dir=<path>` to override the default `doc/ideas/` location.
|
|
14
|
+
- For **update**: `<slug-or-path>` and either a body description (re-generates body) or `--append=<text>` to add a section.
|
|
15
|
+
- For **list**: `[--dir=<path>]` — defaults to listing `doc/ideas/`.
|
|
16
|
+
- For **show**: `<slug-or-path>`.
|
|
15
17
|
|
|
16
18
|
Examples:
|
|
17
|
-
- `/kit:brief new "Channels for Comm Hub"
|
|
19
|
+
- `/kit:brief new "Channels for Comm Hub"`
|
|
18
20
|
- `/kit:brief new "Roadmap nav" --from=discussion:cmt_abc123`
|
|
19
|
-
- `/kit:brief list
|
|
20
|
-
- `/kit:brief show
|
|
21
|
-
- `/kit:brief update
|
|
22
|
-
|
|
23
|
-
## Preflight
|
|
21
|
+
- `/kit:brief list`
|
|
22
|
+
- `/kit:brief show launch-watch`
|
|
23
|
+
- `/kit:brief update launch-watch --append="Resolved: use the Slack metaphor not Teams."`
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
2. For `new`, sanity-check that no existing brief with the same slug already exists — call `mcp__launch-secure__communication_read` filtered by `resourceType=comment` and search the title. If a match is found, ask whether to update instead.
|
|
25
|
+
## Location
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
- **Default directory**: `doc/ideas/` at the repo root.
|
|
28
|
+
- **Filename**: `<slug>.md`, where the slug is the kebab-cased title (e.g. "launch-watch — unified monitor" → `launch-watch.md`; keep it short — derive from the leading words, drop the subtitle after an em-dash).
|
|
29
|
+
- Override with `--dir=<path>` only if the user asks.
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
## Preflight
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- **body**: the long-form markdown — sections below
|
|
36
|
-
- **file_links**: not used here; the FileBackedEntity link is created by LS server-side on first save
|
|
37
|
-
- **tags**: optional module tag, plus a `brief` tag for filtering
|
|
33
|
+
1. Resolve the repo root (the working directory is the repo root in this project).
|
|
34
|
+
2. For **new**, check `doc/ideas/<slug>.md` does not already exist. If it does, surface it and ask whether to `update` instead — do NOT overwrite silently.
|
|
35
|
+
3. No MCP, no network, no Comm Hub calls. This skill only touches the filesystem + git.
|
|
38
36
|
|
|
39
|
-
|
|
37
|
+
## Body template
|
|
40
38
|
|
|
41
|
-
When generating a NEW brief,
|
|
39
|
+
When generating a NEW brief, write this skeleton as the file contents (plain markdown):
|
|
42
40
|
|
|
43
41
|
```markdown
|
|
44
42
|
# <Title>
|
|
45
43
|
|
|
46
|
-
**Status**: PROPOSED
|
|
47
|
-
**Owner**: <
|
|
44
|
+
**Status**: PROPOSED
|
|
45
|
+
**Owner**: <name or "unassigned">
|
|
48
46
|
**Module**: <module slug or "-">
|
|
49
47
|
|
|
50
48
|
## Problem
|
|
@@ -69,44 +67,38 @@ When generating a NEW brief, use this skeleton (markdown body):
|
|
|
69
67
|
|
|
70
68
|
## References
|
|
71
69
|
|
|
72
|
-
- <link to existing code
|
|
73
|
-
- <related comments by id>
|
|
70
|
+
- <link to existing code, cited as `lib/foo/bar.ts:42` — use launch-chart (read_graph / grep_nodes) to find the right nodes; don't invent file paths>
|
|
74
71
|
```
|
|
75
72
|
|
|
76
|
-
The body is plain markdown — Comm Hub renders it. Use launch-chart to add real code references (don't invent file paths).
|
|
77
|
-
|
|
78
73
|
## Write paths
|
|
79
74
|
|
|
80
75
|
### new
|
|
81
76
|
|
|
82
|
-
1. Build the body from the template + the user's description (or the `--from=discussion:<id>` seed — fetch via `
|
|
83
|
-
2.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
- `resource_type: "comment"`
|
|
87
|
-
- `fields: { docCategory: "features", briefStatus: "PROPOSED" }`
|
|
88
|
-
- `tag_ids: <module tag id + "brief" tag id>` (call `mcp__launch-secure__tags_list` first to resolve names → ids; if either tag doesn't exist, surface the missing tag(s) and proceed without)
|
|
89
|
-
3. Print the returned comment id + URL.
|
|
90
|
-
4. Tell the user: "LS server-side file-backed sync will materialize `docs/requirements/features/<slug>.md` on the next default-branch push that includes this brief — pull the branch to see it locally."
|
|
77
|
+
1. Build the body from the template + the user's description (or the `--from=discussion:<id>` seed — fetch via `mcp__launch-secure__communication_read` and weave the relevant points into Problem / Proposed-direction; reading a seed discussion is fine, but the Brief itself is still written to a file, never posted back).
|
|
78
|
+
2. Use launch-chart (`read_graph`, `grep_nodes`) to populate the References section with real code paths — don't invent them.
|
|
79
|
+
3. **Write the file** to `doc/ideas/<slug>.md` with the Write tool.
|
|
80
|
+
4. Print the path written. Do NOT commit or push unless the user explicitly asks — leave it as a working-tree change for them to review and commit.
|
|
91
81
|
|
|
92
82
|
### update
|
|
93
83
|
|
|
94
|
-
1. Resolve `<
|
|
95
|
-
2. If `--append=<text>`,
|
|
96
|
-
3. If a fresh description was passed, regenerate the body from the template + new description,
|
|
84
|
+
1. Resolve `<slug-or-path>` to a file under `doc/ideas/` (or the `--dir` override). If nothing matches, list candidates and stop.
|
|
85
|
+
2. If `--append=<text>`, Read the file, append the text under a `## Update <ISO-date>` heading, and Write it back.
|
|
86
|
+
3. If a fresh description was passed, regenerate the body from the template + new description, show the user the diff briefly, then Write it back on confirmation.
|
|
97
87
|
|
|
98
88
|
### list
|
|
99
89
|
|
|
100
|
-
`
|
|
90
|
+
List `doc/ideas/*.md` (or `--dir`). Render one line per brief: `slug status title` — read each file's `# Title` and `**Status**:` line to fill those columns.
|
|
101
91
|
|
|
102
92
|
### show
|
|
103
93
|
|
|
104
|
-
|
|
94
|
+
Read the file and print its contents as-is, no transformation.
|
|
105
95
|
|
|
106
96
|
## Constraints
|
|
107
97
|
|
|
108
|
-
- **
|
|
109
|
-
- **
|
|
110
|
-
- **
|
|
98
|
+
- **A Brief is a file, never a Comm Hub comment.** Do NOT call `communication_write` / `communication_update` to create or store a Brief. Reading a `--from` discussion seed is the only allowed Comm Hub touch, and it's read-only.
|
|
99
|
+
- **Plain markdown.** No HTML, no emojis unless the user wrote them.
|
|
100
|
+
- **One brief, one file.** Don't fragment a brief across multiple files — append via `--append` to keep the document continuous.
|
|
101
|
+
- **Don't commit or push on your own.** Write the file to the working tree and stop; committing/pushing is the user's call (per project conventions on no unauthorized pushes).
|
|
102
|
+
- **`doc/ideas/` is the user's personal scratch.** Write the brief the user asked for, but do NOT reorganize, reclassify, or migrate other files in that directory. Promotion out of `doc/ideas/` is user-driven only.
|
|
111
103
|
- **Cite real code.** Use launch-chart node ids in the References section — don't invent file paths.
|
|
112
|
-
- **Don't auto-promote to Epic.** A Brief → Epic is a deliberate human action
|
|
104
|
+
- **Don't auto-promote to Epic.** A Brief → Epic is a deliberate human action. Surface a hint at the end: "When DECIDED, promote this to an Epic on the Roadmap."
|
|
@@ -1,54 +1,77 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Investigate a bug, error message, or unexpected behavior
|
|
2
|
+
description: Investigate a bug, error message, or unexpected behavior. Leads with runtime evidence from the launch-beacon monitor ("what was happening when it broke") when a session exists, then traces the code with launch-chart (structural + variable queries), falling back to grep/Read only when the chart can't answer. Fuses runtime + static signals into a ranked diagnosis. Files a feedback comment when a chart gap forces the fallback. Does NOT edit code.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# /kit:debug
|
|
6
6
|
|
|
7
|
-
A guided investigation workflow
|
|
7
|
+
A guided investigation workflow. It works two evidence sources, in order:
|
|
8
|
+
|
|
9
|
+
1. **Runtime** — the launch-beacon monitor's captured events (the error itself, plus the clicks / fetches / route changes leading up to it). This is what *actually happened* in the running app. Beacon was built for exactly this.
|
|
10
|
+
2. **Static** — launch-chart structural + variable queries to find *where the code is* and trace the dependency chain toward the cause.
|
|
11
|
+
|
|
12
|
+
It defaults to beacon-first when there's a live session and the symptom is runtime-shaped, then chart, and only reaches for grep/Read when the chart can't answer — filing a one-line gap report in LS when that happens.
|
|
8
13
|
|
|
9
14
|
Parse `$ARGUMENTS`:
|
|
10
15
|
- **symptom** (required) — the error message, broken behavior, or question to investigate. Quoted is fine: `/kit:debug "tags don't render on the work-item drawer"`.
|
|
11
|
-
- **--start=<node>** — start the investigation from a specific file/function/table id (skip the search step).
|
|
16
|
+
- **--start=<node>** — start the static investigation from a specific file/function/table id (skip the chart search step). Does not skip beacon.
|
|
12
17
|
- **--layer=<id>** — scope chart queries to one layer (ui / api / db / static).
|
|
13
18
|
- **--no-grep-fallback** — refuse the grep fallback entirely (strict MCP-only).
|
|
19
|
+
- **--no-beacon** — skip the runtime-evidence step; go straight to static chart analysis. Use for pure structural questions, or when no monitor is running and you don't want the check.
|
|
20
|
+
- **--worktree=<slug>** / **--project_root=<path>** — forwarded to every beacon MCP call (orbit worktree slug / explicit project root), same semantics as `/kit:beacon-pulse`.
|
|
14
21
|
|
|
15
22
|
Examples:
|
|
16
23
|
- `/kit:debug tags don't render on the work-item drawer`
|
|
17
24
|
- `/kit:debug "TypeError: Cannot read property 'status' of undefined" --layer=ui`
|
|
18
25
|
- `/kit:debug --start=src/server/comms/build-feed.ts`
|
|
26
|
+
- `/kit:debug "checkout button does nothing" --worktree=beacon_rewrite`
|
|
19
27
|
|
|
20
28
|
## Investigation loop
|
|
21
29
|
|
|
22
|
-
Run
|
|
30
|
+
Run Step 0, then the static loop (Steps 1–4), until the user has enough to act, OR a fallback was filed (then surface it).
|
|
31
|
+
|
|
32
|
+
### Step 0 — runtime evidence (launch-beacon)
|
|
33
|
+
|
|
34
|
+
Skip this step if `--no-beacon` was passed, or if the symptom is a purely structural question with no runtime component ("where is X defined", "what depends on Y", "how is auth wired"). Otherwise — for any symptom that describes something *happening* (an error message, a broken interaction, a wrong result in the running app) — start here:
|
|
35
|
+
|
|
36
|
+
1. Call `mcp__local-launch-beacon__beacon_failures` with `limit: 5` (plus `worktree` / `project_root` if supplied). The most recent session is targeted implicitly. A "failure" is broader than `kind=error`: window errors, unhandled rejections, fetch/xhr ≥ 400 or thrown, and clicks where overlay interception blocked the intended target.
|
|
37
|
+
2. **Match the symptom to a failure.** Pick the failure whose message/route best matches the symptom. If several plausibly match, surface the top 2–3 (with `seq`, `kind`, `ts`, message) and ask which — or take the most recent.
|
|
38
|
+
3. **Pull the lead-up.** Call `mcp__local-launch-beacon__beacon_correlate` with `seq: <failure.seq>`, `before: 10`, `after: 0` (forward the same root args). This is the chain of events that produced the failure — the click that set bad state, the fetch that 500'd, the route change that mounted the wrong component. If a context event's summary is too thin (truncated stack, missing response body, selector chain), call `mcp__local-launch-beacon__beacon_event` with that `seq` for the full JSON — only when needed.
|
|
39
|
+
4. **Form a runtime hypothesis** and carry it into the static phase. Example: *"beacon shows `GET /api/work-items/42/tags` returned 500 two events before the render error — so the empty-tags symptom is likely server-side, not the drawer component."* This tells the chart phase **where to start** (the failing endpoint), turning a blind structural search into a targeted one.
|
|
40
|
+
|
|
41
|
+
**Graceful degradation (beacon is additive, never a hard dependency):**
|
|
42
|
+
- `{error: "no session found"}` or empty failures → say so in one line (`"No beacon monitor session found — proceeding with static analysis only. (Start one with: npx launch-beacon monitor)"`) and go to Step 1. Do NOT treat this as a failure of the debug run.
|
|
43
|
+
- Before giving up: if the user passed no `--worktree`/`--project_root` and `launch-orbit` has worktrees for this repo, suggest re-running with `--worktree=<slug>` (the session NDJSON may live in a worktree outside the MCP's watch root).
|
|
44
|
+
- If the beacon MCP isn't wired at all, note it once and continue static-only.
|
|
45
|
+
- For a deeper runtime drill (more preceding events, a different failure), point the user at `/kit:beacon-pulse` rather than re-deriving it here.
|
|
23
46
|
|
|
24
|
-
### Step 1 — locate the entry point
|
|
47
|
+
### Step 1 — locate the entry point (static)
|
|
25
48
|
|
|
26
|
-
If `--start` was given, jump to
|
|
49
|
+
If `--start` was given, jump to Step 2. If Step 0 produced a concrete node (an endpoint, component, or file from the failing event), use THAT as the entry point — skip the blind search. Otherwise, use chart to find candidates:
|
|
27
50
|
|
|
28
|
-
1. Extract key terms from the symptom (component name, identifier, error class). Skip noise words.
|
|
29
|
-
2. Call `mcp__launch-chart__read_graph(search: <term>, type: <best-guess-type>, layer: <layer?>)`. If `type` is uncertain, omit it and filter
|
|
30
|
-
3. If `read_graph` returns 0 candidates, broaden:
|
|
51
|
+
1. Extract key terms from the symptom (component name, identifier, error class) — and from the beacon failure if Step 0 ran (the failing route/selector is a strong term). Skip noise words.
|
|
52
|
+
2. Call `mcp__launch-chart__read_graph(search: <term>, type: <best-guess-type>, layer: <layer?>)`. If `type` is uncertain, omit it and filter by relevance.
|
|
53
|
+
3. If `read_graph` returns 0 candidates, broaden: drop `type`, then `layer`. Surface the top 3 to the user; if they can pick, jump to Step 2 with their pick.
|
|
31
54
|
|
|
32
55
|
**Chart-gap detection (entry-point search):**
|
|
33
|
-
-
|
|
34
|
-
-
|
|
56
|
+
- `read_graph` returns 0 AND a quick `grep` confirms the term exists in source → file a chart-gap report (below), then proceed via grep fallback for this query only.
|
|
57
|
+
- `detect_project_stack` lists a layer (e.g. `api`) but `read_graph(layer:"api")` returns 0 nodes → file a chart-gap report (parser misconfig).
|
|
35
58
|
|
|
36
|
-
### Step 2 — understand the node
|
|
59
|
+
### Step 2 — understand the node (static)
|
|
37
60
|
|
|
38
61
|
Once the entry point is known, query its structure and behavior:
|
|
39
62
|
|
|
40
63
|
- **Structural** — `mcp__launch-chart__read_graph(node_id: <id>, hops: 1, include_edges: true)` for what it renders/imports and what depends on it.
|
|
41
|
-
- **Variable / state** — `mcp__launch-chart__inspect_node(node_id: <id>, fields: ["stateVars"])` or `(filter: <key-term>)` for
|
|
64
|
+
- **Variable / state** — `mcp__launch-chart__inspect_node(node_id: <id>, fields: ["stateVars"])` or `(filter: <key-term>)` for held state and conditions. Per project CLAUDE.md, ALWAYS start with `fields` or `filter` to keep the response small.
|
|
42
65
|
|
|
43
|
-
Compose a hypothesis
|
|
66
|
+
Compose a hypothesis. If Step 0 ran, **test the runtime hypothesis against the code** here — e.g. confirm the failing endpoint's handler actually can return the 500 beacon saw.
|
|
44
67
|
|
|
45
|
-
### Step 3 — follow the trail
|
|
68
|
+
### Step 3 — follow the trail (static)
|
|
46
69
|
|
|
47
|
-
Walk
|
|
70
|
+
Walk dependency edges toward the suspected cause (endpoint, table, util fn). At each hop, `read_graph(node_id, hops:1)` to find the next link. When you hit a leaf, narrate the chain back with file:line refs from the node ids. If Step 0 gave a runtime chain, align the two — the static call path should explain the observed runtime sequence.
|
|
48
71
|
|
|
49
72
|
### Step 4 — propose, don't fix
|
|
50
73
|
|
|
51
|
-
End with a one-paragraph diagnosis + 2
|
|
74
|
+
End with a one-paragraph diagnosis + 2–3 candidate causes ranked by likelihood. **When both sources contributed, say which evidence is runtime vs static** — e.g. *"Runtime (beacon): the tags fetch 500'd. Static (chart): the handler dereferences `org.id` with no null-guard when the session has no org — the likely cause."* A diagnosis backed by an observed failure + the matching code path is far stronger than either alone. Do NOT propose an edit unless asked — debug is investigation, not implementation. Suggest the next move: "Want me to read the handler and confirm?" or "Want to `/kit:diagram sequence` the call chain?"
|
|
52
75
|
|
|
53
76
|
## Grep fallback
|
|
54
77
|
|
|
@@ -78,8 +101,10 @@ Then continue with the grep fallback for THIS query. Don't file again in the sam
|
|
|
78
101
|
|
|
79
102
|
## Constraints
|
|
80
103
|
|
|
81
|
-
- **
|
|
104
|
+
- **Runtime-first, then static.** When a beacon session exists and the symptom is runtime-shaped, lead with beacon — it converts a blind structural search into a targeted one. Beacon is additive evidence: its absence never aborts the run, it just drops you to static-only with a one-line note.
|
|
105
|
+
- **Don't reimplement beacon skills.** Step 0 does a lightweight `beacon_failures` + `beacon_correlate`; for deeper runtime analysis defer to `/kit:beacon-pulse` (failure + N preceding) and `/kit:beacon-scan` (events by kind).
|
|
106
|
+
- **Chart-first for the static phase.** Default to MCP queries; grep only when the chart cannot answer.
|
|
82
107
|
- **One gap report per invocation.** Don't spam comments.
|
|
83
108
|
- **No implementation.** This skill diagnoses; it does not edit. If the user wants the fix, they invoke `/fix:*` or hand the diagnosis back to you in chat.
|
|
84
|
-
- **Cite
|
|
85
|
-
- **Surface
|
|
109
|
+
- **Cite your evidence.** Static claims link to a chart node id (file:line via `inspect_node` lines); runtime claims cite the beacon `seq` + event kind. The user can verify either.
|
|
110
|
+
- **Surface fallbacks verbatim.** When grep is used, or when beacon came up empty, the message (and why) must appear in the output — silent fallback hides the gap.
|