agentworkshop 0.7.3 → 0.7.4

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.
Files changed (127) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/B9Yie5HN.js +2 -0
  3. package/.output/public/_nuxt/CN7Zh8GQ.js +1 -0
  4. package/.output/public/_nuxt/CdSgfcYR.js +1 -0
  5. package/.output/public/_nuxt/CdfAP_IH2.js +1 -0
  6. package/.output/public/_nuxt/ChnfyQHz.js +1 -0
  7. package/.output/public/_nuxt/{BkKYf8xY.js → CyygA0q4.js} +4 -4
  8. package/.output/public/_nuxt/{Bz40vyZS.js → DFnGFEav.js} +7 -7
  9. package/.output/public/_nuxt/Xaf_HIR3.js +1 -0
  10. package/.output/public/_nuxt/ZugRk0CM2.js +4 -0
  11. package/.output/public/_nuxt/builds/latest.json +1 -1
  12. package/.output/public/_nuxt/builds/meta/55c10854-ee0e-4be4-924b-a1b0e100fe11.json +1 -0
  13. package/.output/public/_nuxt/{default.iGJy9dP-.css → default.D17kXlD6.css} +1 -1
  14. package/.output/public/_nuxt/monitor.CmwpEUCI.css +1 -0
  15. package/.output/public/_nuxt/yIKY_V1P.js +1 -0
  16. package/.output/server/chunks/_/nitro.mjs +1131 -920
  17. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  18. package/.output/server/chunks/build/{TownView-BkHxMiwZ.mjs → TownView-Bl8Gkcxi.mjs} +3 -3
  19. package/.output/server/chunks/build/{TownView-BkHxMiwZ.mjs.map → TownView-Bl8Gkcxi.mjs.map} +1 -1
  20. package/.output/server/chunks/build/{_id_-Bna1_JuB.mjs → _id_-CWLFGZjV.mjs} +2 -2
  21. package/.output/server/chunks/build/{_id_-Bna1_JuB.mjs.map → _id_-CWLFGZjV.mjs.map} +1 -1
  22. package/.output/server/chunks/build/_id_-GnRJPykX.mjs +1 -1
  23. package/.output/server/chunks/build/{_wsId_-CzLDGT_V.mjs → _wsId_-BhQMjyHG.mjs} +3 -4
  24. package/.output/server/chunks/build/{_wsId_-CzLDGT_V.mjs.map → _wsId_-BhQMjyHG.mjs.map} +1 -1
  25. package/.output/server/chunks/build/{daq-CmeM4u5u.mjs → daq-BOgpn9sl.mjs} +4 -5
  26. package/.output/server/chunks/build/daq-BOgpn9sl.mjs.map +1 -0
  27. package/.output/server/chunks/build/dcw-BTM5YU-B.mjs +1 -1
  28. package/.output/server/chunks/build/{default-Dt6xLdpd.mjs → default-CKJWhkot.mjs} +60 -17
  29. package/.output/server/chunks/build/{default-Dt6xLdpd.mjs.map → default-CKJWhkot.mjs.map} +1 -1
  30. package/.output/server/chunks/build/{logs-CUQt1z7D.mjs → logs-Dyk0I2I9.mjs} +3 -4
  31. package/.output/server/chunks/build/logs-Dyk0I2I9.mjs.map +1 -0
  32. package/.output/server/chunks/build/{monitor-yNoV98rf.mjs → monitor-KW8WLOJd.mjs} +34 -33
  33. package/.output/server/chunks/build/{monitor-yNoV98rf.mjs.map → monitor-KW8WLOJd.mjs.map} +1 -1
  34. package/.output/server/chunks/build/{town-BN4vQPb8.mjs → town-_4tEEEVW.mjs} +3 -4
  35. package/.output/server/chunks/build/town-_4tEEEVW.mjs.map +1 -0
  36. package/.output/server/chunks/build/useDaqStream-hwkhJHFU.mjs +1 -1
  37. package/.output/server/chunks/build/useDcwStream-Bdew_yrr.mjs +1 -1
  38. package/.output/server/chunks/build/{useWorkshopWs-xcdeiSmJ.mjs → useWorkshopWs-B3j5wIAK.mjs} +177 -3
  39. package/.output/server/chunks/build/useWorkshopWs-B3j5wIAK.mjs.map +1 -0
  40. package/.output/server/chunks/build/{workshop-CLhwe5eo.mjs → workshop-k0XZTFKg.mjs} +2 -3
  41. package/.output/server/chunks/build/workshop-k0XZTFKg.mjs.map +1 -0
  42. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  43. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +1 -1
  44. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +32 -0
  45. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs.map +1 -0
  46. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +56 -0
  47. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs.map +1 -0
  48. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  49. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  50. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  51. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  52. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  53. package/.output/server/chunks/routes/renderer.mjs +2 -2
  54. package/.output/server/chunks/virtual/entry.mjs +17 -11
  55. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  56. package/.output/server/package.json +1 -1
  57. package/README.md +435 -434
  58. package/app/components/AppHeader.vue +138 -0
  59. package/app/composables/workshop/useWorkshopWs.ts +4 -0
  60. package/app/pages/monitor.vue +17 -1
  61. package/app/stores/workshop/hitl.ts +80 -0
  62. package/bin/aw.mjs +0 -0
  63. package/cli/commands/tui.mjs +19 -0
  64. package/config.yml +134 -134
  65. package/docs/tui.md +43 -0
  66. package/i18n/locales/en.ts +3 -0
  67. package/i18n/locales/zh-CN.ts +3 -0
  68. package/package.json +140 -144
  69. package/scripts/_spike-pitui.mjs +116 -0
  70. package/scripts/e2e-hitl-live.mjs +323 -0
  71. package/scripts/e2e-line-live.mjs +144 -0
  72. package/scripts/test-hitl-registry.ts +112 -0
  73. package/scripts/test-tui-commands.mjs +131 -0
  74. package/scripts/test-tui-reducers.mjs +72 -0
  75. package/scripts/tsconfig.json +14 -0
  76. package/scripts/tui-smoke.mjs +91 -0
  77. package/server/api/workshop/hitl/pending.get.ts +28 -0
  78. package/server/api/workshop/hitl/respond.post.ts +67 -0
  79. package/server/api/workshop/ws.ts +30 -1
  80. package/server/data/daqs.json +39 -17
  81. package/server/data/dcw-lines.json +14 -0
  82. package/server/data/dcw-products.json +35 -0
  83. package/server/data/dcw-recipes.json +140 -0
  84. package/server/data/dcw-rollback.json +111 -1
  85. package/server/data/dcw-runs.json +135 -90
  86. package/server/data/dcw-writes.json +120 -0
  87. package/server/data/dcws.json +400 -275
  88. package/server/data/line-runs.json +11 -1
  89. package/server/plugins/workshop.ts +7 -0
  90. package/server/services/workshop/agents/harness-terminal.ts +92 -25
  91. package/server/services/workshop/agents/hitl-registry.ts +181 -0
  92. package/server/services/workshop/agents/tool-approvals.ts +15 -0
  93. package/server/services/workshop/scene-events.ts +19 -9
  94. package/shared/workshop-protocol.ts +37 -0
  95. package/tui/README.md +65 -0
  96. package/tui/aw-tui.mjs +356 -0
  97. package/tui/commands/index.mjs +250 -0
  98. package/tui/components/chat-log.mjs +42 -0
  99. package/tui/components/hitl-card.mjs +36 -0
  100. package/tui/components/monitor-pane.mjs +39 -0
  101. package/tui/components/root.mjs +53 -0
  102. package/tui/components/status-bar.mjs +29 -0
  103. package/tui/lib/api.mjs +82 -0
  104. package/tui/lib/config.mjs +58 -0
  105. package/tui/lib/reducers.mjs +218 -0
  106. package/tui/lib/state.mjs +80 -0
  107. package/tui/lib/virtual-terminal.mjs +48 -0
  108. package/tui/lib/ws.mjs +124 -0
  109. package/tui/theme.mjs +38 -0
  110. package/.output/public/_nuxt/B7V9IfTL.js +0 -1
  111. package/.output/public/_nuxt/BE5QyG5J2.js +0 -1
  112. package/.output/public/_nuxt/BuKI8z-5.js +0 -1
  113. package/.output/public/_nuxt/D0C5Q0di.js +0 -1
  114. package/.output/public/_nuxt/DC-QMEk1.js +0 -2
  115. package/.output/public/_nuxt/DEkQ0qQ02.js +0 -1
  116. package/.output/public/_nuxt/builds/meta/c6c01cdd-762e-4fb8-86e7-753c5185b856.json +0 -1
  117. package/.output/public/_nuxt/dt2tKE95.js +0 -4
  118. package/.output/public/_nuxt/i_MKObHo.js +0 -1
  119. package/.output/public/_nuxt/monitor.41fCD6TB.css +0 -1
  120. package/.output/public/_nuxt/tpDMVY5w.js +0 -1
  121. package/.output/server/chunks/build/connection-Dc0fn6yd.mjs +0 -120
  122. package/.output/server/chunks/build/connection-Dc0fn6yd.mjs.map +0 -1
  123. package/.output/server/chunks/build/daq-CmeM4u5u.mjs.map +0 -1
  124. package/.output/server/chunks/build/logs-CUQt1z7D.mjs.map +0 -1
  125. package/.output/server/chunks/build/town-BN4vQPb8.mjs.map +0 -1
  126. package/.output/server/chunks/build/useWorkshopWs-xcdeiSmJ.mjs.map +0 -1
  127. package/.output/server/chunks/build/workshop-CLhwe5eo.mjs.map +0 -1
