@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,197 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workflow Executor for MSSCI-12084
|
|
3
|
-
*
|
|
4
|
-
* Implements /workflow start, resume, and status commands for stepped workflows.
|
|
5
|
-
* Coordinates step loading, session state tracking, and progress reporting.
|
|
6
|
-
*/
|
|
7
|
-
import { initWorkflowState, updateWorkflowState, parseSessionState, updateSessionContent, } from './session-state.js';
|
|
8
|
-
import { parseStepFromPath } from './step-parser.js';
|
|
9
|
-
import { resolveStepVariables } from './variable-resolver.js';
|
|
10
|
-
/**
|
|
11
|
-
* Start a new stepped workflow
|
|
12
|
-
*
|
|
13
|
-
* @param workflow - Workflow definition
|
|
14
|
-
* @param sessionContent - Current session file content (or empty for new)
|
|
15
|
-
* @param mode - Optional tri-modal mode (default: workflow default or 'create')
|
|
16
|
-
* @returns StartResult with state, first step, and updated session
|
|
17
|
-
*/
|
|
18
|
-
export async function startWorkflow(workflow, sessionContent, mode) {
|
|
19
|
-
// Determine mode: explicit > workflow default > 'create'
|
|
20
|
-
const effectiveMode = mode ?? workflow.modes?.default ?? 'create';
|
|
21
|
-
// Initialize workflow state
|
|
22
|
-
const state = initWorkflowState(workflow.name, workflow.type, effectiveMode);
|
|
23
|
-
// Update session content with workflow state
|
|
24
|
-
const updateResult = updateSessionContent(sessionContent, state);
|
|
25
|
-
if (!updateResult.success || !updateResult.content) {
|
|
26
|
-
return {
|
|
27
|
-
success: false,
|
|
28
|
-
error: updateResult.error ?? 'Failed to update session content',
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
// Try to load step 1 (may fail if step file doesn't exist)
|
|
32
|
-
const step = await loadStep(workflow, 1, workflow.variables);
|
|
33
|
-
return {
|
|
34
|
-
success: true,
|
|
35
|
-
state,
|
|
36
|
-
step: step ?? undefined,
|
|
37
|
-
sessionContent: updateResult.content,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Resume an existing stepped workflow from last completed step
|
|
42
|
-
*
|
|
43
|
-
* @param workflow - Workflow definition
|
|
44
|
-
* @param sessionContent - Current session file content with state
|
|
45
|
-
* @returns ResumeResult with state and next step
|
|
46
|
-
*/
|
|
47
|
-
export async function resumeWorkflow(workflow, sessionContent) {
|
|
48
|
-
// Parse existing state from session
|
|
49
|
-
const parseResult = parseSessionState(sessionContent);
|
|
50
|
-
if (!parseResult.success || !parseResult.state) {
|
|
51
|
-
return {
|
|
52
|
-
success: false,
|
|
53
|
-
error: 'No workflow state found in session',
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
const state = parseResult.state;
|
|
57
|
-
// Check if workflow is already complete
|
|
58
|
-
if (state.status === 'completed') {
|
|
59
|
-
return {
|
|
60
|
-
success: true,
|
|
61
|
-
state,
|
|
62
|
-
isComplete: true,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
// Try to load the current step
|
|
66
|
-
const step = await loadStep(workflow, state.currentStep, workflow.variables);
|
|
67
|
-
return {
|
|
68
|
-
success: true,
|
|
69
|
-
state,
|
|
70
|
-
step: step ?? undefined,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Get current workflow status from session
|
|
75
|
-
*
|
|
76
|
-
* @param sessionContent - Session file content
|
|
77
|
-
* @param totalSteps - Total number of steps in workflow
|
|
78
|
-
* @returns StatusResult with progress information
|
|
79
|
-
*/
|
|
80
|
-
export function getWorkflowStatus(sessionContent, totalSteps) {
|
|
81
|
-
// Parse state from session
|
|
82
|
-
const parseResult = parseSessionState(sessionContent);
|
|
83
|
-
if (!parseResult.success || !parseResult.state) {
|
|
84
|
-
return {
|
|
85
|
-
success: false,
|
|
86
|
-
error: 'No workflow state found in session',
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
const state = parseResult.state;
|
|
90
|
-
// Calculate completion percentage
|
|
91
|
-
const completedCount = state.stepsCompleted.length;
|
|
92
|
-
const completionPercent = totalSteps > 0
|
|
93
|
-
? Math.round((completedCount / totalSteps) * 100)
|
|
94
|
-
: 0;
|
|
95
|
-
const status = {
|
|
96
|
-
name: state.name,
|
|
97
|
-
type: state.type,
|
|
98
|
-
mode: state.mode,
|
|
99
|
-
currentStep: state.currentStep,
|
|
100
|
-
totalSteps,
|
|
101
|
-
stepsCompleted: state.stepsCompleted,
|
|
102
|
-
completionPercent,
|
|
103
|
-
status: state.status,
|
|
104
|
-
started: state.started,
|
|
105
|
-
lastUpdated: state.lastUpdated,
|
|
106
|
-
};
|
|
107
|
-
return {
|
|
108
|
-
success: true,
|
|
109
|
-
status,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Load step file for a specific step number
|
|
114
|
-
*
|
|
115
|
-
* @param workflow - Workflow definition
|
|
116
|
-
* @param stepNumber - Step number to load
|
|
117
|
-
* @param variables - Variables for content resolution
|
|
118
|
-
* @returns ParsedStep with resolved content
|
|
119
|
-
*/
|
|
120
|
-
export async function loadStep(workflow, stepNumber, variables) {
|
|
121
|
-
// Build step file path
|
|
122
|
-
const pattern = workflow.steps.pattern ?? 'step-*.md';
|
|
123
|
-
const paddedNum = String(stepNumber).padStart(2, '0');
|
|
124
|
-
// Replace * in pattern with padded step number
|
|
125
|
-
const filename = pattern.replace('*', paddedNum);
|
|
126
|
-
const stepPath = `${workflow.steps.path}/${filename}`;
|
|
127
|
-
try {
|
|
128
|
-
const parseResult = await parseStepFromPath(stepPath);
|
|
129
|
-
if (!parseResult.success || !parseResult.step) {
|
|
130
|
-
return null;
|
|
131
|
-
}
|
|
132
|
-
// Resolve variables in step content if provided
|
|
133
|
-
if (variables && Object.keys(variables).length > 0) {
|
|
134
|
-
const resolveResult = resolveStepVariables(parseResult.step.content, {
|
|
135
|
-
workflowVars: variables,
|
|
136
|
-
});
|
|
137
|
-
parseResult.step.content = resolveResult.content;
|
|
138
|
-
}
|
|
139
|
-
return parseResult.step;
|
|
140
|
-
}
|
|
141
|
-
catch {
|
|
142
|
-
// Step file doesn't exist or can't be read
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Complete current step and advance workflow state
|
|
148
|
-
*
|
|
149
|
-
* @param sessionContent - Current session content
|
|
150
|
-
* @param stepNumber - Step number being completed
|
|
151
|
-
* @param nextStep - Optional specific next step (for skip scenarios)
|
|
152
|
-
* @returns Updated session content
|
|
153
|
-
*/
|
|
154
|
-
export function completeStep(sessionContent, stepNumber, nextStep) {
|
|
155
|
-
// Parse existing state
|
|
156
|
-
const parseResult = parseSessionState(sessionContent);
|
|
157
|
-
if (!parseResult.success || !parseResult.state) {
|
|
158
|
-
return sessionContent; // Return unchanged if no state
|
|
159
|
-
}
|
|
160
|
-
// Update state with completed step
|
|
161
|
-
const updatedState = updateWorkflowState(parseResult.state, stepNumber, nextStep);
|
|
162
|
-
// Update session content
|
|
163
|
-
const updateResult = updateSessionContent(sessionContent, updatedState);
|
|
164
|
-
return updateResult.content ?? sessionContent;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Check if workflow has an in-progress state in session
|
|
168
|
-
*
|
|
169
|
-
* @param sessionContent - Session file content
|
|
170
|
-
* @returns true if workflow is in progress
|
|
171
|
-
*/
|
|
172
|
-
export function hasActiveWorkflow(sessionContent) {
|
|
173
|
-
const parseResult = parseSessionState(sessionContent);
|
|
174
|
-
if (!parseResult.success || !parseResult.state) {
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
// Active means in_progress or paused (not completed)
|
|
178
|
-
return parseResult.state.status === 'in_progress' || parseResult.state.status === 'paused';
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Detect incomplete workflow from session and return name
|
|
182
|
-
*
|
|
183
|
-
* @param sessionContent - Session file content
|
|
184
|
-
* @returns Workflow name if incomplete workflow found, undefined otherwise
|
|
185
|
-
*/
|
|
186
|
-
export function detectIncompleteWorkflow(sessionContent) {
|
|
187
|
-
const parseResult = parseSessionState(sessionContent);
|
|
188
|
-
if (!parseResult.success || !parseResult.state) {
|
|
189
|
-
return undefined;
|
|
190
|
-
}
|
|
191
|
-
// Only return name if workflow is not completed
|
|
192
|
-
if (parseResult.state.status === 'completed') {
|
|
193
|
-
return undefined;
|
|
194
|
-
}
|
|
195
|
-
return parseResult.state.name;
|
|
196
|
-
}
|
|
197
|
-
//# sourceMappingURL=workflow-executor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-executor.js","sourceRoot":"","sources":["../../src/workflow/workflow-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-executor.test.d.ts","sourceRoot":"","sources":["../../src/workflow/workflow-executor.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -1,444 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workflow Executor Tests for MSSCI-12084
|
|
3
|
-
*
|
|
4
|
-
* Tests for /workflow start, resume, and status commands.
|
|
5
|
-
* Covers all 8 acceptance criteria plus edge cases.
|
|
6
|
-
*/
|
|
7
|
-
import { describe, it } from 'node:test';
|
|
8
|
-
import assert from 'node:assert';
|
|
9
|
-
import { startWorkflow, resumeWorkflow, getWorkflowStatus, loadStep, completeStep, hasActiveWorkflow, detectIncompleteWorkflow, } from './workflow-executor.js';
|
|
10
|
-
// =============================================================================
|
|
11
|
-
// Test Fixtures
|
|
12
|
-
// =============================================================================
|
|
13
|
-
const mockWorkflow = {
|
|
14
|
-
name: 'architecture',
|
|
15
|
-
type: 'stepped',
|
|
16
|
-
description: 'Architecture design workflow',
|
|
17
|
-
steps: {
|
|
18
|
-
path: '/workflows/architecture/steps',
|
|
19
|
-
pattern: 'step-*.md',
|
|
20
|
-
},
|
|
21
|
-
modes: {
|
|
22
|
-
default: 'create',
|
|
23
|
-
available: ['create', 'validate', 'edit'],
|
|
24
|
-
},
|
|
25
|
-
variables: {
|
|
26
|
-
project_name: 'Test Project',
|
|
27
|
-
},
|
|
28
|
-
gates: {
|
|
29
|
-
after_steps: [2, 5],
|
|
30
|
-
},
|
|
31
|
-
totalSteps: 7,
|
|
32
|
-
};
|
|
33
|
-
const emptySession = `# Story Test
|
|
34
|
-
|
|
35
|
-
## Story Overview
|
|
36
|
-
- **Epic:** Test Epic
|
|
37
|
-
|
|
38
|
-
## Acceptance Criteria
|
|
39
|
-
- [ ] AC1
|
|
40
|
-
`;
|
|
41
|
-
const sessionWithWorkflowState = `# Story Test
|
|
42
|
-
|
|
43
|
-
## Story Overview
|
|
44
|
-
- **Epic:** Test Epic
|
|
45
|
-
|
|
46
|
-
## Workflow State
|
|
47
|
-
- **Workflow Name:** architecture
|
|
48
|
-
- **Type:** stepped
|
|
49
|
-
- **Mode:** create
|
|
50
|
-
- **Started:** 2026-01-20T10:00:00.000Z
|
|
51
|
-
- **Last Updated:** 2026-01-20T11:30:00.000Z
|
|
52
|
-
- **Current Step:** 3
|
|
53
|
-
- **Steps Completed:** [1, 2]
|
|
54
|
-
- **Status:** in_progress
|
|
55
|
-
|
|
56
|
-
## Acceptance Criteria
|
|
57
|
-
- [ ] AC1
|
|
58
|
-
`;
|
|
59
|
-
const sessionWithCompletedWorkflow = `# Story Test
|
|
60
|
-
|
|
61
|
-
## Workflow State
|
|
62
|
-
- **Workflow Name:** architecture
|
|
63
|
-
- **Type:** stepped
|
|
64
|
-
- **Mode:** create
|
|
65
|
-
- **Started:** 2026-01-20T10:00:00.000Z
|
|
66
|
-
- **Last Updated:** 2026-01-20T15:00:00.000Z
|
|
67
|
-
- **Current Step:** 7
|
|
68
|
-
- **Steps Completed:** [1, 2, 3, 4, 5, 6, 7]
|
|
69
|
-
- **Status:** completed
|
|
70
|
-
`;
|
|
71
|
-
// =============================================================================
|
|
72
|
-
// AC1: /workflow start <name> [--mode create|validate|edit] implemented
|
|
73
|
-
// =============================================================================
|
|
74
|
-
describe('MSSCI-12084: Workflow Executor', () => {
|
|
75
|
-
describe('AC1: /workflow start command', () => {
|
|
76
|
-
it('should start workflow with given name', async () => {
|
|
77
|
-
const result = await startWorkflow(mockWorkflow, emptySession);
|
|
78
|
-
assert.strictEqual(result.success, true);
|
|
79
|
-
assert.ok(result.state);
|
|
80
|
-
assert.strictEqual(result.state.name, 'architecture');
|
|
81
|
-
assert.strictEqual(result.state.type, 'stepped');
|
|
82
|
-
});
|
|
83
|
-
it('should accept --mode flag for tri-modal selection', async () => {
|
|
84
|
-
const result = await startWorkflow(mockWorkflow, emptySession, 'validate');
|
|
85
|
-
assert.strictEqual(result.success, true);
|
|
86
|
-
assert.strictEqual(result.state?.mode, 'validate');
|
|
87
|
-
});
|
|
88
|
-
it('should accept create mode', async () => {
|
|
89
|
-
const result = await startWorkflow(mockWorkflow, emptySession, 'create');
|
|
90
|
-
assert.strictEqual(result.success, true);
|
|
91
|
-
assert.strictEqual(result.state?.mode, 'create');
|
|
92
|
-
});
|
|
93
|
-
it('should accept validate mode', async () => {
|
|
94
|
-
const result = await startWorkflow(mockWorkflow, emptySession, 'validate');
|
|
95
|
-
assert.strictEqual(result.success, true);
|
|
96
|
-
assert.strictEqual(result.state?.mode, 'validate');
|
|
97
|
-
});
|
|
98
|
-
it('should accept edit mode', async () => {
|
|
99
|
-
const result = await startWorkflow(mockWorkflow, emptySession, 'edit');
|
|
100
|
-
assert.strictEqual(result.success, true);
|
|
101
|
-
assert.strictEqual(result.state?.mode, 'edit');
|
|
102
|
-
});
|
|
103
|
-
it('should return error for invalid workflow definition', async () => {
|
|
104
|
-
const invalidWorkflow = { ...mockWorkflow, name: '' };
|
|
105
|
-
const result = await startWorkflow(invalidWorkflow, emptySession);
|
|
106
|
-
// Should handle invalid workflow gracefully
|
|
107
|
-
assert.ok(result);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
// =============================================================================
|
|
111
|
-
// AC2: /workflow start creates session and loads step 1
|
|
112
|
-
// =============================================================================
|
|
113
|
-
describe('AC2: Start creates session and loads step 1', () => {
|
|
114
|
-
it('should initialize workflow state at step 1', async () => {
|
|
115
|
-
const result = await startWorkflow(mockWorkflow, emptySession);
|
|
116
|
-
assert.strictEqual(result.success, true);
|
|
117
|
-
assert.strictEqual(result.state?.currentStep, 1);
|
|
118
|
-
assert.deepStrictEqual(result.state?.stepsCompleted, []);
|
|
119
|
-
});
|
|
120
|
-
it('should set status to in_progress', async () => {
|
|
121
|
-
const result = await startWorkflow(mockWorkflow, emptySession);
|
|
122
|
-
assert.strictEqual(result.state?.status, 'in_progress');
|
|
123
|
-
});
|
|
124
|
-
it('should include step 1 content in result', async () => {
|
|
125
|
-
const result = await startWorkflow(mockWorkflow, emptySession);
|
|
126
|
-
// Step content should be loaded (or null if file not found)
|
|
127
|
-
assert.ok(result.step !== undefined || result.success === true);
|
|
128
|
-
});
|
|
129
|
-
it('should return updated session content with workflow state', async () => {
|
|
130
|
-
const result = await startWorkflow(mockWorkflow, emptySession);
|
|
131
|
-
assert.ok(result.sessionContent);
|
|
132
|
-
assert.ok(result.sessionContent.includes('## Workflow State'));
|
|
133
|
-
assert.ok(result.sessionContent.includes('**Workflow Name:** architecture'));
|
|
134
|
-
});
|
|
135
|
-
it('should set started timestamp', async () => {
|
|
136
|
-
const result = await startWorkflow(mockWorkflow, emptySession);
|
|
137
|
-
assert.ok(result.state?.started);
|
|
138
|
-
// Should be ISO timestamp
|
|
139
|
-
assert.ok(result.state.started.match(/^\d{4}-\d{2}-\d{2}T/));
|
|
140
|
-
});
|
|
141
|
-
it('should set lastUpdated timestamp', async () => {
|
|
142
|
-
const result = await startWorkflow(mockWorkflow, emptySession);
|
|
143
|
-
assert.ok(result.state?.lastUpdated);
|
|
144
|
-
assert.ok(result.state.lastUpdated.match(/^\d{4}-\d{2}-\d{2}T/));
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
// =============================================================================
|
|
148
|
-
// AC3: --mode flag selects tri-modal path (default: create)
|
|
149
|
-
// =============================================================================
|
|
150
|
-
describe('AC3: Tri-modal mode selection', () => {
|
|
151
|
-
it('should use create as default mode when not specified', async () => {
|
|
152
|
-
const result = await startWorkflow(mockWorkflow, emptySession);
|
|
153
|
-
assert.strictEqual(result.state?.mode, 'create');
|
|
154
|
-
});
|
|
155
|
-
it('should use workflow default mode if specified in definition', async () => {
|
|
156
|
-
const workflowWithValidateDefault = {
|
|
157
|
-
...mockWorkflow,
|
|
158
|
-
modes: {
|
|
159
|
-
default: 'validate',
|
|
160
|
-
available: ['create', 'validate', 'edit'],
|
|
161
|
-
},
|
|
162
|
-
};
|
|
163
|
-
const result = await startWorkflow(workflowWithValidateDefault, emptySession);
|
|
164
|
-
assert.strictEqual(result.state?.mode, 'validate');
|
|
165
|
-
});
|
|
166
|
-
it('should override workflow default with explicit mode', async () => {
|
|
167
|
-
const workflowWithValidateDefault = {
|
|
168
|
-
...mockWorkflow,
|
|
169
|
-
modes: {
|
|
170
|
-
default: 'validate',
|
|
171
|
-
available: ['create', 'validate', 'edit'],
|
|
172
|
-
},
|
|
173
|
-
};
|
|
174
|
-
const result = await startWorkflow(workflowWithValidateDefault, emptySession, 'edit');
|
|
175
|
-
assert.strictEqual(result.state?.mode, 'edit');
|
|
176
|
-
});
|
|
177
|
-
it('should not set mode for workflows without modes config', async () => {
|
|
178
|
-
const workflowWithoutModes = {
|
|
179
|
-
...mockWorkflow,
|
|
180
|
-
modes: undefined,
|
|
181
|
-
};
|
|
182
|
-
const result = await startWorkflow(workflowWithoutModes, emptySession);
|
|
183
|
-
// Mode should be undefined or default to create
|
|
184
|
-
assert.ok(result.state?.mode === undefined || result.state?.mode === 'create');
|
|
185
|
-
});
|
|
186
|
-
it('should include mode in session content when set', async () => {
|
|
187
|
-
const result = await startWorkflow(mockWorkflow, emptySession, 'validate');
|
|
188
|
-
assert.ok(result.sessionContent?.includes('**Mode:** validate'));
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
// =============================================================================
|
|
192
|
-
// AC4: /workflow resume [name] implemented
|
|
193
|
-
// =============================================================================
|
|
194
|
-
describe('AC4: /workflow resume command', () => {
|
|
195
|
-
it('should resume workflow from existing session state', async () => {
|
|
196
|
-
const result = await resumeWorkflow(mockWorkflow, sessionWithWorkflowState);
|
|
197
|
-
assert.strictEqual(result.success, true);
|
|
198
|
-
assert.ok(result.state);
|
|
199
|
-
});
|
|
200
|
-
it('should return current state from session', async () => {
|
|
201
|
-
const result = await resumeWorkflow(mockWorkflow, sessionWithWorkflowState);
|
|
202
|
-
assert.strictEqual(result.state?.name, 'architecture');
|
|
203
|
-
assert.strictEqual(result.state?.currentStep, 3);
|
|
204
|
-
assert.deepStrictEqual(result.state?.stepsCompleted, [1, 2]);
|
|
205
|
-
});
|
|
206
|
-
it('should return error when no workflow state in session', async () => {
|
|
207
|
-
const result = await resumeWorkflow(mockWorkflow, emptySession);
|
|
208
|
-
// Should fail or return isComplete with no active workflow
|
|
209
|
-
assert.ok(result.error || result.state === undefined);
|
|
210
|
-
});
|
|
211
|
-
it('should preserve mode from existing state', async () => {
|
|
212
|
-
const result = await resumeWorkflow(mockWorkflow, sessionWithWorkflowState);
|
|
213
|
-
assert.strictEqual(result.state?.mode, 'create');
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
// =============================================================================
|
|
217
|
-
// AC5: /workflow resume detects incomplete workflow and continues
|
|
218
|
-
// =============================================================================
|
|
219
|
-
describe('AC5: Resume detects incomplete workflow', () => {
|
|
220
|
-
it('should detect incomplete workflow from session', () => {
|
|
221
|
-
const workflowName = detectIncompleteWorkflow(sessionWithWorkflowState);
|
|
222
|
-
assert.strictEqual(workflowName, 'architecture');
|
|
223
|
-
});
|
|
224
|
-
it('should return undefined when no workflow in session', () => {
|
|
225
|
-
const workflowName = detectIncompleteWorkflow(emptySession);
|
|
226
|
-
assert.strictEqual(workflowName, undefined);
|
|
227
|
-
});
|
|
228
|
-
it('should return undefined when workflow is completed', () => {
|
|
229
|
-
const workflowName = detectIncompleteWorkflow(sessionWithCompletedWorkflow);
|
|
230
|
-
// Completed workflows should not be detected as incomplete
|
|
231
|
-
assert.strictEqual(workflowName, undefined);
|
|
232
|
-
});
|
|
233
|
-
it('should continue from last completed step', async () => {
|
|
234
|
-
const result = await resumeWorkflow(mockWorkflow, sessionWithWorkflowState);
|
|
235
|
-
// Current step should be 3 (next after completed steps [1, 2])
|
|
236
|
-
assert.strictEqual(result.state?.currentStep, 3);
|
|
237
|
-
});
|
|
238
|
-
it('should load next step content on resume', async () => {
|
|
239
|
-
const result = await resumeWorkflow(mockWorkflow, sessionWithWorkflowState);
|
|
240
|
-
// Step should be loaded (number should match current step)
|
|
241
|
-
assert.ok(result.step === undefined || result.step?.number === 3);
|
|
242
|
-
});
|
|
243
|
-
it('should mark as complete when all steps done', async () => {
|
|
244
|
-
const result = await resumeWorkflow(mockWorkflow, sessionWithCompletedWorkflow);
|
|
245
|
-
assert.strictEqual(result.isComplete, true);
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
// =============================================================================
|
|
249
|
-
// AC6: /workflow status shows step progress and completion %
|
|
250
|
-
// =============================================================================
|
|
251
|
-
describe('AC6: /workflow status command', () => {
|
|
252
|
-
it('should return workflow status from session', () => {
|
|
253
|
-
const result = getWorkflowStatus(sessionWithWorkflowState, 7);
|
|
254
|
-
assert.strictEqual(result.success, true);
|
|
255
|
-
assert.ok(result.status);
|
|
256
|
-
});
|
|
257
|
-
it('should show current step number', () => {
|
|
258
|
-
const result = getWorkflowStatus(sessionWithWorkflowState, 7);
|
|
259
|
-
assert.strictEqual(result.status?.currentStep, 3);
|
|
260
|
-
});
|
|
261
|
-
it('should show total steps', () => {
|
|
262
|
-
const result = getWorkflowStatus(sessionWithWorkflowState, 7);
|
|
263
|
-
assert.strictEqual(result.status?.totalSteps, 7);
|
|
264
|
-
});
|
|
265
|
-
it('should show completed steps array', () => {
|
|
266
|
-
const result = getWorkflowStatus(sessionWithWorkflowState, 7);
|
|
267
|
-
assert.deepStrictEqual(result.status?.stepsCompleted, [1, 2]);
|
|
268
|
-
});
|
|
269
|
-
it('should calculate completion percentage', () => {
|
|
270
|
-
const result = getWorkflowStatus(sessionWithWorkflowState, 7);
|
|
271
|
-
// 2 of 7 steps completed = ~28.57%
|
|
272
|
-
assert.ok(result.status?.completionPercent);
|
|
273
|
-
assert.ok(result.status.completionPercent >= 28 && result.status.completionPercent <= 29);
|
|
274
|
-
});
|
|
275
|
-
it('should show 0% for new workflow', () => {
|
|
276
|
-
const newWorkflowSession = `## Workflow State
|
|
277
|
-
- **Workflow Name:** test
|
|
278
|
-
- **Type:** stepped
|
|
279
|
-
- **Started:** 2026-01-20T10:00:00.000Z
|
|
280
|
-
- **Last Updated:** 2026-01-20T10:00:00.000Z
|
|
281
|
-
- **Current Step:** 1
|
|
282
|
-
- **Steps Completed:** []
|
|
283
|
-
- **Status:** in_progress
|
|
284
|
-
`;
|
|
285
|
-
const result = getWorkflowStatus(newWorkflowSession, 5);
|
|
286
|
-
assert.strictEqual(result.status?.completionPercent, 0);
|
|
287
|
-
});
|
|
288
|
-
it('should show 100% for completed workflow', () => {
|
|
289
|
-
const result = getWorkflowStatus(sessionWithCompletedWorkflow, 7);
|
|
290
|
-
assert.strictEqual(result.status?.completionPercent, 100);
|
|
291
|
-
});
|
|
292
|
-
it('should show workflow name', () => {
|
|
293
|
-
const result = getWorkflowStatus(sessionWithWorkflowState, 7);
|
|
294
|
-
assert.strictEqual(result.status?.name, 'architecture');
|
|
295
|
-
});
|
|
296
|
-
it('should show workflow type', () => {
|
|
297
|
-
const result = getWorkflowStatus(sessionWithWorkflowState, 7);
|
|
298
|
-
assert.strictEqual(result.status?.type, 'stepped');
|
|
299
|
-
});
|
|
300
|
-
it('should show mode if set', () => {
|
|
301
|
-
const result = getWorkflowStatus(sessionWithWorkflowState, 7);
|
|
302
|
-
assert.strictEqual(result.status?.mode, 'create');
|
|
303
|
-
});
|
|
304
|
-
it('should show workflow status', () => {
|
|
305
|
-
const result = getWorkflowStatus(sessionWithWorkflowState, 7);
|
|
306
|
-
assert.strictEqual(result.status?.status, 'in_progress');
|
|
307
|
-
});
|
|
308
|
-
it('should return error when no workflow state', () => {
|
|
309
|
-
const result = getWorkflowStatus(emptySession, 7);
|
|
310
|
-
// Should indicate no active workflow
|
|
311
|
-
assert.ok(!result.status || result.error);
|
|
312
|
-
});
|
|
313
|
-
});
|
|
314
|
-
// =============================================================================
|
|
315
|
-
// AC7: Session file state tracked via Workflow State section
|
|
316
|
-
// =============================================================================
|
|
317
|
-
describe('AC7: Session state integration', () => {
|
|
318
|
-
it('should write workflow state to session on start', async () => {
|
|
319
|
-
const result = await startWorkflow(mockWorkflow, emptySession);
|
|
320
|
-
assert.ok(result.sessionContent?.includes('## Workflow State'));
|
|
321
|
-
});
|
|
322
|
-
it('should update session state on step completion', () => {
|
|
323
|
-
const updated = completeStep(sessionWithWorkflowState, 3);
|
|
324
|
-
assert.ok(updated.includes('**Steps Completed:**'));
|
|
325
|
-
// Should now include step 3
|
|
326
|
-
assert.ok(updated.includes('[1, 2, 3]'));
|
|
327
|
-
});
|
|
328
|
-
it('should advance current step on completion', () => {
|
|
329
|
-
const updated = completeStep(sessionWithWorkflowState, 3);
|
|
330
|
-
assert.ok(updated.includes('**Current Step:** 4'));
|
|
331
|
-
});
|
|
332
|
-
it('should update lastUpdated timestamp on completion', () => {
|
|
333
|
-
const updated = completeStep(sessionWithWorkflowState, 3);
|
|
334
|
-
// lastUpdated should be different from original
|
|
335
|
-
assert.ok(updated.includes('**Last Updated:**'));
|
|
336
|
-
});
|
|
337
|
-
it('should detect active workflow in session', () => {
|
|
338
|
-
const hasActive = hasActiveWorkflow(sessionWithWorkflowState);
|
|
339
|
-
assert.strictEqual(hasActive, true);
|
|
340
|
-
});
|
|
341
|
-
it('should detect no active workflow in empty session', () => {
|
|
342
|
-
const hasActive = hasActiveWorkflow(emptySession);
|
|
343
|
-
assert.strictEqual(hasActive, false);
|
|
344
|
-
});
|
|
345
|
-
it('should preserve other session content when updating state', async () => {
|
|
346
|
-
const result = await startWorkflow(mockWorkflow, emptySession);
|
|
347
|
-
assert.ok(result.sessionContent?.includes('## Story Overview'));
|
|
348
|
-
assert.ok(result.sessionContent?.includes('## Acceptance Criteria'));
|
|
349
|
-
});
|
|
350
|
-
});
|
|
351
|
-
// =============================================================================
|
|
352
|
-
// AC8: Commands available in CLI with help documentation
|
|
353
|
-
// This AC is about CLI integration - tested via bash script existence
|
|
354
|
-
// =============================================================================
|
|
355
|
-
describe('AC8: CLI availability', () => {
|
|
356
|
-
it('should export startWorkflow function', () => {
|
|
357
|
-
assert.strictEqual(typeof startWorkflow, 'function');
|
|
358
|
-
});
|
|
359
|
-
it('should export resumeWorkflow function', () => {
|
|
360
|
-
assert.strictEqual(typeof resumeWorkflow, 'function');
|
|
361
|
-
});
|
|
362
|
-
it('should export getWorkflowStatus function', () => {
|
|
363
|
-
assert.strictEqual(typeof getWorkflowStatus, 'function');
|
|
364
|
-
});
|
|
365
|
-
it('should export loadStep function', () => {
|
|
366
|
-
assert.strictEqual(typeof loadStep, 'function');
|
|
367
|
-
});
|
|
368
|
-
it('should export completeStep function', () => {
|
|
369
|
-
assert.strictEqual(typeof completeStep, 'function');
|
|
370
|
-
});
|
|
371
|
-
it('should export hasActiveWorkflow function', () => {
|
|
372
|
-
assert.strictEqual(typeof hasActiveWorkflow, 'function');
|
|
373
|
-
});
|
|
374
|
-
it('should export detectIncompleteWorkflow function', () => {
|
|
375
|
-
assert.strictEqual(typeof detectIncompleteWorkflow, 'function');
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
// =============================================================================
|
|
379
|
-
// Edge Cases
|
|
380
|
-
// =============================================================================
|
|
381
|
-
describe('Edge Cases', () => {
|
|
382
|
-
it('should handle workflow with no steps gracefully', async () => {
|
|
383
|
-
const emptyWorkflow = {
|
|
384
|
-
...mockWorkflow,
|
|
385
|
-
totalSteps: 0,
|
|
386
|
-
};
|
|
387
|
-
const result = await startWorkflow(emptyWorkflow, emptySession);
|
|
388
|
-
// Should handle gracefully
|
|
389
|
-
assert.ok(result);
|
|
390
|
-
});
|
|
391
|
-
it('should handle single-step workflow', async () => {
|
|
392
|
-
const singleStepWorkflow = {
|
|
393
|
-
...mockWorkflow,
|
|
394
|
-
totalSteps: 1,
|
|
395
|
-
};
|
|
396
|
-
const result = await startWorkflow(singleStepWorkflow, emptySession);
|
|
397
|
-
assert.ok(result.state?.currentStep === 1);
|
|
398
|
-
});
|
|
399
|
-
it('should handle phased workflow type', async () => {
|
|
400
|
-
const phasedWorkflow = {
|
|
401
|
-
...mockWorkflow,
|
|
402
|
-
type: 'phased',
|
|
403
|
-
};
|
|
404
|
-
const result = await startWorkflow(phasedWorkflow, emptySession);
|
|
405
|
-
assert.strictEqual(result.state?.type, 'phased');
|
|
406
|
-
});
|
|
407
|
-
it('should handle step completion with explicit next step', () => {
|
|
408
|
-
// Skip from step 3 to step 5
|
|
409
|
-
const updated = completeStep(sessionWithWorkflowState, 3, 5);
|
|
410
|
-
assert.ok(updated.includes('**Current Step:** 5'));
|
|
411
|
-
});
|
|
412
|
-
it('should handle resume on paused workflow', async () => {
|
|
413
|
-
const pausedSession = sessionWithWorkflowState.replace('in_progress', 'paused');
|
|
414
|
-
const result = await resumeWorkflow(mockWorkflow, pausedSession);
|
|
415
|
-
// Should be able to resume paused workflow
|
|
416
|
-
assert.ok(result);
|
|
417
|
-
});
|
|
418
|
-
it('should calculate correct percentage for mid-workflow', () => {
|
|
419
|
-
// 3 of 5 steps = 60%
|
|
420
|
-
const sessionWith3of5 = `## Workflow State
|
|
421
|
-
- **Workflow Name:** test
|
|
422
|
-
- **Type:** stepped
|
|
423
|
-
- **Started:** 2026-01-20T10:00:00.000Z
|
|
424
|
-
- **Last Updated:** 2026-01-20T10:00:00.000Z
|
|
425
|
-
- **Current Step:** 4
|
|
426
|
-
- **Steps Completed:** [1, 2, 3]
|
|
427
|
-
- **Status:** in_progress
|
|
428
|
-
`;
|
|
429
|
-
const result = getWorkflowStatus(sessionWith3of5, 5);
|
|
430
|
-
assert.strictEqual(result.status?.completionPercent, 60);
|
|
431
|
-
});
|
|
432
|
-
it('should handle loadStep for non-existent step', async () => {
|
|
433
|
-
const result = await loadStep(mockWorkflow, 999);
|
|
434
|
-
// Should return null or handle gracefully
|
|
435
|
-
assert.ok(result === null || result !== undefined);
|
|
436
|
-
});
|
|
437
|
-
it('should handle workflow variables in step loading', async () => {
|
|
438
|
-
const result = await loadStep(mockWorkflow, 1, { project_name: 'Custom Project' });
|
|
439
|
-
// Should handle variables (even if step doesn't exist)
|
|
440
|
-
assert.ok(result === null || result !== undefined);
|
|
441
|
-
});
|
|
442
|
-
});
|
|
443
|
-
});
|
|
444
|
-
//# sourceMappingURL=workflow-executor.test.js.map
|