@launchsecure/launch-kit 0.0.1

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.
Files changed (64) hide show
  1. package/README.md +37 -0
  2. package/dist/client/assets/index-C8GAsRGO.css +32 -0
  3. package/dist/client/assets/index-CcHIoRl6.js +286 -0
  4. package/dist/client/index.html +22 -0
  5. package/dist/server/cli.js +8853 -0
  6. package/dist/server/fb-wizard.js +136 -0
  7. package/dist/server/graph-mcp-entry.js +1542 -0
  8. package/dist/server/public/app.js +1312 -0
  9. package/dist/server/public/icons.js +36 -0
  10. package/dist/server/public/index.html +159 -0
  11. package/dist/server/public/plan-detector.js +186 -0
  12. package/dist/server/public/session-manager.js +1129 -0
  13. package/dist/server/public/splits.js +569 -0
  14. package/dist/server/public/style.css +1620 -0
  15. package/package.json +73 -0
  16. package/prompts/analysis.md +992 -0
  17. package/prompts/architect-reconcile.md +931 -0
  18. package/prompts/architecture-sync.md +902 -0
  19. package/prompts/be-contract.md +709 -0
  20. package/prompts/be-impl.md +565 -0
  21. package/prompts/be-policy.md +551 -0
  22. package/prompts/be-test.md +591 -0
  23. package/prompts/bug-diagnosis.md +653 -0
  24. package/prompts/bug-intake.md +563 -0
  25. package/prompts/change-request-intake.md +593 -0
  26. package/prompts/db-contract.md +644 -0
  27. package/prompts/db-impl.md +522 -0
  28. package/prompts/db-interaction.md +569 -0
  29. package/prompts/db-test.md +630 -0
  30. package/prompts/decision-pack.md +654 -0
  31. package/prompts/fe-contract.md +992 -0
  32. package/prompts/fe-flow.md +537 -0
  33. package/prompts/fe-impl.md +597 -0
  34. package/prompts/fe-reconcile.md +506 -0
  35. package/prompts/fe-review.md +550 -0
  36. package/prompts/fe-test.md +705 -0
  37. package/prompts/fix-planner.md +1219 -0
  38. package/prompts/global-db-patterns.md +588 -0
  39. package/prompts/global-env-config.md +460 -0
  40. package/prompts/global-integrations.md +504 -0
  41. package/prompts/global-middleware.md +442 -0
  42. package/prompts/global-navigation.md +502 -0
  43. package/prompts/global-security.md +603 -0
  44. package/prompts/global-services.md +427 -0
  45. package/prompts/greenfield-classifier.md +590 -0
  46. package/prompts/llm-council.md +597 -0
  47. package/prompts/module-sequencer.md +529 -0
  48. package/prompts/normalize.md +611 -0
  49. package/prompts/optimization.md +633 -0
  50. package/prompts/prd-generation.md +544 -0
  51. package/prompts/prd-reconcile.md +584 -0
  52. package/prompts/prd-review.md +504 -0
  53. package/prompts/pre-code-analysis.md +565 -0
  54. package/prompts/pre-code-global-analysis.md +169 -0
  55. package/prompts/production-bootstrap.md +577 -0
  56. package/prompts/research.md +702 -0
  57. package/prompts/retrofit-analysis.md +845 -0
  58. package/prompts/spike.md +850 -0
  59. package/prompts/theming.md +835 -0
  60. package/prompts/triage.md +599 -0
  61. package/prompts/unified-reconcile.md +628 -0
  62. package/prompts/unified-review.md +592 -0
  63. package/prompts/user-stories.md +486 -0
  64. package/prompts/wireframe.md +576 -0
