@pixelbyte-software/pixcode 1.51.2 → 1.51.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 (331) hide show
  1. package/CODE_OF_CONDUCT.md +41 -41
  2. package/CONTRIBUTING.md +155 -155
  3. package/LICENSE +718 -718
  4. package/README.de.md +169 -169
  5. package/README.ja.md +167 -167
  6. package/README.ko.md +167 -167
  7. package/README.md +419 -419
  8. package/README.ru.md +169 -169
  9. package/README.tr.md +298 -298
  10. package/README.zh-CN.md +167 -167
  11. package/SECURITY.md +46 -46
  12. package/dist/api-automation.html +110 -110
  13. package/dist/api-docs.html +548 -548
  14. package/dist/assets/index-B9N-gfOQ.css +32 -0
  15. package/dist/assets/{index-EN9ngyxf.js → index-HfGHXhD6.js} +175 -175
  16. package/dist/clear-cache.html +85 -85
  17. package/dist/convert-icons.md +52 -52
  18. package/dist/docs.html +308 -308
  19. package/dist/favicon.svg +8 -8
  20. package/dist/features.html +133 -133
  21. package/dist/generate-icons.js +48 -48
  22. package/dist/humans.txt +15 -15
  23. package/dist/icons/codex-white.svg +3 -3
  24. package/dist/icons/codex.svg +3 -3
  25. package/dist/icons/cursor-white.svg +11 -11
  26. package/dist/icons/icon-128x128.svg +9 -9
  27. package/dist/icons/icon-144x144.svg +9 -9
  28. package/dist/icons/icon-152x152.svg +9 -9
  29. package/dist/icons/icon-192x192.svg +9 -9
  30. package/dist/icons/icon-384x384.svg +9 -9
  31. package/dist/icons/icon-512x512.svg +9 -9
  32. package/dist/icons/icon-72x72.svg +9 -9
  33. package/dist/icons/icon-96x96.svg +9 -9
  34. package/dist/icons/icon-template.svg +9 -9
  35. package/dist/icons/qwen-logo.svg +14 -14
  36. package/dist/index.html +59 -59
  37. package/dist/landing.html +268 -268
  38. package/dist/llms-full.txt +119 -119
  39. package/dist/llms.txt +53 -53
  40. package/dist/logo.svg +12 -12
  41. package/dist/manifest.json +60 -60
  42. package/dist/openapi.yaml +1696 -1696
  43. package/dist/orchestration.html +125 -125
  44. package/dist/robots.txt +4 -4
  45. package/dist/site.css +692 -692
  46. package/dist/sitemap.xml +51 -51
  47. package/dist/sw.js +132 -132
  48. package/dist-server/server/cli.js +96 -96
  49. package/dist-server/server/daemon/manager.js +33 -33
  50. package/dist-server/server/daemon-manager.js +64 -64
  51. package/dist-server/server/database/db.js +14 -2
  52. package/dist-server/server/database/db.js.map +1 -1
  53. package/dist-server/server/index.js +191 -31
  54. package/dist-server/server/index.js.map +1 -1
  55. package/dist-server/server/middleware/auth.js +16 -5
  56. package/dist-server/server/middleware/auth.js.map +1 -1
  57. package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.js +84 -0
  58. package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.js.map +1 -0
  59. package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.test.js +43 -0
  60. package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.test.js.map +1 -0
  61. package/dist-server/server/modules/orchestration/hermes/hermes.routes.js +55 -1
  62. package/dist-server/server/modules/orchestration/hermes/hermes.routes.js.map +1 -1
  63. package/dist-server/server/modules/orchestration/index.js +1 -0
  64. package/dist-server/server/modules/orchestration/index.js.map +1 -1
  65. package/dist-server/server/routes/auth.js +12 -5
  66. package/dist-server/server/routes/auth.js.map +1 -1
  67. package/dist-server/server/routes/commands.js +25 -25
  68. package/dist-server/server/routes/git.js +29 -17
  69. package/dist-server/server/routes/git.js.map +1 -1
  70. package/dist-server/server/routes/live-view.js +46 -46
  71. package/dist-server/server/routes/platformization.js +7 -6
  72. package/dist-server/server/routes/platformization.js.map +1 -1
  73. package/dist-server/server/services/hermes-gateway.js +310 -0
  74. package/dist-server/server/services/hermes-gateway.js.map +1 -1
  75. package/dist-server/server/services/platformization.js +58 -2
  76. package/dist-server/server/services/platformization.js.map +1 -1
  77. package/dist-server/server/services/public-api-manifest.js +59 -51
  78. package/dist-server/server/services/public-api-manifest.js.map +1 -1
  79. package/package.json +222 -222
  80. package/scripts/fix-node-pty.js +67 -67
  81. package/scripts/github/create-v1.38-issues.mjs +351 -351
  82. package/scripts/github/create-vscode-workbench-issues.mjs +121 -121
  83. package/scripts/hermes/configure-pixcode-mcp.mjs +165 -163
  84. package/scripts/hermes/pixcode-mcp-server.mjs +1009 -958
  85. package/scripts/smoke/changes-panel-layout.mjs +48 -48
  86. package/scripts/smoke/chat-composer-fixed-layout.mjs +55 -55
  87. package/scripts/smoke/chat-message-timeline-order.mjs +41 -41
  88. package/scripts/smoke/chat-realtime-hydration.mjs +44 -44
  89. package/scripts/smoke/chat-session-provider-pools.mjs +35 -35
  90. package/scripts/smoke/chat-session-state.mjs +19 -19
  91. package/scripts/smoke/code-editor-theme.mjs +55 -55
  92. package/scripts/smoke/code-editor-vscode-engine.mjs +91 -91
  93. package/scripts/smoke/command-center-agent-writes.mjs +79 -79
  94. package/scripts/smoke/command-center-non-git.mjs +46 -46
  95. package/scripts/smoke/context-packet.mjs +43 -43
  96. package/scripts/smoke/control-room-ux-redesign.mjs +91 -91
  97. package/scripts/smoke/daemon-entrypoint.mjs +20 -20
  98. package/scripts/smoke/default-landing-routing.mjs +33 -33
  99. package/scripts/smoke/desktop-native-notifications.mjs +30 -30
  100. package/scripts/smoke/desktop-tray-icon.mjs +33 -33
  101. package/scripts/smoke/discord-release-workflow.mjs +24 -24
  102. package/scripts/smoke/git-install-update.mjs +255 -255
  103. package/scripts/smoke/handoff-artifact-protocol.mjs +50 -50
  104. package/scripts/smoke/hermes-api-install.mjs +56 -56
  105. package/scripts/smoke/hermes-gateway-persistence.mjs +104 -104
  106. package/scripts/smoke/hermes-mcp-pixcode-roundtrip.mjs +426 -367
  107. package/scripts/smoke/hermes-rest-chat-api.mjs +162 -162
  108. package/scripts/smoke/hermes-rest-chat-live.mjs +45 -45
  109. package/scripts/smoke/hermes-rest-codex-launch.mjs +209 -209
  110. package/scripts/smoke/hermes-rest-gateway.mjs +79 -70
  111. package/scripts/smoke/hermes-rest-live.mjs +42 -42
  112. package/scripts/smoke/hermes-roundtrip.mjs +167 -167
  113. package/scripts/smoke/hermes-settings-commands.mjs +349 -346
  114. package/scripts/smoke/hermes-smoke-launcher-guard.mjs +34 -34
  115. package/scripts/smoke/live-view-diagnostics.mjs +53 -53
  116. package/scripts/smoke/live-view-environment.mjs +92 -92
  117. package/scripts/smoke/live-view-integration.mjs +450 -450
  118. package/scripts/smoke/mac-desktop-runtime.mjs +37 -37
  119. package/scripts/smoke/mobile-tunnel-guidance.mjs +29 -29
  120. package/scripts/smoke/model-registry.mjs +36 -36
  121. package/scripts/smoke/multi-project-ui.mjs +45 -45
  122. package/scripts/smoke/multi-worker-slots.mjs +42 -42
  123. package/scripts/smoke/notification-center.mjs +87 -87
  124. package/scripts/smoke/notification-inapp-preference.mjs +23 -23
  125. package/scripts/smoke/notification-taxonomy.mjs +58 -58
  126. package/scripts/smoke/orchestration-api.mjs +172 -172
  127. package/scripts/smoke/orchestration-execution-dashboard.mjs +33 -33
  128. package/scripts/smoke/orchestration-live-run.mjs +176 -176
  129. package/scripts/smoke/orchestration-mobile-scroll.mjs +29 -29
  130. package/scripts/smoke/orchestration-model-sync.mjs +30 -30
  131. package/scripts/smoke/orchestration-permission-fallback.mjs +34 -34
  132. package/scripts/smoke/orchestration-runtime-guards.mjs +48 -48
  133. package/scripts/smoke/orchestration-user-facing-output.mjs +25 -25
  134. package/scripts/smoke/permission-policy.mjs +50 -50
  135. package/scripts/smoke/pixcode-workbench-1-48.mjs +167 -167
  136. package/scripts/smoke/provider-models-opencode-live.mjs +66 -66
  137. package/scripts/smoke/provider-rest-api.mjs +124 -124
  138. package/scripts/smoke/provider-selection-status.mjs +52 -52
  139. package/scripts/smoke/run-state-refresh.mjs +52 -52
  140. package/scripts/smoke/runtime-manager.mjs +99 -99
  141. package/scripts/smoke/shell-manual-disconnect.mjs +30 -30
  142. package/scripts/smoke/side-panel-editor-layout.mjs +34 -34
  143. package/scripts/smoke/static-root-routing.mjs +21 -21
  144. package/scripts/smoke/strict-handoff-compact.mjs +60 -60
  145. package/scripts/smoke/taskmaster-config.mjs +24 -24
  146. package/scripts/smoke/taskmaster-execution-telegram.mjs +3 -3
  147. package/scripts/smoke/taskmaster-onboarding.mjs +3 -3
  148. package/scripts/smoke/taskmaster-run-graph.mjs +3 -3
  149. package/scripts/smoke/telegram-control.mjs +242 -242
  150. package/scripts/smoke/tunnel-persistence.mjs +56 -56
  151. package/scripts/smoke/update-issue-progress.mjs +69 -69
  152. package/scripts/smoke/update-ux.mjs +55 -55
  153. package/scripts/smoke/v138-completion.mjs +132 -132
  154. package/scripts/smoke/v138-desktop-release-hardening.mjs +69 -69
  155. package/scripts/smoke/v138-diagnostics.mjs +63 -63
  156. package/scripts/smoke/v138-issue-planner.mjs +33 -33
  157. package/scripts/smoke/v143-remote-control.mjs +76 -76
  158. package/scripts/smoke/v144-production-loop.mjs +47 -47
  159. package/scripts/smoke/v145-platformization.mjs +46 -46
  160. package/scripts/smoke/v146-control-room-ui.mjs +150 -150
  161. package/scripts/smoke/version-modal-autoshow.mjs +29 -29
  162. package/scripts/smoke/vscode-workbench-layout.mjs +63 -63
  163. package/scripts/smoke/vscode-workbench-polish.mjs +461 -436
  164. package/scripts/smoke/workflow-fallback-replay.mjs +56 -56
  165. package/scripts/smoke/workflow-templates.mjs +43 -43
  166. package/scripts/smoke/workflow-trace-timeline.mjs +46 -46
  167. package/scripts/update-git-install.mjs +293 -293
  168. package/server/claude-sdk.js +920 -920
  169. package/server/cli.js +1039 -1039
  170. package/server/constants/config.js +4 -4
  171. package/server/cursor-cli.js +344 -344
  172. package/server/daemon/manager.js +563 -563
  173. package/server/daemon-manager.js +964 -964
  174. package/server/database/db.js +908 -895
  175. package/server/database/json-store.js +197 -197
  176. package/server/gemini-cli.js +550 -550
  177. package/server/gemini-response-handler.js +79 -79
  178. package/server/index.js +201 -30
  179. package/server/load-env.js +35 -35
  180. package/server/middleware/auth.js +171 -156
  181. package/server/modules/orchestration/a2a/adapter-registry.ts +108 -108
  182. package/server/modules/orchestration/a2a/adapters/abstract-a2a.adapter.ts +63 -63
  183. package/server/modules/orchestration/a2a/adapters/claude-code.adapter.ts +286 -286
  184. package/server/modules/orchestration/a2a/adapters/codex.adapter.ts +244 -244
  185. package/server/modules/orchestration/a2a/adapters/cursor.adapter.ts +249 -249
  186. package/server/modules/orchestration/a2a/adapters/gemini.adapter.ts +248 -248
  187. package/server/modules/orchestration/a2a/adapters/json-event.adapter.test.ts +60 -0
  188. package/server/modules/orchestration/a2a/adapters/json-event.adapter.ts +101 -0
  189. package/server/modules/orchestration/a2a/adapters/opencode.adapter.ts +248 -248
  190. package/server/modules/orchestration/a2a/adapters/qwen.adapter.ts +248 -248
  191. package/server/modules/orchestration/a2a/agent-card.ts +55 -55
  192. package/server/modules/orchestration/a2a/routes.ts +590 -590
  193. package/server/modules/orchestration/a2a/task-store.ts +178 -178
  194. package/server/modules/orchestration/a2a/types.ts +126 -126
  195. package/server/modules/orchestration/a2a/validator.ts +113 -113
  196. package/server/modules/orchestration/hermes/hermes.routes.ts +642 -583
  197. package/server/modules/orchestration/index.ts +101 -100
  198. package/server/modules/orchestration/preview/port-watcher.ts +112 -112
  199. package/server/modules/orchestration/preview/preview-proxy.ts +60 -60
  200. package/server/modules/orchestration/preview/types.ts +19 -19
  201. package/server/modules/orchestration/security/permission-policy.ts +401 -401
  202. package/server/modules/orchestration/tasks/orchestration-task-store.ts +41 -41
  203. package/server/modules/orchestration/tasks/orchestration-task.routes.ts +64 -64
  204. package/server/modules/orchestration/tasks/orchestration-task.service.ts +209 -209
  205. package/server/modules/orchestration/tasks/orchestration-task.types.ts +40 -40
  206. package/server/modules/orchestration/tasks/task-run-graph.ts +155 -155
  207. package/server/modules/orchestration/workflows/approval-queue.ts +106 -106
  208. package/server/modules/orchestration/workflows/built-in-workflows.ts +127 -127
  209. package/server/modules/orchestration/workflows/context-packet.ts +186 -186
  210. package/server/modules/orchestration/workflows/handoff-artifact.ts +175 -175
  211. package/server/modules/orchestration/workflows/workflow-fallback-policy.ts +161 -161
  212. package/server/modules/orchestration/workflows/workflow-replay.ts +254 -254
  213. package/server/modules/orchestration/workflows/workflow-runner.ts +2070 -2070
  214. package/server/modules/orchestration/workflows/workflow-store.ts +97 -97
  215. package/server/modules/orchestration/workflows/workflow-templates.ts +272 -272
  216. package/server/modules/orchestration/workflows/workflow-trace.ts +424 -424
  217. package/server/modules/orchestration/workflows/workflow.routes.ts +586 -586
  218. package/server/modules/orchestration/workflows/workflow.types.ts +111 -111
  219. package/server/modules/orchestration/workflows/workspace-target.ts +122 -122
  220. package/server/modules/orchestration/workspace/docker-workspace.ts +136 -136
  221. package/server/modules/orchestration/workspace/path-safety.ts +55 -55
  222. package/server/modules/orchestration/workspace/types.ts +52 -52
  223. package/server/modules/orchestration/workspace/workspace-manager.ts +102 -102
  224. package/server/modules/orchestration/workspace/worktree-workspace.ts +126 -126
  225. package/server/modules/providers/index.ts +2 -2
  226. package/server/modules/providers/list/claude/claude-auth.provider.ts +146 -146
  227. package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -135
  228. package/server/modules/providers/list/claude/claude-sessions.provider.ts +306 -306
  229. package/server/modules/providers/list/claude/claude.provider.ts +15 -15
  230. package/server/modules/providers/list/codex/codex-auth.provider.ts +117 -117
  231. package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -135
  232. package/server/modules/providers/list/codex/codex-sessions.provider.ts +319 -319
  233. package/server/modules/providers/list/codex/codex.provider.ts +15 -15
  234. package/server/modules/providers/list/cursor/cursor-auth.provider.ts +147 -147
  235. package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -108
  236. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +421 -421
  237. package/server/modules/providers/list/cursor/cursor.provider.ts +15 -15
  238. package/server/modules/providers/list/gemini/gemini-auth.provider.ts +173 -173
  239. package/server/modules/providers/list/gemini/gemini-mcp.provider.ts +110 -110
  240. package/server/modules/providers/list/gemini/gemini-sessions.provider.ts +227 -227
  241. package/server/modules/providers/list/gemini/gemini.provider.ts +15 -15
  242. package/server/modules/providers/list/opencode/opencode-auth.provider.ts +131 -131
  243. package/server/modules/providers/list/opencode/opencode-mcp.provider.ts +126 -126
  244. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +286 -286
  245. package/server/modules/providers/list/opencode/opencode.provider.ts +29 -29
  246. package/server/modules/providers/list/qwen/qwen-auth.provider.ts +146 -146
  247. package/server/modules/providers/list/qwen/qwen-mcp.provider.ts +114 -114
  248. package/server/modules/providers/list/qwen/qwen-sessions.provider.ts +265 -265
  249. package/server/modules/providers/list/qwen/qwen.provider.ts +21 -21
  250. package/server/modules/providers/provider.registry.ts +40 -40
  251. package/server/modules/providers/provider.routes.ts +944 -944
  252. package/server/modules/providers/services/mcp.service.ts +86 -86
  253. package/server/modules/providers/services/provider-auth.service.ts +26 -26
  254. package/server/modules/providers/services/sessions.service.ts +45 -45
  255. package/server/modules/providers/shared/base/abstract.provider.ts +20 -20
  256. package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -151
  257. package/server/modules/providers/shared/provider-configs.ts +142 -142
  258. package/server/modules/providers/tests/mcp.test.ts +293 -293
  259. package/server/openai-codex.js +462 -462
  260. package/server/opencode-cli.js +491 -491
  261. package/server/opencode-response-handler.js +111 -111
  262. package/server/projects.js +3008 -3008
  263. package/server/qwen-code-cli.js +410 -410
  264. package/server/qwen-response-handler.js +73 -73
  265. package/server/routes/agent.js +1435 -1435
  266. package/server/routes/auth.js +154 -146
  267. package/server/routes/codex.js +20 -20
  268. package/server/routes/commands.js +570 -570
  269. package/server/routes/cursor.js +61 -61
  270. package/server/routes/diagnostics.js +41 -41
  271. package/server/routes/gemini.js +25 -25
  272. package/server/routes/git.js +1650 -1635
  273. package/server/routes/live-view.js +411 -411
  274. package/server/routes/mcp-utils.js +13 -13
  275. package/server/routes/messages.js +62 -62
  276. package/server/routes/network.js +125 -125
  277. package/server/routes/platformization.js +198 -197
  278. package/server/routes/plugins.js +320 -320
  279. package/server/routes/production-agent-loop.js +90 -90
  280. package/server/routes/projects.js +917 -917
  281. package/server/routes/public-api.js +34 -34
  282. package/server/routes/qwen.js +27 -27
  283. package/server/routes/remote.js +55 -55
  284. package/server/routes/settings.js +321 -321
  285. package/server/routes/telegram.js +140 -140
  286. package/server/routes/user.js +125 -125
  287. package/server/routes/webhooks.js +63 -63
  288. package/server/services/control-room.js +102 -102
  289. package/server/services/diagnostics.js +165 -165
  290. package/server/services/external-access.js +375 -375
  291. package/server/services/hermes-gateway.js +1562 -1247
  292. package/server/services/hermes-install-jobs.js +729 -729
  293. package/server/services/install-jobs.js +715 -715
  294. package/server/services/live-view.js +956 -956
  295. package/server/services/managed-runtimes.js +493 -493
  296. package/server/services/model-registry.js +144 -144
  297. package/server/services/notification-orchestrator.js +365 -365
  298. package/server/services/notification-taxonomy.js +204 -204
  299. package/server/services/platformization.js +844 -779
  300. package/server/services/production-agent-loop.js +248 -248
  301. package/server/services/provider-cli-versions.js +149 -149
  302. package/server/services/provider-credentials.js +189 -189
  303. package/server/services/provider-models.js +396 -396
  304. package/server/services/public-api-manifest.js +190 -182
  305. package/server/services/remote-connection.js +127 -127
  306. package/server/services/runtime-manager.js +323 -323
  307. package/server/services/startup-update.js +234 -234
  308. package/server/services/telegram/bot.js +331 -331
  309. package/server/services/telegram/control-center.js +979 -979
  310. package/server/services/telegram/telegram-http-client.js +151 -151
  311. package/server/services/telegram/translations.js +340 -340
  312. package/server/services/vapid-keys.js +36 -36
  313. package/server/services/webhooks.js +216 -216
  314. package/server/sessionManager.js +225 -225
  315. package/server/shared/interfaces.ts +54 -54
  316. package/server/shared/types.ts +172 -172
  317. package/server/shared/utils.ts +193 -193
  318. package/server/tsconfig.json +36 -36
  319. package/server/utils/colors.js +21 -21
  320. package/server/utils/commandParser.js +305 -305
  321. package/server/utils/frontmatter.js +18 -18
  322. package/server/utils/gitConfig.js +34 -34
  323. package/server/utils/plugin-loader.js +457 -457
  324. package/server/utils/plugin-process-manager.js +185 -185
  325. package/server/utils/port-access.js +209 -209
  326. package/server/utils/runtime-paths.js +37 -37
  327. package/server/utils/url-detection.js +71 -71
  328. package/server/vite-daemon.js +79 -79
  329. package/shared/modelConstants.js +161 -161
  330. package/shared/networkHosts.js +22 -22
  331. package/dist/assets/index-DMz0zv6T.css +0 -32
