agentworkshop 0.7.2 → 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 (130) 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 +1144 -933
  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/plugins/_name/_...path_.mjs +8 -2
  43. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs.map +1 -1
  44. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  45. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +1 -1
  46. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +32 -0
  47. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs.map +1 -0
  48. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +56 -0
  49. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs.map +1 -0
  50. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  51. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  52. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  53. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  54. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  55. package/.output/server/chunks/routes/renderer.mjs +2 -2
  56. package/.output/server/chunks/virtual/entry.mjs +17 -11
  57. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  58. package/.output/server/package.json +1 -1
  59. package/README.md +435 -434
  60. package/app/components/AppHeader.vue +138 -0
  61. package/app/composables/workshop/useWorkshopWs.ts +4 -0
  62. package/app/pages/monitor.vue +17 -1
  63. package/app/stores/workshop/hitl.ts +80 -0
  64. package/bin/aw.mjs +0 -0
  65. package/cli/commands/tui.mjs +19 -0
  66. package/config.yml +134 -134
  67. package/docs/tui.md +43 -0
  68. package/i18n/locales/en.ts +3 -0
  69. package/i18n/locales/zh-CN.ts +3 -0
  70. package/package.json +140 -144
  71. package/scripts/_spike-pitui.mjs +116 -0
  72. package/scripts/e2e-hitl-live.mjs +323 -0
  73. package/scripts/e2e-line-live.mjs +144 -0
  74. package/scripts/test-hitl-registry.ts +112 -0
  75. package/scripts/test-tui-commands.mjs +131 -0
  76. package/scripts/test-tui-reducers.mjs +72 -0
  77. package/scripts/tsconfig.json +14 -0
  78. package/scripts/tui-smoke.mjs +91 -0
  79. package/server/api/plugins/[name]/[...path].ts +10 -1
  80. package/server/api/workshop/hitl/pending.get.ts +28 -0
  81. package/server/api/workshop/hitl/respond.post.ts +67 -0
  82. package/server/api/workshop/ws.ts +30 -1
  83. package/server/data/daqs.json +69 -17
  84. package/server/data/dcw-lines.json +21 -0
  85. package/server/data/dcw-products.json +42 -0
  86. package/server/data/dcw-recipes.json +168 -0
  87. package/server/data/dcw-rollback.json +133 -1
  88. package/server/data/dcw-runs.json +162 -108
  89. package/server/data/dcw-writes.json +180 -0
  90. package/server/data/dcws.json +427 -275
  91. package/server/data/line-runs.json +21 -1
  92. package/server/plugins/workshop.ts +7 -0
  93. package/server/services/workshop/agents/harness-terminal.ts +92 -25
  94. package/server/services/workshop/agents/hitl-registry.ts +181 -0
  95. package/server/services/workshop/agents/tool-approvals.ts +15 -0
  96. package/server/services/workshop/scene-events.ts +19 -9
  97. package/shared/workshop-protocol.ts +37 -0
  98. package/tui/README.md +65 -0
  99. package/tui/aw-tui.mjs +356 -0
  100. package/tui/commands/index.mjs +250 -0
  101. package/tui/components/chat-log.mjs +42 -0
  102. package/tui/components/hitl-card.mjs +36 -0
  103. package/tui/components/monitor-pane.mjs +39 -0
  104. package/tui/components/root.mjs +53 -0
  105. package/tui/components/status-bar.mjs +29 -0
  106. package/tui/lib/api.mjs +82 -0
  107. package/tui/lib/config.mjs +58 -0
  108. package/tui/lib/reducers.mjs +218 -0
  109. package/tui/lib/state.mjs +80 -0
  110. package/tui/lib/virtual-terminal.mjs +48 -0
  111. package/tui/lib/ws.mjs +124 -0
  112. package/tui/theme.mjs +38 -0
  113. package/.output/public/_nuxt/B7V9IfTL.js +0 -1
  114. package/.output/public/_nuxt/BE5QyG5J2.js +0 -1
  115. package/.output/public/_nuxt/BuKI8z-5.js +0 -1
  116. package/.output/public/_nuxt/D0C5Q0di.js +0 -1
  117. package/.output/public/_nuxt/DC-QMEk1.js +0 -2
  118. package/.output/public/_nuxt/DEkQ0qQ02.js +0 -1
  119. package/.output/public/_nuxt/builds/meta/4d990d25-ebbb-4fe4-a23b-3d28c7f42fee.json +0 -1
  120. package/.output/public/_nuxt/dt2tKE95.js +0 -4
  121. package/.output/public/_nuxt/i_MKObHo.js +0 -1
  122. package/.output/public/_nuxt/monitor.41fCD6TB.css +0 -1
  123. package/.output/public/_nuxt/tpDMVY5w.js +0 -1
  124. package/.output/server/chunks/build/connection-Dc0fn6yd.mjs +0 -120
  125. package/.output/server/chunks/build/connection-Dc0fn6yd.mjs.map +0 -1
  126. package/.output/server/chunks/build/daq-CmeM4u5u.mjs.map +0 -1
  127. package/.output/server/chunks/build/logs-CUQt1z7D.mjs.map +0 -1
  128. package/.output/server/chunks/build/town-BN4vQPb8.mjs.map +0 -1
  129. package/.output/server/chunks/build/useWorkshopWs-xcdeiSmJ.mjs.map +0 -1
  130. 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.2",
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
+ })()