neo.mjs 11.0.1 → 11.1.0

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 (33) hide show
  1. package/.github/.sync-metadata.json +176 -60
  2. package/.github/ISSUE_ARCHIVE/11.0.1/issue-7732.md +45 -0
  3. package/ServiceWorker.mjs +2 -2
  4. package/ai/mcp/server/github-workflow/openapi.yaml +94 -0
  5. package/ai/mcp/server/github-workflow/services/HealthService.mjs +56 -7
  6. package/ai/mcp/server/github-workflow/services/IssueService.mjs +115 -1
  7. package/ai/mcp/server/github-workflow/services/queries/mutations.mjs +82 -0
  8. package/ai/mcp/server/github-workflow/services/sync/IssueSyncer.mjs +22 -19
  9. package/ai/mcp/server/github-workflow/services/toolService.mjs +17 -16
  10. package/apps/portal/index.html +2 -2
  11. package/apps/portal/llm.txt +89 -0
  12. package/apps/portal/resources/data/blog.json +12 -0
  13. package/apps/portal/resources/data/examples_devmode.json +22 -28
  14. package/apps/portal/robots.txt +4 -0
  15. package/apps/portal/sitemap.xml +359 -0
  16. package/apps/portal/view/ViewportController.mjs +93 -0
  17. package/apps/portal/view/home/FooterContainer.mjs +1 -1
  18. package/buildScripts/buildAll.mjs +4 -0
  19. package/buildScripts/buildESModules.mjs +7 -7
  20. package/buildScripts/copySeoFiles.mjs +102 -0
  21. package/buildScripts/generate-seo-files.mjs +207 -125
  22. package/buildScripts/prepareRelease.mjs +111 -0
  23. package/learn/blog/context-engineering-done-right.md +1899 -0
  24. package/learn/tree.json +2 -0
  25. package/package.json +21 -21
  26. package/src/DefaultConfig.mjs +2 -2
  27. package/src/main/addon/DocumentHead.mjs +192 -0
  28. package/test/playwright/mcp/github-workflow/ghIntegrationGate.spec.mjs +13 -0
  29. package/test/playwright/mcp/github-workflow/test-support/ghGate.mjs +34 -0
  30. package/ai/mcp/server/github-workflow/services/healthHelpers.mjs +0 -51
  31. package/ai/mcp/server/github-workflow/test/healthHelpers.test.mjs +0 -38
  32. package/buildScripts/injectPackageVersion.mjs +0 -75
  33. /package/{ai/mcp/server/github-workflow/docs/gh-absent.md → learn/guides/ai/GitHubWorkflowServerGhAbsent.md} +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
- "lastSync": "2025-11-09T13:42:30.665Z",
3
- "releasesLastFetched": "2025-11-09T13:42:31.017Z",
2
+ "lastSync": "2025-11-12T08:29:20.536Z",
3
+ "releasesLastFetched": "2025-11-12T08:29:20.546Z",
4
4
  "pushFailures": [],
