agentworkshop 0.2.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/.AgentWorkShop/prompts/host-tools.json +631 -0
- package/.AgentWorkShop/prompts/lead-supervise.md +42 -0
- package/.AgentWorkShop/prompts/mode-goal.md +26 -0
- package/.AgentWorkShop/prompts/mode-loop.md +10 -0
- package/.AgentWorkShop/prompts/mode-pipeline.md +16 -0
- package/.AgentWorkShop/prompts/peer-lead-roster.md +3 -0
- package/.AgentWorkShop/prompts/peer-message.md +14 -0
- package/.AgentWorkShop/prompts/peer-reply-optional.md +2 -0
- package/.AgentWorkShop/prompts/peer-reply-required.md +8 -0
- package/.AgentWorkShop/prompts/scenario-default.md +11 -0
- package/.AgentWorkShop/prompts/system-manual.md +18 -0
- package/.AgentWorkShop/prompts/team-roster.md +9 -0
- package/.AgentWorkShop/prompts/worker-workflow.md +19 -0
- package/.env.example +34 -0
- package/README-zh.md +424 -0
- package/README.md +424 -0
- package/app/.mimosa/hook-state/sess_05189059-e42d-4188-8911-4f7baabe009b.json +1 -0
- package/app/.mimosa/hook-state/sess_05189059-e42d-4188-8911-4f7baabe009b.mtg0vz68-49792-75b0709555.baseline/1459e6269990a5d229b9228c8b2f62ffaa7d350068380ae8b875fee0db45cca6.source +180 -0
- package/app/.mimosa/hook-state/sess_05189059-e42d-4188-8911-4f7baabe009b.mtg0vz68-49792-75b0709555.baseline/c2991e909c70c5c12b90a407c7adcf63384c51668a2b334e6e047fa675c268fe.source +305 -0
- package/app/.mimosa/hook-state/sess_05189059-e42d-4188-8911-4f7baabe009b.mtg0vz68-49792-75b0709555.baseline/e09129039d1e27e3fac24becc9bdafd2d1a7c8049bff24173df007be865f0165.source +264 -0
- package/app/.mimosa/hook-status/sess_05189059-e42d-4188-8911-4f7baabe009b-28ef7c75ea.json +14 -0
- package/app/app.vue +139 -0
- package/app/assets/css/main.css +1257 -0
- package/app/components/AppHeader.vue +675 -0
- package/app/components/AppSidebar.vue +286 -0
- package/app/components/AwChart.vue +44 -0
- package/app/components/AwLogo.vue +75 -0
- package/app/components/workshop/A2aRpcDebugger.vue +237 -0
- package/app/components/workshop/AgentInspectorDrawer.vue +424 -0
- package/app/components/workshop/AgentLanesView.vue +947 -0
- package/app/components/workshop/ArtifactCard.vue +120 -0
- package/app/components/workshop/AssetLibrary.vue +450 -0
- package/app/components/workshop/ChannelSessionList.vue +593 -0
- package/app/components/workshop/CommandPalette.vue +270 -0
- package/app/components/workshop/Composer.vue +731 -0
- package/app/components/workshop/DeviceTwinPanel.vue +607 -0
- package/app/components/workshop/EventBlock.vue +602 -0
- package/app/components/workshop/FileSelectorModal.vue +188 -0
- package/app/components/workshop/InspectorPanel.vue +265 -0
- package/app/components/workshop/LiveAgentBar.vue +362 -0
- package/app/components/workshop/MemoryPanel.vue +364 -0
- package/app/components/workshop/MentionHoverCard.vue +155 -0
- package/app/components/workshop/MultiChannelView.vue +189 -0
- package/app/components/workshop/PaneSplitter.vue +142 -0
- package/app/components/workshop/StatsPanel.vue +168 -0
- package/app/components/workshop/TaskBoardView.vue +636 -0
- package/app/components/workshop/TaskInspectorDrawer.vue +390 -0
- package/app/components/workshop/TranscriptTimeline.vue +545 -0
- package/app/components/workshop/blocks/ClusterArtifact.vue +77 -0
- package/app/components/workshop/blocks/ClusterError.vue +85 -0
- package/app/components/workshop/blocks/ClusterLife.vue +87 -0
- package/app/components/workshop/blocks/ClusterMember.vue +93 -0
- package/app/components/workshop/blocks/ClusterMemory.vue +84 -0
- package/app/components/workshop/blocks/ClusterOther.vue +67 -0
- package/app/components/workshop/blocks/ClusterRoute.vue +359 -0
- package/app/components/workshop/blocks/ClusterStatus.vue +147 -0
- package/app/components/workshop/blocks/ClusterStream.vue +325 -0
- package/app/components/workshop/blocks/ClusterTask.vue +151 -0
- package/app/components/workshop/blocks/ClusterTool.vue +158 -0
- package/app/components/workshop/lanes/LaneBlocks.vue +149 -0
- package/app/components/workshop/terminal/OmpTerminalPanel.vue +1010 -0
- package/app/components/workshop/town/ModelPreview3D.vue +276 -0
- package/app/components/workshop/town/TownScene.ts +1355 -0
- package/app/components/workshop/town/TownScene3D.ts +4533 -0
- package/app/components/workshop/town/TownView.vue +7071 -0
- package/app/composables/useCodeCopy.ts +30 -0
- package/app/composables/useHttp.ts +8 -0
- package/app/composables/useRouteMeta.ts +50 -0
- package/app/composables/useSiteConfig.ts +21 -0
- package/app/composables/workshop/apiClient.ts +95 -0
- package/app/composables/workshop/useCharacterAssets.ts +292 -0
- package/app/composables/workshop/useClusteredBlocks.ts +150 -0
- package/app/composables/workshop/useComposerBus.ts +16 -0
- package/app/composables/workshop/useDaqStream.ts +379 -0
- package/app/composables/workshop/useDcwStream.ts +300 -0
- package/app/composables/workshop/useDeviceTwins.ts +147 -0
- package/app/composables/workshop/useEventBlocks.ts +662 -0
- package/app/composables/workshop/useLocalTime.ts +33 -0
- package/app/composables/workshop/useOpsLog.ts +164 -0
- package/app/composables/workshop/useSceneLayouts.ts +166 -0
- package/app/composables/workshop/useTownBus.ts +47 -0
- package/app/composables/workshop/useVisibleInterval.ts +42 -0
- package/app/composables/workshop/useWorkshopApi.ts +224 -0
- package/app/composables/workshop/useWorkshopWs.ts +113 -0
- package/app/config/index.ts +66 -0
- package/app/config/schema.ts +68 -0
- package/app/error.vue +76 -0
- package/app/layouts/default.vue +100 -0
- package/app/layouts/town.vue +16 -0
- package/app/pages/daq/[id].vue +796 -0
- package/app/pages/daq/index.vue +2577 -0
- package/app/pages/dcw/[id].vue +2259 -0
- package/app/pages/dcw/index.vue +1079 -0
- package/app/pages/index.vue +830 -0
- package/app/pages/logs/index.vue +621 -0
- package/app/pages/monitor.vue +665 -0
- package/app/pages/settings.vue +757 -0
- package/app/pages/tokens.vue +610 -0
- package/app/pages/town.vue +145 -0
- package/app/pages/users.vue +257 -0
- package/app/pages/workshop/agents.vue +382 -0
- package/app/pages/workshop/channel-templates.vue +456 -0
- package/app/pages/workshop/index.vue +604 -0
- package/app/pages/workshop/teams.vue +448 -0
- package/app/pages/workshop/w/[wsId].vue +516 -0
- package/app/plugins/http.ts +71 -0
- package/app/plugins/locale-restore.client.ts +13 -0
- package/app/plugins/runtime-config.client.ts +65 -0
- package/app/plugins/session-restore.client.ts +24 -0
- package/app/plugins/theme.client.ts +15 -0
- package/app/stores/app.ts +32 -0
- package/app/stores/route-trail.ts +45 -0
- package/app/stores/runtime-config.ts +212 -0
- package/app/stores/workshop/connection.ts +184 -0
- package/app/stores/workshop/entities.ts +350 -0
- package/app/stores/workshop/events.ts +292 -0
- package/app/stores/workshop/user.ts +176 -0
- package/app/stores/workshop/workspaces.ts +133 -0
- package/bin/aw.mjs +13 -0
- package/cli/aw.mjs +184 -0
- package/cli/commands/build.mjs +33 -0
- package/cli/commands/config.mjs +157 -0
- package/cli/commands/dev.mjs +74 -0
- package/cli/commands/doctor.mjs +120 -0
- package/cli/commands/home.mjs +75 -0
- package/cli/commands/init.mjs +150 -0
- package/cli/commands/register.mjs +123 -0
- package/cli/commands/start.mjs +106 -0
- package/cli/commands/status.mjs +67 -0
- package/cli/commands/update.mjs +116 -0
- package/cli/commands/version.mjs +32 -0
- package/cli/core/args.mjs +95 -0
- package/cli/core/context.mjs +264 -0
- package/cli/core/errors.mjs +18 -0
- package/cli/core/help.mjs +68 -0
- package/cli/core/logger.mjs +40 -0
- package/cli/core/registry.mjs +111 -0
- package/config.yml +70 -0
- package/docker-compose.yml +34 -0
- package/docs/cli.md +220 -0
- package/i18n/dicts/_en.json +1097 -0
- package/i18n/dicts/_en2.json +300 -0
- package/i18n/dicts/_en3.json +102 -0
- package/i18n/dicts/_en4.json +115 -0
- package/i18n/dicts/_en5.json +33 -0
- package/i18n/dicts/a2aRpcDebugger.json +10 -0
- package/i18n/dicts/agentInspectorDrawer.json +25 -0
- package/i18n/dicts/agentLanesView.json +57 -0
- package/i18n/dicts/agents.json +27 -0
- package/i18n/dicts/appHeader.json +7 -0
- package/i18n/dicts/appSidebar.json +1 -0
- package/i18n/dicts/artifactCard.json +6 -0
- package/i18n/dicts/assetLibrary.json +18 -0
- package/i18n/dicts/awChart.json +1 -0
- package/i18n/dicts/awLogo.json +1 -0
- package/i18n/dicts/channelSessionList.json +45 -0
- package/i18n/dicts/clusterArtifact.json +4 -0
- package/i18n/dicts/clusterError.json +3 -0
- package/i18n/dicts/clusterLife.json +5 -0
- package/i18n/dicts/clusterMember.json +3 -0
- package/i18n/dicts/clusterMemory.json +3 -0
- package/i18n/dicts/clusterOther.json +3 -0
- package/i18n/dicts/clusterRoute.json +15 -0
- package/i18n/dicts/clusterStatus.json +3 -0
- package/i18n/dicts/clusterStream.json +3 -0
- package/i18n/dicts/clusterTask.json +10 -0
- package/i18n/dicts/clusterTool.json +3 -0
- package/i18n/dicts/commandPalette.json +16 -0
- package/i18n/dicts/composer.json +38 -0
- package/i18n/dicts/ctpl.json +32 -0
- package/i18n/dicts/daq.json +157 -0
- package/i18n/dicts/daqDetail.json +55 -0
- package/i18n/dicts/dcw.json +68 -0
- package/i18n/dicts/dcwDetail.json +199 -0
- package/i18n/dicts/deviceTwinPanel.json +12 -0
- package/i18n/dicts/eventBlock.json +8 -0
- package/i18n/dicts/fileSelectorModal.json +6 -0
- package/i18n/dicts/inspectorPanel.json +12 -0
- package/i18n/dicts/laneBlocks.json +6 -0
- package/i18n/dicts/liveAgentBar.json +8 -0
- package/i18n/dicts/logs.json +39 -0
- package/i18n/dicts/memoryPanel.json +20 -0
- package/i18n/dicts/mentionHoverCard.json +4 -0
- package/i18n/dicts/modelPreview3D.json +1 -0
- package/i18n/dicts/monitor.json +5 -0
- package/i18n/dicts/multiChannelView.json +13 -0
- package/i18n/dicts/ompTerminalPanel.json +7 -0
- package/i18n/dicts/paneSplitter.json +3 -0
- package/i18n/dicts/settings.json +1 -0
- package/i18n/dicts/statsPanel.json +6 -0
- package/i18n/dicts/taskBoardView.json +22 -0
- package/i18n/dicts/taskInspectorDrawer.json +19 -0
- package/i18n/dicts/teams.json +33 -0
- package/i18n/dicts/tokens.json +30 -0
- package/i18n/dicts/town.json +7 -0
- package/i18n/dicts/townView.json +209 -0
- package/i18n/dicts/transcriptTimeline.json +31 -0
- package/i18n/dicts/users.json +15 -0
- package/i18n/dicts/wsHome.json +33 -0
- package/i18n/dicts/wsView.json +15 -0
- package/i18n/locales/en.ts +1737 -0
- package/i18n/locales/zh-CN.ts +1736 -0
- package/nuxt.config.ts +209 -0
- package/package.json +123 -0
- package/public/assets/game/character/bot.png +0 -0
- package/public/assets/game/character/device-3d.glb +0 -0
- package/public/assets/game/character/hero-3d.glb +0 -0
- package/public/assets/game/character/hero-anime-1.glb +0 -0
- package/public/assets/game/character/hero-anime-2.glb +0 -0
- package/public/assets/game/character/hero-anime-3.glb +0 -0
- package/public/assets/game/character/hero-anime-4.glb +0 -0
- package/public/assets/game/character/knight.png +0 -0
- package/public/assets/game/character/mage.png +0 -0
- package/public/assets/game/coin.png +0 -0
- package/public/assets/game/devices/agv.glb +0 -0
- package/public/assets/game/devices/caster.glb +0 -0
- package/public/assets/game/devices/device-console.glb +0 -0
- package/public/assets/game/devices/device-robot-arm.glb +0 -0
- package/public/assets/game/devices/device-scanner.glb +0 -0
- package/public/assets/game/devices/extruder.glb +0 -0
- package/public/assets/game/devices/mdo.glb +0 -0
- package/public/assets/game/devices/power-cabinet.glb +0 -0
- package/public/assets/game/devices/pump.glb +0 -0
- package/public/assets/game/devices/tdo.glb +0 -0
- package/public/assets/game/devices/thickness-scanner.glb +0 -0
- package/public/assets/game/devices/winder.glb +0 -0
- package/public/assets/game/npc/boltnu-sheet.png +0 -0
- package/public/assets/game/npc/fluttaflap-sheet.png +0 -0
- package/public/assets/game/npc/rockitten-sheet.png +0 -0
- package/public/assets/game/npc/tux-sheet.png +0 -0
- package/public/assets/game/player/misa-back-walk.000.png +0 -0
- package/public/assets/game/player/misa-back-walk.001.png +0 -0
- package/public/assets/game/player/misa-back-walk.002.png +0 -0
- package/public/assets/game/player/misa-back-walk.003.png +0 -0
- package/public/assets/game/player/misa-back.png +0 -0
- package/public/assets/game/player/misa-front-walk.000.png +0 -0
- package/public/assets/game/player/misa-front-walk.001.png +0 -0
- package/public/assets/game/player/misa-front-walk.002.png +0 -0
- package/public/assets/game/player/misa-front-walk.003.png +0 -0
- package/public/assets/game/player/misa-front.png +0 -0
- package/public/assets/game/player/misa-left-walk.000.png +0 -0
- package/public/assets/game/player/misa-left-walk.001.png +0 -0
- package/public/assets/game/player/misa-left-walk.002.png +0 -0
- package/public/assets/game/player/misa-left-walk.003.png +0 -0
- package/public/assets/game/player/misa-left.png +0 -0
- package/public/assets/game/player/misa-right-walk.000.png +0 -0
- package/public/assets/game/player/misa-right-walk.001.png +0 -0
- package/public/assets/game/player/misa-right-walk.002.png +0 -0
- package/public/assets/game/player/misa-right-walk.003.png +0 -0
- package/public/assets/game/player/misa-right.png +0 -0
- package/public/assets/game/player-sheet.png +0 -0
- package/public/assets/game/tuxemon-town.json +1 -0
- package/public/assets/game/tuxmon-sample-32px-extruded.png +0 -0
- package/public/assets/game/wuwa/scene-map.png +0 -0
- package/public/assets/game/wuwa/world-far.png +0 -0
- package/public/assets/game/wuwa/world-middle.png +0 -0
- package/public/assets/game/wuwa/world-near.png +0 -0
- package/public/assets/game/wuwa/wu-aura.png +0 -0
- package/public/assets/game/wuwa/wu-lead.png +0 -0
- package/public/assets/game/wuwa/wu-ring.png +0 -0
- package/public/assets/game/wuwa/wu-slash.png +0 -0
- package/public/assets/game/wuwa/wu-worker-0.png +0 -0
- package/public/assets/game/wuwa/wu-worker-1.png +0 -0
- package/public/assets/game/wuwa/wu-worker-2.png +0 -0
- package/public/favicon.svg +14 -0
- package/public/scene/background/cyber-town-background.svg +110 -0
- package/scripts/_daq-realtime-probe.mjs +68 -0
- package/scripts/_daq-warn-probe.mjs +50 -0
- package/scripts/_dbg-agent-tools-audit.mjs +154 -0
- package/scripts/_dbg-agent-workflow-audit.mjs +177 -0
- package/scripts/_dbg-anim-verify.mjs +81 -0
- package/scripts/_dbg-audit-all-pages.mjs +43 -0
- package/scripts/_dbg-autoframe.mjs +103 -0
- package/scripts/_dbg-beacon-final.mjs +181 -0
- package/scripts/_dbg-bind-bidi-e2e.mjs +239 -0
- package/scripts/_dbg-callout-near.mjs +108 -0
- package/scripts/_dbg-chan-focus.mjs +49 -0
- package/scripts/_dbg-cleanup.mjs +31 -0
- package/scripts/_dbg-closedloop-ui-shot.mjs +61 -0
- package/scripts/_dbg-console-audit.mjs +61 -0
- package/scripts/_dbg-console-probe.mjs +23 -0
- package/scripts/_dbg-context-inject-audit.mjs +231 -0
- package/scripts/_dbg-crash-recovery.mjs +143 -0
- package/scripts/_dbg-crop-shot.mjs +16 -0
- package/scripts/_dbg-daq-acc-probe.mjs +24 -0
- package/scripts/_dbg-daq-attrib.mjs +34 -0
- package/scripts/_dbg-daq-bind-audit.mjs +119 -0
- package/scripts/_dbg-daq-cadence.mjs +104 -0
- package/scripts/_dbg-daq-debug.mjs +22 -0
- package/scripts/_dbg-daq-diag.mjs +33 -0
- package/scripts/_dbg-daq-e2e.mjs +171 -0
- package/scripts/_dbg-daq-film.mjs +136 -0
- package/scripts/_dbg-daq-filter-e2e.mjs +109 -0
- package/scripts/_dbg-daq-filter-e2e2.mjs +62 -0
- package/scripts/_dbg-daq-final-regression.mjs +78 -0
- package/scripts/_dbg-daq-full-check.mjs +179 -0
- package/scripts/_dbg-daq-line-note-verify.mjs +61 -0
- package/scripts/_dbg-daq-linebanner-audit.mjs +107 -0
- package/scripts/_dbg-daq-pages-shot.mjs +37 -0
- package/scripts/_dbg-daq-perf.mjs +61 -0
- package/scripts/_dbg-daq-probe.mjs +27 -0
- package/scripts/_dbg-daq-recipe-e2e.mjs +30 -0
- package/scripts/_dbg-daq-redesign-shot.mjs +88 -0
- package/scripts/_dbg-daq-rows-probe.mjs +26 -0
- package/scripts/_dbg-daq-rowstate-e2e.mjs +152 -0
- package/scripts/_dbg-daq-rowstate-shot.mjs +45 -0
- package/scripts/_dbg-daq-rowstate-shot2.mjs +38 -0
- package/scripts/_dbg-daq-tpl.mjs +144 -0
- package/scripts/_dbg-dash-console-check.mjs +49 -0
- package/scripts/_dbg-dash-deep-probe.mjs +61 -0
- package/scripts/_dbg-dash-hitpoint.mjs +44 -0
- package/scripts/_dbg-dash-live-shot.mjs +36 -0
- package/scripts/_dbg-dash-shot.mjs +21 -0
- package/scripts/_dbg-dashboard-shot.mjs +35 -0
- package/scripts/_dbg-dcw-audit.mjs +126 -0
- package/scripts/_dbg-dcw-card-e2e.mjs +108 -0
- package/scripts/_dbg-dcw-channel-ui.mjs +144 -0
- package/scripts/_dbg-dcw-examples.mjs +81 -0
- package/scripts/_dbg-dcw-light-shot.mjs +19 -0
- package/scripts/_dbg-dcw-line-audit.mjs +107 -0
- package/scripts/_dbg-dcw-pause-tpl-audit.mjs +161 -0
- package/scripts/_dbg-dcw-pause-ui.mjs +175 -0
- package/scripts/_dbg-dcw-scene.mjs +72 -0
- package/scripts/_dbg-dcw-shot2.mjs +14 -0
- package/scripts/_dbg-dcw-twin-e2e.mjs +192 -0
- package/scripts/_dbg-dt-interact.mjs +193 -0
- package/scripts/_dbg-error-probe.mjs +54 -0
- package/scripts/_dbg-filter-light-verify.mjs +54 -0
- package/scripts/_dbg-final-acceptance-2.mjs +72 -0
- package/scripts/_dbg-final-acceptance.mjs +192 -0
- package/scripts/_dbg-final-agent-e2e.mjs +151 -0
- package/scripts/_dbg-final-full-e2e.mjs +218 -0
- package/scripts/_dbg-final-line-e2e.mjs +173 -0
- package/scripts/_dbg-final-t6-hitl.mjs +38 -0
- package/scripts/_dbg-focus-range.mjs +115 -0
- package/scripts/_dbg-fresh-scene-e2e.mjs +125 -0
- package/scripts/_dbg-full-feature-e2e.mjs +219 -0
- package/scripts/_dbg-fullchain-e2e.mjs +178 -0
- package/scripts/_dbg-gate-debug.mjs +37 -0
- package/scripts/_dbg-gif-encode.mjs +111 -0
- package/scripts/_dbg-gizmo.mjs +95 -0
- package/scripts/_dbg-glass-probe.mjs +57 -0
- package/scripts/_dbg-glass-shot.mjs +50 -0
- package/scripts/_dbg-glass-sweep.mjs +25 -0
- package/scripts/_dbg-glb-probe.mjs +43 -0
- package/scripts/_dbg-hardening-probe.mjs +90 -0
- package/scripts/_dbg-hero-btn-probe.mjs +21 -0
- package/scripts/_dbg-hidden-check.mjs +21 -0
- package/scripts/_dbg-hitl-timeout-e2e.mjs +93 -0
- package/scripts/_dbg-hmi-audit.mjs +164 -0
- package/scripts/_dbg-home-repro.mjs +24 -0
- package/scripts/_dbg-home-stack.mjs +13 -0
- package/scripts/_dbg-huashu-survey.mjs +31 -0
- package/scripts/_dbg-huashu-survey2.mjs +35 -0
- package/scripts/_dbg-huashu-verify.mjs +25 -0
- package/scripts/_dbg-huashu-verify2.mjs +26 -0
- package/scripts/_dbg-hydration-detail.mjs +18 -0
- package/scripts/_dbg-i18n-debug.mjs +27 -0
- package/scripts/_dbg-i18n-debug2.mjs +26 -0
- package/scripts/_dbg-i18n-final.mjs +42 -0
- package/scripts/_dbg-i18n-scan.mjs +38 -0
- package/scripts/_dbg-infra-lifecycle.mjs +44 -0
- package/scripts/_dbg-line-aura-shots.mjs +54 -0
- package/scripts/_dbg-line-control-e2e.mjs +120 -0
- package/scripts/_dbg-line-gate-audit.mjs +108 -0
- package/scripts/_dbg-line-live-e2e.mjs +144 -0
- package/scripts/_dbg-line-scenario-e2e.mjs +256 -0
- package/scripts/_dbg-minimal-omp.mjs +77 -0
- package/scripts/_dbg-mode-nav.mjs +173 -0
- package/scripts/_dbg-mqtt-chain-e2e.mjs +90 -0
- package/scripts/_dbg-nav-rpg.mjs +84 -0
- package/scripts/_dbg-nav-shot.mjs +28 -0
- package/scripts/_dbg-nav.mjs +27 -0
- package/scripts/_dbg-opslog-e2e.mjs +121 -0
- package/scripts/_dbg-opslog-shots.mjs +62 -0
- package/scripts/_dbg-opt-team-e2e.mjs +133 -0
- package/scripts/_dbg-optimization-e2e.mjs +94 -0
- package/scripts/_dbg-orbit.mjs +58 -0
- package/scripts/_dbg-panesplitter-fix-check.mjs +62 -0
- package/scripts/_dbg-phase-e3-monitor.mjs +25 -0
- package/scripts/_dbg-pop-clamp-verify.mjs +77 -0
- package/scripts/_dbg-preset-e2e.mjs +116 -0
- package/scripts/_dbg-preview-console.mjs +28 -0
- package/scripts/_dbg-preview-minrepro.mjs +156 -0
- package/scripts/_dbg-preview-pixels.mjs +93 -0
- package/scripts/_dbg-quality-pages-e2e.mjs +84 -0
- package/scripts/_dbg-query-cancel.ts +12 -0
- package/scripts/_dbg-rail-tree-e2e.mjs +183 -0
- package/scripts/_dbg-real-driver-e2e.mjs +55 -0
- package/scripts/_dbg-redesign-shots.mjs +34 -0
- package/scripts/_dbg-restart-persist.mjs +41 -0
- package/scripts/_dbg-rollback-mgr-audit.mjs +169 -0
- package/scripts/_dbg-rpg.mjs +71 -0
- package/scripts/_dbg-sc001-dispatch.mjs +63 -0
- package/scripts/_dbg-scenario-final-shot.mjs +24 -0
- package/scripts/_dbg-scenario-phase-e2.mjs +75 -0
- package/scripts/_dbg-scenario-phase-e3.mjs +96 -0
- package/scripts/_dbg-scenario-phase1.mjs +90 -0
- package/scripts/_dbg-scenario-phase2.mjs +105 -0
- package/scripts/_dbg-scenario-phase3-monitor.mjs +48 -0
- package/scripts/_dbg-scenario-phase3.mjs +111 -0
- package/scripts/_dbg-scene-polish-shot.mjs +118 -0
- package/scripts/_dbg-selring-probe.mjs +47 -0
- package/scripts/_dbg-sideinfo.mjs +101 -0
- package/scripts/_dbg-splitter.mjs +88 -0
- package/scripts/_dbg-team-repro.mjs +76 -0
- package/scripts/_dbg-town-alarm-e2e.mjs +40 -0
- package/scripts/_dbg-town-beauty-shots.mjs +54 -0
- package/scripts/_dbg-town-daq-shot.mjs +26 -0
- package/scripts/_dbg-town-full-e2e.mjs +104 -0
- package/scripts/_dbg-town-gate.mjs +44 -0
- package/scripts/_dbg-town-ins-probe.mjs +37 -0
- package/scripts/_dbg-town-perf.mjs +50 -0
- package/scripts/_dbg-town-polish-shots.mjs +82 -0
- package/scripts/_dbg-town-realtime.mjs +42 -0
- package/scripts/_dbg-town-shot3.mjs +17 -0
- package/scripts/_dbg-town-truth.mjs +37 -0
- package/scripts/_dbg-town-truth2.mjs +27 -0
- package/scripts/_dbg-transform-audit.mjs +98 -0
- package/scripts/_dbg-trend-expand-test.mjs +38 -0
- package/scripts/_dbg-twindaq-focus.mjs +81 -0
- package/scripts/_dbg-ui-polish-shot.mjs +43 -0
- package/scripts/_dbg-ui-polish-verify1.mjs +92 -0
- package/scripts/_dbg-ui-polish-verify2.mjs +50 -0
- package/scripts/_dbg-ui-polish-verify3.mjs +51 -0
- package/scripts/_dbg-ui-polish-verify4.mjs +50 -0
- package/scripts/_dbg-ui-shot.mjs +26 -0
- package/scripts/_dbg-unify-shot.mjs +43 -0
- package/scripts/_dbg-uplink-probe.mjs +36 -0
- package/scripts/_dbg-wizard-preview-shot.mjs +58 -0
- package/scripts/_dbg-wizard-ui-e2e.mjs +93 -0
- package/scripts/_dbg-ws-probe.mjs +86 -0
- package/scripts/_dbg-ws-shot2.mjs +23 -0
- package/scripts/_dbg-wsdot-sanity.mjs +25 -0
- package/scripts/_dev-stack.mjs +46 -0
- package/scripts/_http-driver-probe.mjs +30 -0
- package/scripts/_lib-dcw-line.mjs +24 -0
- package/scripts/_mqtt-driver-probe.mjs +30 -0
- package/scripts/_newdriver-rest-probe.mjs +100 -0
- package/scripts/_node-state-probe.mjs +5 -0
- package/scripts/_opcua-driver-probe.mjs +31 -0
- package/scripts/_rtu-debug.mjs +41 -0
- package/scripts/_rtu-direct.mjs +6 -0
- package/scripts/_rtu-driver-probe.mjs +53 -0
- package/scripts/_rtu-mini-slave.mjs +63 -0
- package/scripts/_townview_style.css +1185 -0
- package/scripts/_townview_template.html +1215 -0
- package/scripts/_wizard-shots.mjs +90 -0
- package/scripts/acceptance-suite.py +207 -0
- package/scripts/api-live-e2e.mjs +467 -0
- package/scripts/build-anime-models.mjs +339 -0
- package/scripts/build-character-models.mjs +175 -0
- package/scripts/build-film-devices.mjs +227 -0
- package/scripts/build-model-3d.mjs +173 -0
- package/scripts/build-player-sheet.mjs +58 -0
- package/scripts/build-world-map.mjs +188 -0
- package/scripts/build-wuwa-assets.mjs +345 -0
- package/scripts/collab-live-test.py +177 -0
- package/scripts/debug-mcp-http.ts +64 -0
- package/scripts/demo-lead-worker.ts +256 -0
- package/scripts/demo-modes.ts +415 -0
- package/scripts/demo-omp-channel.ts +135 -0
- package/scripts/design-preflight.mjs +223 -0
- package/scripts/design-verify-templates.mjs +110 -0
- package/scripts/design-verify.mjs +170 -0
- package/scripts/dev-guard.mjs +74 -0
- package/scripts/dev-modbus-simulator.mjs +55 -0
- package/scripts/dev-opcua-simulator.mjs +57 -0
- package/scripts/dev-protocol-simulators.mjs +145 -0
- package/scripts/dev-window.cmd +6 -0
- package/scripts/device-line-restore.mjs +34 -0
- package/scripts/diag-lead-status.ts +101 -0
- package/scripts/e2e-a2a-steer-live.mjs +193 -0
- package/scripts/e2e-agent-channel-task.ts +151 -0
- package/scripts/e2e-agent-team.mjs +168 -0
- package/scripts/e2e-auth-matrix.mjs +119 -0
- package/scripts/e2e-channel-isolation.ts +325 -0
- package/scripts/e2e-dual-drive-comm.ts +259 -0
- package/scripts/e2e-lead-team-mgmt.ts +217 -0
- package/scripts/e2e-memory-persistence.ts +320 -0
- package/scripts/e2e-memory-system.ts +332 -0
- package/scripts/e2e-omp-modes.ts +274 -0
- package/scripts/e2e-omp-realtime.ts +258 -0
- package/scripts/e2e-omp-workspace.ts +180 -0
- package/scripts/e2e-parallel-execution.mjs +151 -0
- package/scripts/e2e-rest-memory.mjs +251 -0
- package/scripts/e2e-rest-robustness.mjs +177 -0
- package/scripts/e2e-resume-crash.mjs +254 -0
- package/scripts/e2e-tab-close.mjs +136 -0
- package/scripts/e2e-task-queue.ts +277 -0
- package/scripts/e2e-template-isolation.mjs +267 -0
- package/scripts/e2e-token-ui.mjs +149 -0
- package/scripts/final-soup-run.py +192 -0
- package/scripts/final-soup-watch.py +83 -0
- package/scripts/home-bootstrap.mjs +117 -0
- package/scripts/i18n-codemod.mjs +173 -0
- package/scripts/i18n-fix-en.py +28 -0
- package/scripts/i18n-fix-en2.py +31 -0
- package/scripts/i18n-merge.mjs +67 -0
- package/scripts/omp-real-test.py +328 -0
- package/scripts/smoke-optimization-verify.ts +72 -0
- package/scripts/start.mjs +60 -0
- package/scripts/test-a2a-relay.mjs +222 -0
- package/scripts/test-a2a-types.ts +296 -0
- package/scripts/test-agent-brain.ts +135 -0
- package/scripts/test-agent-multi-channel.ts +160 -0
- package/scripts/test-agent-runtime.ts +348 -0
- package/scripts/test-api-client.ts +108 -0
- package/scripts/test-api-suite.mjs +271 -0
- package/scripts/test-block-consumption.mjs +194 -0
- package/scripts/test-channel-routing.ts +301 -0
- package/scripts/test-cmd-render.mjs +218 -0
- package/scripts/test-collab-e2e.mjs +136 -0
- package/scripts/test-collab-omp.mjs +192 -0
- package/scripts/test-dedup-logic.ts +132 -0
- package/scripts/test-dual-drive.ts +227 -0
- package/scripts/test-e2e-collaboration.ts +262 -0
- package/scripts/test-e2e-monitor.ts +192 -0
- package/scripts/test-event-history.ts +112 -0
- package/scripts/test-event-persistence.mjs +169 -0
- package/scripts/test-exec-modes.ts +316 -0
- package/scripts/test-fifo-realtime.mjs +193 -0
- package/scripts/test-final-e2e.mjs +290 -0
- package/scripts/test-full-system.ts +439 -0
- package/scripts/test-game-session.ts +160 -0
- package/scripts/test-goal-summary.ts +202 -0
- package/scripts/test-harness-liveness.ts +109 -0
- package/scripts/test-harness-terminal.ts +164 -0
- package/scripts/test-header-trail.mjs +95 -0
- package/scripts/test-hitl.ts +360 -0
- package/scripts/test-koda-restyle.mjs +105 -0
- package/scripts/test-lane-history-live.mjs +103 -0
- package/scripts/test-lane-raw.ts +67 -0
- package/scripts/test-lanes-history-render.mjs +138 -0
- package/scripts/test-loop-omp.mjs +154 -0
- package/scripts/test-mcp-tools.ts +285 -0
- package/scripts/test-mdlite.ts +53 -0
- package/scripts/test-memory-dynamic.ts +99 -0
- package/scripts/test-memory-maintenance.ts +117 -0
- package/scripts/test-memory-vector.ts +154 -0
- package/scripts/test-memory.ts +431 -0
- package/scripts/test-mock-collab.mjs +226 -0
- package/scripts/test-modern-render.mjs +174 -0
- package/scripts/test-omp-terminal.mjs +187 -0
- package/scripts/test-orchestration.ts +425 -0
- package/scripts/test-persistence-lazy.ts +323 -0
- package/scripts/test-prompt-system.mjs +181 -0
- package/scripts/test-prompts-loader.ts +56 -0
- package/scripts/test-protocol.ts +156 -0
- package/scripts/test-real-scenario.mjs +290 -0
- package/scripts/test-route-reason.mjs +111 -0
- package/scripts/test-scheduler-loop.ts +469 -0
- package/scripts/test-stream-render.ts +37 -0
- package/scripts/test-task-drawer.mjs +204 -0
- package/scripts/test-task-engine.ts +433 -0
- package/scripts/test-task-invariants.mjs +169 -0
- package/scripts/test-terminal-e2e.mjs +264 -0
- package/scripts/test-town-3d.mjs +121 -0
- package/scripts/test-town-drag.mjs +218 -0
- package/scripts/test-town-layout.mjs +200 -0
- package/scripts/test-town-page.mjs +136 -0
- package/scripts/test-town-scene-math.ts +169 -0
- package/scripts/test-town-twin.mjs +121 -0
- package/scripts/test-town-upload.mjs +89 -0
- package/scripts/test-town-user-flow.mjs +619 -0
- package/scripts/test-town-world.mjs +76 -0
- package/scripts/test-town-wuwa.mjs +198 -0
- package/scripts/test-user-isolation.mjs +193 -0
- package/scripts/test-workshop-db.ts +280 -0
- package/scripts/test-workshop-entries.ts +370 -0
- package/scripts/test-workspace-api.ts +329 -0
- package/scripts/test-ws-aep.mjs +187 -0
- package/scripts/test-ws-protocol.ts +134 -0
- package/scripts/test-ws-stress.mjs +208 -0
- package/scripts/town-demo-seed.mjs +75 -0
- package/scripts/town-scene-clear.mjs +56 -0
- package/scripts/ui-screenshot.mjs +128 -0
- package/scripts/verify-a2a-live.mjs +124 -0
- package/scripts/verify-exec-modes-report.ts +248 -0
- package/scripts/verify-game.mjs +477 -0
- package/scripts/verify-lead-mail.ts +188 -0
- package/scripts/verify-page-smoke.mjs +87 -0
- package/scripts/verify-ws-events.mjs +123 -0
- package/scripts/ws-test.mjs +176 -0
- package/scripts/ws-test.py +4 -0
- package/server/api/health.get.ts +32 -0
- package/server/api/mcp/workshop.ts +78 -0
- package/server/api/metrics.ts +75 -0
- package/server/api/system/config.get.ts +12 -0
- package/server/api/system/monitor/terminal/ws.ts +177 -0
- package/server/api/system/monitor/terminate.post.ts +36 -0
- package/server/api/system/monitor.get.ts +13 -0
- package/server/api/system/settings/events.get.ts +28 -0
- package/server/api/system/settings/index.get.ts +14 -0
- package/server/api/system/settings/index.patch.ts +22 -0
- package/server/api/system/settings/reset.post.ts +12 -0
- package/server/api/users/[id].delete.ts +11 -0
- package/server/api/users/[id].get.ts +11 -0
- package/server/api/users/[id].put.ts +14 -0
- package/server/api/users/index.get.ts +13 -0
- package/server/api/users/index.post.ts +13 -0
- package/server/api/users/login.post.ts +11 -0
- package/server/api/users/logout.post.ts +9 -0
- package/server/api/users/me.get.ts +9 -0
- package/server/api/users/register.post.ts +11 -0
- package/server/api/users/tokens/[id]/token.get.ts +11 -0
- package/server/api/users/tokens/[id].delete.ts +11 -0
- package/server/api/users/tokens/[id].patch.ts +14 -0
- package/server/api/users/tokens/index.get.ts +9 -0
- package/server/api/users/tokens/index.post.ts +13 -0
- package/server/api/workshop/[...path].ts +13 -0
- package/server/api/workshop/a2a/[agentId]/card/index.get.ts +75 -0
- package/server/api/workshop/a2a/[agentId]/rpc/index.post.ts +429 -0
- package/server/api/workshop/a2a/send.post.ts +28 -0
- package/server/api/workshop/agent-tools/approvals/[id]/decide.post.ts +21 -0
- package/server/api/workshop/agent-tools/approvals/index.get.ts +18 -0
- package/server/api/workshop/agent-tools/bindings/[id].delete.ts +21 -0
- package/server/api/workshop/agent-tools/bindings/[id].patch.ts +14 -0
- package/server/api/workshop/agent-tools/bindings/index.get.ts +14 -0
- package/server/api/workshop/agent-tools/bindings/index.post.ts +20 -0
- package/server/api/workshop/agent-tools/invoke.post.ts +34 -0
- package/server/api/workshop/agents/[id].delete.ts +20 -0
- package/server/api/workshop/agents/[id].get.ts +19 -0
- package/server/api/workshop/agents/[id].patch.ts +30 -0
- package/server/api/workshop/agents/index.get.ts +13 -0
- package/server/api/workshop/agents/index.post.ts +29 -0
- package/server/api/workshop/agents/subscribe.post.ts +21 -0
- package/server/api/workshop/approvals/[id]/decide.post.ts +30 -0
- package/server/api/workshop/approvals/index.get.ts +22 -0
- package/server/api/workshop/assets/character/[id].delete.ts +33 -0
- package/server/api/workshop/assets/character/index.get.ts +17 -0
- package/server/api/workshop/assets/character/index.post.ts +87 -0
- package/server/api/workshop/assets/devices/[id].delete.ts +43 -0
- package/server/api/workshop/assets/devices/index.get.ts +103 -0
- package/server/api/workshop/assets/devices/index.post.ts +53 -0
- package/server/api/workshop/audit.get.ts +43 -0
- package/server/api/workshop/caller.ts +141 -0
- package/server/api/workshop/channel-templates/[id]/instantiate.post.ts +31 -0
- package/server/api/workshop/channel-templates/[id].delete.ts +20 -0
- package/server/api/workshop/channel-templates/[id].get.ts +19 -0
- package/server/api/workshop/channel-templates/[id].patch.ts +48 -0
- package/server/api/workshop/channel-templates/from-channel.post.ts +31 -0
- package/server/api/workshop/channel-templates/index.get.ts +13 -0
- package/server/api/workshop/channel-templates/index.post.ts +61 -0
- package/server/api/workshop/channels/[id]/activate.post.ts +19 -0
- package/server/api/workshop/channels/[id]/agents/[agentId]/memories/[memoryId].delete.ts +30 -0
- package/server/api/workshop/channels/[id]/agents/[agentId]/memories/index.get.ts +29 -0
- package/server/api/workshop/channels/[id]/agents/[agentId]/memories/index.post.ts +48 -0
- package/server/api/workshop/channels/[id]/agents/[agentId]/memories/search.post.ts +43 -0
- package/server/api/workshop/channels/[id]/agents/[agentId]/model.patch.ts +39 -0
- package/server/api/workshop/channels/[id]/agents/[agentId]/position.patch.ts +33 -0
- package/server/api/workshop/channels/[id]/agents/[agentId]/range.patch.ts +54 -0
- package/server/api/workshop/channels/[id]/agents/[agentId]/stop.post.ts +25 -0
- package/server/api/workshop/channels/[id]/agents/[agentId].delete.ts +23 -0
- package/server/api/workshop/channels/[id]/agents/[agentId].patch.ts +28 -0
- package/server/api/workshop/channels/[id]/agents/index.get.ts +27 -0
- package/server/api/workshop/channels/[id]/agents/index.post.ts +61 -0
- package/server/api/workshop/channels/[id]/events.get.ts +55 -0
- package/server/api/workshop/channels/[id]/index.get.ts +18 -0
- package/server/api/workshop/channels/[id]/index.patch.ts +30 -0
- package/server/api/workshop/channels/[id]/memories/[memoryId].delete.ts +29 -0
- package/server/api/workshop/channels/[id]/memories/index.get.ts +28 -0
- package/server/api/workshop/channels/[id]/memories/index.post.ts +42 -0
- package/server/api/workshop/channels/[id]/messages/index.get.ts +56 -0
- package/server/api/workshop/channels/[id]/messages/index.post.ts +75 -0
- package/server/api/workshop/channels/[id]/queue.get.ts +25 -0
- package/server/api/workshop/channels/[id]/tasks/index.get.ts +24 -0
- package/server/api/workshop/channels/[id]/tasks/index.post.ts +79 -0
- package/server/api/workshop/channels/[id]/terminals.get.ts +21 -0
- package/server/api/workshop/channels/[id].delete.ts +18 -0
- package/server/api/workshop/channels.get.ts +11 -0
- package/server/api/workshop/channels.post.ts +48 -0
- package/server/api/workshop/daq/[id]/bind.post.ts +19 -0
- package/server/api/workshop/daq/[id]/samples.get.ts +22 -0
- package/server/api/workshop/daq/[id]/test.post.ts +17 -0
- package/server/api/workshop/daq/[id].delete.ts +30 -0
- package/server/api/workshop/daq/[id].patch.ts +31 -0
- package/server/api/workshop/daq/alarms/[id]/ack.post.ts +15 -0
- package/server/api/workshop/daq/alarms.get.ts +16 -0
- package/server/api/workshop/daq/controller.post.ts +52 -0
- package/server/api/workshop/daq/index.get.ts +40 -0
- package/server/api/workshop/daq/index.post.ts +33 -0
- package/server/api/workshop/daq/infra/reconnect.post.ts +17 -0
- package/server/api/workshop/daq/infra.get.ts +11 -0
- package/server/api/workshop/daq/templates/[key].delete.ts +17 -0
- package/server/api/workshop/daq/templates/[key].patch.ts +18 -0
- package/server/api/workshop/daq/templates/index.post.ts +17 -0
- package/server/api/workshop/daq/test-driver.post.ts +23 -0
- package/server/api/workshop/dcw/[id]/bind.post.ts +17 -0
- package/server/api/workshop/dcw/[id]/param-ledger.get.ts +15 -0
- package/server/api/workshop/dcw/[id]/test.post.ts +15 -0
- package/server/api/workshop/dcw/[id]/write.post.ts +19 -0
- package/server/api/workshop/dcw/[id].delete.ts +30 -0
- package/server/api/workshop/dcw/[id].patch.ts +18 -0
- package/server/api/workshop/dcw/controller.post.ts +43 -0
- package/server/api/workshop/dcw/index.get.ts +25 -0
- package/server/api/workshop/dcw/index.post.ts +20 -0
- package/server/api/workshop/dcw/journal/index.get.ts +21 -0
- package/server/api/workshop/dcw/journal/node/[nodeId]/rollback.post.ts +22 -0
- package/server/api/workshop/dcw/line/query.get.ts +31 -0
- package/server/api/workshop/dcw/lines/[id]/start.post.ts +35 -0
- package/server/api/workshop/dcw/lines/[id]/stop.post.ts +34 -0
- package/server/api/workshop/dcw/lines/[id].delete.ts +35 -0
- package/server/api/workshop/dcw/lines/[id].patch.ts +15 -0
- package/server/api/workshop/dcw/lines/index.get.ts +14 -0
- package/server/api/workshop/dcw/lines/index.post.ts +31 -0
- package/server/api/workshop/dcw/optimizations/[id]/judge.post.ts +24 -0
- package/server/api/workshop/dcw/optimizations/[id]/rollback.post.ts +29 -0
- package/server/api/workshop/dcw/optimizations/[id]/series.get.ts +18 -0
- package/server/api/workshop/dcw/optimizations/[id].get.ts +17 -0
- package/server/api/workshop/dcw/optimizations/index.get.ts +23 -0
- package/server/api/workshop/dcw/products/[id].delete.ts +16 -0
- package/server/api/workshop/dcw/products/[id].patch.ts +17 -0
- package/server/api/workshop/dcw/products/index.post.ts +16 -0
- package/server/api/workshop/dcw/recipes/[id]/apply.post.ts +40 -0
- package/server/api/workshop/dcw/recipes/[id]/mark-good.post.ts +21 -0
- package/server/api/workshop/dcw/recipes/[id]/rollback-good.post.ts +19 -0
- package/server/api/workshop/dcw/recipes/[id].delete.ts +14 -0
- package/server/api/workshop/dcw/recipes/[id].patch.ts +16 -0
- package/server/api/workshop/dcw/recipes/index.get.ts +12 -0
- package/server/api/workshop/dcw/recipes/index.post.ts +15 -0
- package/server/api/workshop/dcw/runs/[id]/close.post.ts +15 -0
- package/server/api/workshop/dcw/runs/[id]/data.get.ts +15 -0
- package/server/api/workshop/dcw/runs/[id]/rollback.post.ts +20 -0
- package/server/api/workshop/dcw/runs/index.get.ts +11 -0
- package/server/api/workshop/dcw/templates/[key].delete.ts +14 -0
- package/server/api/workshop/dcw/templates/[key].patch.ts +16 -0
- package/server/api/workshop/dcw/templates/index.post.ts +15 -0
- package/server/api/workshop/dcw/test-driver.post.ts +16 -0
- package/server/api/workshop/device-twins/[id]/control.post.ts +21 -0
- package/server/api/workshop/device-twins/[id]/telemetry.post.ts +21 -0
- package/server/api/workshop/device-twins/[id].delete.ts +25 -0
- package/server/api/workshop/device-twins/[id].patch.ts +29 -0
- package/server/api/workshop/device-twins/index.get.ts +16 -0
- package/server/api/workshop/device-twins/index.post.ts +32 -0
- package/server/api/workshop/fs/dirs.get.ts +40 -0
- package/server/api/workshop/mailbox/all.get.ts +19 -0
- package/server/api/workshop/mailbox.get.ts +14 -0
- package/server/api/workshop/memories/maintenance.post.ts +15 -0
- package/server/api/workshop/ops-logs/index.get.ts +30 -0
- package/server/api/workshop/ops-logs/index.post.ts +39 -0
- package/server/api/workshop/runtime.get.ts +11 -0
- package/server/api/workshop/scene/layouts/[channelId].delete.ts +23 -0
- package/server/api/workshop/scene/layouts/[channelId].put.ts +31 -0
- package/server/api/workshop/scene/layouts.get.ts +13 -0
- package/server/api/workshop/tasks/[id]/cancel/index.post.ts +34 -0
- package/server/api/workshop/tasks/[id]/complete.post.ts +32 -0
- package/server/api/workshop/tasks/[id]/dispatch.post.ts +30 -0
- package/server/api/workshop/tasks/[id]/report.post.ts +38 -0
- package/server/api/workshop/tasks/[id]/retry.post.ts +33 -0
- package/server/api/workshop/tasks/[id].get.ts +32 -0
- package/server/api/workshop/tasks.get.ts +13 -0
- package/server/api/workshop/teams/[id]/deploy.post.ts +40 -0
- package/server/api/workshop/teams/[id]/members/[agentId].delete.ts +19 -0
- package/server/api/workshop/teams/[id]/members/index.get.ts +19 -0
- package/server/api/workshop/teams/[id]/members/index.post.ts +32 -0
- package/server/api/workshop/teams/[id].delete.ts +20 -0
- package/server/api/workshop/teams/[id].get.ts +19 -0
- package/server/api/workshop/teams/[id].patch.ts +32 -0
- package/server/api/workshop/teams/index.get.ts +13 -0
- package/server/api/workshop/teams/index.post.ts +27 -0
- package/server/api/workshop/users/me.get.ts +23 -0
- package/server/api/workshop/users/register.post.ts +33 -0
- package/server/api/workshop/workspaces/[id]/channel-templates/[tplId].post.ts +31 -0
- package/server/api/workshop/workspaces/[id]/channels/[channelId].delete.ts +15 -0
- package/server/api/workshop/workspaces/[id]/channels/[channelId].post.ts +15 -0
- package/server/api/workshop/workspaces/[id]/index.delete.ts +14 -0
- package/server/api/workshop/workspaces/index.get.ts +11 -0
- package/server/api/workshop/workspaces/index.post.ts +17 -0
- package/server/api/workshop/ws.ts +694 -0
- package/server/data/agent-node-bindings.json +554 -0
- package/server/data/daq-templates.json +16 -0
- package/server/data/daqs.json +2680 -0
- package/server/data/dcw-lines.json +919 -0
- package/server/data/dcw-products.json +835 -0
- package/server/data/dcw-recipes.json +1650 -0
- package/server/data/dcw-rollback.json +9339 -0
- package/server/data/dcw-runs.json +4633 -0
- package/server/data/dcw-templates.json +26 -0
- package/server/data/dcw-writes.json +9770 -0
- package/server/data/dcws.json +1736 -0
- package/server/data/device-twins.json +133 -0
- package/server/data/line-runs.json +152 -0
- package/server/data/scene-layouts.json +200 -0
- package/server/mcp/workshop-server.ts +510 -0
- package/server/middleware/request-log.ts +15 -0
- package/server/plugins/backup.ts +85 -0
- package/server/plugins/daq.ts +65 -0
- package/server/plugins/dev-stability-guard.ts +42 -0
- package/server/plugins/security.ts +29 -0
- package/server/plugins/system-config.ts +38 -0
- package/server/plugins/workshop.ts +145 -0
- package/server/repositories/user.repository.ts +391 -0
- package/server/schemas/user.schema.ts +67 -0
- package/server/services/system-config.ts +356 -0
- package/server/services/user.service.ts +186 -0
- package/server/services/workshop/agents/adapters/omp-rpc-client.ts +539 -0
- package/server/services/workshop/agents/adapters/to-a2a.ts +40 -0
- package/server/services/workshop/agents/agent-interface.ts +219 -0
- package/server/services/workshop/agents/claude-agent.ts +47 -0
- package/server/services/workshop/agents/factory.ts +24 -0
- package/server/services/workshop/agents/harness-process.ts +158 -0
- package/server/services/workshop/agents/harness-terminal.ts +545 -0
- package/server/services/workshop/agents/industrial-context.ts +222 -0
- package/server/services/workshop/agents/industrial-tools.ts +362 -0
- package/server/services/workshop/agents/mock-agent.ts +396 -0
- package/server/services/workshop/agents/node-bindings.repo.ts +165 -0
- package/server/services/workshop/agents/omp-agent.ts +1598 -0
- package/server/services/workshop/agents/tool-approvals.ts +174 -0
- package/server/services/workshop/assets/character-asset.repo.ts +120 -0
- package/server/services/workshop/assets/device-twin.repo.ts +236 -0
- package/server/services/workshop/daq/alarm-notify.ts +100 -0
- package/server/services/workshop/daq/bus/index.ts +46 -0
- package/server/services/workshop/daq/bus/inproc.adapter.ts +62 -0
- package/server/services/workshop/daq/bus/mqtt.adapter.ts +112 -0
- package/server/services/workshop/daq/bus/queue-port.ts +36 -0
- package/server/services/workshop/daq/daq-controller.ts +778 -0
- package/server/services/workshop/daq/daq-node.repo.ts +96 -0
- package/server/services/workshop/daq/daq-node.ts +247 -0
- package/server/services/workshop/daq/daq-runtime.ts +168 -0
- package/server/services/workshop/daq/daq-templates.ts +157 -0
- package/server/services/workshop/daq/drivers.ts +771 -0
- package/server/services/workshop/daq/host-bindings.ts +71 -0
- package/server/services/workshop/daq/host-ports.ts +64 -0
- package/server/services/workshop/daq/infra.ts +202 -0
- package/server/services/workshop/daq/storage/index.ts +96 -0
- package/server/services/workshop/daq/storage/sqlite.adapter.ts +205 -0
- package/server/services/workshop/daq/storage/timescale.adapter.ts +185 -0
- package/server/services/workshop/daq/storage/tsdb-port.ts +74 -0
- package/server/services/workshop/db/agent.repo.ts +105 -0
- package/server/services/workshop/db/channel-agent.repo.ts +119 -0
- package/server/services/workshop/db/channel-event.repo.ts +154 -0
- package/server/services/workshop/db/channel-template.repo.ts +113 -0
- package/server/services/workshop/db/channel.repo.ts +101 -0
- package/server/services/workshop/db/database.ts +934 -0
- package/server/services/workshop/db/memory.repo.ts +249 -0
- package/server/services/workshop/db/message.repo.ts +149 -0
- package/server/services/workshop/db/ops.repo.ts +323 -0
- package/server/services/workshop/db/schema.sql +143 -0
- package/server/services/workshop/db/subscription.repo.ts +62 -0
- package/server/services/workshop/db/task.repo.ts +175 -0
- package/server/services/workshop/db/team-member.repo.ts +70 -0
- package/server/services/workshop/db/team.repo.ts +109 -0
- package/server/services/workshop/db/user.repo.ts +100 -0
- package/server/services/workshop/dcw/dcw-controller.ts +841 -0
- package/server/services/workshop/dcw/dcw-line.repo.ts +86 -0
- package/server/services/workshop/dcw/dcw-node.repo.ts +89 -0
- package/server/services/workshop/dcw/dcw-node.ts +200 -0
- package/server/services/workshop/dcw/dcw-product.repo.ts +95 -0
- package/server/services/workshop/dcw/dcw-recipe.repo.ts +349 -0
- package/server/services/workshop/dcw/dcw-runtime.ts +82 -0
- package/server/services/workshop/dcw/dcw-templates.ts +138 -0
- package/server/services/workshop/dcw/drivers.ts +523 -0
- package/server/services/workshop/dcw/line-run.ts +101 -0
- package/server/services/workshop/dcw/recipe-rollback-manager.ts +702 -0
- package/server/services/workshop/dcw/recipe-rollback.repo.ts +197 -0
- package/server/services/workshop/logger.ts +58 -0
- package/server/services/workshop/ops/ops.ts +78 -0
- package/server/services/workshop/prompts/loader.ts +112 -0
- package/server/services/workshop/runtime/agent-runtime.ts +698 -0
- package/server/services/workshop/runtime/channel-runtime.ts +202 -0
- package/server/services/workshop/runtime/embedding-provider.ts +79 -0
- package/server/services/workshop/runtime/execution-mode.ts +215 -0
- package/server/services/workshop/runtime/mailbox.ts +148 -0
- package/server/services/workshop/runtime/manager.ts +2543 -0
- package/server/services/workshop/runtime/memory.ts +439 -0
- package/server/services/workshop/runtime/monitor.ts +194 -0
- package/server/services/workshop/runtime/scheduler-loop.ts +773 -0
- package/server/services/workshop/runtime/task-engine.ts +574 -0
- package/server/services/workshop/scene/scene-layout.repo.ts +112 -0
- package/server/services/workshop/scene-events.ts +63 -0
- package/server/services/workshop/types/a2a.ts +61 -0
- package/server/services/workshop/types/task.ts +85 -0
- package/server/types/user.ts +53 -0
- package/server/utils/approval-gate.ts +67 -0
- package/server/utils/auth.ts +13 -0
- package/server/utils/config.ts +40 -0
- package/server/utils/errors.ts +24 -0
- package/server/utils/response.ts +49 -0
- package/server/utils/validate.ts +19 -0
- package/shared/config/engine.d.mts +41 -0
- package/shared/config/engine.mjs +291 -0
- package/shared/config/home.d.mts +48 -0
- package/shared/config/home.mjs +146 -0
- package/shared/config/schema.json +30 -0
- package/shared/daq-protocol.ts +361 -0
- package/shared/dcw-protocol.ts +576 -0
- package/shared/terminal-protocol.ts +70 -0
- package/shared/town-anim.ts +56 -0
- package/shared/town-behavior.ts +136 -0
- package/shared/town-protocol.ts +110 -0
- package/shared/town-scene-math.ts +283 -0
- package/shared/workshop-protocol.ts +199 -0
- package/tsconfig.json +10 -0
- package/uno.config.ts +37 -0
|
@@ -0,0 +1,934 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workshop 持久化层入口(node:sqlite)
|
|
3
|
+
* - openWorkshopDb: 打开(或创建)数据库 → PRAGMA(WAL/foreign_keys)→ 建表 + 增量迁移
|
|
4
|
+
* - 行类型:repo 返回的原始 sqlite 行(JSON 列以字符串存储,由上层按需 parseJson)
|
|
5
|
+
*
|
|
6
|
+
* 数据模型(v5:Agent 模板 + AgentTeam 编组 + Channel 实例分离):
|
|
7
|
+
* - agents: 全局可复用 Agent 模板(仅 name/harness/config/enabled,无 channel 绑定)
|
|
8
|
+
* - teams: AgentTeam(Agent 模板编组,可整体批量部署到 channel)
|
|
9
|
+
* - team_members: team × agent 模板 成员关系(role 标记部署时采用 lead/worker 角色)
|
|
10
|
+
* - channel_agents: Channel 中的 Agent 实例(每次放入 channel 都克隆出新身份 id,
|
|
11
|
+
* name/harness/config 从模板复制,另含独立 role + token)
|
|
12
|
+
* - subscriptions: 订阅按 (channel, 实例, target) 隔离
|
|
13
|
+
* - agent_memories: Agent 持久记忆(FTS5 索引,per-agent 域 + team 共享)
|
|
14
|
+
*/
|
|
15
|
+
import { createRequire } from 'node:module'
|
|
16
|
+
import { DatabaseSync } from 'node:sqlite'
|
|
17
|
+
import type * as sqliteVec from 'sqlite-vec'
|
|
18
|
+
|
|
19
|
+
const require = createRequire(import.meta.url)
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 建表 SQL(与 schema.sql 保持同步;内联字符串而非运行时读文件,
|
|
23
|
+
* 避免 Nitro 打包后相对路径失效——schema.sql 保留为源码文档)。
|
|
24
|
+
*/
|
|
25
|
+
const SCHEMA_SQL = `CREATE TABLE IF NOT EXISTS channels (
|
|
26
|
+
id TEXT PRIMARY KEY,
|
|
27
|
+
name TEXT NOT NULL,
|
|
28
|
+
description TEXT NOT NULL DEFAULT '',
|
|
29
|
+
scenario_prompt TEXT NOT NULL DEFAULT '', -- v6:channel 级作业场景 prompt(全员注入)
|
|
30
|
+
lead_agent_id TEXT,
|
|
31
|
+
workspace TEXT NOT NULL DEFAULT '',
|
|
32
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
33
|
+
created_at TEXT NOT NULL,
|
|
34
|
+
updated_at TEXT NOT NULL
|
|
35
|
+
);
|
|
36
|
+
CREATE TABLE IF NOT EXISTS agents (
|
|
37
|
+
id TEXT PRIMARY KEY,
|
|
38
|
+
name TEXT NOT NULL,
|
|
39
|
+
harness TEXT NOT NULL,
|
|
40
|
+
config_json TEXT NOT NULL DEFAULT '{}',
|
|
41
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
42
|
+
visibility TEXT NOT NULL DEFAULT 'private', -- 'private' | 'public'(owner_user_id NULL = 内置公共,不可变更)
|
|
43
|
+
created_at TEXT NOT NULL,
|
|
44
|
+
updated_at TEXT NOT NULL
|
|
45
|
+
);
|
|
46
|
+
CREATE TABLE IF NOT EXISTS channel_agents (
|
|
47
|
+
id TEXT PRIMARY KEY, -- 实例身份 id(每次放入 channel 独立生成)
|
|
48
|
+
channel_id TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
|
|
49
|
+
template_id TEXT REFERENCES agents(id) ON DELETE SET NULL, -- 来源模板(可空)
|
|
50
|
+
name TEXT NOT NULL, -- 从模板复制
|
|
51
|
+
harness TEXT NOT NULL, -- 从模板复制
|
|
52
|
+
config_json TEXT NOT NULL DEFAULT '{}', -- 从模板复制
|
|
53
|
+
role TEXT NOT NULL DEFAULT 'worker', -- 'lead' | 'worker'(按 channel 独立)
|
|
54
|
+
token TEXT NOT NULL, -- MCP 身份凭证(实例级 UUIDv4)
|
|
55
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
56
|
+
created_at TEXT NOT NULL,
|
|
57
|
+
updated_at TEXT NOT NULL
|
|
58
|
+
);
|
|
59
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_channel_agents_token ON channel_agents(token);
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_channel_agents_channel ON channel_agents(channel_id);
|
|
61
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
62
|
+
id TEXT PRIMARY KEY,
|
|
63
|
+
channel_id TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
|
|
64
|
+
task_id TEXT,
|
|
65
|
+
from_agent_id TEXT,
|
|
66
|
+
to_agent_id TEXT,
|
|
67
|
+
role TEXT NOT NULL, -- 'ROLE_USER' | 'ROLE_AGENT'
|
|
68
|
+
parts_json TEXT NOT NULL,
|
|
69
|
+
metadata_json TEXT NOT NULL DEFAULT '{}', -- x-aw-target-agent / x-aw-task-kind
|
|
70
|
+
state TEXT NOT NULL DEFAULT 'pending', -- pending|consuming|consumed
|
|
71
|
+
created_at TEXT NOT NULL,
|
|
72
|
+
consumed_at TEXT
|
|
73
|
+
);
|
|
74
|
+
CREATE INDEX IF NOT EXISTS idx_messages_queue ON messages(channel_id, to_agent_id, state, created_at);
|
|
75
|
+
CREATE TABLE IF NOT EXISTS subscriptions (
|
|
76
|
+
channel_id TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
|
|
77
|
+
agent_id TEXT NOT NULL REFERENCES channel_agents(id) ON DELETE CASCADE,
|
|
78
|
+
target_agent_id TEXT NOT NULL,
|
|
79
|
+
created_at TEXT NOT NULL,
|
|
80
|
+
PRIMARY KEY (channel_id, agent_id, target_agent_id)
|
|
81
|
+
);
|
|
82
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
83
|
+
id TEXT PRIMARY KEY,
|
|
84
|
+
channel_id TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
|
|
85
|
+
parent_id TEXT,
|
|
86
|
+
assignee_id TEXT NOT NULL, -- 实例身份 id(不再 FK 到 agents)
|
|
87
|
+
creator_id TEXT,
|
|
88
|
+
title TEXT NOT NULL,
|
|
89
|
+
description TEXT,
|
|
90
|
+
state TEXT NOT NULL, -- SUBMITTED|ASSIGNED|WORKING|WAITING|COMPLETED|FAILED|CANCELED
|
|
91
|
+
progress INTEGER NOT NULL DEFAULT 0, -- 0-100
|
|
92
|
+
retry_count INTEGER NOT NULL DEFAULT 0, -- 重派次数(SchedulerLoop reassign 时 +1,>=3 停止重派)
|
|
93
|
+
artifacts_json TEXT NOT NULL DEFAULT '[]',
|
|
94
|
+
history_json TEXT NOT NULL DEFAULT '[]',
|
|
95
|
+
created_at TEXT NOT NULL,
|
|
96
|
+
updated_at TEXT NOT NULL
|
|
97
|
+
);
|
|
98
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_channel ON tasks(channel_id, state);
|
|
99
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_assignee ON tasks(assignee_id, state);
|
|
100
|
+
-- 调度快照/队列视图热查询:listByChannelAssignee(channel+assignee ORDER BY created_at)
|
|
101
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_channel_assignee ON tasks(channel_id, assignee_id, state, created_at);
|
|
102
|
+
-- 子任务聚合(dispatch 判重/complete 闸门/onChildCompleted 统计;childrenOf 热查询)
|
|
103
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_parent ON tasks(parent_id);
|
|
104
|
+
CREATE TABLE IF NOT EXISTS teams (
|
|
105
|
+
id TEXT PRIMARY KEY,
|
|
106
|
+
name TEXT NOT NULL,
|
|
107
|
+
description TEXT NOT NULL DEFAULT '',
|
|
108
|
+
visibility TEXT NOT NULL DEFAULT 'private', -- 'private' | 'public'(owner_user_id NULL = 内置公共,不可变更)
|
|
109
|
+
created_at TEXT NOT NULL,
|
|
110
|
+
updated_at TEXT NOT NULL
|
|
111
|
+
);
|
|
112
|
+
CREATE TABLE IF NOT EXISTS team_members (
|
|
113
|
+
team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
|
|
114
|
+
template_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
|
|
115
|
+
role TEXT NOT NULL DEFAULT 'worker', -- 'lead' | 'worker'(部署到 channel 时采用的实例角色)
|
|
116
|
+
created_at TEXT NOT NULL,
|
|
117
|
+
PRIMARY KEY (team_id, template_id)
|
|
118
|
+
);
|
|
119
|
+
CREATE INDEX IF NOT EXISTS idx_team_members_team ON team_members(team_id);
|
|
120
|
+
|
|
121
|
+
-- v6:Agent 持久记忆(agent_memories)+ FTS5 全文索引。
|
|
122
|
+
-- per-agent 记忆域(agent_id 过滤隔离);团队共享行 agent_id='__team__'(常量 TEAM_AGENT_ID)。
|
|
123
|
+
-- dedup_key 唯一约束去重(含 channel_id:team 哨兵行跨 channel 各自独立):任务 'task:<id>' / 协作 'peer:<msgId>' / 策展 'manual:<uuid>' / 团队任意。
|
|
124
|
+
-- kind:episodic-task/episodic-peer(harvest)/semantic(REST 人工策展,衰减豁免)。
|
|
125
|
+
-- vec0 向量表不在此建:需 sqlite-vec 扩展且维度运行时才知(P1 Task 7 延迟建)。
|
|
126
|
+
|
|
127
|
+
CREATE TABLE IF NOT EXISTS agent_memories (
|
|
128
|
+
id TEXT PRIMARY KEY,
|
|
129
|
+
channel_id TEXT NOT NULL,
|
|
130
|
+
agent_id TEXT NOT NULL,
|
|
131
|
+
kind TEXT NOT NULL,
|
|
132
|
+
title TEXT NOT NULL, -- 原文,供展示
|
|
133
|
+
title_fts TEXT NOT NULL DEFAULT '', -- CJK 切分副本,FTS 索引用(V8)
|
|
134
|
+
content TEXT NOT NULL, -- 已 CJK 切分的存储文本
|
|
135
|
+
importance REAL NOT NULL DEFAULT 0.5,
|
|
136
|
+
task_id TEXT,
|
|
137
|
+
dedup_key TEXT NOT NULL,
|
|
138
|
+
access_count INTEGER NOT NULL DEFAULT 0,
|
|
139
|
+
last_accessed_at TEXT,
|
|
140
|
+
created_at TEXT NOT NULL,
|
|
141
|
+
UNIQUE(agent_id, dedup_key, channel_id)
|
|
142
|
+
);
|
|
143
|
+
CREATE INDEX IF NOT EXISTS idx_memories_agent ON agent_memories(agent_id, created_at DESC);
|
|
144
|
+
|
|
145
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS agent_memories_fts USING fts5(
|
|
146
|
+
title, content, agent_id UNINDEXED, memory_rowid UNINDEXED
|
|
147
|
+
);
|
|
148
|
+
CREATE TRIGGER IF NOT EXISTS trg_agent_memories_ai AFTER INSERT ON agent_memories BEGIN
|
|
149
|
+
INSERT INTO agent_memories_fts(title, content, agent_id, memory_rowid)
|
|
150
|
+
VALUES (new.title_fts, new.content, new.agent_id, new.rowid);
|
|
151
|
+
END;
|
|
152
|
+
CREATE TRIGGER IF NOT EXISTS trg_agent_memories_ad AFTER DELETE ON agent_memories BEGIN
|
|
153
|
+
DELETE FROM agent_memories_fts WHERE memory_rowid = old.rowid;
|
|
154
|
+
END;
|
|
155
|
+
CREATE TRIGGER IF NOT EXISTS trg_agent_memories_au AFTER UPDATE ON agent_memories BEGIN
|
|
156
|
+
DELETE FROM agent_memories_fts WHERE memory_rowid = old.rowid;
|
|
157
|
+
INSERT INTO agent_memories_fts(title, content, agent_id, memory_rowid)
|
|
158
|
+
VALUES (new.title_fts, new.content, new.agent_id, new.rowid);
|
|
159
|
+
END;
|
|
160
|
+
|
|
161
|
+
-- v7:用户级隔离(users + workspaces + 资源 owner 列)。
|
|
162
|
+
-- owner_user_id 为 NULL 的资源 = 遗留数据(对所有已认证用户只读可见,变更需 owner 匹配)。
|
|
163
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
164
|
+
id TEXT PRIMARY KEY,
|
|
165
|
+
name TEXT NOT NULL UNIQUE,
|
|
166
|
+
token TEXT NOT NULL UNIQUE,
|
|
167
|
+
created_at TEXT NOT NULL
|
|
168
|
+
);
|
|
169
|
+
CREATE TABLE IF NOT EXISTS workspaces (
|
|
170
|
+
id TEXT PRIMARY KEY,
|
|
171
|
+
owner_user_id TEXT NOT NULL, -- 归属用户(全局用户系统 id;原 FK 已随全局用户集成移除)
|
|
172
|
+
name TEXT NOT NULL,
|
|
173
|
+
created_at TEXT NOT NULL
|
|
174
|
+
);
|
|
175
|
+
CREATE INDEX IF NOT EXISTS idx_workspaces_owner ON workspaces(owner_user_id);
|
|
176
|
+
-- v8:AEP 事件持久化(hub publish 同步落库;时间线历史由 server 驱动,与 client 无关)
|
|
177
|
+
CREATE TABLE IF NOT EXISTS channel_events (
|
|
178
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
179
|
+
channel_id TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
|
|
180
|
+
seq INTEGER NOT NULL,
|
|
181
|
+
type TEXT NOT NULL,
|
|
182
|
+
at TEXT NOT NULL,
|
|
183
|
+
agent_id TEXT,
|
|
184
|
+
task_id TEXT,
|
|
185
|
+
payload_json TEXT NOT NULL,
|
|
186
|
+
UNIQUE(channel_id, seq)
|
|
187
|
+
);
|
|
188
|
+
CREATE INDEX IF NOT EXISTS idx_channel_events_channel ON channel_events(channel_id, seq DESC);
|
|
189
|
+
|
|
190
|
+
CREATE TABLE IF NOT EXISTS workspace_channels (
|
|
191
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
192
|
+
channel_id TEXT NOT NULL,
|
|
193
|
+
created_at TEXT NOT NULL,
|
|
194
|
+
PRIMARY KEY (workspace_id, channel_id)
|
|
195
|
+
);
|
|
196
|
+
-- v10:Channel 模板(场景 + 工作目录 + 团队编组的可复用组合;实例化 = 一键建 channel 并装配成员)。
|
|
197
|
+
-- lead_json:内联 lead 定义 {name,harness,config}(空串 = 无 lead);
|
|
198
|
+
-- members_json:[{templateId,role}](引用 Agent 模板)或 [{inline:{name,harness,config},role}](内联成员)。
|
|
199
|
+
-- owner_user_id NULL = 内置公共模板(visibility 恒 public,任何人不可修改删除)。
|
|
200
|
+
CREATE TABLE IF NOT EXISTS channel_templates (
|
|
201
|
+
id TEXT PRIMARY KEY,
|
|
202
|
+
name TEXT NOT NULL,
|
|
203
|
+
description TEXT NOT NULL DEFAULT '',
|
|
204
|
+
scenario_prompt TEXT NOT NULL DEFAULT '',
|
|
205
|
+
workspace TEXT NOT NULL DEFAULT '',
|
|
206
|
+
lead_json TEXT NOT NULL DEFAULT '',
|
|
207
|
+
members_json TEXT NOT NULL DEFAULT '[]',
|
|
208
|
+
visibility TEXT NOT NULL DEFAULT 'private',
|
|
209
|
+
owner_user_id TEXT,
|
|
210
|
+
created_at TEXT NOT NULL,
|
|
211
|
+
updated_at TEXT NOT NULL
|
|
212
|
+
);
|
|
213
|
+
CREATE INDEX IF NOT EXISTS idx_channel_templates_owner ON channel_templates(owner_user_id);
|
|
214
|
+
-- v11:工具审批历史(S4:HITL 裁决留痕——进程内 pending 之外的持久化,重启可查)
|
|
215
|
+
CREATE TABLE IF NOT EXISTS approval_history (
|
|
216
|
+
id TEXT PRIMARY KEY,
|
|
217
|
+
agent_id TEXT NOT NULL,
|
|
218
|
+
node_id TEXT NOT NULL,
|
|
219
|
+
kind TEXT NOT NULL, -- 'dcw' | 'daq'
|
|
220
|
+
detail TEXT NOT NULL DEFAULT '',
|
|
221
|
+
status TEXT NOT NULL, -- pending|approved|denied|expired
|
|
222
|
+
comment TEXT NOT NULL DEFAULT '',
|
|
223
|
+
decided_by TEXT NOT NULL DEFAULT '', -- 裁决人(用户 id;空 = 超时/系统收敛)
|
|
224
|
+
decided_name TEXT NOT NULL DEFAULT '', -- 裁决人名(呈现用)
|
|
225
|
+
created_at TEXT NOT NULL,
|
|
226
|
+
decided_at TEXT
|
|
227
|
+
);
|
|
228
|
+
CREATE INDEX IF NOT EXISTS idx_approval_history_created ON approval_history(created_at DESC);
|
|
229
|
+
-- v12:DAQ 报警事件 + ack 闭环(S5:报警持久化/确认/升级)
|
|
230
|
+
CREATE TABLE IF NOT EXISTS alarm_events (
|
|
231
|
+
id TEXT PRIMARY KEY,
|
|
232
|
+
node_id TEXT NOT NULL,
|
|
233
|
+
node_name TEXT NOT NULL DEFAULT '',
|
|
234
|
+
metric TEXT NOT NULL DEFAULT '', -- 触发量名(如 temp)
|
|
235
|
+
value REAL,
|
|
236
|
+
rule TEXT NOT NULL DEFAULT '', -- 'lt-min' | 'gt-max'
|
|
237
|
+
threshold REAL,
|
|
238
|
+
acked_by TEXT NOT NULL DEFAULT '',
|
|
239
|
+
acked_at TEXT,
|
|
240
|
+
escalation INTEGER NOT NULL DEFAULT 0, -- 未确认升级通知次数
|
|
241
|
+
notified_json TEXT NOT NULL DEFAULT '[]', -- 外送记录 [{url,ok,at,attempt}]
|
|
242
|
+
created_at TEXT NOT NULL
|
|
243
|
+
);
|
|
244
|
+
CREATE INDEX IF NOT EXISTS idx_alarm_events_created ON alarm_events(created_at DESC);
|
|
245
|
+
CREATE INDEX IF NOT EXISTS idx_alarm_events_open ON alarm_events(created_at DESC) WHERE acked_at IS NULL;
|
|
246
|
+
-- v13:结构化审计日志(R1:谁/何时/对什么/做了什么)
|
|
247
|
+
CREATE TABLE IF NOT EXISTS audit_log (
|
|
248
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
249
|
+
actor TEXT NOT NULL DEFAULT '',
|
|
250
|
+
actor_name TEXT NOT NULL DEFAULT '',
|
|
251
|
+
actor_kind TEXT NOT NULL DEFAULT 'user', -- 'user' | 'agent' | 'system'
|
|
252
|
+
action TEXT NOT NULL,
|
|
253
|
+
target_kind TEXT NOT NULL DEFAULT '',
|
|
254
|
+
target_id TEXT NOT NULL DEFAULT '',
|
|
255
|
+
detail_json TEXT NOT NULL DEFAULT '{}',
|
|
256
|
+
at TEXT NOT NULL,
|
|
257
|
+
-- 运维日志(OpsLog)维度列:按产线/产品/Recipe 隔离查询 + 分类 + 人读摘要
|
|
258
|
+
line_id TEXT NOT NULL DEFAULT '',
|
|
259
|
+
product_id TEXT NOT NULL DEFAULT '',
|
|
260
|
+
recipe_id TEXT NOT NULL DEFAULT '',
|
|
261
|
+
kind TEXT NOT NULL DEFAULT '', -- write|manual|alarm|line|recipe|rollback|daq|system
|
|
262
|
+
summary TEXT NOT NULL DEFAULT ''
|
|
263
|
+
);
|
|
264
|
+
CREATE INDEX IF NOT EXISTS idx_audit_log_at ON audit_log(at DESC);
|
|
265
|
+
-- v14:高危管理操作双人复核(R3:maker-checker;config 开关默认关)
|
|
266
|
+
CREATE TABLE IF NOT EXISTS approval_requests (
|
|
267
|
+
id TEXT PRIMARY KEY,
|
|
268
|
+
action TEXT NOT NULL, -- 'recipe.apply' | 'controller.toggle' | 'node.delete'
|
|
269
|
+
target_id TEXT NOT NULL,
|
|
270
|
+
payload_json TEXT NOT NULL DEFAULT '{}',
|
|
271
|
+
summary TEXT NOT NULL DEFAULT '',
|
|
272
|
+
requested_by TEXT NOT NULL,
|
|
273
|
+
requested_name TEXT NOT NULL DEFAULT '',
|
|
274
|
+
requested_at TEXT NOT NULL,
|
|
275
|
+
status TEXT NOT NULL DEFAULT 'pending', -- pending|approved|denied
|
|
276
|
+
decided_by TEXT NOT NULL DEFAULT '',
|
|
277
|
+
decided_name TEXT NOT NULL DEFAULT '',
|
|
278
|
+
decided_at TEXT,
|
|
279
|
+
comment TEXT NOT NULL DEFAULT ''
|
|
280
|
+
);
|
|
281
|
+
CREATE INDEX IF NOT EXISTS idx_approval_requests_status ON approval_requests(status, requested_at DESC);`
|
|
282
|
+
|
|
283
|
+
// ===== 默认种子数据(首轮初始化注入;owner NULL = 公共资源,所有登录用户只读共享) =====
|
|
284
|
+
|
|
285
|
+
/** 默认 Agent 模板(id 固定,幂等) */
|
|
286
|
+
const DEFAULT_AGENT_TEMPLATES: Array<{ id: string, name: string, harness: string, config: Record<string, unknown> }> = [
|
|
287
|
+
{ id: 'tpl-default-lead', name: '开发主管', harness: 'mock', config: { role: 'lead', intro: '统筹任务拆解与进度调度,分配 worker 执行' } },
|
|
288
|
+
{ id: 'tpl-default-backend', name: '后端工程师', harness: 'mock', config: { role: 'worker', intro: '负责服务端接口、数据与集成逻辑' } },
|
|
289
|
+
{ id: 'tpl-default-frontend', name: '前端工程师', harness: 'mock', config: { role: 'worker', intro: '负责页面、交互与前端工程' } },
|
|
290
|
+
{ id: 'tpl-default-qa', name: '测试工程师', harness: 'mock', config: { role: 'worker', intro: '负责用例设计与质量验证' } },
|
|
291
|
+
{ id: 'tpl-default-docs', name: '文档撰写', harness: 'mock', config: { role: 'worker', intro: '负责说明、报告与文档沉淀' } },
|
|
292
|
+
// 特定场景 lead 模板:带 systemPromptPrefix 预设,用户添加为 lead 时场景提示词自动注入 harness
|
|
293
|
+
{
|
|
294
|
+
id: 'tpl-scenario-payment-lead',
|
|
295
|
+
name: '支付网关交付主管(场景:高并发支付)',
|
|
296
|
+
harness: 'omp',
|
|
297
|
+
config: {
|
|
298
|
+
role: 'lead',
|
|
299
|
+
intro: '支付网关专项交付 lead;已预设高并发支付场景系统提示',
|
|
300
|
+
systemPromptPrefix: [
|
|
301
|
+
'你是支付网关专项交付组的 Lead 主管,负责拆解并推进支付网关的端到端交付。',
|
|
302
|
+
'## 场景背景',
|
|
303
|
+
'本团队聚焦高并发支付网关:订单支付、退款、对账、风控与降级预案。',
|
|
304
|
+
'## 你的调度原则',
|
|
305
|
+
'1. 每次只拆解当前最有价值的一个子任务,交给最空闲的 worker,不要并行铺开。',
|
|
306
|
+
'2. 子任务须包含明确的验收标准(接口契约/性能指标/失败路径)。',
|
|
307
|
+
'3. 支付类需求默认考虑:幂等、超时兜底、对账一致与限流降级。',
|
|
308
|
+
'4. worker 完成一个任务后要复核其成果是否满足验收标准,不满足则补充分发。',
|
|
309
|
+
'## 交付红线',
|
|
310
|
+
'涉及资金与订单状态的变更,必须以 artifact 显式标注幂等键与回滚方案;任何不确定项先 ask 用户确认。',
|
|
311
|
+
].join('\n'),
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
]
|
|
315
|
+
|
|
316
|
+
/** 默认 AgentTeam(成员引用上述模板 id) */
|
|
317
|
+
const DEFAULT_TEAMS: Array<{ id: string, name: string, description: string, members: Array<{ templateId: string, role: 'lead' | 'worker' }> }> = [
|
|
318
|
+
{
|
|
319
|
+
id: 'team-default-fullstack',
|
|
320
|
+
name: '全栈交付组',
|
|
321
|
+
description: '默认编组:主管 + 后端 + 前端 + 测试,开箱即可部署到 Channel',
|
|
322
|
+
members: [
|
|
323
|
+
{ templateId: 'tpl-default-lead', role: 'lead' },
|
|
324
|
+
{ templateId: 'tpl-default-backend', role: 'worker' },
|
|
325
|
+
{ templateId: 'tpl-default-frontend', role: 'worker' },
|
|
326
|
+
{ templateId: 'tpl-default-qa', role: 'worker' },
|
|
327
|
+
],
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
id: 'team-default-docs',
|
|
331
|
+
name: '文档维护组',
|
|
332
|
+
description: '默认编组:文档撰写(lead)+ 测试复核,适合文档与发布场景',
|
|
333
|
+
members: [
|
|
334
|
+
{ templateId: 'tpl-default-docs', role: 'lead' },
|
|
335
|
+
{ templateId: 'tpl-default-qa', role: 'worker' },
|
|
336
|
+
],
|
|
337
|
+
},
|
|
338
|
+
]
|
|
339
|
+
|
|
340
|
+
/** 内置 Channel 模板成员条目(members_json 元素) */
|
|
341
|
+
type BuiltinChannelMember = { templateId: string, role: 'lead' | 'worker' } | { inline: { name: string, harness: string, config: Record<string, unknown> }, role: 'lead' | 'worker' }
|
|
342
|
+
|
|
343
|
+
/** 默认 Channel 模板(场景 + 团队组合;实例化 = 一键建 channel 并装配成员) */
|
|
344
|
+
const DEFAULT_CHANNEL_TEMPLATES: Array<{
|
|
345
|
+
id: string
|
|
346
|
+
name: string
|
|
347
|
+
description: string
|
|
348
|
+
scenarioPrompt: string
|
|
349
|
+
members: BuiltinChannelMember[]
|
|
350
|
+
}> = [
|
|
351
|
+
{
|
|
352
|
+
id: 'chtpl-default-fullstack',
|
|
353
|
+
name: '全栈交付通道',
|
|
354
|
+
description: '内置模板:主管带队 + 后端/前端/测试,适合常规交付任务',
|
|
355
|
+
scenarioPrompt: '团队按主管调度协作交付;每个子任务完成后由主管复核,产出统一沉淀为 artifact。',
|
|
356
|
+
members: [
|
|
357
|
+
{ templateId: 'tpl-default-lead', role: 'lead' },
|
|
358
|
+
{ templateId: 'tpl-default-backend', role: 'worker' },
|
|
359
|
+
{ templateId: 'tpl-default-frontend', role: 'worker' },
|
|
360
|
+
{ templateId: 'tpl-default-qa', role: 'worker' },
|
|
361
|
+
],
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
id: 'chtpl-default-review',
|
|
365
|
+
name: '文档评审通道',
|
|
366
|
+
description: '内置模板:文档撰写 + 测试复核,适合文档、报告与评审场景',
|
|
367
|
+
scenarioPrompt: '以文档产出与质量复核为主线;撰写完成后由复核角色检查并反馈修改意见。',
|
|
368
|
+
members: [
|
|
369
|
+
{ templateId: 'tpl-default-docs', role: 'lead' },
|
|
370
|
+
{ templateId: 'tpl-default-qa', role: 'worker' },
|
|
371
|
+
],
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
id: 'chtpl-preset-optical-film',
|
|
375
|
+
name: '光学薄膜涂布产线优化组',
|
|
376
|
+
description: '工业场景预设:涂布产线数字孪生优化 —— 生产主管 + 工艺工程师 + 数据分析师,面向烘箱温控与涂层质量闭环',
|
|
377
|
+
scenarioPrompt: `## 产线场景:光学薄膜涂布产线(精密涂布车间)
|
|
378
|
+
本团队服务于一条光学薄膜涂布产线:PET 基材经放卷 → 电晕处理 → 精密涂布(光学胶)→ 烘箱多段干燥 → 收卷,成品为显示面板用光学级薄膜。烘箱温度是涂层厚度均匀性与气泡缺陷的第一工艺根因;供胶/熔体系统压力波动反映输胶健康度,与温度耦合影响流平效果。
|
|
379
|
+
质量目标:涂层厚度均匀性 ±2% 以内,无气泡/橘皮缺陷;能耗约束下避免过热降解。产线的数控节点(烘箱温度设定等)与数采节点(涂布温度/系统压力等)已实时接入数字孪生;节点按产线分色渲染,操作前必须先调用 my_industrial_nodes 理解授权节点的物理意义、安全量程与活动配方工艺窗口。
|
|
380
|
+
|
|
381
|
+
## 团队分工(每位成员按此定位协作)
|
|
382
|
+
- 生产主管(lead):理解用户优化目标 → 拆解为「数据分析」与「工艺调整」子任务并派发 → 复核成员结论(必须带数据证据)→ 汇总汇报;不直接操作节点,协调跨成员信息(如把数据分析师的越限发现转给工艺工程师处置)。
|
|
383
|
+
- 工艺工程师(worker):持有数控节点授权 —— 用 daq_query 取证 → 判定设定-响应关系 → 在「安全量程 ∩ 配方窗口」内小步幅下发 dcw_control(单变量调整);手动确认模式节点先说明理由等用户批准;调整后等待热惯性响应再复测。
|
|
384
|
+
- 数据分析师(worker):持有数采节点授权 —— 用 daq_query 获取时序数据(支持按产品/配方/时间窗过滤),输出趋势/均值/极值/越限统计与工况判读(区分设定-响应滞后与真实异常);发现越限或异常趋势第一时间用 send_message_to_agent 通报 lead 与工艺工程师。
|
|
385
|
+
协作规则:引用数值必带单位与时间窗;结论不确定时先补数据再下判断;所有阶段性结论沉淀为任务交付物。
|
|
386
|
+
|
|
387
|
+
## 作业纪律
|
|
388
|
+
数据先行(先看数再动手)→ 窗口内小步幅(单次 ≤ 量程 2%)→ 单变量调整 → 复测闭环(调整后等待工艺响应再评估,不连续大幅调整)→ 异常先判读再行动 → 结论必附数据证据。任何成员不得越权操作未绑定节点。`,
|
|
389
|
+
members: [
|
|
390
|
+
{ templateId: 'tpl-default-lead', role: 'lead' },
|
|
391
|
+
{ inline: { name: '工艺工程师', harness: 'omp', config: { rpcMode: 'rpc', systemPromptPrefix: '你是光学薄膜涂布产线的工艺工程师,精通烘箱多段温控与涂层质量的关联。操作数控节点的标准流程:my_industrial_nodes 理解节点 → daq_query 取证 → dcw_control 在配方窗口内小步幅下发 → 等待热惯性后复测。手动确认模式下发前必须说明理由。结论一律引用带单位与时间窗的数据。' } }, role: 'worker' },
|
|
392
|
+
{ inline: { name: '数据分析师', harness: 'omp', config: { rpcMode: 'rpc', systemPromptPrefix: '你是光学薄膜涂布产线的数据分析师,擅长时序数据判读与工况诊断。用 daq_query 获取授权数采节点数据,输出趋势/统计/越限分析,判读时结合同产线数控设定考虑设定-响应滞后;发现越限或异常趋势立即通报 lead 与工艺工程师。结论一律引用具体数值。' } }, role: 'worker' },
|
|
393
|
+
],
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
id: 'chtpl-preset-extrusion',
|
|
397
|
+
name: '薄膜挤出流延产线优化组',
|
|
398
|
+
description: '工业场景预设:挤出流延产线数字孪生优化 —— 生产主管 + 工艺工程师 + 数据分析师,面向熔体压力/温度耦合控制',
|
|
399
|
+
scenarioPrompt: `## 产线场景:薄膜挤出流延产线(挤出车间)
|
|
400
|
+
本团队服务于一条薄膜挤出流延产线:原料经计量混料 → 螺杆挤出塑化 → 熔体泵计量 → 挤出模头流延 → 冷辊定型 → 测厚 → 收卷。熔体压力稳定性是挤出质量的脉搏:压力波动直接导致膜厚纵向偏差;熔体温度决定塑化质量,过热引发降解发黄、过低塑化不良。压力与温度强耦合(温度升高黏度下降、压力响应滞后),调参必须单变量小步幅。
|
|
401
|
+
质量目标:膜厚纵向偏差 ≤ ±3%,无晶点/发黄;注意螺杆与熔体泵的机械损耗征兆(压力基线漂移)。产线的数控节点(熔体温度设定等)与数采节点(熔体压力/熔体温度等)已接入数字孪生;操作前必须先调用 my_industrial_nodes 理解授权节点。
|
|
402
|
+
|
|
403
|
+
## 团队分工(每位成员按此定位协作)
|
|
404
|
+
- 生产主管(lead):承接用户优化目标 → 拆解派发子任务 → 复核数据证据 → 汇总汇报;协调信息流(数据侧发现 → 工艺侧处置 → 数据侧复测确认);不直接操作节点。
|
|
405
|
+
- 工艺工程师(worker):持有数控节点授权 —— 温度/转速设定调整遵循「先看数、小步幅、单变量、等响应」;目标值必须在安全量程与活动配方工艺窗口内;手动确认模式先说明理由等用户批准。
|
|
406
|
+
- 数据分析师(worker):持有数采节点授权 —— 监控压力/温度时序,识别基线漂移、周期性波动(螺杆脉动)与越限报警;为工艺调整提供前后对照证据;异常立即通报。
|
|
407
|
+
协作规则:引用数值必带单位与时间窗;跨成员信息经 send_message_to_agent 传递;结论沉淀为任务交付物。
|
|
408
|
+
|
|
409
|
+
## 作业纪律
|
|
410
|
+
数据先行 → 窗口内小步幅(单次 ≤ 量程 2%)→ 单变量调整(温度与转速禁止同时调)→ 复测闭环 → 压力异常优先判读(滤网堵塞倾向 vs 温度耦合 vs 真实波动)→ 结论必附数据证据。任何成员不得越权操作未绑定节点。`,
|
|
411
|
+
members: [
|
|
412
|
+
{ templateId: 'tpl-default-lead', role: 'lead' },
|
|
413
|
+
{ inline: { name: '工艺工程师', harness: 'omp', config: { rpcMode: 'rpc', systemPromptPrefix: '你是薄膜挤出流延产线的工艺工程师,精通熔体压力/温度耦合控制与流延质量。操作数控节点:my_industrial_nodes → daq_query 取证 → dcw_control 窗口内小步幅(温度与转速禁同调)→ 等响应后复测。结论引用带单位与时间窗的数据。' } }, role: 'worker' },
|
|
414
|
+
{ inline: { name: '数据分析师', harness: 'omp', config: { rpcMode: 'rpc', systemPromptPrefix: '你是薄膜挤出流延产线的数据分析师,擅长熔体压力/温度时序判读。用 daq_query 输出趋势/统计/越限分析,识别基线漂移与周期波动;结合同线数控设定考虑耦合与滞后;异常立即通报 lead 与工艺工程师。结论引用具体数值。' } }, role: 'worker' },
|
|
415
|
+
],
|
|
416
|
+
},
|
|
417
|
+
]
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* 默认模板与编组注入:
|
|
421
|
+
* - 固定 id + INSERT OR IGNORE,每次初始化幂等执行(重启安全;已有库补种,新库直接种)
|
|
422
|
+
* - owner_user_id = NULL + visibility = 'public':内置公共模板,所有用户可读可用,任何人(含 admin)不可修改删除
|
|
423
|
+
*/
|
|
424
|
+
function seedDefaultWorkshopData(db: DatabaseSync): void {
|
|
425
|
+
const now = new Date().toISOString()
|
|
426
|
+
const insertAgent = db.prepare(
|
|
427
|
+
'INSERT OR IGNORE INTO agents (id, name, harness, config_json, enabled, visibility, owner_user_id, created_at, updated_at) VALUES (?, ?, ?, ?, 1, \'public\', NULL, ?, ?)',
|
|
428
|
+
)
|
|
429
|
+
for (const t of DEFAULT_AGENT_TEMPLATES) {
|
|
430
|
+
insertAgent.run(t.id, t.name, t.harness, JSON.stringify(t.config), now, now)
|
|
431
|
+
}
|
|
432
|
+
const insertTeam = db.prepare(
|
|
433
|
+
'INSERT OR IGNORE INTO teams (id, name, description, visibility, owner_user_id, created_at, updated_at) VALUES (?, ?, ?, \'public\', NULL, ?, ?)',
|
|
434
|
+
)
|
|
435
|
+
const insertMember = db.prepare(
|
|
436
|
+
'INSERT OR IGNORE INTO team_members (team_id, template_id, role, created_at) VALUES (?, ?, ?, ?)',
|
|
437
|
+
)
|
|
438
|
+
for (const team of DEFAULT_TEAMS) {
|
|
439
|
+
insertTeam.run(team.id, team.name, team.description, now, now)
|
|
440
|
+
for (const m of team.members) {
|
|
441
|
+
insertMember.run(team.id, m.templateId, m.role, now)
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
const insertChannelTpl = db.prepare(
|
|
445
|
+
'INSERT OR IGNORE INTO channel_templates (id, name, description, scenario_prompt, workspace, lead_json, members_json, visibility, owner_user_id, created_at, updated_at) VALUES (?, ?, ?, ?, \'\', \'\', ?, \'public\', NULL, ?, ?)',
|
|
446
|
+
)
|
|
447
|
+
for (const tpl of DEFAULT_CHANNEL_TEMPLATES) {
|
|
448
|
+
insertChannelTpl.run(tpl.id, tpl.name, tpl.description, tpl.scenarioPrompt, JSON.stringify(tpl.members), now, now)
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/** channels 表行 */
|
|
453
|
+
export interface ChannelRow {
|
|
454
|
+
id: string
|
|
455
|
+
name: string
|
|
456
|
+
description: string
|
|
457
|
+
/** channel 级作业场景 prompt(注入全部成员 harness;空串 = 无场景) */
|
|
458
|
+
scenarioPrompt: string
|
|
459
|
+
leadAgentId: string | null
|
|
460
|
+
/** channel 独立工作目录(omp 子进程 cwd;空串表示未设置) */
|
|
461
|
+
workspace: string
|
|
462
|
+
enabled: number
|
|
463
|
+
/** 归属用户(null = 遗留数据) */
|
|
464
|
+
ownerUserId: string | null
|
|
465
|
+
createdAt: string
|
|
466
|
+
updatedAt: string
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/** users 表行(用户级隔离身份) */
|
|
470
|
+
export interface UserRow {
|
|
471
|
+
id: string
|
|
472
|
+
name: string
|
|
473
|
+
/** 用户管理 token(Bearer;区别于 agent 实例 token) */
|
|
474
|
+
token: string
|
|
475
|
+
createdAt: string
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/** channel_events 表行(AEP 事件持久化) */
|
|
479
|
+
export interface ChannelEventRow {
|
|
480
|
+
id: number
|
|
481
|
+
channelId: string
|
|
482
|
+
seq: number
|
|
483
|
+
type: string
|
|
484
|
+
at: string
|
|
485
|
+
agentId: string | null
|
|
486
|
+
taskId: string | null
|
|
487
|
+
payloadJson: string
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/** workspaces 表行(服务端持久化 Workspace;按 owner 隔离) */
|
|
491
|
+
export interface WorkspaceRow {
|
|
492
|
+
id: string
|
|
493
|
+
ownerUserId: string
|
|
494
|
+
name: string
|
|
495
|
+
createdAt: string
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/** agents 表行(全局 Agent 模板,无 channel 绑定) */
|
|
499
|
+
export interface AgentRow {
|
|
500
|
+
id: string
|
|
501
|
+
name: string
|
|
502
|
+
harness: string
|
|
503
|
+
configJson: string
|
|
504
|
+
enabled: number
|
|
505
|
+
/** 可见性:'private' 仅属主 | 'public' 全员可读可用(owner NULL = 内置,恒 public 不可变更) */
|
|
506
|
+
visibility: string
|
|
507
|
+
/** 归属用户(null = 内置公共模板) */
|
|
508
|
+
ownerUserId: string | null
|
|
509
|
+
createdAt: string
|
|
510
|
+
updatedAt: string
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/** teams 表行(AgentTeam:Agent 模板的编组,可整体部署到 channel) */
|
|
514
|
+
export interface TeamRow {
|
|
515
|
+
id: string
|
|
516
|
+
name: string
|
|
517
|
+
description: string
|
|
518
|
+
/** 可见性:'private' 仅属主 | 'public' 全员可读可用(owner NULL = 内置,恒 public 不可变更) */
|
|
519
|
+
visibility: string
|
|
520
|
+
/** 归属用户(null = 内置公共模板) */
|
|
521
|
+
ownerUserId: string | null
|
|
522
|
+
createdAt: string
|
|
523
|
+
updatedAt: string
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* channel_templates 表行(Channel 模板:场景 + 工作目录 + 成员组合)。
|
|
528
|
+
* membersJson 元素:{templateId, role} 引用 Agent 模板 | {inline:{name,harness,config}, role} 内联定义。
|
|
529
|
+
*/
|
|
530
|
+
export interface ChannelTemplateRow {
|
|
531
|
+
id: string
|
|
532
|
+
name: string
|
|
533
|
+
description: string
|
|
534
|
+
scenarioPrompt: string
|
|
535
|
+
workspace: string
|
|
536
|
+
leadJson: string
|
|
537
|
+
membersJson: string
|
|
538
|
+
visibility: string
|
|
539
|
+
ownerUserId: string | null
|
|
540
|
+
createdAt: string
|
|
541
|
+
updatedAt: string
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/** team_members 表行(team × agent 模板 成员关系;role 为部署时采用的实例角色) */
|
|
545
|
+
export interface TeamMemberRow {
|
|
546
|
+
teamId: string
|
|
547
|
+
templateId: string
|
|
548
|
+
role: string
|
|
549
|
+
createdAt: string
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/** agent_memories 表行(content 为已 CJK 切分存储文本;agentId='__team__' 为团队共享行) */
|
|
553
|
+
export interface MemoryRow {
|
|
554
|
+
id: string
|
|
555
|
+
channelId: string
|
|
556
|
+
agentId: string
|
|
557
|
+
kind: 'episodic-task' | 'episodic-peer' | 'semantic'
|
|
558
|
+
title: string
|
|
559
|
+
content: string
|
|
560
|
+
importance: number
|
|
561
|
+
taskId: string | null
|
|
562
|
+
accessCount: number
|
|
563
|
+
lastAccessedAt: string | null
|
|
564
|
+
createdAt: string
|
|
565
|
+
}
|
|
566
|
+
/** channel_agents 表行(Channel 中的 Agent 实例:独立身份 id + 复制自模板的字段) */
|
|
567
|
+
export interface ChannelAgentRow {
|
|
568
|
+
id: string
|
|
569
|
+
channelId: string
|
|
570
|
+
templateId: string | null
|
|
571
|
+
name: string
|
|
572
|
+
harness: string
|
|
573
|
+
configJson: string
|
|
574
|
+
role: string
|
|
575
|
+
token: string
|
|
576
|
+
enabled: number
|
|
577
|
+
createdAt: string
|
|
578
|
+
updatedAt: string
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/** messages 表行 */
|
|
582
|
+
export interface MessageRow {
|
|
583
|
+
id: string
|
|
584
|
+
channelId: string
|
|
585
|
+
taskId: string | null
|
|
586
|
+
fromAgentId: string | null
|
|
587
|
+
toAgentId: string | null
|
|
588
|
+
role: string
|
|
589
|
+
partsJson: string
|
|
590
|
+
metadataJson: string
|
|
591
|
+
state: 'pending' | 'consuming' | 'consumed'
|
|
592
|
+
createdAt: string
|
|
593
|
+
consumedAt: string | null
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/** subscriptions 表行(channel_id + agent_id + target_agent_id 复合主键) */
|
|
597
|
+
export interface SubscriptionRow {
|
|
598
|
+
channelId: string
|
|
599
|
+
agentId: string
|
|
600
|
+
targetAgentId: string
|
|
601
|
+
createdAt: string
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/** tasks 表行 */
|
|
605
|
+
export interface TaskRow {
|
|
606
|
+
id: string
|
|
607
|
+
channelId: string
|
|
608
|
+
parentId: string | null
|
|
609
|
+
assigneeId: string
|
|
610
|
+
creatorId: string | null
|
|
611
|
+
title: string
|
|
612
|
+
description: string | null
|
|
613
|
+
state: string
|
|
614
|
+
progress: number
|
|
615
|
+
retryCount: number
|
|
616
|
+
artifactsJson: string
|
|
617
|
+
historyJson: string
|
|
618
|
+
routeReason: string
|
|
619
|
+
createdAt: string
|
|
620
|
+
updatedAt: string
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* 打开(或创建)workshop 数据库并完成初始化。
|
|
625
|
+
* path 传 ':memory:' 即为内存库(测试用);落盘库由上层决定路径。
|
|
626
|
+
*/
|
|
627
|
+
export function openWorkshopDb(path: string): DatabaseSync {
|
|
628
|
+
// allowExtension + 尝试加载 sqlite-vec(向量检索);失败静默降级纯 FTS(受控环境可能禁扩展)
|
|
629
|
+
const db = new DatabaseSync(path, { allowExtension: true })
|
|
630
|
+
try {
|
|
631
|
+
const { getLoadablePath } = require('sqlite-vec') as typeof sqliteVec
|
|
632
|
+
db.loadExtension(getLoadablePath())
|
|
633
|
+
}
|
|
634
|
+
catch {
|
|
635
|
+
// 扩展不可用:记忆系统自动退化为 FTS-only(vecInit 将失败并禁用向量)
|
|
636
|
+
}
|
|
637
|
+
initWorkshopDb(db)
|
|
638
|
+
return db
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/** 对已打开的库执行初始化:WAL + 外键约束 + 建表 + 增量迁移 */
|
|
642
|
+
export function initWorkshopDb(db: DatabaseSync): void {
|
|
643
|
+
db.exec('PRAGMA journal_mode = WAL;')
|
|
644
|
+
// S6:synchronous=NORMAL(WAL 推荐档)——与 TSDB 仿真库对齐;断电最多丢最后一个事务,不损坏库
|
|
645
|
+
db.exec('PRAGMA synchronous = NORMAL;')
|
|
646
|
+
db.exec('PRAGMA foreign_keys = ON;')
|
|
647
|
+
db.exec(SCHEMA_SQL)
|
|
648
|
+
migrateLegacySchema(db)
|
|
649
|
+
migrateAddColumn(db, 'channels', 'scenario_prompt', 'TEXT NOT NULL DEFAULT \'\'')
|
|
650
|
+
// 派发路由理由(koda RouteDecision 借鉴):lead 派发留痕"为什么派给他",供审计与前端呈现
|
|
651
|
+
migrateAddColumn(db, 'tasks', 'route_reason', 'TEXT NOT NULL DEFAULT \'\'')
|
|
652
|
+
// v10:模板可见性列(既有库补列;默认 private,仅属主可见)
|
|
653
|
+
migrateAddColumn(db, 'agents', 'visibility', 'TEXT NOT NULL DEFAULT \'private\'')
|
|
654
|
+
migrateAddColumn(db, 'teams', 'visibility', 'TEXT NOT NULL DEFAULT \'private\'')
|
|
655
|
+
// 回填:内置/遗留公共模板(owner NULL)强制 public —— 升级后保持全员可读可用
|
|
656
|
+
db.exec('UPDATE agents SET visibility = \'public\' WHERE owner_user_id IS NULL')
|
|
657
|
+
db.exec('UPDATE teams SET visibility = \'public\' WHERE owner_user_id IS NULL')
|
|
658
|
+
// 运维日志(OpsLog)维度列:既有库补列(新库由上方 DDL 直建)
|
|
659
|
+
migrateAddColumn(db, 'audit_log', 'line_id', 'TEXT NOT NULL DEFAULT \'\'')
|
|
660
|
+
migrateAddColumn(db, 'audit_log', 'product_id', 'TEXT NOT NULL DEFAULT \'\'')
|
|
661
|
+
migrateAddColumn(db, 'audit_log', 'recipe_id', 'TEXT NOT NULL DEFAULT \'\'')
|
|
662
|
+
migrateAddColumn(db, 'audit_log', 'kind', 'TEXT NOT NULL DEFAULT \'\'')
|
|
663
|
+
migrateAddColumn(db, 'audit_log', 'summary', 'TEXT NOT NULL DEFAULT \'\'')
|
|
664
|
+
migrateMissingForeignKeys(db)
|
|
665
|
+
migrateDropOwnerFks(db)
|
|
666
|
+
seedDefaultWorkshopData(db)
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/** 通用加列迁移:列不存在时 ALTER TABLE ADD COLUMN(CREATE IF NOT EXISTS 不升级既有表) */
|
|
670
|
+
function migrateAddColumn(db: DatabaseSync, table: string, column: string, ddl: string): void {
|
|
671
|
+
const cols = db.prepare(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>
|
|
672
|
+
if (!cols.some(c => c.name === column)) {
|
|
673
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${ddl}`)
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/** 检测表上是否存在 指向某表的列级外键 */
|
|
678
|
+
function hasForeignKey(db: DatabaseSync, table: string, from: string, refTable: string): boolean {
|
|
679
|
+
const rows = db.prepare(`PRAGMA foreign_key_list(${table})`).all() as Array<{ from: string, table: string }>
|
|
680
|
+
return rows.some(r => r.from === from && r.table === refTable)
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* v3 → v4 迁移:补齐 tasks/subscriptions 缺失的外键。
|
|
685
|
+
* 早期版本(v1→v3 迁移产物、旧建表脚本)的这两张表没有 REFERENCES ... ON DELETE CASCADE,
|
|
686
|
+
* 而 CREATE TABLE IF NOT EXISTS 不会升级既有表 → channel 删除时 tasks/subscriptions 成孤儿数据。
|
|
687
|
+
* 重建前先清除孤儿行(其 channel 已不存在,不可达;新外键会使 INSERT 失败)。
|
|
688
|
+
*/
|
|
689
|
+
function migrateMissingForeignKeys(db: DatabaseSync): void {
|
|
690
|
+
const needTasks = !hasForeignKey(db, 'tasks', 'channel_id', 'channels')
|
|
691
|
+
const needSubs = !hasForeignKey(db, 'subscriptions', 'channel_id', 'channels')
|
|
692
|
+
if (!needTasks && !needSubs) return
|
|
693
|
+
|
|
694
|
+
db.exec('PRAGMA foreign_keys = OFF;')
|
|
695
|
+
try {
|
|
696
|
+
if (needTasks) {
|
|
697
|
+
db.exec(`DELETE FROM tasks WHERE channel_id NOT IN (SELECT id FROM channels);
|
|
698
|
+
CREATE TABLE tasks_new (
|
|
699
|
+
id TEXT PRIMARY KEY,
|
|
700
|
+
channel_id TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
|
|
701
|
+
parent_id TEXT,
|
|
702
|
+
assignee_id TEXT NOT NULL,
|
|
703
|
+
creator_id TEXT,
|
|
704
|
+
title TEXT NOT NULL,
|
|
705
|
+
description TEXT,
|
|
706
|
+
state TEXT NOT NULL,
|
|
707
|
+
progress INTEGER NOT NULL DEFAULT 0,
|
|
708
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
709
|
+
artifacts_json TEXT NOT NULL DEFAULT '[]',
|
|
710
|
+
history_json TEXT NOT NULL DEFAULT '[]',
|
|
711
|
+
route_reason TEXT NOT NULL DEFAULT '',
|
|
712
|
+
created_at TEXT NOT NULL,
|
|
713
|
+
updated_at TEXT NOT NULL
|
|
714
|
+
);
|
|
715
|
+
INSERT INTO tasks_new SELECT id, channel_id, parent_id, assignee_id, creator_id, title, description, state, progress, retry_count, artifacts_json, history_json, route_reason, created_at, updated_at FROM tasks;
|
|
716
|
+
DROP TABLE tasks;
|
|
717
|
+
ALTER TABLE tasks_new RENAME TO tasks;
|
|
718
|
+
-- 重建后索引必须与 SCHEMA_SQL 对齐:漏建则热查询退化为全表扫描(route_reason 列
|
|
719
|
+
-- 由 migrateAddColumn 先于本函数添加,SELECT 引用安全)
|
|
720
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_channel ON tasks(channel_id, state);
|
|
721
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_assignee ON tasks(assignee_id, state);
|
|
722
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_channel_assignee ON tasks(channel_id, assignee_id, state, created_at);
|
|
723
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_parent ON tasks(parent_id);`)
|
|
724
|
+
}
|
|
725
|
+
if (needSubs) {
|
|
726
|
+
db.exec(`DELETE FROM subscriptions
|
|
727
|
+
WHERE channel_id NOT IN (SELECT id FROM channels)
|
|
728
|
+
OR agent_id NOT IN (SELECT id FROM channel_agents);
|
|
729
|
+
CREATE TABLE subscriptions_new (
|
|
730
|
+
channel_id TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
|
|
731
|
+
agent_id TEXT NOT NULL REFERENCES channel_agents(id) ON DELETE CASCADE,
|
|
732
|
+
target_agent_id TEXT NOT NULL,
|
|
733
|
+
created_at TEXT NOT NULL,
|
|
734
|
+
PRIMARY KEY (channel_id, agent_id, target_agent_id)
|
|
735
|
+
);
|
|
736
|
+
INSERT INTO subscriptions_new SELECT channel_id, agent_id, target_agent_id, created_at FROM subscriptions;
|
|
737
|
+
DROP TABLE subscriptions;
|
|
738
|
+
ALTER TABLE subscriptions_new RENAME TO subscriptions;`)
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
finally {
|
|
742
|
+
db.exec('PRAGMA foreign_keys = ON;')
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
* v9(全局用户集成)迁移:剥离 owner_user_id 对本地 users 表的 FK。
|
|
748
|
+
* 身份与 token 已迁移至全局用户系统(data/users.sqlite),owner 列仅存用户 id 引用,
|
|
749
|
+
* 保留 FK 会使新全局用户 id 在本地 users 表无行而写入失败。
|
|
750
|
+
* 表重建期间临时关闭外键,避免 DROP 触发级联;重建后以原名重新命名,引用方 FK 依旧有效。
|
|
751
|
+
*/
|
|
752
|
+
function migrateDropOwnerFks(db: DatabaseSync): void {
|
|
753
|
+
const rebuilds: Array<{ table: string, ddl: string }> = []
|
|
754
|
+
if (hasForeignKey(db, 'workspaces', 'owner_user_id', 'users')) {
|
|
755
|
+
rebuilds.push({
|
|
756
|
+
table: 'workspaces',
|
|
757
|
+
ddl: `CREATE TABLE workspaces_new (
|
|
758
|
+
id TEXT PRIMARY KEY,
|
|
759
|
+
owner_user_id TEXT NOT NULL,
|
|
760
|
+
name TEXT NOT NULL,
|
|
761
|
+
created_at TEXT NOT NULL
|
|
762
|
+
);
|
|
763
|
+
INSERT INTO workspaces_new SELECT id, owner_user_id, name, created_at FROM workspaces;`,
|
|
764
|
+
})
|
|
765
|
+
}
|
|
766
|
+
if (hasForeignKey(db, 'channels', 'owner_user_id', 'users')) {
|
|
767
|
+
rebuilds.push({
|
|
768
|
+
table: 'channels',
|
|
769
|
+
ddl: `CREATE TABLE channels_new (
|
|
770
|
+
id TEXT PRIMARY KEY,
|
|
771
|
+
name TEXT NOT NULL,
|
|
772
|
+
description TEXT NOT NULL DEFAULT '',
|
|
773
|
+
lead_agent_id TEXT,
|
|
774
|
+
workspace TEXT NOT NULL DEFAULT '',
|
|
775
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
776
|
+
owner_user_id TEXT,
|
|
777
|
+
created_at TEXT NOT NULL,
|
|
778
|
+
updated_at TEXT NOT NULL
|
|
779
|
+
);
|
|
780
|
+
INSERT INTO channels_new SELECT id, name, description, lead_agent_id, workspace, enabled, owner_user_id, created_at, updated_at FROM channels;`,
|
|
781
|
+
})
|
|
782
|
+
}
|
|
783
|
+
if (hasForeignKey(db, 'agents', 'owner_user_id', 'users')) {
|
|
784
|
+
rebuilds.push({
|
|
785
|
+
table: 'agents',
|
|
786
|
+
ddl: `CREATE TABLE agents_new (
|
|
787
|
+
id TEXT PRIMARY KEY,
|
|
788
|
+
name TEXT NOT NULL,
|
|
789
|
+
harness TEXT NOT NULL,
|
|
790
|
+
config_json TEXT NOT NULL DEFAULT '{}',
|
|
791
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
792
|
+
visibility TEXT NOT NULL DEFAULT 'private',
|
|
793
|
+
owner_user_id TEXT,
|
|
794
|
+
created_at TEXT NOT NULL,
|
|
795
|
+
updated_at TEXT NOT NULL
|
|
796
|
+
);
|
|
797
|
+
INSERT INTO agents_new SELECT id, name, harness, config_json, enabled, visibility, owner_user_id, created_at, updated_at FROM agents;`,
|
|
798
|
+
})
|
|
799
|
+
}
|
|
800
|
+
if (hasForeignKey(db, 'teams', 'owner_user_id', 'users')) {
|
|
801
|
+
rebuilds.push({
|
|
802
|
+
table: 'teams',
|
|
803
|
+
ddl: `CREATE TABLE teams_new (
|
|
804
|
+
id TEXT PRIMARY KEY,
|
|
805
|
+
name TEXT NOT NULL,
|
|
806
|
+
description TEXT NOT NULL DEFAULT '',
|
|
807
|
+
owner_user_id TEXT,
|
|
808
|
+
created_at TEXT NOT NULL,
|
|
809
|
+
updated_at TEXT NOT NULL
|
|
810
|
+
);
|
|
811
|
+
INSERT INTO teams_new SELECT id, name, description, owner_user_id, created_at, updated_at FROM teams;`,
|
|
812
|
+
})
|
|
813
|
+
}
|
|
814
|
+
if (rebuilds.length === 0) return
|
|
815
|
+
|
|
816
|
+
db.exec('PRAGMA foreign_keys = OFF;')
|
|
817
|
+
try {
|
|
818
|
+
for (const { table, ddl } of rebuilds) {
|
|
819
|
+
db.exec(`${ddl}
|
|
820
|
+
DROP TABLE ${table};
|
|
821
|
+
ALTER TABLE ${table}_new RENAME TO ${table};`)
|
|
822
|
+
}
|
|
823
|
+
db.exec(`CREATE INDEX IF NOT EXISTS idx_workspaces_owner ON workspaces(owner_user_id);`)
|
|
824
|
+
}
|
|
825
|
+
finally {
|
|
826
|
+
db.exec('PRAGMA foreign_keys = ON;')
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/**
|
|
831
|
+
* 旧库迁移到 v3。仅当 agents 仍含 channel_id 列(v1:agents 内嵌 channel_id/role/token)时执行。
|
|
832
|
+
* 迁移过程临时关闭外键,避免 DROP TABLE 触发级联;v1 的 agent id 保留为实例 id,
|
|
833
|
+
* 使 messages/tasks/subscriptions 对 agent 的既有引用继续有效。
|
|
834
|
+
*/
|
|
835
|
+
function migrateLegacySchema(db: DatabaseSync): void {
|
|
836
|
+
const channelsCols = db.prepare(`PRAGMA table_info(channels)`).all() as Array<{ name: string }>
|
|
837
|
+
if (!channelsCols.some(c => c.name === 'workspace')) {
|
|
838
|
+
db.exec(`ALTER TABLE channels ADD COLUMN workspace TEXT NOT NULL DEFAULT ''`)
|
|
839
|
+
}
|
|
840
|
+
// v7:用户隔离 owner 列(幂等;默认 NULL = 遗留公共数据)。
|
|
841
|
+
// v9(全局用户集成):owner 引用改为全局用户系统 id,不再加 REFERENCES(避免跨库 FK)。
|
|
842
|
+
if (!channelsCols.some(c => c.name === 'owner_user_id')) {
|
|
843
|
+
db.exec(`ALTER TABLE channels ADD COLUMN owner_user_id TEXT`)
|
|
844
|
+
}
|
|
845
|
+
// v7:用户隔离 owner 列(幂等;默认 NULL = 遗留公共数据)。
|
|
846
|
+
// v9(全局用户集成):owner 引用改为全局用户系统 id,不再加 REFERENCES(避免跨库 FK)。
|
|
847
|
+
const agentsColsV7 = db.prepare(`PRAGMA table_info(agents)`).all() as Array<{ name: string }>
|
|
848
|
+
if (!agentsColsV7.some(c => c.name === 'owner_user_id')) {
|
|
849
|
+
db.exec(`ALTER TABLE agents ADD COLUMN owner_user_id TEXT`)
|
|
850
|
+
}
|
|
851
|
+
const teamsColsV7 = db.prepare(`PRAGMA table_info(teams)`).all() as Array<{ name: string }>
|
|
852
|
+
if (!teamsColsV7.some(c => c.name === 'owner_user_id')) {
|
|
853
|
+
db.exec(`ALTER TABLE teams ADD COLUMN owner_user_id TEXT`)
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
const agentCols = db.prepare(`PRAGMA table_info(agents)`).all() as Array<{ name: string }>
|
|
857
|
+
const isV1 = agentCols.some(c => c.name === 'channel_id')
|
|
858
|
+
if (!isV1) return
|
|
859
|
+
|
|
860
|
+
db.exec('PRAGMA foreign_keys = OFF;')
|
|
861
|
+
try {
|
|
862
|
+
// 1. subscriptions 补 channel_id(从旧 agents.channel_id 推导),agent_id 指向实例
|
|
863
|
+
const subCols = db.prepare(`PRAGMA table_info(subscriptions)`).all() as Array<{ name: string }>
|
|
864
|
+
if (!subCols.some(c => c.name === 'channel_id')) {
|
|
865
|
+
db.exec(`CREATE TABLE subscriptions_new (
|
|
866
|
+
channel_id TEXT NOT NULL,
|
|
867
|
+
agent_id TEXT NOT NULL,
|
|
868
|
+
target_agent_id TEXT NOT NULL,
|
|
869
|
+
created_at TEXT NOT NULL,
|
|
870
|
+
PRIMARY KEY (channel_id, agent_id, target_agent_id)
|
|
871
|
+
);
|
|
872
|
+
INSERT INTO subscriptions_new (channel_id, agent_id, target_agent_id, created_at)
|
|
873
|
+
SELECT a.channel_id, s.agent_id, s.target_agent_id, s.created_at
|
|
874
|
+
FROM subscriptions s JOIN agents a ON a.id = s.agent_id
|
|
875
|
+
WHERE s.target_agent_id IS NOT NULL;
|
|
876
|
+
DROP TABLE subscriptions;
|
|
877
|
+
ALTER TABLE subscriptions_new RENAME TO subscriptions;`)
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// 2. channel_agents ← v1 agents(id 保留为实例 id;template_id 置空)
|
|
881
|
+
db.exec(`INSERT INTO channel_agents (id, channel_id, template_id, name, harness, config_json, role, token, enabled, created_at, updated_at)
|
|
882
|
+
SELECT id, channel_id, NULL, name, harness, config_json, role, token, enabled, created_at, updated_at FROM agents;`)
|
|
883
|
+
|
|
884
|
+
// 3. tasks 去 assignee_id 的 agents FK(旧库指向 agents,现指向实例 id)
|
|
885
|
+
db.exec(`CREATE TABLE tasks_new (
|
|
886
|
+
id TEXT PRIMARY KEY,
|
|
887
|
+
channel_id TEXT NOT NULL,
|
|
888
|
+
parent_id TEXT,
|
|
889
|
+
assignee_id TEXT NOT NULL,
|
|
890
|
+
creator_id TEXT,
|
|
891
|
+
title TEXT NOT NULL,
|
|
892
|
+
description TEXT,
|
|
893
|
+
state TEXT NOT NULL,
|
|
894
|
+
progress INTEGER NOT NULL DEFAULT 0,
|
|
895
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
896
|
+
artifacts_json TEXT NOT NULL DEFAULT '[]',
|
|
897
|
+
history_json TEXT NOT NULL DEFAULT '[]',
|
|
898
|
+
created_at TEXT NOT NULL,
|
|
899
|
+
updated_at TEXT NOT NULL
|
|
900
|
+
);
|
|
901
|
+
INSERT INTO tasks_new SELECT id, channel_id, parent_id, assignee_id, creator_id, title, description, state, progress, retry_count, artifacts_json, history_json, created_at, updated_at FROM tasks;
|
|
902
|
+
DROP TABLE tasks;
|
|
903
|
+
ALTER TABLE tasks_new RENAME TO tasks;
|
|
904
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_channel ON tasks(channel_id, state);
|
|
905
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_assignee ON tasks(assignee_id, state);`)
|
|
906
|
+
|
|
907
|
+
// 4. agents 重建为模板表(旧数据已迁到 channel_agents,模板表清空)
|
|
908
|
+
db.exec(`CREATE TABLE agents_new (
|
|
909
|
+
id TEXT PRIMARY KEY,
|
|
910
|
+
name TEXT NOT NULL,
|
|
911
|
+
harness TEXT NOT NULL,
|
|
912
|
+
config_json TEXT NOT NULL DEFAULT '{}',
|
|
913
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
914
|
+
created_at TEXT NOT NULL,
|
|
915
|
+
updated_at TEXT NOT NULL
|
|
916
|
+
);
|
|
917
|
+
DROP TABLE agents;
|
|
918
|
+
ALTER TABLE agents_new RENAME TO agents;`)
|
|
919
|
+
}
|
|
920
|
+
finally {
|
|
921
|
+
db.exec('PRAGMA foreign_keys = ON;')
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/** 解析 JSON 列;解析失败返回 fallback(默认值) */
|
|
926
|
+
export function parseJson<T>(text: string | null | undefined, fallback: T): T {
|
|
927
|
+
if (text == null || text === '') return fallback
|
|
928
|
+
try {
|
|
929
|
+
return JSON.parse(text) as T
|
|
930
|
+
}
|
|
931
|
+
catch {
|
|
932
|
+
return fallback
|
|
933
|
+
}
|
|
934
|
+
}
|