opencastle 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +215 -0
  3. package/bin/cli.mjs +69 -0
  4. package/dist/cli/adapters/claude-code.d.ts +22 -0
  5. package/dist/cli/adapters/claude-code.d.ts.map +1 -0
  6. package/dist/cli/adapters/claude-code.js +237 -0
  7. package/dist/cli/adapters/claude-code.js.map +1 -0
  8. package/dist/cli/adapters/cursor.d.ts +20 -0
  9. package/dist/cli/adapters/cursor.d.ts.map +1 -0
  10. package/dist/cli/adapters/cursor.js +231 -0
  11. package/dist/cli/adapters/cursor.js.map +1 -0
  12. package/dist/cli/adapters/vscode.d.ts +20 -0
  13. package/dist/cli/adapters/vscode.d.ts.map +1 -0
  14. package/dist/cli/adapters/vscode.js +132 -0
  15. package/dist/cli/adapters/vscode.js.map +1 -0
  16. package/dist/cli/copy.d.ts +14 -0
  17. package/dist/cli/copy.d.ts.map +1 -0
  18. package/dist/cli/copy.js +62 -0
  19. package/dist/cli/copy.js.map +1 -0
  20. package/dist/cli/dashboard.d.ts +3 -0
  21. package/dist/cli/dashboard.d.ts.map +1 -0
  22. package/dist/cli/dashboard.js +183 -0
  23. package/dist/cli/dashboard.js.map +1 -0
  24. package/dist/cli/diff.d.ts +3 -0
  25. package/dist/cli/diff.d.ts.map +1 -0
  26. package/dist/cli/diff.js +27 -0
  27. package/dist/cli/diff.js.map +1 -0
  28. package/dist/cli/eject.d.ts +3 -0
  29. package/dist/cli/eject.d.ts.map +1 -0
  30. package/dist/cli/eject.js +27 -0
  31. package/dist/cli/eject.js.map +1 -0
  32. package/dist/cli/init.d.ts +3 -0
  33. package/dist/cli/init.d.ts.map +1 -0
  34. package/dist/cli/init.js +92 -0
  35. package/dist/cli/init.js.map +1 -0
  36. package/dist/cli/manifest.d.ts +14 -0
  37. package/dist/cli/manifest.d.ts.map +1 -0
  38. package/dist/cli/manifest.js +34 -0
  39. package/dist/cli/manifest.js.map +1 -0
  40. package/dist/cli/mcp.d.ts +14 -0
  41. package/dist/cli/mcp.d.ts.map +1 -0
  42. package/dist/cli/mcp.js +35 -0
  43. package/dist/cli/mcp.js.map +1 -0
  44. package/dist/cli/prompt.d.ts +12 -0
  45. package/dist/cli/prompt.d.ts.map +1 -0
  46. package/dist/cli/prompt.js +104 -0
  47. package/dist/cli/prompt.js.map +1 -0
  48. package/dist/cli/run/adapters/claude-code.d.ts +16 -0
  49. package/dist/cli/run/adapters/claude-code.d.ts.map +1 -0
  50. package/dist/cli/run/adapters/claude-code.js +82 -0
  51. package/dist/cli/run/adapters/claude-code.js.map +1 -0
  52. package/dist/cli/run/adapters/copilot.d.ts +16 -0
  53. package/dist/cli/run/adapters/copilot.d.ts.map +1 -0
  54. package/dist/cli/run/adapters/copilot.js +84 -0
  55. package/dist/cli/run/adapters/copilot.js.map +1 -0
  56. package/dist/cli/run/adapters/cursor.d.ts +16 -0
  57. package/dist/cli/run/adapters/cursor.d.ts.map +1 -0
  58. package/dist/cli/run/adapters/cursor.js +81 -0
  59. package/dist/cli/run/adapters/cursor.js.map +1 -0
  60. package/dist/cli/run/adapters/index.d.ts +14 -0
  61. package/dist/cli/run/adapters/index.d.ts.map +1 -0
  62. package/dist/cli/run/adapters/index.js +35 -0
  63. package/dist/cli/run/adapters/index.js.map +1 -0
  64. package/dist/cli/run/executor.d.ts +15 -0
  65. package/dist/cli/run/executor.d.ts.map +1 -0
  66. package/dist/cli/run/executor.js +249 -0
  67. package/dist/cli/run/executor.js.map +1 -0
  68. package/dist/cli/run/reporter.d.ts +10 -0
  69. package/dist/cli/run/reporter.d.ts.map +1 -0
  70. package/dist/cli/run/reporter.js +112 -0
  71. package/dist/cli/run/reporter.js.map +1 -0
  72. package/dist/cli/run/schema.d.ts +28 -0
  73. package/dist/cli/run/schema.d.ts.map +1 -0
  74. package/dist/cli/run/schema.js +511 -0
  75. package/dist/cli/run/schema.js.map +1 -0
  76. package/dist/cli/run.d.ts +6 -0
  77. package/dist/cli/run.d.ts.map +1 -0
  78. package/dist/cli/run.js +123 -0
  79. package/dist/cli/run.js.map +1 -0
  80. package/dist/cli/stack-config.d.ts +12 -0
  81. package/dist/cli/stack-config.d.ts.map +1 -0
  82. package/dist/cli/stack-config.js +146 -0
  83. package/dist/cli/stack-config.js.map +1 -0
  84. package/dist/cli/types.d.ts +169 -0
  85. package/dist/cli/types.d.ts.map +1 -0
  86. package/dist/cli/types.js +2 -0
  87. package/dist/cli/types.js.map +1 -0
  88. package/dist/cli/update.d.ts +3 -0
  89. package/dist/cli/update.d.ts.map +1 -0
  90. package/dist/cli/update.js +50 -0
  91. package/dist/cli/update.js.map +1 -0
  92. package/package.json +48 -0
  93. package/src/cli/adapters/claude-code.ts +287 -0
  94. package/src/cli/adapters/cursor.ts +377 -0
  95. package/src/cli/adapters/vscode.ts +168 -0
  96. package/src/cli/copy.ts +79 -0
  97. package/src/cli/dashboard.ts +225 -0
  98. package/src/cli/diff.ts +44 -0
  99. package/src/cli/eject.ts +39 -0
  100. package/src/cli/init.ts +120 -0
  101. package/src/cli/manifest.ts +45 -0
  102. package/src/cli/mcp.ts +49 -0
  103. package/src/cli/prompt.ts +115 -0
  104. package/src/cli/run/adapters/claude-code.ts +95 -0
  105. package/src/cli/run/adapters/copilot.ts +97 -0
  106. package/src/cli/run/adapters/cursor.ts +94 -0
  107. package/src/cli/run/adapters/index.ts +40 -0
  108. package/src/cli/run/executor.ts +292 -0
  109. package/src/cli/run/reporter.ts +129 -0
  110. package/src/cli/run/schema.ts +595 -0
  111. package/src/cli/run.ts +137 -0
  112. package/src/cli/stack-config.ts +180 -0
  113. package/src/cli/types.ts +207 -0
  114. package/src/cli/update.ts +75 -0
  115. package/src/dashboard/astro.config.mjs +6 -0
  116. package/src/dashboard/package-lock.json +5455 -0
  117. package/src/dashboard/package.json +14 -0
  118. package/src/dashboard/public/data/delegations.ndjson +35 -0
  119. package/src/dashboard/public/data/panels.ndjson +13 -0
  120. package/src/dashboard/public/data/sessions.ndjson +50 -0
  121. package/src/dashboard/public/icon-192.png +0 -0
  122. package/src/dashboard/scripts/generate-seed-data.ts +355 -0
  123. package/src/dashboard/src/layouts/Layout.astro +25 -0
  124. package/src/dashboard/src/pages/index.astro +1070 -0
  125. package/src/dashboard/src/styles/dashboard.css +1078 -0
  126. package/src/dashboard/tsconfig.json +6 -0
  127. package/src/orchestrator/agent-workflows/README.md +22 -0
  128. package/src/orchestrator/agent-workflows/bug-fix.md +128 -0
  129. package/src/orchestrator/agent-workflows/data-pipeline.md +145 -0
  130. package/src/orchestrator/agent-workflows/database-migration.md +159 -0
  131. package/src/orchestrator/agent-workflows/feature-implementation.md +223 -0
  132. package/src/orchestrator/agent-workflows/performance-optimization.md +125 -0
  133. package/src/orchestrator/agent-workflows/refactoring.md +142 -0
  134. package/src/orchestrator/agent-workflows/schema-changes.md +164 -0
  135. package/src/orchestrator/agent-workflows/security-audit.md +148 -0
  136. package/src/orchestrator/agent-workflows/shared-delivery-phase.md +33 -0
  137. package/src/orchestrator/agents/api-designer.agent.md +68 -0
  138. package/src/orchestrator/agents/architect.agent.md +129 -0
  139. package/src/orchestrator/agents/content-engineer.agent.md +57 -0
  140. package/src/orchestrator/agents/copywriter.agent.md +95 -0
  141. package/src/orchestrator/agents/data-expert.agent.md +63 -0
  142. package/src/orchestrator/agents/database-engineer.agent.md +62 -0
  143. package/src/orchestrator/agents/developer.agent.md +66 -0
  144. package/src/orchestrator/agents/devops-expert.agent.md +57 -0
  145. package/src/orchestrator/agents/documentation-writer.agent.md +60 -0
  146. package/src/orchestrator/agents/performance-expert.agent.md +58 -0
  147. package/src/orchestrator/agents/release-manager.agent.md +72 -0
  148. package/src/orchestrator/agents/researcher.agent.md +145 -0
  149. package/src/orchestrator/agents/reviewer.agent.md +62 -0
  150. package/src/orchestrator/agents/security-expert.agent.md +64 -0
  151. package/src/orchestrator/agents/seo-specialist.agent.md +67 -0
  152. package/src/orchestrator/agents/team-lead.agent.md +644 -0
  153. package/src/orchestrator/agents/testing-expert.agent.md +85 -0
  154. package/src/orchestrator/agents/ui-ux-expert.agent.md +63 -0
  155. package/src/orchestrator/copilot-instructions.md +3 -0
  156. package/src/orchestrator/customizations/AGENT-EXPERTISE.md +325 -0
  157. package/src/orchestrator/customizations/AGENT-FAILURES.md +69 -0
  158. package/src/orchestrator/customizations/AGENT-PERFORMANCE.md +58 -0
  159. package/src/orchestrator/customizations/DISPUTES.md +162 -0
  160. package/src/orchestrator/customizations/KNOWLEDGE-GRAPH.md +10 -0
  161. package/src/orchestrator/customizations/LESSONS-LEARNED.md +70 -0
  162. package/src/orchestrator/customizations/README.md +59 -0
  163. package/src/orchestrator/customizations/agents/agent-registry.md +46 -0
  164. package/src/orchestrator/customizations/agents/skill-matrix.md +142 -0
  165. package/src/orchestrator/customizations/logs/README.md +181 -0
  166. package/src/orchestrator/customizations/logs/delegations.ndjson +1 -0
  167. package/src/orchestrator/customizations/logs/panels.ndjson +1 -0
  168. package/src/orchestrator/customizations/logs/sessions.ndjson +1 -0
  169. package/src/orchestrator/customizations/project/docs-structure.md +23 -0
  170. package/src/orchestrator/customizations/project/tracker-config.md +45 -0
  171. package/src/orchestrator/customizations/project.instructions.md +64 -0
  172. package/src/orchestrator/customizations/stack/api-config.md +37 -0
  173. package/src/orchestrator/customizations/stack/cms-config.md +26 -0
  174. package/src/orchestrator/customizations/stack/data-pipeline-config.md +41 -0
  175. package/src/orchestrator/customizations/stack/database-config.md +44 -0
  176. package/src/orchestrator/customizations/stack/deployment-config.md +45 -0
  177. package/src/orchestrator/customizations/stack/testing-config.md +56 -0
  178. package/src/orchestrator/instructions/ai-optimization.instructions.md +143 -0
  179. package/src/orchestrator/instructions/general.instructions.md +194 -0
  180. package/src/orchestrator/mcp.json +55 -0
  181. package/src/orchestrator/prompts/bootstrap-customizations.prompt.md +235 -0
  182. package/src/orchestrator/prompts/brainstorm.prompt.md +115 -0
  183. package/src/orchestrator/prompts/bug-fix.prompt.md +141 -0
  184. package/src/orchestrator/prompts/create-skill.prompt.md +103 -0
  185. package/src/orchestrator/prompts/generate-task-spec.prompt.md +154 -0
  186. package/src/orchestrator/prompts/implement-feature.prompt.md +124 -0
  187. package/src/orchestrator/prompts/metrics-report.prompt.md +142 -0
  188. package/src/orchestrator/prompts/quick-refinement.prompt.md +137 -0
  189. package/src/orchestrator/prompts/resolve-pr-comments.prompt.md +100 -0
  190. package/src/orchestrator/skills/accessibility-standards/SKILL.md +164 -0
  191. package/src/orchestrator/skills/agent-hooks/SKILL.md +147 -0
  192. package/src/orchestrator/skills/agent-memory/SKILL.md +144 -0
  193. package/src/orchestrator/skills/api-patterns/SKILL.md +106 -0
  194. package/src/orchestrator/skills/browser-testing/SKILL.md +203 -0
  195. package/src/orchestrator/skills/code-commenting/SKILL.md +133 -0
  196. package/src/orchestrator/skills/contentful-cms/SKILL.md +43 -0
  197. package/src/orchestrator/skills/context-map/SKILL.md +135 -0
  198. package/src/orchestrator/skills/convex-database/SKILL.md +80 -0
  199. package/src/orchestrator/skills/data-engineering/SKILL.md +99 -0
  200. package/src/orchestrator/skills/deployment-infrastructure/SKILL.md +49 -0
  201. package/src/orchestrator/skills/documentation-standards/SKILL.md +85 -0
  202. package/src/orchestrator/skills/fast-review/SKILL.md +327 -0
  203. package/src/orchestrator/skills/frontend-design/SKILL.md +42 -0
  204. package/src/orchestrator/skills/jira-management/SKILL.md +168 -0
  205. package/src/orchestrator/skills/memory-merger/SKILL.md +123 -0
  206. package/src/orchestrator/skills/nextjs-patterns/SKILL.md +75 -0
  207. package/src/orchestrator/skills/nx-workspace/SKILL.md +192 -0
  208. package/src/orchestrator/skills/panel-majority-vote/SKILL.md +184 -0
  209. package/src/orchestrator/skills/panel-majority-vote/panel-report.template.md +38 -0
  210. package/src/orchestrator/skills/performance-optimization/SKILL.md +101 -0
  211. package/src/orchestrator/skills/react-development/SKILL.md +117 -0
  212. package/src/orchestrator/skills/sanity-cms/SKILL.md +18 -0
  213. package/src/orchestrator/skills/security-hardening/SKILL.md +118 -0
  214. package/src/orchestrator/skills/self-improvement/SKILL.md +137 -0
  215. package/src/orchestrator/skills/seo-patterns/SKILL.md +40 -0
  216. package/src/orchestrator/skills/session-checkpoints/SKILL.md +205 -0
  217. package/src/orchestrator/skills/slack-notifications/SKILL.md +211 -0
  218. package/src/orchestrator/skills/strapi-cms/SKILL.md +43 -0
  219. package/src/orchestrator/skills/supabase-database/SKILL.md +24 -0
  220. package/src/orchestrator/skills/task-management/SKILL.md +143 -0
  221. package/src/orchestrator/skills/team-lead-reference/SKILL.md +317 -0
  222. package/src/orchestrator/skills/teams-notifications/SKILL.md +249 -0
  223. package/src/orchestrator/skills/testing-workflow/SKILL.md +134 -0
  224. package/src/orchestrator/skills/validation-gates/SKILL.md +100 -0
