@pixelbyte-software/pixcode 1.54.6 → 1.54.8

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 (288) 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 +418 -418
  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-DJ_KIN2W.js → index-BU3Z3zrh.js} +186 -184
  15. package/dist/assets/index-Dz1luE0u.css +32 -0
  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/features.html +133 -133
  20. package/dist/generate-icons.js +48 -48
  21. package/dist/humans.txt +15 -15
  22. package/dist/icons/codex-white.svg +3 -3
  23. package/dist/icons/codex.svg +3 -3
  24. package/dist/icons/cursor-white.svg +11 -11
  25. package/dist/icons/qwen-logo.svg +14 -14
  26. package/dist/index.html +59 -59
  27. package/dist/landing.html +268 -268
  28. package/dist/llms-full.txt +119 -119
  29. package/dist/llms.txt +53 -53
  30. package/dist/manifest.json +60 -60
  31. package/dist/openapi.yaml +1696 -1696
  32. package/dist/orchestration.html +125 -125
  33. package/dist/robots.txt +4 -4
  34. package/dist/site.css +692 -692
  35. package/dist/sitemap.xml +51 -51
  36. package/dist/sw.js +132 -132
  37. package/dist-server/server/cli.js +100 -100
  38. package/dist-server/server/daemon/manager.js +33 -33
  39. package/dist-server/server/daemon-manager.js +64 -64
  40. package/dist-server/server/index.js +113 -31
  41. package/dist-server/server/index.js.map +1 -1
  42. package/dist-server/server/routes/auth.js +17 -5
  43. package/dist-server/server/routes/auth.js.map +1 -1
  44. package/dist-server/server/routes/commands.js +25 -25
  45. package/dist-server/server/routes/git.js +17 -17
  46. package/dist-server/server/routes/live-view.js +46 -46
  47. package/dist-server/server/services/public-api-manifest.js +51 -51
  48. package/package.json +224 -224
  49. package/scripts/fix-node-pty.js +67 -67
  50. package/scripts/github/create-v1.38-issues.mjs +351 -351
  51. package/scripts/github/create-vscode-workbench-issues.mjs +121 -121
  52. package/scripts/smoke/backend-resource-bounds.mjs +152 -152
  53. package/scripts/smoke/changes-panel-layout.mjs +48 -48
  54. package/scripts/smoke/chat-composer-fixed-layout.mjs +55 -55
  55. package/scripts/smoke/chat-message-timeline-order.mjs +41 -41
  56. package/scripts/smoke/chat-realtime-hydration.mjs +44 -44
  57. package/scripts/smoke/chat-session-provider-pools.mjs +35 -35
  58. package/scripts/smoke/chat-session-state.mjs +19 -19
  59. package/scripts/smoke/code-editor-theme.mjs +55 -55
  60. package/scripts/smoke/code-editor-vscode-engine.mjs +91 -91
  61. package/scripts/smoke/command-center-agent-writes.mjs +79 -79
  62. package/scripts/smoke/command-center-non-git.mjs +46 -46
  63. package/scripts/smoke/context-packet.mjs +43 -43
  64. package/scripts/smoke/control-room-ux-redesign.mjs +91 -91
  65. package/scripts/smoke/daemon-entrypoint.mjs +20 -20
  66. package/scripts/smoke/default-landing-routing.mjs +33 -33
  67. package/scripts/smoke/desktop-native-notifications.mjs +30 -30
  68. package/scripts/smoke/desktop-tray-icon.mjs +33 -33
  69. package/scripts/smoke/discord-release-workflow.mjs +24 -24
  70. package/scripts/smoke/git-install-update.mjs +255 -255
  71. package/scripts/smoke/handoff-artifact-protocol.mjs +50 -50
  72. package/scripts/smoke/live-view-diagnostics.mjs +53 -53
  73. package/scripts/smoke/live-view-environment.mjs +92 -92
  74. package/scripts/smoke/live-view-integration.mjs +450 -450
  75. package/scripts/smoke/mac-desktop-runtime.mjs +37 -37
  76. package/scripts/smoke/mobile-tunnel-guidance.mjs +29 -29
  77. package/scripts/smoke/mobile-ux.mjs +76 -76
  78. package/scripts/smoke/model-registry.mjs +36 -36
  79. package/scripts/smoke/multi-project-ui.mjs +45 -45
  80. package/scripts/smoke/multi-worker-slots.mjs +42 -42
  81. package/scripts/smoke/notification-center.mjs +87 -87
  82. package/scripts/smoke/notification-inapp-preference.mjs +23 -23
  83. package/scripts/smoke/notification-taxonomy.mjs +58 -58
  84. package/scripts/smoke/orchestration-api.mjs +172 -172
  85. package/scripts/smoke/orchestration-execution-dashboard.mjs +33 -33
  86. package/scripts/smoke/orchestration-live-run.mjs +176 -176
  87. package/scripts/smoke/orchestration-mobile-scroll.mjs +29 -29
  88. package/scripts/smoke/orchestration-model-sync.mjs +30 -30
  89. package/scripts/smoke/orchestration-permission-fallback.mjs +34 -34
  90. package/scripts/smoke/orchestration-runtime-guards.mjs +48 -48
  91. package/scripts/smoke/orchestration-user-facing-output.mjs +25 -25
  92. package/scripts/smoke/permission-policy.mjs +50 -50
  93. package/scripts/smoke/pixcode-workbench-1-48.mjs +167 -167
  94. package/scripts/smoke/provider-models-opencode-live.mjs +66 -66
  95. package/scripts/smoke/provider-rest-api.mjs +124 -124
  96. package/scripts/smoke/provider-selection-status.mjs +52 -52
  97. package/scripts/smoke/run-state-refresh.mjs +52 -52
  98. package/scripts/smoke/runtime-manager.mjs +99 -99
  99. package/scripts/smoke/shell-manual-disconnect.mjs +30 -30
  100. package/scripts/smoke/side-panel-editor-layout.mjs +34 -34
  101. package/scripts/smoke/static-root-routing.mjs +21 -21
  102. package/scripts/smoke/strict-handoff-compact.mjs +60 -60
  103. package/scripts/smoke/taskmaster-config.mjs +24 -24
  104. package/scripts/smoke/taskmaster-execution-telegram.mjs +3 -3
  105. package/scripts/smoke/taskmaster-onboarding.mjs +3 -3
  106. package/scripts/smoke/taskmaster-run-graph.mjs +3 -3
  107. package/scripts/smoke/telegram-control.mjs +331 -331
  108. package/scripts/smoke/tunnel-persistence.mjs +56 -56
  109. package/scripts/smoke/update-issue-progress.mjs +69 -69
  110. package/scripts/smoke/update-ux.mjs +55 -55
  111. package/scripts/smoke/v138-completion.mjs +132 -132
  112. package/scripts/smoke/v138-desktop-release-hardening.mjs +69 -69
  113. package/scripts/smoke/v138-diagnostics.mjs +63 -63
  114. package/scripts/smoke/v138-issue-planner.mjs +33 -33
  115. package/scripts/smoke/v143-remote-control.mjs +76 -76
  116. package/scripts/smoke/v144-production-loop.mjs +47 -47
  117. package/scripts/smoke/v145-platformization.mjs +46 -46
  118. package/scripts/smoke/v146-control-room-ui.mjs +150 -150
  119. package/scripts/smoke/version-modal-autoshow.mjs +29 -29
  120. package/scripts/smoke/vscode-workbench-layout.mjs +63 -63
  121. package/scripts/smoke/vscode-workbench-polish.mjs +461 -461
  122. package/scripts/smoke/workflow-fallback-replay.mjs +56 -56
  123. package/scripts/smoke/workflow-templates.mjs +43 -43
  124. package/scripts/smoke/workflow-trace-timeline.mjs +46 -46
  125. package/scripts/update-git-install.mjs +298 -298
  126. package/server/claude-sdk.js +927 -927
  127. package/server/cli.js +1106 -1106
  128. package/server/constants/config.js +4 -4
  129. package/server/cursor-cli.js +344 -344
  130. package/server/daemon/manager.js +563 -563
  131. package/server/daemon-manager.js +964 -964
  132. package/server/database/db.js +988 -988
  133. package/server/database/json-store.js +197 -197
  134. package/server/gemini-cli.js +550 -550
  135. package/server/gemini-response-handler.js +79 -79
  136. package/server/index.js +5620 -5544
  137. package/server/load-env.js +35 -35
  138. package/server/middleware/account-lockout.js +112 -112
  139. package/server/middleware/auth.js +277 -277
  140. package/server/middleware/rate-limiter.js +87 -87
  141. package/server/modules/orchestration/a2a/adapter-registry.ts +108 -108
  142. package/server/modules/orchestration/a2a/adapters/abstract-a2a.adapter.ts +63 -63
  143. package/server/modules/orchestration/a2a/adapters/claude-code.adapter.ts +286 -286
  144. package/server/modules/orchestration/a2a/adapters/codex.adapter.ts +244 -244
  145. package/server/modules/orchestration/a2a/adapters/cursor.adapter.ts +249 -249
  146. package/server/modules/orchestration/a2a/adapters/gemini.adapter.ts +248 -248
  147. package/server/modules/orchestration/a2a/adapters/json-event.adapter.test.ts +60 -60
  148. package/server/modules/orchestration/a2a/adapters/json-event.adapter.ts +101 -101
  149. package/server/modules/orchestration/a2a/adapters/opencode.adapter.ts +248 -248
  150. package/server/modules/orchestration/a2a/adapters/qwen.adapter.ts +248 -248
  151. package/server/modules/orchestration/a2a/agent-card.ts +55 -55
  152. package/server/modules/orchestration/a2a/auth.middleware.ts +29 -29
  153. package/server/modules/orchestration/a2a/bus.ts +46 -46
  154. package/server/modules/orchestration/a2a/routes.ts +586 -586
  155. package/server/modules/orchestration/a2a/task-dispatcher.ts +345 -345
  156. package/server/modules/orchestration/a2a/task-store.ts +178 -178
  157. package/server/modules/orchestration/a2a/types.ts +126 -126
  158. package/server/modules/orchestration/a2a/validator.ts +113 -113
  159. package/server/modules/orchestration/index.ts +99 -99
  160. package/server/modules/orchestration/preview/port-watcher.ts +112 -112
  161. package/server/modules/orchestration/preview/preview-proxy.ts +60 -60
  162. package/server/modules/orchestration/preview/types.ts +19 -19
  163. package/server/modules/orchestration/security/permission-policy.ts +401 -401
  164. package/server/modules/orchestration/tasks/orchestration-task-store.ts +41 -41
  165. package/server/modules/orchestration/tasks/orchestration-task.routes.ts +81 -81
  166. package/server/modules/orchestration/tasks/orchestration-task.service.ts +201 -201
  167. package/server/modules/orchestration/tasks/orchestration-task.types.ts +40 -40
  168. package/server/modules/orchestration/tasks/task-run-graph.ts +155 -155
  169. package/server/modules/orchestration/workflows/approval-queue.ts +106 -106
  170. package/server/modules/orchestration/workflows/built-in-workflows.ts +127 -127
  171. package/server/modules/orchestration/workflows/context-packet.ts +186 -186
  172. package/server/modules/orchestration/workflows/handoff-artifact.ts +175 -175
  173. package/server/modules/orchestration/workflows/workflow-fallback-policy.ts +161 -161
  174. package/server/modules/orchestration/workflows/workflow-replay.ts +254 -254
  175. package/server/modules/orchestration/workflows/workflow-runner.ts +2062 -2062
  176. package/server/modules/orchestration/workflows/workflow-store.ts +97 -97
  177. package/server/modules/orchestration/workflows/workflow-templates.ts +272 -272
  178. package/server/modules/orchestration/workflows/workflow-trace.ts +424 -424
  179. package/server/modules/orchestration/workflows/workflow.routes.ts +586 -586
  180. package/server/modules/orchestration/workflows/workflow.types.ts +111 -111
  181. package/server/modules/orchestration/workflows/workspace-target.ts +122 -122
  182. package/server/modules/orchestration/workspace/docker-workspace.ts +136 -136
  183. package/server/modules/orchestration/workspace/path-safety.ts +55 -55
  184. package/server/modules/orchestration/workspace/types.ts +52 -52
  185. package/server/modules/orchestration/workspace/workspace-manager.ts +102 -102
  186. package/server/modules/orchestration/workspace/worktree-workspace.ts +126 -126
  187. package/server/modules/providers/index.ts +2 -2
  188. package/server/modules/providers/list/claude/claude-auth.provider.ts +146 -146
  189. package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -135
  190. package/server/modules/providers/list/claude/claude-sessions.provider.ts +306 -306
  191. package/server/modules/providers/list/claude/claude.provider.ts +15 -15
  192. package/server/modules/providers/list/codex/codex-auth.provider.ts +117 -117
  193. package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -135
  194. package/server/modules/providers/list/codex/codex-sessions.provider.ts +319 -319
  195. package/server/modules/providers/list/codex/codex.provider.ts +15 -15
  196. package/server/modules/providers/list/cursor/cursor-auth.provider.ts +147 -147
  197. package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -108
  198. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +421 -421
  199. package/server/modules/providers/list/cursor/cursor.provider.ts +15 -15
  200. package/server/modules/providers/list/gemini/gemini-auth.provider.ts +173 -173
  201. package/server/modules/providers/list/gemini/gemini-mcp.provider.ts +110 -110
  202. package/server/modules/providers/list/gemini/gemini-sessions.provider.ts +227 -227
  203. package/server/modules/providers/list/gemini/gemini.provider.ts +15 -15
  204. package/server/modules/providers/list/opencode/opencode-auth.provider.ts +131 -131
  205. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +286 -286
  206. package/server/modules/providers/list/qwen/qwen-auth.provider.ts +146 -146
  207. package/server/modules/providers/list/qwen/qwen-sessions.provider.ts +265 -265
  208. package/server/modules/providers/provider.registry.ts +40 -40
  209. package/server/modules/providers/provider.routes.ts +982 -982
  210. package/server/modules/providers/services/mcp.service.ts +86 -86
  211. package/server/modules/providers/services/provider-auth.service.ts +26 -26
  212. package/server/modules/providers/services/sessions.service.ts +45 -45
  213. package/server/modules/providers/shared/base/abstract.provider.ts +20 -20
  214. package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -151
  215. package/server/modules/providers/tests/mcp.test.ts +293 -293
  216. package/server/openai-codex.js +468 -468
  217. package/server/opencode-cli.js +491 -491
  218. package/server/opencode-response-handler.js +111 -111
  219. package/server/projects.js +3125 -3125
  220. package/server/qwen-code-cli.js +410 -410
  221. package/server/routes/agent.js +1451 -1451
  222. package/server/routes/auth.js +298 -286
  223. package/server/routes/codex.js +20 -20
  224. package/server/routes/commands.js +581 -581
  225. package/server/routes/cursor.js +61 -61
  226. package/server/routes/diagnostics.js +44 -44
  227. package/server/routes/gemini.js +25 -25
  228. package/server/routes/git.js +1822 -1822
  229. package/server/routes/live-view.js +434 -434
  230. package/server/routes/mcp-utils.js +13 -13
  231. package/server/routes/messages.js +97 -97
  232. package/server/routes/network.js +143 -143
  233. package/server/routes/platformization.js +231 -231
  234. package/server/routes/plugins.js +690 -690
  235. package/server/routes/production-agent-loop.js +90 -90
  236. package/server/routes/projects.js +918 -918
  237. package/server/routes/public-api.js +34 -34
  238. package/server/routes/qwen.js +27 -27
  239. package/server/routes/remote.js +56 -56
  240. package/server/routes/settings.js +321 -321
  241. package/server/routes/telegram.js +163 -163
  242. package/server/routes/user.js +125 -125
  243. package/server/routes/webhooks.js +63 -63
  244. package/server/services/control-room.js +102 -102
  245. package/server/services/diagnostics.js +165 -165
  246. package/server/services/external-access.js +403 -403
  247. package/server/services/install-jobs.js +715 -715
  248. package/server/services/live-view.js +956 -956
  249. package/server/services/managed-runtimes.js +493 -493
  250. package/server/services/model-registry.js +144 -144
  251. package/server/services/notification-orchestrator.js +365 -365
  252. package/server/services/notification-taxonomy.js +204 -204
  253. package/server/services/platformization.js +1052 -1052
  254. package/server/services/production-agent-loop.js +248 -248
  255. package/server/services/provider-cli-versions.js +149 -149
  256. package/server/services/provider-credentials.js +189 -189
  257. package/server/services/provider-models.js +396 -396
  258. package/server/services/public-api-manifest.js +181 -181
  259. package/server/services/qr-login.js +126 -126
  260. package/server/services/remote-connection.js +127 -127
  261. package/server/services/runtime-manager.js +323 -323
  262. package/server/services/startup-update.js +259 -259
  263. package/server/services/telegram/bot.js +393 -393
  264. package/server/services/telegram/control-center.js +2453 -2453
  265. package/server/services/telegram/telegram-gateway.js +314 -314
  266. package/server/services/telegram/telegram-http-client.js +201 -201
  267. package/server/services/telegram/translations.js +470 -470
  268. package/server/services/webhooks.js +216 -216
  269. package/server/sessionManager.js +225 -225
  270. package/server/setup-wizard.js +283 -283
  271. package/server/shared/interfaces.ts +54 -54
  272. package/server/shared/types.ts +172 -172
  273. package/server/shared/utils.ts +193 -193
  274. package/server/tsconfig.json +36 -36
  275. package/server/utils/colors.js +21 -21
  276. package/server/utils/commandParser.js +305 -305
  277. package/server/utils/frontmatter.js +18 -18
  278. package/server/utils/gitConfig.js +34 -34
  279. package/server/utils/plugin-loader.js +461 -461
  280. package/server/utils/plugin-process-manager.js +185 -185
  281. package/server/utils/port-access.js +227 -227
  282. package/server/utils/runtime-paths.js +37 -37
  283. package/server/utils/security-log.js +84 -84
  284. package/server/utils/url-detection.js +71 -71
  285. package/server/vite-daemon.js +79 -79
  286. package/shared/modelConstants.js +161 -161
  287. package/shared/networkHosts.js +22 -22
  288. package/dist/assets/index-DvudRU5X.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 };