@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.
Files changed (134) hide show
  1. package/README.md +178 -0
  2. package/dist/advance-helpers.d.ts +27 -0
  3. package/dist/advance-helpers.d.ts.map +1 -0
  4. package/dist/advance-helpers.js +127 -0
  5. package/dist/advance-helpers.js.map +1 -0
  6. package/dist/advance-prompts.d.ts +48 -0
  7. package/dist/advance-prompts.d.ts.map +1 -0
  8. package/dist/advance-prompts.js +420 -0
  9. package/dist/advance-prompts.js.map +1 -0
  10. package/dist/advance.d.ts +30 -0
  11. package/dist/advance.d.ts.map +1 -0
  12. package/dist/advance.js +752 -0
  13. package/dist/advance.js.map +1 -0
  14. package/dist/codebase-index.d.ts +5 -0
  15. package/dist/codebase-index.d.ts.map +1 -0
  16. package/dist/codebase-index.js +5 -0
  17. package/dist/codebase-index.js.map +1 -0
  18. package/dist/dedup-memory.d.ts +30 -0
  19. package/dist/dedup-memory.d.ts.map +1 -0
  20. package/dist/dedup-memory.js +76 -0
  21. package/dist/dedup-memory.js.map +1 -0
  22. package/dist/direct-client.d.ts +57 -0
  23. package/dist/direct-client.d.ts.map +1 -0
  24. package/dist/direct-client.js +92 -0
  25. package/dist/direct-client.js.map +1 -0
  26. package/dist/event-handlers-qa.d.ts +5 -0
  27. package/dist/event-handlers-qa.d.ts.map +1 -0
  28. package/dist/event-handlers-qa.js +186 -0
  29. package/dist/event-handlers-qa.js.map +1 -0
  30. package/dist/event-handlers-scout.d.ts +5 -0
  31. package/dist/event-handlers-scout.d.ts.map +1 -0
  32. package/dist/event-handlers-scout.js +270 -0
  33. package/dist/event-handlers-scout.js.map +1 -0
  34. package/dist/event-handlers-ticket.d.ts +5 -0
  35. package/dist/event-handlers-ticket.d.ts.map +1 -0
  36. package/dist/event-handlers-ticket.js +232 -0
  37. package/dist/event-handlers-ticket.js.map +1 -0
  38. package/dist/event-helpers.d.ts +46 -0
  39. package/dist/event-helpers.d.ts.map +1 -0
  40. package/dist/event-helpers.js +125 -0
  41. package/dist/event-helpers.js.map +1 -0
  42. package/dist/event-processor.d.ts +15 -0
  43. package/dist/event-processor.d.ts.map +1 -0
  44. package/dist/event-processor.js +111 -0
  45. package/dist/event-processor.js.map +1 -0
  46. package/dist/formulas.d.ts +27 -0
  47. package/dist/formulas.d.ts.map +1 -0
  48. package/dist/formulas.js +109 -0
  49. package/dist/formulas.js.map +1 -0
  50. package/dist/guidelines.d.ts +16 -0
  51. package/dist/guidelines.d.ts.map +1 -0
  52. package/dist/guidelines.js +44 -0
  53. package/dist/guidelines.js.map +1 -0
  54. package/dist/index.d.ts +9 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +42 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/learnings.d.ts +42 -0
  59. package/dist/learnings.d.ts.map +1 -0
  60. package/dist/learnings.js +117 -0
  61. package/dist/learnings.js.map +1 -0
  62. package/dist/project-metadata.d.ts +34 -0
  63. package/dist/project-metadata.d.ts.map +1 -0
  64. package/dist/project-metadata.js +617 -0
  65. package/dist/project-metadata.js.map +1 -0
  66. package/dist/proposals.d.ts +23 -0
  67. package/dist/proposals.d.ts.map +1 -0
  68. package/dist/proposals.js +201 -0
  69. package/dist/proposals.js.map +1 -0
  70. package/dist/qa-stats.d.ts +51 -0
  71. package/dist/qa-stats.d.ts.map +1 -0
  72. package/dist/qa-stats.js +121 -0
  73. package/dist/qa-stats.js.map +1 -0
  74. package/dist/run-manager.d.ts +97 -0
  75. package/dist/run-manager.d.ts.map +1 -0
  76. package/dist/run-manager.js +583 -0
  77. package/dist/run-manager.js.map +1 -0
  78. package/dist/run-state-bridge.d.ts +13 -0
  79. package/dist/run-state-bridge.d.ts.map +1 -0
  80. package/dist/run-state-bridge.js +101 -0
  81. package/dist/run-state-bridge.js.map +1 -0
  82. package/dist/scope-policy.d.ts +83 -0
  83. package/dist/scope-policy.d.ts.map +1 -0
  84. package/dist/scope-policy.js +278 -0
  85. package/dist/scope-policy.js.map +1 -0
  86. package/dist/server.d.ts +18 -0
  87. package/dist/server.d.ts.map +1 -0
  88. package/dist/server.js +35 -0
  89. package/dist/server.js.map +1 -0
  90. package/dist/spindle.d.ts +41 -0
  91. package/dist/spindle.d.ts.map +1 -0
  92. package/dist/spindle.js +230 -0
  93. package/dist/spindle.js.map +1 -0
  94. package/dist/state.d.ts +36 -0
  95. package/dist/state.d.ts.map +1 -0
  96. package/dist/state.js +50 -0
  97. package/dist/state.js.map +1 -0
  98. package/dist/ticket-worker.d.ts +37 -0
  99. package/dist/ticket-worker.d.ts.map +1 -0
  100. package/dist/ticket-worker.js +527 -0
  101. package/dist/ticket-worker.js.map +1 -0
  102. package/dist/tool-registry.d.ts +35 -0
  103. package/dist/tool-registry.d.ts.map +1 -0
  104. package/dist/tool-registry.js +129 -0
  105. package/dist/tool-registry.js.map +1 -0
  106. package/dist/tools/execute.d.ts +17 -0
  107. package/dist/tools/execute.d.ts.map +1 -0
  108. package/dist/tools/execute.js +418 -0
  109. package/dist/tools/execute.js.map +1 -0
  110. package/dist/tools/git.d.ts +7 -0
  111. package/dist/tools/git.d.ts.map +1 -0
  112. package/dist/tools/git.js +98 -0
  113. package/dist/tools/git.js.map +1 -0
  114. package/dist/tools/intelligence.d.ts +10 -0
  115. package/dist/tools/intelligence.d.ts.map +1 -0
  116. package/dist/tools/intelligence.js +432 -0
  117. package/dist/tools/intelligence.js.map +1 -0
  118. package/dist/tools/session.d.ts +7 -0
  119. package/dist/tools/session.d.ts.map +1 -0
  120. package/dist/tools/session.js +533 -0
  121. package/dist/tools/session.js.map +1 -0
  122. package/dist/tools/trajectory.d.ts +10 -0
  123. package/dist/tools/trajectory.d.ts.map +1 -0
  124. package/dist/tools/trajectory.js +374 -0
  125. package/dist/tools/trajectory.js.map +1 -0
  126. package/dist/trajectory-io.d.ts +21 -0
  127. package/dist/trajectory-io.d.ts.map +1 -0
  128. package/dist/trajectory-io.js +105 -0
  129. package/dist/trajectory-io.js.map +1 -0
  130. package/dist/types.d.ts +229 -0
  131. package/dist/types.d.ts.map +1 -0
  132. package/dist/types.js +13 -0
  133. package/dist/types.js.map +1 -0
  134. package/package.json +63 -0
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Spindle Loop Detection — MCP server adaptation.
3
+ *
4
+ * Monitors agent execution for unproductive patterns:
5
+ * - Oscillation: diffs flip-flopping (A→B→A)
6
+ * - Repetition: similar outputs repeated
7
+ * - Stalling: no file changes for N iterations
8
+ * - QA ping-pong: alternating test/lint failures
9
+ * - Command signature: same command fails repeatedly
10
+ *
11
+ * Ported from packages/cli/src/lib/spindle.ts, adapted for the
12
+ * event-driven MCP architecture.
13
+ */
14
+ import { shortHash, detectQaPingPong, detectCommandFailure, extractFilesFromDiff, getFileEditWarnings as _getFileEditWarnings, } from '@promptwheel/core/spindle/shared';
15
+ export const DEFAULT_SPINDLE_CONFIG = {
16
+ similarityThreshold: 0.8,
17
+ maxSimilarOutputs: 3,
18
+ maxStallIterations: 5,
19
+ maxCommandFailures: 3,
20
+ maxQaPingPong: 3,
21
+ maxFileEdits: 3,
22
+ };
23
+ const PASS = {
24
+ shouldAbort: false,
25
+ shouldBlock: false,
26
+ confidence: 0,
27
+ diagnostics: {},
28
+ risk: 'none',
29
+ };
30
+ // ---------------------------------------------------------------------------
31
+ // Core check — runs on every advance()
32
+ // ---------------------------------------------------------------------------
33
+ export function checkSpindle(spindle, config = DEFAULT_SPINDLE_CONFIG) {
34
+ // 1. Stalling — no file changes
35
+ if (spindle.iterations_since_change >= config.maxStallIterations) {
36
+ return {
37
+ shouldAbort: true,
38
+ shouldBlock: false,
39
+ reason: 'stalling',
40
+ confidence: 0.9,
41
+ diagnostics: {
42
+ iterations_without_change: spindle.iterations_since_change,
43
+ threshold: config.maxStallIterations,
44
+ },
45
+ risk: 'high',
46
+ };
47
+ }
48
+ // 2. Oscillation — diff flip-flops
49
+ if (spindle.diff_hashes.length >= 3) {
50
+ const osc = detectOscillation(spindle.diff_hashes);
51
+ if (osc) {
52
+ return {
53
+ shouldAbort: true,
54
+ shouldBlock: false,
55
+ reason: 'oscillation',
56
+ confidence: 0.95,
57
+ diagnostics: { pattern: osc },
58
+ risk: 'high',
59
+ };
60
+ }
61
+ }
62
+ // 3. Repetition — similar output hashes
63
+ if (spindle.output_hashes.length >= config.maxSimilarOutputs) {
64
+ const rep = detectRepetition(spindle.output_hashes, config.maxSimilarOutputs);
65
+ if (rep) {
66
+ return {
67
+ shouldAbort: true,
68
+ shouldBlock: false,
69
+ reason: 'repetition',
70
+ confidence: 0.85,
71
+ diagnostics: { repeated_hash: rep, count: config.maxSimilarOutputs },
72
+ risk: 'high',
73
+ };
74
+ }
75
+ }
76
+ // 4. QA ping-pong — alternating failure types
77
+ if (spindle.failing_command_signatures.length >= config.maxQaPingPong * 2) {
78
+ const pp = detectQaPingPong(spindle.failing_command_signatures, config.maxQaPingPong);
79
+ if (pp) {
80
+ return {
81
+ shouldAbort: true,
82
+ shouldBlock: false,
83
+ reason: 'qa_ping_pong',
84
+ confidence: 0.9,
85
+ diagnostics: { pattern: pp },
86
+ risk: 'high',
87
+ };
88
+ }
89
+ }
90
+ // 5. Command signature — same command fails N times
91
+ const cmdFail = detectCommandFailure(spindle.failing_command_signatures, config.maxCommandFailures);
92
+ if (cmdFail) {
93
+ return {
94
+ shouldAbort: false,
95
+ shouldBlock: true, // → BLOCKED_NEEDS_HUMAN
96
+ reason: 'command_failure',
97
+ confidence: 0.8,
98
+ diagnostics: { command: cmdFail, threshold: config.maxCommandFailures },
99
+ risk: 'high',
100
+ };
101
+ }
102
+ // Compute risk level
103
+ const risk = computeRisk(spindle, config);
104
+ return { ...PASS, risk };
105
+ }
106
+ // ---------------------------------------------------------------------------
107
+ // State update helpers — called from event processor
108
+ // ---------------------------------------------------------------------------
109
+ export function recordOutput(spindle, output) {
110
+ const hash = shortHash(output);
111
+ spindle.output_hashes.push(hash);
112
+ if (spindle.output_hashes.length > 10)
113
+ spindle.output_hashes.shift();
114
+ spindle.total_output_chars += output.length;
115
+ }
116
+ export function recordDiff(spindle, diff) {
117
+ if (!diff || diff.trim() === '') {
118
+ spindle.iterations_since_change++;
119
+ return;
120
+ }
121
+ spindle.iterations_since_change = 0;
122
+ const hash = shortHash(diff);
123
+ spindle.diff_hashes.push(hash);
124
+ if (spindle.diff_hashes.length > 10)
125
+ spindle.diff_hashes.shift();
126
+ spindle.total_change_chars += diff.length;
127
+ // Track per-file edit frequency
128
+ const files = extractFilesFromDiff(diff);
129
+ for (const f of files) {
130
+ const existing = spindle.file_edit_counts?.[f] ?? 0;
131
+ if (!spindle.file_edit_counts)
132
+ spindle.file_edit_counts = {};
133
+ spindle.file_edit_counts[f] = existing + 1;
134
+ }
135
+ // Cap file_edit_counts keys to prevent unbounded growth
136
+ const MAX_FILE_EDIT_KEYS = 50;
137
+ if (spindle.file_edit_counts && Object.keys(spindle.file_edit_counts).length > MAX_FILE_EDIT_KEYS) {
138
+ const sorted = Object.entries(spindle.file_edit_counts)
139
+ .sort((a, b) => b[1] - a[1])
140
+ .slice(0, MAX_FILE_EDIT_KEYS);
141
+ spindle.file_edit_counts = Object.fromEntries(sorted);
142
+ }
143
+ }
144
+ export function recordCommandFailure(spindle, command, error) {
145
+ const sig = shortHash(`${command}::${error.slice(0, 200)}`);
146
+ spindle.failing_command_signatures.push(sig);
147
+ if (spindle.failing_command_signatures.length > 20)
148
+ spindle.failing_command_signatures.shift();
149
+ }
150
+ export function recordPlanHash(spindle, plan) {
151
+ const hash = shortHash(JSON.stringify(plan));
152
+ spindle.plan_hashes.push(hash);
153
+ if (spindle.plan_hashes.length > 10)
154
+ spindle.plan_hashes.shift();
155
+ }
156
+ export function recordTicketResult(spindle, changedFiles, diff) {
157
+ recordDiff(spindle, diff);
158
+ }
159
+ // ---------------------------------------------------------------------------
160
+ // Detection functions
161
+ // ---------------------------------------------------------------------------
162
+ /** Detect A→B→A hash oscillation */
163
+ function detectOscillation(hashes) {
164
+ // Check for A→B→A pattern in last 3
165
+ const recent = hashes.slice(-3);
166
+ if (recent.length === 3 && recent[0] === recent[2] && recent[0] !== recent[1]) {
167
+ return `Hash ${recent[0]} appeared at positions -3 and -1 (flip-flop)`;
168
+ }
169
+ // Check for any hash appearing in alternating positions
170
+ for (let i = hashes.length - 1; i >= 2; i--) {
171
+ if (hashes[i] === hashes[i - 2] && hashes[i] !== hashes[i - 1]) {
172
+ return `Hash ${hashes[i]} oscillating at positions ${i - 2}, ${i}`;
173
+ }
174
+ }
175
+ return null;
176
+ }
177
+ /** Detect N consecutive identical output hashes */
178
+ function detectRepetition(hashes, threshold) {
179
+ if (hashes.length < threshold)
180
+ return null;
181
+ const recent = hashes.slice(-threshold);
182
+ const first = recent[0];
183
+ if (recent.every(h => h === first)) {
184
+ return first;
185
+ }
186
+ return null;
187
+ }
188
+ // ---------------------------------------------------------------------------
189
+ // Risk computation
190
+ // ---------------------------------------------------------------------------
191
+ function computeRisk(spindle, config) {
192
+ let score = 0;
193
+ // Stall proximity
194
+ if (spindle.iterations_since_change >= config.maxStallIterations * 0.6)
195
+ score += 2;
196
+ else if (spindle.iterations_since_change >= 2)
197
+ score += 1;
198
+ // Repeated outputs
199
+ const recentOutputs = spindle.output_hashes.slice(-3);
200
+ if (recentOutputs.length >= 2 && recentOutputs[recentOutputs.length - 1] === recentOutputs[recentOutputs.length - 2]) {
201
+ score += 1;
202
+ }
203
+ // File edit frequency warnings
204
+ if (spindle.file_edit_counts) {
205
+ for (const count of Object.values(spindle.file_edit_counts)) {
206
+ if (count >= config.maxFileEdits)
207
+ score += 2;
208
+ }
209
+ }
210
+ // Command failures
211
+ if (spindle.failing_command_signatures.length >= 2)
212
+ score += 1;
213
+ if (score >= 4)
214
+ return 'high';
215
+ if (score >= 2)
216
+ return 'medium';
217
+ if (score >= 1)
218
+ return 'low';
219
+ return 'none';
220
+ }
221
+ // ---------------------------------------------------------------------------
222
+ // Helpers
223
+ // ---------------------------------------------------------------------------
224
+ /** Get file edit frequency warnings — wraps shared function, handles optional field */
225
+ export function getFileEditWarnings(spindle, threshold = 3) {
226
+ if (!spindle.file_edit_counts)
227
+ return [];
228
+ return _getFileEditWarnings(spindle.file_edit_counts, threshold);
229
+ }
230
+ //# sourceMappingURL=spindle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spindle.js","sourceRoot":"","sources":["../src/spindle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Session state manager (v2)
3
+ *
4
+ * Thin wrapper around RunManager + database.
5
+ * Each MCP server instance has at most one active run.
6
+ */
7
+ import type { DatabaseAdapter } from '@promptwheel/core';
8
+ import type { Project } from '@promptwheel/core';
9
+ import { RunManager } from './run-manager.js';
10
+ import type { RunState, SessionConfig } from './types.js';
11
+ export declare class SessionManager {
12
+ readonly db: DatabaseAdapter;
13
+ readonly project: Project;
14
+ readonly projectPath: string;
15
+ readonly run: RunManager;
16
+ constructor(db: DatabaseAdapter, project: Project, projectPath: string);
17
+ /** Start a new session/run */
18
+ start(config: SessionConfig): RunState;
19
+ /** Get active run state or throw */
20
+ requireActive(): RunState;
21
+ /** End the session */
22
+ end(): RunState;
23
+ /** Get current status summary */
24
+ getStatus(): {
25
+ sessionId: string;
26
+ runId: string;
27
+ phase: string;
28
+ stepCount: number;
29
+ budgetRemaining: number;
30
+ ticketsCompleted: number;
31
+ ticketsFailed: number;
32
+ currentTicketId: string | null;
33
+ timeRemainingMs: number | null;
34
+ };
35
+ }
36
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE1D,qBAAa,cAAc;IAIvB,QAAQ,CAAC,EAAE,EAAE,eAAe;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM;IAL9B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;gBAGd,EAAE,EAAE,eAAe,EACnB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,MAAM;IAK9B,8BAA8B;IAC9B,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG,QAAQ;IAItC,oCAAoC;IACpC,aAAa,IAAI,QAAQ;IAIzB,sBAAsB;IACtB,GAAG,IAAI,QAAQ;IAIf,iCAAiC;IACjC,SAAS,IAAI;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;KAChC;CAkBF"}
package/dist/state.js ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Session state manager (v2)
3
+ *
4
+ * Thin wrapper around RunManager + database.
5
+ * Each MCP server instance has at most one active run.
6
+ */
7
+ import { RunManager } from './run-manager.js';
8
+ export class SessionManager {
9
+ db;
10
+ project;
11
+ projectPath;
12
+ run;
13
+ constructor(db, project, projectPath) {
14
+ this.db = db;
15
+ this.project = project;
16
+ this.projectPath = projectPath;
17
+ this.run = new RunManager(projectPath);
18
+ }
19
+ /** Start a new session/run */
20
+ start(config) {
21
+ return this.run.create(this.project.id, config);
22
+ }
23
+ /** Get active run state or throw */
24
+ requireActive() {
25
+ return this.run.require();
26
+ }
27
+ /** End the session */
28
+ end() {
29
+ return this.run.end();
30
+ }
31
+ /** Get current status summary */
32
+ getStatus() {
33
+ const s = this.run.require();
34
+ const timeRemainingMs = s.expires_at
35
+ ? Math.max(0, new Date(s.expires_at).getTime() - Date.now())
36
+ : null;
37
+ return {
38
+ sessionId: s.session_id,
39
+ runId: s.run_id,
40
+ phase: s.phase,
41
+ stepCount: s.step_count,
42
+ budgetRemaining: s.step_budget - s.step_count,
43
+ ticketsCompleted: s.tickets_completed,
44
+ ticketsFailed: s.tickets_failed,
45
+ currentTicketId: s.current_ticket_id,
46
+ timeRemainingMs,
47
+ };
48
+ }
49
+ }
50
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,OAAO,cAAc;IAId;IACA;IACA;IALF,GAAG,CAAa;IAEzB,YACW,EAAmB,EACnB,OAAgB,EAChB,WAAmB;QAFnB,OAAE,GAAF,EAAE,CAAiB;QACnB,YAAO,GAAP,OAAO,CAAS;QAChB,gBAAW,GAAX,WAAW,CAAQ;QAE5B,IAAI,CAAC,GAAG,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAED,8BAA8B;IAC9B,KAAK,CAAC,MAAqB;QACzB,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,oCAAoC;IACpC,aAAa;QACX,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IAED,sBAAsB;IACtB,GAAG;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IACxB,CAAC;IAED,iCAAiC;IACjC,SAAS;QAWP,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC7B,MAAM,eAAe,GAAG,CAAC,CAAC,UAAU;YAClC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5D,CAAC,CAAC,IAAI,CAAC;QAET,OAAO;YACL,SAAS,EAAE,CAAC,CAAC,UAAU;YACvB,KAAK,EAAE,CAAC,CAAC,MAAM;YACf,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,SAAS,EAAE,CAAC,CAAC,UAAU;YACvB,eAAe,EAAE,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,UAAU;YAC7C,gBAAgB,EAAE,CAAC,CAAC,iBAAiB;YACrC,aAAa,EAAE,CAAC,CAAC,cAAc;YAC/B,eAAe,EAAE,CAAC,CAAC,iBAAiB;YACpC,eAAe;SAChB,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Ticket Worker — self-contained mini state machine for one ticket in parallel mode.
3
+ *
4
+ * Each ticket worker follows: PLAN → EXECUTE → QA → PR → DONE
5
+ * State is stored in RunState.ticket_workers[ticketId].
6
+ */
7
+ import type { DatabaseAdapter } from '@promptwheel/core';
8
+ import type { Project } from '@promptwheel/core';
9
+ import { RunManager } from './run-manager.js';
10
+ import type { AdvanceConstraints } from './types.js';
11
+ export interface TicketWorkerContext {
12
+ run: RunManager;
13
+ db: DatabaseAdapter;
14
+ project: Project;
15
+ }
16
+ export interface TicketWorkerResponse {
17
+ action: 'PROMPT' | 'DONE' | 'FAILED';
18
+ phase: string;
19
+ prompt: string | null;
20
+ constraints: AdvanceConstraints | null;
21
+ ticket_id: string;
22
+ reason: string;
23
+ }
24
+ /**
25
+ * Advance a single ticket worker through its lifecycle.
26
+ * Called by the promptwheel_advance_ticket MCP tool.
27
+ */
28
+ export declare function advanceTicketWorker(ctx: TicketWorkerContext, ticketId: string): Promise<TicketWorkerResponse>;
29
+ /**
30
+ * Ingest an event for a specific ticket worker.
31
+ * Mirrors event-processor.ts logic but scoped to one ticket.
32
+ */
33
+ export declare function ingestTicketEvent(ctx: TicketWorkerContext, ticketId: string, type: string, payload: Record<string, unknown>): Promise<{
34
+ processed: boolean;
35
+ message: string;
36
+ }>;
37
+ //# sourceMappingURL=ticket-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-worker.d.ts","sourceRoot":"","sources":["../src/ticket-worker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EACV,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AAiBpB,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,UAAU,CAAC;IAChB,EAAE,EAAE,eAAe,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC,CAoP/B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAsKlD"}