@promptwheel/mcp 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/README.md +178 -0
- package/dist/advance-helpers.d.ts +27 -0
- package/dist/advance-helpers.d.ts.map +1 -0
- package/dist/advance-helpers.js +127 -0
- package/dist/advance-helpers.js.map +1 -0
- package/dist/advance-prompts.d.ts +48 -0
- package/dist/advance-prompts.d.ts.map +1 -0
- package/dist/advance-prompts.js +420 -0
- package/dist/advance-prompts.js.map +1 -0
- package/dist/advance.d.ts +30 -0
- package/dist/advance.d.ts.map +1 -0
- package/dist/advance.js +752 -0
- package/dist/advance.js.map +1 -0
- package/dist/codebase-index.d.ts +5 -0
- package/dist/codebase-index.d.ts.map +1 -0
- package/dist/codebase-index.js +5 -0
- package/dist/codebase-index.js.map +1 -0
- package/dist/dedup-memory.d.ts +30 -0
- package/dist/dedup-memory.d.ts.map +1 -0
- package/dist/dedup-memory.js +76 -0
- package/dist/dedup-memory.js.map +1 -0
- package/dist/direct-client.d.ts +57 -0
- package/dist/direct-client.d.ts.map +1 -0
- package/dist/direct-client.js +92 -0
- package/dist/direct-client.js.map +1 -0
- package/dist/event-handlers-qa.d.ts +5 -0
- package/dist/event-handlers-qa.d.ts.map +1 -0
- package/dist/event-handlers-qa.js +186 -0
- package/dist/event-handlers-qa.js.map +1 -0
- package/dist/event-handlers-scout.d.ts +5 -0
- package/dist/event-handlers-scout.d.ts.map +1 -0
- package/dist/event-handlers-scout.js +270 -0
- package/dist/event-handlers-scout.js.map +1 -0
- package/dist/event-handlers-ticket.d.ts +5 -0
- package/dist/event-handlers-ticket.d.ts.map +1 -0
- package/dist/event-handlers-ticket.js +232 -0
- package/dist/event-handlers-ticket.js.map +1 -0
- package/dist/event-helpers.d.ts +46 -0
- package/dist/event-helpers.d.ts.map +1 -0
- package/dist/event-helpers.js +125 -0
- package/dist/event-helpers.js.map +1 -0
- package/dist/event-processor.d.ts +15 -0
- package/dist/event-processor.d.ts.map +1 -0
- package/dist/event-processor.js +111 -0
- package/dist/event-processor.js.map +1 -0
- package/dist/formulas.d.ts +27 -0
- package/dist/formulas.d.ts.map +1 -0
- package/dist/formulas.js +109 -0
- package/dist/formulas.js.map +1 -0
- package/dist/guidelines.d.ts +16 -0
- package/dist/guidelines.d.ts.map +1 -0
- package/dist/guidelines.js +44 -0
- package/dist/guidelines.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/learnings.d.ts +42 -0
- package/dist/learnings.d.ts.map +1 -0
- package/dist/learnings.js +117 -0
- package/dist/learnings.js.map +1 -0
- package/dist/project-metadata.d.ts +34 -0
- package/dist/project-metadata.d.ts.map +1 -0
- package/dist/project-metadata.js +617 -0
- package/dist/project-metadata.js.map +1 -0
- package/dist/proposals.d.ts +23 -0
- package/dist/proposals.d.ts.map +1 -0
- package/dist/proposals.js +201 -0
- package/dist/proposals.js.map +1 -0
- package/dist/qa-stats.d.ts +51 -0
- package/dist/qa-stats.d.ts.map +1 -0
- package/dist/qa-stats.js +121 -0
- package/dist/qa-stats.js.map +1 -0
- package/dist/run-manager.d.ts +97 -0
- package/dist/run-manager.d.ts.map +1 -0
- package/dist/run-manager.js +583 -0
- package/dist/run-manager.js.map +1 -0
- package/dist/run-state-bridge.d.ts +13 -0
- package/dist/run-state-bridge.d.ts.map +1 -0
- package/dist/run-state-bridge.js +101 -0
- package/dist/run-state-bridge.js.map +1 -0
- package/dist/scope-policy.d.ts +83 -0
- package/dist/scope-policy.d.ts.map +1 -0
- package/dist/scope-policy.js +278 -0
- package/dist/scope-policy.js.map +1 -0
- package/dist/server.d.ts +18 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +35 -0
- package/dist/server.js.map +1 -0
- package/dist/spindle.d.ts +41 -0
- package/dist/spindle.d.ts.map +1 -0
- package/dist/spindle.js +230 -0
- package/dist/spindle.js.map +1 -0
- package/dist/state.d.ts +36 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +50 -0
- package/dist/state.js.map +1 -0
- package/dist/ticket-worker.d.ts +37 -0
- package/dist/ticket-worker.d.ts.map +1 -0
- package/dist/ticket-worker.js +527 -0
- package/dist/ticket-worker.js.map +1 -0
- package/dist/tool-registry.d.ts +35 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +129 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/execute.d.ts +17 -0
- package/dist/tools/execute.d.ts.map +1 -0
- package/dist/tools/execute.js +418 -0
- package/dist/tools/execute.js.map +1 -0
- package/dist/tools/git.d.ts +7 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +98 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/intelligence.d.ts +10 -0
- package/dist/tools/intelligence.d.ts.map +1 -0
- package/dist/tools/intelligence.js +432 -0
- package/dist/tools/intelligence.js.map +1 -0
- package/dist/tools/session.d.ts +7 -0
- package/dist/tools/session.d.ts.map +1 -0
- package/dist/tools/session.js +533 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/tools/trajectory.d.ts +10 -0
- package/dist/tools/trajectory.d.ts.map +1 -0
- package/dist/tools/trajectory.js +374 -0
- package/dist/tools/trajectory.js.map +1 -0
- package/dist/trajectory-io.d.ts +21 -0
- package/dist/trajectory-io.d.ts.map +1 -0
- package/dist/trajectory-io.js +105 -0
- package/dist/trajectory-io.js.map +1 -0
- package/dist/types.d.ts +229 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proposal filtering, dedup, scoring, and ticket creation.
|
|
3
|
+
*
|
|
4
|
+
* Pure algorithms (schema validation, normalization, scoring, balancing,
|
|
5
|
+
* review prompt, description formatting) live in @promptwheel/core/proposals/shared.
|
|
6
|
+
* This file wraps them with database I/O, event logging, and MCP-specific
|
|
7
|
+
* dedup and deferred-proposal management.
|
|
8
|
+
*/
|
|
9
|
+
import type { DatabaseAdapter } from '@promptwheel/core';
|
|
10
|
+
import { type RawProposal, type ValidatedProposal } from '@promptwheel/core/proposals/shared';
|
|
11
|
+
import { RunManager } from './run-manager.js';
|
|
12
|
+
export type { RawProposal, ValidatedProposal, ReviewedProposal } from '@promptwheel/core/proposals/shared';
|
|
13
|
+
export { validateProposalSchema, normalizeProposal, buildProposalReviewPrompt, parseReviewedProposals, applyReviewToProposals, scoreAndRank, balanceProposals, formatProposalDescription, computePriority, PROPOSALS_DEFAULTS, } from '@promptwheel/core/proposals/shared';
|
|
14
|
+
export interface FilterResult {
|
|
15
|
+
accepted: ValidatedProposal[];
|
|
16
|
+
rejected: Array<{
|
|
17
|
+
proposal: RawProposal;
|
|
18
|
+
reason: string;
|
|
19
|
+
}>;
|
|
20
|
+
created_ticket_ids: string[];
|
|
21
|
+
}
|
|
22
|
+
export declare function filterAndCreateTickets(run: RunManager, db: DatabaseAdapter, rawProposals: RawProposal[]): Promise<FilterResult>;
|
|
23
|
+
//# sourceMappingURL=proposals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposals.d.ts","sourceRoot":"","sources":["../src/proposals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,mBAAmB,CAAC;AAGzE,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EAQvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAI9C,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3G,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,yBAAyB,EACzB,eAAe,EACf,kBAAkB,GACnB,MAAM,oCAAoC,CAAC;AAM5C,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAMD,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,eAAe,EACnB,YAAY,EAAE,WAAW,EAAE,GAC1B,OAAO,CAAC,YAAY,CAAC,CA0MvB"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proposal filtering, dedup, scoring, and ticket creation.
|
|
3
|
+
*
|
|
4
|
+
* Pure algorithms (schema validation, normalization, scoring, balancing,
|
|
5
|
+
* review prompt, description formatting) live in @promptwheel/core/proposals/shared.
|
|
6
|
+
* This file wraps them with database I/O, event logging, and MCP-specific
|
|
7
|
+
* dedup and deferred-proposal management.
|
|
8
|
+
*/
|
|
9
|
+
import { repos } from '@promptwheel/core';
|
|
10
|
+
import { bigramSimilarity } from '@promptwheel/core/dedup/shared';
|
|
11
|
+
import { validateProposalSchema, normalizeProposal, scoreAndRank, balanceProposals, formatProposalDescription, computePriority, PROPOSALS_DEFAULTS, } from '@promptwheel/core/proposals/shared';
|
|
12
|
+
import { minimatch } from 'minimatch';
|
|
13
|
+
import { recordDedupEntries } from './dedup-memory.js';
|
|
14
|
+
export { validateProposalSchema, normalizeProposal, buildProposalReviewPrompt, parseReviewedProposals, applyReviewToProposals, scoreAndRank, balanceProposals, formatProposalDescription, computePriority, PROPOSALS_DEFAULTS, } from '@promptwheel/core/proposals/shared';
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Main entry: filter + create tickets
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
export async function filterAndCreateTickets(run, db, rawProposals) {
|
|
19
|
+
const s = run.require();
|
|
20
|
+
const rejected = [];
|
|
21
|
+
// Step 0: Re-promote deferred proposals that now match the current scope
|
|
22
|
+
const currentScope = s.scope || '';
|
|
23
|
+
const currentIsCatchAll = !currentScope || currentScope === '**' || currentScope === '*';
|
|
24
|
+
const stillDeferred = [];
|
|
25
|
+
for (const dp of s.deferred_proposals) {
|
|
26
|
+
const files = dp.files.length > 0 ? dp.files : dp.allowed_paths;
|
|
27
|
+
const nowInScope = currentIsCatchAll || files.length === 0 || files.every(f => minimatch(f, currentScope, { dot: true }));
|
|
28
|
+
if (nowInScope) {
|
|
29
|
+
rawProposals.push({
|
|
30
|
+
category: dp.category,
|
|
31
|
+
title: dp.title,
|
|
32
|
+
description: dp.description,
|
|
33
|
+
files: dp.files,
|
|
34
|
+
allowed_paths: dp.allowed_paths,
|
|
35
|
+
confidence: dp.confidence,
|
|
36
|
+
impact_score: dp.impact_score,
|
|
37
|
+
verification_commands: dp.verification_commands,
|
|
38
|
+
acceptance_criteria: dp.acceptance_criteria,
|
|
39
|
+
risk: dp.risk,
|
|
40
|
+
touched_files_estimate: dp.touched_files_estimate,
|
|
41
|
+
rollback_note: dp.rollback_note,
|
|
42
|
+
rationale: dp.rationale,
|
|
43
|
+
estimated_complexity: dp.estimated_complexity,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
stillDeferred.push(dp);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
s.deferred_proposals = stillDeferred;
|
|
51
|
+
// Step 1: Schema validation
|
|
52
|
+
const valid = [];
|
|
53
|
+
for (const raw of rawProposals) {
|
|
54
|
+
const missing = validateProposalSchema(raw);
|
|
55
|
+
if (missing) {
|
|
56
|
+
rejected.push({ proposal: raw, reason: `Missing fields: ${missing}` });
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
valid.push(normalizeProposal(raw));
|
|
60
|
+
}
|
|
61
|
+
// Step 2a: Reject fundamentally flawed proposals (confidence=0 from adversarial review)
|
|
62
|
+
const afterConfidence = valid.filter(p => {
|
|
63
|
+
if (p.confidence <= 0) {
|
|
64
|
+
rejected.push({ proposal: p, reason: 'Rejected by adversarial review (confidence=0)' });
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
});
|
|
69
|
+
// Step 2b: Impact score filter
|
|
70
|
+
const minImpact = s.min_impact_score ?? PROPOSALS_DEFAULTS.DEFAULT_MIN_IMPACT;
|
|
71
|
+
const afterImpact = afterConfidence.filter(p => {
|
|
72
|
+
const impact = p.impact_score ?? PROPOSALS_DEFAULTS.DEFAULT_IMPACT;
|
|
73
|
+
if (impact < minImpact) {
|
|
74
|
+
rejected.push({ proposal: p, reason: `Impact score ${impact} below min ${minImpact}` });
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
});
|
|
79
|
+
// Step 3: Category trust ladder
|
|
80
|
+
const allowedCategories = new Set(s.categories);
|
|
81
|
+
const afterCategory = afterImpact.filter(p => {
|
|
82
|
+
if (!allowedCategories.has(p.category)) {
|
|
83
|
+
rejected.push({ proposal: p, reason: `Category '${p.category}' not in trust ladder` });
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
});
|
|
88
|
+
// Step 3b: Scope filter — defer proposals whose files fall outside session scope
|
|
89
|
+
const sessionScope = s.scope || '';
|
|
90
|
+
const isCatchAll = !sessionScope || sessionScope === '**' || sessionScope === '*';
|
|
91
|
+
const afterScope = isCatchAll
|
|
92
|
+
? afterCategory
|
|
93
|
+
: afterCategory.filter(p => {
|
|
94
|
+
const files = p.files.length > 0 ? p.files : p.allowed_paths;
|
|
95
|
+
const allInScope = files.length === 0 || files.every(f => minimatch(f, sessionScope, { dot: true }));
|
|
96
|
+
if (!allInScope) {
|
|
97
|
+
s.deferred_proposals.push({
|
|
98
|
+
category: p.category,
|
|
99
|
+
title: p.title,
|
|
100
|
+
description: p.description,
|
|
101
|
+
files: p.files,
|
|
102
|
+
allowed_paths: p.allowed_paths,
|
|
103
|
+
confidence: p.confidence,
|
|
104
|
+
impact_score: p.impact_score,
|
|
105
|
+
original_scope: s.scope,
|
|
106
|
+
verification_commands: p.verification_commands,
|
|
107
|
+
acceptance_criteria: p.acceptance_criteria,
|
|
108
|
+
risk: p.risk,
|
|
109
|
+
touched_files_estimate: p.touched_files_estimate,
|
|
110
|
+
rollback_note: p.rollback_note,
|
|
111
|
+
rationale: p.rationale,
|
|
112
|
+
estimated_complexity: p.estimated_complexity,
|
|
113
|
+
});
|
|
114
|
+
rejected.push({ proposal: p, reason: `Deferred (files outside scope '${s.scope}'): ${files.filter(f => !minimatch(f, sessionScope, { dot: true })).join(', ')}` });
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
return true;
|
|
118
|
+
});
|
|
119
|
+
// Cap deferred proposals to prevent unbounded growth
|
|
120
|
+
if (s.deferred_proposals.length > PROPOSALS_DEFAULTS.MAX_DEFERRED) {
|
|
121
|
+
s.deferred_proposals.sort((a, b) => b.confidence - a.confidence);
|
|
122
|
+
s.deferred_proposals = s.deferred_proposals.slice(0, PROPOSALS_DEFAULTS.MAX_DEFERRED);
|
|
123
|
+
}
|
|
124
|
+
// Step 4: Dedup against existing tickets (title similarity via bigrams)
|
|
125
|
+
const existingTickets = await repos.tickets.listByProject(db, s.project_id, {
|
|
126
|
+
status: ['ready', 'in_progress'],
|
|
127
|
+
});
|
|
128
|
+
const existingTitles = existingTickets.map(t => t.title);
|
|
129
|
+
const afterDedup = afterScope.filter(p => {
|
|
130
|
+
const isDupe = existingTitles.some(t => bigramSimilarity(t, p.title) >= PROPOSALS_DEFAULTS.DEDUP_THRESHOLD);
|
|
131
|
+
if (isDupe) {
|
|
132
|
+
rejected.push({ proposal: p, reason: `Duplicate of existing ticket (title similarity >= ${PROPOSALS_DEFAULTS.DEDUP_THRESHOLD})` });
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
return true;
|
|
136
|
+
});
|
|
137
|
+
// Also dedup within the batch
|
|
138
|
+
const uniqueByTitle = [];
|
|
139
|
+
for (const p of afterDedup) {
|
|
140
|
+
const isDupeInBatch = uniqueByTitle.some(q => bigramSimilarity(q.title, p.title) >= PROPOSALS_DEFAULTS.DEDUP_THRESHOLD);
|
|
141
|
+
if (isDupeInBatch) {
|
|
142
|
+
rejected.push({ proposal: p, reason: `Duplicate within batch (title similarity >= ${PROPOSALS_DEFAULTS.DEDUP_THRESHOLD})` });
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
uniqueByTitle.push(p);
|
|
146
|
+
}
|
|
147
|
+
// Step 5: Score, rank, and cap
|
|
148
|
+
const ranked = scoreAndRank(uniqueByTitle, s.max_proposals_per_scout);
|
|
149
|
+
// Step 5b: Balance test vs non-test proposals
|
|
150
|
+
const accepted = balanceProposals(ranked, PROPOSALS_DEFAULTS.MAX_TEST_RATIO);
|
|
151
|
+
// Step 6: Create tickets
|
|
152
|
+
const ticketInputs = accepted.map(p => ({
|
|
153
|
+
projectId: s.project_id,
|
|
154
|
+
title: p.title,
|
|
155
|
+
description: formatProposalDescription(p),
|
|
156
|
+
status: 'ready',
|
|
157
|
+
priority: computePriority(p.impact_score ?? PROPOSALS_DEFAULTS.DEFAULT_IMPACT, p.confidence),
|
|
158
|
+
category: p.category,
|
|
159
|
+
allowedPaths: p.allowed_paths,
|
|
160
|
+
verificationCommands: p.verification_commands,
|
|
161
|
+
metadata: {
|
|
162
|
+
scoutConfidence: p.confidence,
|
|
163
|
+
estimatedComplexity: p.estimated_complexity,
|
|
164
|
+
},
|
|
165
|
+
}));
|
|
166
|
+
let createdIds = [];
|
|
167
|
+
if (ticketInputs.length > 0) {
|
|
168
|
+
const created = await repos.tickets.createMany(db, ticketInputs);
|
|
169
|
+
createdIds = created.map(t => t.id);
|
|
170
|
+
run.appendEvent('TICKETS_CREATED', {
|
|
171
|
+
count: created.length,
|
|
172
|
+
ids: createdIds,
|
|
173
|
+
titles: accepted.map(p => p.title),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
run.appendEvent('PROPOSALS_FILTERED', {
|
|
177
|
+
submitted: rawProposals.length,
|
|
178
|
+
valid: valid.length,
|
|
179
|
+
after_confidence: afterConfidence.length,
|
|
180
|
+
after_impact: afterImpact.length,
|
|
181
|
+
after_category: afterCategory.length,
|
|
182
|
+
after_dedup: uniqueByTitle.length,
|
|
183
|
+
accepted: accepted.length,
|
|
184
|
+
rejected_count: rejected.length,
|
|
185
|
+
});
|
|
186
|
+
// Record dedup memory — accepted titles as completed, duplicate rejections as attempted
|
|
187
|
+
const dedupEntries = [];
|
|
188
|
+
for (const p of accepted) {
|
|
189
|
+
dedupEntries.push({ title: p.title, completed: true });
|
|
190
|
+
}
|
|
191
|
+
for (const r of rejected) {
|
|
192
|
+
if (r.reason.includes('Duplicate') && r.proposal.title) {
|
|
193
|
+
dedupEntries.push({ title: r.proposal.title, completed: false });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (dedupEntries.length > 0) {
|
|
197
|
+
recordDedupEntries(run.rootPath, dedupEntries);
|
|
198
|
+
}
|
|
199
|
+
return { accepted, rejected, created_ticket_ids: createdIds };
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=proposals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposals.js","sourceRoot":"","sources":["../src/proposals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-command QA statistics tracking for the MCP package.
|
|
3
|
+
*
|
|
4
|
+
* Minimal subset copied from CLI's `packages/cli/src/lib/qa-stats.ts`.
|
|
5
|
+
* Provides persistence to `.promptwheel/qa-stats.json` for QA command
|
|
6
|
+
* result tracking when running through the plugin/MCP path.
|
|
7
|
+
*/
|
|
8
|
+
export interface QaCommandStats {
|
|
9
|
+
name: string;
|
|
10
|
+
totalRuns: number;
|
|
11
|
+
successes: number;
|
|
12
|
+
failures: number;
|
|
13
|
+
timeouts: number;
|
|
14
|
+
preExistingSkips: number;
|
|
15
|
+
totalDurationMs: number;
|
|
16
|
+
avgDurationMs: number;
|
|
17
|
+
lastRunAt: number;
|
|
18
|
+
consecutiveFailures: number;
|
|
19
|
+
consecutiveTimeouts: number;
|
|
20
|
+
/** Ring buffer of recent baseline results (max 10) */
|
|
21
|
+
recentBaselineResults: boolean[];
|
|
22
|
+
}
|
|
23
|
+
export interface DisabledCommand {
|
|
24
|
+
name: string;
|
|
25
|
+
reason: string;
|
|
26
|
+
disabledAt: number;
|
|
27
|
+
}
|
|
28
|
+
export interface QaStatsStore {
|
|
29
|
+
commands: Record<string, QaCommandStats>;
|
|
30
|
+
lastUpdated: number;
|
|
31
|
+
/** Commands disabled by auto-tune, persisted across restarts */
|
|
32
|
+
disabledCommands: DisabledCommand[];
|
|
33
|
+
/** Quality rate when calibrateConfidence last adjusted (hysteresis) */
|
|
34
|
+
lastCalibratedQualityRate: number | null;
|
|
35
|
+
}
|
|
36
|
+
export declare function loadQaStats(projectRoot: string): QaStatsStore;
|
|
37
|
+
export declare function saveQaStats(projectRoot: string, store: QaStatsStore): void;
|
|
38
|
+
/**
|
|
39
|
+
* Record the result of a QA command execution.
|
|
40
|
+
*/
|
|
41
|
+
export declare function recordQaCommandResult(projectRoot: string, name: string, result: {
|
|
42
|
+
passed: boolean;
|
|
43
|
+
durationMs: number;
|
|
44
|
+
timedOut: boolean;
|
|
45
|
+
skippedPreExisting: boolean;
|
|
46
|
+
}): void;
|
|
47
|
+
/**
|
|
48
|
+
* Record a baseline check result (push to ring buffer).
|
|
49
|
+
*/
|
|
50
|
+
export declare function recordBaselineResult(projectRoot: string, name: string, passed: boolean): void;
|
|
51
|
+
//# sourceMappingURL=qa-stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-stats.d.ts","sourceRoot":"","sources":["../src/qa-stats.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sDAAsD;IACtD,qBAAqB,EAAE,OAAO,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,uEAAuE;IACvE,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAiBD,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAkB7D;AAED,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAU1E;AA8BD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE;IACN,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,kBAAkB,EAAE,OAAO,CAAC;CAC7B,GACA,IAAI,CA6BN;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,GACd,IAAI,CAQN"}
|
package/dist/qa-stats.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-command QA statistics tracking for the MCP package.
|
|
3
|
+
*
|
|
4
|
+
* Minimal subset copied from CLI's `packages/cli/src/lib/qa-stats.ts`.
|
|
5
|
+
* Provides persistence to `.promptwheel/qa-stats.json` for QA command
|
|
6
|
+
* result tracking when running through the plugin/MCP path.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'node:fs';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Constants
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
const QA_STATS_FILE = 'qa-stats.json';
|
|
14
|
+
const MAX_BASELINE_RING = 10;
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// File I/O
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
function statsPath(projectRoot) {
|
|
19
|
+
return path.join(projectRoot, '.promptwheel', QA_STATS_FILE);
|
|
20
|
+
}
|
|
21
|
+
export function loadQaStats(projectRoot) {
|
|
22
|
+
const fp = statsPath(projectRoot);
|
|
23
|
+
if (!fs.existsSync(fp)) {
|
|
24
|
+
return { commands: {}, lastUpdated: 0, disabledCommands: [], lastCalibratedQualityRate: null };
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const raw = fs.readFileSync(fp, 'utf8');
|
|
28
|
+
const parsed = JSON.parse(raw);
|
|
29
|
+
return {
|
|
30
|
+
commands: parsed.commands ?? {},
|
|
31
|
+
lastUpdated: parsed.lastUpdated ?? 0,
|
|
32
|
+
disabledCommands: Array.isArray(parsed.disabledCommands) ? parsed.disabledCommands : [],
|
|
33
|
+
lastCalibratedQualityRate: parsed.lastCalibratedQualityRate ?? null,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
console.warn(`[promptwheel] failed to parse qa-stats.json: ${err instanceof Error ? err.message : String(err)}`);
|
|
38
|
+
return { commands: {}, lastUpdated: 0, disabledCommands: [], lastCalibratedQualityRate: null };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function saveQaStats(projectRoot, store) {
|
|
42
|
+
const fp = statsPath(projectRoot);
|
|
43
|
+
const dir = path.dirname(fp);
|
|
44
|
+
if (!fs.existsSync(dir)) {
|
|
45
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
46
|
+
}
|
|
47
|
+
store.lastUpdated = Date.now();
|
|
48
|
+
const tmp = fp + '.tmp';
|
|
49
|
+
fs.writeFileSync(tmp, JSON.stringify(store, null, 2) + '\n', 'utf8');
|
|
50
|
+
fs.renameSync(tmp, fp);
|
|
51
|
+
}
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Helpers
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
function ensureCommand(store, name) {
|
|
56
|
+
if (!store.commands[name]) {
|
|
57
|
+
store.commands[name] = {
|
|
58
|
+
name,
|
|
59
|
+
totalRuns: 0,
|
|
60
|
+
successes: 0,
|
|
61
|
+
failures: 0,
|
|
62
|
+
timeouts: 0,
|
|
63
|
+
preExistingSkips: 0,
|
|
64
|
+
totalDurationMs: 0,
|
|
65
|
+
avgDurationMs: 0,
|
|
66
|
+
lastRunAt: 0,
|
|
67
|
+
consecutiveFailures: 0,
|
|
68
|
+
consecutiveTimeouts: 0,
|
|
69
|
+
recentBaselineResults: [],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return store.commands[name];
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Core API
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
/**
|
|
78
|
+
* Record the result of a QA command execution.
|
|
79
|
+
*/
|
|
80
|
+
export function recordQaCommandResult(projectRoot, name, result) {
|
|
81
|
+
const store = loadQaStats(projectRoot);
|
|
82
|
+
const stats = ensureCommand(store, name);
|
|
83
|
+
stats.totalRuns++;
|
|
84
|
+
stats.lastRunAt = Date.now();
|
|
85
|
+
if (result.skippedPreExisting) {
|
|
86
|
+
stats.preExistingSkips++;
|
|
87
|
+
}
|
|
88
|
+
else if (result.timedOut) {
|
|
89
|
+
stats.timeouts++;
|
|
90
|
+
stats.consecutiveTimeouts++;
|
|
91
|
+
stats.consecutiveFailures++;
|
|
92
|
+
}
|
|
93
|
+
else if (result.passed) {
|
|
94
|
+
stats.successes++;
|
|
95
|
+
stats.consecutiveFailures = 0;
|
|
96
|
+
stats.consecutiveTimeouts = 0;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
stats.failures++;
|
|
100
|
+
stats.consecutiveFailures++;
|
|
101
|
+
stats.consecutiveTimeouts = 0;
|
|
102
|
+
}
|
|
103
|
+
stats.totalDurationMs += result.durationMs;
|
|
104
|
+
stats.avgDurationMs = stats.totalRuns > 0
|
|
105
|
+
? Math.round(stats.totalDurationMs / stats.totalRuns)
|
|
106
|
+
: 0;
|
|
107
|
+
saveQaStats(projectRoot, store);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Record a baseline check result (push to ring buffer).
|
|
111
|
+
*/
|
|
112
|
+
export function recordBaselineResult(projectRoot, name, passed) {
|
|
113
|
+
const store = loadQaStats(projectRoot);
|
|
114
|
+
const stats = ensureCommand(store, name);
|
|
115
|
+
stats.recentBaselineResults.push(passed);
|
|
116
|
+
if (stats.recentBaselineResults.length > MAX_BASELINE_RING) {
|
|
117
|
+
stats.recentBaselineResults.shift();
|
|
118
|
+
}
|
|
119
|
+
saveQaStats(projectRoot, store);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=qa-stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-stats.js","sourceRoot":"","sources":["../src/qa-stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run Manager — creates and manages run folders on disk.
|
|
3
|
+
*
|
|
4
|
+
* Each run lives at `.promptwheel/runs/<run_id>/` and contains:
|
|
5
|
+
* - state.json — current RunState (overwritten on every change)
|
|
6
|
+
* - events.ndjson — append-only event log
|
|
7
|
+
* - diffs/ — patch files per step
|
|
8
|
+
* - artifacts/ — QA logs, scout proposals, etc.
|
|
9
|
+
*/
|
|
10
|
+
import type { RunState, EventType, Phase, SessionConfig, TicketWorkerState } from './types.js';
|
|
11
|
+
export declare class RunManager {
|
|
12
|
+
private readonly projectPath;
|
|
13
|
+
private state;
|
|
14
|
+
private runDir;
|
|
15
|
+
private eventsPath;
|
|
16
|
+
private learningsDecayRate?;
|
|
17
|
+
constructor(projectPath: string);
|
|
18
|
+
/** The project root path */
|
|
19
|
+
get rootPath(): string;
|
|
20
|
+
/** The base .promptwheel directory */
|
|
21
|
+
private get bsDir();
|
|
22
|
+
/** Create a new run, write initial state.json and SESSION_START event */
|
|
23
|
+
create(projectId: string, config: SessionConfig): RunState;
|
|
24
|
+
/** Get current state or throw */
|
|
25
|
+
require(): RunState;
|
|
26
|
+
/** Get current state (may be null) */
|
|
27
|
+
get current(): RunState | null;
|
|
28
|
+
/** Get run directory path */
|
|
29
|
+
get dir(): string | null;
|
|
30
|
+
/** Transition to a new phase */
|
|
31
|
+
setPhase(phase: Phase): void;
|
|
32
|
+
/** Increment step counter (called on each advance) */
|
|
33
|
+
incrementStep(): void;
|
|
34
|
+
/** Assign a ticket as current work */
|
|
35
|
+
assignTicket(ticketId: string): void;
|
|
36
|
+
/** Mark current ticket completed */
|
|
37
|
+
completeTicket(): void;
|
|
38
|
+
/** Mark current ticket failed */
|
|
39
|
+
failTicket(reason: string): void;
|
|
40
|
+
/** Reset spindle and ticket state for recovery after a spindle abort */
|
|
41
|
+
resetForSpindleRecovery(): void;
|
|
42
|
+
/** Add a hint */
|
|
43
|
+
addHint(hint: string): void;
|
|
44
|
+
/** Consume and return all pending hints */
|
|
45
|
+
consumeHints(): string[];
|
|
46
|
+
/** End the run */
|
|
47
|
+
end(): RunState;
|
|
48
|
+
/** Initialize a ticket worker entry */
|
|
49
|
+
initTicketWorker(ticketId: string, _ticket: {
|
|
50
|
+
title: string;
|
|
51
|
+
}): void;
|
|
52
|
+
/** Get a ticket worker state */
|
|
53
|
+
getTicketWorker(ticketId: string): TicketWorkerState | null;
|
|
54
|
+
/** Update a ticket worker state */
|
|
55
|
+
updateTicketWorker(ticketId: string, updates: Partial<TicketWorkerState>): void;
|
|
56
|
+
/** Complete a ticket worker — increment counters and remove from workers */
|
|
57
|
+
completeTicketWorker(ticketId: string): void;
|
|
58
|
+
/** Fail a ticket worker — increment counters and remove from workers */
|
|
59
|
+
failTicketWorker(ticketId: string, reason: string): void;
|
|
60
|
+
/** Check if all ticket workers are done */
|
|
61
|
+
allWorkersComplete(): boolean;
|
|
62
|
+
/** Append an event to events.ndjson */
|
|
63
|
+
appendEvent(type: EventType, payload: Record<string, unknown>): void;
|
|
64
|
+
/** Save an artifact file */
|
|
65
|
+
saveArtifact(filename: string, content: string): void;
|
|
66
|
+
/** Save a diff/patch file */
|
|
67
|
+
saveDiff(step: number, ticketId: string, patch: string): void;
|
|
68
|
+
/** Check if any budget is exhausted */
|
|
69
|
+
isBudgetExhausted(): {
|
|
70
|
+
exhausted: boolean;
|
|
71
|
+
which?: string;
|
|
72
|
+
};
|
|
73
|
+
/** Check if approaching budget limits (80%) */
|
|
74
|
+
getBudgetWarnings(): string[];
|
|
75
|
+
/** Build the digest for advance responses */
|
|
76
|
+
buildDigest(): {
|
|
77
|
+
step: number;
|
|
78
|
+
phase: string;
|
|
79
|
+
tickets_completed: number;
|
|
80
|
+
tickets_failed: number;
|
|
81
|
+
budget_remaining: number;
|
|
82
|
+
ticket_budget_remaining: number;
|
|
83
|
+
spindle_risk: 'none' | 'low' | 'medium' | 'high';
|
|
84
|
+
time_remaining_ms: number | null;
|
|
85
|
+
coverage: {
|
|
86
|
+
sectors_scanned: number;
|
|
87
|
+
sectors_total: number;
|
|
88
|
+
files_scanned: number;
|
|
89
|
+
files_total: number;
|
|
90
|
+
percent: number;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
/** Lazy-load learnings from disk on first access. No-op if already loaded or disabled. */
|
|
94
|
+
ensureLearningsLoaded(): void;
|
|
95
|
+
private persistState;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=run-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-manager.d.ts","sourceRoot":"","sources":["../src/run-manager.ts"],"names":[],"mappings":"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"}
|