@promptwheel/core 0.6.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/dist/codebase-index/index.d.ts +23 -0
- package/dist/codebase-index/index.d.ts.map +1 -0
- package/dist/codebase-index/index.js +361 -0
- package/dist/codebase-index/index.js.map +1 -0
- package/dist/codebase-index/shared.d.ts +95 -0
- package/dist/codebase-index/shared.d.ts.map +1 -0
- package/dist/codebase-index/shared.js +319 -0
- package/dist/codebase-index/shared.js.map +1 -0
- package/dist/config/defaults.d.ts +45 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +79 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/critic/shared.d.ts +49 -0
- package/dist/critic/shared.d.ts.map +1 -0
- package/dist/critic/shared.js +204 -0
- package/dist/critic/shared.js.map +1 -0
- package/dist/db/adapter.d.ts +191 -0
- package/dist/db/adapter.d.ts.map +1 -0
- package/dist/db/adapter.js +40 -0
- package/dist/db/adapter.js.map +1 -0
- package/dist/db/contract.d.ts +47 -0
- package/dist/db/contract.d.ts.map +1 -0
- package/dist/db/contract.js +258 -0
- package/dist/db/contract.js.map +1 -0
- package/dist/db/index.d.ts +6 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +7 -0
- package/dist/db/index.js.map +1 -0
- package/dist/dedup/shared.d.ts +82 -0
- package/dist/dedup/shared.d.ts.map +1 -0
- package/dist/dedup/shared.js +215 -0
- package/dist/dedup/shared.js.map +1 -0
- package/dist/exec/index.d.ts +5 -0
- package/dist/exec/index.d.ts.map +1 -0
- package/dist/exec/index.js +5 -0
- package/dist/exec/index.js.map +1 -0
- package/dist/exec/types.d.ts +64 -0
- package/dist/exec/types.d.ts.map +1 -0
- package/dist/exec/types.js +8 -0
- package/dist/exec/types.js.map +1 -0
- package/dist/formulas/shared.d.ts +42 -0
- package/dist/formulas/shared.d.ts.map +1 -0
- package/dist/formulas/shared.js +204 -0
- package/dist/formulas/shared.js.map +1 -0
- package/dist/guidelines/shared.d.ts +46 -0
- package/dist/guidelines/shared.d.ts.map +1 -0
- package/dist/guidelines/shared.js +128 -0
- package/dist/guidelines/shared.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/learnings/shared.d.ts +112 -0
- package/dist/learnings/shared.d.ts.map +1 -0
- package/dist/learnings/shared.js +402 -0
- package/dist/learnings/shared.js.map +1 -0
- package/dist/proposals/shared.d.ts +137 -0
- package/dist/proposals/shared.d.ts.map +1 -0
- package/dist/proposals/shared.js +254 -0
- package/dist/proposals/shared.js.map +1 -0
- package/dist/repos/index.d.ts +15 -0
- package/dist/repos/index.d.ts.map +1 -0
- package/dist/repos/index.js +11 -0
- package/dist/repos/index.js.map +1 -0
- package/dist/repos/projects.d.ts +41 -0
- package/dist/repos/projects.d.ts.map +1 -0
- package/dist/repos/projects.js +75 -0
- package/dist/repos/projects.js.map +1 -0
- package/dist/repos/run_steps.d.ts +152 -0
- package/dist/repos/run_steps.d.ts.map +1 -0
- package/dist/repos/run_steps.js +328 -0
- package/dist/repos/run_steps.js.map +1 -0
- package/dist/repos/runs.d.ts +92 -0
- package/dist/repos/runs.d.ts.map +1 -0
- package/dist/repos/runs.js +185 -0
- package/dist/repos/runs.js.map +1 -0
- package/dist/repos/tickets.d.ts +71 -0
- package/dist/repos/tickets.d.ts.map +1 -0
- package/dist/repos/tickets.js +158 -0
- package/dist/repos/tickets.js.map +1 -0
- package/dist/scope/shared.d.ts +67 -0
- package/dist/scope/shared.d.ts.map +1 -0
- package/dist/scope/shared.js +355 -0
- package/dist/scope/shared.js.map +1 -0
- package/dist/scout/index.d.ts +18 -0
- package/dist/scout/index.d.ts.map +1 -0
- package/dist/scout/index.js +445 -0
- package/dist/scout/index.js.map +1 -0
- package/dist/scout/kimi-runner.d.ts +21 -0
- package/dist/scout/kimi-runner.d.ts.map +1 -0
- package/dist/scout/kimi-runner.js +76 -0
- package/dist/scout/kimi-runner.js.map +1 -0
- package/dist/scout/mcp-batch-server.d.ts +37 -0
- package/dist/scout/mcp-batch-server.d.ts.map +1 -0
- package/dist/scout/mcp-batch-server.js +144 -0
- package/dist/scout/mcp-batch-server.js.map +1 -0
- package/dist/scout/openai-local-runner.d.ts +20 -0
- package/dist/scout/openai-local-runner.d.ts.map +1 -0
- package/dist/scout/openai-local-runner.js +82 -0
- package/dist/scout/openai-local-runner.js.map +1 -0
- package/dist/scout/prompt.d.ts +49 -0
- package/dist/scout/prompt.d.ts.map +1 -0
- package/dist/scout/prompt.js +153 -0
- package/dist/scout/prompt.js.map +1 -0
- package/dist/scout/runner.d.ts +101 -0
- package/dist/scout/runner.d.ts.map +1 -0
- package/dist/scout/runner.js +521 -0
- package/dist/scout/runner.js.map +1 -0
- package/dist/scout/scanner.d.ts +61 -0
- package/dist/scout/scanner.d.ts.map +1 -0
- package/dist/scout/scanner.js +315 -0
- package/dist/scout/scanner.js.map +1 -0
- package/dist/scout/types.d.ts +221 -0
- package/dist/scout/types.d.ts.map +1 -0
- package/dist/scout/types.js +44 -0
- package/dist/scout/types.js.map +1 -0
- package/dist/sectors/shared.d.ts +146 -0
- package/dist/sectors/shared.d.ts.map +1 -0
- package/dist/sectors/shared.js +408 -0
- package/dist/sectors/shared.js.map +1 -0
- package/dist/services/index.d.ts +10 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +9 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/qa.d.ts +76 -0
- package/dist/services/qa.d.ts.map +1 -0
- package/dist/services/qa.js +228 -0
- package/dist/services/qa.js.map +1 -0
- package/dist/services/scout.d.ts +164 -0
- package/dist/services/scout.d.ts.map +1 -0
- package/dist/services/scout.js +215 -0
- package/dist/services/scout.js.map +1 -0
- package/dist/spindle/shared.d.ts +14 -0
- package/dist/spindle/shared.d.ts.map +1 -0
- package/dist/spindle/shared.js +65 -0
- package/dist/spindle/shared.js.map +1 -0
- package/dist/tools/shared.d.ts +35 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +247 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/trace/shared.d.ts +147 -0
- package/dist/trace/shared.d.ts.map +1 -0
- package/dist/trace/shared.js +414 -0
- package/dist/trace/shared.js.map +1 -0
- package/dist/trajectory/shared.d.ts +69 -0
- package/dist/trajectory/shared.d.ts.map +1 -0
- package/dist/trajectory/shared.js +336 -0
- package/dist/trajectory/shared.js.map +1 -0
- package/dist/utils/id.d.ts +12 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +24 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/id.test.d.ts +5 -0
- package/dist/utils/id.test.d.ts.map +1 -0
- package/dist/utils/id.test.js +173 -0
- package/dist/utils/id.test.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/json.d.ts +9 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +19 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/waves/shared.d.ts +106 -0
- package/dist/waves/shared.d.ts.map +1 -0
- package/dist/waves/shared.js +356 -0
- package/dist/waves/shared.js.map +1 -0
- package/package.json +126 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scout Service - Orchestrates codebase scanning and ticket creation
|
|
3
|
+
*
|
|
4
|
+
* This is pure orchestration - it coordinates between:
|
|
5
|
+
* - File scanning (scanner.ts)
|
|
6
|
+
* - LLM analysis (runner.ts)
|
|
7
|
+
* - Data persistence (repos/*)
|
|
8
|
+
*
|
|
9
|
+
* It accepts dependencies via ScoutDeps, making it testable and adapter-agnostic.
|
|
10
|
+
*/
|
|
11
|
+
import * as projects from '../repos/projects.js';
|
|
12
|
+
import * as tickets from '../repos/tickets.js';
|
|
13
|
+
import * as runs from '../repos/runs.js';
|
|
14
|
+
import { scout as scanAndPropose, } from '../scout/index.js';
|
|
15
|
+
/**
|
|
16
|
+
* Scout a repository for improvement opportunities
|
|
17
|
+
*
|
|
18
|
+
* This is the main entry point for the scout service. It:
|
|
19
|
+
* 1. Resolves the repository root
|
|
20
|
+
* 2. Ensures the project exists in the database
|
|
21
|
+
* 3. Creates a scout run
|
|
22
|
+
* 4. Scans files and generates proposals
|
|
23
|
+
* 5. Optionally creates tickets from proposals
|
|
24
|
+
* 6. Records the run outcome
|
|
25
|
+
*/
|
|
26
|
+
export async function scoutRepo(deps, opts = {}) {
|
|
27
|
+
const { db, git, logger } = deps;
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
const errors = [];
|
|
30
|
+
const report = (progress) => {
|
|
31
|
+
opts.onProgress?.({
|
|
32
|
+
phase: 'init',
|
|
33
|
+
...progress,
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
// Phase 1: Resolve repository
|
|
37
|
+
report({ phase: 'init', message: 'Resolving repository...' });
|
|
38
|
+
const targetPath = opts.path ?? process.cwd();
|
|
39
|
+
const repoRoot = await git.findRepoRoot(targetPath);
|
|
40
|
+
if (!repoRoot) {
|
|
41
|
+
throw new Error(`Not a git repository: ${targetPath}`);
|
|
42
|
+
}
|
|
43
|
+
const remoteUrl = await git.getRemoteUrl(repoRoot);
|
|
44
|
+
const projectId = git.getProjectId(repoRoot, remoteUrl);
|
|
45
|
+
logger?.debug('Resolved repository', { repoRoot, remoteUrl, projectId });
|
|
46
|
+
// Phase 2: Ensure project exists
|
|
47
|
+
const project = await projects.ensureForRepo(db, {
|
|
48
|
+
id: projectId,
|
|
49
|
+
name: repoRoot.split('/').pop() || 'unknown',
|
|
50
|
+
repoUrl: remoteUrl,
|
|
51
|
+
rootPath: repoRoot,
|
|
52
|
+
});
|
|
53
|
+
logger?.info('Project ensured', { projectId: project.id, name: project.name });
|
|
54
|
+
// Phase 3: Create scout run
|
|
55
|
+
const run = await runs.create(db, {
|
|
56
|
+
projectId: project.id,
|
|
57
|
+
type: 'scout',
|
|
58
|
+
metadata: {
|
|
59
|
+
scope: opts.scope ?? 'src/**',
|
|
60
|
+
maxProposals: opts.maxProposals ?? 10,
|
|
61
|
+
model: opts.model ?? (opts.backend ? undefined : 'opus'),
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
logger?.debug('Scout run created', { runId: run.id });
|
|
65
|
+
try {
|
|
66
|
+
// Phase 4: Get dedup context
|
|
67
|
+
const recentTickets = await tickets.getRecentlyCompleted(db, project.id, 20);
|
|
68
|
+
const recentTitles = recentTickets.map(t => t.title);
|
|
69
|
+
// Phase 5: Scan and generate proposals
|
|
70
|
+
report({ phase: 'scanning', message: 'Scanning files...' });
|
|
71
|
+
const scanResult = await scanAndPropose({
|
|
72
|
+
scope: opts.scope ?? 'src/**',
|
|
73
|
+
types: opts.types,
|
|
74
|
+
excludeTypes: opts.excludeTypes,
|
|
75
|
+
maxProposals: opts.maxProposals ?? 10,
|
|
76
|
+
minConfidence: opts.minConfidence ?? 50,
|
|
77
|
+
projectPath: repoRoot,
|
|
78
|
+
model: opts.model ?? (opts.backend ? undefined : 'opus'),
|
|
79
|
+
timeoutMs: opts.timeoutMs ?? 120000,
|
|
80
|
+
signal: opts.signal,
|
|
81
|
+
recentlyCompletedTitles: recentTitles,
|
|
82
|
+
customPrompt: opts.customPrompt,
|
|
83
|
+
backend: opts.backend,
|
|
84
|
+
protectedFiles: opts.protectedFiles,
|
|
85
|
+
batchTokenBudget: opts.batchTokenBudget,
|
|
86
|
+
maxFiles: opts.maxFiles,
|
|
87
|
+
scoutConcurrency: opts.scoutConcurrency,
|
|
88
|
+
moduleGroups: opts.moduleGroups,
|
|
89
|
+
coverageContext: opts.coverageContext,
|
|
90
|
+
onRawOutput: opts.onRawOutput,
|
|
91
|
+
onProgress: (p) => {
|
|
92
|
+
report({
|
|
93
|
+
phase: 'analyzing',
|
|
94
|
+
filesScanned: p.filesScanned,
|
|
95
|
+
totalFiles: p.totalFiles,
|
|
96
|
+
proposalsFound: p.proposalsFound,
|
|
97
|
+
message: `Analyzing batch ${p.currentBatch}/${p.totalBatches}`,
|
|
98
|
+
batchStatuses: p.batchStatuses,
|
|
99
|
+
totalBatches: p.totalBatches,
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
if (!scanResult.success) {
|
|
104
|
+
errors.push(...scanResult.errors);
|
|
105
|
+
}
|
|
106
|
+
logger?.info('Scan complete', {
|
|
107
|
+
files: scanResult.scannedFiles,
|
|
108
|
+
proposals: scanResult.proposals.length,
|
|
109
|
+
});
|
|
110
|
+
// Phase 6: Create tickets if auto-approve
|
|
111
|
+
const createdTickets = [];
|
|
112
|
+
if (opts.autoApprove && scanResult.proposals.length > 0) {
|
|
113
|
+
report({
|
|
114
|
+
phase: 'storing',
|
|
115
|
+
proposalsFound: scanResult.proposals.length,
|
|
116
|
+
message: 'Creating tickets...',
|
|
117
|
+
});
|
|
118
|
+
const ticketInputs = scanResult.proposals.map(proposal => ({
|
|
119
|
+
projectId: project.id,
|
|
120
|
+
title: proposal.title,
|
|
121
|
+
description: formatProposalDescription(proposal),
|
|
122
|
+
status: 'ready',
|
|
123
|
+
priority: proposal.confidence,
|
|
124
|
+
category: proposal.category,
|
|
125
|
+
allowedPaths: proposal.allowed_paths,
|
|
126
|
+
verificationCommands: proposal.verification_commands,
|
|
127
|
+
}));
|
|
128
|
+
const created = await tickets.createMany(db, ticketInputs);
|
|
129
|
+
createdTickets.push(...created);
|
|
130
|
+
logger?.info('Tickets created', { count: created.length });
|
|
131
|
+
}
|
|
132
|
+
// Phase 7: Mark run success
|
|
133
|
+
await runs.markSuccess(db, run.id, {
|
|
134
|
+
scannedFiles: scanResult.scannedFiles,
|
|
135
|
+
proposalCount: scanResult.proposals.length,
|
|
136
|
+
ticketCount: createdTickets.length,
|
|
137
|
+
durationMs: Date.now() - startTime,
|
|
138
|
+
});
|
|
139
|
+
report({
|
|
140
|
+
phase: 'complete',
|
|
141
|
+
filesScanned: scanResult.scannedFiles,
|
|
142
|
+
proposalsFound: scanResult.proposals.length,
|
|
143
|
+
ticketsCreated: createdTickets.length,
|
|
144
|
+
});
|
|
145
|
+
return {
|
|
146
|
+
success: true,
|
|
147
|
+
project,
|
|
148
|
+
run: (await runs.getById(db, run.id)),
|
|
149
|
+
proposals: scanResult.proposals,
|
|
150
|
+
tickets: createdTickets,
|
|
151
|
+
errors: scanResult.errors,
|
|
152
|
+
scannedFiles: scanResult.scannedFiles,
|
|
153
|
+
durationMs: Date.now() - startTime,
|
|
154
|
+
sectorReclassification: scanResult.sectorReclassification,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
// Mark run as failed
|
|
159
|
+
await runs.markFailure(db, run.id, error, {
|
|
160
|
+
durationMs: Date.now() - startTime,
|
|
161
|
+
});
|
|
162
|
+
logger?.error('Scout failed', { error: error.message });
|
|
163
|
+
return {
|
|
164
|
+
success: false,
|
|
165
|
+
project,
|
|
166
|
+
run: (await runs.getById(db, run.id)),
|
|
167
|
+
proposals: [],
|
|
168
|
+
tickets: [],
|
|
169
|
+
errors: [...errors, error.message],
|
|
170
|
+
scannedFiles: 0,
|
|
171
|
+
durationMs: Date.now() - startTime,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Format a proposal into ticket description markdown
|
|
177
|
+
*/
|
|
178
|
+
function formatProposalDescription(proposal) {
|
|
179
|
+
const parts = [
|
|
180
|
+
proposal.description,
|
|
181
|
+
'',
|
|
182
|
+
'## Acceptance Criteria',
|
|
183
|
+
...proposal.acceptance_criteria.map(c => `- ${c}`),
|
|
184
|
+
'',
|
|
185
|
+
'## Rationale',
|
|
186
|
+
proposal.rationale,
|
|
187
|
+
'',
|
|
188
|
+
'## Files',
|
|
189
|
+
...proposal.files.map(f => `- \`${f}\``),
|
|
190
|
+
'',
|
|
191
|
+
`**Complexity:** ${proposal.estimated_complexity}`,
|
|
192
|
+
`**Confidence:** ${proposal.confidence}%`,
|
|
193
|
+
];
|
|
194
|
+
return parts.join('\n');
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Approve specific proposals and create tickets
|
|
198
|
+
*/
|
|
199
|
+
export async function approveProposals(deps, projectId, proposals) {
|
|
200
|
+
const { db, logger } = deps;
|
|
201
|
+
const ticketInputs = proposals.map(proposal => ({
|
|
202
|
+
projectId,
|
|
203
|
+
title: proposal.title,
|
|
204
|
+
description: formatProposalDescription(proposal),
|
|
205
|
+
status: 'ready',
|
|
206
|
+
priority: proposal.confidence,
|
|
207
|
+
category: proposal.category,
|
|
208
|
+
allowedPaths: proposal.allowed_paths,
|
|
209
|
+
verificationCommands: proposal.verification_commands,
|
|
210
|
+
}));
|
|
211
|
+
const created = await tickets.createMany(db, ticketInputs);
|
|
212
|
+
logger?.info('Proposals approved', { count: created.length });
|
|
213
|
+
return created;
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=scout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scout.js","sourceRoot":"","sources":["../../src/services/scout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Spindle detection functions used by both CLI and MCP spindle.
|
|
3
|
+
*/
|
|
4
|
+
/** Short hash for signature tracking */
|
|
5
|
+
export declare function shortHash(s: string): string;
|
|
6
|
+
/** Detect alternating failure signatures: A→B→A→B pattern */
|
|
7
|
+
export declare function detectQaPingPong(sigs: string[], cycles: number): string | null;
|
|
8
|
+
/** Detect same command failing N times */
|
|
9
|
+
export declare function detectCommandFailure(sigs: string[], threshold: number): string | null;
|
|
10
|
+
/** Extract file paths from a unified diff */
|
|
11
|
+
export declare function extractFilesFromDiff(diff: string): string[];
|
|
12
|
+
/** Get file edit frequency warnings (state-shape-agnostic) */
|
|
13
|
+
export declare function getFileEditWarnings(counts: Record<string, number>, threshold?: number): string[];
|
|
14
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/spindle/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wCAAwC;AACxC,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsB9E;AAED,0CAA0C;AAC1C,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAarF;AAED,6CAA6C;AAC7C,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ3D;AAED,8DAA8D;AAC9D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAE,MAAU,GAAG,MAAM,EAAE,CAQnG"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Spindle detection functions used by both CLI and MCP spindle.
|
|
3
|
+
*/
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
5
|
+
/** Short hash for signature tracking */
|
|
6
|
+
export function shortHash(s) {
|
|
7
|
+
return createHash('sha256').update(s).digest('hex').slice(0, 12);
|
|
8
|
+
}
|
|
9
|
+
/** Detect alternating failure signatures: A→B→A→B pattern */
|
|
10
|
+
export function detectQaPingPong(sigs, cycles) {
|
|
11
|
+
if (sigs.length < cycles * 2)
|
|
12
|
+
return null;
|
|
13
|
+
const recent = sigs.slice(-(cycles * 2));
|
|
14
|
+
const a = recent[0];
|
|
15
|
+
const b = recent[1];
|
|
16
|
+
if (a === b)
|
|
17
|
+
return null;
|
|
18
|
+
let alternating = true;
|
|
19
|
+
for (let i = 0; i < recent.length; i++) {
|
|
20
|
+
const expected = i % 2 === 0 ? a : b;
|
|
21
|
+
if (recent[i] !== expected) {
|
|
22
|
+
alternating = false;
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (alternating) {
|
|
27
|
+
return `Alternating failures: ${a} ↔ ${b} (${cycles} cycles)`;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
/** Detect same command failing N times */
|
|
32
|
+
export function detectCommandFailure(sigs, threshold) {
|
|
33
|
+
if (sigs.length < threshold)
|
|
34
|
+
return null;
|
|
35
|
+
const counts = new Map();
|
|
36
|
+
for (const sig of sigs) {
|
|
37
|
+
counts.set(sig, (counts.get(sig) ?? 0) + 1);
|
|
38
|
+
}
|
|
39
|
+
for (const [sig, count] of counts) {
|
|
40
|
+
if (count >= threshold)
|
|
41
|
+
return sig;
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
/** Extract file paths from a unified diff */
|
|
46
|
+
export function extractFilesFromDiff(diff) {
|
|
47
|
+
const files = [];
|
|
48
|
+
for (const line of diff.split('\n')) {
|
|
49
|
+
if (line.startsWith('+++ b/')) {
|
|
50
|
+
files.push(line.slice(6));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return files;
|
|
54
|
+
}
|
|
55
|
+
/** Get file edit frequency warnings (state-shape-agnostic) */
|
|
56
|
+
export function getFileEditWarnings(counts, threshold = 3) {
|
|
57
|
+
const warnings = [];
|
|
58
|
+
for (const [file, count] of Object.entries(counts)) {
|
|
59
|
+
if (count >= threshold) {
|
|
60
|
+
warnings.push(`${file} edited ${count} times`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return warnings;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/spindle/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Registry — pure types, built-in specs, and filtering algorithms.
|
|
3
|
+
*
|
|
4
|
+
* Replaces hardcoded auto-approve arrays with a queryable set of tool specs.
|
|
5
|
+
* No I/O — the ToolRegistry class in @promptwheel/mcp handles custom tool loading.
|
|
6
|
+
*/
|
|
7
|
+
export type TrustLevel = 'safe' | 'default' | 'full';
|
|
8
|
+
export type ToolPhase = 'SCOUT' | 'PLAN' | 'EXECUTE' | 'QA' | 'PR';
|
|
9
|
+
export interface ToolSpec {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
approve_patterns: string[];
|
|
13
|
+
phase_access: ToolPhase[];
|
|
14
|
+
trust_levels: TrustLevel[];
|
|
15
|
+
category_access: string[] | null;
|
|
16
|
+
constraint_note?: string;
|
|
17
|
+
custom?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const BUILTIN_TOOL_SPECS: ToolSpec[];
|
|
20
|
+
/**
|
|
21
|
+
* Filter tool specs by phase, category, and trust level.
|
|
22
|
+
* Category-specific tools (e.g. Edit:docs) exclude their generic counterpart
|
|
23
|
+
* (Edit) for that category to prevent overly-broad auto-approve.
|
|
24
|
+
*/
|
|
25
|
+
export declare function filterToolSpecs(specs: ToolSpec[], phase: ToolPhase, category: string | null, trustLevel?: TrustLevel): ToolSpec[];
|
|
26
|
+
/**
|
|
27
|
+
* Collect all auto-approve patterns from a set of filtered specs.
|
|
28
|
+
*/
|
|
29
|
+
export declare function collectApprovePatterns(specs: ToolSpec[]): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Collect constraint notes from filtered specs.
|
|
32
|
+
* Returns undefined if no constraint notes exist.
|
|
33
|
+
*/
|
|
34
|
+
export declare function collectConstraintNotes(specs: ToolSpec[]): string | undefined;
|
|
35
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AACrD,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnE,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAUD,eAAO,MAAM,kBAAkB,EAAE,QAAQ,EA6KxC,CAAC;AAMF;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,EAAE,EACjB,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,GAAE,UAAsB,GACjC,QAAQ,EAAE,CAoCZ;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAUlE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,GAAG,SAAS,CAK5E"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Registry — pure types, built-in specs, and filtering algorithms.
|
|
3
|
+
*
|
|
4
|
+
* Replaces hardcoded auto-approve arrays with a queryable set of tool specs.
|
|
5
|
+
* No I/O — the ToolRegistry class in @promptwheel/mcp handles custom tool loading.
|
|
6
|
+
*/
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Built-in tool specs (reproducing current hardcoded behavior exactly)
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
const ALL_PHASES = ['SCOUT', 'PLAN', 'EXECUTE', 'QA', 'PR'];
|
|
11
|
+
const ALL_TRUST = ['safe', 'default', 'full'];
|
|
12
|
+
const DEFAULT_PLUS = ['default', 'full'];
|
|
13
|
+
export const BUILTIN_TOOL_SPECS = [
|
|
14
|
+
// Read-only tools — all phases, all trust
|
|
15
|
+
{
|
|
16
|
+
name: 'Read',
|
|
17
|
+
description: 'Read file contents',
|
|
18
|
+
approve_patterns: ['Read(*)'],
|
|
19
|
+
phase_access: ALL_PHASES,
|
|
20
|
+
trust_levels: ALL_TRUST,
|
|
21
|
+
category_access: null,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Glob',
|
|
25
|
+
description: 'Search for files by pattern',
|
|
26
|
+
approve_patterns: ['Glob(*)'],
|
|
27
|
+
phase_access: ALL_PHASES,
|
|
28
|
+
trust_levels: ALL_TRUST,
|
|
29
|
+
category_access: null,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'Grep',
|
|
33
|
+
description: 'Search file contents',
|
|
34
|
+
approve_patterns: ['Grep(*)'],
|
|
35
|
+
phase_access: ALL_PHASES,
|
|
36
|
+
trust_levels: ALL_TRUST,
|
|
37
|
+
category_access: null,
|
|
38
|
+
},
|
|
39
|
+
// Scout/Plan bash — read-only commands
|
|
40
|
+
{
|
|
41
|
+
name: 'Bash:scout',
|
|
42
|
+
description: 'Read-only shell commands for scouting',
|
|
43
|
+
approve_patterns: ['Bash(ls *)', 'Bash(find *)', 'Bash(cat *)', 'Bash(head *)', 'Bash(wc *)'],
|
|
44
|
+
phase_access: ['SCOUT', 'PLAN'],
|
|
45
|
+
trust_levels: ALL_TRUST,
|
|
46
|
+
category_access: null,
|
|
47
|
+
},
|
|
48
|
+
// Generic Edit/Write — EXECUTE only, default+ trust
|
|
49
|
+
{
|
|
50
|
+
name: 'Edit',
|
|
51
|
+
description: 'Edit files (generic)',
|
|
52
|
+
approve_patterns: ['Edit(*)'],
|
|
53
|
+
phase_access: ['EXECUTE'],
|
|
54
|
+
trust_levels: DEFAULT_PLUS,
|
|
55
|
+
category_access: null,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'Write',
|
|
59
|
+
description: 'Write files (generic)',
|
|
60
|
+
approve_patterns: ['Write(*)'],
|
|
61
|
+
phase_access: ['EXECUTE'],
|
|
62
|
+
trust_levels: DEFAULT_PLUS,
|
|
63
|
+
category_access: null,
|
|
64
|
+
},
|
|
65
|
+
// Docs Edit/Write — narrowed patterns, safe+ trust
|
|
66
|
+
{
|
|
67
|
+
name: 'Edit:docs',
|
|
68
|
+
description: 'Edit documentation files only',
|
|
69
|
+
approve_patterns: ['Edit(*.md)', 'Edit(*.mdx)', 'Edit(*.txt)', 'Edit(*.rst)'],
|
|
70
|
+
phase_access: ['EXECUTE'],
|
|
71
|
+
trust_levels: ALL_TRUST,
|
|
72
|
+
category_access: ['docs'],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'Write:docs',
|
|
76
|
+
description: 'Write documentation files only',
|
|
77
|
+
approve_patterns: ['Write(*.md)', 'Write(*.mdx)', 'Write(*.txt)', 'Write(*.rst)'],
|
|
78
|
+
phase_access: ['EXECUTE'],
|
|
79
|
+
trust_levels: ALL_TRUST,
|
|
80
|
+
category_access: ['docs'],
|
|
81
|
+
},
|
|
82
|
+
// Test Edit/Write — narrowed patterns, safe+ trust
|
|
83
|
+
{
|
|
84
|
+
name: 'Edit:test',
|
|
85
|
+
description: 'Edit test files only',
|
|
86
|
+
approve_patterns: [
|
|
87
|
+
'Edit(*.test.*)', 'Edit(*.spec.*)', 'Edit(*__tests__*)',
|
|
88
|
+
'Edit(test_*)', 'Edit(*_test.go)', 'Edit(*_test.py)', 'Edit(*Test.java)', 'Edit(*Test.kt)',
|
|
89
|
+
'Edit(*_test.exs)', 'Edit(*Tests.swift)', 'Edit(*_spec.rb)',
|
|
90
|
+
],
|
|
91
|
+
phase_access: ['EXECUTE'],
|
|
92
|
+
trust_levels: ALL_TRUST,
|
|
93
|
+
category_access: ['test'],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'Write:test',
|
|
97
|
+
description: 'Write test files only',
|
|
98
|
+
approve_patterns: [
|
|
99
|
+
'Write(*.test.*)', 'Write(*.spec.*)', 'Write(*__tests__*)',
|
|
100
|
+
'Write(test_*)', 'Write(*_test.go)', 'Write(*_test.py)', 'Write(*Test.java)', 'Write(*Test.kt)',
|
|
101
|
+
'Write(*_test.exs)', 'Write(*Tests.swift)', 'Write(*_spec.rb)',
|
|
102
|
+
],
|
|
103
|
+
phase_access: ['EXECUTE'],
|
|
104
|
+
trust_levels: ALL_TRUST,
|
|
105
|
+
category_access: ['test'],
|
|
106
|
+
},
|
|
107
|
+
// Test/build commands — EXECUTE + QA
|
|
108
|
+
{
|
|
109
|
+
name: 'Bash:test',
|
|
110
|
+
description: 'Run tests and type checks',
|
|
111
|
+
approve_patterns: [
|
|
112
|
+
// JS/TS
|
|
113
|
+
'Bash(npm test*)', 'Bash(npx vitest*)', 'Bash(npx jest*)', 'Bash(npx tsc*)',
|
|
114
|
+
'Bash(yarn test*)', 'Bash(pnpm test*)', 'Bash(bun test*)',
|
|
115
|
+
// Python
|
|
116
|
+
'Bash(pytest*)', 'Bash(python -m pytest*)', 'Bash(tox*)', 'Bash(python -m unittest*)',
|
|
117
|
+
// Rust
|
|
118
|
+
'Bash(cargo test*)', 'Bash(cargo check*)', 'Bash(cargo clippy*)',
|
|
119
|
+
// Go
|
|
120
|
+
'Bash(go test*)', 'Bash(go vet*)',
|
|
121
|
+
// Java/Kotlin
|
|
122
|
+
'Bash(mvn test*)', 'Bash(./gradlew test*)', 'Bash(gradle test*)',
|
|
123
|
+
// Ruby
|
|
124
|
+
'Bash(bundle exec rspec*)', 'Bash(bundle exec rake test*)',
|
|
125
|
+
// Elixir
|
|
126
|
+
'Bash(mix test*)',
|
|
127
|
+
// .NET
|
|
128
|
+
'Bash(dotnet test*)',
|
|
129
|
+
// PHP
|
|
130
|
+
'Bash(./vendor/bin/phpunit*)', 'Bash(phpunit*)',
|
|
131
|
+
// Swift
|
|
132
|
+
'Bash(swift test*)',
|
|
133
|
+
// Make
|
|
134
|
+
'Bash(make test*)', 'Bash(make check*)',
|
|
135
|
+
],
|
|
136
|
+
phase_access: ['EXECUTE', 'QA'],
|
|
137
|
+
trust_levels: ALL_TRUST,
|
|
138
|
+
category_access: null,
|
|
139
|
+
},
|
|
140
|
+
// Git status — EXECUTE + QA
|
|
141
|
+
{
|
|
142
|
+
name: 'Bash:git-status',
|
|
143
|
+
description: 'Git diff and status commands',
|
|
144
|
+
approve_patterns: ['Bash(git diff*)', 'Bash(git status*)'],
|
|
145
|
+
phase_access: ['EXECUTE', 'QA'],
|
|
146
|
+
trust_levels: ALL_TRUST,
|
|
147
|
+
category_access: null,
|
|
148
|
+
},
|
|
149
|
+
// Git operations — PR phase
|
|
150
|
+
{
|
|
151
|
+
name: 'Bash:git-ops',
|
|
152
|
+
description: 'Git operations for PR creation',
|
|
153
|
+
approve_patterns: ['Bash(git *)'],
|
|
154
|
+
phase_access: ['PR'],
|
|
155
|
+
trust_levels: DEFAULT_PLUS,
|
|
156
|
+
category_access: null,
|
|
157
|
+
},
|
|
158
|
+
// GitHub CLI — PR phase
|
|
159
|
+
{
|
|
160
|
+
name: 'Bash:gh',
|
|
161
|
+
description: 'GitHub CLI for PR creation',
|
|
162
|
+
approve_patterns: ['Bash(gh pr *)'],
|
|
163
|
+
phase_access: ['PR'],
|
|
164
|
+
trust_levels: DEFAULT_PLUS,
|
|
165
|
+
category_access: null,
|
|
166
|
+
},
|
|
167
|
+
// Security constraint (no patterns, just a constraint note)
|
|
168
|
+
{
|
|
169
|
+
name: 'constraint:security',
|
|
170
|
+
description: 'Security ticket constraints',
|
|
171
|
+
approve_patterns: [],
|
|
172
|
+
phase_access: ['EXECUTE'],
|
|
173
|
+
trust_levels: ALL_TRUST,
|
|
174
|
+
category_access: ['security'],
|
|
175
|
+
constraint_note: 'This is a **security** ticket. You have full read/edit access but MUST NOT install new dependencies (`npm install`, `pip install`, `cargo add`, `go get`, `bundle add`, `composer require`, etc.). Do NOT run arbitrary shell commands beyond testing and type-checking.',
|
|
176
|
+
},
|
|
177
|
+
];
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
// Filtering
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
/**
|
|
182
|
+
* Filter tool specs by phase, category, and trust level.
|
|
183
|
+
* Category-specific tools (e.g. Edit:docs) exclude their generic counterpart
|
|
184
|
+
* (Edit) for that category to prevent overly-broad auto-approve.
|
|
185
|
+
*/
|
|
186
|
+
export function filterToolSpecs(specs, phase, category, trustLevel = 'default') {
|
|
187
|
+
const trustOrder = { safe: 0, default: 1, full: 2 };
|
|
188
|
+
const requestedLevel = trustOrder[trustLevel];
|
|
189
|
+
// First pass: find which generic tools have category-specific overrides
|
|
190
|
+
const categoryOverrides = new Set();
|
|
191
|
+
for (const spec of specs) {
|
|
192
|
+
if (spec.category_access !== null && category && spec.category_access.includes(category)) {
|
|
193
|
+
// e.g., Edit:docs → overrides 'Edit'
|
|
194
|
+
const baseName = spec.name.split(':')[0];
|
|
195
|
+
categoryOverrides.add(baseName);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return specs.filter(spec => {
|
|
199
|
+
// Phase check
|
|
200
|
+
if (!spec.phase_access.includes(phase))
|
|
201
|
+
return false;
|
|
202
|
+
// Trust level check
|
|
203
|
+
const minLevel = trustOrder[spec.trust_levels[0]];
|
|
204
|
+
if (requestedLevel < minLevel)
|
|
205
|
+
return false;
|
|
206
|
+
// Category check
|
|
207
|
+
if (spec.category_access !== null) {
|
|
208
|
+
if (!category || !spec.category_access.includes(category))
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
// Generic tool — exclude if a category-specific override exists
|
|
213
|
+
const baseName = spec.name.split(':')[0];
|
|
214
|
+
if (categoryOverrides.has(baseName) && !spec.name.includes(':')) {
|
|
215
|
+
// Only exclude Edit/Write, not Read/Glob/Grep/Bash
|
|
216
|
+
if (baseName === 'Edit' || baseName === 'Write')
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return true;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Collect all auto-approve patterns from a set of filtered specs.
|
|
225
|
+
*/
|
|
226
|
+
export function collectApprovePatterns(specs) {
|
|
227
|
+
const patterns = [];
|
|
228
|
+
for (const spec of specs) {
|
|
229
|
+
for (const p of spec.approve_patterns) {
|
|
230
|
+
if (!patterns.includes(p)) {
|
|
231
|
+
patterns.push(p);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return patterns;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Collect constraint notes from filtered specs.
|
|
239
|
+
* Returns undefined if no constraint notes exist.
|
|
240
|
+
*/
|
|
241
|
+
export function collectConstraintNotes(specs) {
|
|
242
|
+
const notes = specs
|
|
243
|
+
.filter(s => s.constraint_note)
|
|
244
|
+
.map(s => s.constraint_note);
|
|
245
|
+
return notes.length > 0 ? notes.join('\n\n') : undefined;
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"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"}
|