@pennyfarthing/core 7.4.1 → 7.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/package.json +1 -1
- package/packages/core/dist/cli/commands/doctor-legacy.test.d.ts +13 -0
- package/packages/core/dist/cli/commands/doctor-legacy.test.d.ts.map +1 -0
- package/packages/core/dist/cli/commands/doctor-legacy.test.js +207 -0
- package/packages/core/dist/cli/commands/doctor-legacy.test.js.map +1 -0
- package/packages/core/dist/cli/commands/doctor.d.ts +16 -0
- package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/doctor.js +130 -2
- package/packages/core/dist/cli/commands/doctor.js.map +1 -1
- package/packages/core/dist/cli/commands/init.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/init.js +17 -27
- package/packages/core/dist/cli/commands/init.js.map +1 -1
- package/packages/core/dist/cli/commands/update.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/update.js +21 -52
- package/packages/core/dist/cli/commands/update.js.map +1 -1
- package/packages/core/dist/cli/utils/symlinks.d.ts +15 -0
- package/packages/core/dist/cli/utils/symlinks.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/symlinks.js +148 -2
- package/packages/core/dist/cli/utils/symlinks.js.map +1 -1
- package/packages/core/dist/cli/utils/themes.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/themes.js +9 -0
- package/packages/core/dist/cli/utils/themes.js.map +1 -1
- package/pennyfarthing-dist/agents/dev.md +29 -24
- package/pennyfarthing-dist/agents/handoff.md +42 -119
- package/pennyfarthing-dist/agents/reviewer.md +32 -37
- package/pennyfarthing-dist/agents/sm-handoff.md +43 -66
- package/pennyfarthing-dist/agents/sm.md +52 -35
- package/pennyfarthing-dist/agents/tea.md +25 -8
- package/pennyfarthing-dist/agents/testing-runner.md +4 -4
- package/pennyfarthing-dist/commands/architect.md +0 -55
- package/pennyfarthing-dist/commands/dev.md +1 -54
- package/pennyfarthing-dist/commands/devops.md +0 -52
- package/pennyfarthing-dist/commands/health-check.md +33 -0
- package/pennyfarthing-dist/commands/orchestrator.md +0 -49
- package/pennyfarthing-dist/commands/pm.md +0 -53
- package/pennyfarthing-dist/commands/reviewer.md +1 -58
- package/pennyfarthing-dist/commands/sm.md +1 -64
- package/pennyfarthing-dist/commands/sprint.md +133 -0
- package/pennyfarthing-dist/commands/standalone.md +194 -0
- package/pennyfarthing-dist/commands/tea.md +1 -57
- package/pennyfarthing-dist/commands/tech-writer.md +0 -46
- package/pennyfarthing-dist/commands/theme-maker.md +10 -5
- package/pennyfarthing-dist/commands/ux-designer.md +0 -55
- package/pennyfarthing-dist/guides/XML-TAGS.md +156 -0
- package/pennyfarthing-dist/guides/agent-behavior.md +64 -38
- package/pennyfarthing-dist/guides/measurement-framework.md +210 -0
- package/pennyfarthing-dist/personas/themes/a-team.yaml +130 -0
- package/pennyfarthing-dist/personas/themes/alice-in-wonderland.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/ancient-strategists.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/arcane.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/better-call-saul.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/big-lebowski.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/black-sails.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/blade-runner.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/bobiverse.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/breaking-bad.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/count-of-monte-cristo.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/cowboy-bebop.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/deadwood.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/dickens.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/discworld.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/doctor-who.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/don-quixote.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/dune.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/enlightenment-thinkers.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/expeditionary-force.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/futurama.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/game-of-thrones.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/gilligans-island.yaml +131 -1
- package/pennyfarthing-dist/personas/themes/gothic-literature.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/great-gatsby.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/hannibal.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/harry-potter.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/his-dark-materials.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/inspector-morse.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/jane-austen.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/legion-of-doom.yaml +130 -0
- package/pennyfarthing-dist/personas/themes/mad-max.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/moby-dick.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/neuromancer.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/parks-and-rec.yaml +130 -0
- package/pennyfarthing-dist/personas/themes/princess-bride.yaml +130 -0
- package/pennyfarthing-dist/personas/themes/renaissance-masters.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/russian-masters.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/sandman.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/scientific-revolutionaries.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/shakespeare.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/star-trek-tng.yaml +139 -3
- package/pennyfarthing-dist/personas/themes/star-trek-tos.yaml +124 -0
- package/pennyfarthing-dist/personas/themes/star-wars.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/succession.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/superfriends.yaml +131 -1
- package/pennyfarthing-dist/personas/themes/ted-lasso.yaml +131 -1
- package/pennyfarthing-dist/personas/themes/the-americans.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/the-expanse.yaml +131 -1
- package/pennyfarthing-dist/personas/themes/the-good-place.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/the-matrix.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/the-sopranos.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/west-wing.yaml +6 -6
- package/pennyfarthing-dist/personas/themes/world-explorers.yaml +1 -1
- package/pennyfarthing-dist/personas/themes/wwii-leaders.yaml +1 -1
- package/pennyfarthing-dist/scripts/core/check-context.sh +23 -6
- package/pennyfarthing-dist/scripts/core/phase-check-start.sh +95 -0
- package/pennyfarthing-dist/scripts/git/release.sh +3 -2
- package/pennyfarthing-dist/scripts/health/drift-detection.sh +162 -0
- package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +87 -0
- package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +1 -1
- package/pennyfarthing-dist/scripts/misc/deploy.sh +1 -1
- package/pennyfarthing-dist/scripts/misc/statusline.sh +25 -32
- package/pennyfarthing-dist/scripts/sprint/import-epic-to-future.mjs +377 -0
- package/pennyfarthing-dist/scripts/sprint/import-epic-to-future.sh +9 -0
- package/pennyfarthing-dist/scripts/theme/compute-theme-tiers.js +492 -0
- package/pennyfarthing-dist/scripts/theme/compute-theme-tiers.sh +8 -200
- package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +38 -5
- package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +40 -0
- package/pennyfarthing-dist/skills/theme-creation/SKILL.md +12 -7
- package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-04-final-validation.md +11 -3
- package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-05-import-to-future.md +122 -0
- package/pennyfarthing-dist/workflows/epics-and-stories/workflow.yaml +3 -2
- package/packages/core/dist/workflow/generic-handoff.d.ts +0 -281
- package/packages/core/dist/workflow/generic-handoff.d.ts.map +0 -1
- package/packages/core/dist/workflow/generic-handoff.js +0 -411
- package/packages/core/dist/workflow/generic-handoff.js.map +0 -1
- package/packages/core/dist/workflow/generic-handoff.test.d.ts +0 -21
- package/packages/core/dist/workflow/generic-handoff.test.d.ts.map +0 -1
- package/packages/core/dist/workflow/generic-handoff.test.js +0 -499
- package/packages/core/dist/workflow/generic-handoff.test.js.map +0 -1
|
@@ -1,411 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic Workflow-Driven Handoff
|
|
3
|
-
*
|
|
4
|
-
* Replaces hardcoded handoff files with workflow-driven logic.
|
|
5
|
-
* Reads phase requirements from workflow definitions.
|
|
6
|
-
*
|
|
7
|
-
* Provides functions to:
|
|
8
|
-
* - Find current phase in a workflow
|
|
9
|
-
* - Determine next phase (forward or rejection loop)
|
|
10
|
-
* - Check gate conditions based on gate type
|
|
11
|
-
* - Format session file updates for phase transitions
|
|
12
|
-
*/
|
|
13
|
-
import { existsSync, readFileSync } from 'fs';
|
|
14
|
-
/**
|
|
15
|
-
* Find a phase by name in a workflow definition
|
|
16
|
-
*
|
|
17
|
-
* @param workflow - The workflow definition to search
|
|
18
|
-
* @param phaseName - Name of the phase to find
|
|
19
|
-
* @returns The phase definition or null if not found
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```typescript
|
|
23
|
-
* const phase = findCurrentPhase(workflow, 'red');
|
|
24
|
-
* if (phase) {
|
|
25
|
-
* console.log(`Found phase: ${phase.name}, agent: ${phase.agent}`);
|
|
26
|
-
* }
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
export function findCurrentPhase(workflow, phaseName) {
|
|
30
|
-
if (!workflow.phases) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
return workflow.phases.find(phase => phase.name === phaseName) ?? null;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Get the next phase in the workflow
|
|
37
|
-
*
|
|
38
|
-
* For normal progression, returns the next phase in sequence.
|
|
39
|
-
* For rejection (verdict='rejected'), returns the phase to loop back to
|
|
40
|
-
* (typically the most recent phase with a tests_pass gate).
|
|
41
|
-
*
|
|
42
|
-
* @param workflow - The workflow definition
|
|
43
|
-
* @param currentPhaseName - Name of the current phase
|
|
44
|
-
* @param options - Options for handling rejection loops
|
|
45
|
-
* @returns The next phase or null if at end/not found
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* ```typescript
|
|
49
|
-
* // Normal progression
|
|
50
|
-
* const next = getNextPhase(workflow, 'red');
|
|
51
|
-
*
|
|
52
|
-
* // Rejection loop
|
|
53
|
-
* const next = getNextPhase(workflow, 'review', { verdict: 'rejected' });
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
export function getNextPhase(workflow, currentPhaseName, options) {
|
|
57
|
-
if (!workflow.phases) {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
const currentIndex = workflow.phases.findIndex(phase => phase.name === currentPhaseName);
|
|
61
|
-
if (currentIndex === -1) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
// Handle rejection: loop back to previous phase with tests_pass gate
|
|
65
|
-
if (options?.verdict === 'rejected') {
|
|
66
|
-
// Search backwards for a phase with tests_pass gate
|
|
67
|
-
for (let i = currentIndex - 1; i >= 0; i--) {
|
|
68
|
-
const phase = workflow.phases[i];
|
|
69
|
-
if (phase.gate?.type === 'tests_pass') {
|
|
70
|
-
return phase;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
// Fallback: return the phase immediately before current
|
|
74
|
-
if (currentIndex > 0) {
|
|
75
|
-
return workflow.phases[currentIndex - 1];
|
|
76
|
-
}
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
// Forward progression: return next phase in sequence
|
|
80
|
-
if (currentIndex < workflow.phases.length - 1) {
|
|
81
|
-
return workflow.phases[currentIndex + 1];
|
|
82
|
-
}
|
|
83
|
-
// At final phase - no next
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Check if a gate condition is satisfied
|
|
88
|
-
*
|
|
89
|
-
* Gate types:
|
|
90
|
-
* - tests_fail: testsRed must be true
|
|
91
|
-
* - tests_pass: testsGreen must be true
|
|
92
|
-
* - approval: verdict must be provided (approved or rejected)
|
|
93
|
-
* - manual: always passes
|
|
94
|
-
* - (none): always passes
|
|
95
|
-
*
|
|
96
|
-
* @param workflow - The workflow definition
|
|
97
|
-
* @param phaseName - Name of the phase to check
|
|
98
|
-
* @param context - Gate check context with test results, verdicts, etc.
|
|
99
|
-
* @returns Gate check result
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* ```typescript
|
|
103
|
-
* const result = checkGate(workflow, 'red', { testsRed: true });
|
|
104
|
-
* if (result.passed) {
|
|
105
|
-
* // Proceed with handoff
|
|
106
|
-
* }
|
|
107
|
-
* ```
|
|
108
|
-
*/
|
|
109
|
-
export function checkGate(workflow, phaseName, context) {
|
|
110
|
-
const phase = findCurrentPhase(workflow, phaseName);
|
|
111
|
-
if (!phase) {
|
|
112
|
-
return {
|
|
113
|
-
passed: false,
|
|
114
|
-
message: `Phase "${phaseName}" not found in workflow`
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
// No gate defined - always passes
|
|
118
|
-
if (!phase.gate) {
|
|
119
|
-
return { passed: true };
|
|
120
|
-
}
|
|
121
|
-
const gateType = phase.gate.type;
|
|
122
|
-
switch (gateType) {
|
|
123
|
-
case 'tests_fail':
|
|
124
|
-
// RED phase: tests must be failing
|
|
125
|
-
if (context.testsRed === true) {
|
|
126
|
-
return { passed: true, gateType };
|
|
127
|
-
}
|
|
128
|
-
return {
|
|
129
|
-
passed: false,
|
|
130
|
-
gateType,
|
|
131
|
-
message: 'Tests must be failing (RED) to proceed from this phase'
|
|
132
|
-
};
|
|
133
|
-
case 'tests_pass':
|
|
134
|
-
// GREEN phase: tests must be passing
|
|
135
|
-
if (context.testsGreen === true) {
|
|
136
|
-
return { passed: true, gateType };
|
|
137
|
-
}
|
|
138
|
-
return {
|
|
139
|
-
passed: false,
|
|
140
|
-
gateType,
|
|
141
|
-
message: `Tests must be passing (GREEN) to proceed. Currently ${context.testFailCount ?? 0} failing.`
|
|
142
|
-
};
|
|
143
|
-
case 'approval':
|
|
144
|
-
// Review phase: verdict must be provided
|
|
145
|
-
if (context.verdict === 'approved' || context.verdict === 'rejected') {
|
|
146
|
-
return { passed: true, gateType };
|
|
147
|
-
}
|
|
148
|
-
return {
|
|
149
|
-
passed: false,
|
|
150
|
-
gateType,
|
|
151
|
-
message: 'Verdict (approved or rejected) is required to proceed from this phase'
|
|
152
|
-
};
|
|
153
|
-
case 'manual':
|
|
154
|
-
// Manual gate: always passes
|
|
155
|
-
return { passed: true, gateType };
|
|
156
|
-
default:
|
|
157
|
-
// Unknown gate type - treat as manual (pass)
|
|
158
|
-
return { passed: true, gateType };
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Format the workflow tracking section for a session file update
|
|
163
|
-
*
|
|
164
|
-
* @param params - Phase transition parameters
|
|
165
|
-
* @returns Markdown string for the workflow tracking section
|
|
166
|
-
*
|
|
167
|
-
* @example
|
|
168
|
-
* ```typescript
|
|
169
|
-
* const markdown = formatPhaseTransition({
|
|
170
|
-
* workflowName: 'tdd',
|
|
171
|
-
* fromPhase: 'red',
|
|
172
|
-
* toPhase: 'green',
|
|
173
|
-
* startedAt: '2026-01-13T14:00:00Z',
|
|
174
|
-
* endedAt: '2026-01-13T14:30:00Z'
|
|
175
|
-
* });
|
|
176
|
-
* ```
|
|
177
|
-
*/
|
|
178
|
-
export function formatPhaseTransition(params) {
|
|
179
|
-
const { workflowName, fromPhase, toPhase, startedAt, endedAt } = params;
|
|
180
|
-
const duration = calculateDuration(startedAt, endedAt);
|
|
181
|
-
const now = new Date().toISOString();
|
|
182
|
-
// Build markdown for the workflow tracking section
|
|
183
|
-
const lines = [
|
|
184
|
-
`**Workflow:** ${workflowName}`,
|
|
185
|
-
`**Phase:** ${toPhase}`,
|
|
186
|
-
`**Phase Started:** ${now}`,
|
|
187
|
-
'',
|
|
188
|
-
'### Phase History',
|
|
189
|
-
'| Phase | Started | Ended | Duration |',
|
|
190
|
-
'|-------|---------|-------|----------|',
|
|
191
|
-
`| ${fromPhase} | ${startedAt} | ${endedAt} | ${duration} |`
|
|
192
|
-
];
|
|
193
|
-
return lines.join('\n');
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Calculate duration between two ISO 8601 timestamps
|
|
197
|
-
*
|
|
198
|
-
* @param startedAt - Start timestamp
|
|
199
|
-
* @param endedAt - End timestamp
|
|
200
|
-
* @returns Formatted duration string (e.g., "30m", "2h 30m", "45s")
|
|
201
|
-
*/
|
|
202
|
-
export function calculateDuration(startedAt, endedAt) {
|
|
203
|
-
const start = new Date(startedAt);
|
|
204
|
-
const end = new Date(endedAt);
|
|
205
|
-
// Handle invalid timestamps
|
|
206
|
-
if (isNaN(start.getTime()) || isNaN(end.getTime())) {
|
|
207
|
-
return '0m';
|
|
208
|
-
}
|
|
209
|
-
const diffMs = Math.abs(end.getTime() - start.getTime());
|
|
210
|
-
const diffSeconds = Math.floor(diffMs / 1000);
|
|
211
|
-
const diffMinutes = Math.floor(diffSeconds / 60);
|
|
212
|
-
const diffHours = Math.floor(diffMinutes / 60);
|
|
213
|
-
// Format based on duration length
|
|
214
|
-
if (diffSeconds < 60) {
|
|
215
|
-
return `${diffSeconds}s`;
|
|
216
|
-
}
|
|
217
|
-
if (diffHours === 0) {
|
|
218
|
-
return `${diffMinutes}m`;
|
|
219
|
-
}
|
|
220
|
-
const remainingMinutes = diffMinutes % 60;
|
|
221
|
-
if (remainingMinutes === 0) {
|
|
222
|
-
return `${diffHours}h`;
|
|
223
|
-
}
|
|
224
|
-
return `${diffHours}h ${remainingMinutes}m`;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Read handoff mode from Cyclist settings file
|
|
228
|
-
* Returns 'manual' as default if file doesn't exist or is invalid
|
|
229
|
-
*
|
|
230
|
-
* @param settingsPath - Path to the settings file (JSON or YAML)
|
|
231
|
-
* @returns The handoff mode setting
|
|
232
|
-
*/
|
|
233
|
-
export function readHandoffMode(settingsPath) {
|
|
234
|
-
try {
|
|
235
|
-
if (!existsSync(settingsPath)) {
|
|
236
|
-
return 'manual';
|
|
237
|
-
}
|
|
238
|
-
const content = readFileSync(settingsPath, 'utf-8');
|
|
239
|
-
// Try JSON first, then YAML
|
|
240
|
-
if (settingsPath.endsWith('.json') || content.trim().startsWith('{')) {
|
|
241
|
-
return parseHandoffModeFromJson(content);
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
return parseHandoffModeFromYaml(content);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
catch {
|
|
248
|
-
return 'manual';
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* Parse handoff mode from JSON string
|
|
253
|
-
* Handles both new format (handoff_mode) and legacy format (auto_handoff boolean)
|
|
254
|
-
*
|
|
255
|
-
* @param jsonContent - JSON string containing settings
|
|
256
|
-
* @returns The handoff mode setting
|
|
257
|
-
*/
|
|
258
|
-
export function parseHandoffModeFromJson(jsonContent) {
|
|
259
|
-
try {
|
|
260
|
-
const parsed = JSON.parse(jsonContent);
|
|
261
|
-
const workflow = parsed?.workflow;
|
|
262
|
-
if (!workflow) {
|
|
263
|
-
return 'manual';
|
|
264
|
-
}
|
|
265
|
-
// New format: handoff_mode
|
|
266
|
-
if (workflow.handoff_mode === 'auto' || workflow.handoff_mode === 'manual') {
|
|
267
|
-
return workflow.handoff_mode;
|
|
268
|
-
}
|
|
269
|
-
// Legacy format: auto_handoff boolean
|
|
270
|
-
if ('auto_handoff' in workflow) {
|
|
271
|
-
return workflow.auto_handoff === true ? 'auto' : 'manual';
|
|
272
|
-
}
|
|
273
|
-
return 'manual';
|
|
274
|
-
}
|
|
275
|
-
catch {
|
|
276
|
-
return 'manual';
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Parse handoff mode from YAML string
|
|
281
|
-
* Handles both new format (handoff_mode) and legacy format (auto_handoff boolean)
|
|
282
|
-
*
|
|
283
|
-
* @param yamlContent - YAML string containing settings
|
|
284
|
-
* @returns The handoff mode setting
|
|
285
|
-
*/
|
|
286
|
-
export function parseHandoffModeFromYaml(yamlContent) {
|
|
287
|
-
try {
|
|
288
|
-
// Simple YAML parsing for handoff_mode - look for the pattern
|
|
289
|
-
// workflow:
|
|
290
|
-
// handoff_mode: auto|manual
|
|
291
|
-
const lines = yamlContent.split('\n');
|
|
292
|
-
let inWorkflow = false;
|
|
293
|
-
for (const line of lines) {
|
|
294
|
-
const trimmed = line.trim();
|
|
295
|
-
if (trimmed === 'workflow:') {
|
|
296
|
-
inWorkflow = true;
|
|
297
|
-
continue;
|
|
298
|
-
}
|
|
299
|
-
if (inWorkflow) {
|
|
300
|
-
// Check for new format
|
|
301
|
-
const modeMatch = trimmed.match(/^handoff_mode:\s*['"]?(auto|manual)['"]?$/);
|
|
302
|
-
if (modeMatch) {
|
|
303
|
-
return modeMatch[1];
|
|
304
|
-
}
|
|
305
|
-
// Check for legacy format
|
|
306
|
-
const autoMatch = trimmed.match(/^auto_handoff:\s*(true|false)$/i);
|
|
307
|
-
if (autoMatch) {
|
|
308
|
-
return autoMatch[1].toLowerCase() === 'true' ? 'auto' : 'manual';
|
|
309
|
-
}
|
|
310
|
-
// Exit workflow section when we hit a non-indented line
|
|
311
|
-
if (!line.startsWith(' ') && !line.startsWith('\t') && trimmed !== '') {
|
|
312
|
-
inWorkflow = false;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
return 'manual';
|
|
317
|
-
}
|
|
318
|
-
catch {
|
|
319
|
-
return 'manual';
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Get handoff behavior based on mode
|
|
324
|
-
*
|
|
325
|
-
* @param mode - The handoff mode setting
|
|
326
|
-
* @returns Behavior configuration for the mode
|
|
327
|
-
*/
|
|
328
|
-
export function getHandoffBehavior(mode) {
|
|
329
|
-
if (mode === 'auto') {
|
|
330
|
-
return {
|
|
331
|
-
action: 'immediate',
|
|
332
|
-
requiresConfirmation: false,
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
return {
|
|
336
|
-
action: 'prompt',
|
|
337
|
-
requiresConfirmation: true,
|
|
338
|
-
message: 'Ready for handoff. Confirm to proceed to next agent.',
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Format handoff history entry for session file
|
|
343
|
-
* Creates a markdown section with table row for the handoff
|
|
344
|
-
*
|
|
345
|
-
* @param entry - Handoff history entry to format
|
|
346
|
-
* @returns Markdown string for the handoff history section
|
|
347
|
-
*/
|
|
348
|
-
export function formatHandoffHistory(entry) {
|
|
349
|
-
const lines = [
|
|
350
|
-
'## Handoff History',
|
|
351
|
-
'',
|
|
352
|
-
'| Phase | Agent | Timestamp | Mode |',
|
|
353
|
-
'|-------|-------|-----------|------|',
|
|
354
|
-
`| ${entry.phase} | ${entry.agent} | ${entry.timestamp} | ${entry.handoffMode} |`,
|
|
355
|
-
];
|
|
356
|
-
return lines.join('\n');
|
|
357
|
-
}
|
|
358
|
-
// =============================================================================
|
|
359
|
-
// Context Clear Signal (Story MSSCI-11840)
|
|
360
|
-
// =============================================================================
|
|
361
|
-
/**
|
|
362
|
-
* Threshold for context percentage to trigger context clear
|
|
363
|
-
* When auto mode is enabled and context exceeds this threshold, emit CONTEXT_CLEAR
|
|
364
|
-
*/
|
|
365
|
-
export const CONTEXT_CLEAR_THRESHOLD = 60;
|
|
366
|
-
/**
|
|
367
|
-
* Determine if CONTEXT_CLEAR marker should be emitted
|
|
368
|
-
*
|
|
369
|
-
* Returns true when:
|
|
370
|
-
* - handoffMode is 'auto'
|
|
371
|
-
* - contextPercent exceeds CONTEXT_CLEAR_THRESHOLD
|
|
372
|
-
*
|
|
373
|
-
* @param params - Context clear parameters
|
|
374
|
-
* @returns true if CONTEXT_CLEAR should be emitted
|
|
375
|
-
*/
|
|
376
|
-
export function shouldEmitContextClear(params) {
|
|
377
|
-
return params.handoffMode === 'auto' && params.contextPercent > CONTEXT_CLEAR_THRESHOLD;
|
|
378
|
-
}
|
|
379
|
-
/**
|
|
380
|
-
* Format the CYCLIST marker for context clear or regular handoff
|
|
381
|
-
*
|
|
382
|
-
* When auto mode and high context: returns CONTEXT_CLEAR marker
|
|
383
|
-
* Otherwise: returns regular HANDOFF marker
|
|
384
|
-
*
|
|
385
|
-
* @param params - Context clear parameters including nextAgent
|
|
386
|
-
* @returns Marker string (<!-- CYCLIST:CONTEXT_CLEAR:/agent --> or <!-- CYCLIST:HANDOFF:/agent -->)
|
|
387
|
-
*/
|
|
388
|
-
export function formatContextClearMarker(params) {
|
|
389
|
-
const { nextAgent = '/dev' } = params;
|
|
390
|
-
if (shouldEmitContextClear(params)) {
|
|
391
|
-
return `<!-- CYCLIST:CONTEXT_CLEAR:${nextAgent} -->`;
|
|
392
|
-
}
|
|
393
|
-
return `<!-- CYCLIST:HANDOFF:${nextAgent} -->`;
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Format a human-readable output message for context clear handoffs
|
|
397
|
-
*
|
|
398
|
-
* Includes context percentage and the marker for Cyclist to detect
|
|
399
|
-
*
|
|
400
|
-
* @param params - Context clear parameters
|
|
401
|
-
* @returns Formatted output string for display
|
|
402
|
-
*/
|
|
403
|
-
export function formatContextClearOutput(params) {
|
|
404
|
-
const { contextPercent, nextAgent = '/dev' } = params;
|
|
405
|
-
const marker = formatContextClearMarker(params);
|
|
406
|
-
if (shouldEmitContextClear(params)) {
|
|
407
|
-
return `Context at ${contextPercent}% - emitting CONTEXT_CLEAR for automatic session clear and reload.\n\n${marker}`;
|
|
408
|
-
}
|
|
409
|
-
return `Handoff to ${nextAgent}\n\n${marker}`;
|
|
410
|
-
}
|
|
411
|
-
//# sourceMappingURL=generic-handoff.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generic-handoff.js","sourceRoot":"","sources":["../../src/workflow/generic-handoff.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for Story 31-7: Generic Workflow-Driven Handoff Subagent
|
|
3
|
-
*
|
|
4
|
-
* These tests define the contract for the generic handoff module that
|
|
5
|
-
* replaces 5 hardcoded handoff files (sm-handoff, tea-handoff, dev-handoff,
|
|
6
|
-
* reviewer-handoff-approve, reviewer-handoff-reject).
|
|
7
|
-
*
|
|
8
|
-
* The generic handoff reads phase requirements from workflow definitions
|
|
9
|
-
* and performs gate checks based on phase gate type.
|
|
10
|
-
*
|
|
11
|
-
* Test categories:
|
|
12
|
-
* 1. findCurrentPhase() - Locate phase by name in workflow
|
|
13
|
-
* 2. getNextPhase() - Determine next phase (forward or rejection loop)
|
|
14
|
-
* 3. checkGate() - Run gate-specific checks
|
|
15
|
-
* 4. formatPhaseTransition() - Format session file updates
|
|
16
|
-
* 5. Integration - Full handoff scenarios with TDD/trivial workflows
|
|
17
|
-
*
|
|
18
|
-
* Run with: npm test
|
|
19
|
-
*/
|
|
20
|
-
export {};
|
|
21
|
-
//# sourceMappingURL=generic-handoff.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generic-handoff.test.d.ts","sourceRoot":"","sources":["../../src/workflow/generic-handoff.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
|