@@ -0,0 +1,36 @@
1
+ // Minimal SVG icon helper. Returns inline SVG strings using currentColor.
2
+ // Usage: window.icons.name(size)
3
+
4
+ (function () {
5
+ const toSvg = (pathOrContent, attrs = {}) => {
6
+ const base = {
7
+ width: attrs.width || 16,
8
+ height: attrs.height || 16,
9
+ viewBox: attrs.viewBox || '0 0 24 24',
10
+ fill: 'none',
11
+ stroke: 'currentColor',
12
+ 'stroke-width': attrs.strokeWidth || 2,
13
+ 'stroke-linecap': 'round',
14
+ 'stroke-linejoin': 'round'
15
+ };
16
+ const attrStr = Object.entries(base)
17
+ .map(([k, v]) => `${k}="${v}"`).join(' ');
18
+ return `<svg ${attrStr}>${pathOrContent}</svg>`;
19
+ };
20
+
21
+ const circle = (cx, cy, r) => `<circle cx="${cx}" cy="${cy}" r="${r}"/>`;
22
+ const line = (x1, y1, x2, y2) => `<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}"/>`;
23
+
24
+ const icons = {
25
+ check: (s = 16) => toSvg('<polyline points="20 6 9 17 4 12"/>', { width: s, height: s }),
26
+ x: (s = 16) => toSvg('<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>', { width: s, height: s }),
27
+ clipboard: (s = 16) => toSvg('<rect x="4" y="3" width="16" height="18" rx="2"/><line x1="8" y1="7" x2="16" y2="7"/>', { width: s, height: s }),
28
+ folder: (s = 16) => toSvg('<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>', { width: s, height: s }),
29
+ download: (s = 16) => toSvg('<path d="M12 3v12"/><path d="M8 11l4 4 4-4"/><path d="M5 21h14"/>', { width: s, height: s }),
30
+ chartLine: (s = 16) => toSvg('<polyline points="3 17 9 11 13 15 21 7"/><line x1="3" y1="17" x2="3" y2="21"/><line x1="21" y1="7" x2="21" y2="11"/>', { width: s, height: s }),
31
+ dot: (s = 10) => toSvg(circle(12, 12, 5), { width: s, height: s, viewBox: '0 0 24 24', strokeWidth: 0 }),
32
+ };
33
+
34
+ window.icons = icons;
35
+ })();
36
+
@@ -0,0 +1,159 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <base href="/terminal/">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Claude Code Web Interface</title>
8
+
9
+ <meta name="description" content="Web interface for Claude Code - Run Claude commands directly from your browser">
10
+ <meta name="theme-color" content="#161b22">
11
+ <meta name="format-detection" content="telephone=no">
12
+
13
+ <!-- Icons for various platforms -->
14
+ <link rel="icon" type="image/png" sizes="32x32" href="/icon-32.png">
15
+ <link rel="icon" type="image/png" sizes="16x16" href="/icon-16.png">
16
+ <link rel="apple-touch-icon" sizes="180x180" href="/icon-180.png">
17
+ <meta name="msapplication-TileColor" content="#161b22">
18
+ <meta name="msapplication-TileImage" content="/icon-144.png">
19
+
20
+ <!-- Apply saved theme early to avoid flash -->
21
+ <script>
22
+ (function() {
23
+ try {
24
+ const s = JSON.parse(localStorage.getItem('launchpod-terminal-settings') || '{}');
25
+ if (s && s.theme === 'light') {
26
+ document.documentElement.setAttribute('data-theme', 'light');
27
+ } else {
28
+ // Dark is default — ensure no 'light' override is set
29
+ document.documentElement.removeAttribute('data-theme');
30
+ }
31
+ } catch (_) { /* ignore */ }
32
+ })();
33
+ </script>
34
+ <link rel="stylesheet" href="style.css">
35
+ <link rel="preconnect" href="https://fonts.googleapis.com">
36
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
37
+ <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
38
+ <script src="https://unpkg.com/xterm@5.3.0/lib/xterm.js"></script>
39
+ <script src="https://unpkg.com/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
40
+ <script src="https://unpkg.com/xterm-addon-web-links@0.9.0/lib/xterm-addon-web-links.js"></script>
41
+ <link rel="stylesheet" href="https://unpkg.com/xterm@5.3.0/css/xterm.css" />
42
+ </head>
43
+ <body>
44
+ <div id="app">
45
+
46
+ <!-- Session Tabs Bar -->
47
+ <div class="session-tabs-bar" id="sessionTabsBar">
48
+ <div class="tabs-section">
49
+ <div class="tabs-container" id="tabsContainer">
50
+ <!-- Tabs will be dynamically added here -->
51
+ </div>
52
+ <button class="tab-new" id="tabNewBtn" title="New Session (Ctrl+T)">
53
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
54
+ <line x1="12" y1="5" x2="12" y2="19"/>
55
+ <line x1="5" y1="12" x2="19" y2="12"/>
56
+ </svg>
57
+ </button>
58
+ </div>
59
+ <!-- Overflow dropdown for mobile - outside tabs-section to prevent scrolling issues -->
60
+ <div class="tab-overflow-wrapper" id="tabOverflowWrapper" style="display: none;">
61
+ <button class="tab-overflow-btn" id="tabOverflowBtn" title="More tabs">
62
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
63
+ <circle cx="12" cy="5" r="1"/>
64
+ <circle cx="12" cy="12" r="1"/>
65
+ <circle cx="12" cy="19" r="1"/>
66
+ </svg>
67
+ <span class="tab-overflow-count">0</span>
68
+ </button>
69
+ <div class="tab-overflow-menu" id="tabOverflowMenu">
70
+ <!-- Overflow tabs will be listed here -->
71
+ </div>
72
+ </div>
73
+ <div class="tab-actions"></div>
74
+ </div>
75
+
76
+
77
+ <div class="mobile-menu" id="mobileMenu">
78
+ <div class="mobile-menu-header">
79
+ <h2><span class="icon" aria-hidden="true"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="4"/><path d="M8 10h.01M16 10h.01M8 16c1.333-1 2.667-1 4 0 1.333 1 2.667 1 4 0"/></svg></span> Claude Code</h2>
80
+ <button class="close-menu-btn" id="closeMenuBtn">&times;</button>
81
+ </div>
82
+ <div class="mobile-menu-content">
83
+ <button id="sessionsBtnMobile" class="mobile-menu-btn">Sessions</button>
84
+ <button id="closeSessionBtnMobile" class="mobile-menu-btn btn-danger" style="display: none;">Close Session</button>
85
+ <button id="reconnectBtnMobile" class="mobile-menu-btn" disabled>Reconnect</button>
86
+ <button id="clearBtnMobile" class="mobile-menu-btn">Clear Terminal</button>
87
+ </div>
88
+ </div>
89
+
90
+ <main class="main">
91
+ <div class="terminal-container" id="terminalContainer" data-view="single">
92
+ <div class="terminal-wrapper">
93
+ <div id="terminal"></div>
94
+ </div>
95
+ </div>
96
+ </main>
97
+
98
+ <!-- Inline plan panel (not a modal) -->
99
+ <div class="plan-inline-panel" id="planInlinePanel" style="display: none;">
100
+ <div class="plan-inline-header">
101
+ <span class="plan-inline-title">
102
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
103
+ <rect x="4" y="3" width="16" height="18" rx="2"/>
104
+ <line x1="8" y1="7" x2="16" y2="7"/>
105
+ </svg>
106
+ Plan Mode Active
107
+ </span>
108
+ <div class="plan-inline-actions">
109
+ <button class="btn btn-success btn-small" id="acceptPlanBtn" title="Accept Plan">Accept</button>
110
+ <button class="btn btn-danger btn-small" id="rejectPlanBtn" title="Reject Plan">Reject</button>
111
+ <button class="plan-inline-toggle" id="planToggleBtn" title="Collapse">
112
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
113
+ <polyline points="18 15 12 9 6 15"/>
114
+ </svg>
115
+ </button>
116
+ </div>
117
+ </div>
118
+ <div class="plan-inline-content" id="planContent">
119
+ <!-- Plan content appears here -->
120
+ </div>
121
+ </div>
122
+
123
+ <!-- Inline error banner -->
124
+ <div class="error-banner" id="errorBanner" style="display: none;">
125
+ <span id="errorBannerText"></span>
126
+ <button class="error-banner-close" id="errorBannerClose">&times;</button>
127
+ </div>
128
+
129
+ <!-- Inline start prompt (shown when session has no running agent) -->
130
+ <div class="start-prompt-panel" id="startPromptPanel" style="display: none;">
131
+ <div class="start-prompt-inner">
132
+ <p class="start-prompt-dir" id="startPromptDir"></p>
133
+ <div class="start-prompt-buttons">
134
+ <button id="startBtn" class="btn btn-primary">Start Claude</button>
135
+ <button id="startCodexBtn" class="btn btn-primary">Start Codex</button>
136
+ <button id="startAgentBtn" class="btn btn-primary">Start Cursor</button>
137
+ </div>
138
+ </div>
139
+ </div>
140
+
141
+ <!-- App-wide overlay (loading only) -->
142
+ <div class="terminal-overlay" id="overlay" style="display: none;">
143
+ <div class="overlay-content">
144
+ <div class="loading-spinner" id="loadingSpinner">
145
+ <div class="spinner"></div>
146
+ <p>Connecting...</p>
147
+ </div>
148
+ </div>
149
+ </div>
150
+
151
+ </div>
152
+
153
+ <script src="plan-detector.js"></script>
154
+ <script src="session-manager.js"></script>
155
+ <script src="splits.js"></script>
156
+ <script src="icons.js"></script>
157
+ <script src="app.js"></script>
158
+ </body>
159
+ </html>
@@ -0,0 +1,186 @@
1
+ class PlanDetector {
2
+ constructor() {
3
+ this.isMonitoring = false;
4
+ this.outputBuffer = [];
5
+ this.planModeActive = false;
6
+ this.currentPlan = null;
7
+ this.planStartMarker = '## Implementation Plan:';
8
+ this.planEndMarker = 'User has approved your plan';
9
+ this.maxBufferSize = 10000;
10
+ this.onPlanDetected = null;
11
+ this.onPlanModeChange = null;
12
+ }
13
+
14
+ processOutput(data) {
15
+ if (!this.isMonitoring) return;
16
+
17
+ // Add to buffer
18
+ this.outputBuffer.push({
19
+ timestamp: Date.now(),
20
+ data: data
21
+ });
22
+
23
+ // Keep buffer size manageable
24
+ if (this.outputBuffer.length > this.maxBufferSize) {
25
+ this.outputBuffer = this.outputBuffer.slice(-this.maxBufferSize / 2);
26
+ }
27
+
28
+ // Convert buffer to text for analysis
29
+ const recentText = this.getRecentText();
30
+
31
+ // Check for plan mode activation
32
+ if (!this.planModeActive && this.detectPlanModeStart(recentText)) {
33
+ this.planModeActive = true;
34
+ if (this.onPlanModeChange) {
35
+ this.onPlanModeChange(true);
36
+ }
37
+ }
38
+
39
+ // Check for completed plan
40
+ if (this.planModeActive && this.detectCompletedPlan(recentText)) {
41
+ const plan = this.extractPlan(recentText);
42
+ if (plan) {
43
+ this.currentPlan = plan;
44
+ if (this.onPlanDetected) {
45
+ this.onPlanDetected(plan);
46
+ }
47
+ }
48
+ }
49
+
50
+ // Check for plan mode exit
51
+ if (this.planModeActive && this.detectPlanModeEnd(recentText)) {
52
+ this.planModeActive = false;
53
+ if (this.onPlanModeChange) {
54
+ this.onPlanModeChange(false);
55
+ }
56
+ }
57
+ }
58
+
59
+ getRecentText(maxChars = 50000) {
60
+ // Get recent output as text, stripping ANSI codes
61
+ const text = this.outputBuffer
62
+ .map(item => item.data)
63
+ .join('')
64
+ .replace(/\x1b\[[0-9;]*m/g, '') // Remove ANSI color codes
65
+ .replace(/\x1b\[[0-9]*[A-Za-z]/g, ''); // Remove other ANSI sequences
66
+
67
+ return text.slice(-maxChars);
68
+ }
69
+
70
+ detectPlanModeStart(text) {
71
+ // Look for plan mode activation indicators
72
+ const indicators = [
73
+ 'Plan mode is active',
74
+ 'you MUST NOT make any edits',
75
+ 'present your plan by calling the ExitPlanMode tool',
76
+ 'Starting plan mode'
77
+ ];
78
+
79
+ return indicators.some(indicator => text.includes(indicator));
80
+ }
81
+
82
+ detectCompletedPlan(text) {
83
+ // Check if a plan has been presented
84
+ const planPatterns = [
85
+ /## Implementation Plan:/,
86
+ /### \d+\. /,
87
+ /## Plan:/,
88
+ /### Plan Overview/,
89
+ /## Proposed Solution:/
90
+ ];
91
+
92
+ // Must have plan content and be recent
93
+ const hasPattern = planPatterns.some(pattern => pattern.test(text));
94
+ const recentText = text.slice(-10000);
95
+
96
+ return hasPattern && recentText.includes('###');
97
+ }
98
+
99
+ extractPlan(text) {
100
+ // Try multiple extraction strategies
101
+ let plan = null;
102
+
103
+ // Strategy 1: Look for ## Implementation Plan: to next terminal prompt
104
+ const implMatch = text.match(/## Implementation Plan:[\s\S]*?(?=(?:User has approved|Exit plan mode|[$>]|^[a-z]+@))/i);
105
+ if (implMatch) {
106
+ plan = implMatch[0];
107
+ }
108
+
109
+ // Strategy 2: Look for structured plan with ### sections
110
+ if (!plan) {
111
+ const structuredMatch = text.match(/##[^#].*?Plan.*?:[\s\S]*?(?:###.*?[\s\S]*?){2,}(?=(?:User has approved|Exit plan mode|[$>]|^[a-z]+@))/i);
112
+ if (structuredMatch) {
113
+ plan = structuredMatch[0];
114
+ }
115
+ }
116
+
117
+ // Strategy 3: Look for recent plan-like content
118
+ if (!plan) {
119
+ const recentText = text.slice(-5000);
120
+ const planMatch = recentText.match(/(?:##|Plan:)[\s\S]*?(?:###[\s\S]*?){1,}/);
121
+ if (planMatch) {
122
+ plan = planMatch[0];
123
+ }
124
+ }
125
+
126
+ if (plan) {
127
+ // Clean up the plan text
128
+ plan = plan
129
+ .replace(/\x1b\[[0-9;]*m/g, '') // Remove ANSI codes
130
+ .replace(/\r\n/g, '\n') // Normalize line endings
131
+ .replace(/\r/g, '\n')
132
+ .trim();
133
+
134
+ return {
135
+ content: plan,
136
+ timestamp: Date.now(),
137
+ raw: plan
138
+ };
139
+ }
140
+
141
+ return null;
142
+ }
143
+
144
+ detectPlanModeEnd(text) {
145
+ const endIndicators = [
146
+ 'User has approved your plan',
147
+ 'You can now start coding',
148
+ 'Plan mode exited',
149
+ 'Exiting plan mode'
150
+ ];
151
+
152
+ return endIndicators.some(indicator => text.includes(indicator));
153
+ }
154
+
155
+ startMonitoring() {
156
+ this.isMonitoring = true;
157
+ this.outputBuffer = [];
158
+ this.planModeActive = false;
159
+ this.currentPlan = null;
160
+ }
161
+
162
+ stopMonitoring() {
163
+ this.isMonitoring = false;
164
+ this.outputBuffer = [];
165
+ this.planModeActive = false;
166
+ this.currentPlan = null;
167
+ }
168
+
169
+ clearBuffer() {
170
+ this.outputBuffer = [];
171
+ this.currentPlan = null;
172
+ }
173
+
174
+ getPlanModeStatus() {
175
+ return this.planModeActive;
176
+ }
177
+
178
+ getCurrentPlan() {
179
+ return this.currentPlan;
180
+ }
181
+ }
182
+
183
+ // Export for use in app.js
184
+ if (typeof module !== 'undefined' && module.exports) {
185
+ module.exports = PlanDetector;
186
+ }