@@ -0,0 +1,183 @@
1
+ import { createServer } from 'node:http';
2
+ import { readFile, access } from 'node:fs/promises';
3
+ import { resolve, join, extname } from 'node:path';
4
+ import { exec } from 'node:child_process';
5
+ const MIME_TYPES = {
6
+ '.html': 'text/html',
7
+ '.css': 'text/css',
8
+ '.js': 'application/javascript',
9
+ '.json': 'application/json',
10
+ '.ndjson': 'application/x-ndjson',
11
+ '.png': 'image/png',
12
+ '.svg': 'image/svg+xml',
13
+ '.ico': 'image/x-icon',
14
+ '.woff': 'font/woff',
15
+ '.woff2': 'font/woff2',
16
+ };
17
+ const DATA_FILES = [
18
+ 'sessions.ndjson',
19
+ 'delegations.ndjson',
20
+ 'panels.ndjson',
21
+ ];
22
+ function parseArgs(args) {
23
+ let port = 4300;
24
+ let openBrowser = true;
25
+ let seed = false;
26
+ for (let i = 0; i < args.length; i++) {
27
+ if (args[i] === '--port' && args[i + 1]) {
28
+ port = parseInt(args[i + 1], 10);
29
+ i++;
30
+ }
31
+ else if (args[i] === '--no-open') {
32
+ openBrowser = false;
33
+ }
34
+ else if (args[i] === '--seed') {
35
+ seed = true;
36
+ }
37
+ }
38
+ return { port, openBrowser, seed };
39
+ }
40
+ function openUrl(url) {
41
+ const plat = process.platform;
42
+ const cmd = plat === 'darwin'
43
+ ? 'open'
44
+ : plat === 'win32'
45
+ ? 'start'
46
+ : 'xdg-open';
47
+ exec(`${cmd} ${url}`);
48
+ }
49
+ async function fileExists(filePath) {
50
+ try {
51
+ await access(filePath);
52
+ return true;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
58
+ function tryListen(server, port, maxAttempts = 10) {
59
+ return new Promise((res, rej) => {
60
+ let attempt = 0;
61
+ function attemptListen() {
62
+ server.listen(port + attempt, '127.0.0.1', () => {
63
+ res(port + attempt);
64
+ });
65
+ server.once('error', (err) => {
66
+ if (err.code === 'EADDRINUSE' && attempt < maxAttempts) {
67
+ attempt++;
68
+ attemptListen();
69
+ }
70
+ else {
71
+ rej(err);
72
+ }
73
+ });
74
+ }
75
+ attemptListen();
76
+ });
77
+ }
78
+ export default async function dashboard({ pkgRoot, args, }) {
79
+ const { port, openBrowser, seed } = parseArgs(args);
80
+ const distDir = resolve(pkgRoot, 'src', 'dashboard', 'dist');
81
+ const projectRoot = process.cwd();
82
+ const logsDir = resolve(projectRoot, '.github', 'customizations', 'logs');
83
+ // Check if dist exists
84
+ if (!(await fileExists(distDir))) {
85
+ throw new Error('Dashboard not built. Run "npm run build:dashboard" in the opencastle package first.');
86
+ }
87
+ // Check if any log files exist (for messaging)
88
+ let hasLogs = false;
89
+ if (!seed) {
90
+ for (const f of DATA_FILES) {
91
+ if (await fileExists(join(logsDir, f))) {
92
+ hasLogs = true;
93
+ break;
94
+ }
95
+ }
96
+ }
97
+ const server = createServer(async (req, res) => {
98
+ try {
99
+ const url = new URL(req.url ?? '/', `http://${req.headers.host}`);
100
+ let pathname = decodeURIComponent(url.pathname);
101
+ // Serve index.html for root
102
+ if (pathname === '/') {
103
+ pathname = '/index.html';
104
+ }
105
+ // Handle data file requests — proxy to project logs or dist
106
+ const dataMatch = pathname.match(/^\/data\/(.+\.ndjson)$/);
107
+ if (dataMatch && DATA_FILES.includes(dataMatch[1])) {
108
+ const filename = dataMatch[1];
109
+ let filePath;
110
+ if (seed) {
111
+ filePath = join(distDir, 'data', filename);
112
+ }
113
+ else {
114
+ filePath = join(logsDir, filename);
115
+ }
116
+ if (await fileExists(filePath)) {
117
+ const content = await readFile(filePath);
118
+ res.writeHead(200, { 'Content-Type': 'application/x-ndjson' });
119
+ res.end(content);
120
+ }
121
+ else {
122
+ // Graceful fallback — empty body
123
+ res.writeHead(200, { 'Content-Type': 'application/x-ndjson' });
124
+ res.end('');
125
+ }
126
+ return;
127
+ }
128
+ // Serve static files from dist/
129
+ const filePath = resolve(distDir, pathname.slice(1));
130
+ // Security: prevent path traversal
131
+ if (!filePath.startsWith(distDir)) {
132
+ res.writeHead(403);
133
+ res.end('Forbidden');
134
+ return;
135
+ }
136
+ if (await fileExists(filePath)) {
137
+ const ext = extname(filePath);
138
+ const contentType = MIME_TYPES[ext] ?? 'application/octet-stream';
139
+ const content = await readFile(filePath);
140
+ res.writeHead(200, { 'Content-Type': contentType });
141
+ res.end(content);
142
+ }
143
+ else {
144
+ res.writeHead(404);
145
+ res.end('Not Found');
146
+ }
147
+ }
148
+ catch {
149
+ res.writeHead(500);
150
+ res.end('Internal Server Error');
151
+ }
152
+ });
153
+ const actualPort = await tryListen(server, port);
154
+ const url = `http://localhost:${actualPort}`;
155
+ console.log('');
156
+ console.log(' \u{1F3F0} OpenCastle Dashboard');
157
+ console.log('');
158
+ console.log(` \u2192 ${url}`);
159
+ if (seed) {
160
+ console.log(' \u{1F4C2} Showing demo data (use without --seed to read project logs)');
161
+ }
162
+ else if (hasLogs) {
163
+ console.log(' \u{1F4C2} Reading logs from .github/customizations/logs/');
164
+ }
165
+ else {
166
+ console.log(' \u{1F4A1} No agent logs found. Run agents with OpenCastle to generate data, or use --seed for demo data.');
167
+ }
168
+ console.log('');
169
+ console.log(' Press Ctrl+C to stop');
170
+ console.log('');
171
+ if (openBrowser) {
172
+ openUrl(url);
173
+ }
174
+ // Graceful shutdown
175
+ process.on('SIGINT', () => {
176
+ console.log('\n Dashboard stopped.\n');
177
+ server.close();
178
+ process.exit(0);
179
+ });
180
+ // Keep the process alive
181
+ await new Promise(() => { });
182
+ }
183
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/cli/dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CliContext } from './types.js';
2
+ export default function diff({ pkgRoot }: CliContext): Promise<void>;
3
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/cli/diff.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,wBAA8B,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCzE"}
@@ -0,0 +1,27 @@
1
+ import { resolve } from 'node:path';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { readManifest } from './manifest.js';
4
+ export default async function diff({ pkgRoot }) {
5
+ const projectRoot = process.cwd();
6
+ const manifest = await readManifest(projectRoot);
7
+ if (!manifest) {
8
+ console.error(' ✗ No OpenCastle installation found. Run "npx opencastle init" first.');
9
+ process.exit(1);
10
+ }
11
+ const pkg = JSON.parse(await readFile(resolve(pkgRoot, 'package.json'), 'utf8'));
12
+ if (manifest.version === pkg.version) {
13
+ console.log(` No changes — installed version matches package version (v${pkg.version}).`);
14
+ return;
15
+ }
16
+ console.log(`\n 🏰 OpenCastle diff: v${manifest.version} → v${pkg.version}\n`);
17
+ console.log(' Framework files that would be updated:\n');
18
+ for (const path of manifest.managedPaths?.framework ?? []) {
19
+ console.log(` ↻ ${path}`);
20
+ }
21
+ console.log('\n Customization files that would be preserved:\n');
22
+ for (const path of manifest.managedPaths?.customizable ?? []) {
23
+ console.log(` ✓ ${path}`);
24
+ }
25
+ console.log(`\n Run "npx opencastle update" to apply.\n`);
26
+ }
27
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/cli/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAG5C,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,IAAI,CAAC,EAAE,OAAO,EAAc;IACxD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IAEjC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,CAAA;IAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CACX,wEAAwE,CACzE,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAClC,CAAA;IAExB,IAAI,QAAQ,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CACT,8DAA8D,GAAG,CAAC,OAAO,IAAI,CAC9E,CAAA;QACD,OAAM;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CACT,4BAA4B,QAAQ,CAAC,OAAO,OAAO,GAAG,CAAC,OAAO,IAAI,CACnE,CAAA;IACD,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAA;IAEzD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,YAAY,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAA;IAEjE,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,YAAY,EAAE,YAAY,IAAI,EAAE,EAAE,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAA;AAC5D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CliContext } from './types.js';
2
+ export default function eject({ pkgRoot: _pkgRoot, args: _args, }: CliContext): Promise<void>;
3
+ //# sourceMappingURL=eject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eject.d.ts","sourceRoot":"","sources":["../../src/cli/eject.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,wBAA8B,KAAK,CAAC,EAClC,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,KAAK,GACZ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B5B"}
@@ -0,0 +1,27 @@
1
+ import { resolve } from 'node:path';
2
+ import { unlink } from 'node:fs/promises';
3
+ import { readManifest } from './manifest.js';
4
+ import { confirm, closePrompts } from './prompt.js';
5
+ export default async function eject({ pkgRoot: _pkgRoot, args: _args, }) {
6
+ const projectRoot = process.cwd();
7
+ const manifest = await readManifest(projectRoot);
8
+ if (!manifest) {
9
+ console.error(' ✗ No OpenCastle installation found.');
10
+ process.exit(1);
11
+ }
12
+ console.log(`\n 🏰 OpenCastle eject\n`);
13
+ console.log(' This will:');
14
+ console.log(' • Remove .opencastle.json (manifest)');
15
+ console.log(' • Keep ALL generated files as standalone');
16
+ console.log(' • You can safely uninstall the opencastle package after this\n');
17
+ const proceed = await confirm('Continue?');
18
+ if (!proceed) {
19
+ console.log(' Aborted.');
20
+ return;
21
+ }
22
+ await unlink(resolve(projectRoot, '.opencastle.json'));
23
+ console.log('\n ✓ Ejected. Files are now standalone.');
24
+ console.log(' You can uninstall: npm uninstall opencastle\n');
25
+ closePrompts();
26
+ }
27
+ //# sourceMappingURL=eject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eject.js","sourceRoot":"","sources":["../../src/cli/eject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGnD,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,KAAK,CAAC,EAClC,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,KAAK,GACA;IACX,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IAEjC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,CAAA;IAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAA;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;IACxC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAC3B,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAA;IACvD,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAA;IAC3D,OAAO,CAAC,GAAG,CACT,oEAAoE,CACrE,CAAA;IAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAA;IAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QACzB,OAAM;IACR,CAAC;IAED,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAA;IAEtD,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAA;IACvD,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAA;IAE9D,YAAY,EAAE,CAAA;AAChB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CliContext } from './types.js';
2
+ export default function init({ pkgRoot }: CliContext): Promise<void>;
3
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAuE,MAAM,YAAY,CAAA;AASjH,wBAA8B,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA0GzE"}
@@ -0,0 +1,92 @@
1
+ import { resolve } from 'node:path';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { select, confirm, closePrompts } from './prompt.js';
4
+ import { readManifest, writeManifest, createManifest } from './manifest.js';
5
+ const ADAPTERS = {
6
+ vscode: () => import('./adapters/vscode.js'),
7
+ cursor: () => import('./adapters/cursor.js'),
8
+ 'claude-code': () => import('./adapters/claude-code.js'),
9
+ };
10
+ export default async function init({ pkgRoot }) {
11
+ const projectRoot = process.cwd();
12
+ // Check for existing installation
13
+ const existing = await readManifest(projectRoot);
14
+ if (existing) {
15
+ const proceed = await confirm(`OpenCastle already installed (v${existing.version}, ${existing.ide}). Re-initialize?`, false);
16
+ if (!proceed) {
17
+ console.log(' Aborted.');
18
+ return;
19
+ }
20
+ }
21
+ const pkg = JSON.parse(await readFile(resolve(pkgRoot, 'package.json'), 'utf8'));
22
+ console.log(`\n 🏰 OpenCastle v${pkg.version}`);
23
+ console.log(' Multi-agent orchestration framework for AI coding assistants\n');
24
+ // ── IDE selection ───────────────────────────────────────────────
25
+ const ide = await select('Which IDE are you using?', [
26
+ {
27
+ label: 'VS Code',
28
+ hint: 'GitHub Copilot — .github/ agents, instructions, skills',
29
+ value: 'vscode',
30
+ },
31
+ {
32
+ label: 'Cursor',
33
+ hint: '.cursorrules & .cursor/rules/*.mdc',
34
+ value: 'cursor',
35
+ },
36
+ {
37
+ label: 'Claude Code',
38
+ hint: 'CLAUDE.md & .claude/ commands, skills',
39
+ value: 'claude-code',
40
+ },
41
+ ]);
42
+ // ── CMS selection ───────────────────────────────────────────────
43
+ const cms = await select('Which CMS are you using?', [
44
+ { label: 'Sanity', hint: 'GROQ queries, real-time collaboration', value: 'sanity' },
45
+ { label: 'Contentful', hint: 'GraphQL / REST API, structured content', value: 'contentful' },
46
+ { label: 'Strapi', hint: 'Open-source headless CMS', value: 'strapi' },
47
+ { label: 'None', hint: 'No CMS — skip CMS skills and agents', value: 'none' },
48
+ ]);
49
+ // ── Database selection ──────────────────────────────────────────
50
+ const db = await select('Which database are you using?', [
51
+ { label: 'Supabase', hint: 'Postgres + Auth + RLS + Edge Functions', value: 'supabase' },
52
+ { label: 'Convex', hint: 'Reactive backend with real-time sync', value: 'convex' },
53
+ { label: 'None', hint: 'No database — skip DB skills and agents', value: 'none' },
54
+ ]);
55
+ // ── Project management selection ────────────────────────────────
56
+ const pm = await select('Which project management tool are you using?', [
57
+ { label: 'Linear', hint: 'Issue tracking with MCP integration', value: 'linear' },
58
+ { label: 'Jira', hint: 'Atlassian issue tracking via Rovo MCP', value: 'jira' },
59
+ { label: 'None', hint: 'No project management — skip PM skills', value: 'none' },
60
+ ]);
61
+ // ── Notifications selection ────────────────────────────────────
62
+ const notifications = await select('Which notifications tool are you using?', [
63
+ { label: 'Slack', hint: 'Agent notifications and bi-directional communication', value: 'slack' },
64
+ { label: 'Microsoft Teams', hint: 'Agent notifications via Teams channels', value: 'teams' },
65
+ { label: 'None', hint: 'No notifications — skip messaging skills', value: 'none' },
66
+ ]);
67
+ const stack = { cms: cms, db: db, pm: pm, notifications: notifications };
68
+ console.log(`\n Installing for ${ide}...`);
69
+ console.log(` Stack: CMS=${stack.cms}, DB=${stack.db}, PM=${stack.pm}, Notifications=${stack.notifications}\n`);
70
+ // ── Run adapter ─────────────────────────────────────────────────
71
+ const adapter = await ADAPTERS[ide]();
72
+ const results = await adapter.install(pkgRoot, projectRoot, stack);
73
+ // ── Write manifest ──────────────────────────────────────────────
74
+ const manifest = createManifest(pkg.version, ide);
75
+ manifest.managedPaths = adapter.getManagedPaths();
76
+ manifest.stack = stack;
77
+ await writeManifest(projectRoot, manifest);
78
+ // ── Summary ─────────────────────────────────────────────────────
79
+ const created = results.created.length;
80
+ const skipped = results.skipped.length;
81
+ console.log(` ✓ Created ${created} files`);
82
+ if (skipped > 0) {
83
+ console.log(` → Skipped ${skipped} existing files`);
84
+ }
85
+ console.log(`\n Next steps:`);
86
+ console.log(' 1. Run the "Bootstrap Customizations" prompt to configure for your project');
87
+ console.log(' 2. Customize agent definitions for your tech stack');
88
+ console.log(' 3. Commit the generated files to your repository');
89
+ console.log();
90
+ closePrompts();
91
+ }
92
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Manifest } from './types.js';
2
+ /**
3
+ * Read the project's OpenCastle manifest, or null if not installed.
4
+ */
5
+ export declare function readManifest(projectRoot: string): Promise<Manifest | null>;
6
+ /**
7
+ * Write the manifest to the project root.
8
+ */
9
+ export declare function writeManifest(projectRoot: string, manifest: Manifest): Promise<void>;
10
+ /**
11
+ * Create a fresh manifest object.
12
+ */
13
+ export declare function createManifest(version: string, ide: string): Manifest;
14
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/cli/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C;;GAEG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAU1B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAOrE"}
@@ -0,0 +1,34 @@
1
+ import { readFile, writeFile } from 'node:fs/promises';
2
+ import { resolve } from 'node:path';
3
+ const MANIFEST_FILE = '.opencastle.json';
4
+ /**
5
+ * Read the project's OpenCastle manifest, or null if not installed.
6
+ */
7
+ export async function readManifest(projectRoot) {
8
+ try {
9
+ const content = await readFile(resolve(projectRoot, MANIFEST_FILE), 'utf8');
10
+ return JSON.parse(content);
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ }
16
+ /**
17
+ * Write the manifest to the project root.
18
+ */
19
+ export async function writeManifest(projectRoot, manifest) {
20
+ const path = resolve(projectRoot, MANIFEST_FILE);
21
+ await writeFile(path, JSON.stringify(manifest, null, 2) + '\n');
22
+ }
23
+ /**
24
+ * Create a fresh manifest object.
25
+ */
26
+ export function createManifest(version, ide) {
27
+ return {
28
+ version,
29
+ ide,
30
+ installedAt: new Date().toISOString(),
31
+ updatedAt: new Date().toISOString(),
32
+ };
33
+ }
34
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/cli/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,aAAa,GAAG,kBAAkB,CAAC;AAEzC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAC5B,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC,EACnC,MAAM,CACP,CAAC;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAa,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,WAAmB,EACnB,QAAkB;IAElB,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IACjD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAClE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,GAAW;IACzD,OAAO;QACL,OAAO;QACP,GAAG;QACH,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { ScaffoldResult, StackConfig } from './types.js';
2
+ /**
3
+ * Scaffold the MCP server config into the target project.
4
+ *
5
+ * Reads the template from `opencastle/src/orchestrator/mcp.json`,
6
+ * writes it to `<projectRoot>/<destRelPath>` (e.g. `.vscode/mcp.json`).
7
+ *
8
+ * When a StackConfig is provided, only servers relevant to the chosen
9
+ * CMS/DB stack (plus core servers) are included.
10
+ *
11
+ * This is a customizable file — scaffolded once, never overwritten on update.
12
+ */
13
+ export declare function scaffoldMcpConfig(pkgRoot: string, projectRoot: string, destRelPath: string, stack?: StackConfig): Promise<ScaffoldResult>;
14
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/cli/mcp.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9D;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,cAAc,CAAC,CAyBzB"}
@@ -0,0 +1,35 @@
1
+ import { resolve, dirname } from 'node:path';
2
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
3
+ import { existsSync } from 'node:fs';
4
+ import { getOrchestratorRoot } from './copy.js';
5
+ import { getIncludedMcpServers } from './stack-config.js';
6
+ /**
7
+ * Scaffold the MCP server config into the target project.
8
+ *
9
+ * Reads the template from `opencastle/src/orchestrator/mcp.json`,
10
+ * writes it to `<projectRoot>/<destRelPath>` (e.g. `.vscode/mcp.json`).
11
+ *
12
+ * When a StackConfig is provided, only servers relevant to the chosen
13
+ * CMS/DB stack (plus core servers) are included.
14
+ *
15
+ * This is a customizable file — scaffolded once, never overwritten on update.
16
+ */
17
+ export async function scaffoldMcpConfig(pkgRoot, projectRoot, destRelPath, stack) {
18
+ const destPath = resolve(projectRoot, destRelPath);
19
+ if (existsSync(destPath)) {
20
+ return { path: destPath, action: 'skipped' };
21
+ }
22
+ const srcRoot = getOrchestratorRoot(pkgRoot);
23
+ const templatePath = resolve(srcRoot, 'mcp.json');
24
+ const content = await readFile(templatePath, 'utf8');
25
+ const template = JSON.parse(content);
26
+ // Filter servers based on stack config
27
+ if (stack) {
28
+ const included = getIncludedMcpServers(stack);
29
+ template.servers = Object.fromEntries(Object.entries(template.servers).filter(([key]) => included.has(key)));
30
+ }
31
+ await mkdir(dirname(destPath), { recursive: true });
32
+ await writeFile(destPath, JSON.stringify(template, null, 2) + '\n');
33
+ return { path: destPath, action: 'created' };
34
+ }
35
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/cli/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG1D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAe,EACf,WAAmB,EACnB,WAAmB,EACnB,KAAmB;IAEnB,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAEnD,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAyC,CAAC;IAE7E,uCAAuC;IACvC,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC9C,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC,WAAW,CACnC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CACtE,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEpE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { SelectOption } from './types.js';
2
+ /** Close the shared readline interface. Call once at command end. */
3
+ export declare function closePrompts(): void;
4
+ /**
5
+ * Interactive single-choice selection prompt.
6
+ */
7
+ export declare function select(message: string, options: SelectOption[]): Promise<string>;
8
+ /**
9
+ * Yes/No confirmation prompt.
10
+ */
11
+ export declare function confirm(message: string, defaultYes?: boolean): Promise<boolean>;
12
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA0D/C,qEAAqE;AACrE,wBAAgB,YAAY,IAAI,IAAI,CAOnC;AAED;;GAEG;AACH,wBAAsB,MAAM,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,EAAE,GACtB,OAAO,CAAC,MAAM,CAAC,CAwBjB;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,MAAM,EACf,UAAU,UAAO,GAChB,OAAO,CAAC,OAAO,CAAC,CAMlB"}
@@ -0,0 +1,104 @@
1
+ import { createInterface } from 'node:readline/promises';
2
+ import { stdin, stdout } from 'node:process';
3
+ // ── Line-buffered readline ────────────────────────────────────────
4
+ // readline.question() drops lines that arrived between calls because
5
+ // it only listens for the NEXT 'line' event. When piped input
6
+ // delivers multiple lines in one chunk (e.g. `printf 'y\n3\n' | …`),
7
+ // the second line fires before the second question() is registered.
8
+ //
9
+ // We solve this with a permanent 'line' listener that pushes into a
10
+ // queue. nextLine() either pops from the queue or awaits the next
11
+ // event — no data is ever lost.
12
+ let _rl = null;
13
+ const _lineBuffer = [];
14
+ let _lineResolver = null;
15
+ function ensureRL() {
16
+ if (_rl)
17
+ return;
18
+ _rl = createInterface({ input: stdin, output: stdout });
19
+ _rl.on('line', (line) => {
20
+ if (_lineResolver) {
21
+ const resolve = _lineResolver;
22
+ _lineResolver = null;
23
+ resolve(line);
24
+ }
25
+ else {
26
+ _lineBuffer.push(line);
27
+ }
28
+ });
29
+ _rl.on('close', () => {
30
+ _rl = null;
31
+ // Resolve any pending prompt with empty string → triggers defaults
32
+ if (_lineResolver) {
33
+ const resolve = _lineResolver;
34
+ _lineResolver = null;
35
+ resolve('');
36
+ }
37
+ });
38
+ }
39
+ /**
40
+ * Read the next line from stdin, displaying a prompt first.
41
+ * Consumes from the internal buffer when piped input delivered
42
+ * multiple lines in a single chunk.
43
+ */
44
+ async function nextLine(prompt) {
45
+ ensureRL();
46
+ stdout.write(prompt);
47
+ if (_lineBuffer.length > 0) {
48
+ const line = _lineBuffer.shift();
49
+ // Echo the buffered answer for non-TTY so logs read naturally
50
+ if (!stdin.isTTY)
51
+ stdout.write(line + '\n');
52
+ return line;
53
+ }
54
+ return new Promise((resolve) => {
55
+ _lineResolver = resolve;
56
+ });
57
+ }
58
+ /** Close the shared readline interface. Call once at command end. */
59
+ export function closePrompts() {
60
+ if (_rl) {
61
+ _rl.close();
62
+ _rl = null;
63
+ _lineBuffer.length = 0;
64
+ _lineResolver = null;
65
+ }
66
+ }
67
+ /**
68
+ * Interactive single-choice selection prompt.
69
+ */
70
+ export async function select(message, options) {
71
+ console.log(`\n ${message}\n`);
72
+ options.forEach((opt, i) => {
73
+ const hint = opt.hint ? ` — ${opt.hint}` : '';
74
+ console.log(` ${i + 1}) ${opt.label}${hint}`);
75
+ });
76
+ let choice;
77
+ while (!choice) {
78
+ const answer = await nextLine(`\n Select [1-${options.length}]: `);
79
+ // Handle EOF — stdin closed without valid selection
80
+ if (answer === '' && (!_rl || !stdin.isTTY)) {
81
+ console.error('\n ✗ No input received (stdin closed). Aborting.');
82
+ process.exit(1);
83
+ }
84
+ const num = parseInt(answer, 10);
85
+ if (num >= 1 && num <= options.length) {
86
+ choice = options[num - 1];
87
+ }
88
+ else {
89
+ console.log(` Please enter a number between 1 and ${options.length}`);
90
+ }
91
+ }
92
+ return choice.value;
93
+ }
94
+ /**
95
+ * Yes/No confirmation prompt.
96
+ */
97
+ export async function confirm(message, defaultYes = true) {
98
+ const hint = defaultYes ? '[Y/n]' : '[y/N]';
99
+ const answer = await nextLine(` ${message} ${hint} `);
100
+ if (!answer.trim())
101
+ return defaultYes;
102
+ return answer.trim().toLowerCase().startsWith('y');
103
+ }
104
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"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"}