@amsterdamdatalabs/enact-factory 0.1.1
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/LICENSE +674 -0
- package/README.md +566 -0
- package/dist/adapters/agenticLoop.d.ts +90 -0
- package/dist/adapters/agenticLoop.d.ts.map +1 -0
- package/dist/adapters/agenticLoop.js +219 -0
- package/dist/adapters/agenticLoop.js.map +1 -0
- package/dist/adapters/base.d.ts +16 -0
- package/dist/adapters/base.d.ts.map +1 -0
- package/dist/adapters/base.js +135 -0
- package/dist/adapters/base.js.map +1 -0
- package/dist/adapters/claude.d.ts +13 -0
- package/dist/adapters/claude.d.ts.map +1 -0
- package/dist/adapters/claude.js +318 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/codex.d.ts +14 -0
- package/dist/adapters/codex.d.ts.map +1 -0
- package/dist/adapters/codex.js +366 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/cryptoQuantAdapter.d.ts +85 -0
- package/dist/adapters/cryptoQuantAdapter.d.ts.map +1 -0
- package/dist/adapters/cryptoQuantAdapter.js +238 -0
- package/dist/adapters/cryptoQuantAdapter.js.map +1 -0
- package/dist/adapters/cursor.d.ts +13 -0
- package/dist/adapters/cursor.d.ts.map +1 -0
- package/dist/adapters/cursor.js +300 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/envPath.d.ts +20 -0
- package/dist/adapters/envPath.d.ts.map +1 -0
- package/dist/adapters/envPath.js +49 -0
- package/dist/adapters/envPath.js.map +1 -0
- package/dist/adapters/hermes.d.ts +13 -0
- package/dist/adapters/hermes.d.ts.map +1 -0
- package/dist/adapters/hermes.js +283 -0
- package/dist/adapters/hermes.js.map +1 -0
- package/dist/adapters/index.d.ts +18 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +56 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/opencode.d.ts +13 -0
- package/dist/adapters/opencode.d.ts.map +1 -0
- package/dist/adapters/opencode.js +282 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/processRegistry.d.ts +38 -0
- package/dist/adapters/processRegistry.d.ts.map +1 -0
- package/dist/adapters/processRegistry.js +147 -0
- package/dist/adapters/processRegistry.js.map +1 -0
- package/dist/adapters/responses.d.ts +16 -0
- package/dist/adapters/responses.d.ts.map +1 -0
- package/dist/adapters/responses.js +244 -0
- package/dist/adapters/responses.js.map +1 -0
- package/dist/adapters/streamBuffer.d.ts +59 -0
- package/dist/adapters/streamBuffer.d.ts.map +1 -0
- package/dist/adapters/streamBuffer.js +123 -0
- package/dist/adapters/streamBuffer.js.map +1 -0
- package/dist/adapters/tools.d.ts +30 -0
- package/dist/adapters/tools.d.ts.map +1 -0
- package/dist/adapters/tools.js +219 -0
- package/dist/adapters/tools.js.map +1 -0
- package/dist/adapters/types.d.ts +82 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +6 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/agents/agentBus.d.ts +160 -0
- package/dist/agents/agentBus.d.ts.map +1 -0
- package/dist/agents/agentBus.js +350 -0
- package/dist/agents/agentBus.js.map +1 -0
- package/dist/agents/agentPair.d.ts +215 -0
- package/dist/agents/agentPair.d.ts.map +1 -0
- package/dist/agents/agentPair.js +456 -0
- package/dist/agents/agentPair.js.map +1 -0
- package/dist/agents/auditor.d.ts +27 -0
- package/dist/agents/auditor.d.ts.map +1 -0
- package/dist/agents/auditor.js +238 -0
- package/dist/agents/auditor.js.map +1 -0
- package/dist/agents/cliStreamParser.d.ts +18 -0
- package/dist/agents/cliStreamParser.d.ts.map +1 -0
- package/dist/agents/cliStreamParser.js +156 -0
- package/dist/agents/cliStreamParser.js.map +1 -0
- package/dist/agents/documenter.d.ts +31 -0
- package/dist/agents/documenter.d.ts.map +1 -0
- package/dist/agents/documenter.js +286 -0
- package/dist/agents/documenter.js.map +1 -0
- package/dist/agents/draftAnalyzer.d.ts +50 -0
- package/dist/agents/draftAnalyzer.d.ts.map +1 -0
- package/dist/agents/draftAnalyzer.js +289 -0
- package/dist/agents/draftAnalyzer.js.map +1 -0
- package/dist/agents/evaluator.d.ts +61 -0
- package/dist/agents/evaluator.d.ts.map +1 -0
- package/dist/agents/evaluator.js +338 -0
- package/dist/agents/evaluator.js.map +1 -0
- package/dist/agents/executor.d.ts +33 -0
- package/dist/agents/executor.d.ts.map +1 -0
- package/dist/agents/executor.js +130 -0
- package/dist/agents/executor.js.map +1 -0
- package/dist/agents/index.d.ts +10 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +10 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/pairMetrics.d.ts +63 -0
- package/dist/agents/pairMetrics.d.ts.map +1 -0
- package/dist/agents/pairMetrics.js +232 -0
- package/dist/agents/pairMetrics.js.map +1 -0
- package/dist/agents/pairPipeline.d.ts +184 -0
- package/dist/agents/pairPipeline.d.ts.map +1 -0
- package/dist/agents/pairPipeline.js +934 -0
- package/dist/agents/pairPipeline.js.map +1 -0
- package/dist/agents/pairWebhook.d.ts +59 -0
- package/dist/agents/pairWebhook.d.ts.map +1 -0
- package/dist/agents/pairWebhook.js +242 -0
- package/dist/agents/pairWebhook.js.map +1 -0
- package/dist/agents/pipelineFormat.d.ts +8 -0
- package/dist/agents/pipelineFormat.d.ts.map +1 -0
- package/dist/agents/pipelineFormat.js +65 -0
- package/dist/agents/pipelineFormat.js.map +1 -0
- package/dist/agents/pipelineGuards.d.ts +23 -0
- package/dist/agents/pipelineGuards.d.ts.map +1 -0
- package/dist/agents/pipelineGuards.js +257 -0
- package/dist/agents/pipelineGuards.js.map +1 -0
- package/dist/agents/reviewer.d.ts +37 -0
- package/dist/agents/reviewer.d.ts.map +1 -0
- package/dist/agents/reviewer.js +214 -0
- package/dist/agents/reviewer.js.map +1 -0
- package/dist/agents/skillDocumenter.d.ts +23 -0
- package/dist/agents/skillDocumenter.d.ts.map +1 -0
- package/dist/agents/skillDocumenter.js +219 -0
- package/dist/agents/skillDocumenter.js.map +1 -0
- package/dist/agents/tester.d.ts +37 -0
- package/dist/agents/tester.d.ts.map +1 -0
- package/dist/agents/tester.js +309 -0
- package/dist/agents/tester.js.map +1 -0
- package/dist/automation/autonomousRunner.d.ts +145 -0
- package/dist/automation/autonomousRunner.d.ts.map +1 -0
- package/dist/automation/autonomousRunner.js +1272 -0
- package/dist/automation/autonomousRunner.js.map +1 -0
- package/dist/automation/dailyReporter.d.ts +26 -0
- package/dist/automation/dailyReporter.d.ts.map +1 -0
- package/dist/automation/dailyReporter.js +130 -0
- package/dist/automation/dailyReporter.js.map +1 -0
- package/dist/automation/index.d.ts +5 -0
- package/dist/automation/index.d.ts.map +1 -0
- package/dist/automation/index.js +5 -0
- package/dist/automation/index.js.map +1 -0
- package/dist/automation/longRunningMonitor.d.ts +26 -0
- package/dist/automation/longRunningMonitor.d.ts.map +1 -0
- package/dist/automation/longRunningMonitor.js +356 -0
- package/dist/automation/longRunningMonitor.js.map +1 -0
- package/dist/automation/prOwnership.d.ts +18 -0
- package/dist/automation/prOwnership.d.ts.map +1 -0
- package/dist/automation/prOwnership.js +61 -0
- package/dist/automation/prOwnership.js.map +1 -0
- package/dist/automation/runnerExecution.d.ts +57 -0
- package/dist/automation/runnerExecution.d.ts.map +1 -0
- package/dist/automation/runnerExecution.js +701 -0
- package/dist/automation/runnerExecution.js.map +1 -0
- package/dist/automation/runnerState.d.ts +170 -0
- package/dist/automation/runnerState.d.ts.map +1 -0
- package/dist/automation/runnerState.js +496 -0
- package/dist/automation/runnerState.js.map +1 -0
- package/dist/automation/runnerTypes.d.ts +57 -0
- package/dist/automation/runnerTypes.d.ts.map +1 -0
- package/dist/automation/runnerTypes.js +5 -0
- package/dist/automation/runnerTypes.js.map +1 -0
- package/dist/automation/scheduler.d.ts +75 -0
- package/dist/automation/scheduler.d.ts.map +1 -0
- package/dist/automation/scheduler.js +402 -0
- package/dist/automation/scheduler.js.map +1 -0
- package/dist/azdo/azdo.d.ts +70 -0
- package/dist/azdo/azdo.d.ts.map +1 -0
- package/dist/azdo/azdo.js +328 -0
- package/dist/azdo/azdo.js.map +1 -0
- package/dist/azdo/index.d.ts +3 -0
- package/dist/azdo/index.d.ts.map +1 -0
- package/dist/azdo/index.js +3 -0
- package/dist/azdo/index.js.map +1 -0
- package/dist/azdo/projectUpdater.d.ts +13 -0
- package/dist/azdo/projectUpdater.d.ts.map +1 -0
- package/dist/azdo/projectUpdater.js +155 -0
- package/dist/azdo/projectUpdater.js.map +1 -0
- package/dist/azureDevOps/client.d.ts +75 -0
- package/dist/azureDevOps/client.d.ts.map +1 -0
- package/dist/azureDevOps/client.js +150 -0
- package/dist/azureDevOps/client.js.map +1 -0
- package/dist/azureDevOps/hierarchy.d.ts +119 -0
- package/dist/azureDevOps/hierarchy.d.ts.map +1 -0
- package/dist/azureDevOps/hierarchy.js +470 -0
- package/dist/azureDevOps/hierarchy.js.map +1 -0
- package/dist/azureDevOps/mapper.d.ts +101 -0
- package/dist/azureDevOps/mapper.d.ts.map +1 -0
- package/dist/azureDevOps/mapper.js +438 -0
- package/dist/azureDevOps/mapper.js.map +1 -0
- package/dist/azureDevOps/stateMapping.d.ts +15 -0
- package/dist/azureDevOps/stateMapping.d.ts.map +1 -0
- package/dist/azureDevOps/stateMapping.js +141 -0
- package/dist/azureDevOps/stateMapping.js.map +1 -0
- package/dist/cli/authHandler.d.ts +13 -0
- package/dist/cli/authHandler.d.ts.map +1 -0
- package/dist/cli/authHandler.js +70 -0
- package/dist/cli/authHandler.js.map +1 -0
- package/dist/cli/checkHandler.d.ts +27 -0
- package/dist/cli/checkHandler.d.ts.map +1 -0
- package/dist/cli/checkHandler.js +560 -0
- package/dist/cli/checkHandler.js.map +1 -0
- package/dist/cli/daemon.d.ts +30 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +141 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/factoryCommands.d.ts +3 -0
- package/dist/cli/factoryCommands.d.ts.map +1 -0
- package/dist/cli/factoryCommands.js +165 -0
- package/dist/cli/factoryCommands.js.map +1 -0
- package/dist/cli/promptHandler.d.ts +13 -0
- package/dist/cli/promptHandler.d.ts.map +1 -0
- package/dist/cli/promptHandler.js +193 -0
- package/dist/cli/promptHandler.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +320 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/agentLifecycle.d.ts +322 -0
- package/dist/core/agentLifecycle.d.ts.map +1 -0
- package/dist/core/agentLifecycle.js +230 -0
- package/dist/core/agentLifecycle.js.map +1 -0
- package/dist/core/areaMapping.d.ts +9 -0
- package/dist/core/areaMapping.d.ts.map +1 -0
- package/dist/core/areaMapping.js +37 -0
- package/dist/core/areaMapping.js.map +1 -0
- package/dist/core/config.d.ts +469 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +780 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/dashboardContract.d.ts +204 -0
- package/dist/core/dashboardContract.d.ts.map +1 -0
- package/dist/core/dashboardContract.js +205 -0
- package/dist/core/dashboardContract.js.map +1 -0
- package/dist/core/devopsModel.d.ts +138 -0
- package/dist/core/devopsModel.d.ts.map +1 -0
- package/dist/core/devopsModel.js +137 -0
- package/dist/core/devopsModel.js.map +1 -0
- package/dist/core/envFile.d.ts +11 -0
- package/dist/core/envFile.d.ts.map +1 -0
- package/dist/core/envFile.js +104 -0
- package/dist/core/envFile.js.map +1 -0
- package/dist/core/eventHub.d.ts +220 -0
- package/dist/core/eventHub.d.ts.map +1 -0
- package/dist/core/eventHub.js +136 -0
- package/dist/core/eventHub.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/laneExecutionState.d.ts +29 -0
- package/dist/core/laneExecutionState.d.ts.map +1 -0
- package/dist/core/laneExecutionState.js +18 -0
- package/dist/core/laneExecutionState.js.map +1 -0
- package/dist/core/laneStatus.d.ts +49 -0
- package/dist/core/laneStatus.d.ts.map +1 -0
- package/dist/core/laneStatus.js +153 -0
- package/dist/core/laneStatus.js.map +1 -0
- package/dist/core/prSidecar.d.ts +96 -0
- package/dist/core/prSidecar.d.ts.map +1 -0
- package/dist/core/prSidecar.js +33 -0
- package/dist/core/prSidecar.js.map +1 -0
- package/dist/core/runtimeConfig.d.ts +6 -0
- package/dist/core/runtimeConfig.d.ts.map +1 -0
- package/dist/core/runtimeConfig.js +24 -0
- package/dist/core/runtimeConfig.js.map +1 -0
- package/dist/core/scmProvider.d.ts +19 -0
- package/dist/core/scmProvider.d.ts.map +1 -0
- package/dist/core/scmProvider.js +38 -0
- package/dist/core/scmProvider.js.map +1 -0
- package/dist/core/service.d.ts +10 -0
- package/dist/core/service.d.ts.map +1 -0
- package/dist/core/service.js +297 -0
- package/dist/core/service.js.map +1 -0
- package/dist/core/traceCollector.d.ts +105 -0
- package/dist/core/traceCollector.d.ts.map +1 -0
- package/dist/core/traceCollector.js +141 -0
- package/dist/core/traceCollector.js.map +1 -0
- package/dist/core/types.d.ts +432 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/workItemMapper.d.ts +39 -0
- package/dist/core/workItemMapper.d.ts.map +1 -0
- package/dist/core/workItemMapper.js +427 -0
- package/dist/core/workItemMapper.js.map +1 -0
- package/dist/core/workItemModel.d.ts +120 -0
- package/dist/core/workItemModel.d.ts.map +1 -0
- package/dist/core/workItemModel.js +104 -0
- package/dist/core/workItemModel.js.map +1 -0
- package/dist/core/workItemPayload.d.ts +195 -0
- package/dist/core/workItemPayload.d.ts.map +1 -0
- package/dist/core/workItemPayload.js +24 -0
- package/dist/core/workItemPayload.js.map +1 -0
- package/dist/core/workspaceConfig.d.ts +57 -0
- package/dist/core/workspaceConfig.d.ts.map +1 -0
- package/dist/core/workspaceConfig.js +184 -0
- package/dist/core/workspaceConfig.js.map +1 -0
- package/dist/doctor.d.ts +18 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +34 -0
- package/dist/doctor.js.map +1 -0
- package/dist/factory/activeSkill.d.ts +11 -0
- package/dist/factory/activeSkill.d.ts.map +1 -0
- package/dist/factory/activeSkill.js +44 -0
- package/dist/factory/activeSkill.js.map +1 -0
- package/dist/factory/assignment.d.ts +54 -0
- package/dist/factory/assignment.d.ts.map +1 -0
- package/dist/factory/assignment.js +94 -0
- package/dist/factory/assignment.js.map +1 -0
- package/dist/factory/auditLog.d.ts +10 -0
- package/dist/factory/auditLog.d.ts.map +1 -0
- package/dist/factory/auditLog.js +38 -0
- package/dist/factory/auditLog.js.map +1 -0
- package/dist/factory/closureRequirements.d.ts +12 -0
- package/dist/factory/closureRequirements.d.ts.map +1 -0
- package/dist/factory/closureRequirements.js +30 -0
- package/dist/factory/closureRequirements.js.map +1 -0
- package/dist/factory/delegationPrompt.d.ts +3 -0
- package/dist/factory/delegationPrompt.d.ts.map +1 -0
- package/dist/factory/delegationPrompt.js +16 -0
- package/dist/factory/delegationPrompt.js.map +1 -0
- package/dist/factory/http.d.ts +3 -0
- package/dist/factory/http.d.ts.map +1 -0
- package/dist/factory/http.js +555 -0
- package/dist/factory/http.js.map +1 -0
- package/dist/factory/lifecyclePushMap.d.ts +4 -0
- package/dist/factory/lifecyclePushMap.d.ts.map +1 -0
- package/dist/factory/lifecyclePushMap.js +7 -0
- package/dist/factory/lifecyclePushMap.js.map +1 -0
- package/dist/factory/missions.d.ts +125 -0
- package/dist/factory/missions.d.ts.map +1 -0
- package/dist/factory/missions.js +304 -0
- package/dist/factory/missions.js.map +1 -0
- package/dist/factory/mode.d.ts +9 -0
- package/dist/factory/mode.d.ts.map +1 -0
- package/dist/factory/mode.js +30 -0
- package/dist/factory/mode.js.map +1 -0
- package/dist/factory/operatorActiveSkill.d.ts +15 -0
- package/dist/factory/operatorActiveSkill.d.ts.map +1 -0
- package/dist/factory/operatorActiveSkill.js +95 -0
- package/dist/factory/operatorActiveSkill.js.map +1 -0
- package/dist/factory/paseoDispatcher.d.ts +52 -0
- package/dist/factory/paseoDispatcher.d.ts.map +1 -0
- package/dist/factory/paseoDispatcher.js +122 -0
- package/dist/factory/paseoDispatcher.js.map +1 -0
- package/dist/factory/paseoLifecycle.d.ts +32 -0
- package/dist/factory/paseoLifecycle.d.ts.map +1 -0
- package/dist/factory/paseoLifecycle.js +260 -0
- package/dist/factory/paseoLifecycle.js.map +1 -0
- package/dist/factory/paths.d.ts +31 -0
- package/dist/factory/paths.d.ts.map +1 -0
- package/dist/factory/paths.js +139 -0
- package/dist/factory/paths.js.map +1 -0
- package/dist/factory/progressWatchdog.d.ts +58 -0
- package/dist/factory/progressWatchdog.d.ts.map +1 -0
- package/dist/factory/progressWatchdog.js +160 -0
- package/dist/factory/progressWatchdog.js.map +1 -0
- package/dist/factory/roster.d.ts +59 -0
- package/dist/factory/roster.d.ts.map +1 -0
- package/dist/factory/roster.js +116 -0
- package/dist/factory/roster.js.map +1 -0
- package/dist/factory/runtime.d.ts +44 -0
- package/dist/factory/runtime.d.ts.map +1 -0
- package/dist/factory/runtime.js +238 -0
- package/dist/factory/runtime.js.map +1 -0
- package/dist/factory/sync.d.ts +29 -0
- package/dist/factory/sync.d.ts.map +1 -0
- package/dist/factory/sync.js +77 -0
- package/dist/factory/sync.js.map +1 -0
- package/dist/factory/workitemQueues.d.ts +37 -0
- package/dist/factory/workitemQueues.d.ts.map +1 -0
- package/dist/factory/workitemQueues.js +99 -0
- package/dist/factory/workitemQueues.js.map +1 -0
- package/dist/factory/workitemTriage.d.ts +9 -0
- package/dist/factory/workitemTriage.d.ts.map +1 -0
- package/dist/factory/workitemTriage.js +81 -0
- package/dist/factory/workitemTriage.js.map +1 -0
- package/dist/hooks.d.ts +18 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +96 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +90 -0
- package/dist/index.js.map +1 -0
- package/dist/install/agentCatalog.d.ts +7 -0
- package/dist/install/agentCatalog.d.ts.map +1 -0
- package/dist/install/agentCatalog.js +28 -0
- package/dist/install/agentCatalog.js.map +1 -0
- package/dist/install/bundlePaths.d.ts +10 -0
- package/dist/install/bundlePaths.d.ts.map +1 -0
- package/dist/install/bundlePaths.js +30 -0
- package/dist/install/bundlePaths.js.map +1 -0
- package/dist/install/codex.d.ts +43 -0
- package/dist/install/codex.d.ts.map +1 -0
- package/dist/install/codex.js +207 -0
- package/dist/install/codex.js.map +1 -0
- package/dist/install/enactHome.d.ts +37 -0
- package/dist/install/enactHome.d.ts.map +1 -0
- package/dist/install/enactHome.js +152 -0
- package/dist/install/enactHome.js.map +1 -0
- package/dist/install/plugins.d.ts +115 -0
- package/dist/install/plugins.d.ts.map +1 -0
- package/dist/install/plugins.js +259 -0
- package/dist/install/plugins.js.map +1 -0
- package/dist/install/setup.d.ts +33 -0
- package/dist/install/setup.d.ts.map +1 -0
- package/dist/install/setup.js +167 -0
- package/dist/install/setup.js.map +1 -0
- package/dist/locale/en.d.ts +3 -0
- package/dist/locale/en.d.ts.map +1 -0
- package/dist/locale/en.js +435 -0
- package/dist/locale/en.js.map +1 -0
- package/dist/locale/index.d.ts +28 -0
- package/dist/locale/index.d.ts.map +1 -0
- package/dist/locale/index.js +84 -0
- package/dist/locale/index.js.map +1 -0
- package/dist/locale/prompts/en.d.ts +3 -0
- package/dist/locale/prompts/en.d.ts.map +1 -0
- package/dist/locale/prompts/en.js +254 -0
- package/dist/locale/prompts/en.js.map +1 -0
- package/dist/locale/types.d.ts +433 -0
- package/dist/locale/types.d.ts.map +1 -0
- package/dist/locale/types.js +5 -0
- package/dist/locale/types.js.map +1 -0
- package/dist/mcp/server.d.ts +489 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +597 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/orchestration/decisionEngine.d.ts +175 -0
- package/dist/orchestration/decisionEngine.d.ts.map +1 -0
- package/dist/orchestration/decisionEngine.js +471 -0
- package/dist/orchestration/decisionEngine.js.map +1 -0
- package/dist/orchestration/index.d.ts +5 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +5 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/workItemParser.d.ts +67 -0
- package/dist/orchestration/workItemParser.d.ts.map +1 -0
- package/dist/orchestration/workItemParser.js +560 -0
- package/dist/orchestration/workItemParser.js.map +1 -0
- package/dist/orchestration/workItemScheduler.d.ts +141 -0
- package/dist/orchestration/workItemScheduler.d.ts.map +1 -0
- package/dist/orchestration/workItemScheduler.js +317 -0
- package/dist/orchestration/workItemScheduler.js.map +1 -0
- package/dist/orchestration/workflow.d.ts +145 -0
- package/dist/orchestration/workflow.d.ts.map +1 -0
- package/dist/orchestration/workflow.js +301 -0
- package/dist/orchestration/workflow.js.map +1 -0
- package/dist/providers/codexSessions.d.ts +93 -0
- package/dist/providers/codexSessions.d.ts.map +1 -0
- package/dist/providers/codexSessions.js +366 -0
- package/dist/providers/codexSessions.js.map +1 -0
- package/dist/registry/bsDetector.d.ts +24 -0
- package/dist/registry/bsDetector.d.ts.map +1 -0
- package/dist/registry/bsDetector.js +276 -0
- package/dist/registry/bsDetector.js.map +1 -0
- package/dist/registry/entityScanner.d.ts +36 -0
- package/dist/registry/entityScanner.d.ts.map +1 -0
- package/dist/registry/entityScanner.js +693 -0
- package/dist/registry/entityScanner.js.map +1 -0
- package/dist/registry/index.d.ts +9 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +13 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/schema.d.ts +307 -0
- package/dist/registry/schema.d.ts.map +1 -0
- package/dist/registry/schema.js +139 -0
- package/dist/registry/schema.js.map +1 -0
- package/dist/registry/sqliteStore.d.ts +101 -0
- package/dist/registry/sqliteStore.d.ts.map +1 -0
- package/dist/registry/sqliteStore.js +688 -0
- package/dist/registry/sqliteStore.js.map +1 -0
- package/dist/registry/workItemBridge.d.ts +8 -0
- package/dist/registry/workItemBridge.d.ts.map +1 -0
- package/dist/registry/workItemBridge.js +30 -0
- package/dist/registry/workItemBridge.js.map +1 -0
- package/dist/runners/cliRunner.d.ts +11 -0
- package/dist/runners/cliRunner.d.ts.map +1 -0
- package/dist/runners/cliRunner.js +193 -0
- package/dist/runners/cliRunner.js.map +1 -0
- package/dist/support/apiCache.d.ts +85 -0
- package/dist/support/apiCache.d.ts.map +1 -0
- package/dist/support/apiCache.js +163 -0
- package/dist/support/apiCache.js.map +1 -0
- package/dist/support/chat.d.ts +3 -0
- package/dist/support/chat.d.ts.map +1 -0
- package/dist/support/chat.js +305 -0
- package/dist/support/chat.js.map +1 -0
- package/dist/support/chatBackend.d.ts +25 -0
- package/dist/support/chatBackend.d.ts.map +1 -0
- package/dist/support/chatBackend.js +289 -0
- package/dist/support/chatBackend.js.map +1 -0
- package/dist/support/chatTui.d.ts +3 -0
- package/dist/support/chatTui.d.ts.map +1 -0
- package/dist/support/chatTui.js +1082 -0
- package/dist/support/chatTui.js.map +1 -0
- package/dist/support/costTracker.d.ts +29 -0
- package/dist/support/costTracker.d.ts.map +1 -0
- package/dist/support/costTracker.js +113 -0
- package/dist/support/costTracker.js.map +1 -0
- package/dist/support/dashboardHtml.d.ts +5 -0
- package/dist/support/dashboardHtml.d.ts.map +1 -0
- package/dist/support/dashboardHtml.js +2629 -0
- package/dist/support/dashboardHtml.js.map +1 -0
- package/dist/support/dev.d.ts +55 -0
- package/dist/support/dev.d.ts.map +1 -0
- package/dist/support/dev.js +298 -0
- package/dist/support/dev.js.map +1 -0
- package/dist/support/editParser.d.ts +37 -0
- package/dist/support/editParser.d.ts.map +1 -0
- package/dist/support/editParser.js +365 -0
- package/dist/support/editParser.js.map +1 -0
- package/dist/support/ghosttyThemeCatalog.generated.d.ts +2 -0
- package/dist/support/ghosttyThemeCatalog.generated.d.ts.map +1 -0
- package/dist/support/ghosttyThemeCatalog.generated.js +11116 -0
- package/dist/support/ghosttyThemeCatalog.generated.js.map +1 -0
- package/dist/support/gitStatus.d.ts +21 -0
- package/dist/support/gitStatus.d.ts.map +1 -0
- package/dist/support/gitStatus.js +108 -0
- package/dist/support/gitStatus.js.map +1 -0
- package/dist/support/gitTracker.d.ts +30 -0
- package/dist/support/gitTracker.d.ts.map +1 -0
- package/dist/support/gitTracker.js +143 -0
- package/dist/support/gitTracker.js.map +1 -0
- package/dist/support/index.d.ts +12 -0
- package/dist/support/index.d.ts.map +1 -0
- package/dist/support/index.js +12 -0
- package/dist/support/index.js.map +1 -0
- package/dist/support/planner.d.ts +64 -0
- package/dist/support/planner.d.ts.map +1 -0
- package/dist/support/planner.js +396 -0
- package/dist/support/planner.js.map +1 -0
- package/dist/support/projectMapper.d.ts +46 -0
- package/dist/support/projectMapper.d.ts.map +1 -0
- package/dist/support/projectMapper.js +273 -0
- package/dist/support/projectMapper.js.map +1 -0
- package/dist/support/pty-helper.py +117 -0
- package/dist/support/quotaTracker.d.ts +29 -0
- package/dist/support/quotaTracker.d.ts.map +1 -0
- package/dist/support/quotaTracker.js +89 -0
- package/dist/support/quotaTracker.js.map +1 -0
- package/dist/support/rateLimiter.d.ts +101 -0
- package/dist/support/rateLimiter.d.ts.map +1 -0
- package/dist/support/rateLimiter.js +219 -0
- package/dist/support/rateLimiter.js.map +1 -0
- package/dist/support/rollback.d.ts +61 -0
- package/dist/support/rollback.d.ts.map +1 -0
- package/dist/support/rollback.js +329 -0
- package/dist/support/rollback.js.map +1 -0
- package/dist/support/sharedShell.d.ts +17 -0
- package/dist/support/sharedShell.d.ts.map +1 -0
- package/dist/support/sharedShell.js +439 -0
- package/dist/support/sharedShell.js.map +1 -0
- package/dist/support/stuckDetector.d.ts +68 -0
- package/dist/support/stuckDetector.d.ts.map +1 -0
- package/dist/support/stuckDetector.js +174 -0
- package/dist/support/stuckDetector.js.map +1 -0
- package/dist/support/terminalBridge.d.ts +18 -0
- package/dist/support/terminalBridge.d.ts.map +1 -0
- package/dist/support/terminalBridge.js +553 -0
- package/dist/support/terminalBridge.js.map +1 -0
- package/dist/support/timeWindow.d.ts +60 -0
- package/dist/support/timeWindow.d.ts.map +1 -0
- package/dist/support/timeWindow.js +236 -0
- package/dist/support/timeWindow.js.map +1 -0
- package/dist/support/uiThemes.d.ts +44 -0
- package/dist/support/uiThemes.d.ts.map +1 -0
- package/dist/support/uiThemes.js +290 -0
- package/dist/support/uiThemes.js.map +1 -0
- package/dist/support/web.d.ts +29 -0
- package/dist/support/web.d.ts.map +1 -0
- package/dist/support/web.js +1097 -0
- package/dist/support/web.js.map +1 -0
- package/dist/support/worktreeManager.d.ts +20 -0
- package/dist/support/worktreeManager.d.ts.map +1 -0
- package/dist/support/worktreeManager.js +140 -0
- package/dist/support/worktreeManager.js.map +1 -0
- package/dist/task_state_model.py +55 -0
- package/dist/workItemState/store.d.ts +122 -0
- package/dist/workItemState/store.d.ts.map +1 -0
- package/dist/workItemState/store.js +438 -0
- package/dist/workItemState/store.js.map +1 -0
- package/dist/workItems/azdoBridge.d.ts +42 -0
- package/dist/workItems/azdoBridge.d.ts.map +1 -0
- package/dist/workItems/azdoBridge.js +143 -0
- package/dist/workItems/azdoBridge.js.map +1 -0
- package/dist/workItems/azdoSyncRuntime.d.ts +28 -0
- package/dist/workItems/azdoSyncRuntime.d.ts.map +1 -0
- package/dist/workItems/azdoSyncRuntime.js +158 -0
- package/dist/workItems/azdoSyncRuntime.js.map +1 -0
- package/dist/workItems/azureDevOpsSync.d.ts +128 -0
- package/dist/workItems/azureDevOpsSync.d.ts.map +1 -0
- package/dist/workItems/azureDevOpsSync.js +748 -0
- package/dist/workItems/azureDevOpsSync.js.map +1 -0
- package/dist/workItems/helpers.d.ts +11 -0
- package/dist/workItems/helpers.d.ts.map +1 -0
- package/dist/workItems/helpers.js +17 -0
- package/dist/workItems/helpers.js.map +1 -0
- package/dist/workItems/index.d.ts +21 -0
- package/dist/workItems/index.d.ts.map +1 -0
- package/dist/workItems/index.js +89 -0
- package/dist/workItems/index.js.map +1 -0
- package/dist/workItems/localWorkItemFetcher.d.ts +55 -0
- package/dist/workItems/localWorkItemFetcher.d.ts.map +1 -0
- package/dist/workItems/localWorkItemFetcher.js +209 -0
- package/dist/workItems/localWorkItemFetcher.js.map +1 -0
- package/dist/workItems/migrations/001_rename_workItem_to_work_item.sql +10 -0
- package/dist/workItems/postgresStore.d.ts +78 -0
- package/dist/workItems/postgresStore.d.ts.map +1 -0
- package/dist/workItems/postgresStore.js +937 -0
- package/dist/workItems/postgresStore.js.map +1 -0
- package/dist/workItems/schema.d.ts +257 -0
- package/dist/workItems/schema.d.ts.map +1 -0
- package/dist/workItems/schema.js +176 -0
- package/dist/workItems/schema.js.map +1 -0
- package/dist/workItems/sqliteStore.d.ts +124 -0
- package/dist/workItems/sqliteStore.d.ts.map +1 -0
- package/dist/workItems/sqliteStore.js +713 -0
- package/dist/workItems/sqliteStore.js.map +1 -0
- package/dist/workItems/workItemBoardHtml.d.ts +5 -0
- package/dist/workItems/workItemBoardHtml.d.ts.map +1 -0
- package/dist/workItems/workItemBoardHtml.js +2192 -0
- package/dist/workItems/workItemBoardHtml.js.map +1 -0
- package/package.json +99 -0
- package/templates/AGENTS.md +432 -0
- package/templates/BOOT.md +25 -0
- package/templates/BOOTSTRAP.md +50 -0
- package/templates/CHANGELOG_AUDIT.md +74 -0
- package/templates/HEARTBEAT.md +86 -0
- package/templates/IDENTITY.md +27 -0
- package/templates/PR_LAND.md +75 -0
- package/templates/PR_REVIEW.md +97 -0
- package/templates/SOUL.dev.md +52 -0
- package/templates/SOUL.md +81 -0
- package/templates/TOOLS.md +52 -0
- package/templates/USER.md +22 -0
- package/templates/WORKITEM_ANALYSIS.md +31 -0
- package/templates/agents/executor.md +26 -0
- package/templates/agents/plan.md +22 -0
- package/templates/agents/ralph.md +37 -0
- package/templates/agents/review.md +22 -0
- package/templates/agents/team.md +39 -0
|
@@ -0,0 +1,713 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// EnactFactory - SQLite Work Item Store
|
|
3
|
+
// Created: 2026-04-03
|
|
4
|
+
// Purpose: better-sqlite3 기반 워크아이템 저장소
|
|
5
|
+
// Dependencies: better-sqlite3, nanoid
|
|
6
|
+
// ============================================
|
|
7
|
+
import Database from 'better-sqlite3';
|
|
8
|
+
import { nanoid } from 'nanoid';
|
|
9
|
+
import { resolve } from 'node:path';
|
|
10
|
+
import { existsSync, mkdirSync, renameSync } from 'node:fs';
|
|
11
|
+
import { statePath } from '../factory/paths.js';
|
|
12
|
+
import { loadConfig } from '../core/config.js';
|
|
13
|
+
const DEFAULT_DB_PATH = statePath('workitems.db');
|
|
14
|
+
const LEGACY_DB_PATH = statePath('workItems.db');
|
|
15
|
+
export class SqliteWorkItemStore {
|
|
16
|
+
db;
|
|
17
|
+
constructor(dbPath) {
|
|
18
|
+
const path = dbPath ?? DEFAULT_DB_PATH;
|
|
19
|
+
if (!dbPath && !existsSync(path) && existsSync(LEGACY_DB_PATH)) {
|
|
20
|
+
renameSync(LEGACY_DB_PATH, path);
|
|
21
|
+
for (const suffix of ['-wal', '-shm']) {
|
|
22
|
+
const legacySidecar = `${LEGACY_DB_PATH}${suffix}`;
|
|
23
|
+
if (existsSync(legacySidecar)) {
|
|
24
|
+
renameSync(legacySidecar, `${path}${suffix}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
mkdirSync(resolve(path, '..'), { recursive: true });
|
|
29
|
+
this.db = new Database(path);
|
|
30
|
+
// WAL 모드 (동시성 + 성능)
|
|
31
|
+
this.db.pragma('journal_mode = WAL');
|
|
32
|
+
this.db.pragma('foreign_keys = ON');
|
|
33
|
+
this.migrate();
|
|
34
|
+
}
|
|
35
|
+
migrate() {
|
|
36
|
+
const tableExists = (name) => Boolean(this.db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name = ?").get(name));
|
|
37
|
+
const renameColumnIfNeeded = (table, from, to) => {
|
|
38
|
+
if (!tableExists(table))
|
|
39
|
+
return;
|
|
40
|
+
const cols = this.db.prepare(`PRAGMA table_info(${table})`).all().map((c) => c.name);
|
|
41
|
+
if (cols.includes(from) && !cols.includes(to)) {
|
|
42
|
+
this.db.exec(`ALTER TABLE ${table} RENAME COLUMN ${from} TO ${to}`);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
this.db.exec("CREATE TABLE IF NOT EXISTS schema_meta (key TEXT PRIMARY KEY, value TEXT)");
|
|
46
|
+
if (tableExists('workItems') && !tableExists('work_items')) {
|
|
47
|
+
this.db.exec('DROP TRIGGER IF EXISTS workItems_ai');
|
|
48
|
+
this.db.exec('DROP TRIGGER IF EXISTS workItems_ad');
|
|
49
|
+
this.db.exec('DROP TRIGGER IF EXISTS workItems_au');
|
|
50
|
+
this.db.exec('ALTER TABLE workItems RENAME TO work_items');
|
|
51
|
+
if (tableExists('workItem_labels') && !tableExists('work_item_labels'))
|
|
52
|
+
this.db.exec('ALTER TABLE workItem_labels RENAME TO work_item_labels');
|
|
53
|
+
if (tableExists('workItem_dependencies') && !tableExists('work_item_dependencies'))
|
|
54
|
+
this.db.exec('ALTER TABLE workItem_dependencies RENAME TO work_item_dependencies');
|
|
55
|
+
if (tableExists('workItem_relevant_files') && !tableExists('work_item_relevant_files'))
|
|
56
|
+
this.db.exec('ALTER TABLE workItem_relevant_files RENAME TO work_item_relevant_files');
|
|
57
|
+
if (tableExists('workItem_acceptance_criteria') && !tableExists('work_item_acceptance_criteria'))
|
|
58
|
+
this.db.exec('ALTER TABLE workItem_acceptance_criteria RENAME TO work_item_acceptance_criteria');
|
|
59
|
+
if (tableExists('workItem_memory_links') && !tableExists('work_item_memory_links'))
|
|
60
|
+
this.db.exec('ALTER TABLE workItem_memory_links RENAME TO work_item_memory_links');
|
|
61
|
+
if (tableExists('workItem_events') && !tableExists('work_item_events'))
|
|
62
|
+
this.db.exec('ALTER TABLE workItem_events RENAME TO work_item_events');
|
|
63
|
+
if (tableExists('work_item_labels'))
|
|
64
|
+
renameColumnIfNeeded('work_item_labels', 'workItem_id', 'work_item_id');
|
|
65
|
+
if (tableExists('work_item_dependencies'))
|
|
66
|
+
renameColumnIfNeeded('work_item_dependencies', 'workItem_id', 'work_item_id');
|
|
67
|
+
if (tableExists('work_item_relevant_files'))
|
|
68
|
+
renameColumnIfNeeded('work_item_relevant_files', 'workItem_id', 'work_item_id');
|
|
69
|
+
if (tableExists('work_item_acceptance_criteria'))
|
|
70
|
+
renameColumnIfNeeded('work_item_acceptance_criteria', 'workItem_id', 'work_item_id');
|
|
71
|
+
if (tableExists('work_item_memory_links'))
|
|
72
|
+
renameColumnIfNeeded('work_item_memory_links', 'workItem_id', 'work_item_id');
|
|
73
|
+
if (tableExists('work_item_events'))
|
|
74
|
+
renameColumnIfNeeded('work_item_events', 'workItem_id', 'work_item_id');
|
|
75
|
+
}
|
|
76
|
+
this.db.exec(`
|
|
77
|
+
CREATE TABLE IF NOT EXISTS work_items (
|
|
78
|
+
id TEXT PRIMARY KEY,
|
|
79
|
+
project_id TEXT NOT NULL,
|
|
80
|
+
title TEXT NOT NULL,
|
|
81
|
+
description TEXT DEFAULT '',
|
|
82
|
+
-- No DEFAULT on these columns: insert path passes explicit values so SQLite
|
|
83
|
+
-- never fabricates content. Pre-existing DBs keep the column DEFAULT from
|
|
84
|
+
-- prior migrations but the insert path no longer relies on it.
|
|
85
|
+
status TEXT,
|
|
86
|
+
priority TEXT,
|
|
87
|
+
source TEXT,
|
|
88
|
+
kind TEXT,
|
|
89
|
+
area TEXT,
|
|
90
|
+
review_state TEXT,
|
|
91
|
+
resolution TEXT,
|
|
92
|
+
assignee TEXT,
|
|
93
|
+
milestone TEXT,
|
|
94
|
+
estimate_minutes INTEGER,
|
|
95
|
+
complexity TEXT,
|
|
96
|
+
parent_id TEXT,
|
|
97
|
+
azdo_id TEXT,
|
|
98
|
+
azdo_identifier TEXT,
|
|
99
|
+
azdo_url TEXT,
|
|
100
|
+
payload_json TEXT,
|
|
101
|
+
operator_session_id TEXT,
|
|
102
|
+
operator_lane TEXT,
|
|
103
|
+
is_session_root INTEGER DEFAULT 0,
|
|
104
|
+
external_work_item_id TEXT,
|
|
105
|
+
created_at TEXT NOT NULL,
|
|
106
|
+
updated_at TEXT NOT NULL,
|
|
107
|
+
closed_at TEXT,
|
|
108
|
+
FOREIGN KEY (parent_id) REFERENCES work_items(id) ON DELETE SET NULL
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
CREATE TABLE IF NOT EXISTS work_item_labels (
|
|
112
|
+
work_item_id TEXT NOT NULL,
|
|
113
|
+
label_id TEXT NOT NULL,
|
|
114
|
+
PRIMARY KEY (work_item_id, label_id),
|
|
115
|
+
FOREIGN KEY (work_item_id) REFERENCES work_items(id) ON DELETE CASCADE,
|
|
116
|
+
FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
CREATE TABLE IF NOT EXISTS work_item_dependencies (
|
|
120
|
+
work_item_id TEXT NOT NULL,
|
|
121
|
+
depends_on_id TEXT NOT NULL,
|
|
122
|
+
PRIMARY KEY (work_item_id, depends_on_id),
|
|
123
|
+
FOREIGN KEY (work_item_id) REFERENCES work_items(id) ON DELETE CASCADE,
|
|
124
|
+
FOREIGN KEY (depends_on_id) REFERENCES work_items(id) ON DELETE CASCADE
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
CREATE TABLE IF NOT EXISTS work_item_relevant_files (
|
|
128
|
+
work_item_id TEXT NOT NULL,
|
|
129
|
+
file_path TEXT NOT NULL,
|
|
130
|
+
PRIMARY KEY (work_item_id, file_path),
|
|
131
|
+
FOREIGN KEY (work_item_id) REFERENCES work_items(id) ON DELETE CASCADE
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
CREATE TABLE IF NOT EXISTS work_item_acceptance_criteria (
|
|
135
|
+
work_item_id TEXT NOT NULL,
|
|
136
|
+
criterion TEXT NOT NULL,
|
|
137
|
+
sort_order INTEGER DEFAULT 0,
|
|
138
|
+
FOREIGN KEY (work_item_id) REFERENCES work_items(id) ON DELETE CASCADE
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
CREATE TABLE IF NOT EXISTS work_item_memory_links (
|
|
142
|
+
work_item_id TEXT NOT NULL,
|
|
143
|
+
memory_id TEXT NOT NULL,
|
|
144
|
+
linked_at TEXT NOT NULL,
|
|
145
|
+
PRIMARY KEY (work_item_id, memory_id),
|
|
146
|
+
FOREIGN KEY (work_item_id) REFERENCES work_items(id) ON DELETE CASCADE
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
CREATE TABLE IF NOT EXISTS work_item_events (
|
|
150
|
+
id TEXT PRIMARY KEY,
|
|
151
|
+
work_item_id TEXT NOT NULL,
|
|
152
|
+
type TEXT NOT NULL,
|
|
153
|
+
old_value TEXT,
|
|
154
|
+
new_value TEXT,
|
|
155
|
+
content TEXT,
|
|
156
|
+
memory_id TEXT,
|
|
157
|
+
actor TEXT DEFAULT 'system',
|
|
158
|
+
created_at TEXT NOT NULL,
|
|
159
|
+
FOREIGN KEY (work_item_id) REFERENCES work_items(id) ON DELETE CASCADE
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
CREATE TABLE IF NOT EXISTS labels (
|
|
163
|
+
id TEXT PRIMARY KEY,
|
|
164
|
+
name TEXT NOT NULL UNIQUE,
|
|
165
|
+
color TEXT DEFAULT '#6B7280',
|
|
166
|
+
description TEXT
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
CREATE TABLE IF NOT EXISTS milestones (
|
|
170
|
+
id TEXT PRIMARY KEY,
|
|
171
|
+
name TEXT NOT NULL,
|
|
172
|
+
description TEXT,
|
|
173
|
+
due_date TEXT,
|
|
174
|
+
status TEXT DEFAULT 'active',
|
|
175
|
+
created_at TEXT NOT NULL
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
CREATE TABLE IF NOT EXISTS sync_meta (
|
|
179
|
+
key TEXT PRIMARY KEY,
|
|
180
|
+
value TEXT NOT NULL,
|
|
181
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
182
|
+
);
|
|
183
|
+
`);
|
|
184
|
+
const workItemCols = this.db.prepare('PRAGMA table_info(work_items)').all().map((c) => c.name);
|
|
185
|
+
if (!workItemCols.includes('payload_json'))
|
|
186
|
+
this.db.exec('ALTER TABLE work_items ADD COLUMN payload_json TEXT');
|
|
187
|
+
if (!workItemCols.includes('kind'))
|
|
188
|
+
this.db.exec("ALTER TABLE work_items ADD COLUMN kind TEXT DEFAULT 'Backlog item'");
|
|
189
|
+
if (!workItemCols.includes('area'))
|
|
190
|
+
this.db.exec("ALTER TABLE work_items ADD COLUMN area TEXT DEFAULT 'Enact/Factory'");
|
|
191
|
+
if (!workItemCols.includes('review_state'))
|
|
192
|
+
this.db.exec("ALTER TABLE work_items ADD COLUMN review_state TEXT DEFAULT 'none'");
|
|
193
|
+
if (!workItemCols.includes('resolution'))
|
|
194
|
+
this.db.exec("ALTER TABLE work_items ADD COLUMN resolution TEXT DEFAULT 'unresolved'");
|
|
195
|
+
if (!workItemCols.includes('azdo_id'))
|
|
196
|
+
this.db.exec('ALTER TABLE work_items ADD COLUMN azdo_id TEXT');
|
|
197
|
+
if (!workItemCols.includes('azdo_identifier'))
|
|
198
|
+
this.db.exec('ALTER TABLE work_items ADD COLUMN azdo_identifier TEXT');
|
|
199
|
+
if (!workItemCols.includes('azdo_url'))
|
|
200
|
+
this.db.exec('ALTER TABLE work_items ADD COLUMN azdo_url TEXT');
|
|
201
|
+
if (!workItemCols.includes('operator_session_id'))
|
|
202
|
+
this.db.exec('ALTER TABLE work_items ADD COLUMN operator_session_id TEXT');
|
|
203
|
+
if (!workItemCols.includes('operator_lane'))
|
|
204
|
+
this.db.exec('ALTER TABLE work_items ADD COLUMN operator_lane TEXT');
|
|
205
|
+
if (!workItemCols.includes('is_session_root'))
|
|
206
|
+
this.db.exec('ALTER TABLE work_items ADD COLUMN is_session_root INTEGER DEFAULT 0');
|
|
207
|
+
if (!workItemCols.includes('external_work_item_id'))
|
|
208
|
+
this.db.exec('ALTER TABLE work_items ADD COLUMN external_work_item_id TEXT');
|
|
209
|
+
this.db.exec('DROP TABLE IF EXISTS work_items_fts');
|
|
210
|
+
this.db.exec(`
|
|
211
|
+
CREATE VIRTUAL TABLE work_items_fts USING fts5(
|
|
212
|
+
title, description, content=work_items, content_rowid=rowid
|
|
213
|
+
);
|
|
214
|
+
CREATE INDEX IF NOT EXISTS idx_work_items_project ON work_items(project_id);
|
|
215
|
+
CREATE INDEX IF NOT EXISTS idx_work_items_status ON work_items(status);
|
|
216
|
+
CREATE INDEX IF NOT EXISTS idx_work_items_priority ON work_items(priority);
|
|
217
|
+
CREATE INDEX IF NOT EXISTS idx_work_items_parent ON work_items(parent_id);
|
|
218
|
+
CREATE INDEX IF NOT EXISTS idx_work_items_azdo ON work_items(azdo_id);
|
|
219
|
+
CREATE INDEX IF NOT EXISTS idx_work_item_events_item ON work_item_events(work_item_id);
|
|
220
|
+
CREATE INDEX IF NOT EXISTS idx_work_item_events_created ON work_item_events(created_at);
|
|
221
|
+
DROP TRIGGER IF EXISTS work_items_ai;
|
|
222
|
+
DROP TRIGGER IF EXISTS work_items_ad;
|
|
223
|
+
DROP TRIGGER IF EXISTS work_items_au;
|
|
224
|
+
CREATE TRIGGER work_items_ai AFTER INSERT ON work_items BEGIN
|
|
225
|
+
INSERT INTO work_items_fts(rowid, title, description)
|
|
226
|
+
VALUES (new.rowid, new.title, new.description);
|
|
227
|
+
END;
|
|
228
|
+
CREATE TRIGGER work_items_ad AFTER DELETE ON work_items BEGIN
|
|
229
|
+
INSERT INTO work_items_fts(work_items_fts, rowid, title, description)
|
|
230
|
+
VALUES ('delete', old.rowid, old.title, old.description);
|
|
231
|
+
END;
|
|
232
|
+
CREATE TRIGGER work_items_au AFTER UPDATE ON work_items BEGIN
|
|
233
|
+
INSERT INTO work_items_fts(work_items_fts, rowid, title, description)
|
|
234
|
+
VALUES ('delete', old.rowid, old.title, old.description);
|
|
235
|
+
INSERT INTO work_items_fts(rowid, title, description)
|
|
236
|
+
VALUES (new.rowid, new.title, new.description);
|
|
237
|
+
END;
|
|
238
|
+
INSERT INTO work_items_fts(work_items_fts) VALUES('rebuild');
|
|
239
|
+
`);
|
|
240
|
+
const PURGE_KEY = 'azdo_legacy_local_purge_v1';
|
|
241
|
+
const purged = this.db.prepare("SELECT value FROM schema_meta WHERE key = ?").get(PURGE_KEY);
|
|
242
|
+
if (!purged) {
|
|
243
|
+
const cnt = this.db.prepare("SELECT COUNT(*) as cnt FROM work_items WHERE source = 'local' AND payload_json IS NULL").get().cnt;
|
|
244
|
+
if (cnt > 0) {
|
|
245
|
+
console.warn(`[WorkItemStore] Purging ${cnt} legacy source='local' rows (pre-Wave1 sync residue). ` +
|
|
246
|
+
`AzDO heartbeat will re-mirror authoritative items.`);
|
|
247
|
+
this.db.exec("DELETE FROM work_items WHERE source = 'local' AND payload_json IS NULL");
|
|
248
|
+
}
|
|
249
|
+
this.db.prepare("INSERT INTO schema_meta (key, value) VALUES (?, ?)").run(PURGE_KEY, new Date().toISOString());
|
|
250
|
+
}
|
|
251
|
+
this.db.exec(`
|
|
252
|
+
UPDATE work_items
|
|
253
|
+
SET
|
|
254
|
+
kind = COALESCE(kind, CASE
|
|
255
|
+
WHEN EXISTS (
|
|
256
|
+
SELECT 1
|
|
257
|
+
FROM work_item_labels l
|
|
258
|
+
WHERE l.work_item_id = work_items.id
|
|
259
|
+
AND lower(l.label_id) IN ('epic', 'feature', 'bug', 'backlog', 'backlog item')
|
|
260
|
+
) THEN (
|
|
261
|
+
SELECT CASE lower(l.label_id)
|
|
262
|
+
WHEN 'epic' THEN 'Epic'
|
|
263
|
+
WHEN 'feature' THEN 'Feature'
|
|
264
|
+
WHEN 'bug' THEN 'Bug'
|
|
265
|
+
ELSE 'Backlog item'
|
|
266
|
+
END
|
|
267
|
+
FROM work_item_labels l
|
|
268
|
+
WHERE l.work_item_id = work_items.id
|
|
269
|
+
AND lower(l.label_id) IN ('epic', 'feature', 'bug', 'backlog', 'backlog item')
|
|
270
|
+
LIMIT 1
|
|
271
|
+
)
|
|
272
|
+
ELSE 'Backlog item'
|
|
273
|
+
END),
|
|
274
|
+
area = COALESCE(area, CASE
|
|
275
|
+
WHEN lower(project_id) LIKE '%cli%' THEN 'Enact/CLI'
|
|
276
|
+
WHEN lower(project_id) LIKE '%context%' THEN 'Enact/Context'
|
|
277
|
+
WHEN lower(project_id) LIKE '%wiki%' THEN 'Enact/Wiki'
|
|
278
|
+
WHEN lower(project_id) LIKE '%mission-control%' THEN 'Enact/Mission Control'
|
|
279
|
+
WHEN lower(project_id) LIKE '%proc-tap%' THEN 'Enact/Proc Tap'
|
|
280
|
+
WHEN lower(project_id) LIKE '%runtime%' THEN 'Enact/Runtime'
|
|
281
|
+
WHEN lower(project_id) LIKE '%watchdog%' THEN 'Enact/Watchdog'
|
|
282
|
+
ELSE 'Enact/Factory'
|
|
283
|
+
END),
|
|
284
|
+
review_state = COALESCE(review_state, CASE WHEN status = 'in_review' THEN 'pending' ELSE 'none' END),
|
|
285
|
+
resolution = COALESCE(resolution, CASE
|
|
286
|
+
WHEN status = 'done' THEN 'succeeded'
|
|
287
|
+
WHEN status = 'cancelled' THEN 'cancelled'
|
|
288
|
+
WHEN status = 'duplicate' THEN 'duplicate'
|
|
289
|
+
ELSE 'unresolved'
|
|
290
|
+
END)
|
|
291
|
+
`);
|
|
292
|
+
}
|
|
293
|
+
// ============ 워크아이템 CRUD ============
|
|
294
|
+
createWorkItem(input) {
|
|
295
|
+
const id = input.id ?? nanoid(12);
|
|
296
|
+
const now = new Date().toISOString();
|
|
297
|
+
// If a row already exists with this explicit id (e.g. AzDO sync replaying
|
|
298
|
+
// the same numeric id), short-circuit to a no-op return of the existing
|
|
299
|
+
// record. This is what makes the sync idempotent across heartbeats.
|
|
300
|
+
if (input.id) {
|
|
301
|
+
const existing = this.getWorkItem(input.id);
|
|
302
|
+
if (existing)
|
|
303
|
+
return existing;
|
|
304
|
+
}
|
|
305
|
+
const insertWorkItem = this.db.prepare(`
|
|
306
|
+
INSERT INTO work_items (id, project_id, title, description, status, priority, source,
|
|
307
|
+
kind, area, review_state, resolution, assignee, milestone, estimate_minutes,
|
|
308
|
+
complexity, parent_id, azdo_id, azdo_identifier, azdo_url,
|
|
309
|
+
operator_lane, is_session_root, external_work_item_id,
|
|
310
|
+
created_at, updated_at, closed_at)
|
|
311
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
312
|
+
`);
|
|
313
|
+
const insertLabel = this.db.prepare('INSERT OR IGNORE INTO work_item_labels (work_item_id, label_id) VALUES (?, ?)');
|
|
314
|
+
const insertDep = this.db.prepare('INSERT OR IGNORE INTO work_item_dependencies (work_item_id, depends_on_id) VALUES (?, ?)');
|
|
315
|
+
const insertFile = this.db.prepare('INSERT OR IGNORE INTO work_item_relevant_files (work_item_id, file_path) VALUES (?, ?)');
|
|
316
|
+
const insertCriteria = this.db.prepare('INSERT INTO work_item_acceptance_criteria (work_item_id, criterion, sort_order) VALUES (?, ?, ?)');
|
|
317
|
+
const insertEvent = this.db.prepare(`
|
|
318
|
+
INSERT INTO work_item_events (id, work_item_id, type, new_value, actor, created_at)
|
|
319
|
+
VALUES (?, ?, 'created', ?, 'system', ?)
|
|
320
|
+
`);
|
|
321
|
+
const transaction = this.db.transaction(() => {
|
|
322
|
+
insertWorkItem.run(id, input.projectId, input.title, input.description ?? '', input.status ?? null, input.priority ?? null, input.source ?? null, input.kind ?? null, input.area ?? null, input.reviewState ?? null, input.resolution ?? null, input.assignee ?? null, input.milestone ?? null, input.estimateMinutes ?? null, input.complexity ?? null, input.parentId ?? null, input.azdoId ?? null, input.azdoIdentifier ?? null, input.azdoUrl ?? null, input.operatorLane ?? null, input.isSessionRoot ? 1 : 0, input.externalWorkItemId ?? null, input.createdAt ?? now, input.updatedAt ?? now, input.closedAt ?? null);
|
|
323
|
+
for (const labelId of input.labels ?? []) {
|
|
324
|
+
insertLabel.run(id, labelId);
|
|
325
|
+
}
|
|
326
|
+
for (const depId of input.dependencies ?? []) {
|
|
327
|
+
insertDep.run(id, depId);
|
|
328
|
+
}
|
|
329
|
+
for (const filePath of input.relevantFiles ?? []) {
|
|
330
|
+
insertFile.run(id, filePath);
|
|
331
|
+
}
|
|
332
|
+
for (let i = 0; i < (input.acceptanceCriteria ?? []).length; i++) {
|
|
333
|
+
insertCriteria.run(id, input.acceptanceCriteria[i], i);
|
|
334
|
+
}
|
|
335
|
+
insertEvent.run(nanoid(12), id, input.title, now);
|
|
336
|
+
});
|
|
337
|
+
transaction();
|
|
338
|
+
return this.getWorkItem(id);
|
|
339
|
+
}
|
|
340
|
+
getWorkItem(id) {
|
|
341
|
+
const row = this.db.prepare('SELECT * FROM work_items WHERE id = ?').get(id);
|
|
342
|
+
if (!row)
|
|
343
|
+
return null;
|
|
344
|
+
return this.rowToWorkItem(row);
|
|
345
|
+
}
|
|
346
|
+
updateWorkItem(id, patch) {
|
|
347
|
+
const existing = this.getWorkItem(id);
|
|
348
|
+
if (!existing)
|
|
349
|
+
return null;
|
|
350
|
+
const now = new Date().toISOString();
|
|
351
|
+
const fields = [];
|
|
352
|
+
const values = [];
|
|
353
|
+
const fieldMap = {
|
|
354
|
+
projectId: 'project_id', title: 'title', description: 'description',
|
|
355
|
+
status: 'status', priority: 'priority', source: 'source',
|
|
356
|
+
kind: 'kind', area: 'area', reviewState: 'review_state', resolution: 'resolution',
|
|
357
|
+
assignee: 'assignee', milestone: 'milestone',
|
|
358
|
+
estimateMinutes: 'estimate_minutes', complexity: 'complexity',
|
|
359
|
+
parentId: 'parent_id', azdoId: 'azdo_id',
|
|
360
|
+
azdoIdentifier: 'azdo_identifier', azdoUrl: 'azdo_url',
|
|
361
|
+
operatorLane: 'operator_lane',
|
|
362
|
+
externalWorkItemId: 'external_work_item_id',
|
|
363
|
+
};
|
|
364
|
+
for (const [key, col] of Object.entries(fieldMap)) {
|
|
365
|
+
if (key in patch) {
|
|
366
|
+
fields.push(`${col} = ?`);
|
|
367
|
+
values.push(patch[key] ?? null);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if ('isSessionRoot' in patch && patch.isSessionRoot !== undefined) {
|
|
371
|
+
fields.push('is_session_root = ?');
|
|
372
|
+
values.push(patch.isSessionRoot ? 1 : 0);
|
|
373
|
+
}
|
|
374
|
+
if ('createdAt' in patch && patch.createdAt !== undefined) {
|
|
375
|
+
fields.push('created_at = ?');
|
|
376
|
+
values.push(patch.createdAt);
|
|
377
|
+
}
|
|
378
|
+
if ('closedAt' in patch) {
|
|
379
|
+
fields.push('closed_at = ?');
|
|
380
|
+
values.push(patch.closedAt ?? null);
|
|
381
|
+
}
|
|
382
|
+
if (fields.length === 0 && !patch.labels && !patch.dependencies
|
|
383
|
+
&& !patch.relevantFiles && !patch.acceptanceCriteria) {
|
|
384
|
+
return existing;
|
|
385
|
+
}
|
|
386
|
+
// Always set updated_at on every update; use caller-supplied value if present.
|
|
387
|
+
fields.push('updated_at = ?');
|
|
388
|
+
values.push(patch.updatedAt ?? now);
|
|
389
|
+
values.push(id);
|
|
390
|
+
const transaction = this.db.transaction(() => {
|
|
391
|
+
if (fields.length > 1) {
|
|
392
|
+
this.db.prepare(`UPDATE work_items SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
393
|
+
}
|
|
394
|
+
if (patch.labels !== undefined) {
|
|
395
|
+
this.db.prepare('DELETE FROM work_item_labels WHERE work_item_id = ?').run(id);
|
|
396
|
+
const ins = this.db.prepare('INSERT OR IGNORE INTO work_item_labels (work_item_id, label_id) VALUES (?, ?)');
|
|
397
|
+
for (const labelId of patch.labels)
|
|
398
|
+
ins.run(id, labelId);
|
|
399
|
+
}
|
|
400
|
+
if (patch.dependencies !== undefined) {
|
|
401
|
+
this.db.prepare('DELETE FROM work_item_dependencies WHERE work_item_id = ?').run(id);
|
|
402
|
+
const ins = this.db.prepare('INSERT OR IGNORE INTO work_item_dependencies (work_item_id, depends_on_id) VALUES (?, ?)');
|
|
403
|
+
for (const depId of patch.dependencies)
|
|
404
|
+
ins.run(id, depId);
|
|
405
|
+
}
|
|
406
|
+
if (patch.relevantFiles !== undefined) {
|
|
407
|
+
this.db.prepare('DELETE FROM work_item_relevant_files WHERE work_item_id = ?').run(id);
|
|
408
|
+
const ins = this.db.prepare('INSERT OR IGNORE INTO work_item_relevant_files (work_item_id, file_path) VALUES (?, ?)');
|
|
409
|
+
for (const fp of patch.relevantFiles)
|
|
410
|
+
ins.run(id, fp);
|
|
411
|
+
}
|
|
412
|
+
if (patch.acceptanceCriteria !== undefined) {
|
|
413
|
+
this.db.prepare('DELETE FROM work_item_acceptance_criteria WHERE work_item_id = ?').run(id);
|
|
414
|
+
const ins = this.db.prepare('INSERT INTO work_item_acceptance_criteria (work_item_id, criterion, sort_order) VALUES (?, ?, ?)');
|
|
415
|
+
for (let i = 0; i < patch.acceptanceCriteria.length; i++) {
|
|
416
|
+
ins.run(id, patch.acceptanceCriteria[i], i);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
transaction();
|
|
421
|
+
return this.getWorkItem(id);
|
|
422
|
+
}
|
|
423
|
+
deleteWorkItem(id) {
|
|
424
|
+
const result = this.db.prepare('DELETE FROM work_items WHERE id = ?').run(id);
|
|
425
|
+
return result.changes > 0;
|
|
426
|
+
}
|
|
427
|
+
listWorkItems(filter) {
|
|
428
|
+
const conditions = [];
|
|
429
|
+
const params = [];
|
|
430
|
+
if (filter?.projectId) {
|
|
431
|
+
conditions.push('i.project_id = ?');
|
|
432
|
+
params.push(filter.projectId);
|
|
433
|
+
}
|
|
434
|
+
if (filter?.status && filter.status.length > 0) {
|
|
435
|
+
conditions.push(`i.status IN (${filter.status.map(() => '?').join(',')})`);
|
|
436
|
+
params.push(...filter.status);
|
|
437
|
+
}
|
|
438
|
+
if (filter?.priority && filter.priority.length > 0) {
|
|
439
|
+
conditions.push(`i.priority IN (${filter.priority.map(() => '?').join(',')})`);
|
|
440
|
+
params.push(...filter.priority);
|
|
441
|
+
}
|
|
442
|
+
if (filter?.assignee) {
|
|
443
|
+
conditions.push('i.assignee = ?');
|
|
444
|
+
params.push(filter.assignee);
|
|
445
|
+
}
|
|
446
|
+
if (filter?.source) {
|
|
447
|
+
conditions.push('i.source = ?');
|
|
448
|
+
params.push(filter.source);
|
|
449
|
+
}
|
|
450
|
+
if (filter?.parentId) {
|
|
451
|
+
conditions.push('i.parent_id = ?');
|
|
452
|
+
params.push(filter.parentId);
|
|
453
|
+
}
|
|
454
|
+
if (filter?.labels && filter.labels.length > 0) {
|
|
455
|
+
conditions.push(`i.id IN (
|
|
456
|
+
SELECT work_item_id FROM work_item_labels WHERE label_id IN (${filter.labels.map(() => '?').join(',')})
|
|
457
|
+
)`);
|
|
458
|
+
params.push(...filter.labels);
|
|
459
|
+
}
|
|
460
|
+
// FTS 전문검색
|
|
461
|
+
let ftsJoin = '';
|
|
462
|
+
if (filter?.search) {
|
|
463
|
+
ftsJoin = 'INNER JOIN work_items_fts ON work_items_fts.rowid = i.rowid';
|
|
464
|
+
conditions.push('work_items_fts MATCH ?');
|
|
465
|
+
params.push(filter.search);
|
|
466
|
+
}
|
|
467
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
468
|
+
const limit = filter?.limit ?? 50;
|
|
469
|
+
const offset = filter?.offset ?? 0;
|
|
470
|
+
const countRow = this.db.prepare(`SELECT COUNT(*) as cnt FROM work_items i ${ftsJoin} ${where}`).get(...params);
|
|
471
|
+
const total = countRow.cnt;
|
|
472
|
+
const rows = this.db.prepare(`
|
|
473
|
+
SELECT i.* FROM work_items i ${ftsJoin} ${where}
|
|
474
|
+
ORDER BY
|
|
475
|
+
CASE i.priority
|
|
476
|
+
WHEN 'urgent' THEN 0
|
|
477
|
+
WHEN 'high' THEN 1
|
|
478
|
+
WHEN 'medium' THEN 2
|
|
479
|
+
WHEN 'low' THEN 3
|
|
480
|
+
ELSE 4
|
|
481
|
+
END,
|
|
482
|
+
i.updated_at DESC
|
|
483
|
+
LIMIT ? OFFSET ?
|
|
484
|
+
`).all(...params, limit, offset);
|
|
485
|
+
return {
|
|
486
|
+
workItems: rows.map((r) => this.rowToWorkItem(r)),
|
|
487
|
+
total,
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
// ============ 상태 전이 ============
|
|
491
|
+
changeStatus(id, status, actor) {
|
|
492
|
+
const existing = this.getWorkItem(id);
|
|
493
|
+
if (!existing)
|
|
494
|
+
return null;
|
|
495
|
+
const now = new Date().toISOString();
|
|
496
|
+
const closedAt = (status === 'done' || status === 'cancelled' || status === 'duplicate') ? now : null;
|
|
497
|
+
this.db.prepare(`
|
|
498
|
+
UPDATE work_items SET status = ?, updated_at = ?, closed_at = ?
|
|
499
|
+
WHERE id = ?
|
|
500
|
+
`).run(status, now, closedAt, id);
|
|
501
|
+
this.addEvent(id, 'status_changed', {
|
|
502
|
+
oldValue: existing.status,
|
|
503
|
+
newValue: status,
|
|
504
|
+
actor: actor ?? 'system',
|
|
505
|
+
});
|
|
506
|
+
return this.getWorkItem(id);
|
|
507
|
+
}
|
|
508
|
+
// ============ 이벤트 로그 ============
|
|
509
|
+
addEvent(workItemId, type, data) {
|
|
510
|
+
const id = nanoid(12);
|
|
511
|
+
const now = new Date().toISOString();
|
|
512
|
+
this.db.prepare(`
|
|
513
|
+
INSERT INTO work_item_events (id, work_item_id, type, old_value, new_value, content, memory_id, actor, created_at)
|
|
514
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
515
|
+
`).run(id, workItemId, type, data?.oldValue ?? null, data?.newValue ?? null, data?.content ?? null, data?.memoryId ?? null, data?.actor ?? 'system', now);
|
|
516
|
+
return {
|
|
517
|
+
id,
|
|
518
|
+
workItemId,
|
|
519
|
+
type,
|
|
520
|
+
oldValue: data?.oldValue,
|
|
521
|
+
newValue: data?.newValue,
|
|
522
|
+
content: data?.content,
|
|
523
|
+
memoryId: data?.memoryId,
|
|
524
|
+
actor: data?.actor ?? 'system',
|
|
525
|
+
createdAt: now,
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
getEvents(workItemId, limit = 50) {
|
|
529
|
+
return this.db.prepare('SELECT * FROM work_item_events WHERE work_item_id = ? ORDER BY created_at DESC, rowid DESC LIMIT ?').all(workItemId, limit).map(this.rowToEvent);
|
|
530
|
+
}
|
|
531
|
+
getRecentEvents(limit = 20) {
|
|
532
|
+
return this.db.prepare('SELECT * FROM work_item_events ORDER BY created_at DESC, rowid DESC LIMIT ?').all(limit).map(this.rowToEvent);
|
|
533
|
+
}
|
|
534
|
+
// ============ 라벨 ============
|
|
535
|
+
createLabel(name, color = '#6B7280', description) {
|
|
536
|
+
const id = nanoid(8);
|
|
537
|
+
this.db.prepare('INSERT OR IGNORE INTO labels (id, name, color, description) VALUES (?, ?, ?, ?)').run(id, name, color, description ?? null);
|
|
538
|
+
return { id, name, color, description };
|
|
539
|
+
}
|
|
540
|
+
listLabels() {
|
|
541
|
+
return this.db.prepare('SELECT * FROM labels ORDER BY name').all().map((r) => ({
|
|
542
|
+
id: r.id,
|
|
543
|
+
name: r.name,
|
|
544
|
+
color: r.color,
|
|
545
|
+
description: r.description ?? undefined,
|
|
546
|
+
}));
|
|
547
|
+
}
|
|
548
|
+
deleteLabel(id) {
|
|
549
|
+
return this.db.prepare('DELETE FROM labels WHERE id = ?').run(id).changes > 0;
|
|
550
|
+
}
|
|
551
|
+
// ============ 마일스톤 ============
|
|
552
|
+
createMilestone(name, description, dueDate) {
|
|
553
|
+
const id = nanoid(8);
|
|
554
|
+
const now = new Date().toISOString();
|
|
555
|
+
this.db.prepare('INSERT INTO milestones (id, name, description, due_date, status, created_at) VALUES (?, ?, ?, ?, ?, ?)').run(id, name, description ?? null, dueDate ?? null, 'active', now);
|
|
556
|
+
return { id, name, description, dueDate, status: 'active', createdAt: now };
|
|
557
|
+
}
|
|
558
|
+
listMilestones() {
|
|
559
|
+
return this.db.prepare('SELECT * FROM milestones ORDER BY due_date').all().map((r) => ({
|
|
560
|
+
id: r.id,
|
|
561
|
+
name: r.name,
|
|
562
|
+
description: r.description ?? undefined,
|
|
563
|
+
dueDate: r.due_date ?? undefined,
|
|
564
|
+
status: r.status,
|
|
565
|
+
createdAt: r.created_at,
|
|
566
|
+
}));
|
|
567
|
+
}
|
|
568
|
+
// ============ 메모리 연동 ============
|
|
569
|
+
linkMemory(workItemId, memoryId) {
|
|
570
|
+
const now = new Date().toISOString();
|
|
571
|
+
this.db.prepare('INSERT OR IGNORE INTO work_item_memory_links (work_item_id, memory_id, linked_at) VALUES (?, ?, ?)').run(workItemId, memoryId, now);
|
|
572
|
+
this.addEvent(workItemId, 'memory_linked', { memoryId });
|
|
573
|
+
}
|
|
574
|
+
getLinkedMemories(workItemId) {
|
|
575
|
+
return this.db.prepare('SELECT memory_id FROM work_item_memory_links WHERE work_item_id = ? ORDER BY linked_at').all(workItemId).map((r) => r.memory_id);
|
|
576
|
+
}
|
|
577
|
+
// ============ 통계 ============
|
|
578
|
+
getStats(projectId) {
|
|
579
|
+
const where = projectId ? 'WHERE project_id = ?' : '';
|
|
580
|
+
const params = projectId ? [projectId] : [];
|
|
581
|
+
const total = this.db.prepare(`SELECT COUNT(*) as cnt FROM work_items ${where}`).get(...params).cnt;
|
|
582
|
+
const byStatus = {};
|
|
583
|
+
this.db.prepare(`SELECT status, COUNT(*) as cnt FROM work_items ${where} GROUP BY status`).all(...params).forEach((r) => { byStatus[r.status] = r.cnt; });
|
|
584
|
+
const byPriority = {};
|
|
585
|
+
this.db.prepare(`SELECT priority, COUNT(*) as cnt FROM work_items ${where} GROUP BY priority`).all(...params).forEach((r) => { byPriority[r.priority] = r.cnt; });
|
|
586
|
+
const byProject = {};
|
|
587
|
+
this.db.prepare('SELECT project_id, COUNT(*) as cnt FROM work_items GROUP BY project_id').all().forEach((r) => { byProject[r.project_id] = r.cnt; });
|
|
588
|
+
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
|
|
589
|
+
const recentlyCreated = this.db.prepare(`SELECT COUNT(*) as cnt FROM work_items ${where ? where + ' AND' : 'WHERE'} created_at > ?`).get(...params, sevenDaysAgo).cnt;
|
|
590
|
+
const recentlyClosed = this.db.prepare(`SELECT COUNT(*) as cnt FROM work_items ${where ? where + ' AND' : 'WHERE'} closed_at > ?`).get(...params, sevenDaysAgo).cnt;
|
|
591
|
+
return { total, byStatus, byPriority, byProject, recentlyCreated, recentlyClosed };
|
|
592
|
+
}
|
|
593
|
+
// ============ AzDO mirror payload ============
|
|
594
|
+
setPayloadJson(workItemId, json) {
|
|
595
|
+
this.db.prepare('UPDATE work_items SET payload_json = ? WHERE id = ?').run(json, workItemId);
|
|
596
|
+
}
|
|
597
|
+
getPayloadJson(workItemId) {
|
|
598
|
+
const row = this.db.prepare('SELECT payload_json FROM work_items WHERE id = ?').get(workItemId);
|
|
599
|
+
if (!row)
|
|
600
|
+
return null;
|
|
601
|
+
return row.payload_json ?? null;
|
|
602
|
+
}
|
|
603
|
+
// ============ Sync watermark KV ============
|
|
604
|
+
getSyncMeta(key) {
|
|
605
|
+
const row = this.db.prepare('SELECT value FROM sync_meta WHERE key = ?').get(key);
|
|
606
|
+
return row?.value ?? null;
|
|
607
|
+
}
|
|
608
|
+
setSyncMeta(key, value) {
|
|
609
|
+
this.db.prepare(`
|
|
610
|
+
INSERT INTO sync_meta (key, value, updated_at)
|
|
611
|
+
VALUES (?, ?, datetime('now'))
|
|
612
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = datetime('now')
|
|
613
|
+
`).run(key, value);
|
|
614
|
+
}
|
|
615
|
+
getProjectConfigs() {
|
|
616
|
+
return loadConfig().projects;
|
|
617
|
+
}
|
|
618
|
+
seedProjectConfigsIfEmpty(projects) {
|
|
619
|
+
return projects.length > 0 ? projects : this.getProjectConfigs();
|
|
620
|
+
}
|
|
621
|
+
updateOperatorSessionId(workItemId, sessionId) {
|
|
622
|
+
this.db.prepare('UPDATE work_items SET operator_session_id = ?, updated_at = ? WHERE id = ?')
|
|
623
|
+
.run(sessionId, new Date().toISOString(), workItemId);
|
|
624
|
+
}
|
|
625
|
+
pruneOrphans(source, keepIds) {
|
|
626
|
+
const allOfSource = this.db.prepare('SELECT id FROM work_items WHERE source = ?').all(source).map((r) => r.id);
|
|
627
|
+
const toDelete = allOfSource.filter((id) => !keepIds.has(id));
|
|
628
|
+
if (toDelete.length === 0)
|
|
629
|
+
return 0;
|
|
630
|
+
const stmt = this.db.prepare('DELETE FROM work_items WHERE id = ?');
|
|
631
|
+
const tx = this.db.transaction(() => {
|
|
632
|
+
for (const id of toDelete)
|
|
633
|
+
stmt.run(id);
|
|
634
|
+
});
|
|
635
|
+
tx();
|
|
636
|
+
return toDelete.length;
|
|
637
|
+
}
|
|
638
|
+
// ============ 유틸 ============
|
|
639
|
+
close() {
|
|
640
|
+
this.db.close();
|
|
641
|
+
}
|
|
642
|
+
rowToWorkItem(row) {
|
|
643
|
+
const id = row.id;
|
|
644
|
+
const labels = this.db.prepare('SELECT label_id FROM work_item_labels WHERE work_item_id = ?').all(id).map((r) => r.label_id);
|
|
645
|
+
const dependencies = this.db.prepare('SELECT depends_on_id FROM work_item_dependencies WHERE work_item_id = ?').all(id).map((r) => r.depends_on_id);
|
|
646
|
+
const relevantFiles = this.db.prepare('SELECT file_path FROM work_item_relevant_files WHERE work_item_id = ?').all(id).map((r) => r.file_path);
|
|
647
|
+
const acceptanceCriteria = this.db.prepare('SELECT criterion FROM work_item_acceptance_criteria WHERE work_item_id = ? ORDER BY sort_order').all(id).map((r) => r.criterion);
|
|
648
|
+
const memoryIds = this.db.prepare('SELECT memory_id FROM work_item_memory_links WHERE work_item_id = ?').all(id).map((r) => r.memory_id);
|
|
649
|
+
const childIds = this.db.prepare('SELECT id FROM work_items WHERE parent_id = ?').all(id).map((r) => r.id);
|
|
650
|
+
return {
|
|
651
|
+
id,
|
|
652
|
+
projectId: row.project_id,
|
|
653
|
+
title: row.title,
|
|
654
|
+
description: row.description ?? '',
|
|
655
|
+
status: row.status,
|
|
656
|
+
priority: row.priority,
|
|
657
|
+
source: row.source,
|
|
658
|
+
kind: row.kind ?? undefined,
|
|
659
|
+
area: row.area ?? undefined,
|
|
660
|
+
reviewState: row.review_state ?? undefined,
|
|
661
|
+
resolution: row.resolution ?? undefined,
|
|
662
|
+
labels,
|
|
663
|
+
assignee: row.assignee ?? undefined,
|
|
664
|
+
milestone: row.milestone ?? undefined,
|
|
665
|
+
relevantFiles,
|
|
666
|
+
acceptanceCriteria,
|
|
667
|
+
estimateMinutes: row.estimate_minutes ?? undefined,
|
|
668
|
+
complexity: row.complexity ?? undefined,
|
|
669
|
+
dependencies,
|
|
670
|
+
parentId: row.parent_id ?? undefined,
|
|
671
|
+
childIds,
|
|
672
|
+
azdoId: row.azdo_id ?? undefined,
|
|
673
|
+
azdoIdentifier: row.azdo_identifier ?? undefined,
|
|
674
|
+
azdoUrl: row.azdo_url ?? undefined,
|
|
675
|
+
operatorSessionId: row.operator_session_id ?? undefined,
|
|
676
|
+
operatorLane: row.operator_lane ?? undefined,
|
|
677
|
+
isSessionRoot: row.is_session_root === 1 || row.is_session_root === true,
|
|
678
|
+
externalWorkItemId: row.external_work_item_id ?? undefined,
|
|
679
|
+
memoryIds,
|
|
680
|
+
createdAt: row.created_at,
|
|
681
|
+
updatedAt: row.updated_at,
|
|
682
|
+
closedAt: row.closed_at ?? undefined,
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
rowToEvent(row) {
|
|
686
|
+
return {
|
|
687
|
+
id: row.id,
|
|
688
|
+
workItemId: row.work_item_id,
|
|
689
|
+
type: row.type,
|
|
690
|
+
oldValue: row.old_value ?? undefined,
|
|
691
|
+
newValue: row.new_value ?? undefined,
|
|
692
|
+
content: row.content ?? undefined,
|
|
693
|
+
memoryId: row.memory_id ?? undefined,
|
|
694
|
+
actor: row.actor,
|
|
695
|
+
createdAt: row.created_at,
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
// 싱글톤 인스턴스
|
|
700
|
+
let workItemStoreInstance = null;
|
|
701
|
+
export function openSqliteWorkItemStore(dbPath) {
|
|
702
|
+
if (!workItemStoreInstance) {
|
|
703
|
+
workItemStoreInstance = new SqliteWorkItemStore(dbPath);
|
|
704
|
+
}
|
|
705
|
+
return workItemStoreInstance;
|
|
706
|
+
}
|
|
707
|
+
export function closeSqliteWorkItemStore() {
|
|
708
|
+
if (workItemStoreInstance) {
|
|
709
|
+
workItemStoreInstance.close();
|
|
710
|
+
workItemStoreInstance = null;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
//# sourceMappingURL=sqliteStore.js.map
|