5
5
  "issues": {
6
6
  "3789": {
@@ -4323,25 +4323,25 @@
4323
4323
  "contentHash": "59c9e2e83a8c4adadc706801b593e96b483c1b3be975451a07898910bc87b2bd"
4324
4324
  },
4325
4325
  "7446": {
4326
- "state": "OPEN",
4326
+ "state": "CLOSED",
4327
4327
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7446.md",
4328
- "closedAt": null,
4329
- "updatedAt": "2025-10-11T09:34:50Z",
4330
- "contentHash": "eb5b464e928abd0a4d0db7c84ca9588a3399c9baa8953fabf01e5dde7c741c1f"
4328
+ "closedAt": "2025-11-11T18:30:24Z",
4329
+ "updatedAt": "2025-11-11T18:30:24Z",
4330
+ "contentHash": "2a66ca1c834a04f5eff0d4ca3788920ebb6df76ea473d6da912981170702ae98"
4331
4331
  },
4332
4332
  "7447": {
4333
4333
  "state": "OPEN",
4334
4334
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7447.md",
4335
4335
  "closedAt": null,
4336
- "updatedAt": "2025-10-10T20:08:08Z",
4337
- "contentHash": "b018c1f57275dd0bd8d132a779632d6ea0d8ce5da25fb21285e40ec3f21a30d9"
4336
+ "updatedAt": "2025-11-11T18:30:06Z",
4337
+ "contentHash": "2de714d07a8b79b2810a980fcc33457d39dd8806636e9a572d9adcdc36496823"
4338
4338
  },
4339
4339
  "7448": {
4340
- "state": "OPEN",
4340
+ "state": "CLOSED",
4341
4341
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7448.md",
4342
- "closedAt": null,
4343
- "updatedAt": "2025-10-17T14:36:47Z",
4344
- "contentHash": "e6b45dfed2e72d1d278bce497c590c409d318617cfb97bddd6565b587f8e5489"
4342
+ "closedAt": "2025-11-11T10:59:35Z",
4343
+ "updatedAt": "2025-11-11T10:59:35Z",
4344
+ "contentHash": "616f9d50e382885e5ac6b783d5950bf790ab23a55580fcf64dee3d581128d983"
4345
4345
  },
4346
4346
  "7449": {
4347
4347
  "state": "CLOSED",
@@ -4351,32 +4351,32 @@
4351
4351
  "contentHash": "b225777ec0084061dfaa0b744ced1af88a6a7b2d4c9cf3366df5b9aa9ee52cd0"
4352
4352
  },
4353
4353
  "7451": {
4354
- "state": "OPEN",
4354
+ "state": "CLOSED",
4355
4355
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7451.md",
4356
- "closedAt": null,
4357
- "updatedAt": "2025-10-10T20:22:09Z",
4358
- "contentHash": "87aabfb5d407e2ba4e8211c8b4930db1bfcbd80f1ce1c3111974976cac0bd858"
4356
+ "closedAt": "2025-11-11T12:27:38Z",
4357
+ "updatedAt": "2025-11-11T12:27:38Z",
4358
+ "contentHash": "a89593221ed1684a55f6f3401441e472dde7e0174247cf16311c360c22678256"
4359
4359
  },
4360
4360
  "7452": {
4361
- "state": "OPEN",
4361
+ "state": "CLOSED",
4362
4362
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7452.md",
4363
- "closedAt": null,
4364
- "updatedAt": "2025-10-10T20:21:34Z",
4365
- "contentHash": "721f9ea97a5d00b94b9aa50f96415757bf70f2c1a467eeebe2b4f0c97063a026"
4363
+ "closedAt": "2025-11-11T12:26:47Z",
4364
+ "updatedAt": "2025-11-11T12:26:47Z",
4365
+ "contentHash": "78a9440800363f54b8e6206561c28c293ac74c0a1fb164f2013d02d3cf9187c7"
4366
4366
  },
4367
4367
  "7453": {
4368
- "state": "OPEN",
4368
+ "state": "CLOSED",
4369
4369
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7453.md",
4370
- "closedAt": null,
4371
- "updatedAt": "2025-10-10T20:20:28Z",
4372
- "contentHash": "e9347e410aeed9219b6362f77a5b167a278b8bc3a85a75af99e479f84185ff57"
4370
+ "closedAt": "2025-11-11T12:27:24Z",
4371
+ "updatedAt": "2025-11-11T12:27:24Z",
4372
+ "contentHash": "f9e3ebd543dd12ee3dd0aa10fa1b35d48600de496efea0c35a13610b38811c4d"
4373
4373
  },
4374
4374
  "7460": {
4375
- "state": "OPEN",
4375
+ "state": "CLOSED",
4376
4376
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7460.md",
4377
- "closedAt": null,
4378
- "updatedAt": "2025-10-11T15:15:55Z",
4379
- "contentHash": "9a64a7752e0246e15d7b85db0f05b926daf7aa88353c50b1f8ce9a84c8d44e58"
4377
+ "closedAt": "2025-11-11T12:28:41Z",
4378
+ "updatedAt": "2025-11-11T12:28:41Z",
4379
+ "contentHash": "66ad338115f5ed72ba679335bb9c4829e3c3c113191559bbee2afee481cbdfa7"
4380
4380
  },
4381
4381
  "7464": {
4382
4382
  "state": "CLOSED",
@@ -4533,11 +4533,11 @@
4533
4533
  "contentHash": "a667023221df9a79400779a18c455480d775cacb677aa6636ab3be48bb00f6f4"
4534
4534
  },
4535
4535
  "7488": {
4536
- "state": "OPEN",
4536
+ "state": "CLOSED",
4537
4537
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7488.md",
4538
- "closedAt": null,
4539
- "updatedAt": "2025-10-23T19:17:18Z",
4540
- "contentHash": "a45ac6d2a6921303ad3e44c1aa5f3e0a306d4dd8a1c26a79a191029f667637a2"
4538
+ "closedAt": "2025-11-10T20:23:24Z",
4539
+ "updatedAt": "2025-11-10T20:23:24Z",
4540
+ "contentHash": "bbe532ba2b9c8ce9c4fada7754a4a03f95eccae9756638ce90d85a91ec584d9c"
4541
4541
  },
4542
4542
  "7489": {
4543
4543
  "state": "OPEN",
@@ -5492,11 +5492,11 @@
5492
5492
  "contentHash": "4337d7db40ddd3f5b311a532450f7b31b707056b2c2daaaea8d33bd7956e0755"
5493
5493
  },
5494
5494
  "7632": {
5495
- "state": "OPEN",
5495
+ "state": "CLOSED",
5496
5496
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7632.md",
5497
- "closedAt": null,
5498
- "updatedAt": "2025-10-24T10:15:43Z",
5499
- "contentHash": "b874cd1c73623124568e31fd3b904f7a12c7154b6b442e1550a8a9ab67f3dcc4"
5497
+ "closedAt": "2025-11-12T08:20:31Z",
5498
+ "updatedAt": "2025-11-12T08:20:31Z",
5499
+ "contentHash": "f2435113c3b65db01c1a13ec68f6d4f63b66074e28582f3ad6d1bc734ebde087"
5500
5500
  },
5501
5501
  "7633": {
5502
5502
  "state": "CLOSED",
@@ -5856,11 +5856,11 @@
5856
5856
  "contentHash": "830b39187f815a5faf7b81b42e8089502cffc0cdcdad2831a0e49e5bf1cbfeaa"
5857
5857
  },
5858
5858
  "7687": {
5859
- "state": "OPEN",
5859
+ "state": "CLOSED",
5860
5860
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7687.md",
5861
- "closedAt": null,
5862
- "updatedAt": "2025-11-01T18:49:30Z",
5863
- "contentHash": "4277d1016e03d187efac0ddcbd853fe5c2326b5a75133ae0d697ceb1faa3ce1d"
5861
+ "closedAt": "2025-11-10T20:31:38Z",
5862
+ "updatedAt": "2025-11-10T20:31:38Z",
5863
+ "contentHash": "2d1323e02d08d99835328ddd1ce5aedc716d3ff83db687355013e248a9b9deca"
5864
5864
  },
5865
5865
  "7688": {
5866
5866
  "state": "CLOSED",
@@ -6045,11 +6045,11 @@
6045
6045
  "contentHash": "7b40d59fb8a42281e7d8cd57d121f45ea7c09bae2b7f838a3ee7430b706a1ebb"
6046
6046
  },
6047
6047
  "7714": {
6048
- "state": "OPEN",
6048
+ "state": "CLOSED",
6049
6049
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7714.md",
6050
- "closedAt": null,
6051
- "updatedAt": "2025-11-07T08:49:15Z",
6052
- "contentHash": "e28cd571d0e592e47f8483fcf73ca61097bf9626aa5a36cd902698c9cc2fc0a3"
6050
+ "closedAt": "2025-11-10T20:17:37Z",
6051
+ "updatedAt": "2025-11-10T20:17:37Z",
6052
+ "contentHash": "0751de4a201f637ce1d561577fa0f959e656fdbd0b969f928a3726608c9fdb45"
6053
6053
  },
6054
6054
  "7715": {
6055
6055
  "state": "CLOSED",
@@ -6080,25 +6080,25 @@
6080
6080
  "contentHash": "c7fbd6da63da3664feb2776ba55e394deac0ac40064ef9f394c95db8c2faa0cc"
6081
6081
  },
6082
6082
  "7720": {
6083
- "state": "OPEN",
6083
+ "state": "CLOSED",
6084
6084
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7720.md",
6085
- "closedAt": null,
6086
- "updatedAt": "2025-11-08T09:50:28Z",
6087
- "contentHash": "323c44222cf63bb34747a8f645c54eda69bb56666a4169327c7ae1e965595af7"
6085
+ "closedAt": "2025-11-11T08:35:17Z",
6086
+ "updatedAt": "2025-11-11T08:35:17Z",
6087
+ "contentHash": "6d159a010433bc4bfaa419cf1de0e15395c7769acd9411bca444389f2fceafbf"
6088
6088
  },
6089
6089
  "7721": {
6090
- "state": "OPEN",
6090
+ "state": "CLOSED",
6091
6091
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7721.md",
6092
- "closedAt": null,
6093
- "updatedAt": "2025-11-08T09:56:33Z",
6094
- "contentHash": "b5cb9dfa17f78372bf78c55a9994eb4851febbd8b9eb6a9780d4ebf52ac0dbaa"
6092
+ "closedAt": "2025-11-10T20:07:24Z",
6093
+ "updatedAt": "2025-11-10T20:07:24Z",
6094
+ "contentHash": "778dace95c637fce63801b65871ec54829fe4b0efe58e8b132e864815c96a764"
6095
6095
  },
6096
6096
  "7722": {
6097
- "state": "OPEN",
6097
+ "state": "CLOSED",
6098
6098
  "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7722.md",
6099
- "closedAt": null,
6100
- "updatedAt": "2025-11-08T09:57:48Z",
6101
- "contentHash": "ca2be3da89ae68a90a3b7a3caee26b7287e6e4000d7bc286edb7c5f5b9085ebc"
6099
+ "closedAt": "2025-11-10T20:03:08Z",
6100
+ "updatedAt": "2025-11-10T20:03:08Z",
6101
+ "contentHash": "74893812ea514d79dc531d3045eafbe245df6a68385cdefb4ab817154696bb13"
6102
6102
  },
6103
6103
  "7723": {
6104
6104
  "state": "CLOSED",
@@ -6143,11 +6143,123 @@
6143
6143
  "contentHash": "85081a09a72043cb26bb5dacccfa477884eb64f2d533a0ca98b5d2e10d0398e1"
6144
6144
  },
6145
6145
  "7732": {
6146
+ "state": "CLOSED",
6147
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE_ARCHIVE/11.0.1/issue-7732.md",
6148
+ "closedAt": "2025-11-09T13:49:14Z",
6149
+ "updatedAt": "2025-11-09T13:49:14Z",
6150
+ "contentHash": "dacc9d223f5968bc74a997c0cdd8906c6a2573d2057c99f88e567b8f94a5def5"
6151
+ },
6152
+ "7733": {
6153
+ "state": "CLOSED",
6154
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7733.md",
6155
+ "closedAt": "2025-11-10T09:56:06Z",
6156
+ "updatedAt": "2025-11-10T09:56:06Z",
6157
+ "contentHash": "87bea208896f2689ab28e062f12d41c325108e8421f96183f1667cd49396f5e8"
6158
+ },
6159
+ "7735": {
6160
+ "state": "CLOSED",
6161
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7735.md",
6162
+ "closedAt": "2025-11-10T12:18:09Z",
6163
+ "updatedAt": "2025-11-10T12:18:09Z",
6164
+ "contentHash": "dfa19a9906b58ea84f25c5fc7e5ed938d39a5f10bbf1e415c850c0cf8550f2e3"
6165
+ },
6166
+ "7736": {
6167
+ "state": "CLOSED",
6168
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7736.md",
6169
+ "closedAt": "2025-11-10T20:20:43Z",
6170
+ "updatedAt": "2025-11-10T20:20:43Z",
6171
+ "contentHash": "dea4b158a88c5ef42de4d01b428169e5f36c0bf1738950f20dd43c33ff509358"
6172
+ },
6173
+ "7737": {
6174
+ "state": "OPEN",
6175
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7737.md",
6176
+ "closedAt": null,
6177
+ "updatedAt": "2025-11-10T21:03:48Z",
6178
+ "contentHash": "2e09f6365bcfaec5cfd403438890ecfaf0b81e52f7372d4c7f80995f16126f82"
6179
+ },
6180
+ "7739": {
6181
+ "state": "CLOSED",
6182
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7739.md",
6183
+ "closedAt": "2025-11-11T09:23:57Z",
6184
+ "updatedAt": "2025-11-11T09:23:57Z",
6185
+ "contentHash": "fb87f14d5723e535cde18e7bb2ce8db7bef08437cfee6cb79193998f5fc533f8"
6186
+ },
6187
+ "7742": {
6188
+ "state": "CLOSED",
6189
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7742.md",
6190
+ "closedAt": "2025-11-11T11:55:15Z",
6191
+ "updatedAt": "2025-11-11T11:55:15Z",
6192
+ "contentHash": "1851858771aab1c5078f04f8727a295f3f95d076b51e0ae57ea38015c7c64560"
6193
+ },
6194
+ "7743": {
6195
+ "state": "CLOSED",
6196
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7743.md",
6197
+ "closedAt": "2025-11-11T12:00:32Z",
6198
+ "updatedAt": "2025-11-11T12:00:32Z",
6199
+ "contentHash": "1635e7711dab6233039c59fb4696c88d7745692b077d738c32c6f45f3c8dbe00"
6200
+ },
6201
+ "7744": {
6202
+ "state": "CLOSED",
6203
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7744.md",
6204
+ "closedAt": "2025-11-11T13:02:33Z",
6205
+ "updatedAt": "2025-11-11T13:02:33Z",
6206
+ "contentHash": "9251e6dfcc1637f2afb881b763340379410fcf19e33e8860352c10d6fe31bfb1"
6207
+ },
6208
+ "7745": {
6209
+ "state": "CLOSED",
6210
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7745.md",
6211
+ "closedAt": "2025-11-11T12:59:39Z",
6212
+ "updatedAt": "2025-11-11T12:59:39Z",
6213
+ "contentHash": "826c44e0591d985167838e5dfc7f21714c9dda87de833049e5878029e1d8b06d"
6214
+ },
6215
+ "7746": {
6216
+ "state": "CLOSED",
6217
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7746.md",
6218
+ "closedAt": "2025-11-11T17:29:38Z",
6219
+ "updatedAt": "2025-11-11T17:29:38Z",
6220
+ "contentHash": "3edd23770e94a726a98da4baf0f136cfa8b3fc940880f849f964ba66c4034516"
6221
+ },
6222
+ "7747": {
6223
+ "state": "CLOSED",
6224
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7747.md",
6225
+ "closedAt": "2025-11-11T18:12:19Z",
6226
+ "updatedAt": "2025-11-11T18:12:19Z",
6227
+ "contentHash": "44b86f4265655ba08656632e632783bdfe9a41895dc35efde0840880e0a86524"
6228
+ },
6229
+ "7748": {
6230
+ "state": "CLOSED",
6231
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7748.md",
6232
+ "closedAt": "2025-11-11T18:28:44Z",
6233
+ "updatedAt": "2025-11-11T18:28:44Z",
6234
+ "contentHash": "cca7cf3e26a56a42e41ee2738a5f72995d15b715d780a8d4615defe72363d3f3"
6235
+ },
6236
+ "7749": {
6146
6237
  "state": "OPEN",
6147
- "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7732.md",
6238
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7749.md",
6148
6239
  "closedAt": null,
6149
- "updatedAt": "2025-11-09T10:40:33Z",
6150
- "contentHash": "aa1aba29dcf78ada24f83bef606cfd2067037c04073e0c9b6f5c8383563d15e2"
6240
+ "updatedAt": "2025-11-12T07:58:04Z",
6241
+ "contentHash": "3b3d2aa230f40d4f6cee9bd244f7746ab2b2da3690d700cd268d8a8825b8f14d"
6242
+ },
6243
+ "7750": {
6244
+ "state": "OPEN",
6245
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7750.md",
6246
+ "closedAt": null,
6247
+ "updatedAt": "2025-11-12T07:59:51Z",
6248
+ "contentHash": "a9162dd69b3594b8b515049b09b9da1ce91ebe80ed5f1dc334322a07461b1814"
6249
+ },
6250
+ "7751": {
6251
+ "state": "OPEN",
6252
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7751.md",
6253
+ "closedAt": null,
6254
+ "updatedAt": "2025-11-12T08:12:03Z",
6255
+ "contentHash": "282f855f862772f59fb0af9d8d2df415733be0d11cba09e6c765402a4f62077d"
6256
+ },
6257
+ "7752": {
6258
+ "state": "OPEN",
6259
+ "path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7752.md",
6260
+ "closedAt": null,
6261
+ "updatedAt": "2025-11-12T08:21:09Z",
6262
+ "contentHash": "f9b3887116834d71eb79c5effa110f22d2da787a0bbb9c86beaffb05abf32495"
6151
6263
  }
6152
6264
  },
