slavedriver 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.
- package/README.md +165 -0
- package/agents/executor.md +26 -0
- package/agents/planner.md +41 -0
- package/agents/researcher.md +28 -0
- package/agents/verifier.md +25 -0
- package/dist/agents/backends/claude-code.d.ts +2 -0
- package/dist/agents/backends/claude-code.js +215 -0
- package/dist/agents/backends/claude-code.js.map +1 -0
- package/dist/agents/backends/mock.d.ts +9 -0
- package/dist/agents/backends/mock.js +31 -0
- package/dist/agents/backends/mock.js.map +1 -0
- package/dist/agents/context-builder.d.ts +10 -0
- package/dist/agents/context-builder.js +61 -0
- package/dist/agents/context-builder.js.map +1 -0
- package/dist/agents/prompt-compiler.d.ts +27 -0
- package/dist/agents/prompt-compiler.js +549 -0
- package/dist/agents/prompt-compiler.js.map +1 -0
- package/dist/agents/runtime.d.ts +40 -0
- package/dist/agents/runtime.js +2 -0
- package/dist/agents/runtime.js.map +1 -0
- package/dist/cli/arg-parser.d.ts +6 -0
- package/dist/cli/arg-parser.js +59 -0
- package/dist/cli/arg-parser.js.map +1 -0
- package/dist/cli/commands/config.d.ts +9 -0
- package/dist/cli/commands/config.js +120 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/dashboard.d.ts +1 -0
- package/dist/cli/commands/dashboard.js +54 -0
- package/dist/cli/commands/dashboard.js.map +1 -0
- package/dist/cli/commands/find-root.d.ts +14 -0
- package/dist/cli/commands/find-root.js +55 -0
- package/dist/cli/commands/find-root.js.map +1 -0
- package/dist/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.js +65 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/next.d.ts +1 -0
- package/dist/cli/commands/next.js +61 -0
- package/dist/cli/commands/next.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +2 -0
- package/dist/cli/commands/plan.js +53 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/replan.d.ts +1 -0
- package/dist/cli/commands/replan.js +54 -0
- package/dist/cli/commands/replan.js.map +1 -0
- package/dist/cli/commands/run-pipeline.d.ts +2 -0
- package/dist/cli/commands/run-pipeline.js +74 -0
- package/dist/cli/commands/run-pipeline.js.map +1 -0
- package/dist/cli/commands/run.d.ts +2 -0
- package/dist/cli/commands/run.js +106 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/status.d.ts +1 -0
- package/dist/cli/commands/status.js +51 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +1 -0
- package/dist/cli/commands/verify.js +63 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/commands/wizard.d.ts +8 -0
- package/dist/cli/commands/wizard.js +39 -0
- package/dist/cli/commands/wizard.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +82 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/wizard/index.d.ts +11 -0
- package/dist/cli/wizard/index.js +40 -0
- package/dist/cli/wizard/index.js.map +1 -0
- package/dist/cli/wizard/interview.d.ts +26 -0
- package/dist/cli/wizard/interview.js +284 -0
- package/dist/cli/wizard/interview.js.map +1 -0
- package/dist/cli/wizard/prompt.d.ts +18 -0
- package/dist/cli/wizard/prompt.js +72 -0
- package/dist/cli/wizard/prompt.js.map +1 -0
- package/dist/cli/wizard/template-generator.d.ts +8 -0
- package/dist/cli/wizard/template-generator.js +133 -0
- package/dist/cli/wizard/template-generator.js.map +1 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +68 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/protocol.d.ts +33 -0
- package/dist/mcp/protocol.js +82 -0
- package/dist/mcp/protocol.js.map +1 -0
- package/dist/mcp/resources.d.ts +20 -0
- package/dist/mcp/resources.js +101 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/run-manager.d.ts +36 -0
- package/dist/mcp/run-manager.js +179 -0
- package/dist/mcp/run-manager.js.map +1 -0
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +99 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +32 -0
- package/dist/mcp/tools.js +259 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/orchestrator/alert-types.d.ts +16 -0
- package/dist/orchestrator/alert-types.js +2 -0
- package/dist/orchestrator/alert-types.js.map +1 -0
- package/dist/orchestrator/alerts.d.ts +20 -0
- package/dist/orchestrator/alerts.js +76 -0
- package/dist/orchestrator/alerts.js.map +1 -0
- package/dist/orchestrator/checkpoints.d.ts +8 -0
- package/dist/orchestrator/checkpoints.js +24 -0
- package/dist/orchestrator/checkpoints.js.map +1 -0
- package/dist/orchestrator/engine.d.ts +71 -0
- package/dist/orchestrator/engine.js +420 -0
- package/dist/orchestrator/engine.js.map +1 -0
- package/dist/orchestrator/phase-gates.d.ts +6 -0
- package/dist/orchestrator/phase-gates.js +127 -0
- package/dist/orchestrator/phase-gates.js.map +1 -0
- package/dist/orchestrator/plan-approval.d.ts +10 -0
- package/dist/orchestrator/plan-approval.js +51 -0
- package/dist/orchestrator/plan-approval.js.map +1 -0
- package/dist/orchestrator/safety.d.ts +22 -0
- package/dist/orchestrator/safety.js +126 -0
- package/dist/orchestrator/safety.js.map +1 -0
- package/dist/orchestrator/task-graph.d.ts +17 -0
- package/dist/orchestrator/task-graph.js +156 -0
- package/dist/orchestrator/task-graph.js.map +1 -0
- package/dist/orchestrator/wave-executor.d.ts +37 -0
- package/dist/orchestrator/wave-executor.js +237 -0
- package/dist/orchestrator/wave-executor.js.map +1 -0
- package/dist/session/in-process.d.ts +2 -0
- package/dist/session/in-process.js +149 -0
- package/dist/session/in-process.js.map +1 -0
- package/dist/session/log-capture.d.ts +7 -0
- package/dist/session/log-capture.js +56 -0
- package/dist/session/log-capture.js.map +1 -0
- package/dist/session/manager.d.ts +20 -0
- package/dist/session/manager.js +2 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/state/file-store.d.ts +3 -0
- package/dist/state/file-store.js +124 -0
- package/dist/state/file-store.js.map +1 -0
- package/dist/state/lock.d.ts +6 -0
- package/dist/state/lock.js +71 -0
- package/dist/state/lock.js.map +1 -0
- package/dist/state/plan-parser.d.ts +6 -0
- package/dist/state/plan-parser.js +54 -0
- package/dist/state/plan-parser.js.map +1 -0
- package/dist/state/store.d.ts +27 -0
- package/dist/state/store.js +2 -0
- package/dist/state/store.js.map +1 -0
- package/dist/steps/events.d.ts +49 -0
- package/dist/steps/events.js +2 -0
- package/dist/steps/events.js.map +1 -0
- package/dist/steps/pipeline.d.ts +14 -0
- package/dist/steps/pipeline.js +284 -0
- package/dist/steps/pipeline.js.map +1 -0
- package/dist/steps/plan-parser.d.ts +35 -0
- package/dist/steps/plan-parser.js +147 -0
- package/dist/steps/plan-parser.js.map +1 -0
- package/dist/steps/runner.d.ts +13 -0
- package/dist/steps/runner.js +155 -0
- package/dist/steps/runner.js.map +1 -0
- package/dist/steps/store.d.ts +26 -0
- package/dist/steps/store.js +164 -0
- package/dist/steps/store.js.map +1 -0
- package/dist/steps/types.d.ts +36 -0
- package/dist/steps/types.js +2 -0
- package/dist/steps/types.js.map +1 -0
- package/dist/tui/app.d.ts +15 -0
- package/dist/tui/app.js +297 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/banner.d.ts +1 -0
- package/dist/tui/banner.js +11 -0
- package/dist/tui/banner.js.map +1 -0
- package/dist/tui/colors.d.ts +22 -0
- package/dist/tui/colors.js +30 -0
- package/dist/tui/colors.js.map +1 -0
- package/dist/tui/components/agent-panel.d.ts +8 -0
- package/dist/tui/components/agent-panel.js +80 -0
- package/dist/tui/components/agent-panel.js.map +1 -0
- package/dist/tui/components/header.d.ts +15 -0
- package/dist/tui/components/header.js +69 -0
- package/dist/tui/components/header.js.map +1 -0
- package/dist/tui/components/status-bar.d.ts +2 -0
- package/dist/tui/components/status-bar.js +8 -0
- package/dist/tui/components/status-bar.js.map +1 -0
- package/dist/tui/components/task-board.d.ts +3 -0
- package/dist/tui/components/task-board.js +96 -0
- package/dist/tui/components/task-board.js.map +1 -0
- package/dist/tui/display.d.ts +23 -0
- package/dist/tui/display.js +125 -0
- package/dist/tui/display.js.map +1 -0
- package/dist/tui/input.d.ts +2 -0
- package/dist/tui/input.js +44 -0
- package/dist/tui/input.js.map +1 -0
- package/dist/tui/layout-master.d.ts +7 -0
- package/dist/tui/layout-master.js +31 -0
- package/dist/tui/layout-master.js.map +1 -0
- package/dist/tui/layout.d.ts +13 -0
- package/dist/tui/layout.js +37 -0
- package/dist/tui/layout.js.map +1 -0
- package/dist/tui/pane-formatter.d.ts +27 -0
- package/dist/tui/pane-formatter.js +153 -0
- package/dist/tui/pane-formatter.js.map +1 -0
- package/dist/tui/renderer.d.ts +8 -0
- package/dist/tui/renderer.js +30 -0
- package/dist/tui/renderer.js.map +1 -0
- package/dist/tui/screen.d.ts +12 -0
- package/dist/tui/screen.js +32 -0
- package/dist/tui/screen.js.map +1 -0
- package/dist/tui/structured-display.d.ts +5 -0
- package/dist/tui/structured-display.js +74 -0
- package/dist/tui/structured-display.js.map +1 -0
- package/dist/tui/tmux-display.d.ts +6 -0
- package/dist/tui/tmux-display.js +187 -0
- package/dist/tui/tmux-display.js.map +1 -0
- package/dist/tui/tmux.d.ts +26 -0
- package/dist/tui/tmux.js +265 -0
- package/dist/tui/tmux.js.map +1 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/git.d.ts +6 -0
- package/dist/utils/git.js +35 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/hello.d.ts +1 -0
- package/dist/utils/hello.js +4 -0
- package/dist/utils/hello.js.map +1 -0
- package/dist/utils/id.d.ts +1 -0
- package/dist/utils/id.js +5 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/jsonl.d.ts +2 -0
- package/dist/utils/jsonl.js +18 -0
- package/dist/utils/jsonl.js.map +1 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/logger.js +40 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/pricing.d.ts +3 -0
- package/dist/utils/pricing.js +26 -0
- package/dist/utils/pricing.js.map +1 -0
- package/dist/utils/xml.d.ts +13 -0
- package/dist/utils/xml.js +67 -0
- package/dist/utils/xml.js.map +1 -0
- package/dist/utils/yaml.d.ts +5 -0
- package/dist/utils/yaml.js +126 -0
- package/dist/utils/yaml.js.map +1 -0
- package/package.json +45 -0
- package/templates/CONSTITUTION.md +10 -0
- package/templates/STATE.md +3 -0
- package/templates/config.json +11 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { generateId } from '../../utils/id.js';
|
|
4
|
+
import { askText } from './prompt.js';
|
|
5
|
+
const HINT_FILES = [
|
|
6
|
+
'package.json',
|
|
7
|
+
'tsconfig.json',
|
|
8
|
+
'Cargo.toml',
|
|
9
|
+
'go.mod',
|
|
10
|
+
'pyproject.toml',
|
|
11
|
+
'requirements.txt',
|
|
12
|
+
];
|
|
13
|
+
function tryReadJson(path) {
|
|
14
|
+
try {
|
|
15
|
+
const raw = readFileSync(path, 'utf-8');
|
|
16
|
+
return JSON.parse(raw);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function detectFromPackageJson(rootDir, profile) {
|
|
23
|
+
const pkgPath = join(rootDir, 'package.json');
|
|
24
|
+
const pkg = tryReadJson(pkgPath);
|
|
25
|
+
if (!pkg)
|
|
26
|
+
return;
|
|
27
|
+
const deps = {
|
|
28
|
+
...pkg.dependencies,
|
|
29
|
+
...pkg.devDependencies,
|
|
30
|
+
};
|
|
31
|
+
// Language detection
|
|
32
|
+
if (deps.typescript) {
|
|
33
|
+
profile.language = 'typescript';
|
|
34
|
+
profile.hasTypeScript = true;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
profile.language = 'javascript';
|
|
38
|
+
}
|
|
39
|
+
// Framework detection
|
|
40
|
+
if (deps.next)
|
|
41
|
+
profile.framework = 'next';
|
|
42
|
+
else if (deps.react)
|
|
43
|
+
profile.framework = 'react';
|
|
44
|
+
else if (deps.vue)
|
|
45
|
+
profile.framework = 'vue';
|
|
46
|
+
else if (deps.express)
|
|
47
|
+
profile.framework = 'express';
|
|
48
|
+
else if (deps.fastify)
|
|
49
|
+
profile.framework = 'fastify';
|
|
50
|
+
// Test framework detection
|
|
51
|
+
if (deps.vitest)
|
|
52
|
+
profile.testFramework = 'vitest';
|
|
53
|
+
else if (deps.jest)
|
|
54
|
+
profile.testFramework = 'jest';
|
|
55
|
+
else if (deps.mocha)
|
|
56
|
+
profile.testFramework = 'mocha';
|
|
57
|
+
// Build tool detection
|
|
58
|
+
if (deps.vite)
|
|
59
|
+
profile.buildTool = 'vite';
|
|
60
|
+
else if (deps.webpack)
|
|
61
|
+
profile.buildTool = 'webpack';
|
|
62
|
+
else if (deps.esbuild)
|
|
63
|
+
profile.buildTool = 'esbuild';
|
|
64
|
+
else if (deps.rollup)
|
|
65
|
+
profile.buildTool = 'rollup';
|
|
66
|
+
else if (deps.typescript)
|
|
67
|
+
profile.buildTool = 'tsc';
|
|
68
|
+
// Package manager detection
|
|
69
|
+
if (existsSync(join(rootDir, 'pnpm-lock.yaml'))) {
|
|
70
|
+
profile.packageManager = 'pnpm';
|
|
71
|
+
}
|
|
72
|
+
else if (existsSync(join(rootDir, 'yarn.lock'))) {
|
|
73
|
+
profile.packageManager = 'yarn';
|
|
74
|
+
}
|
|
75
|
+
else if (existsSync(join(rootDir, 'bun.lockb'))) {
|
|
76
|
+
profile.packageManager = 'bun';
|
|
77
|
+
}
|
|
78
|
+
else if (existsSync(join(rootDir, 'package-lock.json'))) {
|
|
79
|
+
profile.packageManager = 'npm';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export async function scanCodebase(rootDir) {
|
|
83
|
+
const detectedFiles = [];
|
|
84
|
+
const profile = {};
|
|
85
|
+
// Scan for hint files
|
|
86
|
+
for (const file of HINT_FILES) {
|
|
87
|
+
if (existsSync(join(rootDir, file))) {
|
|
88
|
+
detectedFiles.push(file);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// package.json analysis
|
|
92
|
+
if (detectedFiles.includes('package.json')) {
|
|
93
|
+
detectFromPackageJson(rootDir, profile);
|
|
94
|
+
}
|
|
95
|
+
// tsconfig.json
|
|
96
|
+
if (detectedFiles.includes('tsconfig.json')) {
|
|
97
|
+
profile.hasTypeScript = true;
|
|
98
|
+
if (!profile.language) {
|
|
99
|
+
profile.language = 'typescript';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Cargo.toml → Rust
|
|
103
|
+
if (detectedFiles.includes('Cargo.toml')) {
|
|
104
|
+
profile.language = 'rust';
|
|
105
|
+
profile.buildTool = 'cargo';
|
|
106
|
+
}
|
|
107
|
+
// go.mod → Go
|
|
108
|
+
if (detectedFiles.includes('go.mod')) {
|
|
109
|
+
profile.language = 'go';
|
|
110
|
+
profile.buildTool = 'go';
|
|
111
|
+
}
|
|
112
|
+
// pyproject.toml or requirements.txt → Python
|
|
113
|
+
if (detectedFiles.includes('pyproject.toml') || detectedFiles.includes('requirements.txt')) {
|
|
114
|
+
if (!profile.language) {
|
|
115
|
+
profile.language = 'python';
|
|
116
|
+
}
|
|
117
|
+
if (detectedFiles.includes('pyproject.toml')) {
|
|
118
|
+
const raw = readFileSync(join(rootDir, 'pyproject.toml'), 'utf-8');
|
|
119
|
+
if (raw.includes('pytest'))
|
|
120
|
+
profile.testFramework = 'pytest';
|
|
121
|
+
if (raw.includes('poetry'))
|
|
122
|
+
profile.packageManager = 'poetry';
|
|
123
|
+
else if (raw.includes('hatch'))
|
|
124
|
+
profile.packageManager = 'hatch';
|
|
125
|
+
else
|
|
126
|
+
profile.packageManager = 'pip';
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return { ...profile, detectedFiles };
|
|
130
|
+
}
|
|
131
|
+
const INTERVIEW_SYSTEM_PROMPT = [
|
|
132
|
+
'You are an interview agent helping set up a new slavedriver project.',
|
|
133
|
+
'',
|
|
134
|
+
'Your job is to ask the user targeted questions about their project to generate:',
|
|
135
|
+
'1. A CONSTITUTION — project-specific rules and constraints for agents to follow.',
|
|
136
|
+
'2. A CONTEXT — a summary of the project for agents to understand the codebase.',
|
|
137
|
+
'',
|
|
138
|
+
'Ask 3-5 focused questions covering:',
|
|
139
|
+
'- Project purpose and architecture',
|
|
140
|
+
'- Security posture: "Does this project handle sensitive data? Do you want automated security reviews?"',
|
|
141
|
+
'- QA preferences: "What is your testing philosophy? Do you want automated QA reviews?"',
|
|
142
|
+
'- Checkpoint preferences: "How much control do you want during execution? (approve at every step vs. just the plan)"',
|
|
143
|
+
'',
|
|
144
|
+
'After each question, wait for the user\'s response.',
|
|
145
|
+
'Format each question on its own line prefixed with "Q: ".',
|
|
146
|
+
'',
|
|
147
|
+
'When you have enough information, output your final result in this format:',
|
|
148
|
+
'<constitution>',
|
|
149
|
+
'...the constitution text...',
|
|
150
|
+
'</constitution>',
|
|
151
|
+
'<context>',
|
|
152
|
+
'...the context text...',
|
|
153
|
+
'</context>',
|
|
154
|
+
].join('\n');
|
|
155
|
+
function parseInterviewOutput(output) {
|
|
156
|
+
const constitutionMatch = output.match(/<constitution>([\s\S]*?)<\/constitution>/);
|
|
157
|
+
const contextMatch = output.match(/<context>([\s\S]*?)<\/context>/);
|
|
158
|
+
return {
|
|
159
|
+
constitution: constitutionMatch?.[1]?.trim() ?? '',
|
|
160
|
+
context: contextMatch?.[1]?.trim() ?? '',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function extractQuestions(text) {
|
|
164
|
+
const questions = [];
|
|
165
|
+
const lines = text.split('\n');
|
|
166
|
+
for (const line of lines) {
|
|
167
|
+
const trimmed = line.trim();
|
|
168
|
+
if (trimmed.startsWith('Q: ')) {
|
|
169
|
+
questions.push(trimmed.slice(3));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return questions;
|
|
173
|
+
}
|
|
174
|
+
function generateDefaultConstitution(profile) {
|
|
175
|
+
const lines = [
|
|
176
|
+
'# Project Constitution',
|
|
177
|
+
'',
|
|
178
|
+
'## Coding Standards',
|
|
179
|
+
];
|
|
180
|
+
if (profile.language === 'typescript') {
|
|
181
|
+
lines.push('- Use TypeScript strict mode');
|
|
182
|
+
lines.push('- Prefer named exports over default exports');
|
|
183
|
+
}
|
|
184
|
+
else if (profile.language === 'rust') {
|
|
185
|
+
lines.push('- Follow Rust standard naming conventions');
|
|
186
|
+
lines.push('- Run clippy before committing');
|
|
187
|
+
}
|
|
188
|
+
else if (profile.language === 'go') {
|
|
189
|
+
lines.push('- Follow Go standard naming conventions');
|
|
190
|
+
lines.push('- Run go vet before committing');
|
|
191
|
+
}
|
|
192
|
+
else if (profile.language === 'python') {
|
|
193
|
+
lines.push('- Follow PEP 8 style guidelines');
|
|
194
|
+
}
|
|
195
|
+
else if (profile.language) {
|
|
196
|
+
lines.push(`- Follow ${profile.language} standard conventions`);
|
|
197
|
+
}
|
|
198
|
+
if (profile.testFramework) {
|
|
199
|
+
lines.push(`- Write tests using ${profile.testFramework}`);
|
|
200
|
+
}
|
|
201
|
+
lines.push('- Make atomic, well-described commits');
|
|
202
|
+
return lines.join('\n');
|
|
203
|
+
}
|
|
204
|
+
function generateDefaultContext(profile) {
|
|
205
|
+
const lines = ['# Project Context', ''];
|
|
206
|
+
if (profile.language) {
|
|
207
|
+
lines.push(`- Language: ${profile.language}`);
|
|
208
|
+
}
|
|
209
|
+
if (profile.framework) {
|
|
210
|
+
lines.push(`- Framework: ${profile.framework}`);
|
|
211
|
+
}
|
|
212
|
+
if (profile.buildTool) {
|
|
213
|
+
lines.push(`- Build tool: ${profile.buildTool}`);
|
|
214
|
+
}
|
|
215
|
+
if (profile.testFramework) {
|
|
216
|
+
lines.push(`- Test framework: ${profile.testFramework}`);
|
|
217
|
+
}
|
|
218
|
+
if (profile.packageManager) {
|
|
219
|
+
lines.push(`- Package manager: ${profile.packageManager}`);
|
|
220
|
+
}
|
|
221
|
+
return lines.join('\n');
|
|
222
|
+
}
|
|
223
|
+
export async function runInterview(opts) {
|
|
224
|
+
const { runtime, rootDir, mode } = opts;
|
|
225
|
+
const profile = await scanCodebase(rootDir);
|
|
226
|
+
if (mode === 'autopilot') {
|
|
227
|
+
return {
|
|
228
|
+
profile,
|
|
229
|
+
answers: {},
|
|
230
|
+
constitution: generateDefaultConstitution(profile),
|
|
231
|
+
context: generateDefaultContext(profile),
|
|
232
|
+
mode: 'autopilot',
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
// Interactive mode: spawn a Claude agent to conduct the interview
|
|
236
|
+
const answers = {};
|
|
237
|
+
let fullOutput = '';
|
|
238
|
+
const executionId = generateId();
|
|
239
|
+
const events = runtime.execute({
|
|
240
|
+
executionId,
|
|
241
|
+
prompt: [
|
|
242
|
+
'Interview the user about their project to generate a constitution and context.',
|
|
243
|
+
'',
|
|
244
|
+
`Detected codebase profile:`,
|
|
245
|
+
`- Language: ${profile.language ?? 'unknown'}`,
|
|
246
|
+
`- Framework: ${profile.framework ?? 'none'}`,
|
|
247
|
+
`- Build tool: ${profile.buildTool ?? 'none'}`,
|
|
248
|
+
`- Test framework: ${profile.testFramework ?? 'none'}`,
|
|
249
|
+
`- Package manager: ${profile.packageManager ?? 'unknown'}`,
|
|
250
|
+
`- TypeScript: ${profile.hasTypeScript ? 'yes' : 'no'}`,
|
|
251
|
+
`- Detected files: ${profile.detectedFiles.join(', ') || 'none'}`,
|
|
252
|
+
].join('\n'),
|
|
253
|
+
systemPrompt: INTERVIEW_SYSTEM_PROMPT,
|
|
254
|
+
workingDirectory: rootDir,
|
|
255
|
+
});
|
|
256
|
+
for await (const event of events) {
|
|
257
|
+
if (event.type === 'text_delta') {
|
|
258
|
+
fullOutput += event.text;
|
|
259
|
+
// Check for questions in accumulated output so far
|
|
260
|
+
const questions = extractQuestions(fullOutput);
|
|
261
|
+
for (const question of questions) {
|
|
262
|
+
if (!(question in answers)) {
|
|
263
|
+
const answer = await askText(question, {
|
|
264
|
+
input: opts.input,
|
|
265
|
+
output: opts.output,
|
|
266
|
+
});
|
|
267
|
+
answers[question] = answer;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else if (event.type === 'complete') {
|
|
272
|
+
fullOutput = event.result;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const parsed = parseInterviewOutput(fullOutput);
|
|
276
|
+
return {
|
|
277
|
+
profile,
|
|
278
|
+
answers,
|
|
279
|
+
constitution: parsed.constitution || generateDefaultConstitution(profile),
|
|
280
|
+
context: parsed.context || generateDefaultContext(profile),
|
|
281
|
+
mode: 'interactive',
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=interview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interview.js","sourceRoot":"","sources":["../../../src/cli/wizard/interview.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface PromptOptions {
|
|
2
|
+
readonly default?: string;
|
|
3
|
+
readonly input?: NodeJS.ReadableStream;
|
|
4
|
+
readonly output?: NodeJS.WritableStream;
|
|
5
|
+
}
|
|
6
|
+
export interface ChoiceOptions {
|
|
7
|
+
readonly default?: number;
|
|
8
|
+
readonly input?: NodeJS.ReadableStream;
|
|
9
|
+
readonly output?: NodeJS.WritableStream;
|
|
10
|
+
}
|
|
11
|
+
export interface ConfirmOptions {
|
|
12
|
+
readonly default?: boolean;
|
|
13
|
+
readonly input?: NodeJS.ReadableStream;
|
|
14
|
+
readonly output?: NodeJS.WritableStream;
|
|
15
|
+
}
|
|
16
|
+
export declare function askText(question: string, opts?: PromptOptions): Promise<string>;
|
|
17
|
+
export declare function askChoice(question: string, choices: readonly string[], opts?: ChoiceOptions): Promise<number>;
|
|
18
|
+
export declare function askConfirm(question: string, opts?: ConfirmOptions): Promise<boolean>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline';
|
|
2
|
+
function readLine(prompt, input, output) {
|
|
3
|
+
const rl = createInterface({ input, output });
|
|
4
|
+
return new Promise((resolve) => {
|
|
5
|
+
rl.question(prompt, (answer) => {
|
|
6
|
+
rl.close();
|
|
7
|
+
resolve(answer);
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
function isTTY(stream) {
|
|
12
|
+
return !!stream.isTTY;
|
|
13
|
+
}
|
|
14
|
+
export async function askText(question, opts) {
|
|
15
|
+
const input = opts?.input ?? process.stdin;
|
|
16
|
+
const output = opts?.output ?? process.stdout;
|
|
17
|
+
const defaultValue = opts?.default;
|
|
18
|
+
if (!isTTY(input)) {
|
|
19
|
+
return defaultValue ?? '';
|
|
20
|
+
}
|
|
21
|
+
const suffix = defaultValue !== undefined ? ` (${defaultValue})` : '';
|
|
22
|
+
const answer = await readLine(`${question}${suffix}: `, input, output);
|
|
23
|
+
const trimmed = answer.trim();
|
|
24
|
+
if (trimmed === '' && defaultValue !== undefined) {
|
|
25
|
+
return defaultValue;
|
|
26
|
+
}
|
|
27
|
+
return trimmed;
|
|
28
|
+
}
|
|
29
|
+
export async function askChoice(question, choices, opts) {
|
|
30
|
+
const input = opts?.input ?? process.stdin;
|
|
31
|
+
const output = opts?.output ?? process.stdout;
|
|
32
|
+
const defaultIndex = opts?.default;
|
|
33
|
+
if (!isTTY(input)) {
|
|
34
|
+
return defaultIndex ?? 0;
|
|
35
|
+
}
|
|
36
|
+
const lines = choices.map((c, i) => {
|
|
37
|
+
const marker = i === defaultIndex ? '*' : ' ';
|
|
38
|
+
return ` ${marker}${i + 1}) ${c}`;
|
|
39
|
+
});
|
|
40
|
+
const prompt = `${question}\n${lines.join('\n')}\nChoice: `;
|
|
41
|
+
for (;;) {
|
|
42
|
+
const answer = await readLine(prompt, input, output);
|
|
43
|
+
const trimmed = answer.trim();
|
|
44
|
+
if (trimmed === '' && defaultIndex !== undefined) {
|
|
45
|
+
return defaultIndex;
|
|
46
|
+
}
|
|
47
|
+
const num = parseInt(trimmed, 10);
|
|
48
|
+
if (!isNaN(num) && num >= 1 && num <= choices.length) {
|
|
49
|
+
return num - 1;
|
|
50
|
+
}
|
|
51
|
+
// Write error and re-prompt
|
|
52
|
+
const rl = createInterface({ input, output });
|
|
53
|
+
rl.write(`Please enter a number between 1 and ${choices.length}.\n`);
|
|
54
|
+
rl.close();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export async function askConfirm(question, opts) {
|
|
58
|
+
const input = opts?.input ?? process.stdin;
|
|
59
|
+
const output = opts?.output ?? process.stdout;
|
|
60
|
+
const defaultValue = opts?.default ?? false;
|
|
61
|
+
if (!isTTY(input)) {
|
|
62
|
+
return defaultValue;
|
|
63
|
+
}
|
|
64
|
+
const hint = defaultValue ? 'Y/n' : 'y/N';
|
|
65
|
+
const answer = await readLine(`${question} [${hint}] `, input, output);
|
|
66
|
+
const trimmed = answer.trim().toLowerCase();
|
|
67
|
+
if (trimmed === '') {
|
|
68
|
+
return defaultValue;
|
|
69
|
+
}
|
|
70
|
+
return trimmed === 'y' || trimmed === 'yes';
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/cli/wizard/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProjectConfig } from '../../types.js';
|
|
2
|
+
import type { InterviewResult } from './interview.js';
|
|
3
|
+
export interface WizardResult {
|
|
4
|
+
readonly constitution: string;
|
|
5
|
+
readonly context: string;
|
|
6
|
+
readonly config: ProjectConfig;
|
|
7
|
+
}
|
|
8
|
+
export declare function generateFromInterview(result: InterviewResult): WizardResult;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export function generateFromInterview(result) {
|
|
2
|
+
return {
|
|
3
|
+
constitution: buildConstitution(result),
|
|
4
|
+
context: buildContext(result),
|
|
5
|
+
config: buildConfig(result),
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function buildConstitution(result) {
|
|
9
|
+
if (result.mode === 'interactive' && result.constitution) {
|
|
10
|
+
return result.constitution;
|
|
11
|
+
}
|
|
12
|
+
const { profile } = result;
|
|
13
|
+
const lines = ['# Project Constitution', '', '## Non-Negotiable Rules', ''];
|
|
14
|
+
switch (profile.language) {
|
|
15
|
+
case 'typescript':
|
|
16
|
+
lines.push('- TypeScript strict mode is required');
|
|
17
|
+
lines.push('- No use of `any` type — use `unknown` and type guards instead');
|
|
18
|
+
lines.push('- Prefer named exports over default exports');
|
|
19
|
+
lines.push('- Use readonly modifiers for interface properties');
|
|
20
|
+
lines.push('- ESM imports must use `.js` file extensions');
|
|
21
|
+
lines.push('- Prefer `const` over `let`, never use `var`');
|
|
22
|
+
break;
|
|
23
|
+
case 'rust':
|
|
24
|
+
lines.push('- All code must pass `cargo clippy` without warnings');
|
|
25
|
+
lines.push('- No `unsafe` blocks without documented justification');
|
|
26
|
+
lines.push('- Follow Rust standard naming conventions (snake_case functions, CamelCase types)');
|
|
27
|
+
break;
|
|
28
|
+
case 'go':
|
|
29
|
+
lines.push('- All code must pass `go vet` and `golint`');
|
|
30
|
+
lines.push('- Follow Go standard naming conventions');
|
|
31
|
+
lines.push('- Exported functions must have doc comments');
|
|
32
|
+
break;
|
|
33
|
+
case 'python':
|
|
34
|
+
lines.push('- Follow PEP 8 style guidelines');
|
|
35
|
+
lines.push('- Use type hints for function signatures');
|
|
36
|
+
lines.push('- Prefer f-strings over format() or % formatting');
|
|
37
|
+
break;
|
|
38
|
+
case 'javascript':
|
|
39
|
+
lines.push('- Use strict mode');
|
|
40
|
+
lines.push('- Prefer const over let, avoid var');
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
if (profile.language) {
|
|
44
|
+
lines.push(`- Follow ${profile.language} standard conventions`);
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
lines.push('');
|
|
49
|
+
lines.push('## Testing');
|
|
50
|
+
lines.push('');
|
|
51
|
+
if (profile.testFramework) {
|
|
52
|
+
lines.push(`- Write tests using ${profile.testFramework}`);
|
|
53
|
+
lines.push('- All new code must have corresponding tests');
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
lines.push('- All new code should have corresponding tests');
|
|
57
|
+
}
|
|
58
|
+
lines.push('');
|
|
59
|
+
lines.push('## Git');
|
|
60
|
+
lines.push('');
|
|
61
|
+
lines.push('- Make atomic, well-described commits');
|
|
62
|
+
lines.push('- Do not commit generated files or build artifacts');
|
|
63
|
+
return lines.join('\n');
|
|
64
|
+
}
|
|
65
|
+
function buildContext(result) {
|
|
66
|
+
if (result.mode === 'interactive' && result.context) {
|
|
67
|
+
return result.context;
|
|
68
|
+
}
|
|
69
|
+
const { profile } = result;
|
|
70
|
+
const lines = ['# Project Context', ''];
|
|
71
|
+
lines.push('## Stack');
|
|
72
|
+
lines.push('');
|
|
73
|
+
if (profile.language) {
|
|
74
|
+
lines.push(`- **Language**: ${profile.language}${profile.hasTypeScript ? ' (TypeScript)' : ''}`);
|
|
75
|
+
}
|
|
76
|
+
if (profile.framework) {
|
|
77
|
+
lines.push(`- **Framework**: ${profile.framework}`);
|
|
78
|
+
}
|
|
79
|
+
if (profile.buildTool) {
|
|
80
|
+
lines.push(`- **Build tool**: ${profile.buildTool}`);
|
|
81
|
+
}
|
|
82
|
+
if (profile.testFramework) {
|
|
83
|
+
lines.push(`- **Test framework**: ${profile.testFramework}`);
|
|
84
|
+
}
|
|
85
|
+
if (profile.packageManager) {
|
|
86
|
+
lines.push(`- **Package manager**: ${profile.packageManager}`);
|
|
87
|
+
}
|
|
88
|
+
if (profile.detectedFiles.length > 0) {
|
|
89
|
+
lines.push('');
|
|
90
|
+
lines.push('## Detected Configuration');
|
|
91
|
+
lines.push('');
|
|
92
|
+
lines.push(`Config files found: ${profile.detectedFiles.join(', ')}`);
|
|
93
|
+
}
|
|
94
|
+
return lines.join('\n');
|
|
95
|
+
}
|
|
96
|
+
function concurrencyForLanguage(language) {
|
|
97
|
+
switch (language) {
|
|
98
|
+
case 'rust':
|
|
99
|
+
return 3; // cargo builds are memory-heavy
|
|
100
|
+
default:
|
|
101
|
+
return 8;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function excludedPathsForProfile(profile) {
|
|
105
|
+
const paths = ['node_modules', '.git', 'dist', 'build', 'coverage'];
|
|
106
|
+
switch (profile.language) {
|
|
107
|
+
case 'rust':
|
|
108
|
+
paths.push('target');
|
|
109
|
+
break;
|
|
110
|
+
case 'python':
|
|
111
|
+
paths.push('__pycache__', '.venv', 'venv', '.mypy_cache');
|
|
112
|
+
break;
|
|
113
|
+
case 'go':
|
|
114
|
+
paths.push('vendor');
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
return paths;
|
|
118
|
+
}
|
|
119
|
+
function buildConfig(result) {
|
|
120
|
+
const { profile } = result;
|
|
121
|
+
const maxConcurrentAgents = concurrencyForLanguage(profile.language);
|
|
122
|
+
const excludedPaths = excludedPathsForProfile(profile);
|
|
123
|
+
return {
|
|
124
|
+
maxConcurrentAgents,
|
|
125
|
+
excludedPaths,
|
|
126
|
+
excludedCommands: ['rm -rf /', 'DROP DATABASE', 'FORMAT'],
|
|
127
|
+
maxTotalTokens: 2_000_000,
|
|
128
|
+
maxTokensPerStep: 200_000,
|
|
129
|
+
maxWallTimeSeconds: 3600,
|
|
130
|
+
maxAgentInvocations: 50,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=template-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-generator.js","sourceRoot":"","sources":["../../../src/cli/wizard/template-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { createStepStore } from '../steps/store.js';
|
|
5
|
+
import { createClaudeCodeRuntime } from '../agents/backends/claude-code.js';
|
|
6
|
+
import { findSlavedriverRoot } from '../cli/commands/find-root.js';
|
|
7
|
+
import { createRunManager } from './run-manager.js';
|
|
8
|
+
import { createToolRegistry } from './tools.js';
|
|
9
|
+
import { createResourceRegistry } from './resources.js';
|
|
10
|
+
import { createMcpServer } from './server.js';
|
|
11
|
+
async function main() {
|
|
12
|
+
const projectRoot = findSlavedriverRoot();
|
|
13
|
+
if (projectRoot === null) {
|
|
14
|
+
process.stderr.write('slavedriver-mcp: No .slavedriver/ directory found. Run `slavedriver init` first.\n');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const sdRoot = join(projectRoot, '.slavedriver');
|
|
18
|
+
const configPath = join(sdRoot, 'config.json');
|
|
19
|
+
const config = JSON.parse(await readFile(configPath, 'utf-8'));
|
|
20
|
+
const runtime = createClaudeCodeRuntime();
|
|
21
|
+
const store = createStepStore(sdRoot);
|
|
22
|
+
const runManager = createRunManager({
|
|
23
|
+
runtime,
|
|
24
|
+
store,
|
|
25
|
+
config,
|
|
26
|
+
sdRoot,
|
|
27
|
+
workingDirectory: projectRoot,
|
|
28
|
+
});
|
|
29
|
+
const tools = createToolRegistry({
|
|
30
|
+
runManager,
|
|
31
|
+
store,
|
|
32
|
+
runtime,
|
|
33
|
+
sdRoot,
|
|
34
|
+
workingDirectory: projectRoot,
|
|
35
|
+
configPath,
|
|
36
|
+
});
|
|
37
|
+
const resources = createResourceRegistry({ store, sdRoot });
|
|
38
|
+
const server = createMcpServer({
|
|
39
|
+
input: process.stdin,
|
|
40
|
+
output: process.stdout,
|
|
41
|
+
tools,
|
|
42
|
+
resources,
|
|
43
|
+
});
|
|
44
|
+
process.stderr.write('slavedriver-mcp: server started\n');
|
|
45
|
+
// Clean shutdown
|
|
46
|
+
const shutdown = () => {
|
|
47
|
+
process.stderr.write('slavedriver-mcp: shutting down\n');
|
|
48
|
+
process.exit(0);
|
|
49
|
+
};
|
|
50
|
+
process.on('SIGTERM', shutdown);
|
|
51
|
+
process.on('SIGINT', shutdown);
|
|
52
|
+
await server.start();
|
|
53
|
+
// stdin closed — drain stdout before exiting
|
|
54
|
+
process.stderr.write('slavedriver-mcp: stdin closed, exiting\n');
|
|
55
|
+
await new Promise((resolve) => {
|
|
56
|
+
if (process.stdout.writableFinished) {
|
|
57
|
+
resolve();
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
process.stdout.end(resolve);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
main().catch((err) => {
|
|
65
|
+
process.stderr.write(`slavedriver-mcp: fatal error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Readable, Writable } from 'node:stream';
|
|
2
|
+
export interface JsonRpcRequest {
|
|
3
|
+
jsonrpc: '2.0';
|
|
4
|
+
id?: string | number | null;
|
|
5
|
+
method: string;
|
|
6
|
+
params?: unknown;
|
|
7
|
+
}
|
|
8
|
+
export interface JsonRpcResponse {
|
|
9
|
+
jsonrpc: '2.0';
|
|
10
|
+
id: string | number | null;
|
|
11
|
+
result?: unknown;
|
|
12
|
+
error?: {
|
|
13
|
+
code: number;
|
|
14
|
+
message: string;
|
|
15
|
+
data?: unknown;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export declare const MAX_MESSAGE_SIZE = 1048576;
|
|
19
|
+
export declare const PARSE_ERROR = -32700;
|
|
20
|
+
export declare const INVALID_REQUEST = -32600;
|
|
21
|
+
export declare const METHOD_NOT_FOUND = -32601;
|
|
22
|
+
export declare const INVALID_PARAMS = -32602;
|
|
23
|
+
export declare const INTERNAL_ERROR = -32603;
|
|
24
|
+
/**
|
|
25
|
+
* Create an async iterable that yields validated `JsonRpcRequest` objects
|
|
26
|
+
* from a newline-delimited JSON stream (MCP stdio transport).
|
|
27
|
+
*/
|
|
28
|
+
export declare function createMessageReader(input: Readable): AsyncGenerator<JsonRpcRequest>;
|
|
29
|
+
export declare function createMessageWriter(output: Writable): {
|
|
30
|
+
write(msg: JsonRpcResponse): void;
|
|
31
|
+
};
|
|
32
|
+
export declare function createSuccessResponse(id: string | number | null, result: unknown): JsonRpcResponse;
|
|
33
|
+
export declare function createErrorResponse(id: string | number | null, code: number, message: string, data?: unknown): JsonRpcResponse;
|