nexus-agents 2.133.0 → 2.134.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.
- package/dist/{child-mcp-config-R67B2KM6.js → child-mcp-config-TWHH63UK.js} +3 -3
- package/dist/{chunk-GYDO2WOR.js → chunk-33MFMXBQ.js} +5 -5
- package/dist/{chunk-VZCQRLXT.js → chunk-3EYXPV5F.js} +7 -7
- package/dist/{chunk-RLYXX3FQ.js → chunk-6LMZ7HFU.js} +2 -2
- package/dist/{chunk-4CLBJ2NA.js → chunk-6UCWR3DS.js} +3 -3
- package/dist/{chunk-RJEP2AZW.js → chunk-76R5ES6Z.js} +36 -36
- package/dist/{chunk-RJEP2AZW.js.map → chunk-76R5ES6Z.js.map} +1 -1
- package/dist/{chunk-HGUO36KW.js → chunk-7GSYICTL.js} +8 -8
- package/dist/{chunk-ZVBGZBW5.js → chunk-7TQZR5VU.js} +114 -7
- package/dist/chunk-7TQZR5VU.js.map +1 -0
- package/dist/{chunk-2CLFX73Y.js → chunk-B26FGLIJ.js} +2 -2
- package/dist/{chunk-27DRQWON.js → chunk-BTYYZ6VU.js} +4 -4
- package/dist/{chunk-K5WBFAR4.js → chunk-CLRSNWRQ.js} +4 -4
- package/dist/{chunk-TGGR6ST5.js → chunk-COJOUIO2.js} +3 -3
- package/dist/{chunk-QJIHSQZX.js → chunk-DBDWMHUL.js} +65 -14
- package/dist/chunk-DBDWMHUL.js.map +1 -0
- package/dist/{chunk-4CVITS5D.js → chunk-DLUFDKPA.js} +9 -9
- package/dist/{chunk-PM63X3QG.js → chunk-E64SZTEP.js} +3 -3
- package/dist/{chunk-QMCHVYZB.js → chunk-EHLJLIHS.js} +2 -2
- package/dist/{chunk-ZTRBMKXK.js → chunk-F74ZGHAP.js} +2 -2
- package/dist/{chunk-NZGNOXXW.js → chunk-FPMQ2JAK.js} +2 -2
- package/dist/{chunk-4DLHM6LI.js → chunk-FSFF7EFR.js} +2 -2
- package/dist/{chunk-J435FU54.js → chunk-FUJ3XR7T.js} +4 -4
- package/dist/{chunk-CI5KGCX5.js → chunk-FVSZLVMR.js} +3 -3
- package/dist/{chunk-RUSP5PJR.js → chunk-GZ4NF4ZW.js} +5 -1
- package/dist/{chunk-RUSP5PJR.js.map → chunk-GZ4NF4ZW.js.map} +1 -1
- package/dist/{chunk-DETYVPZO.js → chunk-IWQH6TP7.js} +6 -6
- package/dist/{chunk-ZQEQVCIU.js → chunk-MY52DFXC.js} +2 -2
- package/dist/{chunk-FKTLAPXJ.js → chunk-OCKZ6F5O.js} +3 -3
- package/dist/{chunk-E4IYX7LD.js → chunk-ORQAFTAZ.js} +2 -2
- package/dist/{chunk-QLRH6KOT.js → chunk-OU2NQVKD.js} +2 -2
- package/dist/{chunk-7BONPRR2.js → chunk-PFBV5FCT.js} +2 -2
- package/dist/{chunk-S4U3Z6ZS.js → chunk-QZUT22LP.js} +6 -6
- package/dist/{chunk-EFDXX5MC.js → chunk-UDB5NHJI.js} +3 -3
- package/dist/{chunk-RAWF4JOT.js → chunk-VI7LELES.js} +7 -7
- package/dist/{chunk-ECDJM6UB.js → chunk-WFKVUZ3O.js} +2 -2
- package/dist/{chunk-XIFOAZ5B.js → chunk-WYJJUF6N.js} +4 -4
- package/dist/{chunk-GET2MTLW.js → chunk-Z6DXZ6AS.js} +2 -2
- package/dist/{chunk-WHZD2W6Q.js → chunk-ZMDOGN33.js} +2 -2
- package/dist/{cli-circuit-breaker-J6UFONNE.js → cli-circuit-breaker-VXBDCAD7.js} +5 -5
- package/dist/cli.js +844 -155
- package/dist/cli.js.map +1 -1
- package/dist/{composite-router-HQUSCJO4.js → composite-router-E6FXXMMR.js} +3 -3
- package/dist/{consensus-vote-MVZ27Y43.js → consensus-vote-R6X5IL57.js} +15 -15
- package/dist/{context-retriever-5OVRAWNZ.js → context-retriever-I4NEOUEV.js} +9 -9
- package/dist/{doctor-deep-HJ3NQ365.js → doctor-deep-CZXN4YD6.js} +4 -4
- package/dist/{expert-bridge-MINXBC73.js → expert-bridge-GMB5IHHF.js} +5 -5
- package/dist/factory-WR62MEIJ.js +14 -0
- package/dist/factory-ZBQGA373.js +21 -0
- package/dist/{improvement-review-ZL3364R2.js → improvement-review-77BKIQGN.js} +5 -5
- package/dist/index.d.ts +210 -192
- package/dist/index.js +30 -30
- package/dist/{init-opencode-L3NT524E.js → init-opencode-4H2VPN23.js} +7 -7
- package/dist/issue-triage-NJB6SL4S.js +16 -0
- package/dist/{learning-persistence-QFCQ5POD.js → learning-persistence-2KO4CXNL.js} +2 -2
- package/dist/{pr-reviewer-helpers-PLKDVWYF.js → pr-reviewer-helpers-F3SHCHNV.js} +5 -5
- package/dist/{registry-command-HPKNLYUL.js → registry-command-VFCSMHME.js} +3 -3
- package/dist/{repo-security-plan-HSYGGVEJ.js → repo-security-plan-U2ZIFW53.js} +4 -4
- package/dist/research-helpers-synthesize-5TLNHT3I.js +14 -0
- package/dist/{routing-memory-OGUOL7UF.js → routing-memory-VVLJL3MG.js} +3 -3
- package/dist/{session-memory-HQWAXH3C.js → session-memory-GMQYZLJE.js} +4 -4
- package/dist/{setup-command-CIXJXFPC.js → setup-command-IMAX6EAO.js} +12 -12
- package/dist/setup-config-2ZSJ3HNE.js +10 -0
- package/dist/{setup-custom-api-W7EDVKWR.js → setup-custom-api-NJGCRIRO.js} +4 -4
- package/dist/{tool-memory-Z2B7CAH7.js → tool-memory-TSYJXGOV.js} +6 -6
- package/dist/unified-registry-IMAL3SY6.js +24 -0
- package/dist/{weather-report-GX7OIUL2.js → weather-report-OU65NJS3.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-QJIHSQZX.js.map +0 -1
- package/dist/chunk-ZVBGZBW5.js.map +0 -1
- package/dist/factory-KC7BYHAP.js +0 -21
- package/dist/factory-ZG2FZYVA.js +0 -14
- package/dist/issue-triage-CZPFNGB7.js +0 -16
- package/dist/research-helpers-synthesize-IQHDU27S.js +0 -14
- package/dist/setup-config-HYX3BRSE.js +0 -10
- package/dist/unified-registry-UFNSWKZA.js +0 -24
- /package/dist/{child-mcp-config-R67B2KM6.js.map → child-mcp-config-TWHH63UK.js.map} +0 -0
- /package/dist/{chunk-GYDO2WOR.js.map → chunk-33MFMXBQ.js.map} +0 -0
- /package/dist/{chunk-VZCQRLXT.js.map → chunk-3EYXPV5F.js.map} +0 -0
- /package/dist/{chunk-RLYXX3FQ.js.map → chunk-6LMZ7HFU.js.map} +0 -0
- /package/dist/{chunk-4CLBJ2NA.js.map → chunk-6UCWR3DS.js.map} +0 -0
- /package/dist/{chunk-HGUO36KW.js.map → chunk-7GSYICTL.js.map} +0 -0
- /package/dist/{chunk-2CLFX73Y.js.map → chunk-B26FGLIJ.js.map} +0 -0
- /package/dist/{chunk-27DRQWON.js.map → chunk-BTYYZ6VU.js.map} +0 -0
- /package/dist/{chunk-K5WBFAR4.js.map → chunk-CLRSNWRQ.js.map} +0 -0
- /package/dist/{chunk-TGGR6ST5.js.map → chunk-COJOUIO2.js.map} +0 -0
- /package/dist/{chunk-4CVITS5D.js.map → chunk-DLUFDKPA.js.map} +0 -0
- /package/dist/{chunk-PM63X3QG.js.map → chunk-E64SZTEP.js.map} +0 -0
- /package/dist/{chunk-QMCHVYZB.js.map → chunk-EHLJLIHS.js.map} +0 -0
- /package/dist/{chunk-ZTRBMKXK.js.map → chunk-F74ZGHAP.js.map} +0 -0
- /package/dist/{chunk-NZGNOXXW.js.map → chunk-FPMQ2JAK.js.map} +0 -0
- /package/dist/{chunk-4DLHM6LI.js.map → chunk-FSFF7EFR.js.map} +0 -0
- /package/dist/{chunk-J435FU54.js.map → chunk-FUJ3XR7T.js.map} +0 -0
- /package/dist/{chunk-CI5KGCX5.js.map → chunk-FVSZLVMR.js.map} +0 -0
- /package/dist/{chunk-DETYVPZO.js.map → chunk-IWQH6TP7.js.map} +0 -0
- /package/dist/{chunk-ZQEQVCIU.js.map → chunk-MY52DFXC.js.map} +0 -0
- /package/dist/{chunk-FKTLAPXJ.js.map → chunk-OCKZ6F5O.js.map} +0 -0
- /package/dist/{chunk-E4IYX7LD.js.map → chunk-ORQAFTAZ.js.map} +0 -0
- /package/dist/{chunk-QLRH6KOT.js.map → chunk-OU2NQVKD.js.map} +0 -0
- /package/dist/{chunk-7BONPRR2.js.map → chunk-PFBV5FCT.js.map} +0 -0
- /package/dist/{chunk-S4U3Z6ZS.js.map → chunk-QZUT22LP.js.map} +0 -0
- /package/dist/{chunk-EFDXX5MC.js.map → chunk-UDB5NHJI.js.map} +0 -0
- /package/dist/{chunk-RAWF4JOT.js.map → chunk-VI7LELES.js.map} +0 -0
- /package/dist/{chunk-ECDJM6UB.js.map → chunk-WFKVUZ3O.js.map} +0 -0
- /package/dist/{chunk-XIFOAZ5B.js.map → chunk-WYJJUF6N.js.map} +0 -0
- /package/dist/{chunk-GET2MTLW.js.map → chunk-Z6DXZ6AS.js.map} +0 -0
- /package/dist/{chunk-WHZD2W6Q.js.map → chunk-ZMDOGN33.js.map} +0 -0
- /package/dist/{cli-circuit-breaker-J6UFONNE.js.map → cli-circuit-breaker-VXBDCAD7.js.map} +0 -0
- /package/dist/{composite-router-HQUSCJO4.js.map → composite-router-E6FXXMMR.js.map} +0 -0
- /package/dist/{consensus-vote-MVZ27Y43.js.map → consensus-vote-R6X5IL57.js.map} +0 -0
- /package/dist/{context-retriever-5OVRAWNZ.js.map → context-retriever-I4NEOUEV.js.map} +0 -0
- /package/dist/{doctor-deep-HJ3NQ365.js.map → doctor-deep-CZXN4YD6.js.map} +0 -0
- /package/dist/{expert-bridge-MINXBC73.js.map → expert-bridge-GMB5IHHF.js.map} +0 -0
- /package/dist/{factory-KC7BYHAP.js.map → factory-WR62MEIJ.js.map} +0 -0
- /package/dist/{factory-ZG2FZYVA.js.map → factory-ZBQGA373.js.map} +0 -0
- /package/dist/{improvement-review-ZL3364R2.js.map → improvement-review-77BKIQGN.js.map} +0 -0
- /package/dist/{init-opencode-L3NT524E.js.map → init-opencode-4H2VPN23.js.map} +0 -0
- /package/dist/{issue-triage-CZPFNGB7.js.map → issue-triage-NJB6SL4S.js.map} +0 -0
- /package/dist/{learning-persistence-QFCQ5POD.js.map → learning-persistence-2KO4CXNL.js.map} +0 -0
- /package/dist/{pr-reviewer-helpers-PLKDVWYF.js.map → pr-reviewer-helpers-F3SHCHNV.js.map} +0 -0
- /package/dist/{registry-command-HPKNLYUL.js.map → registry-command-VFCSMHME.js.map} +0 -0
- /package/dist/{repo-security-plan-HSYGGVEJ.js.map → repo-security-plan-U2ZIFW53.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-IQHDU27S.js.map → research-helpers-synthesize-5TLNHT3I.js.map} +0 -0
- /package/dist/{routing-memory-OGUOL7UF.js.map → routing-memory-VVLJL3MG.js.map} +0 -0
- /package/dist/{session-memory-HQWAXH3C.js.map → session-memory-GMQYZLJE.js.map} +0 -0
- /package/dist/{setup-command-CIXJXFPC.js.map → setup-command-IMAX6EAO.js.map} +0 -0
- /package/dist/{setup-config-HYX3BRSE.js.map → setup-config-2ZSJ3HNE.js.map} +0 -0
- /package/dist/{setup-custom-api-W7EDVKWR.js.map → setup-custom-api-NJGCRIRO.js.map} +0 -0
- /package/dist/{tool-memory-Z2B7CAH7.js.map → tool-memory-TSYJXGOV.js.map} +0 -0
- /package/dist/{unified-registry-UFNSWKZA.js.map → unified-registry-IMAL3SY6.js.map} +0 -0
- /package/dist/{weather-report-GX7OIUL2.js.map → weather-report-OU65NJS3.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -13,17 +13,17 @@ import {
|
|
|
13
13
|
generateSummary,
|
|
14
14
|
parseFindings,
|
|
15
15
|
sumFindings
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-OCKZ6F5O.js";
|
|
17
|
+
import "./chunk-6LMZ7HFU.js";
|
|
18
18
|
import {
|
|
19
19
|
buildOpenAICompatAdapters,
|
|
20
20
|
readOpenAICompatEnv
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-BTYYZ6VU.js";
|
|
22
22
|
import {
|
|
23
23
|
setupCommandAsync,
|
|
24
24
|
verifyCommand
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-IWQH6TP7.js";
|
|
26
|
+
import "./chunk-OU2NQVKD.js";
|
|
27
27
|
import {
|
|
28
28
|
AuthHandler,
|
|
29
29
|
DEFAULT_EXPERTS,
|
|
@@ -142,18 +142,18 @@ import {
|
|
|
142
142
|
validateCommand,
|
|
143
143
|
validateWorkflow,
|
|
144
144
|
wrapInMarkdownFence
|
|
145
|
-
} from "./chunk-
|
|
146
|
-
import "./chunk-
|
|
145
|
+
} from "./chunk-76R5ES6Z.js";
|
|
146
|
+
import "./chunk-Z6DXZ6AS.js";
|
|
147
147
|
import "./chunk-3ACDP4E6.js";
|
|
148
148
|
import {
|
|
149
149
|
CATEGORY_DISPLAY_NAMES,
|
|
150
150
|
DEFAULT_PR_REVIEW_CONFIG
|
|
151
151
|
} from "./chunk-WAYGXUSM.js";
|
|
152
|
-
import "./chunk-
|
|
153
|
-
import "./chunk-
|
|
152
|
+
import "./chunk-E64SZTEP.js";
|
|
153
|
+
import "./chunk-FVSZLVMR.js";
|
|
154
154
|
import {
|
|
155
155
|
shutdownExpertBridge
|
|
156
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-VI7LELES.js";
|
|
157
157
|
import {
|
|
158
158
|
ConsensusVoteInputSchema,
|
|
159
159
|
DEFAULT_VOTE_TIMEOUT_MS,
|
|
@@ -162,25 +162,25 @@ import {
|
|
|
162
162
|
VoteThresholdSchema,
|
|
163
163
|
executeVoting,
|
|
164
164
|
registerConsensusVoteTool
|
|
165
|
-
} from "./chunk-
|
|
165
|
+
} from "./chunk-DLUFDKPA.js";
|
|
166
166
|
import {
|
|
167
167
|
loadUsageEvents,
|
|
168
168
|
rollupByModel
|
|
169
|
-
} from "./chunk-
|
|
169
|
+
} from "./chunk-COJOUIO2.js";
|
|
170
170
|
import {
|
|
171
171
|
synthesizeResearch
|
|
172
|
-
} from "./chunk-
|
|
172
|
+
} from "./chunk-UDB5NHJI.js";
|
|
173
173
|
import {
|
|
174
174
|
classifyTrust,
|
|
175
175
|
createFullGitHubProvider,
|
|
176
176
|
evaluatePolicy,
|
|
177
177
|
parsePRUrl
|
|
178
|
-
} from "./chunk-
|
|
179
|
-
import "./chunk-
|
|
178
|
+
} from "./chunk-FUJ3XR7T.js";
|
|
179
|
+
import "./chunk-FSFF7EFR.js";
|
|
180
180
|
import {
|
|
181
181
|
ReputationCache,
|
|
182
182
|
sanitizeInput
|
|
183
|
-
} from "./chunk-
|
|
183
|
+
} from "./chunk-EHLJLIHS.js";
|
|
184
184
|
import {
|
|
185
185
|
ImprovementReviewInputSchema,
|
|
186
186
|
calculateFitnessScore,
|
|
@@ -194,10 +194,10 @@ import {
|
|
|
194
194
|
registerImprovementReviewTool,
|
|
195
195
|
runImprovementReview,
|
|
196
196
|
scanForSecrets
|
|
197
|
-
} from "./chunk-
|
|
197
|
+
} from "./chunk-7TQZR5VU.js";
|
|
198
198
|
import {
|
|
199
199
|
createDefaultPolicyFirewall
|
|
200
|
-
} from "./chunk-
|
|
200
|
+
} from "./chunk-6UCWR3DS.js";
|
|
201
201
|
import "./chunk-HFOQKCD2.js";
|
|
202
202
|
import {
|
|
203
203
|
PaperStatusSchema,
|
|
@@ -221,20 +221,20 @@ import {
|
|
|
221
221
|
loadSourcesRegistry,
|
|
222
222
|
rankDiscoveredItems,
|
|
223
223
|
saveSourcesRegistry
|
|
224
|
-
} from "./chunk-
|
|
224
|
+
} from "./chunk-QZUT22LP.js";
|
|
225
225
|
import {
|
|
226
226
|
resolveToken
|
|
227
|
-
} from "./chunk-
|
|
227
|
+
} from "./chunk-MY52DFXC.js";
|
|
228
228
|
import {
|
|
229
229
|
loadPapersRegistry,
|
|
230
230
|
loadTechniquesRegistry,
|
|
231
231
|
savePapersRegistry
|
|
232
|
-
} from "./chunk-
|
|
232
|
+
} from "./chunk-B26FGLIJ.js";
|
|
233
233
|
import {
|
|
234
234
|
MemoryError,
|
|
235
235
|
shutdownToolMemory
|
|
236
|
-
} from "./chunk-
|
|
237
|
-
import "./chunk-
|
|
236
|
+
} from "./chunk-33MFMXBQ.js";
|
|
237
|
+
import "./chunk-FPMQ2JAK.js";
|
|
238
238
|
import {
|
|
239
239
|
CustomExpertDefinitionSchema,
|
|
240
240
|
DATA_SUBDIRECTORIES,
|
|
@@ -254,7 +254,7 @@ import {
|
|
|
254
254
|
loadConfig,
|
|
255
255
|
runDoctor,
|
|
256
256
|
validateNexusEnv
|
|
257
|
-
} from "./chunk-
|
|
257
|
+
} from "./chunk-7GSYICTL.js";
|
|
258
258
|
import "./chunk-NUBSJGQZ.js";
|
|
259
259
|
import {
|
|
260
260
|
capitalize,
|
|
@@ -265,20 +265,20 @@ import "./chunk-ZM4O442V.js";
|
|
|
265
265
|
import "./chunk-PQHVC4BD.js";
|
|
266
266
|
import {
|
|
267
267
|
createUnifiedRegistry
|
|
268
|
-
} from "./chunk-
|
|
268
|
+
} from "./chunk-WYJJUF6N.js";
|
|
269
269
|
import {
|
|
270
270
|
createAllAdapters,
|
|
271
271
|
getAvailableClis,
|
|
272
272
|
isRecord,
|
|
273
273
|
probeAllClis
|
|
274
|
-
} from "./chunk-
|
|
274
|
+
} from "./chunk-3EYXPV5F.js";
|
|
275
275
|
import {
|
|
276
276
|
DEFAULTS
|
|
277
|
-
} from "./chunk-
|
|
278
|
-
import "./chunk-
|
|
279
|
-
import "./chunk-
|
|
280
|
-
import "./chunk-
|
|
281
|
-
import "./chunk-
|
|
277
|
+
} from "./chunk-ZMDOGN33.js";
|
|
278
|
+
import "./chunk-WFKVUZ3O.js";
|
|
279
|
+
import "./chunk-F74ZGHAP.js";
|
|
280
|
+
import "./chunk-PFBV5FCT.js";
|
|
281
|
+
import "./chunk-ORQAFTAZ.js";
|
|
282
282
|
import {
|
|
283
283
|
API_TIMEOUTS,
|
|
284
284
|
AgentCapability,
|
|
@@ -352,16 +352,16 @@ import {
|
|
|
352
352
|
validateTimeout,
|
|
353
353
|
writeEmptyLine,
|
|
354
354
|
writeLine
|
|
355
|
-
} from "./chunk-
|
|
355
|
+
} from "./chunk-DBDWMHUL.js";
|
|
356
356
|
import {
|
|
357
357
|
applyPortableMode,
|
|
358
358
|
detectSandbox,
|
|
359
359
|
findRepoRoot,
|
|
360
|
-
getNexusDataDir,
|
|
361
360
|
getPerRepoSubdirs,
|
|
362
361
|
nexusDataPath,
|
|
362
|
+
nexusSharedPath,
|
|
363
363
|
sessionsDbPath
|
|
364
|
-
} from "./chunk-
|
|
364
|
+
} from "./chunk-GZ4NF4ZW.js";
|
|
365
365
|
import "./chunk-ZPWHCABL.js";
|
|
366
366
|
|
|
367
367
|
// src/cli/cli-log-bootstrap.ts
|
|
@@ -1629,14 +1629,14 @@ ${colors.dim}Session ended.${colors.reset}
|
|
|
1629
1629
|
});
|
|
1630
1630
|
});
|
|
1631
1631
|
rl.prompt();
|
|
1632
|
-
return new Promise((
|
|
1632
|
+
return new Promise((resolve14) => {
|
|
1633
1633
|
rl.on("line", (line) => {
|
|
1634
1634
|
void (async () => {
|
|
1635
1635
|
try {
|
|
1636
1636
|
const shouldExit = await processLine(line, session, logger19);
|
|
1637
1637
|
if (shouldExit) {
|
|
1638
1638
|
rl.close();
|
|
1639
|
-
|
|
1639
|
+
resolve14();
|
|
1640
1640
|
return;
|
|
1641
1641
|
}
|
|
1642
1642
|
} catch (error) {
|
|
@@ -1648,7 +1648,7 @@ ${colors.dim}Session ended.${colors.reset}
|
|
|
1648
1648
|
})();
|
|
1649
1649
|
});
|
|
1650
1650
|
rl.on("close", () => {
|
|
1651
|
-
|
|
1651
|
+
resolve14();
|
|
1652
1652
|
});
|
|
1653
1653
|
});
|
|
1654
1654
|
}
|
|
@@ -2984,7 +2984,10 @@ var COMMAND_CATALOG = [
|
|
|
2984
2984
|
},
|
|
2985
2985
|
{
|
|
2986
2986
|
command: "vote",
|
|
2987
|
-
|
|
2987
|
+
// Default panel is 7 roles; `--quick` runs 3 (getVoterRoles in
|
|
2988
|
+
// mcp/tools/consensus-vote.ts). Prior drift: "5-6 agents" here, "6 agents"
|
|
2989
|
+
// in HELP_TEXT, "6 agents by default" in COMMAND_HELP — all wrong (#3209).
|
|
2990
|
+
description: "Run consensus vote on a proposal (7 agents; --quick uses 3)",
|
|
2988
2991
|
audience: "essential"
|
|
2989
2992
|
},
|
|
2990
2993
|
{
|
|
@@ -3227,6 +3230,9 @@ function filterCatalog(showAll) {
|
|
|
3227
3230
|
function catalogForExtractors() {
|
|
3228
3231
|
return COMMAND_CATALOG.filter((e) => e.command !== "(default)");
|
|
3229
3232
|
}
|
|
3233
|
+
function getCommandDescription(command) {
|
|
3234
|
+
return COMMAND_CATALOG.find((e) => e.command === command)?.description;
|
|
3235
|
+
}
|
|
3230
3236
|
function groupByAudience(entries) {
|
|
3231
3237
|
const groups = /* @__PURE__ */ new Map();
|
|
3232
3238
|
for (const entry of entries) {
|
|
@@ -3265,7 +3271,8 @@ function renderCommandsSection(showAll) {
|
|
|
3265
3271
|
}
|
|
3266
3272
|
|
|
3267
3273
|
// src/cli-help-text.ts
|
|
3268
|
-
var
|
|
3274
|
+
var COMMANDS_PLACEHOLDER = "__COMMANDS__";
|
|
3275
|
+
var HELP_TEXT_FRAME = `
|
|
3269
3276
|
nexus-agents - Intelligent orchestration platform for AI coding tools
|
|
3270
3277
|
|
|
3271
3278
|
USAGE:
|
|
@@ -3273,44 +3280,7 @@ USAGE:
|
|
|
3273
3280
|
nexus-agents [COMMAND] [SUBCOMMAND] [OPTIONS]
|
|
3274
3281
|
|
|
3275
3282
|
COMMANDS:
|
|
3276
|
-
|
|
3277
|
-
hello Show welcome message and quick start (no API keys needed)
|
|
3278
|
-
demo API-free exploration mode (no API keys needed)
|
|
3279
|
-
setup Configure Claude CLI integration (MCP + CLAUDE.md rules)
|
|
3280
|
-
login Show per-CLI auth status + login fix instructions
|
|
3281
|
-
verify Quick installation verification (no API keys needed)
|
|
3282
|
-
doctor Check CLI installations and health status
|
|
3283
|
-
config Manage configuration (init, get, set, list, reset, export, import)
|
|
3284
|
-
expert list List available experts (built-in and custom)
|
|
3285
|
-
workflow list List available workflow templates
|
|
3286
|
-
workflow run Execute a workflow template
|
|
3287
|
-
review <url> Review a GitHub pull request (dogfooding)
|
|
3288
|
-
routing-audit Debug model routing decisions
|
|
3289
|
-
orchestrate Execute task using CLI tools (standalone mode)
|
|
3290
|
-
vote Run consensus vote on a proposal (6 agents)
|
|
3291
|
-
system-review Run automated system review (5-phase checklist)
|
|
3292
|
-
sprint Automated sprint planning from open issues
|
|
3293
|
-
session Manage session persistence (list, show, export, delete, prune)
|
|
3294
|
-
evaluate Self-evaluation of codebase components
|
|
3295
|
-
issue Issue template validation and management
|
|
3296
|
-
index Generate and manage codebase index
|
|
3297
|
-
research Manage research registry and index
|
|
3298
|
-
validation Show learning validation dashboard
|
|
3299
|
-
learning-metrics Show aggregated learning metrics dashboard
|
|
3300
|
-
swe-bench Run SWE-bench evaluation benchmark
|
|
3301
|
-
atbench Run ATBench trajectory-safety evaluation (#1981)
|
|
3302
|
-
hooks Claude CLI hook integration commands
|
|
3303
|
-
fitness-audit Run CLI orchestration fitness score audit
|
|
3304
|
-
release-notes Generate release notes from git commits
|
|
3305
|
-
release-validate Run expert swarm validation for releases
|
|
3306
|
-
release-announce Generate release announcements (blog, Bluesky)
|
|
3307
|
-
scaffold Generate project files from templates (tool, expert, workflow, command)
|
|
3308
|
-
visualize Generate Mermaid diagrams and ASCII dashboards (architecture, swarm, flow)
|
|
3309
|
-
capabilities Show model capabilities matrix (modalities, tools, features)
|
|
3310
|
-
status At-a-glance project health dashboard (fitness, adapters, version)
|
|
3311
|
-
health Swarm health metrics dashboard (utilization, routing accuracy, failures)
|
|
3312
|
-
validate Run unified validation (doctor + fitness + config)
|
|
3313
|
-
auth Manage MCP authentication tokens (init, show, rotate)
|
|
3283
|
+
${COMMANDS_PLACEHOLDER}
|
|
3314
3284
|
|
|
3315
3285
|
OPTIONS:
|
|
3316
3286
|
-h, --help Show this help message
|
|
@@ -3336,14 +3306,13 @@ EXAMPLES:
|
|
|
3336
3306
|
|
|
3337
3307
|
For more information, visit: https://github.com/nexus-substrate/nexus-agents
|
|
3338
3308
|
`.trim();
|
|
3339
|
-
|
|
3309
|
+
function composeHelp(commandsSection) {
|
|
3310
|
+
return HELP_TEXT_FRAME.replace(COMMANDS_PLACEHOLDER, commandsSection);
|
|
3311
|
+
}
|
|
3312
|
+
var HELP_TEXT = composeHelp(renderCommandsSection(true));
|
|
3340
3313
|
function renderHelp(opts) {
|
|
3341
3314
|
if (opts.all) return HELP_TEXT;
|
|
3342
|
-
|
|
3343
|
-
return HELP_TEXT.replace(COMMANDS_BLOCK_RE, `COMMANDS:
|
|
3344
|
-
${replacement}
|
|
3345
|
-
|
|
3346
|
-
OPTIONS:`);
|
|
3315
|
+
return composeHelp(renderCommandsSection(false));
|
|
3347
3316
|
}
|
|
3348
3317
|
|
|
3349
3318
|
// src/cli-types.ts
|
|
@@ -4055,7 +4024,7 @@ ${file.patch}
|
|
|
4055
4024
|
violations: policyResult.violations
|
|
4056
4025
|
});
|
|
4057
4026
|
}
|
|
4058
|
-
const { formatReviewComment: formatReviewComment2 } = await import("./pr-reviewer-helpers-
|
|
4027
|
+
const { formatReviewComment: formatReviewComment2 } = await import("./pr-reviewer-helpers-F3SHCHNV.js");
|
|
4059
4028
|
const body = formatReviewComment2(result);
|
|
4060
4029
|
const postResult = await provider.createReview(pr.prNumber, body, result.decision);
|
|
4061
4030
|
if (!postResult.ok) {
|
|
@@ -12987,7 +12956,7 @@ function writeResultAndExit(result) {
|
|
|
12987
12956
|
|
|
12988
12957
|
// src/cli/hooks/hook-router.ts
|
|
12989
12958
|
async function readStdin() {
|
|
12990
|
-
return new Promise((
|
|
12959
|
+
return new Promise((resolve14, reject) => {
|
|
12991
12960
|
let data = "";
|
|
12992
12961
|
process.stdin.setEncoding("utf8");
|
|
12993
12962
|
process.stdin.on("readable", () => {
|
|
@@ -12998,24 +12967,24 @@ async function readStdin() {
|
|
|
12998
12967
|
}
|
|
12999
12968
|
});
|
|
13000
12969
|
process.stdin.on("end", () => {
|
|
13001
|
-
|
|
12970
|
+
resolve14(data);
|
|
13002
12971
|
});
|
|
13003
12972
|
process.stdin.on("error", (err2) => {
|
|
13004
12973
|
reject(err2);
|
|
13005
12974
|
});
|
|
13006
12975
|
if (process.stdin.isTTY) {
|
|
13007
|
-
|
|
12976
|
+
resolve14("");
|
|
13008
12977
|
}
|
|
13009
12978
|
});
|
|
13010
12979
|
}
|
|
13011
12980
|
async function readStdinWithTimeout(timeoutMs = 5e3) {
|
|
13012
|
-
return new Promise((
|
|
12981
|
+
return new Promise((resolve14, reject) => {
|
|
13013
12982
|
const timeout2 = setTimeout(() => {
|
|
13014
12983
|
reject(new Error(`Stdin read timeout after ${String(timeoutMs)}ms`));
|
|
13015
12984
|
}, timeoutMs);
|
|
13016
12985
|
readStdin().then((data) => {
|
|
13017
12986
|
clearTimeout(timeout2);
|
|
13018
|
-
|
|
12987
|
+
resolve14(data);
|
|
13019
12988
|
}).catch((err2) => {
|
|
13020
12989
|
clearTimeout(timeout2);
|
|
13021
12990
|
reject(err2 instanceof Error ? err2 : new Error(String(err2)));
|
|
@@ -14505,9 +14474,9 @@ function interactiveIO() {
|
|
|
14505
14474
|
write: (text) => {
|
|
14506
14475
|
process.stdout.write(text);
|
|
14507
14476
|
},
|
|
14508
|
-
prompt: (question) => new Promise((
|
|
14477
|
+
prompt: (question) => new Promise((resolve14) => {
|
|
14509
14478
|
rl.question(question, (answer) => {
|
|
14510
|
-
|
|
14479
|
+
resolve14(answer.trim());
|
|
14511
14480
|
});
|
|
14512
14481
|
}),
|
|
14513
14482
|
close: () => {
|
|
@@ -16956,9 +16925,6 @@ function authCommand(subcommand, options) {
|
|
|
16956
16925
|
return result.success;
|
|
16957
16926
|
}
|
|
16958
16927
|
|
|
16959
|
-
// src/cli-commands-handlers.ts
|
|
16960
|
-
import { existsSync as existsSync22 } from "fs";
|
|
16961
|
-
|
|
16962
16928
|
// src/cli/init-portable.ts
|
|
16963
16929
|
import {
|
|
16964
16930
|
existsSync as existsSync21,
|
|
@@ -17042,8 +17008,8 @@ function autoGitignoreMcpConfig(workspaceDir, dryRun) {
|
|
|
17042
17008
|
if (already) return false;
|
|
17043
17009
|
}
|
|
17044
17010
|
if (!dryRun) {
|
|
17045
|
-
const
|
|
17046
|
-
appendFileSync(gitignorePath, `${
|
|
17011
|
+
const sep4 = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
|
|
17012
|
+
appendFileSync(gitignorePath, `${sep4}${MCP_CONFIG_FILENAME}
|
|
17047
17013
|
`, "utf-8");
|
|
17048
17014
|
}
|
|
17049
17015
|
return true;
|
|
@@ -17282,8 +17248,8 @@ function maybeUpdateGitignore(workspaceDir, portableDirName, dryRun) {
|
|
|
17282
17248
|
}
|
|
17283
17249
|
}
|
|
17284
17250
|
if (!dryRun) {
|
|
17285
|
-
const
|
|
17286
|
-
appendFileSync2(gitignorePath, `${
|
|
17251
|
+
const sep4 = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
|
|
17252
|
+
appendFileSync2(gitignorePath, `${sep4}${entry}
|
|
17287
17253
|
`, "utf-8");
|
|
17288
17254
|
}
|
|
17289
17255
|
return true;
|
|
@@ -17831,7 +17797,7 @@ function startImprovementReviewScheduler(options) {
|
|
|
17831
17797
|
let running = false;
|
|
17832
17798
|
const runOnce = async () => {
|
|
17833
17799
|
try {
|
|
17834
|
-
const { runImprovementReview: runImprovementReview2, ImprovementReviewInputSchema: ImprovementReviewInputSchema2 } = await import("./improvement-review-
|
|
17800
|
+
const { runImprovementReview: runImprovementReview2, ImprovementReviewInputSchema: ImprovementReviewInputSchema2 } = await import("./improvement-review-77BKIQGN.js");
|
|
17835
17801
|
const input = ImprovementReviewInputSchema2.parse({ fileIssues });
|
|
17836
17802
|
const result = await runImprovementReview2(input, { logger: logger19 });
|
|
17837
17803
|
logger19.info("Scheduled improvement_review complete", {
|
|
@@ -18219,8 +18185,8 @@ async function initUpstreamServers(gatewayConfig, server, logger19) {
|
|
|
18219
18185
|
servers: upstreamServers.length,
|
|
18220
18186
|
tools: tools.length
|
|
18221
18187
|
});
|
|
18222
|
-
const { z:
|
|
18223
|
-
const passthroughSchema =
|
|
18188
|
+
const { z: z14 } = await import("zod");
|
|
18189
|
+
const passthroughSchema = z14.looseObject({});
|
|
18224
18190
|
for (const tool of tools) {
|
|
18225
18191
|
const toolName = tool.name;
|
|
18226
18192
|
const desc = tool.description ?? `Upstream tool: ${toolName}`;
|
|
@@ -18617,7 +18583,7 @@ async function executeReplTask(task, options, logger19, rl) {
|
|
|
18617
18583
|
}
|
|
18618
18584
|
}
|
|
18619
18585
|
function runOrchestratorRepl(options, logger19) {
|
|
18620
|
-
return new Promise((
|
|
18586
|
+
return new Promise((resolve14) => {
|
|
18621
18587
|
const rl = readline2.createInterface({
|
|
18622
18588
|
input: process.stdin,
|
|
18623
18589
|
output: process.stdout,
|
|
@@ -18640,7 +18606,7 @@ function runOrchestratorRepl(options, logger19) {
|
|
|
18640
18606
|
});
|
|
18641
18607
|
rl.on("close", () => {
|
|
18642
18608
|
logger19.info("Orchestrator REPL closed");
|
|
18643
|
-
|
|
18609
|
+
resolve14();
|
|
18644
18610
|
});
|
|
18645
18611
|
});
|
|
18646
18612
|
}
|
|
@@ -19774,7 +19740,7 @@ function adaptConfigToLibrary(config) {
|
|
|
19774
19740
|
}
|
|
19775
19741
|
function createBeliefPromoter() {
|
|
19776
19742
|
return async (event) => {
|
|
19777
|
-
const { getToolMemory } = await import("./tool-memory-
|
|
19743
|
+
const { getToolMemory } = await import("./tool-memory-TSYJXGOV.js");
|
|
19778
19744
|
const tm = getToolMemory();
|
|
19779
19745
|
await tm.recordBelief(
|
|
19780
19746
|
`skill:${event.name}`,
|
|
@@ -20517,18 +20483,7 @@ function buildOrchestratorOptions(args) {
|
|
|
20517
20483
|
...args.options.maxCostUsd !== void 0 && { maxCostUsd: args.options.maxCostUsd }
|
|
20518
20484
|
};
|
|
20519
20485
|
}
|
|
20520
|
-
function printFirstRunHint() {
|
|
20521
|
-
const isTTY = process.stderr.isTTY;
|
|
20522
|
-
if (!isTTY) return;
|
|
20523
|
-
const dataDir = getNexusDataDir();
|
|
20524
|
-
const hasConfig = existsSync22("./.nexus-agents/nexus-agents.yaml") || existsSync22("./.nexus-agents/nexus-agents.yml") || existsSync22("./nexus-agents.yaml") || existsSync22("./nexus-agents.yml");
|
|
20525
|
-
if (existsSync22(dataDir) || hasConfig) return;
|
|
20526
|
-
process.stderr.write(
|
|
20527
|
-
"\n\x1B[36mnexus-agents\x1B[0m: First time? Run \x1B[1mnexus-agents setup\x1B[0m to configure.\n\n"
|
|
20528
|
-
);
|
|
20529
|
-
}
|
|
20530
20486
|
async function handleServerCommand(args) {
|
|
20531
|
-
printFirstRunHint();
|
|
20532
20487
|
if (args.options.interactive) {
|
|
20533
20488
|
const exitCode = await replCommand({ verbose: args.options.verbose });
|
|
20534
20489
|
return cliExitFromStatus(exitCode);
|
|
@@ -20638,7 +20593,7 @@ async function handleResearchCommand(args) {
|
|
|
20638
20593
|
}
|
|
20639
20594
|
}
|
|
20640
20595
|
async function handleRegistryCommand(args) {
|
|
20641
|
-
const { registryCommand, isValidRegistrySubcommand, formatRegistryUsage } = await import("./registry-command-
|
|
20596
|
+
const { registryCommand, isValidRegistrySubcommand, formatRegistryUsage } = await import("./registry-command-VFCSMHME.js");
|
|
20642
20597
|
const subcommand = args.subcommand;
|
|
20643
20598
|
if (!isValidRegistrySubcommand(subcommand)) {
|
|
20644
20599
|
process.stdout.write(`${formatRegistryUsage()}
|
|
@@ -20686,7 +20641,7 @@ async function handleVerifyCommand(args) {
|
|
|
20686
20641
|
async function handleDoctorCommand(args) {
|
|
20687
20642
|
const exitCode = await doctorCommand({ fix: args.options.fix });
|
|
20688
20643
|
if (args.options.deep) {
|
|
20689
|
-
const { runDeepDiagnostics: runDeepDiagnostics2, formatDeepDiagnostics: formatDeepDiagnostics2 } = await import("./doctor-deep-
|
|
20644
|
+
const { runDeepDiagnostics: runDeepDiagnostics2, formatDeepDiagnostics: formatDeepDiagnostics2 } = await import("./doctor-deep-CZXN4YD6.js");
|
|
20690
20645
|
const diag = runDeepDiagnostics2();
|
|
20691
20646
|
process.stdout.write(formatDeepDiagnostics2(diag) + "\n");
|
|
20692
20647
|
}
|
|
@@ -20736,7 +20691,7 @@ async function runInitPortableFlow(args) {
|
|
|
20736
20691
|
return cliExit(result.success ? EXIT_CODES.SUCCESS : EXIT_CODES.SERVER_START_FAILED);
|
|
20737
20692
|
}
|
|
20738
20693
|
async function runInitOpencodeFlow(args) {
|
|
20739
|
-
const { runInitOpencode } = await import("./init-opencode-
|
|
20694
|
+
const { runInitOpencode } = await import("./init-opencode-4H2VPN23.js");
|
|
20740
20695
|
const opencodePath = args.options.opencode;
|
|
20741
20696
|
if (opencodePath === void 0 || opencodePath === "") {
|
|
20742
20697
|
process.stderr.write("Error: --opencode requires a path argument.\n");
|
|
@@ -20762,7 +20717,7 @@ async function runInitOpencodeFlow(args) {
|
|
|
20762
20717
|
return cliExit(EXIT_CODES.SUCCESS);
|
|
20763
20718
|
}
|
|
20764
20719
|
async function renderOpencodeValidate(opencodePath) {
|
|
20765
|
-
const { runOpencodeValidate } = await import("./init-opencode-
|
|
20720
|
+
const { runOpencodeValidate } = await import("./init-opencode-4H2VPN23.js");
|
|
20766
20721
|
const result = await runOpencodeValidate(opencodePath);
|
|
20767
20722
|
if (!result.ok) {
|
|
20768
20723
|
process.stderr.write(`init --opencode --validate: ${result.reason ?? "failed"}
|
|
@@ -20801,7 +20756,7 @@ async function handleSetupCommandAsync(args) {
|
|
|
20801
20756
|
return cliExitFromStatus(exitCode);
|
|
20802
20757
|
}
|
|
20803
20758
|
async function runCustomApiSetup(args) {
|
|
20804
|
-
const { configureCustomApi } = await import("./setup-custom-api-
|
|
20759
|
+
const { configureCustomApi } = await import("./setup-custom-api-NJGCRIRO.js");
|
|
20805
20760
|
const baseUrl = args.options.customApi;
|
|
20806
20761
|
if (baseUrl === void 0) return EXIT_CODES.SERVER_START_FAILED;
|
|
20807
20762
|
const input = {
|
|
@@ -22534,7 +22489,7 @@ function checkCircularDependencies(workflow) {
|
|
|
22534
22489
|
var defaultStubFactory = {
|
|
22535
22490
|
createAgentStub(agentType, action) {
|
|
22536
22491
|
return async (inputs) => {
|
|
22537
|
-
await new Promise((
|
|
22492
|
+
await new Promise((resolve14) => setTimeout(resolve14, 10));
|
|
22538
22493
|
return {
|
|
22539
22494
|
stepId: `${agentType}-${action}`,
|
|
22540
22495
|
status: "success",
|
|
@@ -23162,7 +23117,10 @@ var ACTION_BY_CATEGORY = {
|
|
|
23162
23117
|
consensus: "investigate",
|
|
23163
23118
|
// #3852: a deprecation/consolidation candidate is a human decision, never an
|
|
23164
23119
|
// autonomous code change — investigate only (Epic D ratification path).
|
|
23165
|
-
"tool-fitness": "investigate"
|
|
23120
|
+
"tool-fitness": "investigate",
|
|
23121
|
+
// #3692/#3246: a perf regression needs root-cause diagnosis before any change —
|
|
23122
|
+
// investigate only; the surfaced signal never auto-applies a fix.
|
|
23123
|
+
"perf-regression": "investigate"
|
|
23166
23124
|
};
|
|
23167
23125
|
function clip(s, max) {
|
|
23168
23126
|
return s.length > max ? s.slice(0, max) : s;
|
|
@@ -23343,8 +23301,16 @@ var RemediationStepSchema = z9.object({
|
|
|
23343
23301
|
var RemediationPlanSchema = z9.object({
|
|
23344
23302
|
/** Source signal key (mirrors ImprovementSignal.signalKey). */
|
|
23345
23303
|
signalKey: z9.string().min(1).max(200),
|
|
23346
|
-
/** Signal category (mirrors SignalCategory; 'tool-fitness'
|
|
23347
|
-
category: z9.enum([
|
|
23304
|
+
/** Signal category (mirrors SignalCategory; 'tool-fitness' #3852, 'perf-regression' #3692). */
|
|
23305
|
+
category: z9.enum([
|
|
23306
|
+
"routing",
|
|
23307
|
+
"tech-debt",
|
|
23308
|
+
"bug",
|
|
23309
|
+
"security",
|
|
23310
|
+
"consensus",
|
|
23311
|
+
"tool-fitness",
|
|
23312
|
+
"perf-regression"
|
|
23313
|
+
]),
|
|
23348
23314
|
summary: z9.string().min(1).max(1e3),
|
|
23349
23315
|
steps: z9.array(RemediationStepSchema).min(1).max(20)
|
|
23350
23316
|
}).strict();
|
|
@@ -23428,13 +23394,13 @@ function makeProposalPrImplementAdapter(opts) {
|
|
|
23428
23394
|
};
|
|
23429
23395
|
}
|
|
23430
23396
|
function makeGitWorktreeOps(repoRoot) {
|
|
23431
|
-
const
|
|
23397
|
+
const git2 = async (args, cwd) => {
|
|
23432
23398
|
await execFileAsync4("git", [...args], { cwd });
|
|
23433
23399
|
};
|
|
23434
23400
|
return {
|
|
23435
23401
|
async addWorktree(branch, baseBranch) {
|
|
23436
23402
|
const path21 = join19(repoRoot, ".nexus-worktrees", branch.replace(/\//g, "_"));
|
|
23437
|
-
await
|
|
23403
|
+
await git2(["worktree", "add", "-b", branch, path21, baseBranch], repoRoot);
|
|
23438
23404
|
return path21;
|
|
23439
23405
|
},
|
|
23440
23406
|
async writeFileIn(worktreePath, relPath, content) {
|
|
@@ -23443,14 +23409,14 @@ function makeGitWorktreeOps(repoRoot) {
|
|
|
23443
23409
|
await writeFile6(abs, content, "utf8");
|
|
23444
23410
|
},
|
|
23445
23411
|
async commitAll(worktreePath, message) {
|
|
23446
|
-
await
|
|
23447
|
-
await
|
|
23412
|
+
await git2(["add", "-A"], worktreePath);
|
|
23413
|
+
await git2(["commit", "-m", message], worktreePath);
|
|
23448
23414
|
},
|
|
23449
23415
|
async pushBranch(worktreePath, branch) {
|
|
23450
|
-
await
|
|
23416
|
+
await git2(["push", "-u", "origin", branch], worktreePath);
|
|
23451
23417
|
},
|
|
23452
23418
|
async removeWorktree(worktreePath) {
|
|
23453
|
-
await
|
|
23419
|
+
await git2(["worktree", "remove", worktreePath, "--force"], repoRoot);
|
|
23454
23420
|
}
|
|
23455
23421
|
};
|
|
23456
23422
|
}
|
|
@@ -23632,6 +23598,689 @@ function buildAutoRemediationDeps(opts = {}) {
|
|
|
23632
23598
|
};
|
|
23633
23599
|
}
|
|
23634
23600
|
|
|
23601
|
+
// src/mcp/tools/codepr-soak-consumer.ts
|
|
23602
|
+
import { createHash as createHash4 } from "crypto";
|
|
23603
|
+
|
|
23604
|
+
// src/mcp/tools/codepr-orchestrator.ts
|
|
23605
|
+
import { createHash as createHash3 } from "crypto";
|
|
23606
|
+
import { mkdtempSync, mkdirSync as mkdirSync6, writeFileSync as writeFileSync8, rmSync as rmSync2, realpathSync as realpathSync2 } from "fs";
|
|
23607
|
+
import { tmpdir } from "os";
|
|
23608
|
+
import { dirname as dirname13, join as join20 } from "path";
|
|
23609
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
23610
|
+
import { z as z12 } from "zod";
|
|
23611
|
+
|
|
23612
|
+
// src/mcp/tools/codepr-guards.ts
|
|
23613
|
+
import { realpathSync } from "fs";
|
|
23614
|
+
import { isAbsolute as isAbsolute4, resolve as resolve13, relative as relative5, sep as sep3, dirname as dirname12, basename as basename5 } from "path";
|
|
23615
|
+
import { z as z11 } from "zod";
|
|
23616
|
+
function deny(reason, detail) {
|
|
23617
|
+
return { ok: false, reason, detail };
|
|
23618
|
+
}
|
|
23619
|
+
function errnoCode(err2) {
|
|
23620
|
+
if (err2 !== null && typeof err2 === "object" && "code" in err2) {
|
|
23621
|
+
const code = err2.code;
|
|
23622
|
+
return typeof code === "string" ? code : void 0;
|
|
23623
|
+
}
|
|
23624
|
+
return void 0;
|
|
23625
|
+
}
|
|
23626
|
+
function confinePath(worktreeRoot, candidatePath, realpath = realpathSync) {
|
|
23627
|
+
if (!isAbsolute4(worktreeRoot)) {
|
|
23628
|
+
return deny("path_escape", "worktreeRoot must be an absolute path");
|
|
23629
|
+
}
|
|
23630
|
+
let resolvedRoot;
|
|
23631
|
+
try {
|
|
23632
|
+
resolvedRoot = realpath(worktreeRoot);
|
|
23633
|
+
} catch {
|
|
23634
|
+
return deny("path_escape", "worktreeRoot could not be resolved (fail-closed)");
|
|
23635
|
+
}
|
|
23636
|
+
const joined = isAbsolute4(candidatePath) ? candidatePath : resolve13(resolvedRoot, candidatePath);
|
|
23637
|
+
const reassembled = resolveNewFilePath(joined, realpath);
|
|
23638
|
+
if (reassembled === void 0) {
|
|
23639
|
+
return deny("path_escape", "candidate path could not be resolved (fail-closed)");
|
|
23640
|
+
}
|
|
23641
|
+
if (!isWithin(resolvedRoot, reassembled)) {
|
|
23642
|
+
return deny("path_escape", "resolved path is outside the worktree root");
|
|
23643
|
+
}
|
|
23644
|
+
return { ok: true, resolvedPath: reassembled };
|
|
23645
|
+
}
|
|
23646
|
+
function resolveNewFilePath(joined, realpath) {
|
|
23647
|
+
let existing = joined;
|
|
23648
|
+
const trailing = [];
|
|
23649
|
+
for (; ; ) {
|
|
23650
|
+
try {
|
|
23651
|
+
existing = realpath(existing);
|
|
23652
|
+
break;
|
|
23653
|
+
} catch (err2) {
|
|
23654
|
+
if (errnoCode(err2) !== "ENOENT") return void 0;
|
|
23655
|
+
const parent = dirname12(existing);
|
|
23656
|
+
if (parent === existing) return void 0;
|
|
23657
|
+
trailing.push(basename5(existing));
|
|
23658
|
+
existing = parent;
|
|
23659
|
+
}
|
|
23660
|
+
}
|
|
23661
|
+
return trailing.length === 0 ? existing : resolve13(existing, ...trailing.reverse());
|
|
23662
|
+
}
|
|
23663
|
+
function isWithin(parent, child) {
|
|
23664
|
+
if (child === parent) return true;
|
|
23665
|
+
const rel = relative5(parent, child);
|
|
23666
|
+
if (rel === "") return true;
|
|
23667
|
+
if (rel === ".." || rel.startsWith(".." + sep3)) return false;
|
|
23668
|
+
if (isAbsolute4(rel)) return false;
|
|
23669
|
+
return true;
|
|
23670
|
+
}
|
|
23671
|
+
function basenamePosix(relPathPosix) {
|
|
23672
|
+
const idx = relPathPosix.lastIndexOf("/");
|
|
23673
|
+
return idx === -1 ? relPathPosix : relPathPosix.slice(idx + 1);
|
|
23674
|
+
}
|
|
23675
|
+
var SELF_GUARD_MODULE_BASENAMES = [
|
|
23676
|
+
"codepr-guards",
|
|
23677
|
+
// this guard module (+ its tests / future dir) — prefix match
|
|
23678
|
+
"diff-secret-scan",
|
|
23679
|
+
// reused: pre-push secret scan
|
|
23680
|
+
"repo-root-detection",
|
|
23681
|
+
// reused: repo-root / path confinement source
|
|
23682
|
+
"audit-logger",
|
|
23683
|
+
// reused: hash-chained audit log
|
|
23684
|
+
"audit-types",
|
|
23685
|
+
// reused: audit schemas/interfaces the guard imports
|
|
23686
|
+
"improvement-enforce-readiness",
|
|
23687
|
+
// the enable-readiness module (shadow→enforce gate)
|
|
23688
|
+
"remediation-readiness-collector"
|
|
23689
|
+
// companion readiness collector
|
|
23690
|
+
];
|
|
23691
|
+
function isSelfGuardPath(relPathPosix) {
|
|
23692
|
+
const base = basenamePosix(relPathPosix);
|
|
23693
|
+
for (const name of SELF_GUARD_MODULE_BASENAMES) {
|
|
23694
|
+
if (base === name) return true;
|
|
23695
|
+
if (base.startsWith(name + ".")) return true;
|
|
23696
|
+
if (relPathPosix === name || relPathPosix.startsWith(name + "/")) return true;
|
|
23697
|
+
if (relPathPosix.includes("/" + name + "/")) return true;
|
|
23698
|
+
}
|
|
23699
|
+
return false;
|
|
23700
|
+
}
|
|
23701
|
+
var SENSITIVE_PATH_RULES = [
|
|
23702
|
+
{
|
|
23703
|
+
category: "self_guard",
|
|
23704
|
+
description: "the adapter\u2019s own guard code + reused safety primitives (precondition B)",
|
|
23705
|
+
match: isSelfGuardPath
|
|
23706
|
+
},
|
|
23707
|
+
{
|
|
23708
|
+
category: "governance",
|
|
23709
|
+
description: "governance/** \u2014 voting, ratification, tier ledgers",
|
|
23710
|
+
match: (p) => p === "governance" || p.startsWith("governance/") || p.includes("/governance/")
|
|
23711
|
+
},
|
|
23712
|
+
{
|
|
23713
|
+
category: "workflow",
|
|
23714
|
+
description: ".github/workflows/** \u2014 CI/CD definitions",
|
|
23715
|
+
match: (p) => p.startsWith(".github/workflows/") || p.includes("/.github/workflows/")
|
|
23716
|
+
},
|
|
23717
|
+
{
|
|
23718
|
+
category: "codeowners",
|
|
23719
|
+
// `p` is already lower-cased by classifyPath (case-insensitive matching).
|
|
23720
|
+
description: "any CODEOWNERS file",
|
|
23721
|
+
match: (p) => basenamePosix(p) === "codeowners"
|
|
23722
|
+
},
|
|
23723
|
+
{
|
|
23724
|
+
category: "audit",
|
|
23725
|
+
description: "audit subsystem: src/audit/** (tamper-evidence \u2014 human-authored only)",
|
|
23726
|
+
match: (p) => p === "src/audit" || p.startsWith("src/audit/") || p.includes("/src/audit/")
|
|
23727
|
+
},
|
|
23728
|
+
{
|
|
23729
|
+
category: "authority",
|
|
23730
|
+
description: "auth/authority code: **/authority-*, **/auth/**",
|
|
23731
|
+
match: (p) => basenamePosix(p).startsWith("authority-") || p.includes("/auth/") || p.startsWith("auth/")
|
|
23732
|
+
},
|
|
23733
|
+
{
|
|
23734
|
+
category: "dependency_manifest",
|
|
23735
|
+
description: "dependency manifests: package.json, pnpm-lock.yaml, tsconfig*.json (precondition E)",
|
|
23736
|
+
match: (p) => {
|
|
23737
|
+
const base = basenamePosix(p);
|
|
23738
|
+
if (base === "package.json") return true;
|
|
23739
|
+
if (base === "pnpm-lock.yaml") return true;
|
|
23740
|
+
if (base.startsWith("tsconfig") && base.endsWith(".json")) return true;
|
|
23741
|
+
return false;
|
|
23742
|
+
}
|
|
23743
|
+
}
|
|
23744
|
+
];
|
|
23745
|
+
function normalizeRelPath(relPath) {
|
|
23746
|
+
const adsIdx = relPath.indexOf("::");
|
|
23747
|
+
let p = adsIdx === -1 ? relPath : relPath.slice(0, adsIdx);
|
|
23748
|
+
p = p.replace(/\\/g, "/");
|
|
23749
|
+
p = p.replace(/\/{2,}/g, "/");
|
|
23750
|
+
while (p.startsWith("./")) p = p.slice(2);
|
|
23751
|
+
p = p.split("/").map((seg) => seg.replace(/[. ]+$/, "")).join("/");
|
|
23752
|
+
return p;
|
|
23753
|
+
}
|
|
23754
|
+
function classifyPath(relPath) {
|
|
23755
|
+
const p = normalizeRelPath(relPath).toLowerCase();
|
|
23756
|
+
for (const rule of SENSITIVE_PATH_RULES) {
|
|
23757
|
+
if (rule.match(p)) return { sensitive: true, category: rule.category };
|
|
23758
|
+
}
|
|
23759
|
+
return { sensitive: false };
|
|
23760
|
+
}
|
|
23761
|
+
var BlastRadiusLimitsSchema = z11.object({
|
|
23762
|
+
/** Max number of files the change may touch. Default 20. */
|
|
23763
|
+
maxFiles: z11.number().int().positive().default(20),
|
|
23764
|
+
/** Max total changed lines (added + removed across all files). Default 400. */
|
|
23765
|
+
maxLines: z11.number().int().positive().default(400)
|
|
23766
|
+
}).strict();
|
|
23767
|
+
var DEFAULT_BLAST_RADIUS_LIMITS = Object.freeze(
|
|
23768
|
+
BlastRadiusLimitsSchema.parse({})
|
|
23769
|
+
);
|
|
23770
|
+
function checkBlastRadius(changedFiles, limits = DEFAULT_BLAST_RADIUS_LIMITS) {
|
|
23771
|
+
const parsed = BlastRadiusLimitsSchema.safeParse(limits);
|
|
23772
|
+
if (!parsed.success) {
|
|
23773
|
+
return deny("blast_radius_exceeded", "invalid blast-radius limits (fail-closed)");
|
|
23774
|
+
}
|
|
23775
|
+
const { maxFiles, maxLines } = parsed.data;
|
|
23776
|
+
for (const f of changedFiles) {
|
|
23777
|
+
const cls = classifyPath(f.path);
|
|
23778
|
+
if (cls.sensitive) {
|
|
23779
|
+
return deny("sensitive_path", `changed file is sensitive (${cls.category}): ${f.path}`);
|
|
23780
|
+
}
|
|
23781
|
+
}
|
|
23782
|
+
const filesTouched = changedFiles.length;
|
|
23783
|
+
if (filesTouched > maxFiles) {
|
|
23784
|
+
return deny(
|
|
23785
|
+
"blast_radius_exceeded",
|
|
23786
|
+
`files touched ${String(filesTouched)} exceeds maxFiles ${String(maxFiles)}`
|
|
23787
|
+
);
|
|
23788
|
+
}
|
|
23789
|
+
let linesTouched = 0;
|
|
23790
|
+
for (const f of changedFiles) linesTouched += f.addedLines + f.removedLines;
|
|
23791
|
+
if (linesTouched > maxLines) {
|
|
23792
|
+
return deny(
|
|
23793
|
+
"blast_radius_exceeded",
|
|
23794
|
+
`changed lines ${String(linesTouched)} exceeds maxLines ${String(maxLines)}`
|
|
23795
|
+
);
|
|
23796
|
+
}
|
|
23797
|
+
return { ok: true, filesTouched, linesTouched };
|
|
23798
|
+
}
|
|
23799
|
+
function scanDiffOrDeny(diff) {
|
|
23800
|
+
const scan = scanForSecrets(diff);
|
|
23801
|
+
if (!scan.clean) {
|
|
23802
|
+
const summary = scan.findings.map((f) => `${f.pattern}@L${String(f.line)}`).join(", ");
|
|
23803
|
+
return deny(
|
|
23804
|
+
"secret_detected",
|
|
23805
|
+
`secret scan found ${String(scan.findings.length)} finding(s): ${summary}`
|
|
23806
|
+
);
|
|
23807
|
+
}
|
|
23808
|
+
return { ok: true, scan };
|
|
23809
|
+
}
|
|
23810
|
+
var AUTONOMOUS_ACTOR = {
|
|
23811
|
+
type: "system",
|
|
23812
|
+
id: "autonomous-code-pr",
|
|
23813
|
+
name: "Autonomous Code-PR Adapter (Stage 1, OFF)"
|
|
23814
|
+
};
|
|
23815
|
+
function auditAutonomousEvent(logger19, record) {
|
|
23816
|
+
try {
|
|
23817
|
+
logger19.log({
|
|
23818
|
+
category: "security",
|
|
23819
|
+
severity: record.decision === "abort" ? "warning" : "info",
|
|
23820
|
+
outcome: record.decision === "abort" ? "denied" : "success",
|
|
23821
|
+
action: `autonomous_code_pr.${record.decision}`,
|
|
23822
|
+
description: record.decision === "abort" ? `autonomous code-PR aborted (${record.abortReason ?? "unspecified"})` : "autonomous code-PR write-guards passed (would open PR)",
|
|
23823
|
+
actor: record.actor ?? AUTONOMOUS_ACTOR,
|
|
23824
|
+
resource: { type: "autonomous-run", id: record.runId, name: record.runId },
|
|
23825
|
+
metadata: {
|
|
23826
|
+
runId: record.runId,
|
|
23827
|
+
sourceSignalHash: record.sourceSignalHash,
|
|
23828
|
+
diffHash: record.diffHash,
|
|
23829
|
+
scanVerdict: record.scanVerdict,
|
|
23830
|
+
filesTouched: record.filesTouched,
|
|
23831
|
+
linesTouched: record.linesTouched,
|
|
23832
|
+
tokenIdentity: record.tokenIdentity,
|
|
23833
|
+
decision: record.decision,
|
|
23834
|
+
abortReason: record.abortReason ?? null
|
|
23835
|
+
}
|
|
23836
|
+
});
|
|
23837
|
+
} catch (err2) {
|
|
23838
|
+
const detail = err2 instanceof Error ? err2.message : String(err2);
|
|
23839
|
+
return deny("audit_append_failed", `audit append threw (fail-closed): ${detail}`);
|
|
23840
|
+
}
|
|
23841
|
+
return { ok: true };
|
|
23842
|
+
}
|
|
23843
|
+
var ResourceBudgetLimitsSchema = z11.object({
|
|
23844
|
+
/** Wall-clock ceiling in ms. Default 600000 (10 min). */
|
|
23845
|
+
maxWallClockMs: z11.number().int().positive().default(6e5),
|
|
23846
|
+
/** Token ceiling. Default 200000. */
|
|
23847
|
+
maxTokens: z11.number().int().positive().default(2e5),
|
|
23848
|
+
/** Tool-call ceiling. Default 200. */
|
|
23849
|
+
maxToolCalls: z11.number().int().positive().default(200)
|
|
23850
|
+
}).strict();
|
|
23851
|
+
var DEFAULT_RESOURCE_BUDGET_LIMITS = Object.freeze(
|
|
23852
|
+
ResourceBudgetLimitsSchema.parse({})
|
|
23853
|
+
);
|
|
23854
|
+
function checkResourceBudget(usage, limits = DEFAULT_RESOURCE_BUDGET_LIMITS) {
|
|
23855
|
+
const parsed = ResourceBudgetLimitsSchema.safeParse(limits);
|
|
23856
|
+
if (!parsed.success) {
|
|
23857
|
+
return deny("budget_exceeded", "invalid resource limits (fail-closed)");
|
|
23858
|
+
}
|
|
23859
|
+
const { maxWallClockMs, maxTokens, maxToolCalls } = parsed.data;
|
|
23860
|
+
if (usage.wallClockMs > maxWallClockMs) {
|
|
23861
|
+
return deny(
|
|
23862
|
+
"budget_exceeded",
|
|
23863
|
+
`wall-clock ${String(usage.wallClockMs)}ms exceeds ${String(maxWallClockMs)}ms`
|
|
23864
|
+
);
|
|
23865
|
+
}
|
|
23866
|
+
if (usage.tokens > maxTokens) {
|
|
23867
|
+
return deny("budget_exceeded", `tokens ${String(usage.tokens)} exceeds ${String(maxTokens)}`);
|
|
23868
|
+
}
|
|
23869
|
+
if (usage.toolCalls > maxToolCalls) {
|
|
23870
|
+
return deny(
|
|
23871
|
+
"budget_exceeded",
|
|
23872
|
+
`tool calls ${String(usage.toolCalls)} exceeds ${String(maxToolCalls)}`
|
|
23873
|
+
);
|
|
23874
|
+
}
|
|
23875
|
+
return { ok: true };
|
|
23876
|
+
}
|
|
23877
|
+
function evaluateWriteGuards(input) {
|
|
23878
|
+
for (const f of input.changedFiles) {
|
|
23879
|
+
const confined = runGuard(
|
|
23880
|
+
"confinePath",
|
|
23881
|
+
() => confinePath(input.worktreeRoot, f.path, input.realpath)
|
|
23882
|
+
);
|
|
23883
|
+
if (!confined.ok) return confined;
|
|
23884
|
+
}
|
|
23885
|
+
const blast = runGuard(
|
|
23886
|
+
"checkBlastRadius",
|
|
23887
|
+
() => checkBlastRadius(input.changedFiles, input.blastRadiusLimits)
|
|
23888
|
+
);
|
|
23889
|
+
if (!blast.ok) return blast;
|
|
23890
|
+
const secrets = runGuard("scanDiffOrDeny", () => scanDiffOrDeny(input.diff));
|
|
23891
|
+
if (!secrets.ok) return secrets;
|
|
23892
|
+
const budget = runGuard(
|
|
23893
|
+
"checkResourceBudget",
|
|
23894
|
+
() => checkResourceBudget(input.usage, input.resourceLimits)
|
|
23895
|
+
);
|
|
23896
|
+
if (!budget.ok) return budget;
|
|
23897
|
+
return { ok: true };
|
|
23898
|
+
}
|
|
23899
|
+
function runGuard(name, fn) {
|
|
23900
|
+
try {
|
|
23901
|
+
return fn();
|
|
23902
|
+
} catch (err2) {
|
|
23903
|
+
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
23904
|
+
return deny("guard_error", `guard ${name} threw (fail-closed): ${message}`);
|
|
23905
|
+
}
|
|
23906
|
+
}
|
|
23907
|
+
|
|
23908
|
+
// src/mcp/tools/codepr-orchestrator.ts
|
|
23909
|
+
var ProposedChangeSchema = z12.object({
|
|
23910
|
+
/** Repo-relative path the change would write. */
|
|
23911
|
+
relPath: z12.string().min(1),
|
|
23912
|
+
/** The full new file content. */
|
|
23913
|
+
newContent: z12.string()
|
|
23914
|
+
}).strict();
|
|
23915
|
+
var CodePrRunInputSchema = z12.object({
|
|
23916
|
+
/** Correlates all audit events for this run. */
|
|
23917
|
+
runId: z12.string().min(1),
|
|
23918
|
+
/** Hash of the source signal (fitness/improvement) that triggered the run. */
|
|
23919
|
+
sourceSignalHash: z12.string().min(1),
|
|
23920
|
+
/** The proposed change set. */
|
|
23921
|
+
changes: z12.array(ProposedChangeSchema).min(1)
|
|
23922
|
+
}).strict();
|
|
23923
|
+
var ORCHESTRATOR_USAGE_ZERO = { wallClockMs: 0, tokens: 0, toolCalls: 0 };
|
|
23924
|
+
function sha256(s) {
|
|
23925
|
+
return createHash3("sha256").update(s).digest("hex");
|
|
23926
|
+
}
|
|
23927
|
+
function git(cwd, args) {
|
|
23928
|
+
return execFileSync3("git", [...args], { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
23929
|
+
}
|
|
23930
|
+
function parseNumstat(numstat) {
|
|
23931
|
+
const files = [];
|
|
23932
|
+
for (const line of numstat.split("\n")) {
|
|
23933
|
+
if (line.trim() === "") continue;
|
|
23934
|
+
const parts = line.split(" ");
|
|
23935
|
+
if (parts.length < 3) continue;
|
|
23936
|
+
const added = parts[0] === "-" ? 0 : Number.parseInt(parts[0] ?? "0", 10);
|
|
23937
|
+
const removed = parts[1] === "-" ? 0 : Number.parseInt(parts[1] ?? "0", 10);
|
|
23938
|
+
const path21 = parts.slice(2).join(" ");
|
|
23939
|
+
files.push({
|
|
23940
|
+
path: path21,
|
|
23941
|
+
addedLines: Number.isFinite(added) ? added : 0,
|
|
23942
|
+
removedLines: Number.isFinite(removed) ? removed : 0
|
|
23943
|
+
});
|
|
23944
|
+
}
|
|
23945
|
+
return files;
|
|
23946
|
+
}
|
|
23947
|
+
function denied(reason, detail, auditRecorded) {
|
|
23948
|
+
return { ok: false, reason, detail, auditRecorded };
|
|
23949
|
+
}
|
|
23950
|
+
function auditAbort(logger19, a) {
|
|
23951
|
+
const res = auditAutonomousEvent(logger19, {
|
|
23952
|
+
runId: a.input.runId,
|
|
23953
|
+
sourceSignalHash: a.input.sourceSignalHash,
|
|
23954
|
+
diffHash: a.diffHash,
|
|
23955
|
+
scanVerdict: a.reason === "secret_detected" ? "secret_detected" : "clean",
|
|
23956
|
+
filesTouched: a.filesTouched,
|
|
23957
|
+
linesTouched: a.linesTouched,
|
|
23958
|
+
tokenIdentity: "none",
|
|
23959
|
+
decision: "abort",
|
|
23960
|
+
abortReason: a.reason
|
|
23961
|
+
});
|
|
23962
|
+
return res.ok;
|
|
23963
|
+
}
|
|
23964
|
+
function precheckChanges(worktreeRoot, run, logger19) {
|
|
23965
|
+
for (const change of run.changes) {
|
|
23966
|
+
const confined = confinePath(worktreeRoot, change.relPath);
|
|
23967
|
+
if (!confined.ok) {
|
|
23968
|
+
const recorded = auditAbort(logger19, {
|
|
23969
|
+
input: run,
|
|
23970
|
+
reason: confined.reason,
|
|
23971
|
+
diffHash: sha256(""),
|
|
23972
|
+
filesTouched: 0,
|
|
23973
|
+
linesTouched: 0
|
|
23974
|
+
});
|
|
23975
|
+
return denied(confined.reason, confined.detail, recorded);
|
|
23976
|
+
}
|
|
23977
|
+
const cls = classifyPath(change.relPath);
|
|
23978
|
+
if (cls.sensitive) {
|
|
23979
|
+
const recorded = auditAbort(logger19, {
|
|
23980
|
+
input: run,
|
|
23981
|
+
reason: "sensitive_path",
|
|
23982
|
+
diffHash: sha256(""),
|
|
23983
|
+
filesTouched: 0,
|
|
23984
|
+
linesTouched: 0
|
|
23985
|
+
});
|
|
23986
|
+
return denied("sensitive_path", `sensitive path (${cls.category}): ${change.relPath}`, recorded);
|
|
23987
|
+
}
|
|
23988
|
+
}
|
|
23989
|
+
return void 0;
|
|
23990
|
+
}
|
|
23991
|
+
function applyChanges(worktreeRoot, run) {
|
|
23992
|
+
for (const change of run.changes) {
|
|
23993
|
+
const confined = confinePath(worktreeRoot, change.relPath);
|
|
23994
|
+
if (!confined.ok) throw new Error(`apply: ${confined.detail}`);
|
|
23995
|
+
mkdirSync6(dirname13(confined.resolvedPath), { recursive: true });
|
|
23996
|
+
writeFileSync8(confined.resolvedPath, change.newContent);
|
|
23997
|
+
}
|
|
23998
|
+
}
|
|
23999
|
+
function realizeDiff(worktreeRoot) {
|
|
24000
|
+
git(worktreeRoot, ["add", "-A"]);
|
|
24001
|
+
const diffText = git(worktreeRoot, ["diff", "--cached"]);
|
|
24002
|
+
const changedFiles = parseNumstat(git(worktreeRoot, ["diff", "--cached", "--numstat"]));
|
|
24003
|
+
let linesTouched = 0;
|
|
24004
|
+
for (const f of changedFiles) linesTouched += f.addedLines + f.removedLines;
|
|
24005
|
+
return { diffText, diffHash: sha256(diffText), changedFiles, linesTouched };
|
|
24006
|
+
}
|
|
24007
|
+
function runGuardsAndPlan(args, logger19) {
|
|
24008
|
+
const { worktreeRoot, run, realized } = args;
|
|
24009
|
+
const verdict = evaluateWriteGuards({
|
|
24010
|
+
worktreeRoot,
|
|
24011
|
+
changedFiles: realized.changedFiles,
|
|
24012
|
+
diff: realized.diffText,
|
|
24013
|
+
usage: args.usage,
|
|
24014
|
+
blastRadiusLimits: args.blastRadiusLimits,
|
|
24015
|
+
resourceLimits: args.resourceLimits
|
|
24016
|
+
});
|
|
24017
|
+
if (!verdict.ok) {
|
|
24018
|
+
const recorded = auditAbort(logger19, {
|
|
24019
|
+
input: run,
|
|
24020
|
+
reason: verdict.reason,
|
|
24021
|
+
diffHash: realized.diffHash,
|
|
24022
|
+
filesTouched: realized.changedFiles.length,
|
|
24023
|
+
linesTouched: realized.linesTouched
|
|
24024
|
+
});
|
|
24025
|
+
return denied(verdict.reason, verdict.detail, recorded);
|
|
24026
|
+
}
|
|
24027
|
+
const plan = {
|
|
24028
|
+
branchName: `auto/codepr/${run.runId}`,
|
|
24029
|
+
title: `auto code-PR (dry-run, NO push) for run ${run.runId}`,
|
|
24030
|
+
files: realized.changedFiles.map((f) => ({
|
|
24031
|
+
path: f.path,
|
|
24032
|
+
addedLines: f.addedLines,
|
|
24033
|
+
removedLines: f.removedLines
|
|
24034
|
+
})),
|
|
24035
|
+
filesTouched: realized.changedFiles.length,
|
|
24036
|
+
linesTouched: realized.linesTouched,
|
|
24037
|
+
diffHash: realized.diffHash
|
|
24038
|
+
};
|
|
24039
|
+
const audit = auditAutonomousEvent(logger19, {
|
|
24040
|
+
runId: run.runId,
|
|
24041
|
+
sourceSignalHash: run.sourceSignalHash,
|
|
24042
|
+
diffHash: realized.diffHash,
|
|
24043
|
+
scanVerdict: "clean",
|
|
24044
|
+
filesTouched: plan.filesTouched,
|
|
24045
|
+
linesTouched: plan.linesTouched,
|
|
24046
|
+
tokenIdentity: "none",
|
|
24047
|
+
decision: "would_open_pr"
|
|
24048
|
+
});
|
|
24049
|
+
if (!audit.ok) {
|
|
24050
|
+
return denied(audit.reason, audit.detail, false);
|
|
24051
|
+
}
|
|
24052
|
+
return { ok: true, plan, auditRecorded: true };
|
|
24053
|
+
}
|
|
24054
|
+
function runInWorktree(run, logger19, options, handle) {
|
|
24055
|
+
const fault = options.faultInjector;
|
|
24056
|
+
const repoRoot = options.repoRoot ?? process.cwd();
|
|
24057
|
+
handle.tempParent = realpathSync2(mkdtempSync(join20(tmpdir(), "codepr-orchestrator-")));
|
|
24058
|
+
handle.worktreeRoot = join20(handle.tempParent, "wt");
|
|
24059
|
+
git(repoRoot, ["worktree", "add", "--detach", handle.worktreeRoot]);
|
|
24060
|
+
fault?.("after-worktree");
|
|
24061
|
+
const precheck = precheckChanges(handle.worktreeRoot, run, logger19);
|
|
24062
|
+
if (precheck !== void 0) return precheck;
|
|
24063
|
+
applyChanges(handle.worktreeRoot, run);
|
|
24064
|
+
fault?.("after-apply");
|
|
24065
|
+
const realized = realizeDiff(handle.worktreeRoot);
|
|
24066
|
+
fault?.("after-diff");
|
|
24067
|
+
return runGuardsAndPlan(
|
|
24068
|
+
{
|
|
24069
|
+
worktreeRoot: handle.worktreeRoot,
|
|
24070
|
+
run,
|
|
24071
|
+
realized,
|
|
24072
|
+
usage: options.usage ?? ORCHESTRATOR_USAGE_ZERO,
|
|
24073
|
+
blastRadiusLimits: options.blastRadiusLimits,
|
|
24074
|
+
resourceLimits: options.resourceLimits
|
|
24075
|
+
},
|
|
24076
|
+
logger19
|
|
24077
|
+
);
|
|
24078
|
+
}
|
|
24079
|
+
function discardWorktree(repoRoot, handle) {
|
|
24080
|
+
if (handle.worktreeRoot !== void 0) {
|
|
24081
|
+
try {
|
|
24082
|
+
git(repoRoot, ["worktree", "remove", "--force", handle.worktreeRoot]);
|
|
24083
|
+
} catch {
|
|
24084
|
+
}
|
|
24085
|
+
}
|
|
24086
|
+
if (handle.tempParent !== void 0) {
|
|
24087
|
+
try {
|
|
24088
|
+
rmSync2(handle.tempParent, { recursive: true, force: true });
|
|
24089
|
+
} catch {
|
|
24090
|
+
}
|
|
24091
|
+
}
|
|
24092
|
+
}
|
|
24093
|
+
function planCodePrRun(input, logger19, options = {}) {
|
|
24094
|
+
const parsed = CodePrRunInputSchema.safeParse(input);
|
|
24095
|
+
if (!parsed.success) {
|
|
24096
|
+
return denied("guard_error", "invalid code-PR run input (fail-closed)", false);
|
|
24097
|
+
}
|
|
24098
|
+
const run = parsed.data;
|
|
24099
|
+
const repoRoot = options.repoRoot ?? process.cwd();
|
|
24100
|
+
const handle = {};
|
|
24101
|
+
try {
|
|
24102
|
+
return runInWorktree(run, logger19, options, handle);
|
|
24103
|
+
} catch (err2) {
|
|
24104
|
+
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
24105
|
+
let recorded = false;
|
|
24106
|
+
try {
|
|
24107
|
+
recorded = auditAbort(logger19, {
|
|
24108
|
+
input: run,
|
|
24109
|
+
reason: "guard_error",
|
|
24110
|
+
diffHash: sha256(""),
|
|
24111
|
+
filesTouched: 0,
|
|
24112
|
+
linesTouched: 0
|
|
24113
|
+
});
|
|
24114
|
+
} catch {
|
|
24115
|
+
recorded = false;
|
|
24116
|
+
}
|
|
24117
|
+
return denied("guard_error", `orchestrator failed (fail-closed): ${message}`, recorded);
|
|
24118
|
+
} finally {
|
|
24119
|
+
discardWorktree(repoRoot, handle);
|
|
24120
|
+
}
|
|
24121
|
+
}
|
|
24122
|
+
|
|
24123
|
+
// src/mcp/tools/codepr-soak-store.ts
|
|
24124
|
+
import { z as z13 } from "zod";
|
|
24125
|
+
var CodePrSoakRecordSchema = z13.object({
|
|
24126
|
+
/** ISO-8601 capture time. */
|
|
24127
|
+
timestamp: z13.string(),
|
|
24128
|
+
/** Correlates the data point to the dry-run's orchestrator runId. */
|
|
24129
|
+
runId: z13.string(),
|
|
24130
|
+
/** The improvement signal's stable key that triggered the dry-run. */
|
|
24131
|
+
signalKey: z13.string(),
|
|
24132
|
+
/** True when the dry-run plan succeeded with ZERO guard denial. */
|
|
24133
|
+
green: z13.boolean(),
|
|
24134
|
+
/** The guard denial reason when `green` is false; omitted for a green plan. */
|
|
24135
|
+
denialReason: z13.string().optional(),
|
|
24136
|
+
/** Files the dry-run plan touched (0 on denial before the diff was realized). */
|
|
24137
|
+
filesTouched: z13.number().int().nonnegative()
|
|
24138
|
+
}).strict();
|
|
24139
|
+
var CODEPR_SOAK_MAX_RECORDS = 1e4;
|
|
24140
|
+
function getCodePrSoakFile() {
|
|
24141
|
+
return nexusDataPath("learning", "codepr-guards-soak.jsonl");
|
|
24142
|
+
}
|
|
24143
|
+
function createCodePrSoakSink(filePath = getCodePrSoakFile(), maxRecords = CODEPR_SOAK_MAX_RECORDS) {
|
|
24144
|
+
const store = new JsonlStore({
|
|
24145
|
+
filePath,
|
|
24146
|
+
schema: CodePrSoakRecordSchema,
|
|
24147
|
+
maxRecords,
|
|
24148
|
+
component: "CodePrSoakSink"
|
|
24149
|
+
});
|
|
24150
|
+
return {
|
|
24151
|
+
record(record) {
|
|
24152
|
+
store.append(record);
|
|
24153
|
+
},
|
|
24154
|
+
getRecords() {
|
|
24155
|
+
return store.all();
|
|
24156
|
+
}
|
|
24157
|
+
};
|
|
24158
|
+
}
|
|
24159
|
+
var soakSingleton;
|
|
24160
|
+
function getCodePrSoakSink() {
|
|
24161
|
+
soakSingleton ??= createCodePrSoakSink();
|
|
24162
|
+
return soakSingleton;
|
|
24163
|
+
}
|
|
24164
|
+
function greenCodePrSoakRecord(args) {
|
|
24165
|
+
return {
|
|
24166
|
+
timestamp: new Date(getTimeProvider().now()).toISOString(),
|
|
24167
|
+
runId: args.runId,
|
|
24168
|
+
signalKey: args.signalKey,
|
|
24169
|
+
green: true,
|
|
24170
|
+
filesTouched: args.filesTouched
|
|
24171
|
+
};
|
|
24172
|
+
}
|
|
24173
|
+
function deniedCodePrSoakRecord(args) {
|
|
24174
|
+
return {
|
|
24175
|
+
timestamp: new Date(getTimeProvider().now()).toISOString(),
|
|
24176
|
+
runId: args.runId,
|
|
24177
|
+
signalKey: args.signalKey,
|
|
24178
|
+
green: false,
|
|
24179
|
+
denialReason: args.denialReason,
|
|
24180
|
+
filesTouched: 0
|
|
24181
|
+
};
|
|
24182
|
+
}
|
|
24183
|
+
|
|
24184
|
+
// src/mcp/tools/codepr-soak-consumer.ts
|
|
24185
|
+
var CODE_TOUCHING_KINDS = /* @__PURE__ */ new Set([
|
|
24186
|
+
"add-test",
|
|
24187
|
+
"refactor",
|
|
24188
|
+
"update-docs",
|
|
24189
|
+
"fix-bug"
|
|
24190
|
+
]);
|
|
24191
|
+
function planTouchesCode(plan) {
|
|
24192
|
+
return plan.steps.some((s) => CODE_TOUCHING_KINDS.has(s.kind));
|
|
24193
|
+
}
|
|
24194
|
+
function placeholderPathFor(plan, kind) {
|
|
24195
|
+
const h = createHash4("sha256").update(`${plan.signalKey}:${kind}`).digest("hex").slice(0, 12);
|
|
24196
|
+
return `src/__codepr_soak__/${kind}-${h}.ts`;
|
|
24197
|
+
}
|
|
24198
|
+
function deriveProposedChanges(plan) {
|
|
24199
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24200
|
+
const changes = [];
|
|
24201
|
+
for (const step of plan.steps) {
|
|
24202
|
+
if (!CODE_TOUCHING_KINDS.has(step.kind)) continue;
|
|
24203
|
+
const path21 = step.targetPath !== void 0 && step.targetPath !== "" ? step.targetPath : placeholderPathFor(plan, step.kind);
|
|
24204
|
+
if (seen.has(path21)) continue;
|
|
24205
|
+
seen.add(path21);
|
|
24206
|
+
changes.push({
|
|
24207
|
+
relPath: path21,
|
|
24208
|
+
newContent: `// codepr soak dry-run placeholder for ${plan.signalKey} (${step.kind})
|
|
24209
|
+
`
|
|
24210
|
+
});
|
|
24211
|
+
}
|
|
24212
|
+
return changes;
|
|
24213
|
+
}
|
|
24214
|
+
function loggerBackedAuditLogger(logger19) {
|
|
24215
|
+
return {
|
|
24216
|
+
log: (input) => {
|
|
24217
|
+
logger19.debug("codepr soak dry-run audit event", {
|
|
24218
|
+
action: input.action,
|
|
24219
|
+
outcome: input.outcome
|
|
24220
|
+
});
|
|
24221
|
+
},
|
|
24222
|
+
logToolInvocation: () => {
|
|
24223
|
+
},
|
|
24224
|
+
logPolicyDecision: () => {
|
|
24225
|
+
},
|
|
24226
|
+
logSecurityEvent: () => {
|
|
24227
|
+
},
|
|
24228
|
+
logRateLimitViolation: () => {
|
|
24229
|
+
},
|
|
24230
|
+
logTierTransition: () => {
|
|
24231
|
+
},
|
|
24232
|
+
flush: () => Promise.resolve(),
|
|
24233
|
+
close: () => Promise.resolve()
|
|
24234
|
+
};
|
|
24235
|
+
}
|
|
24236
|
+
function soakRunId(plan) {
|
|
24237
|
+
return `codepr-soak-${createHash4("sha256").update(plan.signalKey).digest("hex").slice(0, 16)}`;
|
|
24238
|
+
}
|
|
24239
|
+
function sourceSignalHash(plan) {
|
|
24240
|
+
return createHash4("sha256").update(plan.signalKey).digest("hex");
|
|
24241
|
+
}
|
|
24242
|
+
function runCodePrSoak(plan, inject = {}) {
|
|
24243
|
+
const logger19 = inject.logger ?? createLogger({ tool: "codepr-soak" });
|
|
24244
|
+
try {
|
|
24245
|
+
soakOnce(plan, inject, logger19);
|
|
24246
|
+
} catch (err2) {
|
|
24247
|
+
logger19.warn("codepr soak step failed (swallowed; cycle proceeds)", {
|
|
24248
|
+
signalKey: plan.signalKey,
|
|
24249
|
+
error: getErrorMessage(err2)
|
|
24250
|
+
});
|
|
24251
|
+
}
|
|
24252
|
+
}
|
|
24253
|
+
function soakOnce(plan, inject, logger19) {
|
|
24254
|
+
if (!planTouchesCode(plan)) return;
|
|
24255
|
+
const changes = deriveProposedChanges(plan);
|
|
24256
|
+
if (changes.length === 0) return;
|
|
24257
|
+
const runId = soakRunId(plan);
|
|
24258
|
+
const planRun = inject.planRun ?? planCodePrRun;
|
|
24259
|
+
const result = planRun(
|
|
24260
|
+
{ runId, sourceSignalHash: sourceSignalHash(plan), changes },
|
|
24261
|
+
inject.auditLogger ?? loggerBackedAuditLogger(logger19),
|
|
24262
|
+
inject.orchestratorOptions ?? {}
|
|
24263
|
+
);
|
|
24264
|
+
const sink = inject.sink ?? getCodePrSoakSink();
|
|
24265
|
+
if (result.ok) {
|
|
24266
|
+
sink.record(
|
|
24267
|
+
greenCodePrSoakRecord({ runId, signalKey: plan.signalKey, filesTouched: result.plan.filesTouched })
|
|
24268
|
+
);
|
|
24269
|
+
logger19.debug("codepr soak: green dry-run recorded", {
|
|
24270
|
+
signalKey: plan.signalKey,
|
|
24271
|
+
filesTouched: result.plan.filesTouched
|
|
24272
|
+
});
|
|
24273
|
+
} else {
|
|
24274
|
+
sink.record(
|
|
24275
|
+
deniedCodePrSoakRecord({ runId, signalKey: plan.signalKey, denialReason: result.reason })
|
|
24276
|
+
);
|
|
24277
|
+
logger19.debug("codepr soak: denied dry-run recorded (streak reset)", {
|
|
24278
|
+
signalKey: plan.signalKey,
|
|
24279
|
+
reason: result.reason
|
|
24280
|
+
});
|
|
24281
|
+
}
|
|
24282
|
+
}
|
|
24283
|
+
|
|
23635
24284
|
// src/mcp/tools/improvement-remediation-guard.ts
|
|
23636
24285
|
var DEFAULT_REMEDIATION_GUARD_CONFIG = {
|
|
23637
24286
|
cooldownMs: 6 * 60 * 60 * 1e3,
|
|
@@ -23974,6 +24623,17 @@ ${renderPlanAsResearch(plan)}`;
|
|
|
23974
24623
|
}
|
|
23975
24624
|
return null;
|
|
23976
24625
|
}
|
|
24626
|
+
function firePlanObserver(deps, signal, plan) {
|
|
24627
|
+
if (deps.onPlanProduced === void 0) return;
|
|
24628
|
+
try {
|
|
24629
|
+
deps.onPlanProduced(signal, plan);
|
|
24630
|
+
} catch (err2) {
|
|
24631
|
+
deps.logger?.warn("onPlanProduced observer threw (swallowed)", {
|
|
24632
|
+
signalKey: signal.signalKey,
|
|
24633
|
+
error: err2 instanceof Error ? err2.message : String(err2)
|
|
24634
|
+
});
|
|
24635
|
+
}
|
|
24636
|
+
}
|
|
23977
24637
|
async function executeOne(signal, deps, mode, ctx) {
|
|
23978
24638
|
const { guard, now, requirement } = ctx;
|
|
23979
24639
|
const ledger = new CapabilityLedger();
|
|
@@ -23991,6 +24651,7 @@ async function executeOne(signal, deps, mode, ctx) {
|
|
|
23991
24651
|
signalKey: signal.signalKey,
|
|
23992
24652
|
detail: `${String(plan.steps.length)} steps`
|
|
23993
24653
|
});
|
|
24654
|
+
firePlanObserver(deps, signal, plan);
|
|
23994
24655
|
const protectedPaths = planTouchesProtectedPath(plan);
|
|
23995
24656
|
if (protectedPaths.protected) {
|
|
23996
24657
|
const reason = `protected path(s) ${protectedPaths.paths.join(", ")} \u2014 human attestation required`;
|
|
@@ -24024,7 +24685,7 @@ async function runAutoRemediationCycle(config = {}, inject = {}) {
|
|
|
24024
24685
|
logger19.info(`auto-remediation cycle: ${mode} over ${String(signals.length)} signals`);
|
|
24025
24686
|
if (mode === "audit") {
|
|
24026
24687
|
const collector = buildSoakCollector(signals, inject);
|
|
24027
|
-
const soakDeps = withSoakAudit(deps, collector);
|
|
24688
|
+
const soakDeps = withCodePrSoak(withSoakAudit(deps, collector), inject);
|
|
24028
24689
|
try {
|
|
24029
24690
|
return await runAutoRemediation(signals, soakDeps, { mode });
|
|
24030
24691
|
} finally {
|
|
@@ -24033,6 +24694,15 @@ async function runAutoRemediationCycle(config = {}, inject = {}) {
|
|
|
24033
24694
|
}
|
|
24034
24695
|
return runAutoRemediation(signals, deps, { mode });
|
|
24035
24696
|
}
|
|
24697
|
+
function withCodePrSoak(deps, inject) {
|
|
24698
|
+
const runSoak = inject.runCodePrSoak ?? runCodePrSoak;
|
|
24699
|
+
return {
|
|
24700
|
+
...deps,
|
|
24701
|
+
onPlanProduced: (_signal, plan) => {
|
|
24702
|
+
runSoak(plan, inject.codePrSoak);
|
|
24703
|
+
}
|
|
24704
|
+
};
|
|
24705
|
+
}
|
|
24036
24706
|
function buildSoakCollector(signals, inject) {
|
|
24037
24707
|
const meta = /* @__PURE__ */ new Map();
|
|
24038
24708
|
for (const s of signals) {
|
|
@@ -24204,18 +24874,18 @@ async function handleRemediationReviewCommand(args) {
|
|
|
24204
24874
|
}
|
|
24205
24875
|
|
|
24206
24876
|
// src/cli/migrate-command.ts
|
|
24207
|
-
import { cpSync, existsSync as
|
|
24877
|
+
import { cpSync, existsSync as existsSync23, mkdirSync as mkdirSync7, readdirSync as readdirSync3 } from "fs";
|
|
24208
24878
|
import { homedir } from "os";
|
|
24209
|
-
import { join as
|
|
24879
|
+
import { join as join21 } from "path";
|
|
24210
24880
|
var logger18 = createLogger({ component: "migrate-command" });
|
|
24211
|
-
var HOMEDIR_DEFAULT_BASE =
|
|
24881
|
+
var HOMEDIR_DEFAULT_BASE = join21(homedir(), ".nexus-agents");
|
|
24212
24882
|
function countItems(dir) {
|
|
24213
|
-
if (!
|
|
24883
|
+
if (!existsSync23(dir)) return 0;
|
|
24214
24884
|
try {
|
|
24215
24885
|
const entries = readdirSync3(dir, { withFileTypes: true });
|
|
24216
24886
|
let n = 0;
|
|
24217
24887
|
for (const e of entries) {
|
|
24218
|
-
const p =
|
|
24888
|
+
const p = join21(dir, e.name);
|
|
24219
24889
|
if (e.isDirectory()) {
|
|
24220
24890
|
n += countItems(p);
|
|
24221
24891
|
} else {
|
|
@@ -24257,7 +24927,7 @@ function checkEarlyExits(fromBase, toBase, dryRun) {
|
|
|
24257
24927
|
summary: "No git repo detected from cwd. Run from inside a repo or pass --to <path> to choose an explicit destination."
|
|
24258
24928
|
};
|
|
24259
24929
|
}
|
|
24260
|
-
if (!
|
|
24930
|
+
if (!existsSync23(fromBase)) {
|
|
24261
24931
|
return {
|
|
24262
24932
|
fromBase,
|
|
24263
24933
|
toBase,
|
|
@@ -24270,8 +24940,8 @@ function checkEarlyExits(fromBase, toBase, dryRun) {
|
|
|
24270
24940
|
return null;
|
|
24271
24941
|
}
|
|
24272
24942
|
function planAndExecuteEntry(name, fromBase, toBase, perRepoSet, dryRun) {
|
|
24273
|
-
const source =
|
|
24274
|
-
const target =
|
|
24943
|
+
const source = join21(fromBase, name);
|
|
24944
|
+
const target = join21(toBase, name);
|
|
24275
24945
|
if (!perRepoSet.has(name)) {
|
|
24276
24946
|
return { subdir: name, status: "skipped-not-per-repo", source, target: "", itemsCopied: 0 };
|
|
24277
24947
|
}
|
|
@@ -24279,11 +24949,11 @@ function planAndExecuteEntry(name, fromBase, toBase, perRepoSet, dryRun) {
|
|
|
24279
24949
|
if (items === 0) {
|
|
24280
24950
|
return { subdir: name, status: "skipped-empty", source, target, itemsCopied: 0 };
|
|
24281
24951
|
}
|
|
24282
|
-
if (
|
|
24952
|
+
if (existsSync23(target) && readdirSync3(target).length > 0) {
|
|
24283
24953
|
return { subdir: name, status: "skipped-exists", source, target, itemsCopied: 0 };
|
|
24284
24954
|
}
|
|
24285
24955
|
if (!dryRun) {
|
|
24286
|
-
|
|
24956
|
+
mkdirSync7(toBase, { recursive: true });
|
|
24287
24957
|
cpSync(source, target, { recursive: true, errorOnExist: false });
|
|
24288
24958
|
}
|
|
24289
24959
|
return { subdir: name, status: "copied", source, target, itemsCopied: items };
|
|
@@ -24291,7 +24961,7 @@ function planAndExecuteEntry(name, fromBase, toBase, perRepoSet, dryRun) {
|
|
|
24291
24961
|
function resolveDefaultTarget(cwd) {
|
|
24292
24962
|
const repoRoot = findRepoRoot(cwd);
|
|
24293
24963
|
if (repoRoot === null) return null;
|
|
24294
|
-
return
|
|
24964
|
+
return join21(repoRoot, ".nexus-agents");
|
|
24295
24965
|
}
|
|
24296
24966
|
function formatMigrationResult(result) {
|
|
24297
24967
|
if (!result.success) {
|
|
@@ -24332,6 +25002,32 @@ async function handleMigrateCommand(args) {
|
|
|
24332
25002
|
return cliExit(result.success ? EXIT_CODES.SUCCESS : EXIT_CODES.SERVER_START_FAILED);
|
|
24333
25003
|
}
|
|
24334
25004
|
|
|
25005
|
+
// src/cli/first-run-hint.ts
|
|
25006
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
25007
|
+
import { dirname as dirname14 } from "path";
|
|
25008
|
+
var HINT_SUPPRESSED_COMMANDS = /* @__PURE__ */ new Set(["version", "help", "setup"]);
|
|
25009
|
+
function firstRunMarkerPath() {
|
|
25010
|
+
return nexusSharedPath(".first-run-done");
|
|
25011
|
+
}
|
|
25012
|
+
function maybeShowFirstRunHint(command) {
|
|
25013
|
+
if (HINT_SUPPRESSED_COMMANDS.has(command)) return;
|
|
25014
|
+
if (!process.stderr.isTTY) return;
|
|
25015
|
+
const marker = firstRunMarkerPath();
|
|
25016
|
+
try {
|
|
25017
|
+
if (existsSync24(marker)) return;
|
|
25018
|
+
} catch {
|
|
25019
|
+
}
|
|
25020
|
+
process.stderr.write(
|
|
25021
|
+
"\x1B[36mnexus-agents\x1B[0m: First time? Run \x1B[1mnexus-agents setup\x1B[0m to configure.\n (This one-time hint is now dismissed.)\n"
|
|
25022
|
+
);
|
|
25023
|
+
try {
|
|
25024
|
+
mkdirSync8(dirname14(marker), { recursive: true });
|
|
25025
|
+
writeFileSync9(marker, `${(/* @__PURE__ */ new Date()).toISOString()}
|
|
25026
|
+
`, { flag: "w" });
|
|
25027
|
+
} catch {
|
|
25028
|
+
}
|
|
25029
|
+
}
|
|
25030
|
+
|
|
24335
25031
|
// src/cli-commands.ts
|
|
24336
25032
|
function printHelp(args) {
|
|
24337
25033
|
const all = args?.options.all ?? false;
|
|
@@ -24454,6 +25150,7 @@ async function handleAsyncCommand(args) {
|
|
|
24454
25150
|
}
|
|
24455
25151
|
async function dispatchCommand(args) {
|
|
24456
25152
|
initDataDirectories();
|
|
25153
|
+
maybeShowFirstRunHint(args.command);
|
|
24457
25154
|
bootstrapStepNotifications({ mode: args.command === "server" ? "mcp-stdio" : "cli" });
|
|
24458
25155
|
if (!handleSyncCommand(args)) {
|
|
24459
25156
|
await handleAsyncCommand(args);
|
|
@@ -24463,7 +25160,6 @@ async function dispatchCommand(args) {
|
|
|
24463
25160
|
// src/cli-command-help.ts
|
|
24464
25161
|
var ORCHESTRATE_HELP = {
|
|
24465
25162
|
command: "orchestrate",
|
|
24466
|
-
description: "Execute a task using CLI tools (standalone mode). Routes to optimal model.",
|
|
24467
25163
|
examples: [
|
|
24468
25164
|
'nexus-agents orchestrate "Explain this function"',
|
|
24469
25165
|
'nexus-agents orchestrate "Generate unit tests" --model=claude',
|
|
@@ -24486,7 +25182,6 @@ var ORCHESTRATE_HELP = {
|
|
|
24486
25182
|
};
|
|
24487
25183
|
var VOTE_HELP = {
|
|
24488
25184
|
command: "vote",
|
|
24489
|
-
description: "Run multi-agent consensus vote on a proposal (6 agents by default).",
|
|
24490
25185
|
examples: [
|
|
24491
25186
|
'nexus-agents vote --proposal "Add caching layer"',
|
|
24492
25187
|
'nexus-agents vote -p "Migrate to PostgreSQL" -t supermajority',
|
|
@@ -24496,7 +25191,7 @@ var VOTE_HELP = {
|
|
|
24496
25191
|
flags: [
|
|
24497
25192
|
{ flag: "-p, --proposal <text>", description: "Proposal text to vote on (required)" },
|
|
24498
25193
|
{ flag: "-t, --threshold <t>", description: "Threshold: majority, supermajority, unanimous" },
|
|
24499
|
-
{ flag: "--quick", description: "Use 3 agents instead of
|
|
25194
|
+
{ flag: "--quick", description: "Use 3 agents instead of the full 7 for faster votes" },
|
|
24500
25195
|
{ flag: "--dry-run", description: "Simulate votes without agent execution" },
|
|
24501
25196
|
{ flag: "--timeout=<seconds>", description: "Timeout per vote in seconds", defaultValue: "90" },
|
|
24502
25197
|
{
|
|
@@ -24509,7 +25204,6 @@ var VOTE_HELP = {
|
|
|
24509
25204
|
};
|
|
24510
25205
|
var EXPERT_HELP = {
|
|
24511
25206
|
command: "expert",
|
|
24512
|
-
description: "Manage expert agents. Subcommands: list, create, execute.",
|
|
24513
25207
|
examples: ["nexus-agents expert list", "nexus-agents expert list --format=json"],
|
|
24514
25208
|
flags: [
|
|
24515
25209
|
{
|
|
@@ -24521,7 +25215,6 @@ var EXPERT_HELP = {
|
|
|
24521
25215
|
};
|
|
24522
25216
|
var WORKFLOW_HELP = {
|
|
24523
25217
|
command: "workflow",
|
|
24524
|
-
description: "Manage and run workflow templates. Subcommands: list, run.",
|
|
24525
25218
|
examples: [
|
|
24526
25219
|
"nexus-agents workflow list",
|
|
24527
25220
|
`nexus-agents workflow run code-review --input='{"url":"https://github.com/o/r/pull/1"}'`,
|
|
@@ -24534,7 +25227,6 @@ var WORKFLOW_HELP = {
|
|
|
24534
25227
|
};
|
|
24535
25228
|
var DOCTOR_HELP = {
|
|
24536
25229
|
command: "doctor",
|
|
24537
|
-
description: "Check CLI installations, adapters, and system health.",
|
|
24538
25230
|
examples: ["nexus-agents doctor", "nexus-agents doctor --deep", "nexus-agents doctor --fix"],
|
|
24539
25231
|
flags: [
|
|
24540
25232
|
{ flag: "--deep", description: "Run deep health checks (adapter connectivity)" },
|
|
@@ -24544,7 +25236,6 @@ var DOCTOR_HELP = {
|
|
|
24544
25236
|
};
|
|
24545
25237
|
var MODE_HELP = {
|
|
24546
25238
|
command: "mode",
|
|
24547
|
-
description: "Inspect the detected invocation mode (server vs orchestrator), the signals that fed the decision, and the one-line reasoning. Useful for debugging unexpected modes in CI/containers.",
|
|
24548
25239
|
examples: [
|
|
24549
25240
|
"nexus-agents mode",
|
|
24550
25241
|
"nexus-agents mode --format=json",
|
|
@@ -24560,7 +25251,6 @@ var MODE_HELP = {
|
|
|
24560
25251
|
};
|
|
24561
25252
|
var SETUP_HELP = {
|
|
24562
25253
|
command: "setup",
|
|
24563
|
-
description: "Configure MCP integration for Claude, Gemini, Codex, and OpenCode CLIs.",
|
|
24564
25254
|
examples: [
|
|
24565
25255
|
"nexus-agents setup",
|
|
24566
25256
|
"nexus-agents setup --interactive",
|
|
@@ -24597,7 +25287,6 @@ var SETUP_HELP = {
|
|
|
24597
25287
|
};
|
|
24598
25288
|
var CONFIG_HELP = {
|
|
24599
25289
|
command: "config",
|
|
24600
|
-
description: "Manage nexus-agents configuration. Subcommands: init, get, set, list, reset, export, import.",
|
|
24601
25290
|
examples: [
|
|
24602
25291
|
"nexus-agents config init",
|
|
24603
25292
|
"nexus-agents config get TIMEOUT_DEFAULTS.cliMs",
|
|
@@ -24617,7 +25306,6 @@ var CONFIG_HELP = {
|
|
|
24617
25306
|
};
|
|
24618
25307
|
var RESEARCH_HELP = {
|
|
24619
25308
|
command: "research",
|
|
24620
|
-
description: "Manage research registry and paper tracking. Subcommands: status, overlap, add, stats, refresh, check, index.",
|
|
24621
25309
|
examples: [
|
|
24622
25310
|
"nexus-agents research status",
|
|
24623
25311
|
"nexus-agents research stats --format=json",
|
|
@@ -24632,7 +25320,6 @@ var RESEARCH_HELP = {
|
|
|
24632
25320
|
};
|
|
24633
25321
|
var FITNESS_AUDIT_HELP = {
|
|
24634
25322
|
command: "fitness-audit",
|
|
24635
|
-
description: "Run CLI orchestration fitness score audit. Target: 90+/100.",
|
|
24636
25323
|
examples: [
|
|
24637
25324
|
"nexus-agents fitness-audit",
|
|
24638
25325
|
"nexus-agents fitness-audit --format=json",
|
|
@@ -24649,7 +25336,6 @@ var FITNESS_AUDIT_HELP = {
|
|
|
24649
25336
|
};
|
|
24650
25337
|
var REVIEW_HELP = {
|
|
24651
25338
|
command: "review",
|
|
24652
|
-
description: "Review a GitHub pull request (dogfooding mode).",
|
|
24653
25339
|
examples: [
|
|
24654
25340
|
"nexus-agents review https://github.com/owner/repo/pull/123",
|
|
24655
25341
|
"nexus-agents review owner/repo#123 --dry-run",
|
|
@@ -24678,11 +25364,14 @@ function formatFlag(entry) {
|
|
|
24678
25364
|
const defaultSuffix = entry.defaultValue !== void 0 ? ` (default: ${entry.defaultValue})` : "";
|
|
24679
25365
|
return ` ${entry.flag.padEnd(28)} ${entry.description}${defaultSuffix}`;
|
|
24680
25366
|
}
|
|
25367
|
+
function describe(command) {
|
|
25368
|
+
return getCommandDescription(command) ?? "";
|
|
25369
|
+
}
|
|
24681
25370
|
function formatCommandHelp(command) {
|
|
24682
25371
|
const entry = COMMAND_HELP.find((e) => e.command === command);
|
|
24683
25372
|
if (entry === void 0) return void 0;
|
|
24684
25373
|
const lines = [];
|
|
24685
|
-
lines.push(`nexus-agents ${entry.command} -- ${entry.
|
|
25374
|
+
lines.push(`nexus-agents ${entry.command} -- ${describe(entry.command)}`);
|
|
24686
25375
|
lines.push("");
|
|
24687
25376
|
if (entry.flags !== void 0 && entry.flags.length > 0) {
|
|
24688
25377
|
lines.push("FLAGS:");
|