6153
6265
  "releases": {
@@ -6293,7 +6405,11 @@
6293
6405
  },
6294
6406
  "11.0.0": {
6295
6407
  "publishedAt": "2025-11-09T10:22:08Z",
6296
- "contentHash": "87670395e3b911a6dae09f8567e5ce1190170d58e23f9a3a5b29119bd2b5b75e"
6408
+ "contentHash": "be9789732be74eda2d04cc092328f6e63f4ade3f735c59063cc583e832d2dce7"
6409
+ },
6410
+ "11.0.1": {
6411
+ "publishedAt": "2025-11-09T14:22:57Z",
6412
+ "contentHash": "8dd1b9bc9a57aa911a0f1513649469dba6502609022edc487b861dcdbdfd746c"
6297
6413
  }
6298
6414
  }
6299
6415
  }
@@ -0,0 +1,45 @@
1
+ ---
2
+ id: 7732
3
+ title: 'bug: sync_all does not move existing local issues to archive on new release'
4
+ state: OPEN
5
+ labels:
6
+ - bug
7
+ - ai
8
+ assignees:
9
+ - tobiu
10
+ createdAt: '2025-11-09T10:31:59Z'
11
+ updatedAt: '2025-11-09T10:40:33Z'
12
+ githubUrl: 'https://github.com/neomjs/neo/issues/7732'
13
+ author: tobiu
14
+ commentsCount: 0
15
+ parentIssue: null
16
+ subIssues: []
17
+ subIssuesCompleted: 0
18
+ subIssuesTotal: 0
19
+ ---
20
+ # bug: sync_all does not move existing local issues to archive on new release
21
+
22
+ **Reported by:** @tobiu on 2025-11-09
23
+
24
+ ### Summary
25
+
26
+ The `sync_all` tool fails to move existing local issues from the `.github/ISSUE/` directory to the appropriate release archive folder when a new release is synced.
27
+
28
+ ### Steps to Reproduce
29
+
30
+ 1. Have a closed issue with a milestone (e.g., `v11.0.0`) that already exists as a local file in `.github/ISSUE/`.
31
+ 2. Publish the corresponding release (`v11.0.0`) on GitHub.
32
+ 3. Run the `sync_all` tool.
33
+
34
+ ### Expected Behavior
35
+
36
+ The local issue file is moved from `.github/ISSUE/` to `.github/ISSUE_ARCHIVE/11.0.0/`. The local metadata in `.github/.sync-metadata.json` is updated with the new file path.
37
+
38
+ ### Actual Behavior
39
+
40
+ The local issue file is not moved. The sync logic appears to skip re-evaluating the location of local files if their content hash has not changed, even though its milestone now dictates it should be archived.
41
+
42
+ ### Technical Analysis
43
+
44
+ The bug is likely within the `IssueSyncer` service. The current logic prioritizes content hash checking over location validation. The logic needs to be refactored to ensure that for every issue pulled from GitHub, its correct local path (active vs. archived) is determined based on its milestone, and the local file is moved if its current path does not match the expected path. This location check must happen independently of the content sync check.
45
+
package/ServiceWorker.mjs CHANGED
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='11.0.1'
23
+ * @member {String} version='11.1.0'
24
24
  */
