@pennyfarthing/core 7.4.0 → 7.5.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/cli/utils/files.d.ts +0 -1
- package/dist/cli/utils/files.js +73 -56
- package/dist/cli/utils/manifest.d.ts +0 -1
- package/dist/cli/utils/manifest.js +48 -45
- package/dist/cli/utils/version.d.ts +0 -1
- package/dist/cli/utils/version.js +38 -32
- package/dist/index.d.ts +0 -1
- package/dist/index.js +39 -11
- package/dist/permissions/index.d.ts +0 -1
- package/dist/permissions/index.js +7 -4
- package/dist/permissions/permission-schema.d.ts +0 -1
- package/dist/permissions/permission-schema.js +13 -9
- package/dist/scripts/job-fair-aggregator.d.ts +0 -1
- package/dist/scripts/job-fair-aggregator.js +484 -341
- package/dist/workflow/index.d.ts +0 -1
- package/dist/workflow/index.js +12 -5
- package/dist/workflow/workflow-loader.d.ts +0 -1
- package/dist/workflow/workflow-loader.js +40 -34
- package/dist/workflow/workflow-permissions.d.ts +0 -1
- package/dist/workflow/workflow-permissions.js +14 -8
- package/dist/workflow/workflow-router.d.ts +0 -1
- package/dist/workflow/workflow-router.js +70 -51
- package/dist/workflow/workflow-schema.d.ts +0 -1
- package/dist/workflow/workflow-schema.js +62 -59
- package/package.json +1 -1
- package/dist/bmad/context-reader.d.ts +0 -71
- package/dist/bmad/context-reader.d.ts.map +0 -1
- package/dist/bmad/context-reader.js +0 -369
- package/dist/bmad/context-reader.js.map +0 -1
- package/dist/bmad/context-reader.test.d.ts +0 -71
- package/dist/bmad/context-reader.test.d.ts.map +0 -1
- package/dist/bmad/context-reader.test.js +0 -878
- package/dist/bmad/context-reader.test.js.map +0 -1
- package/dist/bmad/epics-parser.d.ts +0 -61
- package/dist/bmad/epics-parser.d.ts.map +0 -1
- package/dist/bmad/epics-parser.js +0 -331
- package/dist/bmad/epics-parser.js.map +0 -1
- package/dist/bmad/epics-parser.test.d.ts +0 -7
- package/dist/bmad/epics-parser.test.d.ts.map +0 -1
- package/dist/bmad/epics-parser.test.js +0 -449
- package/dist/bmad/epics-parser.test.js.map +0 -1
- package/dist/bmad/index.d.ts +0 -11
- package/dist/bmad/index.d.ts.map +0 -1
- package/dist/bmad/index.js +0 -24
- package/dist/bmad/index.js.map +0 -1
- package/dist/bmad/status-sync.d.ts +0 -173
- package/dist/bmad/status-sync.d.ts.map +0 -1
- package/dist/bmad/status-sync.js +0 -463
- package/dist/bmad/status-sync.js.map +0 -1
- package/dist/bmad/status-sync.test.d.ts +0 -7
- package/dist/bmad/status-sync.test.d.ts.map +0 -1
- package/dist/bmad/status-sync.test.js +0 -702
- package/dist/bmad/status-sync.test.js.map +0 -1
- package/dist/bmad/story-exporter.d.ts +0 -55
- package/dist/bmad/story-exporter.d.ts.map +0 -1
- package/dist/bmad/story-exporter.js +0 -170
- package/dist/bmad/story-exporter.js.map +0 -1
- package/dist/bmad/story-exporter.test.d.ts +0 -51
- package/dist/bmad/story-exporter.test.d.ts.map +0 -1
- package/dist/bmad/story-exporter.test.js +0 -603
- package/dist/bmad/story-exporter.test.js.map +0 -1
- package/dist/bmad/story-parser.d.ts +0 -44
- package/dist/bmad/story-parser.d.ts.map +0 -1
- package/dist/bmad/story-parser.js +0 -307
- package/dist/bmad/story-parser.js.map +0 -1
- package/dist/bmad/story-parser.test.d.ts +0 -44
- package/dist/bmad/story-parser.test.d.ts.map +0 -1
- package/dist/bmad/story-parser.test.js +0 -693
- package/dist/bmad/story-parser.test.js.map +0 -1
- package/dist/cli/commands/command.d.ts +0 -28
- package/dist/cli/commands/command.d.ts.map +0 -1
- package/dist/cli/commands/command.js +0 -399
- package/dist/cli/commands/command.js.map +0 -1
- package/dist/cli/commands/cyclist.d.ts +0 -46
- package/dist/cli/commands/cyclist.d.ts.map +0 -1
- package/dist/cli/commands/cyclist.js +0 -196
- package/dist/cli/commands/cyclist.js.map +0 -1
- package/dist/cli/commands/cyclist.test.d.ts +0 -13
- package/dist/cli/commands/cyclist.test.d.ts.map +0 -1
- package/dist/cli/commands/cyclist.test.js +0 -245
- package/dist/cli/commands/cyclist.test.js.map +0 -1
- package/dist/cli/commands/doctor.d.ts +0 -9
- package/dist/cli/commands/doctor.d.ts.map +0 -1
- package/dist/cli/commands/doctor.js +0 -652
- package/dist/cli/commands/doctor.js.map +0 -1
- package/dist/cli/commands/init.d.ts +0 -8
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/init.js +0 -524
- package/dist/cli/commands/init.js.map +0 -1
- package/dist/cli/commands/skill.d.ts +0 -28
- package/dist/cli/commands/skill.d.ts.map +0 -1
- package/dist/cli/commands/skill.js +0 -416
- package/dist/cli/commands/skill.js.map +0 -1
- package/dist/cli/commands/theme.d.ts +0 -21
- package/dist/cli/commands/theme.d.ts.map +0 -1
- package/dist/cli/commands/theme.js +0 -201
- package/dist/cli/commands/theme.js.map +0 -1
- package/dist/cli/commands/uninstall.d.ts +0 -8
- package/dist/cli/commands/uninstall.d.ts.map +0 -1
- package/dist/cli/commands/uninstall.js +0 -237
- package/dist/cli/commands/uninstall.js.map +0 -1
- package/dist/cli/commands/update.d.ts +0 -9
- package/dist/cli/commands/update.d.ts.map +0 -1
- package/dist/cli/commands/update.js +0 -418
- package/dist/cli/commands/update.js.map +0 -1
- package/dist/cli/commands/version.d.ts +0 -2
- package/dist/cli/commands/version.d.ts.map +0 -1
- package/dist/cli/commands/version.js +0 -28
- package/dist/cli/commands/version.js.map +0 -1
- package/dist/cli/customization.test.d.ts +0 -12
- package/dist/cli/customization.test.d.ts.map +0 -1
- package/dist/cli/customization.test.js +0 -84
- package/dist/cli/customization.test.js.map +0 -1
- package/dist/cli/cyclist-migration.test.d.ts +0 -16
- package/dist/cli/cyclist-migration.test.d.ts.map +0 -1
- package/dist/cli/cyclist-migration.test.js +0 -225
- package/dist/cli/cyclist-migration.test.js.map +0 -1
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -174
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/ocean-profiles.test.d.ts +0 -13
- package/dist/cli/ocean-profiles.test.d.ts.map +0 -1
- package/dist/cli/ocean-profiles.test.js +0 -134
- package/dist/cli/ocean-profiles.test.js.map +0 -1
- package/dist/cli/theme-maker.test.d.ts +0 -11
- package/dist/cli/theme-maker.test.d.ts.map +0 -1
- package/dist/cli/theme-maker.test.js +0 -356
- package/dist/cli/theme-maker.test.js.map +0 -1
- package/dist/cli/utils/constants.d.ts +0 -66
- package/dist/cli/utils/constants.d.ts.map +0 -1
- package/dist/cli/utils/constants.js +0 -54
- package/dist/cli/utils/constants.js.map +0 -1
- package/dist/cli/utils/files.d.ts.map +0 -1
- package/dist/cli/utils/files.js.map +0 -1
- package/dist/cli/utils/logger.d.ts +0 -26
- package/dist/cli/utils/logger.d.ts.map +0 -1
- package/dist/cli/utils/logger.js +0 -88
- package/dist/cli/utils/logger.js.map +0 -1
- package/dist/cli/utils/manifest.d.ts.map +0 -1
- package/dist/cli/utils/manifest.js.map +0 -1
- package/dist/cli/utils/node-modules.d.ts +0 -6
- package/dist/cli/utils/node-modules.d.ts.map +0 -1
- package/dist/cli/utils/node-modules.js +0 -31
- package/dist/cli/utils/node-modules.js.map +0 -1
- package/dist/cli/utils/prompts.d.ts +0 -34
- package/dist/cli/utils/prompts.d.ts.map +0 -1
- package/dist/cli/utils/prompts.js +0 -93
- package/dist/cli/utils/prompts.js.map +0 -1
- package/dist/cli/utils/symlinks.d.ts +0 -29
- package/dist/cli/utils/symlinks.d.ts.map +0 -1
- package/dist/cli/utils/symlinks.js +0 -181
- package/dist/cli/utils/symlinks.js.map +0 -1
- package/dist/cli/utils/themes.d.ts +0 -101
- package/dist/cli/utils/themes.d.ts.map +0 -1
- package/dist/cli/utils/themes.js +0 -373
- package/dist/cli/utils/themes.js.map +0 -1
- package/dist/cli/utils/themes.test.d.ts +0 -12
- package/dist/cli/utils/themes.test.d.ts.map +0 -1
- package/dist/cli/utils/themes.test.js +0 -147
- package/dist/cli/utils/themes.test.js.map +0 -1
- package/dist/cli/utils/version.d.ts.map +0 -1
- package/dist/cli/utils/version.js.map +0 -1
- package/dist/cli/workspace.test.d.ts +0 -8
- package/dist/cli/workspace.test.d.ts.map +0 -1
- package/dist/cli/workspace.test.js +0 -151
- package/dist/cli/workspace.test.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jira/jira-epic-creation.d.ts +0 -109
- package/dist/jira/jira-epic-creation.d.ts.map +0 -1
- package/dist/jira/jira-epic-creation.js +0 -253
- package/dist/jira/jira-epic-creation.js.map +0 -1
- package/dist/jira/jira-epic-creation.test.d.ts +0 -16
- package/dist/jira/jira-epic-creation.test.d.ts.map +0 -1
- package/dist/jira/jira-epic-creation.test.js +0 -387
- package/dist/jira/jira-epic-creation.test.js.map +0 -1
- package/dist/jira/jira-sprint-sync.d.ts +0 -247
- package/dist/jira/jira-sprint-sync.d.ts.map +0 -1
- package/dist/jira/jira-sprint-sync.js +0 -670
- package/dist/jira/jira-sprint-sync.js.map +0 -1
- package/dist/jira/jira-sprint-sync.test.d.ts +0 -16
- package/dist/jira/jira-sprint-sync.test.d.ts.map +0 -1
- package/dist/jira/jira-sprint-sync.test.js +0 -845
- package/dist/jira/jira-sprint-sync.test.js.map +0 -1
- package/dist/permissions/index.d.ts.map +0 -1
- package/dist/permissions/index.js.map +0 -1
- package/dist/permissions/permission-schema.d.ts.map +0 -1
- package/dist/permissions/permission-schema.js.map +0 -1
- package/dist/permissions/permission-schema.test.d.ts +0 -40
- package/dist/permissions/permission-schema.test.d.ts.map +0 -1
- package/dist/permissions/permission-schema.test.js +0 -367
- package/dist/permissions/permission-schema.test.js.map +0 -1
- package/dist/scripts/add-ocean-profiles.d.ts +0 -9
- package/dist/scripts/add-ocean-profiles.d.ts.map +0 -1
- package/dist/scripts/add-ocean-profiles.js +0 -695
- package/dist/scripts/add-ocean-profiles.js.map +0 -1
- package/dist/scripts/benchmark-integration.d.ts +0 -182
- package/dist/scripts/benchmark-integration.d.ts.map +0 -1
- package/dist/scripts/benchmark-integration.js +0 -691
- package/dist/scripts/benchmark-integration.js.map +0 -1
- package/dist/scripts/benchmark-integration.test.d.ts +0 -13
- package/dist/scripts/benchmark-integration.test.d.ts.map +0 -1
- package/dist/scripts/benchmark-integration.test.js +0 -680
- package/dist/scripts/benchmark-integration.test.js.map +0 -1
- package/dist/scripts/debugging-scenarios.test.d.ts +0 -18
- package/dist/scripts/debugging-scenarios.test.d.ts.map +0 -1
- package/dist/scripts/debugging-scenarios.test.js +0 -317
- package/dist/scripts/debugging-scenarios.test.js.map +0 -1
- package/dist/scripts/generate-all-spiders.d.ts +0 -10
- package/dist/scripts/generate-all-spiders.d.ts.map +0 -1
- package/dist/scripts/generate-all-spiders.js +0 -306
- package/dist/scripts/generate-all-spiders.js.map +0 -1
- package/dist/scripts/generate-report.d.ts +0 -65
- package/dist/scripts/generate-report.d.ts.map +0 -1
- package/dist/scripts/generate-report.js +0 -378
- package/dist/scripts/generate-report.js.map +0 -1
- package/dist/scripts/generate-report.test.d.ts +0 -13
- package/dist/scripts/generate-report.test.d.ts.map +0 -1
- package/dist/scripts/generate-report.test.js +0 -363
- package/dist/scripts/generate-report.test.js.map +0 -1
- package/dist/scripts/generate-spider-report.d.ts +0 -65
- package/dist/scripts/generate-spider-report.d.ts.map +0 -1
- package/dist/scripts/generate-spider-report.js +0 -366
- package/dist/scripts/generate-spider-report.js.map +0 -1
- package/dist/scripts/generate-spider-report.test.d.ts +0 -13
- package/dist/scripts/generate-spider-report.test.d.ts.map +0 -1
- package/dist/scripts/generate-spider-report.test.js +0 -367
- package/dist/scripts/generate-spider-report.test.js.map +0 -1
- package/dist/scripts/generate-spider.d.ts +0 -47
- package/dist/scripts/generate-spider.d.ts.map +0 -1
- package/dist/scripts/generate-spider.js +0 -338
- package/dist/scripts/generate-spider.js.map +0 -1
- package/dist/scripts/generate-spider.test.d.ts +0 -14
- package/dist/scripts/generate-spider.test.d.ts.map +0 -1
- package/dist/scripts/generate-spider.test.js +0 -271
- package/dist/scripts/generate-spider.test.js.map +0 -1
- package/dist/scripts/job-fair-aggregator.d.ts.map +0 -1
- package/dist/scripts/job-fair-aggregator.js.map +0 -1
- package/dist/scripts/job-fair-aggregator.test.d.ts +0 -14
- package/dist/scripts/job-fair-aggregator.test.d.ts.map +0 -1
- package/dist/scripts/job-fair-aggregator.test.js +0 -616
- package/dist/scripts/job-fair-aggregator.test.js.map +0 -1
- package/dist/scripts/run-ci.test.d.ts +0 -20
- package/dist/scripts/run-ci.test.d.ts.map +0 -1
- package/dist/scripts/run-ci.test.js +0 -127
- package/dist/scripts/run-ci.test.js.map +0 -1
- package/dist/scripts/theme-detail.test.d.ts +0 -10
- package/dist/scripts/theme-detail.test.d.ts.map +0 -1
- package/dist/scripts/theme-detail.test.js +0 -199
- package/dist/scripts/theme-detail.test.js.map +0 -1
- package/dist/scripts/validate-ocean-profiles.d.ts +0 -9
- package/dist/scripts/validate-ocean-profiles.d.ts.map +0 -1
- package/dist/scripts/validate-ocean-profiles.js +0 -130
- package/dist/scripts/validate-ocean-profiles.js.map +0 -1
- package/dist/workflow/gate-handler.d.ts +0 -94
- package/dist/workflow/gate-handler.d.ts.map +0 -1
- package/dist/workflow/gate-handler.js +0 -189
- package/dist/workflow/gate-handler.js.map +0 -1
- package/dist/workflow/gate-handler.test.d.ts +0 -14
- package/dist/workflow/gate-handler.test.d.ts.map +0 -1
- package/dist/workflow/gate-handler.test.js +0 -543
- package/dist/workflow/gate-handler.test.js.map +0 -1
- package/dist/workflow/generic-handoff.d.ts +0 -281
- package/dist/workflow/generic-handoff.d.ts.map +0 -1
- package/dist/workflow/generic-handoff.js +0 -411
- package/dist/workflow/generic-handoff.js.map +0 -1
- package/dist/workflow/generic-handoff.test.d.ts +0 -21
- package/dist/workflow/generic-handoff.test.d.ts.map +0 -1
- package/dist/workflow/generic-handoff.test.js +0 -499
- package/dist/workflow/generic-handoff.test.js.map +0 -1
- package/dist/workflow/generic-sm-finish.d.ts +0 -89
- package/dist/workflow/generic-sm-finish.d.ts.map +0 -1
- package/dist/workflow/generic-sm-finish.js +0 -157
- package/dist/workflow/generic-sm-finish.js.map +0 -1
- package/dist/workflow/generic-sm-setup.d.ts +0 -138
- package/dist/workflow/generic-sm-setup.d.ts.map +0 -1
- package/dist/workflow/generic-sm-setup.js +0 -382
- package/dist/workflow/generic-sm-setup.js.map +0 -1
- package/dist/workflow/index.d.ts.map +0 -1
- package/dist/workflow/index.js.map +0 -1
- package/dist/workflow/session-state.d.ts +0 -92
- package/dist/workflow/session-state.d.ts.map +0 -1
- package/dist/workflow/session-state.js +0 -198
- package/dist/workflow/session-state.js.map +0 -1
- package/dist/workflow/session-state.test.d.ts +0 -8
- package/dist/workflow/session-state.test.d.ts.map +0 -1
- package/dist/workflow/session-state.test.js +0 -551
- package/dist/workflow/session-state.test.js.map +0 -1
- package/dist/workflow/sm-subagents.test.d.ts +0 -23
- package/dist/workflow/sm-subagents.test.d.ts.map +0 -1
- package/dist/workflow/sm-subagents.test.js +0 -727
- package/dist/workflow/sm-subagents.test.js.map +0 -1
- package/dist/workflow/step-parser.d.ts +0 -45
- package/dist/workflow/step-parser.d.ts.map +0 -1
- package/dist/workflow/step-parser.js +0 -147
- package/dist/workflow/step-parser.js.map +0 -1
- package/dist/workflow/step-parser.test.d.ts +0 -14
- package/dist/workflow/step-parser.test.d.ts.map +0 -1
- package/dist/workflow/step-parser.test.js +0 -470
- package/dist/workflow/step-parser.test.js.map +0 -1
- package/dist/workflow/story-workflow-routing.test.d.ts +0 -17
- package/dist/workflow/story-workflow-routing.test.d.ts.map +0 -1
- package/dist/workflow/story-workflow-routing.test.js +0 -559
- package/dist/workflow/story-workflow-routing.test.js.map +0 -1
- package/dist/workflow/test-cache.d.ts +0 -131
- package/dist/workflow/test-cache.d.ts.map +0 -1
- package/dist/workflow/test-cache.js +0 -226
- package/dist/workflow/test-cache.js.map +0 -1
- package/dist/workflow/test-cache.test.d.ts +0 -17
- package/dist/workflow/test-cache.test.d.ts.map +0 -1
- package/dist/workflow/test-cache.test.js +0 -438
- package/dist/workflow/test-cache.test.js.map +0 -1
- package/dist/workflow/trimodal.d.ts +0 -86
- package/dist/workflow/trimodal.d.ts.map +0 -1
- package/dist/workflow/trimodal.js +0 -118
- package/dist/workflow/trimodal.js.map +0 -1
- package/dist/workflow/trimodal.test.d.ts +0 -11
- package/dist/workflow/trimodal.test.d.ts.map +0 -1
- package/dist/workflow/trimodal.test.js +0 -395
- package/dist/workflow/trimodal.test.js.map +0 -1
- package/dist/workflow/variable-resolver.d.ts +0 -67
- package/dist/workflow/variable-resolver.d.ts.map +0 -1
- package/dist/workflow/variable-resolver.js +0 -156
- package/dist/workflow/variable-resolver.js.map +0 -1
- package/dist/workflow/variable-resolver.test.d.ts +0 -14
- package/dist/workflow/variable-resolver.test.d.ts.map +0 -1
- package/dist/workflow/variable-resolver.test.js +0 -400
- package/dist/workflow/variable-resolver.test.js.map +0 -1
- package/dist/workflow/workflow-executor.d.ts +0 -163
- package/dist/workflow/workflow-executor.d.ts.map +0 -1
- package/dist/workflow/workflow-executor.js +0 -197
- package/dist/workflow/workflow-executor.js.map +0 -1
- package/dist/workflow/workflow-executor.test.d.ts +0 -8
- package/dist/workflow/workflow-executor.test.d.ts.map +0 -1
- package/dist/workflow/workflow-executor.test.js +0 -444
- package/dist/workflow/workflow-executor.test.js.map +0 -1
- package/dist/workflow/workflow-loader.d.ts.map +0 -1
- package/dist/workflow/workflow-loader.js.map +0 -1
- package/dist/workflow/workflow-loader.test.d.ts +0 -15
- package/dist/workflow/workflow-loader.test.d.ts.map +0 -1
- package/dist/workflow/workflow-loader.test.js +0 -354
- package/dist/workflow/workflow-loader.test.js.map +0 -1
- package/dist/workflow/workflow-migration.test.d.ts +0 -17
- package/dist/workflow/workflow-migration.test.d.ts.map +0 -1
- package/dist/workflow/workflow-migration.test.js +0 -371
- package/dist/workflow/workflow-migration.test.js.map +0 -1
- package/dist/workflow/workflow-permissions.d.ts.map +0 -1
- package/dist/workflow/workflow-permissions.js.map +0 -1
- package/dist/workflow/workflow-permissions.test.d.ts +0 -15
- package/dist/workflow/workflow-permissions.test.d.ts.map +0 -1
- package/dist/workflow/workflow-permissions.test.js +0 -301
- package/dist/workflow/workflow-permissions.test.js.map +0 -1
- package/dist/workflow/workflow-router.d.ts.map +0 -1
- package/dist/workflow/workflow-router.js.map +0 -1
- package/dist/workflow/workflow-router.test.d.ts +0 -20
- package/dist/workflow/workflow-router.test.d.ts.map +0 -1
- package/dist/workflow/workflow-router.test.js +0 -607
- package/dist/workflow/workflow-router.test.js.map +0 -1
- package/dist/workflow/workflow-schema.d.ts.map +0 -1
- package/dist/workflow/workflow-schema.js.map +0 -1
- package/dist/workflow/workflow-schema.test.d.ts +0 -45
- package/dist/workflow/workflow-schema.test.d.ts.map +0 -1
- package/dist/workflow/workflow-schema.test.js +0 -512
- package/dist/workflow/workflow-schema.test.js.map +0 -1
- package/dist/workflow/workflow-stepped-schema.test.d.ts +0 -18
- package/dist/workflow/workflow-stepped-schema.test.d.ts.map +0 -1
- package/dist/workflow/workflow-stepped-schema.test.js +0 -608
- package/dist/workflow/workflow-stepped-schema.test.js.map +0 -1
|
@@ -1,281 +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 type { WorkflowDefinition, WorkflowPhase } from './workflow-schema.js';
|
|
14
|
-
/**
|
|
15
|
-
* Context for gate checks - provides test results, verdicts, etc.
|
|
16
|
-
*/
|
|
17
|
-
export interface GateContext {
|
|
18
|
-
/** For tests_fail gate: are tests currently failing? */
|
|
19
|
-
testsRed?: boolean;
|
|
20
|
-
/** For tests_pass gate: are all tests passing? */
|
|
21
|
-
testsGreen?: boolean;
|
|
22
|
-
/** Number of passing tests */
|
|
23
|
-
testPassCount?: number;
|
|
24
|
-
/** Number of failing tests */
|
|
25
|
-
testFailCount?: number;
|
|
26
|
-
/** For approval gate: approved or rejected */
|
|
27
|
-
verdict?: 'approved' | 'rejected';
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Options for getNextPhase to handle rejection loops
|
|
31
|
-
*/
|
|
32
|
-
export interface NextPhaseOptions {
|
|
33
|
-
/** For approval gates: determines forward vs loop-back */
|
|
34
|
-
verdict?: 'approved' | 'rejected';
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Result of checking a gate condition
|
|
38
|
-
*/
|
|
39
|
-
export interface GateCheckResult {
|
|
40
|
-
/** Whether the gate check passed */
|
|
41
|
-
passed: boolean;
|
|
42
|
-
/** Gate type that was checked (undefined if phase has no gate) */
|
|
43
|
-
gateType?: string;
|
|
44
|
-
/** Human-readable message (especially on failure) */
|
|
45
|
-
message?: string;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Context for handoff operations
|
|
49
|
-
*/
|
|
50
|
-
export interface HandoffContext {
|
|
51
|
-
/** Story ID being worked on */
|
|
52
|
-
storyId: string;
|
|
53
|
-
/** Current workflow name */
|
|
54
|
-
workflowName: string;
|
|
55
|
-
/** Current phase name */
|
|
56
|
-
currentPhase: string;
|
|
57
|
-
/** Session file path */
|
|
58
|
-
sessionFile: string;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Result of a handoff operation
|
|
62
|
-
*/
|
|
63
|
-
export interface HandoffResult {
|
|
64
|
-
/** Whether handoff succeeded */
|
|
65
|
-
success: boolean;
|
|
66
|
-
/** Next phase to transition to */
|
|
67
|
-
nextPhase?: string;
|
|
68
|
-
/** Next agent to invoke */
|
|
69
|
-
nextAgent?: string;
|
|
70
|
-
/** Error message if failed */
|
|
71
|
-
error?: string;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Parameters for formatting phase transition
|
|
75
|
-
*/
|
|
76
|
-
export interface PhaseTransitionParams {
|
|
77
|
-
workflowName: string;
|
|
78
|
-
fromPhase: string;
|
|
79
|
-
toPhase: string;
|
|
80
|
-
startedAt: string;
|
|
81
|
-
endedAt: string;
|
|
82
|
-
isRejection?: boolean;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Find a phase by name in a workflow definition
|
|
86
|
-
*
|
|
87
|
-
* @param workflow - The workflow definition to search
|
|
88
|
-
* @param phaseName - Name of the phase to find
|
|
89
|
-
* @returns The phase definition or null if not found
|
|
90
|
-
*
|
|
91
|
-
* @example
|
|
92
|
-
* ```typescript
|
|
93
|
-
* const phase = findCurrentPhase(workflow, 'red');
|
|
94
|
-
* if (phase) {
|
|
95
|
-
* console.log(`Found phase: ${phase.name}, agent: ${phase.agent}`);
|
|
96
|
-
* }
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
export declare function findCurrentPhase(workflow: WorkflowDefinition, phaseName: string): WorkflowPhase | null;
|
|
100
|
-
/**
|
|
101
|
-
* Get the next phase in the workflow
|
|
102
|
-
*
|
|
103
|
-
* For normal progression, returns the next phase in sequence.
|
|
104
|
-
* For rejection (verdict='rejected'), returns the phase to loop back to
|
|
105
|
-
* (typically the most recent phase with a tests_pass gate).
|
|
106
|
-
*
|
|
107
|
-
* @param workflow - The workflow definition
|
|
108
|
-
* @param currentPhaseName - Name of the current phase
|
|
109
|
-
* @param options - Options for handling rejection loops
|
|
110
|
-
* @returns The next phase or null if at end/not found
|
|
111
|
-
*
|
|
112
|
-
* @example
|
|
113
|
-
* ```typescript
|
|
114
|
-
* // Normal progression
|
|
115
|
-
* const next = getNextPhase(workflow, 'red');
|
|
116
|
-
*
|
|
117
|
-
* // Rejection loop
|
|
118
|
-
* const next = getNextPhase(workflow, 'review', { verdict: 'rejected' });
|
|
119
|
-
* ```
|
|
120
|
-
*/
|
|
121
|
-
export declare function getNextPhase(workflow: WorkflowDefinition, currentPhaseName: string, options?: NextPhaseOptions): WorkflowPhase | null;
|
|
122
|
-
/**
|
|
123
|
-
* Check if a gate condition is satisfied
|
|
124
|
-
*
|
|
125
|
-
* Gate types:
|
|
126
|
-
* - tests_fail: testsRed must be true
|
|
127
|
-
* - tests_pass: testsGreen must be true
|
|
128
|
-
* - approval: verdict must be provided (approved or rejected)
|
|
129
|
-
* - manual: always passes
|
|
130
|
-
* - (none): always passes
|
|
131
|
-
*
|
|
132
|
-
* @param workflow - The workflow definition
|
|
133
|
-
* @param phaseName - Name of the phase to check
|
|
134
|
-
* @param context - Gate check context with test results, verdicts, etc.
|
|
135
|
-
* @returns Gate check result
|
|
136
|
-
*
|
|
137
|
-
* @example
|
|
138
|
-
* ```typescript
|
|
139
|
-
* const result = checkGate(workflow, 'red', { testsRed: true });
|
|
140
|
-
* if (result.passed) {
|
|
141
|
-
* // Proceed with handoff
|
|
142
|
-
* }
|
|
143
|
-
* ```
|
|
144
|
-
*/
|
|
145
|
-
export declare function checkGate(workflow: WorkflowDefinition, phaseName: string, context: GateContext): GateCheckResult;
|
|
146
|
-
/**
|
|
147
|
-
* Format the workflow tracking section for a session file update
|
|
148
|
-
*
|
|
149
|
-
* @param params - Phase transition parameters
|
|
150
|
-
* @returns Markdown string for the workflow tracking section
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* ```typescript
|
|
154
|
-
* const markdown = formatPhaseTransition({
|
|
155
|
-
* workflowName: 'tdd',
|
|
156
|
-
* fromPhase: 'red',
|
|
157
|
-
* toPhase: 'green',
|
|
158
|
-
* startedAt: '2026-01-13T14:00:00Z',
|
|
159
|
-
* endedAt: '2026-01-13T14:30:00Z'
|
|
160
|
-
* });
|
|
161
|
-
* ```
|
|
162
|
-
*/
|
|
163
|
-
export declare function formatPhaseTransition(params: PhaseTransitionParams): string;
|
|
164
|
-
/**
|
|
165
|
-
* Calculate duration between two ISO 8601 timestamps
|
|
166
|
-
*
|
|
167
|
-
* @param startedAt - Start timestamp
|
|
168
|
-
* @param endedAt - End timestamp
|
|
169
|
-
* @returns Formatted duration string (e.g., "30m", "2h 30m", "45s")
|
|
170
|
-
*/
|
|
171
|
-
export declare function calculateDuration(startedAt: string, endedAt: string): string;
|
|
172
|
-
/**
|
|
173
|
-
* Handoff mode type - auto triggers immediately, manual prompts first
|
|
174
|
-
*/
|
|
175
|
-
export type HandoffMode = 'auto' | 'manual';
|
|
176
|
-
/**
|
|
177
|
-
* Handoff behavior based on mode
|
|
178
|
-
*/
|
|
179
|
-
export interface HandoffBehavior {
|
|
180
|
-
/** What action to take */
|
|
181
|
-
action: 'immediate' | 'prompt';
|
|
182
|
-
/** Whether user confirmation is required */
|
|
183
|
-
requiresConfirmation: boolean;
|
|
184
|
-
/** Message to show user (for prompt action) */
|
|
185
|
-
message?: string;
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Entry for handoff history tracking
|
|
189
|
-
*/
|
|
190
|
-
export interface HandoffHistoryEntry {
|
|
191
|
-
phase: string;
|
|
192
|
-
agent: string;
|
|
193
|
-
timestamp: string;
|
|
194
|
-
handoffMode: HandoffMode;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Read handoff mode from Cyclist settings file
|
|
198
|
-
* Returns 'manual' as default if file doesn't exist or is invalid
|
|
199
|
-
*
|
|
200
|
-
* @param settingsPath - Path to the settings file (JSON or YAML)
|
|
201
|
-
* @returns The handoff mode setting
|
|
202
|
-
*/
|
|
203
|
-
export declare function readHandoffMode(settingsPath: string): HandoffMode;
|
|
204
|
-
/**
|
|
205
|
-
* Parse handoff mode from JSON string
|
|
206
|
-
* Handles both new format (handoff_mode) and legacy format (auto_handoff boolean)
|
|
207
|
-
*
|
|
208
|
-
* @param jsonContent - JSON string containing settings
|
|
209
|
-
* @returns The handoff mode setting
|
|
210
|
-
*/
|
|
211
|
-
export declare function parseHandoffModeFromJson(jsonContent: string): HandoffMode;
|
|
212
|
-
/**
|
|
213
|
-
* Parse handoff mode from YAML string
|
|
214
|
-
* Handles both new format (handoff_mode) and legacy format (auto_handoff boolean)
|
|
215
|
-
*
|
|
216
|
-
* @param yamlContent - YAML string containing settings
|
|
217
|
-
* @returns The handoff mode setting
|
|
218
|
-
*/
|
|
219
|
-
export declare function parseHandoffModeFromYaml(yamlContent: string): HandoffMode;
|
|
220
|
-
/**
|
|
221
|
-
* Get handoff behavior based on mode
|
|
222
|
-
*
|
|
223
|
-
* @param mode - The handoff mode setting
|
|
224
|
-
* @returns Behavior configuration for the mode
|
|
225
|
-
*/
|
|
226
|
-
export declare function getHandoffBehavior(mode: HandoffMode): HandoffBehavior;
|
|
227
|
-
/**
|
|
228
|
-
* Format handoff history entry for session file
|
|
229
|
-
* Creates a markdown section with table row for the handoff
|
|
230
|
-
*
|
|
231
|
-
* @param entry - Handoff history entry to format
|
|
232
|
-
* @returns Markdown string for the handoff history section
|
|
233
|
-
*/
|
|
234
|
-
export declare function formatHandoffHistory(entry: HandoffHistoryEntry): string;
|
|
235
|
-
/**
|
|
236
|
-
* Threshold for context percentage to trigger context clear
|
|
237
|
-
* When auto mode is enabled and context exceeds this threshold, emit CONTEXT_CLEAR
|
|
238
|
-
*/
|
|
239
|
-
export declare const CONTEXT_CLEAR_THRESHOLD = 60;
|
|
240
|
-
/**
|
|
241
|
-
* Parameters for context clear marker decision
|
|
242
|
-
*/
|
|
243
|
-
export interface ContextClearParams {
|
|
244
|
-
/** Current handoff mode from settings */
|
|
245
|
-
handoffMode: HandoffMode;
|
|
246
|
-
/** Current context usage percentage (0-100) */
|
|
247
|
-
contextPercent: number;
|
|
248
|
-
/** Next agent to load after clear (for marker value) */
|
|
249
|
-
nextAgent?: string;
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* Determine if CONTEXT_CLEAR marker should be emitted
|
|
253
|
-
*
|
|
254
|
-
* Returns true when:
|
|
255
|
-
* - handoffMode is 'auto'
|
|
256
|
-
* - contextPercent exceeds CONTEXT_CLEAR_THRESHOLD
|
|
257
|
-
*
|
|
258
|
-
* @param params - Context clear parameters
|
|
259
|
-
* @returns true if CONTEXT_CLEAR should be emitted
|
|
260
|
-
*/
|
|
261
|
-
export declare function shouldEmitContextClear(params: ContextClearParams): boolean;
|
|
262
|
-
/**
|
|
263
|
-
* Format the CYCLIST marker for context clear or regular handoff
|
|
264
|
-
*
|
|
265
|
-
* When auto mode and high context: returns CONTEXT_CLEAR marker
|
|
266
|
-
* Otherwise: returns regular HANDOFF marker
|
|
267
|
-
*
|
|
268
|
-
* @param params - Context clear parameters including nextAgent
|
|
269
|
-
* @returns Marker string (<!-- CYCLIST:CONTEXT_CLEAR:/agent --> or <!-- CYCLIST:HANDOFF:/agent -->)
|
|
270
|
-
*/
|
|
271
|
-
export declare function formatContextClearMarker(params: ContextClearParams): string;
|
|
272
|
-
/**
|
|
273
|
-
* Format a human-readable output message for context clear handoffs
|
|
274
|
-
*
|
|
275
|
-
* Includes context percentage and the marker for Cyclist to detect
|
|
276
|
-
*
|
|
277
|
-
* @param params - Context clear parameters
|
|
278
|
-
* @returns Formatted output string for display
|
|
279
|
-
*/
|
|
280
|
-
export declare function formatContextClearOutput(params: ContextClearParams): string;
|
|
281
|
-
//# sourceMappingURL=generic-handoff.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generic-handoff.d.ts","sourceRoot":"","sources":["../../src/workflow/generic-handoff.ts"],"names":[],"mappings":"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"}
|
|
@@ -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
|