package/package.json CHANGED
@@ -1,144 +1,140 @@
1
- {
2
- "name": "agentworkshop",
3
- "version": "0.7.3",
4
- "type": "module",
5
- "description": "AgentWorkShop 软件开发系统 - 基于 Nuxt 4 的配置驱动运行范式",
6
- "license": "PolyForm-Noncommercial-1.0.0",
7
- "exports": {
8
- ".": {
9
- "types": "./sdk/index.d.mts",
10
- "default": "./sdk/index.mjs"
11
- },
12
- "./sdk": {
13
- "types": "./sdk/index.d.mts",
14
- "default": "./sdk/index.mjs"
15
- },
16
- "./sdk/client": {
17
- "types": "./sdk/client.d.mts",
18
- "default": "./sdk/client.mjs"
19
- },
20
- "./package.json": "./package.json"
21
- },
22
- "bin": {
23
- "aw": "bin/aw.mjs",
24
- "agentworkshop": "bin/aw.mjs"
25
- },
26
- "files": [
27
- ".output",
28
- "bin",
29
- "cli",
30
- "sdk",
31
- "app",
32
- "server",
33
- "shared",
34
- "i18n",
35
- "public",
36
- "scripts",
37
- ".AgentWorkShop/prompts",
38
- "config.yml",
39
- "nuxt.config.ts",
40
- "tsconfig.json",
41
- "uno.config.ts",
42
- "docker-compose.yml",
43
- ".env.example",
44
- "README-zh.md",
45
- "docs/cli.md",
46
- "docs/plugins.md",
47
- "docs/sdk.md"
48
- ],
49
- "packageManager": "pnpm@11.9.0",
50
- "engines": {
51
- "node": ">=23.4.0"
52
- },
53
- "scripts": {
54
- "dev": "node bin/aw.mjs dev",
55
- "build": "node bin/aw.mjs build",
56
- "start": "node bin/aw.mjs start",
57
- "generate": "nuxt generate",
58
- "preview": "node bin/aw.mjs start",
59
- "cli": "node bin/aw.mjs",
60
- "postinstall": "node scripts/home-bootstrap.mjs",
61
- "prepublishOnly": "node bin/aw.mjs build",
62
- "lint": "eslint .",
63
- "lint:fix": "eslint . --fix",
64
- "typecheck": "nuxt typecheck",
65
- "prepare": "husky",
66
- "game:test": "tsx scripts/test-agent-brain.ts && tsx scripts/test-game-session.ts",
67
- "test:api-live": "node scripts/api-live-e2e.mjs",
68
- "game:verify": "node scripts/verify-game.mjs",
69
- "game:build-assets": "node scripts/build-player-sheet.mjs",
70
- "game:build-wuwa": "node scripts/build-wuwa-assets.mjs",
71
- "game:build-models": "node scripts/build-character-models.mjs",
72
- "game:build-world": "node scripts/build-world-map.mjs",
73
- "game:build-model3d": "node scripts/build-model-3d.mjs"
74
- },
75
- "lint-staged": {
76
- "*.{js,mjs,cjs,ts,vue}": "eslint --fix"
77
- },
78
- "dependencies": {
79
- "@ant-design-vue/nuxt": "^1.4.6",
80
- "@ant-design/icons-vue": "^7.0.1",
81
- "@fontsource-variable/fraunces": "^5.3.0",
82
- "@fontsource-variable/geist": "^5.3.0",
83
- "@fontsource-variable/geist-mono": "^5.3.0",
84
- "@fontsource-variable/inter": "^5.3.0",
85
- "@fontsource/eb-garamond": "^5.3.0",
86
- "@fontsource/ibm-plex-mono": "^5.3.0",
87
- "@iconify-json/tabler": "^1.2.0",
88
- "@modelcontextprotocol/sdk": "^1.30.0",
89
- "@nuxtjs/i18n": "^9.0.0",
90
- "@pinia/nuxt": "^0.11.0",
91
- "@unocss/nuxt": "^66.0.0",
92
- "@unocss/preset-attributify": "^66.0.0",
93
- "@unocss/preset-icons": "^66.7.5",
94
- "@unocss/preset-typography": "^66.0.0",
95
- "@vueuse/core": "^13.0.0",
96
- "@vueuse/nuxt": "^13.0.0",
97
- "@xterm/addon-fit": "^0.11.0",
98
- "@xterm/xterm": "^6.0.0",
99
- "ant-design-vue": "^4.2.6",
100
- "axios": "^1.7.9",
101
- "echarts": "^5.6.0",
102
- "h3": "2.0.1-rc.26",
103
- "js-yaml": "^4.1.0",
104
- "minio": "^8.0.7",
105
- "modbus-serial": "^8.0.25",
106
- "mqtt": "^5.15.2",
107
- "node-opcua": "^2.178.0",
108
- "nuxt": "^4.0.0",
109
- "nuxt-auth-utils": "^0.5.0",
110
- "pg": "^8.23.0",
111
- "phaser": "^4.0.0",
112
- "pinia": "^3.0.0",
113
- "pinia-plugin-persistedstate": "^4.2.0",
114
- "sqlite-vec": "^0.1.9",
115
- "three": "^0.185.1",
116
- "unocss": "^66.0.0",
117
- "unplugin-icons": "^22.0.0",
118
- "vue": "^3.5.13",
119
- "vue-echarts": "^7.0.3",
120
- "vue-router": "^4.5.0",
121
- "zod": "^3.24.1"
122
- },
123
- "devDependencies": {
124
- "@commitlint/cli": "^19.6.1",
125
- "@commitlint/config-conventional": "^19.6.0",
126
- "@nuxt/eslint": "^1.0.0",
127
- "@types/js-yaml": "^4.0.9",
128
- "@types/node": "^26.2.0",
129
- "@types/three": "^0.185.4",
130
- "eslint": "^9.17.0",
131
- "husky": "^9.1.7",
132
- "lint-staged": "^15.3.0",
133
- "pngjs": "^7.0.0",
134
- "puppeteer-core": "^25.5.0",
135
- "tsx": "^4.23.12",
136
- "typescript": "^5.7.3",
137
- "vue-tsc": "^3.3.10"
138
- },
139
- "pnpm": {
140
- "ignoredBuiltDependencies": [
141
- "@serialport/bindings-cpp"
142
- ]
143
- }
144
- }
1
+ {
2
+ "name": "agentworkshop",
3
+ "version": "0.7.4",
4
+ "type": "module",
5
+ "description": "AgentWorkShop 软件开发系统 - 基于 Nuxt 4 的配置驱动运行范式",
6
+ "license": "PolyForm-Noncommercial-1.0.0",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./sdk/index.d.mts",
10
+ "default": "./sdk/index.mjs"
11
+ },
12
+ "./sdk": {
13
+ "types": "./sdk/index.d.mts",
14
+ "default": "./sdk/index.mjs"
15
+ },
16
+ "./sdk/client": {
17
+ "types": "./sdk/client.d.mts",
18
+ "default": "./sdk/client.mjs"
19
+ },
20
+ "./package.json": "./package.json"
21
+ },
22
+ "bin": {
23
+ "aw": "bin/aw.mjs",
24
+ "agentworkshop": "bin/aw.mjs"
25
+ },
26
+ "files": [
27
+ ".output",
28
+ "bin",
29
+ "cli",
30
+ "sdk",
31
+ "app",
32
+ "server",
33
+ "shared",
34
+ "i18n",
35
+ "public",
36
+ "scripts",
37
+ ".AgentWorkShop/prompts",
38
+ "config.yml",
39
+ "nuxt.config.ts",
40
+ "tsconfig.json",
41
+ "uno.config.ts",
42
+ "docker-compose.yml",
43
+ ".env.example",
44
+ "README-zh.md",
45
+ "docs/cli.md",
46
+ "docs/plugins.md",
47
+ "docs/sdk.md",
48
+ "docs/tui.md",
49
+ "tui"
50
+ ],
51
+ "engines": {
52
+ "node": ">=23.4.0"
53
+ },
54
+ "lint-staged": {
55
+ "*.{js,mjs,cjs,ts,vue}": "eslint --fix"
56
+ },
57
+ "dependencies": {
58
+ "@ant-design-vue/nuxt": "^1.4.6",
59
+ "@ant-design/icons-vue": "^7.0.1",
60
+ "@earendil-works/pi-tui": "^0.84.4",
61
+ "@fontsource-variable/fraunces": "^5.3.0",
62
+ "@fontsource-variable/geist": "^5.3.0",
63
+ "@fontsource-variable/geist-mono": "^5.3.0",
64
+ "@fontsource-variable/inter": "^5.3.0",
65
+ "@fontsource/eb-garamond": "^5.3.0",
66
+ "@fontsource/ibm-plex-mono": "^5.3.0",
67
+ "@iconify-json/tabler": "^1.2.0",
68
+ "@modelcontextprotocol/sdk": "^1.30.0",
69
+ "@nuxtjs/i18n": "^9.0.0",
70
+ "@pinia/nuxt": "^0.11.0",
71
+ "@unocss/nuxt": "^66.0.0",
72
+ "@unocss/preset-attributify": "^66.0.0",
73
+ "@unocss/preset-icons": "^66.7.5",
74
+ "@unocss/preset-typography": "^66.0.0",
75
+ "@vueuse/core": "^13.0.0",
76
+ "@vueuse/nuxt": "^13.0.0",
77
+ "@xterm/addon-fit": "^0.11.0",
78
+ "@xterm/xterm": "^6.0.0",
79
+ "ant-design-vue": "^4.2.6",
80
+ "axios": "^1.7.9",
81
+ "echarts": "^5.6.0",
82
+ "h3": "2.0.1-rc.26",
83
+ "js-yaml": "^4.1.0",
84
+ "minio": "^8.0.7",
85
+ "modbus-serial": "^8.0.25",
86
+ "mqtt": "^5.15.2",
87
+ "node-opcua": "^2.178.0",
88
+ "nuxt": "^4.0.0",
89
+ "nuxt-auth-utils": "^0.5.0",
90
+ "pg": "^8.23.0",
91
+ "phaser": "^4.0.0",
92
+ "pinia": "^3.0.0",
93
+ "pinia-plugin-persistedstate": "^4.2.0",
94
+ "sqlite-vec": "^0.1.9",
95
+ "three": "^0.185.1",
96
+ "unocss": "^66.0.0",
97
+ "unplugin-icons": "^22.0.0",
98
+ "vue": "^3.5.13",
99
+ "vue-echarts": "^7.0.3",
100
+ "vue-router": "^4.5.0",
101
+ "zod": "^3.24.1"
102
+ },
103
+ "devDependencies": {
104
+ "@commitlint/cli": "^19.6.1",
105
+ "@commitlint/config-conventional": "^19.6.0",
106
+ "@nuxt/eslint": "^1.0.0",
107
+ "@types/js-yaml": "^4.0.9",
108
+ "@types/node": "^26.2.0",
109
+ "@types/three": "^0.185.4",
110
+ "eslint": "^9.17.0",
111
+ "husky": "^9.1.7",
112
+ "lint-staged": "^15.3.0",
113
+ "pngjs": "^7.0.0",
114
+ "puppeteer-core": "^25.5.0",
115
+ "tsx": "^4.23.12",
116
+ "typescript": "^5.7.3",
117
+ "vue-tsc": "^3.3.10"
118
+ },
119
+ "scripts": {
120
+ "dev": "node bin/aw.mjs dev",
121
+ "build": "node bin/aw.mjs build",
122
+ "start": "node bin/aw.mjs start",
123
+ "generate": "nuxt generate",
124
+ "preview": "node bin/aw.mjs start",
125
+ "cli": "node bin/aw.mjs",
126
+ "tui": "node tui/aw-tui.mjs",
127
+ "postinstall": "node scripts/home-bootstrap.mjs",
128
+ "lint": "eslint .",
129
+ "lint:fix": "eslint . --fix",
130
+ "typecheck": "nuxt typecheck",
131
+ "game:test": "tsx scripts/test-agent-brain.ts && tsx scripts/test-game-session.ts",
132
+ "test:api-live": "node scripts/api-live-e2e.mjs",
133
+ "game:verify": "node scripts/verify-game.mjs",
134
+ "game:build-assets": "node scripts/build-player-sheet.mjs",
135
+ "game:build-wuwa": "node scripts/build-wuwa-assets.mjs",
136
+ "game:build-models": "node scripts/build-character-models.mjs",
137
+ "game:build-world": "node scripts/build-world-map.mjs",
138
+ "game:build-model3d": "node scripts/build-model-3d.mjs"
139
+ }
140
+ }
@@ -0,0 +1,116 @@
1
+ // Phase 0 spike:pi-tui(@earendil-works/pi-tui)无 TTY 可行性验证。
2
+ // 用虚拟终端(Terminal 接口最小实现)驱动真实 TUI 渲染 + Editor 输入,
3
+ // 全部断言通过 ⇒ 框架机制可用,交互层(真实终端 raw-mode/VT)由人工在
4
+ // Git Bash / Windows Terminal 各跑一次 `node scripts/_spike-pitui.mjs --live` 终验。
5
+ import { TuiMainScreen, Text, Editor, ProcessTerminal } from '@earendil-works/pi-tui'
6
+
7
+ const isLive = process.argv.includes('--live')
8
+
9
+ /** 虚拟终端:捕获写入、可注入输入(Terminal 接口最小 duck-typing 实现) */
10
+ class VirtualTerminal {
11
+ constructor(cols = 100, rows = 30) {
12
+ this.columns = cols
13
+ this.rows = rows
14
+ this.frames = []
15
+ this.inputHandler = null
16
+ this.kittyProtocolActive = false
17
+ }
18
+
19
+ start(onInput) { this.inputHandler = onInput }
20
+ stop() {}
21
+ async drainInput() {}
22
+ write(data) { this.frames.push(data) }
23
+ moveBy() {}
24
+ hideCursor() {}
25
+ showCursor() {}
26
+ clearLine() {}
27
+ clearFromCursor() {}
28
+ clearScreen() {}
29
+ setTitle() {}
30
+ setProgress() {}
31
+ /** 测试注入按键(模拟 raw-mode 字节流) */
32
+ emitInput(data) { this.inputHandler?.(data) }
33
+ /** 全部输出拼接(strip ANSI 后可断言) */
34
+ output() { return this.frames.join('') }
35
+ }
36
+
37
+ // eslint-disable-next-line no-control-regex
38
+ const stripAnsi = s => s.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, '').replace(/\x1b\][^\x07]*\x07/g, '')
39
+
40
+ // ---- 主题(与 tui/theme.mjs 同源的极简令牌;spike 内联验证结构) ----
41
+ const theme = {
42
+ borderColor: s => `\x1b[38;2;53;224;160m${s}\x1b[0m`,
43
+ selectList: {
44
+ selectedPrefix: s => `› ${s}`,
45
+ selectedText: s => `\x1b[38;2;65;200;244m${s}\x1b[0m`,
46
+ description: s => `\x1b[2m${s}\x1b[0m`,
47
+ scrollInfo: s => `\x1b[2m${s}\x1b[0m`,
48
+ noMatch: s => s,
49
+ },
50
+ }
51
+
52
+ let failures = 0
53
+ function check(name, cond) {
54
+ console.log(`${cond ? ' ✓' : ' ✗ FAIL'} ${name}`)
55
+ if (!cond) failures++
56
+ }
57
+
58
+ if (isLive) {
59
+ // 真实终端交互验证:输入字符 + 回车;Ctrl+C 退出
60
+ const tui = new TuiMainScreen(new ProcessTerminal())
61
+ tui.addChild(new Text('pi-tui live spike: 输入任意文字后回车,Ctrl+C 退出'))
62
+ const editor = new Editor(tui, theme)
63
+ editor.onSubmit = text => tui.addChild(new Text(`[submit] ${text}`))
64
+ tui.addChild(editor)
65
+ tui.setFocus(editor)
66
+ tui.start()
67
+ console.log('live spike running…')
68
+ }
69
+ else await (async () => {
70
+ // ---- headless 验证 ----
71
+ console.log('[spike] pi-tui headless 渲染验证')
72
+ const vt = new VirtualTerminal()
73
+ const tui = new TuiMainScreen(vt)
74
+ tui.addChild(new Text('AgentWorkShop TUI boot ok'))
75
+ tui.addChild(new Text('频道: daq-产线A · 2 agents · HITL 待处理 1'))
76
+ const editor = new Editor(tui, theme)
77
+ const submitted = []
78
+ editor.onSubmit = text => submitted.push(text)
79
+ tui.addChild(editor)
80
+ tui.setFocus(editor)
81
+ tui.start()
82
+ await new Promise(r => setTimeout(r, 150))
83
+
84
+ const out1 = stripAnsi(vt.output())
85
+ check('TUI 实例化并启动(tui.start 无异常)', true)
86
+ check('Text 组件渲染出现在输出帧', out1.includes('AgentWorkShop TUI boot ok'))
87
+ check('中文与多行文本渲染', out1.includes('频道: daq-产线A'))
88
+ check('Editor 边框渲染(borderColor 令牌生效)', vt.output().includes('\x1b[38;2;53;224;160m'))
89
+
90
+ // Editor 输入:/help 回车 → onSubmit
91
+ vt.frames.length = 0
92
+ for (const ch of '/help') vt.emitInput(ch)
93
+ await new Promise(r => setTimeout(r, 50))
94
+ check('编辑器回显输入文本', stripAnsi(vt.output()).includes('/help'))
95
+ vt.emitInput('\r')
96
+ await new Promise(r => setTimeout(r, 50))
97
+ check('回车触发 onSubmit', submitted.length === 1 && submitted[0] === '/help')
98
+
99
+ // 光标移动 + 退格 + 历史(编辑器核心机制)
100
+ vt.emitInput('abc')
101
+ vt.emitInput('\x7f') // backspace
102
+ check('退格删除字符', editor.getText() === 'ab')
103
+ vt.emitInput('\x15') // Ctrl+U 清行
104
+ check('Ctrl+U 清空输入行', editor.getText() === '')
105
+
106
+ // 动态 addChild(流式追加语义)
107
+ const before = stripAnsi(vt.output()).length
108
+ tui.addChild(new Text('agent.delta 流块追加'))
109
+ tui.requestRender(true)
110
+ await new Promise(r => setTimeout(r, 80))
111
+ check('动态 addChild + requestRender 增量渲染', stripAnsi(vt.output()).length > before && stripAnsi(vt.output()).includes('agent.delta 流块追加'))
112
+
113
+ tui.stop()
114
+ console.log(failures === 0 ? '\n[spike] GO —— pi-tui 机制全部可用(真实终端交互请另跑 --live 人工终验)' : `\n[spike] NO-GO —— ${failures} 项失败`)
115
+ process.exit(failures === 0 ? 0 : 1)
116
+ })()