@launchsecure/launch-kit 0.0.28 → 0.0.30
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/beacon/beacon.mjs +2759 -1246
- package/dist/beacon/beacon.mjs.map +1 -1
- package/dist/beacon/beacon.umd.js +710 -95
- package/dist/beacon/beacon.umd.js.map +1 -1
- package/dist/beacon/types/core.d.ts +14 -0
- package/dist/beacon/types/core.d.ts.map +1 -0
- package/dist/beacon/types/ctx.d.ts +14 -0
- package/dist/beacon/types/ctx.d.ts.map +1 -0
- package/dist/beacon/types/element.d.ts +16 -48
- package/dist/beacon/types/element.d.ts.map +1 -1
- package/dist/beacon/types/index.d.ts +5 -4
- package/dist/beacon/types/index.d.ts.map +1 -1
- package/dist/beacon/types/internal/annotation-cache.d.ts +10 -0
- package/dist/beacon/types/internal/annotation-cache.d.ts.map +1 -0
- package/dist/beacon/types/internal/element-capture.d.ts +19 -0
- package/dist/beacon/types/internal/element-capture.d.ts.map +1 -0
- package/dist/beacon/types/internal/event-buffer.d.ts +16 -0
- package/dist/beacon/types/internal/event-buffer.d.ts.map +1 -0
- package/dist/beacon/types/internal/framework-detect.d.ts +6 -0
- package/dist/beacon/types/internal/framework-detect.d.ts.map +1 -0
- package/dist/beacon/types/internal/markers.d.ts +17 -0
- package/dist/beacon/types/internal/markers.d.ts.map +1 -0
- package/dist/beacon/types/internal/monitor/capture-dom.d.ts +14 -0
- package/dist/beacon/types/internal/monitor/capture-dom.d.ts.map +1 -0
- package/dist/beacon/types/internal/monitor/capture-network.d.ts +12 -0
- package/dist/beacon/types/internal/monitor/capture-network.d.ts.map +1 -0
- package/dist/beacon/types/internal/monitor/overlay.d.ts +16 -0
- package/dist/beacon/types/internal/monitor/overlay.d.ts.map +1 -0
- package/dist/beacon/types/internal/monitor/session.d.ts +41 -0
- package/dist/beacon/types/internal/monitor/session.d.ts.map +1 -0
- package/dist/beacon/types/{monitor → internal/monitor}/transport.d.ts +3 -3
- package/dist/beacon/types/internal/monitor/transport.d.ts.map +1 -0
- package/dist/beacon/types/{monitor/types.d.ts → internal/monitor/wire.d.ts} +69 -27
- package/dist/beacon/types/internal/monitor/wire.d.ts.map +1 -0
- package/dist/beacon/types/{ui → internal}/pick-mode-overlay.d.ts +4 -5
- package/dist/beacon/types/internal/pick-mode-overlay.d.ts.map +1 -0
- package/dist/beacon/types/{capture → internal}/picker.d.ts +0 -1
- package/dist/beacon/types/internal/picker.d.ts.map +1 -0
- package/dist/beacon/types/{ui → internal}/pin-popover.d.ts +1 -1
- package/dist/beacon/types/internal/pin-popover.d.ts.map +1 -0
- package/dist/beacon/types/{capture → internal}/screenshot.d.ts +1 -0
- package/dist/beacon/types/internal/screenshot.d.ts.map +1 -0
- package/dist/beacon/types/internal/selector.d.ts.map +1 -0
- package/dist/beacon/types/plugins/domEle.d.ts +14 -0
- package/dist/beacon/types/plugins/domEle.d.ts.map +1 -0
- package/dist/beacon/types/plugins/domSS.d.ts +8 -0
- package/dist/beacon/types/plugins/domSS.d.ts.map +1 -0
- package/dist/beacon/types/plugins/errors.d.ts +3 -0
- package/dist/beacon/types/plugins/errors.d.ts.map +1 -0
- package/dist/beacon/types/plugins/index.d.ts +8 -0
- package/dist/beacon/types/plugins/index.d.ts.map +1 -0
- package/dist/beacon/types/plugins/liveMonitor.d.ts +14 -0
- package/dist/beacon/types/plugins/liveMonitor.d.ts.map +1 -0
- package/dist/beacon/types/plugins/metadata.d.ts +3 -0
- package/dist/beacon/types/plugins/metadata.d.ts.map +1 -0
- package/dist/beacon/types/registry.d.ts +33 -0
- package/dist/beacon/types/registry.d.ts.map +1 -0
- package/dist/beacon/types/styles.d.ts +8 -0
- package/dist/beacon/types/styles.d.ts.map +1 -0
- package/dist/beacon/types/transport.d.ts +3 -0
- package/dist/beacon/types/transport.d.ts.map +1 -0
- package/dist/beacon/types/types.d.ts +152 -68
- package/dist/beacon/types/types.d.ts.map +1 -1
- package/dist/beacon/types/ui/dialog.d.ts +53 -0
- package/dist/beacon/types/ui/dialog.d.ts.map +1 -0
- package/dist/beacon/types/ui/form.d.ts +7 -0
- package/dist/beacon/types/ui/form.d.ts.map +1 -0
- package/dist/beacon/types/ui/overlay.d.ts +6 -0
- package/dist/beacon/types/ui/overlay.d.ts.map +1 -0
- package/dist/deck-client/assets/{_baseUniq-W2JQDmje.js → _baseUniq-DCt2IMRR.js} +1 -1
- package/dist/deck-client/assets/{arc-DIBWAId9.js → arc-h-ifqmNR.js} +1 -1
- package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-CAIRMvJK.js → architectureDiagram-Q4EWVU46-C9dITSPv.js} +1 -1
- package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-BeNaNiOi.js → blockDiagram-DXYQGD6D-BHuJT34t.js} +1 -1
- package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-B9Ozi62h.js → c4Diagram-AHTNJAMY-CpvMGtDG.js} +1 -1
- package/dist/deck-client/assets/channel-2PZVMiXf.js +1 -0
- package/dist/deck-client/assets/{chunk-4BX2VUAB-D7AZ47dt.js → chunk-4BX2VUAB-B6md1VIm.js} +1 -1
- package/dist/deck-client/assets/{chunk-4TB4RGXK-DnVnNPcI.js → chunk-4TB4RGXK-BmEnX8ik.js} +1 -1
- package/dist/deck-client/assets/{chunk-55IACEB6-UKYs-YNd.js → chunk-55IACEB6-BZPUyZAZ.js} +1 -1
- package/dist/deck-client/assets/{chunk-EDXVE4YY-D43b-SKn.js → chunk-EDXVE4YY-BWwNUK-l.js} +1 -1
- package/dist/deck-client/assets/{chunk-FMBD7UC4-QzBAoyyW.js → chunk-FMBD7UC4-o7gSppGI.js} +1 -1
- package/dist/deck-client/assets/{chunk-OYMX7WX6-Cjif4r6W.js → chunk-OYMX7WX6-C4KoTL5p.js} +1 -1
- package/dist/deck-client/assets/{chunk-QZHKN3VN-CqLDirEI.js → chunk-QZHKN3VN-jkf68sDs.js} +1 -1
- package/dist/deck-client/assets/{chunk-YZCP3GAM-_FQvmMs4.js → chunk-YZCP3GAM-Cd4yBE7o.js} +1 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-Bt8xBAof.js +1 -0
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-Bt8xBAof.js +1 -0
- package/dist/deck-client/assets/clone-BHQryoDl.js +1 -0
- package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-rfrocesE.js → cose-bilkent-S5V4N54A-DeGFUgAV.js} +1 -1
- package/dist/deck-client/assets/{dagre-KV5264BT-Bv_7DJat.js → dagre-KV5264BT-ekcYJuUV.js} +1 -1
- package/dist/deck-client/assets/{diagram-5BDNPKRD-4F1414G5.js → diagram-5BDNPKRD-YHPk4rV2.js} +1 -1
- package/dist/deck-client/assets/{diagram-G4DWMVQ6-C4-Pszqm.js → diagram-G4DWMVQ6-DM-JCd_B.js} +1 -1
- package/dist/deck-client/assets/{diagram-MMDJMWI5-B647TIx9.js → diagram-MMDJMWI5-l5FK1ybk.js} +1 -1
- package/dist/deck-client/assets/{diagram-TYMM5635-BFAqpezd.js → diagram-TYMM5635-CIN4_1-j.js} +1 -1
- package/dist/deck-client/assets/{erDiagram-SMLLAGMA-BfBfrJOC.js → erDiagram-SMLLAGMA-MyinSkEl.js} +1 -1
- package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-DX9YAYes.js → flowDiagram-DWJPFMVM-Dk8nn42x.js} +1 -1
- package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-DCuiy7wF.js → ganttDiagram-T4ZO3ILL-BU1ihicu.js} +1 -1
- package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-CGp1IXUh.js → gitGraphDiagram-UUTBAWPF-BjsTL13C.js} +1 -1
- package/dist/deck-client/assets/{graph-B7g8aoxv.js → graph-DJmh-xi7.js} +1 -1
- package/dist/deck-client/assets/{index-Dg1r-WSN.js → index-KsShfCV-.js} +3 -3
- package/dist/deck-client/assets/{infoDiagram-42DDH7IO-L3fahMkF.js → infoDiagram-42DDH7IO-Dxvy_RB4.js} +1 -1
- package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-aS_EjWBZ.js → ishikawaDiagram-UXIWVN3A-DPOaNF1l.js} +1 -1
- package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-djTSQZF9.js → journeyDiagram-VCZTEJTY-DMew3K5c.js} +1 -1
- package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-CcTHo4CM.js → kanban-definition-6JOO6SKY-csciJFuk.js} +1 -1
- package/dist/deck-client/assets/{layout-mEJiadb7.js → layout-Dg4yyms2.js} +1 -1
- package/dist/deck-client/assets/{linear-XgTKqyRu.js → linear-BA3zU6gq.js} +1 -1
- package/dist/deck-client/assets/{min-Ct9jZdpd.js → min-lz-Ird-p.js} +1 -1
- package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-BaFxCGNU.js → mindmap-definition-QFDTVHPH-CCEN8OQV.js} +1 -1
- package/dist/deck-client/assets/{pieDiagram-DEJITSTG-CIbYYjtw.js → pieDiagram-DEJITSTG-DM6n1HY7.js} +1 -1
- package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-D9EtCOvh.js → quadrantDiagram-34T5L4WZ-_ULoR66n.js} +1 -1
- package/dist/deck-client/assets/{requirementDiagram-MS252O5E-xeni9eVG.js → requirementDiagram-MS252O5E-BuwJs7Tn.js} +1 -1
- package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-LYeknz9h.js → sankeyDiagram-XADWPNL6-BEsuzkW4.js} +1 -1
- package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-RDbsKFZf.js → sequenceDiagram-FGHM5R23-CP2H0YWf.js} +1 -1
- package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-BH1Zjglk.js → stateDiagram-FHFEXIEX-B5Gw_NNL.js} +1 -1
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-4T4wMDXr.js +1 -0
- package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-IFXxKptt.js → timeline-definition-GMOUNBTQ-DsoYydQa.js} +1 -1
- package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-D-sLkQs9.js → vennDiagram-DHZGUBPP-Dz8JT_ob.js} +1 -1
- package/dist/deck-client/assets/wardley-RL74JXVD-DGHQ_Ijv.js +162 -0
- package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-BTjjuDU3.js → wardleyDiagram-NUSXRM2D-DN1LJMB1.js} +1 -1
- package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-AYbv92n-.js → xychartDiagram-5P7HB3ND-nb0oSfrQ.js} +1 -1
- package/dist/deck-client/index.html +1 -1
- package/dist/server/beacon-monitor-entry.js +548 -6
- package/dist/server/chart-serve.js +920 -249
- package/dist/server/cli.js +1599 -595
- package/dist/server/course-entry.js +3 -3
- package/dist/server/graph-mcp-entry.js +1361 -394
- package/dist/server/init-entry.js +799 -195
- package/dist/server/orbit-entry.js +135 -7
- package/dist/server/parse-worker-entry.js +918 -247
- package/package.json +3 -2
- package/scaffolds/ls-marketplace/.claude-plugin/marketplace.json +4 -4
- package/scaffolds/ls-marketplace/plugins/{ls → kit}/.claude-plugin/plugin.json +1 -10
- package/scaffolds/ls-marketplace/plugins/{ls → kit}/commands/activate-beacon.md +2 -2
- package/scaffolds/ls-marketplace/plugins/kit/commands/activate-statusline.md +46 -0
- package/scaffolds/ls-marketplace/plugins/kit/commands/deactivate-statusline.md +34 -0
- package/scaffolds/ls-marketplace/plugins/{ls → kit}/commands/standup.md +52 -38
- package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-array.md +107 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-clear.md +94 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-pulse.md +82 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-scan.md +66 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/blast-radius.md +101 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/brief.md +112 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/course.md +84 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/debug.md +92 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/deploy-check.md +160 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/diagram.md +134 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/orbit.md +87 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/prototype.md +90 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/recall.md +83 -0
- package/scaffolds/ls-marketplace/plugins/{ls/commands → kit/skills}/show-mcp-status.md +8 -8
- package/scaffolds/ls-marketplace/plugins/kit/skills/wireframe.md +70 -0
- package/scaffolds/statusline/statusline-mcp.sh +204 -0
- package/scaffolds/statusline/statusline-wrapper.sh +50 -0
- package/dist/beacon/types/capture/element.d.ts +0 -3
- package/dist/beacon/types/capture/element.d.ts.map +0 -1
- package/dist/beacon/types/capture/events.d.ts +0 -20
- package/dist/beacon/types/capture/events.d.ts.map +0 -1
- package/dist/beacon/types/capture/framework.d.ts +0 -3
- package/dist/beacon/types/capture/framework.d.ts.map +0 -1
- package/dist/beacon/types/capture/metadata.d.ts +0 -3
- package/dist/beacon/types/capture/metadata.d.ts.map +0 -1
- package/dist/beacon/types/capture/overlay.d.ts +0 -7
- package/dist/beacon/types/capture/overlay.d.ts.map +0 -1
- package/dist/beacon/types/capture/picker.d.ts.map +0 -1
- package/dist/beacon/types/capture/screenshot.d.ts.map +0 -1
- package/dist/beacon/types/capture/selector.d.ts.map +0 -1
- package/dist/beacon/types/monitor/dom.d.ts +0 -13
- package/dist/beacon/types/monitor/dom.d.ts.map +0 -1
- package/dist/beacon/types/monitor/index.d.ts +0 -19
- package/dist/beacon/types/monitor/index.d.ts.map +0 -1
- package/dist/beacon/types/monitor/network.d.ts +0 -12
- package/dist/beacon/types/monitor/network.d.ts.map +0 -1
- package/dist/beacon/types/monitor/transport.d.ts.map +0 -1
- package/dist/beacon/types/monitor/types.d.ts.map +0 -1
- package/dist/beacon/types/transport/submit.d.ts +0 -3
- package/dist/beacon/types/transport/submit.d.ts.map +0 -1
- package/dist/beacon/types/ui/button.d.ts +0 -2
- package/dist/beacon/types/ui/button.d.ts.map +0 -1
- package/dist/beacon/types/ui/drawer.d.ts +0 -33
- package/dist/beacon/types/ui/drawer.d.ts.map +0 -1
- package/dist/beacon/types/ui/icons.d.ts +0 -9
- package/dist/beacon/types/ui/icons.d.ts.map +0 -1
- package/dist/beacon/types/ui/monitor-panel.d.ts +0 -19
- package/dist/beacon/types/ui/monitor-panel.d.ts.map +0 -1
- package/dist/beacon/types/ui/pick-mode-overlay.d.ts.map +0 -1
- package/dist/beacon/types/ui/pin-popover.d.ts.map +0 -1
- package/dist/deck-client/assets/channel-CRdozqbp.js +0 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-lIZMp57W.js +0 -1
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-lIZMp57W.js +0 -1
- package/dist/deck-client/assets/clone-BtWeSTyJ.js +0 -1
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-BrV78NDR.js +0 -1
- package/dist/deck-client/assets/wardley-RL74JXVD-C010F8l4.js +0 -162
- package/scaffolds/ls-marketplace/plugins/ls/commands/beacon-array.md +0 -92
- package/scaffolds/ls-marketplace/plugins/ls/commands/beacon-clear.md +0 -68
- package/scaffolds/ls-marketplace/plugins/ls/commands/beacon-pulse.md +0 -80
- package/scaffolds/ls-marketplace/plugins/ls/commands/beacon-scan.md +0 -62
- /package/dist/beacon/types/{capture → internal}/selector.d.ts +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Show the most recent failure from the active launch-beacon monitor session, plus the N events that preceded it (default 10). Answers "what was happening when it broke" without scrolling through the full stream. Read-only.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /kit:beacon-pulse
|
|
6
|
+
|
|
7
|
+
The "what happened just before this failure" command — a single pulse, freezing the moment the beacon caught a failure. When a bug fires, the actual story is usually the chain of events leading up to it: the click that triggered a state change, the failed fetch that left auth in a bad state, the route change that mounted the wrong component.
|
|
8
|
+
|
|
9
|
+
A "failure" here is anything `mcp__local-launch-beacon__beacon_failures` returns — window errors, unhandled rejections, fetch/xhr with status ≥ 400 or thrown, and clicks where overlay interception blocked the intended target. Broader than just `kind=error`; matches what users mean when they say "something broke."
|
|
10
|
+
|
|
11
|
+
Parse `$ARGUMENTS` as space-separated tokens, in any order:
|
|
12
|
+
- An optional **integer** — the count of preceding events to include. Default 10. Cap at 50 (the `beacon_correlate.before` tool limit).
|
|
13
|
+
- `--worktree=<slug>` — orbit worktree slug. Forwarded to every MCP call as the `worktree` arg.
|
|
14
|
+
- `--project_root=<path>` — explicit project root (absolute, or relative to cwd). Forwarded as `project_root`. Takes precedence over `--worktree`.
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
- `/kit:beacon-pulse` → 10 events before the latest failure
|
|
18
|
+
- `/kit:beacon-pulse 25` → 25 events before
|
|
19
|
+
- `/kit:beacon-pulse --worktree=beacon_rewrite` → query a worktree's session
|
|
20
|
+
|
|
21
|
+
## Locate the most recent failure
|
|
22
|
+
|
|
23
|
+
Call `mcp__local-launch-beacon__beacon_failures` with `limit: 1` (and `worktree` / `project_root` if the user supplied them). The tool implicitly targets the most recent session.
|
|
24
|
+
|
|
25
|
+
If the response is `{error: "no session found"}` OR an empty failures array, **alert the user with the exact MCP error string**, then walk the fallback below — do NOT silently grep. The MCP can come up empty for two non-bug reasons: (a) no session has been started, (b) the session NDJSON lives outside the MCP's watch root (e.g. inside an orbit worktree the user didn't name).
|
|
26
|
+
|
|
27
|
+
**Fallback when the MCP returns nothing:**
|
|
28
|
+
1. If the user did NOT pass `--worktree` / `--project_root` and `launch-orbit` has worktrees registered for this repo, suggest re-running with `--worktree=<slug>` before falling back to the filesystem.
|
|
29
|
+
2. Look for `.launchsecure/beacon-*.ndjson` in cwd, then in up to 2 parent dirs. Use the `Read` tool to inspect the most-recently-modified matching file — do NOT use `grep`, `find`, or `ls` as the primary path.
|
|
30
|
+
3. If files are found at an alternative path, tell the user the path mismatch explicitly: `"MCP scans <root>/.launchsecure/ but the session lives at <found-path>. Reading directly."`
|
|
31
|
+
4. If nothing is found anywhere, stop with: `"No beacon sessions found. Start one with: npx launch-beacon monitor"`.
|
|
32
|
+
|
|
33
|
+
Capture the failure's `seq`, `kind`, `ts`, and message.
|
|
34
|
+
|
|
35
|
+
## Pull the context window
|
|
36
|
+
|
|
37
|
+
Call `mcp__local-launch-beacon__beacon_correlate` with `seq: <failure.seq>`, `before: N`, `after: 0`, plus the same `worktree` / `project_root` args you used on `beacon_failures`. The tool returns event summaries directly — no JSON parsing required.
|
|
38
|
+
|
|
39
|
+
If a context event's summary is missing detail you need for analysis (truncated stack, missing response body, selector chain), call `mcp__local-launch-beacon__beacon_event` with that event's specific `seq` for the full JSON — and forward the same root args. Only do this when the summary is insufficient — not unconditional.
|
|
40
|
+
|
|
41
|
+
## Output
|
|
42
|
+
|
|
43
|
+
Render a **timeline** with the failure visually separated at the bottom:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
session: <token>
|
|
47
|
+
window: N events before failure at seq <seq>
|
|
48
|
+
|
|
49
|
+
12:34:51 click button.submit-btn
|
|
50
|
+
12:34:51 fetch POST 401 /api/sessions (120ms) FAILED
|
|
51
|
+
12:34:51 fetch GET 401 /api/me (45ms) FAILED
|
|
52
|
+
12:34:52 route /login → /dashboard (pushState)
|
|
53
|
+
...
|
|
54
|
+
|
|
55
|
+
╴╴╴╴ FAILURE ╴╴╴╴
|
|
56
|
+
12:34:53 error Cannot read properties of undefined (reading 'orgSlug')
|
|
57
|
+
at apps/Console.tsx:42:18
|
|
58
|
+
stack: Console.render
|
|
59
|
+
React.renderWithHooks
|
|
60
|
+
React.beginWork
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Format rules:
|
|
64
|
+
- One line per event, same SUMMARY format as `/kit:beacon-scan`.
|
|
65
|
+
- The failure block at the end gets the message + (truncated) stack frames if present. For fetch/xhr failures, include method + status + url + response body summary.
|
|
66
|
+
- Separator above the failure is the visual cue.
|
|
67
|
+
|
|
68
|
+
After the timeline, write **one short paragraph** of analysis: what does the chain *look* like? Common patterns:
|
|
69
|
+
- 401s → error referencing user/org → "auth expired or org context missing"
|
|
70
|
+
- click → no observable effect → click again → error → "first click handler crashed silently; second click landed on something else"
|
|
71
|
+
- route change → error → "component on the new route blew up during initial render"
|
|
72
|
+
- repeated 400s on the same endpoint → "request shape mismatch — check the server's Zod schema against the client payload"
|
|
73
|
+
|
|
74
|
+
Don't dive into a fix — name the suspected proximate cause, suggest one concrete next step (which file to read, which probe to add, which `/kit:beacon-scan <kind>` to drill into).
|
|
75
|
+
|
|
76
|
+
## Constraints
|
|
77
|
+
|
|
78
|
+
- **MCP-first.** Use `beacon_failures`, `beacon_correlate`, `beacon_event` — never `grep`, `find`, `ls`, `sed`, `cut`, or `tail` as the primary path.
|
|
79
|
+
- **Alert on fallback.** If the MCP can't answer, say so verbatim before reading the file directly.
|
|
80
|
+
- **Read-only.**
|
|
81
|
+
- **Most recent failure only.** For an earlier one, clear the session (`/kit:beacon-clear`) and reproduce, or use `/kit:beacon-scan error` / `/kit:beacon-scan fetch` to browse.
|
|
82
|
+
- **Plain text.** Same monospace conventions as `/kit:beacon-scan`.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scan recent events from the active launch-beacon monitor session via the launch-beacon MCP. Defaults to last 50 events across all kinds; pass a kind (`error`, `click`, `fetch`, `route`, `dialog`, `probe`, etc.) to filter, and/or a numeric limit. Read-only.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /kit:beacon-scan
|
|
6
|
+
|
|
7
|
+
Recent runtime events captured by a `launch-beacon monitor` session. Use this as the first step when investigating something that just happened in the browser — clicks, failed network calls, errors, route changes, probe() calls, dialog mount/unmount.
|
|
8
|
+
|
|
9
|
+
Parse `$ARGUMENTS` as space-separated tokens, in any order:
|
|
10
|
+
- A **kind filter**: one of `error`, `unhandledrejection`, `fetch`, `xhr`, `click`, `mousedown`, `route`, `dialog`, `submit`, `probe`. Anything else that doesn't parse as an integer or a known `--flag` is treated as an explicit session token.
|
|
11
|
+
- A **limit**: integer. Default 50. Hard cap 500 (the `beacon_recent.limit` tool ceiling).
|
|
12
|
+
- An explicit **session token** (8-char hex like `8f3c2a91`) — passed straight through as the `session` MCP arg.
|
|
13
|
+
- `--worktree=<slug>` — orbit worktree slug (from `launch-orbit create`). Forwarded to the MCP as the `worktree` arg so a Claude session pinned to the main repo can read sessions captured inside a worktree.
|
|
14
|
+
- `--project_root=<path>` — explicit project root (absolute, or relative to cwd). Forwarded to the MCP as `project_root`. Takes precedence over `--worktree`.
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
- `/kit:beacon-scan` → last 50 events of any kind from the latest session
|
|
18
|
+
- `/kit:beacon-scan error` → last 50 errors only
|
|
19
|
+
- `/kit:beacon-scan click 20` → last 20 click events
|
|
20
|
+
- `/kit:beacon-scan 100` → last 100 events of any kind
|
|
21
|
+
- `/kit:beacon-scan fetch 50 8f3c2a91` → last 50 fetches from a specific session
|
|
22
|
+
- `/kit:beacon-scan fetch --worktree=beacon_rewrite` → last 50 fetches captured in that worktree
|
|
23
|
+
|
|
24
|
+
## Scan
|
|
25
|
+
|
|
26
|
+
Call `mcp__local-launch-beacon__beacon_recent` with `kind: <kind?>`, `limit: <limit>`, `session: <session?>`, plus `worktree: <slug?>` and `project_root: <path?>` if the user supplied them. The tool defaults to the most-recent session and returns one compact summary line per event.
|
|
27
|
+
|
|
28
|
+
If the response is `{error: "no session found"}` OR an empty events array, **alert the user with the exact MCP error string**, then walk the fallback below — do NOT silently grep.
|
|
29
|
+
|
|
30
|
+
**Fallback when the MCP returns nothing:**
|
|
31
|
+
1. If the user did NOT pass `--worktree` / `--project_root` and the cwd is the main repo of a project that has worktrees registered with `launch-orbit`, suggest re-running with `--worktree=<slug>` before falling back to the filesystem — that's usually the actual fix and avoids a wrong-directory scan.
|
|
32
|
+
2. Look for `.launchsecure/beacon-*.ndjson` in cwd, then in up to 2 parent dirs. Use the `Read` tool to inspect the most-recently-modified matching file — do NOT use `grep`, `find`, or `ls` as the primary path.
|
|
33
|
+
3. If files are found at an alternative path, tell the user the path mismatch explicitly: `"MCP scans <root>/.launchsecure/ but the session lives at <found-path>. Reading directly."`
|
|
34
|
+
4. If nothing is found anywhere, stop with: `"No beacon sessions found. Start one with: npx launch-beacon monitor"`.
|
|
35
|
+
|
|
36
|
+
## Output
|
|
37
|
+
|
|
38
|
+
Group events by **time** (most recent last — chronological matches user intuition for "what happened"). For each event, render one line:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
HH:MM:SS KIND SUMMARY
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Where SUMMARY is a one-liner pulled from the event body:
|
|
45
|
+
- **error / unhandledrejection** → `message` (truncate ≤ 80 chars)
|
|
46
|
+
- **fetch / xhr** → `METHOD status url (durationMs)` — flag `FAILED` if `failed:true`
|
|
47
|
+
- **click / mousedown** → `target.selector` and, when `hitMatchesTarget === false`, also append `(occluded by <hitTarget.selector>)` — that's exactly the diagnostic the user is here for
|
|
48
|
+
- **route** → `from → to (via)`
|
|
49
|
+
- **dialog** → `<action> <selector>` (e.g. `mount dialog#xyz` or `unmount section[role=dialog]`)
|
|
50
|
+
- **submit** → `<form selector> (preventDefault?)`
|
|
51
|
+
- **probe** → `<label>: <truncated JSON>`
|
|
52
|
+
|
|
53
|
+
If a summary line is missing detail you need (truncated response body, full selector chain, stack frames), call `mcp__local-launch-beacon__beacon_event` with that event's `seq` for the full JSON — and forward the same `worktree` / `project_root` args you used on `beacon_recent`. Only on demand — not unconditional.
|
|
54
|
+
|
|
55
|
+
After the timeline, if anything looks suspicious (clusters of failed network calls, a click followed by no observable effect, a `hitMatchesTarget:false` event, an unhandled rejection), call it out in **one short paragraph** at the end. Don't analyze every event — only surface the standouts.
|
|
56
|
+
|
|
57
|
+
If the buffer is empty after filtering, say so: `No events match that filter in <session>.`
|
|
58
|
+
|
|
59
|
+
## Constraints
|
|
60
|
+
|
|
61
|
+
- **MCP-first.** Use `beacon_recent` / `beacon_event` — never `grep`, `find`, `ls`, `tail`, `head` as the primary path.
|
|
62
|
+
- **Alert on fallback.** If the MCP can't answer, say so verbatim before reading the file directly.
|
|
63
|
+
- **Read-only.** Never delete, modify, or write to the NDJSON file. Wiping is `/kit:beacon-clear`.
|
|
64
|
+
- **Always use the latest session by default.** Pass an explicit token as the third arg only when the user wants a specific older session.
|
|
65
|
+
- **Plain text output.** Monospace alignment beats markdown tables here.
|
|
66
|
+
- **Don't speculate on root cause.** Surface anomalies; let the user direct the next query (often: `/kit:beacon-pulse` for context around the latest failure).
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Build a blast radius for a file/table/endpoint via launch-chart and push it to launch-deck as an interactive radial graph. Use to assess "what breaks if I change X" before refactors, schema migrations, or API contract changes. Chart-first; on chart gaps (no nodes, missing layer, empty edges) files a feedback comment to LaunchSecure so the gap is monitored.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /kit:blast-radius
|
|
6
|
+
|
|
7
|
+
Calculate the reverse-dependency blast radius for a target node and visualise it as an interactive radial graph in launch-deck. The graph centres on the target and rings out by hop distance across all project layers (db / api / ui / static / etc.).
|
|
8
|
+
|
|
9
|
+
Parse `$ARGUMENTS`:
|
|
10
|
+
- **target** (required) — a node id from the project graph (file path like `lib/permissions/types.ts`, table name like `User`, endpoint id like `POST /api/work-items`). If absent, ask the user.
|
|
11
|
+
- **hops=N** — max traversal depth. Default 2.
|
|
12
|
+
- **layer=<id>** — restrict to one layer when the same name exists in multiple layers (e.g. `layer=db`).
|
|
13
|
+
- **--session=<id>** — deck session name. Default `blast-<target-slug>`.
|
|
14
|
+
- **--mode=feature** — render with feature rings (modify / create / ripple) instead of the default structural rings (hop1 / hop2). Use when the radius represents planned change scope rather than pure structural reachability.
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
- `/kit:blast-radius lib/permissions/types.ts`
|
|
18
|
+
- `/kit:blast-radius User layer=db hops=3`
|
|
19
|
+
- `/kit:blast-radius POST /api/work-items --mode=feature`
|
|
20
|
+
|
|
21
|
+
## Preflight
|
|
22
|
+
|
|
23
|
+
1. Confirm both MCPs are wired — `mcp__launch-chart__chart_server_status` and `mcp__launch-deck__server_status`. If either is missing, stop and tell the user to run `npx @launchsecure/launch-kit refresh` (or `npx launch-deck` for the deck server).
|
|
24
|
+
2. Run `mcp__launch-chart__detect_project_stack` once. Cache the returned `layers` for the bug-report fallback below.
|
|
25
|
+
|
|
26
|
+
## 1. Compute the blast points
|
|
27
|
+
|
|
28
|
+
Call `mcp__launch-chart__blast_points` with `node_id: <target>`, `hops: <hops>`, `direction: "reverse"`, and `layer` if supplied. The tool returns affected nodes (with hop, type, layer, module) plus a summary.
|
|
29
|
+
|
|
30
|
+
**Chart-gap detection** — if any of these are true, file a feedback comment per the shared `chart-gap` protocol below before stopping:
|
|
31
|
+
- `error` is set
|
|
32
|
+
- `nodes` is empty AND the user explicitly named a node id that exists on disk (verify by `Read`-ing the path)
|
|
33
|
+
- `summary.byLayer` covers fewer layers than `detect_project_stack` reported as available
|
|
34
|
+
|
|
35
|
+
## 2. Build the manifest
|
|
36
|
+
|
|
37
|
+
Translate the blast_points result into the deck `blast-radius` block manifest shape. Reuse layer ids/icons/colors from `detect_project_stack` so the visual matches the project's conventions; fall back to:
|
|
38
|
+
- db → `database`, `#172554`
|
|
39
|
+
- api → `server`, `#1e3a5f`
|
|
40
|
+
- ui → `layout-dashboard`, `#0c4a6e`
|
|
41
|
+
- static → `file-text`, `#374151`
|
|
42
|
+
- shared → `puzzle`, `#4338ca`
|
|
43
|
+
- middleware → `shield`, `#1f2937`
|
|
44
|
+
- config → `cog`, `#52525b`
|
|
45
|
+
|
|
46
|
+
Rings:
|
|
47
|
+
- structural mode (default): `[{id:"hop1",name:"Direct",color:"#f97316"},{id:"hop2",name:"Indirect",color:"#eab308"}]`
|
|
48
|
+
- feature mode: `[{id:"modify",name:"Modify",color:"#f97316"},{id:"create",name:"Create",color:"#22c55e"},{id:"ripple",name:"Ripple",color:"#eab308"}]`
|
|
49
|
+
|
|
50
|
+
Centre node: `{ name: <target>, description: "<N> direct, <M> indirect (<hops> hops)" }`.
|
|
51
|
+
|
|
52
|
+
Nodes: map each blast result row to `{ id, name, layer, ring: hop===1 ? "hop1" : "hop2", path, type }`.
|
|
53
|
+
|
|
54
|
+
Edges: connect the centre to every hop=1 node; connect each hop=2 node to one hop=1 ancestor from its dependency chain (read from `blast_points` `via` field if present, otherwise pick any hop=1 node in the same layer).
|
|
55
|
+
|
|
56
|
+
## 3. Push to deck
|
|
57
|
+
|
|
58
|
+
Call `mcp__launch-deck__deck` with `session: <session>`, `mode: "show"`, `blocks: [{ type: "blast-radius", label: <target>, manifest: <built-manifest> }]`.
|
|
59
|
+
|
|
60
|
+
If the deck server isn't running, call `mcp__launch-deck__start_server` first, then retry. Report the deck URL back to the user.
|
|
61
|
+
|
|
62
|
+
## Output
|
|
63
|
+
|
|
64
|
+
After the push, print a terse summary:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
blast-radius for <target> — <N> direct, <M> indirect (<hops> hops)
|
|
68
|
+
by layer: db 4, api 7, ui 12
|
|
69
|
+
pushed to deck session "<session>" — http://localhost:52829/?session=<session>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Chart-gap protocol (shared)
|
|
73
|
+
|
|
74
|
+
When the chart MCP returns less data than expected, file ONE feedback comment in the project's Comm Hub (cloud LS by default per project memory — use `mcp__launch-secure__communication_write`, not the local variant) before stopping:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
resource_type: "feedback"
|
|
78
|
+
title: "launch-chart gap: <one-line>"
|
|
79
|
+
body: |
|
|
80
|
+
Skill: /kit:blast-radius
|
|
81
|
+
Tool: blast_points(node_id=<id>, hops=<n>, layer=<layer?>)
|
|
82
|
+
Returned: <nodes_count> nodes, layers=<layers_seen>
|
|
83
|
+
Expected: <what-was-expected, e.g. "node exists at <path>" or "layer X should appear">
|
|
84
|
+
Project stack: <one-line summary from detect_project_stack>
|
|
85
|
+
fields:
|
|
86
|
+
severity: "low"
|
|
87
|
+
source: "kit-skill"
|
|
88
|
+
skill: "blast-radius"
|
|
89
|
+
tool: "blast_points"
|
|
90
|
+
args: { node_id, hops, layer }
|
|
91
|
+
response_summary: { nodes_count, layers_seen, error }
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Do NOT spam — file at most one comment per skill invocation. After filing, tell the user "Filed chart-gap report to LS (id: …). Falling back to read_graph + Read." and continue with a degraded path: try `mcp__launch-chart__read_graph` with `search: <target>` to confirm the node exists in any layer; if so, do the blast-radius math from `include_edges: true` results manually; otherwise stop and surface the gap to the user.
|
|
95
|
+
|
|
96
|
+
## Constraints
|
|
97
|
+
|
|
98
|
+
- **MCP-first.** Never grep the filesystem to build the manifest — use `blast_points` and `read_graph`.
|
|
99
|
+
- **Idempotent on re-run.** Re-pushing to the same session overwrites the previous render — that's fine, just tell the user.
|
|
100
|
+
- **Single bug-file per run.** Don't file a comment for every gap; bundle into one report.
|
|
101
|
+
- **Plain text output.** No markdown tables, no fenced blocks in the human-facing summary.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create or update a repo-backed Brief in the LaunchSecure Comm Hub per the LS Briefs framework — Discovery-plane document (docCategory=features) authored as a comment that's also synced to a markdown file in the repo. Use to capture an idea before promoting it to an Epic.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /kit:brief
|
|
6
|
+
|
|
7
|
+
A **Brief** is an LS Discovery-plane artefact: a long-form description of a problem/opportunity, authored as a comment in the project's Comm Hub AND backed by a markdown file in the repo (`docs/requirements/features/<slug>.md` by convention). It's the structured alternative to a free-form Discussion when the idea has enough shape to write down. Briefs get promoted to Epics on the Roadmap once they're DECIDED.
|
|
8
|
+
|
|
9
|
+
Parse `$ARGUMENTS`:
|
|
10
|
+
- **subcommand** (required) — `new` | `update` | `list` | `show`.
|
|
11
|
+
- For **new**: `<title>` (required), `--from=discussion:<id>` to seed body from an existing discussion thread, `--module=<slug>` to tag.
|
|
12
|
+
- For **update**: `<brief-id-or-slug>` and either a body description (re-generates body) or `--append=<text>` to add a section.
|
|
13
|
+
- For **list**: `[--module=<slug>] [--status=open|decided|declined]`.
|
|
14
|
+
- For **show**: `<brief-id-or-slug>`.
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
- `/kit:brief new "Channels for Comm Hub" --module=communication`
|
|
18
|
+
- `/kit:brief new "Roadmap nav" --from=discussion:cmt_abc123`
|
|
19
|
+
- `/kit:brief list --status=open`
|
|
20
|
+
- `/kit:brief show channels-for-comms`
|
|
21
|
+
- `/kit:brief update channels-for-comms --append="Resolved: use the Slack metaphor not Teams."`
|
|
22
|
+
|
|
23
|
+
## Preflight
|
|
24
|
+
|
|
25
|
+
1. Confirm `mcp__launch-secure__ping` works (the cloud LS MCP must be wired). If only `mcp__local-launch-secure__*` is wired, ask the user whether to post to local or cloud — default per project memory is CLOUD.
|
|
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.
|
|
27
|
+
|
|
28
|
+
## The Brief shape
|
|
29
|
+
|
|
30
|
+
Per the LS Briefs framework (`docs/requirements/work-items/roadmap-and-hierarchy.md`):
|
|
31
|
+
|
|
32
|
+
- **resourceType**: `comment` (Briefs are comments)
|
|
33
|
+
- **docCategory**: `features` (this is what file-backed sync watches)
|
|
34
|
+
- **title**: the human-friendly name; the slug is derived
|
|
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
|
|
38
|
+
|
|
39
|
+
### Body template
|
|
40
|
+
|
|
41
|
+
When generating a NEW brief, use this skeleton (markdown body):
|
|
42
|
+
|
|
43
|
+
```markdown
|
|
44
|
+
# <Title>
|
|
45
|
+
|
|
46
|
+
**Status**: PROPOSED
|
|
47
|
+
**Owner**: <user-mention or "unassigned">
|
|
48
|
+
**Module**: <module slug or "-">
|
|
49
|
+
|
|
50
|
+
## Problem
|
|
51
|
+
|
|
52
|
+
<1-2 paragraphs — what's broken or missing, who feels it, why now>
|
|
53
|
+
|
|
54
|
+
## Proposed direction
|
|
55
|
+
|
|
56
|
+
<1-3 paragraphs — the shape of the solution, not the implementation>
|
|
57
|
+
|
|
58
|
+
## Out of scope
|
|
59
|
+
|
|
60
|
+
- <bullets — what this brief deliberately does NOT cover>
|
|
61
|
+
|
|
62
|
+
## Open questions
|
|
63
|
+
|
|
64
|
+
- [ ] <bullets — what we still need to decide before this can become an Epic>
|
|
65
|
+
|
|
66
|
+
## Success looks like
|
|
67
|
+
|
|
68
|
+
<1-2 sentences — observable outcome, not "ship X">
|
|
69
|
+
|
|
70
|
+
## References
|
|
71
|
+
|
|
72
|
+
- <link to existing code via launch-chart node id (use mcp__launch-chart__read_graph to find the right nodes; cite them as `lib/foo/bar.ts:42`)>
|
|
73
|
+
- <related comments by id>
|
|
74
|
+
```
|
|
75
|
+
|
|
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
|
+
## Write paths
|
|
79
|
+
|
|
80
|
+
### new
|
|
81
|
+
|
|
82
|
+
1. Build the body from the template + the user's description (or the `--from=discussion:<id>` seed — fetch via `communication_read` and weave the relevant points into the Problem/Proposed-direction sections).
|
|
83
|
+
2. Call `mcp__launch-secure__communication_write` with:
|
|
84
|
+
- `title: <user-supplied>`
|
|
85
|
+
- `body: <generated-markdown>`
|
|
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."
|
|
91
|
+
|
|
92
|
+
### update
|
|
93
|
+
|
|
94
|
+
1. Resolve `<brief-id-or-slug>` via `communication_read(resourceType: "comment", search: <slug>)`. If multiple match, list them and stop.
|
|
95
|
+
2. If `--append=<text>`, fetch the current body, append the text under a `## Update <ISO-date>` heading, and call `mcp__launch-secure__communication_update` with the new body.
|
|
96
|
+
3. If a fresh description was passed, regenerate the body from the template + new description, ask the user to confirm (show the diff briefly), then update.
|
|
97
|
+
|
|
98
|
+
### list
|
|
99
|
+
|
|
100
|
+
`mcp__launch-secure__communication_read` filtered by `resourceType=comment`, narrow on `docCategory=features` if the API supports it (otherwise pull a wider set and filter client-side by tag/status). Render one line per brief: `id status title module updated`.
|
|
101
|
+
|
|
102
|
+
### show
|
|
103
|
+
|
|
104
|
+
Fetch via `communication_read` and print the body as-is, no transformation.
|
|
105
|
+
|
|
106
|
+
## Constraints
|
|
107
|
+
|
|
108
|
+
- **Plain markdown body.** Per project memory `feedback_comms_plain_text.md`, comms posts are plain — no HTML, no emojis unless the user wrote them.
|
|
109
|
+
- **One brief, one comment.** Don't fragment a brief across multiple comments — append via `--append` to keep the document continuous.
|
|
110
|
+
- **Cloud LS by default.** Per memory `feedback_post_to_cloud_ls_default.md`. Local LS only when the user explicitly says "local".
|
|
111
|
+
- **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 (project memory: bucket transitions are deliberate, not derived). Surface a hint at the end: "When DECIDED, run `/work-items create epic --from-brief=<id>` to promote."
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Show the currently active LaunchSecure course (server profile) and list the others available in .launch-secure.cred.config. Surfaces which serverUrl/org/project this Claude session is talking to so the user doesn't post local LS comms to prod, or vice versa. Read-only by default; switch is opt-in.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /kit:course
|
|
6
|
+
|
|
7
|
+
A "course" is a named LaunchSecure destination — `serverUrl + PAT + orgSlug + projectSlug` — stored under `profiles` in `.launch-secure.cred.config`. The active course drives every MCP call and every `npx launch-pod` invocation. This skill answers two questions: *which course am I on right now*, and *what others are available* — without changing anything unless explicitly told to.
|
|
8
|
+
|
|
9
|
+
Parse `$ARGUMENTS` — first token is the subcommand:
|
|
10
|
+
|
|
11
|
+
- (empty) or **status** — one-line: which course is active.
|
|
12
|
+
- **list** — table of every course, active marked with `★`.
|
|
13
|
+
- **switch <name>** — change the active course (rewrites `.launch-secure.cred.config` AND `.mcp.json`'s launch-secure URL). Asks for confirmation.
|
|
14
|
+
- **diff** — show the deltas between two courses (`--a=<name> --b=<name>`).
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
- `/kit:course` → "active: prod (acme/launchsecure-v2 @ launchsecure-v2.vercel.app)"
|
|
18
|
+
- `/kit:course list` → table
|
|
19
|
+
- `/kit:course switch local`
|
|
20
|
+
- `/kit:course diff --a=local --b=prod`
|
|
21
|
+
|
|
22
|
+
## Preflight
|
|
23
|
+
|
|
24
|
+
Confirm `.launch-secure.cred.config` exists in the cwd (or in the nearest parent up to 3 levels — `cred-shape.ts`'s lookup convention). If missing, tell the user: `"No .launch-secure.cred.config here. Run \`npx @launchsecure/launch-kit init\` first."`
|
|
25
|
+
|
|
26
|
+
Read the cred file directly (it's gitignored, lives at the repo root, JSON shape with `active` + `profiles`). Never call out to launch-course CLI from inside the skill for read operations — read the file. Use `launch-course` (Bash) only for `switch` (it owns the MCP rewrite invariant).
|
|
27
|
+
|
|
28
|
+
## Per-subcommand behavior
|
|
29
|
+
|
|
30
|
+
### status (default)
|
|
31
|
+
|
|
32
|
+
Read the cred file. Print one line:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
active: <name> (<orgSlug>/<projectSlug> @ <serverUrl>)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If the file is in legacy flat shape (single profile at the top), say so explicitly: `"active: (legacy single-profile shape — no name; first multi-profile op auto-migrates)"`.
|
|
39
|
+
|
|
40
|
+
### list
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
courses (3):
|
|
44
|
+
name serverUrl org/project
|
|
45
|
+
★ prod https://launchsecure-v2.vercel.app acme/launchsecure-v2
|
|
46
|
+
staging https://staging.launchsecure-v2.app acme/launchsecure-v2
|
|
47
|
+
local http://localhost:3000 acme/launchsecure-v2
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Sort: active first, then alphabetical. Column-align with monospace.
|
|
51
|
+
|
|
52
|
+
### switch
|
|
53
|
+
|
|
54
|
+
1. Sanity-check `<name>` exists in `profiles`. If not, list available names and stop.
|
|
55
|
+
2. Print the BEFORE → AFTER one-liner:
|
|
56
|
+
```
|
|
57
|
+
switching: prod (acme/launchsecure-v2 @ launchsecure-v2.vercel.app)
|
|
58
|
+
→ local (acme/launchsecure-v2 @ localhost:3000)
|
|
59
|
+
```
|
|
60
|
+
3. Ask: `"Continue? (yes / no)"` — wait for `yes`. Per project memory, destructive/sticky changes require explicit confirmation.
|
|
61
|
+
4. On `yes`, run `npx launch-course set <name>` via Bash. This rewrites both `.launch-secure.cred.config` (active pointer) AND `.mcp.json` (the launch-secure URL). Surface the CLI output verbatim.
|
|
62
|
+
5. After switch, remind: `"Restart Claude Code to pick up the new MCP URL (or use \`/mcp reload\` if available)."`
|
|
63
|
+
|
|
64
|
+
### diff
|
|
65
|
+
|
|
66
|
+
Resolve `--a` and `--b` from `profiles`. Print a compact diff:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
local → prod
|
|
70
|
+
serverUrl http://localhost:3000 → https://launchsecure-v2.vercel.app
|
|
71
|
+
org acme → acme
|
|
72
|
+
project launchsecure-v2 → launchsecure-v2
|
|
73
|
+
pat sha256:abc1…ef → sha256:def0…12
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
PAT values are hashed (sha256 first 8 of each, last 2 — purely for the user to confirm they differ; never print full PATs). Same row for unchanged values.
|
|
77
|
+
|
|
78
|
+
## Constraints
|
|
79
|
+
|
|
80
|
+
- **Read-only by default.** Only `switch` writes; status/list/diff never mutate.
|
|
81
|
+
- **Switch requires confirmation.** Per project memory, never destructive without `yes`.
|
|
82
|
+
- **No PAT exfiltration.** Never print the full PAT value; show short hashes for diff identification only.
|
|
83
|
+
- **Don't bypass launch-course CLI.** The `switch` MCP-rewrite logic is its responsibility — call the CLI; don't reimplement the .mcp.json mutation inside the skill (drift risk).
|
|
84
|
+
- **Surface the active course on every run.** Even on `list`/`diff`, the first or last line shows which course is active so the user is never confused about session scope.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Investigate a bug, error message, or unexpected behavior using launch-chart first (structural + variable queries), falling back to grep/Read only when the chart can't answer. When the chart gap is the reason for the fallback, files a feedback comment to LaunchSecure so the gap is monitored and fixed.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /kit:debug
|
|
6
|
+
|
|
7
|
+
A guided investigation workflow that defaults to chart-MCP queries and only reaches for grep/Read when the chart can't answer — and when that happens, files a one-line feedback comment in LS so the gap doesn't go unnoticed.
|
|
8
|
+
|
|
9
|
+
Parse `$ARGUMENTS`:
|
|
10
|
+
- **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).
|
|
12
|
+
- **--layer=<id>** — scope chart queries to one layer (ui / api / db / static).
|
|
13
|
+
- **--no-grep-fallback** — refuse the grep fallback entirely (strict MCP-only).
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
- `/kit:debug tags don't render on the work-item drawer`
|
|
17
|
+
- `/kit:debug "TypeError: Cannot read property 'status' of undefined" --layer=ui`
|
|
18
|
+
- `/kit:debug --start=src/server/comms/build-feed.ts`
|
|
19
|
+
|
|
20
|
+
## Investigation loop
|
|
21
|
+
|
|
22
|
+
Run this loop until the user has enough to act, OR until a fallback was filed (then surface the fallback):
|
|
23
|
+
|
|
24
|
+
### Step 1 — locate the entry point
|
|
25
|
+
|
|
26
|
+
If `--start` was given, jump to step 2. Otherwise, use chart to find candidate nodes:
|
|
27
|
+
|
|
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 the response by relevance.
|
|
30
|
+
3. If `read_graph` returns 0 candidates, broaden: try without `type`, then without `layer`. Surface the top 3 candidates to the user as ranked options; if the user can pick, jump to step 2 with their pick.
|
|
31
|
+
|
|
32
|
+
**Chart-gap detection (entry-point search):**
|
|
33
|
+
- If `read_graph` returns 0 candidates AND a quick `grep` confirms the term exists somewhere in source → file a chart-gap report per the protocol below, then proceed via the grep fallback for this query only.
|
|
34
|
+
- If `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
|
+
|
|
36
|
+
### Step 2 — understand the node
|
|
37
|
+
|
|
38
|
+
Once the entry point is known, query its structure and behavior:
|
|
39
|
+
|
|
40
|
+
- **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 what state it holds, what conditions exist. Per project CLAUDE.md, ALWAYS start with `fields` or `filter` to keep the response small.
|
|
42
|
+
|
|
43
|
+
Compose a hypothesis from these two reads. Example: "WorkItemDrawer fetches tags via `useWorkItemTags`, which calls `GET /api/work-items/:id/tags` — let's see what that returns."
|
|
44
|
+
|
|
45
|
+
### Step 3 — follow the trail
|
|
46
|
+
|
|
47
|
+
Walk the dependency edges toward the suspected cause (API endpoint, DB table, util fn, etc.). At each hop, use `read_graph(node_id, hops:1)` to find the next link. When you hit a leaf or run out of edges, narrate the chain back to the user with file:line refs from the node ids.
|
|
48
|
+
|
|
49
|
+
### Step 4 — propose, don't fix
|
|
50
|
+
|
|
51
|
+
End with a one-paragraph diagnosis + 2-3 candidate causes ranked by likelihood. Do NOT propose an edit unless the user asks for one — debug is investigation, not implementation. Suggest the next move: "Want me to read the route handler and confirm?" or "Want `/kit:diagram sequence`-ing the call chain?"
|
|
52
|
+
|
|
53
|
+
## Grep fallback
|
|
54
|
+
|
|
55
|
+
Only enter this path when:
|
|
56
|
+
- the chart returned no results AND a chart-gap report was filed, OR
|
|
57
|
+
- the symptom is about a non-TS asset (CSS string, env var, JSON value, comment) — the chart doesn't model these and the gap is expected.
|
|
58
|
+
|
|
59
|
+
Then use `grep`/`Read` directly. Always tell the user explicitly: `"Chart returned nothing — falling back to grep (filed gap report id: …)"` or `"Symptom is in CSS/JSON, which chart doesn't model — using grep directly (no gap report needed)."`
|
|
60
|
+
|
|
61
|
+
## Chart-gap protocol (shared)
|
|
62
|
+
|
|
63
|
+
When the chart MCP returns less than the symptom suggests it should, file ONE feedback comment in the project's Comm Hub via `mcp__launch-secure__communication_write` (cloud LS by default):
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
resource_type: "feedback"
|
|
67
|
+
title: "launch-chart gap: <one-line>"
|
|
68
|
+
body: |
|
|
69
|
+
Skill: /kit:debug
|
|
70
|
+
Symptom: <one-line symptom>
|
|
71
|
+
Tool: read_graph(search="…", layer="…", type="…")
|
|
72
|
+
Returned: 0 nodes
|
|
73
|
+
Cross-check: grep "<term>" matched <N> files (sample: <path1>, <path2>)
|
|
74
|
+
Project stack: <detect_project_stack one-liner>
|
|
75
|
+
fields:
|
|
76
|
+
severity: "low"
|
|
77
|
+
source: "kit-skill"
|
|
78
|
+
skill: "debug"
|
|
79
|
+
tool: "read_graph"
|
|
80
|
+
args: { search, layer, type }
|
|
81
|
+
response_summary: { nodes_count: 0, grep_hit_count }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Then continue with the grep fallback for THIS query. Don't file again in the same invocation.
|
|
85
|
+
|
|
86
|
+
## Constraints
|
|
87
|
+
|
|
88
|
+
- **Chart-first.** Default to MCP queries; grep only when the chart cannot answer.
|
|
89
|
+
- **One gap report per invocation.** Don't spam comments.
|
|
90
|
+
- **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.
|
|
91
|
+
- **Cite by node id.** Every claim links to a chart node id (file:line via `inspect_node` lines) so the user can verify.
|
|
92
|
+
- **Surface the fallback verbatim.** When grep is used, the message that grep was used (and why) must appear in the output — silent fallback hides the gap.
|