red64-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +454 -0
- package/dist/cli/parseArgs.d.ts +16 -0
- package/dist/cli/parseArgs.d.ts.map +1 -0
- package/dist/cli/parseArgs.js +172 -0
- package/dist/cli/parseArgs.js.map +1 -0
- package/dist/cli/validateFlags.d.ts +22 -0
- package/dist/cli/validateFlags.d.ts.map +1 -0
- package/dist/cli/validateFlags.js +24 -0
- package/dist/cli/validateFlags.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +90 -0
- package/dist/cli.js.map +1 -0
- package/dist/components/App.d.ts +20 -0
- package/dist/components/App.d.ts.map +1 -0
- package/dist/components/App.js +35 -0
- package/dist/components/App.js.map +1 -0
- package/dist/components/CommandRouter.d.ts +21 -0
- package/dist/components/CommandRouter.d.ts.map +1 -0
- package/dist/components/CommandRouter.js +30 -0
- package/dist/components/CommandRouter.js.map +1 -0
- package/dist/components/GlobalConfig.d.ts +26 -0
- package/dist/components/GlobalConfig.d.ts.map +1 -0
- package/dist/components/GlobalConfig.js +30 -0
- package/dist/components/GlobalConfig.js.map +1 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +9 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/init/CompleteStep.d.ts +11 -0
- package/dist/components/init/CompleteStep.d.ts.map +1 -0
- package/dist/components/init/CompleteStep.js +15 -0
- package/dist/components/init/CompleteStep.js.map +1 -0
- package/dist/components/init/ErrorStep.d.ts +14 -0
- package/dist/components/init/ErrorStep.d.ts.map +1 -0
- package/dist/components/init/ErrorStep.js +36 -0
- package/dist/components/init/ErrorStep.js.map +1 -0
- package/dist/components/init/FetchStep.d.ts +15 -0
- package/dist/components/init/FetchStep.d.ts.map +1 -0
- package/dist/components/init/FetchStep.js +33 -0
- package/dist/components/init/FetchStep.js.map +1 -0
- package/dist/components/init/SetupStep.d.ts +14 -0
- package/dist/components/init/SetupStep.d.ts.map +1 -0
- package/dist/components/init/SetupStep.js +78 -0
- package/dist/components/init/SetupStep.js.map +1 -0
- package/dist/components/init/SteeringStep.d.ts +12 -0
- package/dist/components/init/SteeringStep.d.ts.map +1 -0
- package/dist/components/init/SteeringStep.js +43 -0
- package/dist/components/init/SteeringStep.js.map +1 -0
- package/dist/components/init/WelcomeStep.d.ts +12 -0
- package/dist/components/init/WelcomeStep.d.ts.map +1 -0
- package/dist/components/init/WelcomeStep.js +52 -0
- package/dist/components/init/WelcomeStep.js.map +1 -0
- package/dist/components/init/index.d.ts +11 -0
- package/dist/components/init/index.d.ts.map +1 -0
- package/dist/components/init/index.js +10 -0
- package/dist/components/init/index.js.map +1 -0
- package/dist/components/init/types.d.ts +98 -0
- package/dist/components/init/types.d.ts.map +1 -0
- package/dist/components/init/types.js +6 -0
- package/dist/components/init/types.js.map +1 -0
- package/dist/components/screens/AbortScreen.d.ts +14 -0
- package/dist/components/screens/AbortScreen.d.ts.map +1 -0
- package/dist/components/screens/AbortScreen.js +181 -0
- package/dist/components/screens/AbortScreen.js.map +1 -0
- package/dist/components/screens/ApprovalScreen.d.ts +24 -0
- package/dist/components/screens/ApprovalScreen.d.ts.map +1 -0
- package/dist/components/screens/ApprovalScreen.js +82 -0
- package/dist/components/screens/ApprovalScreen.js.map +1 -0
- package/dist/components/screens/HelpScreen.d.ts +20 -0
- package/dist/components/screens/HelpScreen.d.ts.map +1 -0
- package/dist/components/screens/HelpScreen.js +70 -0
- package/dist/components/screens/HelpScreen.js.map +1 -0
- package/dist/components/screens/InitScreen.d.ts +15 -0
- package/dist/components/screens/InitScreen.d.ts.map +1 -0
- package/dist/components/screens/InitScreen.js +420 -0
- package/dist/components/screens/InitScreen.js.map +1 -0
- package/dist/components/screens/ListScreen.d.ts +14 -0
- package/dist/components/screens/ListScreen.d.ts.map +1 -0
- package/dist/components/screens/ListScreen.js +57 -0
- package/dist/components/screens/ListScreen.js.map +1 -0
- package/dist/components/screens/ProgressScreen.d.ts +26 -0
- package/dist/components/screens/ProgressScreen.d.ts.map +1 -0
- package/dist/components/screens/ProgressScreen.js +64 -0
- package/dist/components/screens/ProgressScreen.js.map +1 -0
- package/dist/components/screens/ResumeScreen.d.ts +14 -0
- package/dist/components/screens/ResumeScreen.d.ts.map +1 -0
- package/dist/components/screens/ResumeScreen.js +108 -0
- package/dist/components/screens/ResumeScreen.js.map +1 -0
- package/dist/components/screens/ScreenProps.d.ts +12 -0
- package/dist/components/screens/ScreenProps.d.ts.map +1 -0
- package/dist/components/screens/ScreenProps.js +5 -0
- package/dist/components/screens/ScreenProps.js.map +1 -0
- package/dist/components/screens/StartScreen.d.ts +26 -0
- package/dist/components/screens/StartScreen.d.ts.map +1 -0
- package/dist/components/screens/StartScreen.js +1021 -0
- package/dist/components/screens/StartScreen.js.map +1 -0
- package/dist/components/screens/StatusScreen.d.ts +14 -0
- package/dist/components/screens/StatusScreen.d.ts.map +1 -0
- package/dist/components/screens/StatusScreen.js +115 -0
- package/dist/components/screens/StatusScreen.js.map +1 -0
- package/dist/components/screens/index.d.ts +15 -0
- package/dist/components/screens/index.d.ts.map +1 -0
- package/dist/components/screens/index.js +12 -0
- package/dist/components/screens/index.js.map +1 -0
- package/dist/components/ui/ErrorBoundary.d.ts +34 -0
- package/dist/components/ui/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/ui/ErrorBoundary.js +37 -0
- package/dist/components/ui/ErrorBoundary.js.map +1 -0
- package/dist/components/ui/ErrorDisplay.d.ts +20 -0
- package/dist/components/ui/ErrorDisplay.d.ts.map +1 -0
- package/dist/components/ui/ErrorDisplay.js +12 -0
- package/dist/components/ui/ErrorDisplay.js.map +1 -0
- package/dist/components/ui/ErrorRecoveryPrompt.d.ts +30 -0
- package/dist/components/ui/ErrorRecoveryPrompt.d.ts.map +1 -0
- package/dist/components/ui/ErrorRecoveryPrompt.js +66 -0
- package/dist/components/ui/ErrorRecoveryPrompt.js.map +1 -0
- package/dist/components/ui/FeatureSidebar.d.ts +27 -0
- package/dist/components/ui/FeatureSidebar.d.ts.map +1 -0
- package/dist/components/ui/FeatureSidebar.js +166 -0
- package/dist/components/ui/FeatureSidebar.js.map +1 -0
- package/dist/components/ui/FlowTable.d.ts +21 -0
- package/dist/components/ui/FlowTable.d.ts.map +1 -0
- package/dist/components/ui/FlowTable.js +105 -0
- package/dist/components/ui/FlowTable.js.map +1 -0
- package/dist/components/ui/Header.d.ts +20 -0
- package/dist/components/ui/Header.d.ts.map +1 -0
- package/dist/components/ui/Header.js +11 -0
- package/dist/components/ui/Header.js.map +1 -0
- package/dist/components/ui/OutputRegion.d.ts +20 -0
- package/dist/components/ui/OutputRegion.d.ts.map +1 -0
- package/dist/components/ui/OutputRegion.js +14 -0
- package/dist/components/ui/OutputRegion.js.map +1 -0
- package/dist/components/ui/PhaseProgressView.d.ts +23 -0
- package/dist/components/ui/PhaseProgressView.d.ts.map +1 -0
- package/dist/components/ui/PhaseProgressView.js +117 -0
- package/dist/components/ui/PhaseProgressView.js.map +1 -0
- package/dist/components/ui/ProgressBar.d.ts +20 -0
- package/dist/components/ui/ProgressBar.d.ts.map +1 -0
- package/dist/components/ui/ProgressBar.js +12 -0
- package/dist/components/ui/ProgressBar.js.map +1 -0
- package/dist/components/ui/SelectMenu.d.ts +27 -0
- package/dist/components/ui/SelectMenu.d.ts.map +1 -0
- package/dist/components/ui/SelectMenu.js +21 -0
- package/dist/components/ui/SelectMenu.js.map +1 -0
- package/dist/components/ui/Spinner.d.ts +18 -0
- package/dist/components/ui/Spinner.d.ts.map +1 -0
- package/dist/components/ui/Spinner.js +10 -0
- package/dist/components/ui/Spinner.js.map +1 -0
- package/dist/components/ui/StatusLine.d.ts +21 -0
- package/dist/components/ui/StatusLine.d.ts.map +1 -0
- package/dist/components/ui/StatusLine.js +30 -0
- package/dist/components/ui/StatusLine.js.map +1 -0
- package/dist/components/ui/index.d.ts +16 -0
- package/dist/components/ui/index.d.ts.map +1 -0
- package/dist/components/ui/index.js +16 -0
- package/dist/components/ui/index.js.map +1 -0
- package/dist/services/AgentInvoker.d.ts +20 -0
- package/dist/services/AgentInvoker.d.ts.map +1 -0
- package/dist/services/AgentInvoker.js +282 -0
- package/dist/services/AgentInvoker.js.map +1 -0
- package/dist/services/BranchService.d.ts +28 -0
- package/dist/services/BranchService.d.ts.map +1 -0
- package/dist/services/BranchService.js +114 -0
- package/dist/services/BranchService.js.map +1 -0
- package/dist/services/CacheService.d.ts +57 -0
- package/dist/services/CacheService.d.ts.map +1 -0
- package/dist/services/CacheService.js +208 -0
- package/dist/services/CacheService.js.map +1 -0
- package/dist/services/ClaudeErrorDetector.d.ts +45 -0
- package/dist/services/ClaudeErrorDetector.d.ts.map +1 -0
- package/dist/services/ClaudeErrorDetector.js +207 -0
- package/dist/services/ClaudeErrorDetector.js.map +1 -0
- package/dist/services/ClaudeHealthCheck.d.ts +37 -0
- package/dist/services/ClaudeHealthCheck.d.ts.map +1 -0
- package/dist/services/ClaudeHealthCheck.js +197 -0
- package/dist/services/ClaudeHealthCheck.js.map +1 -0
- package/dist/services/CommitService.d.ts +36 -0
- package/dist/services/CommitService.d.ts.map +1 -0
- package/dist/services/CommitService.js +159 -0
- package/dist/services/CommitService.js.map +1 -0
- package/dist/services/ConfigService.d.ts +49 -0
- package/dist/services/ConfigService.d.ts.map +1 -0
- package/dist/services/ConfigService.js +57 -0
- package/dist/services/ConfigService.js.map +1 -0
- package/dist/services/DockerRunner.d.ts +45 -0
- package/dist/services/DockerRunner.d.ts.map +1 -0
- package/dist/services/DockerRunner.js +170 -0
- package/dist/services/DockerRunner.js.map +1 -0
- package/dist/services/ExtendedFlowStateMachine.d.ts +31 -0
- package/dist/services/ExtendedFlowStateMachine.d.ts.map +1 -0
- package/dist/services/ExtendedFlowStateMachine.js +302 -0
- package/dist/services/ExtendedFlowStateMachine.js.map +1 -0
- package/dist/services/FeatureValidator.d.ts +26 -0
- package/dist/services/FeatureValidator.d.ts.map +1 -0
- package/dist/services/FeatureValidator.js +48 -0
- package/dist/services/FeatureValidator.js.map +1 -0
- package/dist/services/FlowStateMachine.d.ts +26 -0
- package/dist/services/FlowStateMachine.d.ts.map +1 -0
- package/dist/services/FlowStateMachine.js +177 -0
- package/dist/services/FlowStateMachine.js.map +1 -0
- package/dist/services/GitHubService.d.ts +72 -0
- package/dist/services/GitHubService.d.ts.map +1 -0
- package/dist/services/GitHubService.js +150 -0
- package/dist/services/GitHubService.js.map +1 -0
- package/dist/services/GitStatusChecker.d.ts +29 -0
- package/dist/services/GitStatusChecker.d.ts.map +1 -0
- package/dist/services/GitStatusChecker.js +127 -0
- package/dist/services/GitStatusChecker.js.map +1 -0
- package/dist/services/PRCreatorService.d.ts +59 -0
- package/dist/services/PRCreatorService.d.ts.map +1 -0
- package/dist/services/PRCreatorService.js +212 -0
- package/dist/services/PRCreatorService.js.map +1 -0
- package/dist/services/PRStatusFetcher.d.ts +39 -0
- package/dist/services/PRStatusFetcher.d.ts.map +1 -0
- package/dist/services/PRStatusFetcher.js +144 -0
- package/dist/services/PRStatusFetcher.js.map +1 -0
- package/dist/services/PhaseExecutor.d.ts +29 -0
- package/dist/services/PhaseExecutor.d.ts.map +1 -0
- package/dist/services/PhaseExecutor.js +125 -0
- package/dist/services/PhaseExecutor.js.map +1 -0
- package/dist/services/SpecInitService.d.ts +33 -0
- package/dist/services/SpecInitService.d.ts.map +1 -0
- package/dist/services/SpecInitService.js +168 -0
- package/dist/services/SpecInitService.js.map +1 -0
- package/dist/services/StateStore.d.ts +24 -0
- package/dist/services/StateStore.d.ts.map +1 -0
- package/dist/services/StateStore.js +171 -0
- package/dist/services/StateStore.js.map +1 -0
- package/dist/services/TaskParser.d.ts +44 -0
- package/dist/services/TaskParser.d.ts.map +1 -0
- package/dist/services/TaskParser.js +167 -0
- package/dist/services/TaskParser.js.map +1 -0
- package/dist/services/TaskRunner.d.ts +52 -0
- package/dist/services/TaskRunner.d.ts.map +1 -0
- package/dist/services/TaskRunner.js +135 -0
- package/dist/services/TaskRunner.js.map +1 -0
- package/dist/services/TemplateService.d.ts +73 -0
- package/dist/services/TemplateService.d.ts.map +1 -0
- package/dist/services/TemplateService.js +263 -0
- package/dist/services/TemplateService.js.map +1 -0
- package/dist/services/WorktreeService.d.ts +51 -0
- package/dist/services/WorktreeService.d.ts.map +1 -0
- package/dist/services/WorktreeService.js +204 -0
- package/dist/services/WorktreeService.js.map +1 -0
- package/dist/services/index.d.ts +25 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +25 -0
- package/dist/services/index.js.map +1 -0
- package/dist/types/extended-flow.d.ts +167 -0
- package/dist/types/extended-flow.d.ts.map +1 -0
- package/dist/types/extended-flow.js +103 -0
- package/dist/types/extended-flow.js.map +1 -0
- package/dist/types/index.d.ts +210 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +28 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/git.d.ts +41 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +68 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/paths.d.ts +30 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +43 -0
- package/dist/utils/paths.js.map +1 -0
- package/framework/.red64/settings/rules/design-discovery-full.md +93 -0
- package/framework/.red64/settings/rules/design-discovery-light.md +49 -0
- package/framework/.red64/settings/rules/design-principles.md +182 -0
- package/framework/.red64/settings/rules/design-review.md +110 -0
- package/framework/.red64/settings/rules/ears-format.md +49 -0
- package/framework/.red64/settings/rules/gap-analysis.md +144 -0
- package/framework/.red64/settings/rules/steering-principles.md +90 -0
- package/framework/.red64/settings/rules/tasks-generation.md +131 -0
- package/framework/.red64/settings/rules/tasks-parallel-analysis.md +34 -0
- package/framework/.red64/settings/templates/flow-state.json +48 -0
- package/framework/.red64/settings/templates/specs/design.md +276 -0
- package/framework/.red64/settings/templates/specs/init.json +24 -0
- package/framework/.red64/settings/templates/specs/requirements-init.md +9 -0
- package/framework/.red64/settings/templates/specs/requirements.md +26 -0
- package/framework/.red64/settings/templates/specs/research.md +61 -0
- package/framework/.red64/settings/templates/specs/tasks.md +21 -0
- package/framework/.red64/settings/templates/steering/product.md +18 -0
- package/framework/.red64/settings/templates/steering/structure.md +41 -0
- package/framework/.red64/settings/templates/steering/tech.md +45 -0
- package/framework/.red64/settings/templates/steering-custom/api-standards.md +69 -0
- package/framework/.red64/settings/templates/steering-custom/authentication.md +67 -0
- package/framework/.red64/settings/templates/steering-custom/database.md +46 -0
- package/framework/.red64/settings/templates/steering-custom/deployment.md +54 -0
- package/framework/.red64/settings/templates/steering-custom/error-handling.md +59 -0
- package/framework/.red64/settings/templates/steering-custom/security.md +55 -0
- package/framework/.red64/settings/templates/steering-custom/testing.md +47 -0
- package/framework/agents/claude/.claude/agents/red64/spec-design.md +174 -0
- package/framework/agents/claude/.claude/agents/red64/spec-impl.md +120 -0
- package/framework/agents/claude/.claude/agents/red64/spec-requirements.md +102 -0
- package/framework/agents/claude/.claude/agents/red64/spec-tasks.md +141 -0
- package/framework/agents/claude/.claude/agents/red64/steering-custom.md +147 -0
- package/framework/agents/claude/.claude/agents/red64/steering.md +163 -0
- package/framework/agents/claude/.claude/agents/red64/validate-design.md +98 -0
- package/framework/agents/claude/.claude/agents/red64/validate-gap.md +99 -0
- package/framework/agents/claude/.claude/agents/red64/validate-impl.md +146 -0
- package/framework/agents/claude/.claude/commands/red64/spec-design.md +64 -0
- package/framework/agents/claude/.claude/commands/red64/spec-impl.md +68 -0
- package/framework/agents/claude/.claude/commands/red64/spec-init.md +65 -0
- package/framework/agents/claude/.claude/commands/red64/spec-quick.md +360 -0
- package/framework/agents/claude/.claude/commands/red64/spec-requirements.md +62 -0
- package/framework/agents/claude/.claude/commands/red64/spec-status.md +87 -0
- package/framework/agents/claude/.claude/commands/red64/spec-tasks.md +75 -0
- package/framework/agents/claude/.claude/commands/red64/steering-custom.md +59 -0
- package/framework/agents/claude/.claude/commands/red64/steering.md +62 -0
- package/framework/agents/claude/.claude/commands/red64/validate-design.md +59 -0
- package/framework/agents/claude/.claude/commands/red64/validate-gap.md +53 -0
- package/framework/agents/claude/.claude/commands/red64/validate-impl.md +68 -0
- package/framework/agents/claude/docs/CLAUDE.md +45 -0
- package/framework/agents/codex/.codex/agents/red64/spec-design.md +174 -0
- package/framework/agents/codex/.codex/agents/red64/spec-impl.md +120 -0
- package/framework/agents/codex/.codex/agents/red64/spec-requirements.md +102 -0
- package/framework/agents/codex/.codex/agents/red64/spec-tasks.md +141 -0
- package/framework/agents/codex/.codex/agents/red64/steering-custom.md +147 -0
- package/framework/agents/codex/.codex/agents/red64/steering.md +163 -0
- package/framework/agents/codex/.codex/agents/red64/validate-design.md +98 -0
- package/framework/agents/codex/.codex/agents/red64/validate-gap.md +99 -0
- package/framework/agents/codex/.codex/agents/red64/validate-impl.md +146 -0
- package/framework/agents/codex/.codex/commands/red64/spec-design.md +64 -0
- package/framework/agents/codex/.codex/commands/red64/spec-impl.md +68 -0
- package/framework/agents/codex/.codex/commands/red64/spec-init.md +65 -0
- package/framework/agents/codex/.codex/commands/red64/spec-quick.md +360 -0
- package/framework/agents/codex/.codex/commands/red64/spec-requirements.md +62 -0
- package/framework/agents/codex/.codex/commands/red64/spec-status.md +87 -0
- package/framework/agents/codex/.codex/commands/red64/spec-tasks.md +75 -0
- package/framework/agents/codex/.codex/commands/red64/steering-custom.md +59 -0
- package/framework/agents/codex/.codex/commands/red64/steering.md +62 -0
- package/framework/agents/codex/.codex/commands/red64/validate-design.md +59 -0
- package/framework/agents/codex/.codex/commands/red64/validate-gap.md +53 -0
- package/framework/agents/codex/.codex/commands/red64/validate-impl.md +68 -0
- package/framework/agents/codex/docs/AGENTS.md +68 -0
- package/framework/agents/gemini/commands.toml +607 -0
- package/framework/agents/gemini/docs/GEMINI.md +45 -0
- package/framework/stacks/generic/product.md +27 -0
- package/framework/stacks/generic/structure.md +46 -0
- package/framework/stacks/generic/tech.md +47 -0
- package/framework/stacks/node/product.md +27 -0
- package/framework/stacks/node/structure.md +82 -0
- package/framework/stacks/node/tech.md +63 -0
- package/framework/stacks/python/product.md +27 -0
- package/framework/stacks/python/structure.md +78 -0
- package/framework/stacks/python/tech.md +64 -0
- package/framework/stacks/react/product.md +27 -0
- package/framework/stacks/react/structure.md +76 -0
- package/framework/stacks/react/tech.md +65 -0
- package/package.json +47 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec Initialization Service
|
|
3
|
+
* Creates the spec directory structure with templates
|
|
4
|
+
* Replaces the /red64:spec-init command for orchestrator use
|
|
5
|
+
*/
|
|
6
|
+
import { mkdir, writeFile, readFile } from 'node:fs/promises';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { existsSync } from 'node:fs';
|
|
9
|
+
import { sanitizeFeatureName } from './WorktreeService.js';
|
|
10
|
+
/**
|
|
11
|
+
* Default spec.json template content
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_SPEC_JSON_TEMPLATE = `{
|
|
14
|
+
"feature_name": "{{FEATURE_NAME}}",
|
|
15
|
+
"created_at": "{{TIMESTAMP}}",
|
|
16
|
+
"updated_at": "{{TIMESTAMP}}",
|
|
17
|
+
"language": "en",
|
|
18
|
+
"phase": "initialized",
|
|
19
|
+
"approvals": {
|
|
20
|
+
"requirements": {
|
|
21
|
+
"generated": false,
|
|
22
|
+
"approved": false
|
|
23
|
+
},
|
|
24
|
+
"design": {
|
|
25
|
+
"generated": false,
|
|
26
|
+
"approved": false
|
|
27
|
+
},
|
|
28
|
+
"tasks": {
|
|
29
|
+
"generated": false,
|
|
30
|
+
"approved": false
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"ready_for_implementation": false
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
/**
|
|
37
|
+
* Default requirements.md template content
|
|
38
|
+
*/
|
|
39
|
+
const DEFAULT_REQUIREMENTS_TEMPLATE = `# Requirements Document
|
|
40
|
+
|
|
41
|
+
## Project Description (Input)
|
|
42
|
+
{{PROJECT_DESCRIPTION}}
|
|
43
|
+
|
|
44
|
+
## Requirements
|
|
45
|
+
<!-- Will be generated in /red64:spec-requirements phase -->
|
|
46
|
+
|
|
47
|
+
`;
|
|
48
|
+
/**
|
|
49
|
+
* Replace template placeholders
|
|
50
|
+
*/
|
|
51
|
+
function replacePlaceholders(template, featureName, description) {
|
|
52
|
+
const timestamp = new Date().toISOString();
|
|
53
|
+
return template
|
|
54
|
+
.replace(/\{\{FEATURE_NAME\}\}/g, featureName)
|
|
55
|
+
.replace(/\{\{TIMESTAMP\}\}/g, timestamp)
|
|
56
|
+
.replace(/\{\{PROJECT_DESCRIPTION\}\}/g, description);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Read template file or return default
|
|
60
|
+
*/
|
|
61
|
+
async function readTemplateOrDefault(workDir, templatePath, defaultContent) {
|
|
62
|
+
const fullPath = join(workDir, templatePath);
|
|
63
|
+
if (existsSync(fullPath)) {
|
|
64
|
+
try {
|
|
65
|
+
return await readFile(fullPath, 'utf-8');
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return defaultContent;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return defaultContent;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Check if spec already exists
|
|
75
|
+
* Returns true if spec directory exists with spec.json
|
|
76
|
+
*/
|
|
77
|
+
async function specExists(workDir, featureName) {
|
|
78
|
+
const specJsonPath = join(workDir, '.red64', 'specs', featureName, 'spec.json');
|
|
79
|
+
return existsSync(specJsonPath);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Create spec init service
|
|
83
|
+
*/
|
|
84
|
+
export function createSpecInitService() {
|
|
85
|
+
return {
|
|
86
|
+
/**
|
|
87
|
+
* Initialize spec directory and files from templates
|
|
88
|
+
*
|
|
89
|
+
* Uses the sanitized feature name consistently (same as worktree/branch naming).
|
|
90
|
+
* If spec already exists, returns success without overwriting (supports resume).
|
|
91
|
+
*
|
|
92
|
+
* 1. Sanitize feature name (consistent with worktree naming)
|
|
93
|
+
* 2. Check if spec already exists (skip if so)
|
|
94
|
+
* 3. Create directory .red64/specs/[feature-name]/
|
|
95
|
+
* 4. Read templates and replace placeholders
|
|
96
|
+
* 5. Write spec.json and requirements.md
|
|
97
|
+
*/
|
|
98
|
+
async init(workDir, featureName, description) {
|
|
99
|
+
const sanitizedName = sanitizeFeatureName(featureName);
|
|
100
|
+
const specDir = join(workDir, '.red64', 'specs', sanitizedName);
|
|
101
|
+
try {
|
|
102
|
+
// Check if spec already exists (resume scenario)
|
|
103
|
+
if (await specExists(workDir, sanitizedName)) {
|
|
104
|
+
return {
|
|
105
|
+
success: true,
|
|
106
|
+
specDir,
|
|
107
|
+
featureName: sanitizedName
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Create spec directory
|
|
111
|
+
await mkdir(specDir, { recursive: true });
|
|
112
|
+
// Read templates (with fallback to defaults)
|
|
113
|
+
const specJsonTemplate = await readTemplateOrDefault(workDir, '.red64/settings/templates/specs/init.json', DEFAULT_SPEC_JSON_TEMPLATE);
|
|
114
|
+
const requirementsTemplate = await readTemplateOrDefault(workDir, '.red64/settings/templates/specs/requirements-init.md', DEFAULT_REQUIREMENTS_TEMPLATE);
|
|
115
|
+
// Replace placeholders
|
|
116
|
+
const specJsonContent = replacePlaceholders(specJsonTemplate, sanitizedName, description);
|
|
117
|
+
const requirementsContent = replacePlaceholders(requirementsTemplate, sanitizedName, description);
|
|
118
|
+
// Write files
|
|
119
|
+
await writeFile(join(specDir, 'spec.json'), specJsonContent, 'utf-8');
|
|
120
|
+
await writeFile(join(specDir, 'requirements.md'), requirementsContent, 'utf-8');
|
|
121
|
+
return {
|
|
122
|
+
success: true,
|
|
123
|
+
specDir,
|
|
124
|
+
featureName: sanitizedName
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
return {
|
|
129
|
+
success: false,
|
|
130
|
+
specDir,
|
|
131
|
+
featureName: sanitizedName,
|
|
132
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
/**
|
|
137
|
+
* Update spec.json when tasks are approved
|
|
138
|
+
* Sets tasks.approved = true and ready_for_implementation = true
|
|
139
|
+
* This is called by the orchestrator when transitioning from tasks-approval to implementing
|
|
140
|
+
*/
|
|
141
|
+
async updateTaskApproval(workDir, featureName) {
|
|
142
|
+
const sanitizedName = sanitizeFeatureName(featureName);
|
|
143
|
+
const specJsonPath = join(workDir, '.red64', 'specs', sanitizedName, 'spec.json');
|
|
144
|
+
try {
|
|
145
|
+
// Read existing spec.json
|
|
146
|
+
const specJsonContent = await readFile(specJsonPath, 'utf-8');
|
|
147
|
+
const specJson = JSON.parse(specJsonContent);
|
|
148
|
+
// Update approval flags
|
|
149
|
+
specJson.approvals.tasks.approved = true;
|
|
150
|
+
specJson.approvals.tasks.approvedAt = new Date().toISOString();
|
|
151
|
+
specJson.approvals.tasks.approvedBy = 'orchestrator';
|
|
152
|
+
specJson.ready_for_implementation = true;
|
|
153
|
+
specJson.phase = 'ready-for-implementation';
|
|
154
|
+
specJson.updated_at = new Date().toISOString();
|
|
155
|
+
// Write back
|
|
156
|
+
await writeFile(specJsonPath, JSON.stringify(specJson, null, 2), 'utf-8');
|
|
157
|
+
return { success: true };
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
return {
|
|
161
|
+
success: false,
|
|
162
|
+
error: error instanceof Error ? error.message : 'Failed to update spec.json'
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=SpecInitService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpecInitService.js","sourceRoot":"","sources":["../../src/services/SpecInitService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State persistence service
|
|
3
|
+
* Requirements: 1.5, 1.7, 8.2
|
|
4
|
+
*/
|
|
5
|
+
import type { FlowState } from '../types/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* State store service interface
|
|
8
|
+
* Requirements: 1.5 - Persist and restore flow state through TypeScript file I/O
|
|
9
|
+
* Task 1.4: Extended with archive capability for abort flows
|
|
10
|
+
*/
|
|
11
|
+
export interface StateStoreService {
|
|
12
|
+
save(state: FlowState): Promise<void>;
|
|
13
|
+
load(feature: string): Promise<FlowState | undefined>;
|
|
14
|
+
list(): Promise<readonly FlowState[]>;
|
|
15
|
+
delete(feature: string): Promise<void>;
|
|
16
|
+
exists(feature: string): Promise<boolean>;
|
|
17
|
+
archive(feature: string): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create state store service
|
|
21
|
+
* Requirements: 1.5 - State persistence service factory
|
|
22
|
+
*/
|
|
23
|
+
export declare function createStateStore(baseDir: string): StateStoreService;
|
|
24
|
+
//# sourceMappingURL=StateStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StateStore.d.ts","sourceRoot":"","sources":["../../src/services/StateStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGnD;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IACtD,IAAI,IAAI,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IACtC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC;AAgDD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAkInE"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State persistence service
|
|
3
|
+
* Requirements: 1.5, 1.7, 8.2
|
|
4
|
+
*/
|
|
5
|
+
import { mkdir, readFile, writeFile, rm, readdir, rename, access } from 'node:fs/promises';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { randomBytes } from 'node:crypto';
|
|
8
|
+
import { sanitizeFeatureName } from './WorktreeService.js';
|
|
9
|
+
/**
|
|
10
|
+
* Get flows directory path
|
|
11
|
+
* Requirements: 8.2 - Use .red64/ as the unified directory
|
|
12
|
+
*/
|
|
13
|
+
function getFlowsDir(baseDir) {
|
|
14
|
+
return join(baseDir, '.red64', 'flows');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get feature state file path
|
|
18
|
+
*/
|
|
19
|
+
function getStatePath(baseDir, feature) {
|
|
20
|
+
return join(getFlowsDir(baseDir), sanitizeFeatureName(feature), 'state.json');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get feature directory path
|
|
24
|
+
*/
|
|
25
|
+
function getFeatureDir(baseDir, feature) {
|
|
26
|
+
return join(getFlowsDir(baseDir), sanitizeFeatureName(feature));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Validate loaded state structure
|
|
30
|
+
* Requirements: 1.7 - Validate state on load
|
|
31
|
+
*/
|
|
32
|
+
function isValidFlowState(data) {
|
|
33
|
+
if (typeof data !== 'object' || data === null) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const obj = data;
|
|
37
|
+
return (typeof obj.feature === 'string' &&
|
|
38
|
+
typeof obj.phase === 'object' &&
|
|
39
|
+
obj.phase !== null &&
|
|
40
|
+
typeof obj.phase.type === 'string' &&
|
|
41
|
+
typeof obj.createdAt === 'string' &&
|
|
42
|
+
typeof obj.updatedAt === 'string' &&
|
|
43
|
+
Array.isArray(obj.history) &&
|
|
44
|
+
typeof obj.metadata === 'object' &&
|
|
45
|
+
obj.metadata !== null);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create state store service
|
|
49
|
+
* Requirements: 1.5 - State persistence service factory
|
|
50
|
+
*/
|
|
51
|
+
export function createStateStore(baseDir) {
|
|
52
|
+
return {
|
|
53
|
+
/**
|
|
54
|
+
* Save flow state
|
|
55
|
+
* Requirements: 1.5 - Use atomic write pattern (temp file + rename)
|
|
56
|
+
*/
|
|
57
|
+
async save(state) {
|
|
58
|
+
const featureDir = getFeatureDir(baseDir, state.feature);
|
|
59
|
+
const statePath = getStatePath(baseDir, state.feature);
|
|
60
|
+
// Ensure directory exists
|
|
61
|
+
await mkdir(featureDir, { recursive: true });
|
|
62
|
+
// Atomic write: write to temp file, then rename
|
|
63
|
+
const tempPath = join(featureDir, `state.${randomBytes(8).toString('hex')}.tmp`);
|
|
64
|
+
try {
|
|
65
|
+
await writeFile(tempPath, JSON.stringify(state, null, 2), 'utf-8');
|
|
66
|
+
await rename(tempPath, statePath);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
// Clean up temp file on error
|
|
70
|
+
try {
|
|
71
|
+
await rm(tempPath, { force: true });
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Ignore cleanup errors
|
|
75
|
+
}
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* Load flow state
|
|
81
|
+
* Requirements: 1.5, 1.7 - Read and validate persisted state
|
|
82
|
+
*/
|
|
83
|
+
async load(feature) {
|
|
84
|
+
const statePath = getStatePath(baseDir, feature);
|
|
85
|
+
try {
|
|
86
|
+
const content = await readFile(statePath, 'utf-8');
|
|
87
|
+
const data = JSON.parse(content);
|
|
88
|
+
if (!isValidFlowState(data)) {
|
|
89
|
+
// Invalid state file - treat as non-existent
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
return data;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// File doesn't exist or couldn't be read
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
/**
|
|
100
|
+
* List all flow states
|
|
101
|
+
* Requirements: 1.5 - Flow management operations
|
|
102
|
+
*/
|
|
103
|
+
async list() {
|
|
104
|
+
const flowsDir = getFlowsDir(baseDir);
|
|
105
|
+
try {
|
|
106
|
+
const entries = await readdir(flowsDir, { withFileTypes: true });
|
|
107
|
+
const features = entries
|
|
108
|
+
.filter(entry => entry.isDirectory())
|
|
109
|
+
.map(entry => entry.name);
|
|
110
|
+
const states = [];
|
|
111
|
+
for (const feature of features) {
|
|
112
|
+
const state = await this.load(feature);
|
|
113
|
+
if (state) {
|
|
114
|
+
states.push(state);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return states;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Directory doesn't exist
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
/**
|
|
125
|
+
* Delete flow state
|
|
126
|
+
* Requirements: 1.5 - Flow cleanup on abort
|
|
127
|
+
*/
|
|
128
|
+
async delete(feature) {
|
|
129
|
+
const featureDir = getFeatureDir(baseDir, feature);
|
|
130
|
+
try {
|
|
131
|
+
await rm(featureDir, { recursive: true, force: true });
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Ignore errors - feature may not exist
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
/**
|
|
138
|
+
* Check if flow exists
|
|
139
|
+
* Requirements: 1.5 - Quick existence check
|
|
140
|
+
*/
|
|
141
|
+
async exists(feature) {
|
|
142
|
+
const statePath = getStatePath(baseDir, feature);
|
|
143
|
+
try {
|
|
144
|
+
await access(statePath);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
/**
|
|
152
|
+
* Archive flow state for historical preservation
|
|
153
|
+
* Task 1.4: Rename state.json to state.archived.json
|
|
154
|
+
* Requirements: 4.5 - Archive flow state on abort
|
|
155
|
+
*/
|
|
156
|
+
async archive(feature) {
|
|
157
|
+
const statePath = getStatePath(baseDir, feature);
|
|
158
|
+
const featureDir = getFeatureDir(baseDir, feature);
|
|
159
|
+
const archivePath = join(featureDir, 'state.archived.json');
|
|
160
|
+
try {
|
|
161
|
+
await access(statePath);
|
|
162
|
+
// Atomic rename for archive
|
|
163
|
+
await rename(statePath, archivePath);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// State file doesn't exist - nothing to archive
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=StateStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StateStore.js","sourceRoot":"","sources":["../../src/services/StateStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task Parser Service
|
|
3
|
+
* Task 4.1: Create task parser to extract tasks from tasks.md
|
|
4
|
+
* Requirements: 5.1
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Task interface
|
|
8
|
+
* Requirements: 5.1 - Extract task ID, title, description, completion status
|
|
9
|
+
*/
|
|
10
|
+
export interface Task {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly title: string;
|
|
13
|
+
readonly description: string;
|
|
14
|
+
readonly completed: boolean;
|
|
15
|
+
readonly priority: boolean;
|
|
16
|
+
readonly hasAsterisk: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Result of marking a task complete
|
|
20
|
+
*/
|
|
21
|
+
export interface MarkTaskCompleteResult {
|
|
22
|
+
readonly success: boolean;
|
|
23
|
+
readonly error?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Task parser service interface
|
|
27
|
+
* Requirements: 5.1
|
|
28
|
+
*/
|
|
29
|
+
export interface TaskParserService {
|
|
30
|
+
parse(specDir: string): Promise<readonly Task[]>;
|
|
31
|
+
getPendingTasks(tasks: readonly Task[]): readonly Task[];
|
|
32
|
+
getTaskById(tasks: readonly Task[], id: string): Task | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Mark a task as complete in tasks.md (orchestrator-controlled)
|
|
35
|
+
* Updates checkbox from [ ] to [x]
|
|
36
|
+
*/
|
|
37
|
+
markTaskComplete(specDir: string, taskId: string): Promise<MarkTaskCompleteResult>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create task parser service
|
|
41
|
+
* Requirements: 5.1 - Factory function for task parsing
|
|
42
|
+
*/
|
|
43
|
+
export declare function createTaskParser(): TaskParserService;
|
|
44
|
+
//# sourceMappingURL=TaskParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskParser.d.ts","sourceRoot":"","sources":["../../src/services/TaskParser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;GAGG;AACH,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IACjD,eAAe,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,SAAS,IAAI,EAAE,CAAC;IACzD,WAAW,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClE;;;OAGG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACpF;AAgED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,iBAAiB,CAuHpD"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task Parser Service
|
|
3
|
+
* Task 4.1: Create task parser to extract tasks from tasks.md
|
|
4
|
+
* Requirements: 5.1
|
|
5
|
+
*/
|
|
6
|
+
import { readFile, writeFile, rename, rm } from 'node:fs/promises';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { randomBytes } from 'node:crypto';
|
|
9
|
+
/**
|
|
10
|
+
* Task line pattern
|
|
11
|
+
* Matches: - [ ] 1.1 Task title or - [x] 1.1 Task title
|
|
12
|
+
* Also handles: - [ ]* 1.1 (P) Task title
|
|
13
|
+
*/
|
|
14
|
+
const TASK_LINE_PATTERN = /^-\s+\[([ x])\](\*)?\s+(\d+\.\d+)\s+(?:\(P\)\s+)?(.+)$/;
|
|
15
|
+
/**
|
|
16
|
+
* Check if a line is a task line (subtask with number like 1.1, 2.3, etc.)
|
|
17
|
+
*/
|
|
18
|
+
function isTaskLine(line) {
|
|
19
|
+
return TASK_LINE_PATTERN.test(line.trim());
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse a single task line
|
|
23
|
+
*/
|
|
24
|
+
function parseTaskLine(line) {
|
|
25
|
+
const match = line.trim().match(TASK_LINE_PATTERN);
|
|
26
|
+
if (!match) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const [, checkmark, asterisk, id, titlePart] = match;
|
|
30
|
+
const completed = checkmark === 'x';
|
|
31
|
+
const hasAsterisk = asterisk === '*';
|
|
32
|
+
const priority = line.includes('(P)');
|
|
33
|
+
const title = titlePart.trim();
|
|
34
|
+
return { id, title, completed, priority, hasAsterisk };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse task description from indented lines following the task line
|
|
38
|
+
*/
|
|
39
|
+
function parseDescription(lines, startIndex) {
|
|
40
|
+
const descriptionLines = [];
|
|
41
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
42
|
+
const line = lines[i];
|
|
43
|
+
const trimmed = line.trim();
|
|
44
|
+
// Stop at next task line or empty line sequence
|
|
45
|
+
if (isTaskLine(line) || line.match(/^-\s+\[\s*[x ]?\s*\]\s+\d+\./)) {
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
// Include indented description lines (starting with -)
|
|
49
|
+
if (trimmed.startsWith('-') && !trimmed.startsWith('- [')) {
|
|
50
|
+
descriptionLines.push(trimmed.substring(1).trim());
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return descriptionLines.join('\n');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create task parser service
|
|
57
|
+
* Requirements: 5.1 - Factory function for task parsing
|
|
58
|
+
*/
|
|
59
|
+
export function createTaskParser() {
|
|
60
|
+
return {
|
|
61
|
+
/**
|
|
62
|
+
* Parse tasks.md from specification directory
|
|
63
|
+
* Requirements: 5.1 - Read and parse tasks.md
|
|
64
|
+
*/
|
|
65
|
+
async parse(specDir) {
|
|
66
|
+
const tasksPath = join(specDir, 'tasks.md');
|
|
67
|
+
let content;
|
|
68
|
+
try {
|
|
69
|
+
content = await readFile(tasksPath, 'utf-8');
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// File doesn't exist or couldn't be read
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
const lines = content.split('\n');
|
|
76
|
+
const tasks = [];
|
|
77
|
+
for (let i = 0; i < lines.length; i++) {
|
|
78
|
+
const line = lines[i];
|
|
79
|
+
if (isTaskLine(line)) {
|
|
80
|
+
const parsed = parseTaskLine(line);
|
|
81
|
+
if (parsed) {
|
|
82
|
+
const description = parseDescription(lines, i + 1);
|
|
83
|
+
tasks.push({
|
|
84
|
+
id: parsed.id,
|
|
85
|
+
title: parsed.title,
|
|
86
|
+
description,
|
|
87
|
+
completed: parsed.completed,
|
|
88
|
+
priority: parsed.priority,
|
|
89
|
+
hasAsterisk: parsed.hasAsterisk
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return tasks;
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* Filter to get only pending (uncompleted) tasks
|
|
98
|
+
* Requirements: 5.1 - Track completion status
|
|
99
|
+
*/
|
|
100
|
+
getPendingTasks(tasks) {
|
|
101
|
+
return tasks.filter(task => !task.completed);
|
|
102
|
+
},
|
|
103
|
+
/**
|
|
104
|
+
* Find task by ID
|
|
105
|
+
* Requirements: 5.1 - Access tasks by identifier
|
|
106
|
+
*/
|
|
107
|
+
getTaskById(tasks, id) {
|
|
108
|
+
return tasks.find(task => task.id === id);
|
|
109
|
+
},
|
|
110
|
+
/**
|
|
111
|
+
* Mark a task as complete in tasks.md
|
|
112
|
+
* Orchestrator-controlled: updates checkbox from [ ] to [x]
|
|
113
|
+
* Uses atomic write pattern (temp file + rename)
|
|
114
|
+
*/
|
|
115
|
+
async markTaskComplete(specDir, taskId) {
|
|
116
|
+
const tasksPath = join(specDir, 'tasks.md');
|
|
117
|
+
let content;
|
|
118
|
+
try {
|
|
119
|
+
content = await readFile(tasksPath, 'utf-8');
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return { success: false, error: `Cannot read tasks.md at ${tasksPath}` };
|
|
123
|
+
}
|
|
124
|
+
const lines = content.split('\n');
|
|
125
|
+
let found = false;
|
|
126
|
+
// Find and update the task line
|
|
127
|
+
for (let i = 0; i < lines.length; i++) {
|
|
128
|
+
const line = lines[i];
|
|
129
|
+
// Match: - [ ] taskId or - [ ]* taskId (with optional asterisk)
|
|
130
|
+
// Pattern: starts with "- [ ]" optionally followed by "*", then the task ID
|
|
131
|
+
const taskPattern = new RegExp(`^(-\\s+\\[) (\\]\\*?\\s+${taskId.replace('.', '\\.')}\\s)`);
|
|
132
|
+
const match = line.match(taskPattern);
|
|
133
|
+
if (match) {
|
|
134
|
+
// Replace [ ] with [x]
|
|
135
|
+
lines[i] = line.replace(taskPattern, '$1x$2');
|
|
136
|
+
found = true;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (!found) {
|
|
141
|
+
return { success: false, error: `Task ${taskId} not found in tasks.md` };
|
|
142
|
+
}
|
|
143
|
+
// Atomic write: temp file + rename
|
|
144
|
+
const tempPath = join(specDir, `tasks.${randomBytes(8).toString('hex')}.tmp`);
|
|
145
|
+
const newContent = lines.join('\n');
|
|
146
|
+
try {
|
|
147
|
+
await writeFile(tempPath, newContent, 'utf-8');
|
|
148
|
+
await rename(tempPath, tasksPath);
|
|
149
|
+
return { success: true };
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
// Clean up temp file on error
|
|
153
|
+
try {
|
|
154
|
+
await rm(tempPath, { force: true });
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// Ignore cleanup errors
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
success: false,
|
|
161
|
+
error: error instanceof Error ? error.message : 'Failed to write tasks.md'
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=TaskParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskParser.js","sourceRoot":"","sources":["../../src/services/TaskParser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAsC1C;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,wDAAwD,CAAC;AAEnF;;GAEG;AACH,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,IAAY;IAOjC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;IACrD,MAAM,SAAS,GAAG,SAAS,KAAK,GAAG,CAAC;IACpC,MAAM,WAAW,GAAG,QAAQ,KAAK,GAAG,CAAC;IACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAE/B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,KAAe,EAAE,UAAkB;IAC3D,MAAM,gBAAgB,GAAa,EAAE,CAAC;IAEtC,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,gDAAgD;QAChD,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,EAAE,CAAC;YACnE,MAAM;QACR,CAAC;QAED,uDAAuD;QACvD,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1D,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL;;;WAGG;QACH,KAAK,CAAC,KAAK,CAAC,OAAe;YACzB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAE5C,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,yCAAyC;gBACzC,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,KAAK,GAAW,EAAE,CAAC;YAEzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBAEtB,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrB,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;oBACnC,IAAI,MAAM,EAAE,CAAC;wBACX,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;wBAEnD,KAAK,CAAC,IAAI,CAAC;4BACT,EAAE,EAAE,MAAM,CAAC,EAAE;4BACb,KAAK,EAAE,MAAM,CAAC,KAAK;4BACnB,WAAW;4BACX,SAAS,EAAE,MAAM,CAAC,SAAS;4BAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;4BACzB,WAAW,EAAE,MAAM,CAAC,WAAW;yBAChC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAED;;;WAGG;QACH,eAAe,CAAC,KAAsB;YACpC,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC;QAED;;;WAGG;QACH,WAAW,CAAC,KAAsB,EAAE,EAAU;YAC5C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,CAAC;QAED;;;;WAIG;QACH,KAAK,CAAC,gBAAgB,CAAC,OAAe,EAAE,MAAc;YACpD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAE5C,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,SAAS,EAAE,EAAE,CAAC;YAC3E,CAAC;YAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,KAAK,GAAG,KAAK,CAAC;YAElB,gCAAgC;YAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,gEAAgE;gBAChE,4EAA4E;gBAC5E,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,2BAA2B,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC5F,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBAEtC,IAAI,KAAK,EAAE,CAAC;oBACV,uBAAuB;oBACvB,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;oBAC9C,KAAK,GAAG,IAAI,CAAC;oBACb,MAAM;gBACR,CAAC;YACH,CAAC;YAED,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,MAAM,wBAAwB,EAAE,CAAC;YAC3E,CAAC;YAED,mCAAmC;YACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC9E,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEpC,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;gBAC/C,MAAM,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;gBAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC3B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,8BAA8B;gBAC9B,IAAI,CAAC;oBACH,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACtC,CAAC;gBAAC,MAAM,CAAC;oBACP,wBAAwB;gBAC1B,CAAC;gBACD,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B;iBAC3E,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task Runner Service
|
|
3
|
+
* Task 4.2: Implement task runner for incremental implementation execution
|
|
4
|
+
* Requirements: 5.2, 5.3, 5.4
|
|
5
|
+
*/
|
|
6
|
+
import type { AgentInvokerService } from './AgentInvoker.js';
|
|
7
|
+
import type { CommitServiceInterface } from './CommitService.js';
|
|
8
|
+
import type { TaskParserService, Task } from './TaskParser.js';
|
|
9
|
+
import type { GlobalFlags } from '../types/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* Checkpoint decision type
|
|
12
|
+
* Requirements: 5.5 - Support continue, pause, and abort at checkpoints
|
|
13
|
+
*/
|
|
14
|
+
export type CheckpointDecision = 'continue' | 'pause' | 'abort';
|
|
15
|
+
/**
|
|
16
|
+
* Task execution options
|
|
17
|
+
* Requirements: 5.2 - Execute tasks with configurable options
|
|
18
|
+
*/
|
|
19
|
+
export interface TaskExecutionOptions {
|
|
20
|
+
readonly feature: string;
|
|
21
|
+
readonly specDir: string;
|
|
22
|
+
readonly workingDir: string;
|
|
23
|
+
readonly startFromTask: number;
|
|
24
|
+
readonly onProgress: (current: number, total: number, task: Task) => void;
|
|
25
|
+
readonly onCheckpoint: (current: number, total: number) => Promise<CheckpointDecision>;
|
|
26
|
+
readonly flags: GlobalFlags;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Task execution result
|
|
30
|
+
* Requirements: 5.4 - Track progress and completion
|
|
31
|
+
*/
|
|
32
|
+
export interface TaskExecutionResult {
|
|
33
|
+
readonly success: boolean;
|
|
34
|
+
readonly completedTasks: number;
|
|
35
|
+
readonly totalTasks: number;
|
|
36
|
+
readonly pausedAt: number | undefined;
|
|
37
|
+
readonly error: string | undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Task runner service interface
|
|
41
|
+
* Requirements: 5.2, 5.3, 5.4
|
|
42
|
+
*/
|
|
43
|
+
export interface TaskRunnerService {
|
|
44
|
+
execute(options: TaskExecutionOptions): Promise<TaskExecutionResult>;
|
|
45
|
+
abort(): void;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create task runner service
|
|
49
|
+
* Requirements: 5.2, 5.3, 5.4 - Factory function for task execution
|
|
50
|
+
*/
|
|
51
|
+
export declare function createTaskRunner(agentInvoker: AgentInvokerService, commitService: CommitServiceInterface, taskParser: TaskParserService): TaskRunnerService;
|
|
52
|
+
//# sourceMappingURL=TaskRunner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskRunner.d.ts","sourceRoot":"","sources":["../../src/services/TaskRunner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAEhE;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC1E,QAAQ,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACvF,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACrE,KAAK,IAAI,IAAI,CAAC;CACf;AA2BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,mBAAmB,EACjC,aAAa,EAAE,sBAAsB,EACrC,UAAU,EAAE,iBAAiB,GAC5B,iBAAiB,CAyHnB"}
|