@@ -1,351 +1,351 @@
1
- #!/usr/bin/env node
2
- import fs from 'node:fs';
3
- import https from 'node:https';
4
- import { fileURLToPath } from 'node:url';
5
-
6
- const OWNER = 'alicomert';
7
- const REPO = 'pixcode';
8
- const TRACKING_FILE = 'RELEASE_TRACKING_v1.38.md';
9
-
10
- const issues = [
11
- {
12
- key: 'remote',
13
- placeholder: 'GH-TBD-remote',
14
- title: 'feat(remote): add first-run local/remote connection mode and API URL pairing',
15
- body: [
16
- '## Problem',
17
- 'Pixcode can run on a server, desktop, or local machine, but first-run setup still assumes the current machine is the primary runtime. Users need to choose whether they are using this computer directly or connecting to a remote Pixcode server.',
18
- '',
19
- '## Goal',
20
- 'Add a first-run connection mode before normal setup and update checks: local computer mode or remote server mode. Remote mode should accept an API URL, handle login/register/pairing, show connection health, and keep the app usable when the controlled server continues running.',
21
- '',
22
- '## Requirements',
23
- '- Ask local vs remote before normal onboarding and before startup update flow.',
24
- '- Remote mode accepts server URL and API key/session credentials.',
25
- '- If login/register is needed, guide the user inside the app instead of failing silently.',
26
- '- Show a full-width connection warning when the remote server is unreachable or degraded.',
27
- '- Persist the selected mode and allow changing it from Settings.',
28
- '- Keep update checks and release notes aware of the selected runtime.',
29
- '',
30
- '## Acceptance Criteria',
31
- '- New users can choose remote mode and connect to an existing Pixcode server.',
32
- '- A disconnected remote server shows a clear banner and retry action.',
33
- '- Local mode behavior remains unchanged.',
34
- '- Smoke coverage verifies local/remote mode persistence and health banner behavior.',
35
- ].join('\n'),
36
- },
37
- {
38
- key: 'api',
39
- placeholder: 'GH-TBD-api',
40
- title: 'feat(api): expose complete Pixcode control surface through API keys',
41
- body: [
42
- '## Problem',
43
- 'Pixcode has many internal endpoints, but users need a clean public API model so every major feature can be automated from external clients, scripts, Telegram, or another UI.',
44
- '',
45
- '## Goal',
46
- 'Create a stable API key and base URL system that exposes projects, sessions, providers, orchestration, tasks, files, source-control state, notifications, and settings through documented endpoints.',
47
- '',
48
- '## Requirements',
49
- '- Define public API groups for auth, projects, sessions, provider runs, orchestration, Taskmaster tasks, notifications, files, git/source-control, settings, and update status.',
50
- '- Keep px_ API key prefix and support scoped/revocable keys.',
51
- '- Add OpenAPI coverage for the public routes.',
52
- '- Ensure Telegram and future remote clients use the same API/service layer instead of separate logic.',
53
- '- Add rate limits and audit records for sensitive actions.',
54
- '',
55
- '## Acceptance Criteria',
56
- '- A user can operate core Pixcode flows using API URL + API key without the web UI.',
57
- '- OpenAPI docs include authenticated examples.',
58
- '- Invalid/missing scopes produce clear 401/403 responses.',
59
- '- Smoke coverage validates at least one full API-key flow: create/list project -> run provider prompt -> fetch result.',
60
- ].join('\n'),
61
- },
62
- {
63
- key: 'telegram',
64
- placeholder: 'GH-TBD-telegram',
65
- title: 'feat(telegram): reach web UI feature parity for remote control',
66
- body: [
67
- '## Problem',
68
- 'Telegram control exists, but the long-term product goal is to manage Pixcode without opening the web UI. Telegram should not be just completion notifications or simple forwarding.',
69
- '',
70
- '## Goal',
71
- 'Make Telegram a first-class Pixcode control client for sessions, projects, providers, models, orchestration, Taskmaster, settings, notifications, and progress/output preferences.',
72
- '',
73
- '## Requirements',
74
- '- Add structured menus for active sessions, new chat, existing project, provider/model selection, orchestration workflows, Taskmaster tasks, and settings.',
75
- '- Let users choose notification granularity: final result only, step summaries, all agent outputs, errors only.',
76
- '- Allow selecting active worker slot and project from Telegram.',
77
- '- Support task creation/start/stop/status from Telegram.',
78
- '- Keep inline menus edited in place to avoid chat spam.',
79
- '- Respect user language preference across every menu.',
80
- '',
81
- '## Acceptance Criteria',
82
- '- A linked Telegram user can start an orchestration run and monitor it without the web UI.',
83
- '- A linked Telegram user can create and run a Taskmaster task.',
84
- '- Telegram can switch active project/session/provider/model.',
85
- '- Smoke coverage verifies command routing, callback routing, language, and task/run status messages.',
86
- ].join('\n'),
87
- },
88
- {
89
- key: 'taskmaster',
90
- placeholder: 'GH-TBD-taskmaster',
91
- title: 'feat(tasks): make Taskmaster the shared execution queue for CLI agents',
92
- body: [
93
- '## Problem',
94
- 'Taskmaster setup and Telegram execution foundations exist, but tasks are not yet the shared queue that coordinates all CLI agents and long-running project work.',
95
- '',
96
- '## Goal',
97
- 'Make Taskmaster a first-class execution backbone: create tasks, assign provider/model, run until completion, update progress, retry/fallback on errors, and expose the same state in UI, API, and Telegram.',
98
- '',
99
- '## Requirements',
100
- '- Add task create/edit/list/detail flows in the web UI.',
101
- '- Bind tasks to project path, provider, model, permission mode, fallback provider, and worker slot.',
102
- '- Persist step summaries, final output, failure reasons, and changed files per task.',
103
- '- Support retry, pause/cancel, fallback, and continue-from-last-output.',
104
- '- Emit notifications for task started, waiting, completed, failed, fallback used.',
105
- '- Make Telegram and API operate the same task model.',
106
- '',
107
- '## Acceptance Criteria',
108
- '- A task can be created in UI/API/Telegram and run by a selected CLI provider.',
109
- '- Failed provider execution can route to configured fallback.',
110
- '- Task detail shows progress, outputs, changed files, and final summary.',
111
- '- Smoke coverage validates create -> dispatch -> progress -> completion/failure state.',
112
- ].join('\n'),
113
- },
114
- {
115
- key: 'plugins',
116
- placeholder: 'GH-TBD-plugins',
117
- title: 'feat(providers): expose CLI plugin and external tool configuration',
118
- body: [
119
- '## Problem',
120
- 'Claude, Codex, OpenCode, Gemini, Qwen, and Cursor have their own plugin/MCP/tool configuration surfaces, but Pixcode does not yet make those external configurations visible and manageable in one place.',
121
- '',
122
- '## Goal',
123
- 'Add provider plugin/tool configuration management so users can inspect, enable, disable, update, and validate provider-specific plugins/MCP/tool integrations without leaving Pixcode.',
124
- '',
125
- '## Requirements',
126
- '- Detect provider-specific plugin/tool config locations where supported.',
127
- '- Show installed/available plugin state per provider.',
128
- '- Allow safe enable/disable/update with preview and backup.',
129
- '- Add validation and repair hints for broken plugin configs.',
130
- '- Avoid IDE-specific integrations unless explicitly requested.',
131
- '- Keep secrets redacted.',
132
- '',
133
- '## Acceptance Criteria',
134
- '- Settings shows provider plugin/tool state without slow repeated checks.',
135
- '- Users can refresh plugin state manually.',
136
- '- Broken config produces actionable diagnostics.',
137
- '- Smoke coverage validates config discovery/parsing for sample provider configs.',
138
- ].join('\n'),
139
- },
140
- {
141
- key: 'desktop',
142
- placeholder: 'GH-TBD-desktop',
143
- title: 'build(desktop): harden installer release, signing, and update recovery',
144
- body: [
145
- '## Problem',
146
- 'Desktop installers build, but macOS unsigned-app warnings, release artifact confidence, and update recovery need a dedicated release-hardening pass.',
147
- '',
148
- '## Goal',
149
- 'Improve desktop release quality for .exe, .dmg, and AppImage users while keeping npm/server update recovery reliable.',
150
- '',
151
- '## Requirements',
152
- '- Document and/or implement macOS signing/notarization path.',
153
- '- Surface unsigned macOS warning guidance in README/release docs until signing is complete.',
154
- '- Verify installer artifacts against the app version and bundled Pixcode dependency.',
155
- '- Keep startup update/recovery visible to users.',
156
- '- Add release checklist coverage for desktop artifacts.',
157
- '',
158
- '## Acceptance Criteria',
159
- '- Desktop artifact versions match package version.',
160
- '- Release notes clearly explain macOS unsigned behavior until signing is complete.',
161
- '- Installer build workflow status is tracked as part of release readiness.',
162
- '- Smoke or script coverage verifies desktop package version alignment.',
163
- ].join('\n'),
164
- },
165
- {
166
- key: 'observability',
167
- placeholder: 'GH-TBD-observability',
168
- title: 'feat(observability): add run diagnostics and provider health visibility',
169
- body: [
170
- '## Problem',
171
- 'When a provider, workflow, Telegram action, or task stalls, users need a clear reason instead of guessing from blank screens or network panels.',
172
- '',
173
- '## Goal',
174
- 'Add a diagnostics surface that explains provider availability, run state, queued work, recent errors, CLI auth/install status, WebSocket health, and notification delivery.',
175
- '',
176
- '## Requirements',
177
- '- Add a diagnostics page/panel for provider health, active runs, WebSocket state, notification channel status, and recent errors.',
178
- '- Add lightweight server-side event/error records for provider runs and workflow tasks.',
179
- '- Show stalled/waiting/error states in user language.',
180
- '- Add manual refresh instead of expensive repeated checks.',
181
- '- Include copyable diagnostics bundle for support/debugging.',
182
- '',
183
- '## Acceptance Criteria',
184
- '- Users can see why a CLI is unavailable or why a run is waiting.',
185
- '- Settings no longer blocks on repeated provider checks.',
186
- '- Diagnostics can be copied without leaking secrets.',
187
- '- Smoke coverage validates health-state aggregation and secret redaction.',
188
- ].join('\n'),
189
- },
190
- ];
191
-
192
- function buildPayload(issueNumbers = new Map()) {
193
- const scope = issues
194
- .map(issue => {
195
- const reference = issueNumbers.has(issue.key) ? `#${issueNumbers.get(issue.key)}` : issue.placeholder;
196
- return `- ${reference} ${issue.title}`;
197
- })
198
- .join('\n');
199
-
200
- const epic = {
201
- key: 'epic',
202
- placeholder: 'GH-TBD-epic',
203
- title: 'epic(product): track v1.38 remote API and task operations',
204
- body: [
205
- '## Goal',
206
- 'Track the v1.38 remote-control, API, task, provider, desktop, and diagnostics package as a GitHub-native work plan. v1.37 shipped the orchestration reliability foundation; v1.38 should make Pixcode easier to operate remotely, automate externally, and diagnose confidently.',
207
- '',
208
- '## Scope',
209
- scope,
210
- '',
211
- '## Release Strategy',
212
- '1. Stabilize remote/local first-run mode and public API foundation.',
213
- '2. Build Telegram and Taskmaster on the same API/task service model.',
214
- '3. Add provider plugin/tool configuration visibility and diagnostics.',
215
- '4. Harden desktop installer/signing/update recovery paths.',
216
- '5. Ship release notes with issue-backed progress metadata.',
217
- '',
218
- '## Acceptance Criteria',
219
- '- Each child issue has implementation and smoke coverage before closure.',
220
- '- The v1.38 release notes reference completed issue numbers.',
221
- '- Update UI can show issue-backed progress for v1.38.',
222
- '- API/Telegram/Taskmaster work share service contracts instead of divergent behavior.',
223
- ].join('\n'),
224
- };
225
-
226
- return {
227
- version: '1.38',
228
- owner: OWNER,
229
- repo: REPO,
230
- issues,
231
- epic,
232
- trackingReplacements: [
233
- ...issues.map(issue => ({
234
- placeholder: issue.placeholder,
235
- value: issueNumbers.has(issue.key) ? `#${issueNumbers.get(issue.key)}` : issue.placeholder,
236
- })),
237
- {
238
- placeholder: epic.placeholder,
239
- value: issueNumbers.has('epic') ? `#${issueNumbers.get('epic')}` : epic.placeholder,
240
- },
241
- ],
242
- };
243
- }
244
-
245
- function githubRequest(method, path, payload) {
246
- const token = process.env.GITHUB_TOKEN;
247
- if (!token) {
248
- throw new Error('GITHUB_TOKEN is required for --apply');
249
- }
250
-
251
- const data = payload ? JSON.stringify(payload) : undefined;
252
- return new Promise((resolve, reject) => {
253
- const req = https.request({
254
- hostname: 'api.github.com',
255
- path,
256
- method,
257
- headers: {
258
- Authorization: `Bearer ${token}`,
259
- Accept: 'application/vnd.github+json',
260
- 'User-Agent': 'pixcode-v138-issue-planner',
261
- 'X-GitHub-Api-Version': '2022-11-28',
262
- ...(data ? { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) } : {}),
263
- },
264
- }, res => {
265
- let raw = '';
266
- res.setEncoding('utf8');
267
- res.on('data', chunk => {
268
- raw += chunk;
269
- });
270
- res.on('end', () => {
271
- if (res.statusCode >= 200 && res.statusCode < 300) {
272
- resolve(raw ? JSON.parse(raw) : null);
273
- return;
274
- }
275
- reject(new Error(`${method} ${path} -> ${res.statusCode}: ${raw}`));
276
- });
277
- });
278
- req.on('error', reject);
279
- if (data) {
280
- req.write(data);
281
- }
282
- req.end();
283
- });
284
- }
285
-
286
- async function findExistingIssue(title) {
287
- const q = encodeURIComponent(`repo:${OWNER}/${REPO} type:issue in:title "${title}"`);
288
- const result = await githubRequest('GET', `/search/issues?q=${q}&per_page=10`);
289
- return result.items?.find(item => item.title === title) || null;
290
- }
291
-
292
- async function createOrReuseIssue(issue) {
293
- const existing = await findExistingIssue(issue.title);
294
- if (existing) {
295
- return existing;
296
- }
297
- return await githubRequest('POST', `/repos/${OWNER}/${REPO}/issues`, {
298
- title: issue.title,
299
- body: issue.body,
300
- });
301
- }
302
-
303
- function writeTracking(payload) {
304
- let content = fs.readFileSync(TRACKING_FILE, 'utf8');
305
- for (const replacement of payload.trackingReplacements) {
306
- content = content.replaceAll(replacement.placeholder, replacement.value);
307
- }
308
- fs.writeFileSync(TRACKING_FILE, content);
309
- }
310
-
311
- async function main() {
312
- const args = new Set(process.argv.slice(2));
313
- const dryRun = args.has('--dry-run') || !args.has('--apply');
314
- const shouldWriteTracking = args.has('--write-tracking') || args.has('--apply');
315
-
316
- if (dryRun) {
317
- process.stdout.write(`${JSON.stringify(buildPayload(), null, 2)}\n`);
318
- return;
319
- }
320
-
321
- const numbers = new Map();
322
- for (const issue of issues) {
323
- const created = await createOrReuseIssue(issue);
324
- numbers.set(issue.key, created.number);
325
- console.log(`#${created.number} ${created.title}`);
326
- }
327
-
328
- const payloadBeforeEpic = buildPayload(numbers);
329
- const epic = await createOrReuseIssue(payloadBeforeEpic.epic);
330
- numbers.set('epic', epic.number);
331
- console.log(`#${epic.number} ${epic.title}`);
332
-
333
- const finalPayload = buildPayload(numbers);
334
- if (shouldWriteTracking) {
335
- writeTracking(finalPayload);
336
- console.log(`${TRACKING_FILE} updated`);
337
- }
338
- }
339
-
340
- const invokedPath = process.argv[1] ? fileURLToPath(import.meta.url) === process.argv[1] : false;
341
- if (invokedPath) {
342
- try {
343
- await main();
344
- } catch (error) {
345
- const message = error instanceof Error ? error.message : String(error);
346
- console.error(`Failed to create v1.38 issues: ${message}`);
347
- process.exitCode = 1;
348
- }
349
- }
350
-
351
- export { buildPayload, issues };
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import https from 'node:https';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const OWNER = 'alicomert';
7
+ const REPO = 'pixcode';
8
+ const TRACKING_FILE = 'RELEASE_TRACKING_v1.38.md';
9
+
10
+ const issues = [
11
+ {
12
+ key: 'remote',
13
+ placeholder: 'GH-TBD-remote',
14
+ title: 'feat(remote): add first-run local/remote connection mode and API URL pairing',
15
+ body: [
16
+ '## Problem',
17
+ 'Pixcode can run on a server, desktop, or local machine, but first-run setup still assumes the current machine is the primary runtime. Users need to choose whether they are using this computer directly or connecting to a remote Pixcode server.',
18
+ '',
19
+ '## Goal',
20
+ 'Add a first-run connection mode before normal setup and update checks: local computer mode or remote server mode. Remote mode should accept an API URL, handle login/register/pairing, show connection health, and keep the app usable when the controlled server continues running.',
21
+ '',
22
+ '## Requirements',
23
+ '- Ask local vs remote before normal onboarding and before startup update flow.',
24
+ '- Remote mode accepts server URL and API key/session credentials.',
25
+ '- If login/register is needed, guide the user inside the app instead of failing silently.',
26
+ '- Show a full-width connection warning when the remote server is unreachable or degraded.',
27
+ '- Persist the selected mode and allow changing it from Settings.',
28
+ '- Keep update checks and release notes aware of the selected runtime.',
29
+ '',
30
+ '## Acceptance Criteria',
31
+ '- New users can choose remote mode and connect to an existing Pixcode server.',
32
+ '- A disconnected remote server shows a clear banner and retry action.',
33
+ '- Local mode behavior remains unchanged.',
34
+ '- Smoke coverage verifies local/remote mode persistence and health banner behavior.',
35
+ ].join('\n'),
36
+ },
37
+ {
38
+ key: 'api',
39
+ placeholder: 'GH-TBD-api',
40
+ title: 'feat(api): expose complete Pixcode control surface through API keys',
41
+ body: [
42
+ '## Problem',
43
+ 'Pixcode has many internal endpoints, but users need a clean public API model so every major feature can be automated from external clients, scripts, Telegram, or another UI.',
44
+ '',
45
+ '## Goal',
46
+ 'Create a stable API key and base URL system that exposes projects, sessions, providers, orchestration, tasks, files, source-control state, notifications, and settings through documented endpoints.',
47
+ '',
48
+ '## Requirements',
49
+ '- Define public API groups for auth, projects, sessions, provider runs, orchestration, Taskmaster tasks, notifications, files, git/source-control, settings, and update status.',
50
+ '- Keep px_ API key prefix and support scoped/revocable keys.',
51
+ '- Add OpenAPI coverage for the public routes.',
52
+ '- Ensure Telegram and future remote clients use the same API/service layer instead of separate logic.',
53
+ '- Add rate limits and audit records for sensitive actions.',
54
+ '',
55
+ '## Acceptance Criteria',
56
+ '- A user can operate core Pixcode flows using API URL + API key without the web UI.',
57
+ '- OpenAPI docs include authenticated examples.',
58
+ '- Invalid/missing scopes produce clear 401/403 responses.',
59
+ '- Smoke coverage validates at least one full API-key flow: create/list project -> run provider prompt -> fetch result.',
60
+ ].join('\n'),
61
+ },
62
+ {
63
+ key: 'telegram',
64
+ placeholder: 'GH-TBD-telegram',
65
+ title: 'feat(telegram): reach web UI feature parity for remote control',
66
+ body: [
67
+ '## Problem',
68
+ 'Telegram control exists, but the long-term product goal is to manage Pixcode without opening the web UI. Telegram should not be just completion notifications or simple forwarding.',
69
+ '',
70
+ '## Goal',
71
+ 'Make Telegram a first-class Pixcode control client for sessions, projects, providers, models, orchestration, Taskmaster, settings, notifications, and progress/output preferences.',
72
+ '',
73
+ '## Requirements',
74
+ '- Add structured menus for active sessions, new chat, existing project, provider/model selection, orchestration workflows, Taskmaster tasks, and settings.',
75
+ '- Let users choose notification granularity: final result only, step summaries, all agent outputs, errors only.',
76
+ '- Allow selecting active worker slot and project from Telegram.',
77
+ '- Support task creation/start/stop/status from Telegram.',
78
+ '- Keep inline menus edited in place to avoid chat spam.',
79
+ '- Respect user language preference across every menu.',
80
+ '',
81
+ '## Acceptance Criteria',
82
+ '- A linked Telegram user can start an orchestration run and monitor it without the web UI.',
83
+ '- A linked Telegram user can create and run a Taskmaster task.',
84
+ '- Telegram can switch active project/session/provider/model.',
85
+ '- Smoke coverage verifies command routing, callback routing, language, and task/run status messages.',
86
+ ].join('\n'),
87
+ },
88
+ {
89
+ key: 'taskmaster',
90
+ placeholder: 'GH-TBD-taskmaster',
91
+ title: 'feat(tasks): make Taskmaster the shared execution queue for CLI agents',
92
+ body: [
93
+ '## Problem',
94
+ 'Taskmaster setup and Telegram execution foundations exist, but tasks are not yet the shared queue that coordinates all CLI agents and long-running project work.',
95
+ '',
96
+ '## Goal',
97
+ 'Make Taskmaster a first-class execution backbone: create tasks, assign provider/model, run until completion, update progress, retry/fallback on errors, and expose the same state in UI, API, and Telegram.',
98
+ '',
99
+ '## Requirements',
100
+ '- Add task create/edit/list/detail flows in the web UI.',
101
+ '- Bind tasks to project path, provider, model, permission mode, fallback provider, and worker slot.',
102
+ '- Persist step summaries, final output, failure reasons, and changed files per task.',
103
+ '- Support retry, pause/cancel, fallback, and continue-from-last-output.',
104
+ '- Emit notifications for task started, waiting, completed, failed, fallback used.',
105
+ '- Make Telegram and API operate the same task model.',
106
+ '',
107
+ '## Acceptance Criteria',
108
+ '- A task can be created in UI/API/Telegram and run by a selected CLI provider.',
109
+ '- Failed provider execution can route to configured fallback.',
110
+ '- Task detail shows progress, outputs, changed files, and final summary.',
111
+ '- Smoke coverage validates create -> dispatch -> progress -> completion/failure state.',
112
+ ].join('\n'),
113
+ },
114
+ {
115
+ key: 'plugins',
116
+ placeholder: 'GH-TBD-plugins',
117
+ title: 'feat(providers): expose CLI plugin and external tool configuration',
118
+ body: [
119
+ '## Problem',
120
+ 'Claude, Codex, OpenCode, Gemini, Qwen, and Cursor have their own plugin/MCP/tool configuration surfaces, but Pixcode does not yet make those external configurations visible and manageable in one place.',
121
+ '',
122
+ '## Goal',
123
+ 'Add provider plugin/tool configuration management so users can inspect, enable, disable, update, and validate provider-specific plugins/MCP/tool integrations without leaving Pixcode.',
124
+ '',
125
+ '## Requirements',
126
+ '- Detect provider-specific plugin/tool config locations where supported.',
127
+ '- Show installed/available plugin state per provider.',
128
+ '- Allow safe enable/disable/update with preview and backup.',
129
+ '- Add validation and repair hints for broken plugin configs.',
130
+ '- Avoid IDE-specific integrations unless explicitly requested.',
131
+ '- Keep secrets redacted.',
132
+ '',
133
+ '## Acceptance Criteria',
134
+ '- Settings shows provider plugin/tool state without slow repeated checks.',
135
+ '- Users can refresh plugin state manually.',
136
+ '- Broken config produces actionable diagnostics.',
137
+ '- Smoke coverage validates config discovery/parsing for sample provider configs.',
138
+ ].join('\n'),
139
+ },
140
+ {
141
+ key: 'desktop',
142
+ placeholder: 'GH-TBD-desktop',
143
+ title: 'build(desktop): harden installer release, signing, and update recovery',
144
+ body: [
145
+ '## Problem',
146
+ 'Desktop installers build, but macOS unsigned-app warnings, release artifact confidence, and update recovery need a dedicated release-hardening pass.',
147
+ '',
148
+ '## Goal',
149
+ 'Improve desktop release quality for .exe, .dmg, and AppImage users while keeping npm/server update recovery reliable.',
150
+ '',
151
+ '## Requirements',
152
+ '- Document and/or implement macOS signing/notarization path.',
153
+ '- Surface unsigned macOS warning guidance in README/release docs until signing is complete.',
154
+ '- Verify installer artifacts against the app version and bundled Pixcode dependency.',
155
+ '- Keep startup update/recovery visible to users.',
156
+ '- Add release checklist coverage for desktop artifacts.',
157
+ '',
158
+ '## Acceptance Criteria',
159
+ '- Desktop artifact versions match package version.',
160
+ '- Release notes clearly explain macOS unsigned behavior until signing is complete.',
161
+ '- Installer build workflow status is tracked as part of release readiness.',
162
+ '- Smoke or script coverage verifies desktop package version alignment.',
163
+ ].join('\n'),
164
+ },
165
+ {
166
+ key: 'observability',
167
+ placeholder: 'GH-TBD-observability',
168
+ title: 'feat(observability): add run diagnostics and provider health visibility',
169
+ body: [
170
+ '## Problem',
171
+ 'When a provider, workflow, Telegram action, or task stalls, users need a clear reason instead of guessing from blank screens or network panels.',
172
+ '',
173
+ '## Goal',
174
+ 'Add a diagnostics surface that explains provider availability, run state, queued work, recent errors, CLI auth/install status, WebSocket health, and notification delivery.',
175
+ '',
176
+ '## Requirements',
177
+ '- Add a diagnostics page/panel for provider health, active runs, WebSocket state, notification channel status, and recent errors.',
178
+ '- Add lightweight server-side event/error records for provider runs and workflow tasks.',
179
+ '- Show stalled/waiting/error states in user language.',
180
+ '- Add manual refresh instead of expensive repeated checks.',
181
+ '- Include copyable diagnostics bundle for support/debugging.',
182
+ '',
183
+ '## Acceptance Criteria',
184
+ '- Users can see why a CLI is unavailable or why a run is waiting.',
185
+ '- Settings no longer blocks on repeated provider checks.',
186
+ '- Diagnostics can be copied without leaking secrets.',
187
+ '- Smoke coverage validates health-state aggregation and secret redaction.',
188
+ ].join('\n'),
189
+ },
190
+ ];
191
+
192
+ function buildPayload(issueNumbers = new Map()) {
193
+ const scope = issues
194
+ .map(issue => {
195
+ const reference = issueNumbers.has(issue.key) ? `#${issueNumbers.get(issue.key)}` : issue.placeholder;
196
+ return `- ${reference} ${issue.title}`;
197
+ })
198
+ .join('\n');
199
+
200
+ const epic = {
201
+ key: 'epic',
202
+ placeholder: 'GH-TBD-epic',
203
+ title: 'epic(product): track v1.38 remote API and task operations',
204
+ body: [
205
+ '## Goal',
206
+ 'Track the v1.38 remote-control, API, task, provider, desktop, and diagnostics package as a GitHub-native work plan. v1.37 shipped the orchestration reliability foundation; v1.38 should make Pixcode easier to operate remotely, automate externally, and diagnose confidently.',
207
+ '',
208
+ '## Scope',
209
+ scope,
210
+ '',
211
+ '## Release Strategy',
212
+ '1. Stabilize remote/local first-run mode and public API foundation.',
213
+ '2. Build Telegram and Taskmaster on the same API/task service model.',
214
+ '3. Add provider plugin/tool configuration visibility and diagnostics.',
215
+ '4. Harden desktop installer/signing/update recovery paths.',
216
+ '5. Ship release notes with issue-backed progress metadata.',
217
+ '',
218
+ '## Acceptance Criteria',
219
+ '- Each child issue has implementation and smoke coverage before closure.',
220
+ '- The v1.38 release notes reference completed issue numbers.',
221
+ '- Update UI can show issue-backed progress for v1.38.',
222
+ '- API/Telegram/Taskmaster work share service contracts instead of divergent behavior.',
223
+ ].join('\n'),
224
+ };
225
+
226
+ return {
227
+ version: '1.38',
228
+ owner: OWNER,
229
+ repo: REPO,
230
+ issues,
231
+ epic,
232
+ trackingReplacements: [
233
+ ...issues.map(issue => ({
234
+ placeholder: issue.placeholder,
235
+ value: issueNumbers.has(issue.key) ? `#${issueNumbers.get(issue.key)}` : issue.placeholder,
236
+ })),
237
+ {
238
+ placeholder: epic.placeholder,
239
+ value: issueNumbers.has('epic') ? `#${issueNumbers.get('epic')}` : epic.placeholder,
240
+ },
241
+ ],
242
+ };
243
+ }
244
+
245
+ function githubRequest(method, path, payload) {
246
+ const token = process.env.GITHUB_TOKEN;
247
+ if (!token) {
248
+ throw new Error('GITHUB_TOKEN is required for --apply');
249
+ }
250
+
251
+ const data = payload ? JSON.stringify(payload) : undefined;
252
+ return new Promise((resolve, reject) => {
253
+ const req = https.request({
254
+ hostname: 'api.github.com',
255
+ path,
256
+ method,
257
+ headers: {
258
+ Authorization: `Bearer ${token}`,
259
+ Accept: 'application/vnd.github+json',
260
+ 'User-Agent': 'pixcode-v138-issue-planner',
261
+ 'X-GitHub-Api-Version': '2022-11-28',
262
+ ...(data ? { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) } : {}),
263
+ },
264
+ }, res => {
265
+ let raw = '';
266
+ res.setEncoding('utf8');
267
+ res.on('data', chunk => {
268
+ raw += chunk;
269
+ });
270
+ res.on('end', () => {
271
+ if (res.statusCode >= 200 && res.statusCode < 300) {
272
+ resolve(raw ? JSON.parse(raw) : null);
273
+ return;
274
+ }
275
+ reject(new Error(`${method} ${path} -> ${res.statusCode}: ${raw}`));
276
+ });
277
+ });
278
+ req.on('error', reject);
279
+ if (data) {
280
+ req.write(data);
281
+ }
282
+ req.end();
283
+ });
284
+ }
285
+
286
+ async function findExistingIssue(title) {
287
+ const q = encodeURIComponent(`repo:${OWNER}/${REPO} type:issue in:title "${title}"`);
288
+ const result = await githubRequest('GET', `/search/issues?q=${q}&per_page=10`);
289
+ return result.items?.find(item => item.title === title) || null;
290
+ }
291
+
292
+ async function createOrReuseIssue(issue) {
293
+ const existing = await findExistingIssue(issue.title);
294
+ if (existing) {
295
+ return existing;
296
+ }
297
+ return await githubRequest('POST', `/repos/${OWNER}/${REPO}/issues`, {
298
+ title: issue.title,
299
+ body: issue.body,
300
+ });
301
+ }
302
+
303
+ function writeTracking(payload) {
304
+ let content = fs.readFileSync(TRACKING_FILE, 'utf8');
305
+ for (const replacement of payload.trackingReplacements) {
306
+ content = content.replaceAll(replacement.placeholder, replacement.value);
307
+ }
308
+ fs.writeFileSync(TRACKING_FILE, content);
309
+ }
310
+
311
+ async function main() {
312
+ const args = new Set(process.argv.slice(2));
313
+ const dryRun = args.has('--dry-run') || !args.has('--apply');
314
+ const shouldWriteTracking = args.has('--write-tracking') || args.has('--apply');
315
+
316
+ if (dryRun) {
317
+ process.stdout.write(`${JSON.stringify(buildPayload(), null, 2)}\n`);
318
+ return;
319
+ }
320
+
321
+ const numbers = new Map();
322
+ for (const issue of issues) {
323
+ const created = await createOrReuseIssue(issue);
324
+ numbers.set(issue.key, created.number);
325
+ console.log(`#${created.number} ${created.title}`);
326
+ }
327
+
328
+ const payloadBeforeEpic = buildPayload(numbers);
329
+ const epic = await createOrReuseIssue(payloadBeforeEpic.epic);
330
+ numbers.set('epic', epic.number);
331
+ console.log(`#${epic.number} ${epic.title}`);
332
+
333
+ const finalPayload = buildPayload(numbers);
334
+ if (shouldWriteTracking) {
335
+ writeTracking(finalPayload);
336
+ console.log(`${TRACKING_FILE} updated`);
337
+ }
338
+ }
339
+
340
+ const invokedPath = process.argv[1] ? fileURLToPath(import.meta.url) === process.argv[1] : false;
341
+ if (invokedPath) {
342
+ try {
343
+ await main();
344
+ } catch (error) {
345
+ const message = error instanceof Error ? error.message : String(error);
346
+ console.error(`Failed to create v1.38 issues: ${message}`);
347
+ process.exitCode = 1;
348
+ }
349
+ }
350
+
351
+ export { buildPayload, issues };