@bongos/core 1.19.289 → 1.19.291
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.
- package/.bongos-core.json +25 -20
- package/.claude/skills/idea-triage/SKILL.md +32 -2
- package/docs/copy-inventory.md +15 -13
- package/docs/copy-registry.json +32 -14
- package/modules/dev-box/app/src/vendor/bongos-client.cjs +8 -0
- package/modules/hall-ui/public/task-detail.js +75 -0
- package/package-lock.json +121 -2
- package/package.json +3 -2
- package/scripts/gds/package-core.js +7 -4
- package/scripts/gds/triage.js +98 -7
- package/src/module-api.js +5 -1
- package/tests/cutover_codemod.mjs +1 -1
- package/tests/package_core.mjs +6 -6
- package/tests/promote_goal_id.mjs +316 -0
- package/tests/pruned_lockfile_integrity.mjs +2 -2
package/package-lock.json
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.291",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.291",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
|
13
13
|
"pg": "^8.20.0"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
+
"node_modules/@pinojs/redact": {
|
|
17
|
+
"version": "0.4.0",
|
|
18
|
+
"resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz",
|
|
19
|
+
"integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==",
|
|
20
|
+
"license": "MIT"
|
|
21
|
+
},
|
|
16
22
|
"node_modules/accepts": {
|
|
17
23
|
"version": "1.3.8",
|
|
18
24
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
|
@@ -32,6 +38,15 @@
|
|
|
32
38
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
|
33
39
|
"license": "MIT"
|
|
34
40
|
},
|
|
41
|
+
"node_modules/atomic-sleep": {
|
|
42
|
+
"version": "1.0.0",
|
|
43
|
+
"resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
|
|
44
|
+
"integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=8.0.0"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
35
50
|
"node_modules/body-parser": {
|
|
36
51
|
"version": "1.20.5",
|
|
37
52
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz",
|
|
@@ -539,6 +554,15 @@
|
|
|
539
554
|
"url": "https://github.com/sponsors/ljharb"
|
|
540
555
|
}
|
|
541
556
|
},
|
|
557
|
+
"node_modules/on-exit-leak-free": {
|
|
558
|
+
"version": "2.1.2",
|
|
559
|
+
"resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz",
|
|
560
|
+
"integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==",
|
|
561
|
+
"license": "MIT",
|
|
562
|
+
"engines": {
|
|
563
|
+
"node": ">=14.0.0"
|
|
564
|
+
}
|
|
565
|
+
},
|
|
542
566
|
"node_modules/on-finished": {
|
|
543
567
|
"version": "2.4.1",
|
|
544
568
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
|
@@ -655,6 +679,43 @@
|
|
|
655
679
|
"split2": "^4.1.0"
|
|
656
680
|
}
|
|
657
681
|
},
|
|
682
|
+
"node_modules/pino": {
|
|
683
|
+
"version": "9.14.0",
|
|
684
|
+
"resolved": "https://registry.npmjs.org/pino/-/pino-9.14.0.tgz",
|
|
685
|
+
"integrity": "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==",
|
|
686
|
+
"license": "MIT",
|
|
687
|
+
"dependencies": {
|
|
688
|
+
"@pinojs/redact": "^0.4.0",
|
|
689
|
+
"atomic-sleep": "^1.0.0",
|
|
690
|
+
"on-exit-leak-free": "^2.1.0",
|
|
691
|
+
"pino-abstract-transport": "^2.0.0",
|
|
692
|
+
"pino-std-serializers": "^7.0.0",
|
|
693
|
+
"process-warning": "^5.0.0",
|
|
694
|
+
"quick-format-unescaped": "^4.0.3",
|
|
695
|
+
"real-require": "^0.2.0",
|
|
696
|
+
"safe-stable-stringify": "^2.3.1",
|
|
697
|
+
"sonic-boom": "^4.0.1",
|
|
698
|
+
"thread-stream": "^3.0.0"
|
|
699
|
+
},
|
|
700
|
+
"bin": {
|
|
701
|
+
"pino": "bin.js"
|
|
702
|
+
}
|
|
703
|
+
},
|
|
704
|
+
"node_modules/pino-abstract-transport": {
|
|
705
|
+
"version": "2.0.0",
|
|
706
|
+
"resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz",
|
|
707
|
+
"integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==",
|
|
708
|
+
"license": "MIT",
|
|
709
|
+
"dependencies": {
|
|
710
|
+
"split2": "^4.0.0"
|
|
711
|
+
}
|
|
712
|
+
},
|
|
713
|
+
"node_modules/pino-std-serializers": {
|
|
714
|
+
"version": "7.1.0",
|
|
715
|
+
"resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz",
|
|
716
|
+
"integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==",
|
|
717
|
+
"license": "MIT"
|
|
718
|
+
},
|
|
658
719
|
"node_modules/postgres-array": {
|
|
659
720
|
"version": "2.0.0",
|
|
660
721
|
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
|
|
@@ -694,6 +755,22 @@
|
|
|
694
755
|
"node": ">=0.10.0"
|
|
695
756
|
}
|
|
696
757
|
},
|
|
758
|
+
"node_modules/process-warning": {
|
|
759
|
+
"version": "5.1.0",
|
|
760
|
+
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.1.0.tgz",
|
|
761
|
+
"integrity": "sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw==",
|
|
762
|
+
"funding": [
|
|
763
|
+
{
|
|
764
|
+
"type": "github",
|
|
765
|
+
"url": "https://github.com/sponsors/fastify"
|
|
766
|
+
},
|
|
767
|
+
{
|
|
768
|
+
"type": "opencollective",
|
|
769
|
+
"url": "https://opencollective.com/fastify"
|
|
770
|
+
}
|
|
771
|
+
],
|
|
772
|
+
"license": "MIT"
|
|
773
|
+
},
|
|
697
774
|
"node_modules/proxy-addr": {
|
|
698
775
|
"version": "2.0.7",
|
|
699
776
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
|
@@ -722,6 +799,12 @@
|
|
|
722
799
|
"url": "https://github.com/sponsors/ljharb"
|
|
723
800
|
}
|
|
724
801
|
},
|
|
802
|
+
"node_modules/quick-format-unescaped": {
|
|
803
|
+
"version": "4.0.4",
|
|
804
|
+
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
|
|
805
|
+
"integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==",
|
|
806
|
+
"license": "MIT"
|
|
807
|
+
},
|
|
725
808
|
"node_modules/range-parser": {
|
|
726
809
|
"version": "1.2.1",
|
|
727
810
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
|
@@ -746,6 +829,15 @@
|
|
|
746
829
|
"node": ">= 0.8"
|
|
747
830
|
}
|
|
748
831
|
},
|
|
832
|
+
"node_modules/real-require": {
|
|
833
|
+
"version": "0.2.0",
|
|
834
|
+
"resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz",
|
|
835
|
+
"integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==",
|
|
836
|
+
"license": "MIT",
|
|
837
|
+
"engines": {
|
|
838
|
+
"node": ">= 12.13.0"
|
|
839
|
+
}
|
|
840
|
+
},
|
|
749
841
|
"node_modules/safe-buffer": {
|
|
750
842
|
"version": "5.2.1",
|
|
751
843
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
|
@@ -766,6 +858,15 @@
|
|
|
766
858
|
],
|
|
767
859
|
"license": "MIT"
|
|
768
860
|
},
|
|
861
|
+
"node_modules/safe-stable-stringify": {
|
|
862
|
+
"version": "2.5.0",
|
|
863
|
+
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
|
|
864
|
+
"integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
|
|
865
|
+
"license": "MIT",
|
|
866
|
+
"engines": {
|
|
867
|
+
"node": ">=10"
|
|
868
|
+
}
|
|
869
|
+
},
|
|
769
870
|
"node_modules/safer-buffer": {
|
|
770
871
|
"version": "2.1.2",
|
|
771
872
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
|
@@ -895,6 +996,15 @@
|
|
|
895
996
|
"url": "https://github.com/sponsors/ljharb"
|
|
896
997
|
}
|
|
897
998
|
},
|
|
999
|
+
"node_modules/sonic-boom": {
|
|
1000
|
+
"version": "4.2.1",
|
|
1001
|
+
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz",
|
|
1002
|
+
"integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==",
|
|
1003
|
+
"license": "MIT",
|
|
1004
|
+
"dependencies": {
|
|
1005
|
+
"atomic-sleep": "^1.0.0"
|
|
1006
|
+
}
|
|
1007
|
+
},
|
|
898
1008
|
"node_modules/split2": {
|
|
899
1009
|
"version": "4.2.0",
|
|
900
1010
|
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
|
@@ -913,6 +1023,15 @@
|
|
|
913
1023
|
"node": ">= 0.8"
|
|
914
1024
|
}
|
|
915
1025
|
},
|
|
1026
|
+
"node_modules/thread-stream": {
|
|
1027
|
+
"version": "3.2.0",
|
|
1028
|
+
"resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.2.0.tgz",
|
|
1029
|
+
"integrity": "sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==",
|
|
1030
|
+
"license": "MIT",
|
|
1031
|
+
"dependencies": {
|
|
1032
|
+
"real-require": "^0.2.0"
|
|
1033
|
+
}
|
|
1034
|
+
},
|
|
916
1035
|
"node_modules/toidentifier": {
|
|
917
1036
|
"version": "1.0.1",
|
|
918
1037
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.291",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"express": "^4.21.2",
|
|
28
|
-
"pg": "^8.20.0"
|
|
28
|
+
"pg": "^8.20.0",
|
|
29
|
+
"pino": "^9.14.0"
|
|
29
30
|
},
|
|
30
31
|
"overrides": {
|
|
31
32
|
"undici": "^6.27.0"
|
|
@@ -252,10 +252,13 @@ function isNpmStripped(pathRel) {
|
|
|
252
252
|
// git) and staged in their place. Everything else still ships through the
|
|
253
253
|
// normal isPublishable()/processCoreFile path.
|
|
254
254
|
//
|
|
255
|
-
// Core deps are express + pg (+ an undici pin) — ADR 0108 §Context.
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
|
|
255
|
+
// Core deps are express + pg + pino (+ an undici pin) — ADR 0108 §Context.
|
|
256
|
+
// pino joined the core boot path with the structured logger (task 1003130:
|
|
257
|
+
// platform-server → serve-internal → routes → middleware/audit → logger); a
|
|
258
|
+
// published core without it crashes MODULE_NOT_FOUND at startup (task 1003160).
|
|
259
|
+
// discord.js (+ its undici requirement) is an OPTIONAL MODULE dependency, not
|
|
260
|
+
// core; a consumer that enables the discord module installs it itself.
|
|
261
|
+
const CORE_DEP_NAMES = ['express', 'pg', 'pino'];
|
|
259
262
|
|
|
260
263
|
// Pure — takes the source package.json's `dependencies`/`overrides` as plain
|
|
261
264
|
// objects so this is unit-testable with no disk I/O. Throws if a required core
|
package/scripts/gds/triage.js
CHANGED
|
@@ -151,11 +151,80 @@ async function patchIdea(id, patch) {
|
|
|
151
151
|
return r.data?.idea;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
// resolveGoalDefault — what goal should a triaged promotion land in? (task
|
|
155
|
+
// 1003071 / R13.)
|
|
156
|
+
//
|
|
157
|
+
// PRECEDENCE IS DELIBERATE:
|
|
158
|
+
// 1. `idea.suggested_goal_id` — the STORED hint. inbox.captureIdea writes it
|
|
159
|
+
// even when the matrix declined to route, precisely so "/idea-triage
|
|
160
|
+
// inherits the guess instead of re-deriving it" (core_222, its own comment).
|
|
161
|
+
// A human or a filing surface already named this goal; a heuristic must not
|
|
162
|
+
// overrule that.
|
|
163
|
+
// 2. the R07 suggester (GET /goals/suggestions) — only when there is no hint.
|
|
164
|
+
// Best-scoring candidate, and its score/matched_terms are shown so the
|
|
165
|
+
// operator can see WHY before accepting.
|
|
166
|
+
// Returns { goalId, label, source } — goalId null when neither yields anything.
|
|
167
|
+
// The caller prints `source` as provenance, because "the suggester guessed this"
|
|
168
|
+
// and "the filing already named this" deserve different trust. Never throws: a
|
|
169
|
+
// suggester outage degrades to "no default", it does not block a triage verdict.
|
|
170
|
+
//
|
|
171
|
+
// `client` is injectable so the precedence can be driven end-to-end in a test
|
|
172
|
+
// rather than pattern-matched in the source. (Task 1003102 shipped a handler
|
|
173
|
+
// whose collaborators were not injectable; its tests read the source, passed,
|
|
174
|
+
// and the route 500'd on every call. Not repeating that.)
|
|
175
|
+
async function resolveGoalDefault(idea, versionId, { client = cliClient } = {}) {
|
|
176
|
+
// Guarded: a junk stored value must not become goalId NaN and then a goal_id
|
|
177
|
+
// the server rejects with 400 on every retry.
|
|
178
|
+
const hint = Number(idea.suggested_goal_id);
|
|
179
|
+
if (Number.isInteger(hint) && hint > 0) {
|
|
180
|
+
return { goalId: hint, label: `goal ${hint}`, source: 'hint' };
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
const api = await client();
|
|
184
|
+
// The GENERATED typed method (regenerated when R07 landed), not the generic
|
|
185
|
+
// request() escape hatch — so a path or param rename reds the client build.
|
|
186
|
+
const r = await api.goals.getGoalsSuggestions({
|
|
187
|
+
query: { version: versionId, title: idea.title || '', body: (idea.body_md || '').slice(0, 2000), limit: 3 },
|
|
188
|
+
});
|
|
189
|
+
const top = r.ok && r.data && Array.isArray(r.data.suggestions) ? r.data.suggestions[0] : null;
|
|
190
|
+
if (!top) return { goalId: null, label: null, source: 'none' };
|
|
191
|
+
const why = (top.matched_terms || []).join('/');
|
|
192
|
+
return { goalId: Number(top.id), label: `${top.id} ${trim(top.title, 44)} (score ${top.score}${why ? ' · ' + why : ''})`, source: 'suggester' };
|
|
193
|
+
} catch (_) {
|
|
194
|
+
return { goalId: null, label: null, source: 'unavailable' };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// What the operator's answer to the goal prompt means. Blank ACCEPTS the shown
|
|
199
|
+
// default — declining has to be said ('-' or 'none'), because silently dropping a
|
|
200
|
+
// real default on a bare Enter is how work ends up in the general bucket by
|
|
201
|
+
// accident. Declining is legal: the server then applies the catch-all itself.
|
|
202
|
+
function applyGoalAnswer(defaultGoalId, rawAnswer) {
|
|
203
|
+
const answer = String(rawAnswer == null ? '' : rawAnswer).trim();
|
|
204
|
+
if (answer === '') return { goalId: defaultGoalId, warn: null };
|
|
205
|
+
if (answer === '-' || answer.toLowerCase() === 'none') return { goalId: null, warn: null };
|
|
206
|
+
const parsed = Number(answer);
|
|
207
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
208
|
+
return { goalId: null, warn: "not a goal id — falling back to the version's general bucket" };
|
|
209
|
+
}
|
|
210
|
+
return { goalId: parsed, warn: null };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function createTask({ versionId, title, description, priority, sourceRef, goalId = null }) {
|
|
214
|
+
// (The old note here said POST /api/gds/tasks does not accept 'kind'. That is
|
|
215
|
+
// no longer true — routes/tasks.js takes it, and the hall promote path already
|
|
216
|
+
// sends it. Left un-sent from THIS path deliberately: changing what kind a
|
|
217
|
+
// triaged promotion lands with is a behaviour change task R13 was not asked to
|
|
218
|
+
// make, and the server classifier still runs. Corrected rather than deleted so
|
|
219
|
+
// the next reader does not re-derive it.)
|
|
220
|
+
//
|
|
221
|
+
// task 1003071 (R13): goal_id is the point of this task. Omitting it does NOT
|
|
222
|
+
// leave the task goal-less — db.createTask (modules/lifecycle/db.js) defaults a
|
|
223
|
+
// goal-less create into the version's catch-all "<version> — general" goal. That
|
|
224
|
+
// bucket is the actual defect: it carries no done-when criteria, so since ADR
|
|
225
|
+
// 0183 made criteria close themselves off LINKED tasks, work parked there can
|
|
226
|
+
// never advance anything, and it does not read as real goal work on the board.
|
|
227
|
+
// Naming the goal here is what stops a triaged promotion falling into it.
|
|
159
228
|
const body = {
|
|
160
229
|
version_id: versionId,
|
|
161
230
|
title,
|
|
@@ -165,6 +234,7 @@ async function createTask({ versionId, title, description, priority, sourceRef }
|
|
|
165
234
|
source: 'idea_inbox',
|
|
166
235
|
source_ref: sourceRef ?? null,
|
|
167
236
|
};
|
|
237
|
+
if (goalId != null) body.goal_id = Number(goalId);
|
|
168
238
|
const api = await cliClient();
|
|
169
239
|
const r = await api.tasks.postTasks({ body });
|
|
170
240
|
if (!r.ok) {
|
|
@@ -296,7 +366,7 @@ async function main() {
|
|
|
296
366
|
}
|
|
297
367
|
|
|
298
368
|
if (ans === 'p' || ans === 'promote') {
|
|
299
|
-
// Promote:
|
|
369
|
+
// Promote: version, priority, title, goal — each defaulted from the idea.
|
|
300
370
|
const defaultVersion = idea.suggested_version || 'PMS-V2';
|
|
301
371
|
const versionAns = (await prompt(rl, ` version [${defaultVersion}]: `)).trim();
|
|
302
372
|
const versionId = versionAns || defaultVersion;
|
|
@@ -308,6 +378,23 @@ async function main() {
|
|
|
308
378
|
const titleAns = (await prompt(rl, ` title [${trim(idea.title, 60)}]: `)).trim();
|
|
309
379
|
const title = titleAns || idea.title;
|
|
310
380
|
|
|
381
|
+
// task 1003071 (R13): a triaged promotion NAMES its goal. The default
|
|
382
|
+
// comes from the stored hint, else the R07 suggester; '-' opts out
|
|
383
|
+
// explicitly, which falls through to the version's catch-all "general"
|
|
384
|
+
// bucket — now a choice someone typed rather than the silent default.
|
|
385
|
+
// The EFFECTIVE title, not idea.title: the suggester matches on title
|
|
386
|
+
// terms, and the operator may just have retitled this.
|
|
387
|
+
const gd = await resolveGoalDefault({ ...idea, title }, versionId);
|
|
388
|
+
if (gd.source === 'suggester') console.log(` suggested goal: ${gd.label}`);
|
|
389
|
+
if (gd.source === 'unavailable') console.log(' (goal suggester unreachable — enter a goal id, or "-" to accept the general bucket)');
|
|
390
|
+
const goalPrompt = gd.goalId != null
|
|
391
|
+
? ` goal [${gd.goalId}] ("-" for the version's general bucket): `
|
|
392
|
+
: ' goal (blank/"-" for the version\'s general bucket): ';
|
|
393
|
+
const goalAns = (await prompt(rl, goalPrompt)).trim();
|
|
394
|
+
const picked = applyGoalAnswer(gd.goalId, goalAns);
|
|
395
|
+
if (picked.warn) console.log(` ! ${picked.warn}`);
|
|
396
|
+
const goalId = picked.goalId;
|
|
397
|
+
|
|
311
398
|
try {
|
|
312
399
|
const task = await createTask({
|
|
313
400
|
versionId,
|
|
@@ -315,6 +402,7 @@ async function main() {
|
|
|
315
402
|
description: idea.body_md || '',
|
|
316
403
|
priority: Number.isFinite(priority) ? priority : null,
|
|
317
404
|
sourceRef: `idea:${idea.id}`,
|
|
405
|
+
goalId,
|
|
318
406
|
});
|
|
319
407
|
await patchIdea(idea.id, {
|
|
320
408
|
status: 'promoted',
|
|
@@ -323,7 +411,7 @@ async function main() {
|
|
|
323
411
|
});
|
|
324
412
|
summary.promoted++;
|
|
325
413
|
promotedIds.push({ ideaId: idea.id, taskId: task.id });
|
|
326
|
-
console.log(` ✓ promoted #${idea.id} → task #${task.id} (${versionId}, P${priority})`);
|
|
414
|
+
console.log(` ✓ promoted #${idea.id} → task #${task.id} (${versionId}, P${priority}${goalId != null ? `, goal ${goalId}` : ', → general bucket'})`);
|
|
327
415
|
} catch (err) {
|
|
328
416
|
console.error(` ! ${err.message}`);
|
|
329
417
|
}
|
|
@@ -360,6 +448,9 @@ if (require.main === module) {
|
|
|
360
448
|
}
|
|
361
449
|
|
|
362
450
|
module.exports = {
|
|
451
|
+
resolveGoalDefault,
|
|
452
|
+
applyGoalAnswer,
|
|
453
|
+
createTask,
|
|
363
454
|
resolveDevelopmentPath,
|
|
364
455
|
parseDevelopment,
|
|
365
456
|
loadDevelopment,
|
package/src/module-api.js
CHANGED
|
@@ -1005,8 +1005,12 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
|
|
|
1005
1005
|
// landed since 1.19.287 with no explicit bump. run 32546561232. (task 1002620)
|
|
1006
1006
|
// 1.19.289 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1007
1007
|
// landed since 1.19.288 with no explicit bump. run 32549912116. (task 1002620)
|
|
1008
|
+
// 1.19.290 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1009
|
+
// landed since 1.19.289 with no explicit bump. run 32552538814. (task 1002620)
|
|
1010
|
+
// 1.19.291 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1011
|
+
// landed since 1.19.290 with no explicit bump. run 32580353000. (task 1002620)
|
|
1008
1012
|
// ---------------------------------------------------------------------------
|
|
1009
|
-
const CORE_VERSION = '1.19.
|
|
1013
|
+
const CORE_VERSION = '1.19.291'; // CI auto-patch carrier (ADR 0161); see changelog above
|
|
1010
1014
|
|
|
1011
1015
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
1012
1016
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
|
@@ -174,7 +174,7 @@ t('planCodemod rewrites host files, skips core files, reports unmapped', () => {
|
|
|
174
174
|
|
|
175
175
|
t('every CORE_INTERNAL_MAP target is exported by the core package (a rewrite never outruns an export)', () => {
|
|
176
176
|
const { buildPackageJson } = require('../scripts/gds/package-core.js');
|
|
177
|
-
const pkg = buildPackageJson({ version: '0.0.0-test', sourceDeps: { express: '^4.0.0', pg: '^8.0.0' } });
|
|
177
|
+
const pkg = buildPackageJson({ version: '0.0.0-test', sourceDeps: { express: '^4.0.0', pg: '^8.0.0', pino: '^9.0.0' } });
|
|
178
178
|
for (const mapped of Object.values(CORE_INTERNAL_MAP)) {
|
|
179
179
|
assert.ok(pkg.exports[`./${mapped}`], `@bongos/core must export ./${mapped} (targeted by the codemod)`);
|
|
180
180
|
}
|
package/tests/package_core.mjs
CHANGED
|
@@ -360,15 +360,15 @@ t('TAR_ROOT is the npm-required "package/" (not the ARTIFACT_NAME dir)', () => {
|
|
|
360
360
|
assert.equal(TAR_ROOT, 'package/');
|
|
361
361
|
});
|
|
362
362
|
|
|
363
|
-
t('buildPackageJson: prunes to express+pg, keeps the source ranges + the undici override', () => {
|
|
363
|
+
t('buildPackageJson: prunes to express+pg+pino, keeps the source ranges + the undici override', () => {
|
|
364
364
|
const pkg = buildPackageJson({
|
|
365
365
|
version: '1.14.0',
|
|
366
|
-
sourceDeps: { express: '^4.21.2', pg: '^8.20.0', phaser: '^3.87.0', 'discord.js': '^14.26.4' },
|
|
366
|
+
sourceDeps: { express: '^4.21.2', pg: '^8.20.0', pino: '^9.14.0', phaser: '^3.87.0', 'discord.js': '^14.26.4' },
|
|
367
367
|
sourceOverrides: { undici: '^6.27.0' },
|
|
368
368
|
});
|
|
369
369
|
assert.equal(pkg.name, '@bongos/core');
|
|
370
370
|
assert.equal(pkg.version, '1.14.0');
|
|
371
|
-
assert.deepEqual(pkg.dependencies, { express: '^4.21.2', pg: '^8.20.0' });
|
|
371
|
+
assert.deepEqual(pkg.dependencies, { express: '^4.21.2', pg: '^8.20.0', pino: '^9.14.0' });
|
|
372
372
|
assert.equal(pkg.dependencies.phaser, undefined);
|
|
373
373
|
assert.equal(pkg.dependencies['discord.js'], undefined);
|
|
374
374
|
assert.deepEqual(pkg.overrides, { undici: '^6.27.0' });
|
|
@@ -400,7 +400,7 @@ t('publishArgs: private (restricted) publish, dry-run unless live (task 2089 / A
|
|
|
400
400
|
});
|
|
401
401
|
|
|
402
402
|
t('buildPackageJson: omits `overrides` when the source has none', () => {
|
|
403
|
-
const pkg = buildPackageJson({ version: '1.0.0', sourceDeps: { express: '^4.0.0', pg: '^8.0.0' } });
|
|
403
|
+
const pkg = buildPackageJson({ version: '1.0.0', sourceDeps: { express: '^4.0.0', pg: '^8.0.0', pino: '^9.0.0' } });
|
|
404
404
|
assert.equal(pkg.overrides, undefined);
|
|
405
405
|
});
|
|
406
406
|
|
|
@@ -408,8 +408,8 @@ t('buildPackageJson: throws when a required core dep is missing from the source'
|
|
|
408
408
|
assert.throws(() => buildPackageJson({ version: '1.0.0', sourceDeps: { express: '^4.0.0' } }), /missing required core dependency "pg"/);
|
|
409
409
|
});
|
|
410
410
|
|
|
411
|
-
t('CORE_DEP_NAMES is exactly [express, pg]', () => {
|
|
412
|
-
assert.deepEqual(CORE_DEP_NAMES, ['express', 'pg']);
|
|
411
|
+
t('CORE_DEP_NAMES is exactly [express, pg, pino]', () => {
|
|
412
|
+
assert.deepEqual(CORE_DEP_NAMES, ['express', 'pg', 'pino']);
|
|
413
413
|
});
|
|
414
414
|
|
|
415
415
|
// A tiny synthetic lockfile fixture with a THREE-level chain (root -> a -> b) and
|