25
- version: '11.0.1'
25
+ version: '11.1.0'
26
26
  }
27
27
 
28
28
  /**
@@ -717,6 +717,75 @@ paths:
717
717
  schema:
718
718
  $ref: '#/components/schemas/ErrorResponse'
719
719
 
720
+ /issues/relationship:
721
+ post:
722
+ summary: Manage Parent-Child Issue Relationships
723
+ operationId: update_issue_relationship
724
+ x-pass-as-object: true
725
+ x-annotations:
726
+ readOnlyHint: false
727
+ description: |
728
+ Manages parent-child relationships between GitHub issues using the sub-issues feature.
729
+ This tool allows you to set or unset the parent of a child issue, which automatically
730
+ updates the parent's `subIssues` array on GitHub.
731
+
732
+ **When to Use:**
733
+ - To organize work by creating issue hierarchies (epics with sub-tasks)
734
+ - To link a child issue to a parent issue
735
+ - To unlink a child issue from its parent
736
+ - To move a child issue from one parent to another
737
+
738
+ **Important Notes:**
739
+ - Changes are made directly on GitHub via the GraphQL API
740
+ - The local markdown files will be updated on the next `sync_all` operation
741
+ - An issue can only have ONE parent at a time
742
+ - Use `replace_parent=true` to replace an existing parent relationship
743
+ - To remove a parent, call with only `child_issue` specified (omit `parent_issue`)
744
+
745
+ **Workflow:**
746
+ 1. Identify the child issue number and parent issue number
747
+ 2. Call this tool to establish or modify the relationship
748
+ 3. Run `sync_all` to update local markdown files with the new relationship
749
+ tags: [Issues]
750
+ requestBody:
751
+ required: true
752
+ content:
753
+ application/json:
754
+ schema:
755
+ type: object
756
+ required:
757
+ - child_issue
758
+ properties:
759
+ child_issue:
760
+ type: integer
761
+ description: The issue number of the child issue.
762
+ example: 7388
763
+ parent_issue:
764
+ type: integer
765
+ description: |
766
+ The issue number of the parent issue.
767
+ Omit this field (or set to null) to remove the parent relationship.
768
+ example: 7385
769
+ replace_parent:
770
+ type: boolean
771
+ description: |
772
+ If true, replaces the child's existing parent relationship.
773
+ If false and the child already has a parent, the operation will fail.
774
+ default: false
775
+ responses:
776
+ '200':
777
+ description: Relationship updated successfully.
778
+ content:
779
+ application/json:
780
+ schema:
781
+ $ref: '#/components/schemas/UpdateIssueRelationshipResponse'
782
+ '500':
783
+ description: Internal server error, e.g., GraphQL API failure.
784
+ content:
785
+ application/json:
786
+ schema:
787
+ $ref: '#/components/schemas/ErrorResponse'
788
+
720
789
  /sync-all:
721
790
  post:
722
791
  summary: Sync GitHub Issues & Releases
@@ -1069,6 +1138,31 @@ components:
1069
1138
  format: uri
1070
1139
  description: The URL of the newly created issue.
1071
1140
 
1141
+ UpdateIssueRelationshipResponse:
1142
+ type: object
1143
+ properties:
1144
+ message:
1145
+ type: string
1146
+ description: A human-readable message describing the result of the operation.
1147
+ example: "Successfully set #7385 as parent of #7388"
1148
+ childIssue:
1149
+ type: integer
1150
+ description: The issue number of the child issue.
1151
+ example: 7388
1152
+ parentIssue:
1153
+ type: integer
1154
+ nullable: true
1155
+ description: The issue number of the parent issue, or null if the parent was removed.
1156
+ example: 7385
1157
+ oldParent:
1158
+ type: integer
1159
+ description: The previous parent issue number, if one was replaced or removed.
1160
+ example: 7380
1161
+ replaceParentApplied:
1162
+ type: boolean
1163
+ description: Indicates whether the replace_parent flag was used.
1164
+ example: false
1165
+
1072
1166
  LocalIssueResponse:
1073
1167
  type: object
1074
1168
  properties:
@@ -4,7 +4,6 @@ import aiConfig from '../config.mjs';
4
4
  import Base from '../../../../../src/core/Base.mjs';
5
5
  import logger from '../logger.mjs';
6
6
  import semver from 'semver';
7
- import { combineOutput, parseAuthOutput, parseVersionOutput, interpretExecError } from './healthHelpers.mjs';
8
7
 
9
8
  const execAsync = promisify(exec);
10
9
 
@@ -87,10 +86,10 @@ class HealthService extends Base {
87
86
  async #checkGhAuth() {
88
87
  try {
89
88
  const { stdout, stderr } = await execAsync('gh auth status');
90
- const out = combineOutput(stdout, stderr);
91
- return parseAuthOutput(out);
89
+ const out = this.#combineOutput(stdout, stderr);
90
+ return this.#parseAuthOutput(out);
92
91
  } catch (e) {
93
- if (interpretExecError(e)) {
92
+ if (this.#interpretExecError(e)) {
94
93
  return {
95
94
  authenticated: false,
96
95
  error : 'GitHub CLI is not installed or not available in PATH. Please install it or run `gh auth login`.'
@@ -120,10 +119,10 @@ class HealthService extends Base {
120
119
  async #checkGhVersion() {
121
120
  try {
122
121
  const { stdout, stderr } = await execAsync('gh --version');
123
- const out = combineOutput(stdout, stderr);
124
- return parseVersionOutput(out, aiConfig.minGhVersion);
122
+ const out = this.#combineOutput(stdout, stderr);
123
+ return this.#parseVersionOutput(out, aiConfig.minGhVersion);
125
124
  } catch (e) {
126
- if (interpretExecError(e)) {
125
+ if (this.#interpretExecError(e)) {
127
126
  return {
128
127
  installed: false,
129
128
  versionOk: false,
@@ -180,6 +179,11 @@ class HealthService extends Base {
180
179
  if (!versionCheck.installed) {
181
180
  payload.status = 'unhealthy';
182
181
  payload.githubCli.details.push(versionCheck.error);
182
+ // Emit a short structured diagnostic line so monitoring/CI can detect
183
+ // that `gh` is missing without parsing free-form logs.
184
+ // Example: `[HealthService] gh-status: missing; reason=GitHub CLI is not installed...`
185
+ logger.info(`[HealthService] gh-status: missing; reason=${versionCheck.error}`);
186
+
183
187
  return payload;
184
188
  }
185
189
 
@@ -201,16 +205,61 @@ class HealthService extends Base {
201
205
  if (!authCheck.authenticated) {
202
206
  payload.status = 'unhealthy';
203
207
  payload.githubCli.details.push(authCheck.error);
208
+ logger.info('[HealthService] gh-status: unauthenticated');
204
209
  }
205
210
 
206
211
  // If we made it here with no issues, everything is healthy
207
212
  if (payload.status === 'healthy') {
208
213
  payload.githubCli.details.push('GitHub CLI is installed, authenticated, and up to date.');
214
+ logger.info('[HealthService] gh-status: healthy');
209
215
  }
210
216
 
211
217
  return payload;
212
218
  }
213
219
 
220
+ // ---- inlined helpers from healthHelpers.mjs (moved here as private methods) ----
221
+ #combineOutput(stdout, stderr) {
222
+ return `${stdout || ''}\n${stderr || ''}`;
223
+ }
224
+
225
+ #parseAuthOutput(out) {
226
+ if (typeof out !== 'string') out = String(out || '');
227
+ if (out.includes('Logged in to github.com')) {
228
+ return { authenticated: true };
229
+ }
230
+ return { authenticated: false, error: 'Not logged in to github.com. Please run `gh auth login`.' };
231
+ }
232
+
233
+ #parseVersionOutput(out, minVersion = '2.0.0') {
234
+ if (typeof out !== 'string') out = String(out || '');
235
+
236
+ // Match version string, including pre-release versions
237
+ const m = out.match(/gh version ([\d.]+(?:-[\w.]+)?)/);
238
+ if (!m) {
239
+ return { installed: false, versionOk: false, version: null, error: 'GitHub CLI is not installed. Please install it from https://cli.github.com/' };
240
+ }
241
+ const version = m[1];
242
+ try {
243
+ // Use semver library for robust version comparison
244
+ // Handles edge cases like pre-release versions (e.g., v11.0.0-alpha.2)
245
+ const versionOk = semver.gte(version, minVersion);
246
+
247
+ if (versionOk) return { installed: true, versionOk: true, version };
248
+ return { installed: true, versionOk: false, version, error: `gh version (${version}) is outdated. Please upgrade to at least ${minVersion}.` };
249
+ } catch (e) {
250
+ return { installed: true, versionOk: false, version, error: `Could not parse gh version: ${e.message}` };
251
+ }
252
+ }
253
+
254
+ #interpretExecError(err) {
255
+ if (!err) return false;
256
+ if (err.code === 'ENOENT') return true;
257
+ const msg = String(err.message || err || '');
258
+ if (/not found|ENOENT|is not recognized as an internal or external command/i.test(msg)) return true;
259
+ return false;
260
+ }
261
+ // ---- end inlined helpers ----
262
+
214
263
  /**
215
264
  * Public API: Checks the health of the GitHub CLI with intelligent caching.
216
265
  *