sentinelayer-cli 0.46.4 → 0.48.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/README.md +63 -3
- package/package.json +12 -7
- package/skills/omar-gate-setup/SKILL.md +103 -0
- package/skills/senti-agent-identity/SKILL.md +80 -0
- package/skills/senti-judge/SKILL.md +139 -0
- package/skills/senti-room-notifications/SKILL.md +73 -0
- package/skills/senti-room-notifications/listen-wrapper.cjs +150 -0
- package/skills/senti-room-notifications/package.json +1 -0
- package/skills/senti-room-notifications/test-classifier.js +109 -0
- package/skills/senti-room-notifications/test-receipt.js +54 -0
- package/skills/sentinelayer-cli/SKILL.md +222 -0
- package/src/agents/devtestbot/runner.js +22 -11
- package/src/agents/devtestbot/tool.js +24 -11
- package/src/agents/jules/fix-cycle.js +7 -1
- package/src/agents/jules/tools/runtime-audit.js +17 -12
- package/src/agents/shared-tools/dispatch-core.js +10 -5
- package/src/ai/aidenid.js +4 -2
- package/src/ai/domain-target-store.js +11 -5
- package/src/ai/identity-store.js +11 -5
- package/src/ai/site-store.js +8 -4
- package/src/audit/orchestrator.js +21 -14
- package/src/audit/package.js +6 -4
- package/src/audit/persona-loop.js +7 -0
- package/src/audit/replay.js +4 -2
- package/src/auth/gate.js +46 -8
- package/src/auth/service.js +34 -15
- package/src/auth/session-store.js +105 -47
- package/src/board/evidence-resolvers.js +3 -4
- package/src/cli.js +23 -3
- package/src/commands/ai/identity-lifecycle.js +30 -26
- package/src/commands/ai/provision-governance.js +32 -24
- package/src/commands/ai/shared.js +6 -4
- package/src/commands/audit.js +14 -12
- package/src/commands/auth.js +24 -4
- package/src/commands/board.js +2 -2
- package/src/commands/chat.js +8 -6
- package/src/commands/judge.js +125 -0
- package/src/commands/legacy-args.js +1 -0
- package/src/commands/mcp.js +45 -52
- package/src/commands/omargate.js +2 -1
- package/src/commands/plugin.js +11 -3
- package/src/commands/review.js +9 -4
- package/src/commands/scan.js +7 -7
- package/src/commands/session.js +607 -57
- package/src/commands/skills.js +45 -0
- package/src/commands/watch.js +9 -7
- package/src/config/output-filesystem.js +156 -0
- package/src/config/schema.js +4 -2
- package/src/config/service.js +40 -4
- package/src/cost/history.js +15 -9
- package/src/daemon/artifact-lineage.js +15 -12
- package/src/daemon/assignment-ledger.js +31 -25
- package/src/daemon/ast-drift.js +7 -3
- package/src/daemon/budget-governor.js +26 -20
- package/src/daemon/error-worker.js +28 -22
- package/src/daemon/fix-cycle.js +5 -4
- package/src/daemon/hybrid-mapper.js +19 -16
- package/src/daemon/ingest-refresh.js +4 -0
- package/src/daemon/jira-lifecycle.js +21 -17
- package/src/daemon/operator-control.js +18 -15
- package/src/daemon/reliability-lane.js +18 -15
- package/src/daemon/scope-engine.js +12 -8
- package/src/daemon/watchdog.js +15 -12
- package/src/engram/build-state.js +24 -3
- package/src/engram/capability-index.js +367 -0
- package/src/engram/compile-graph.js +1063 -0
- package/src/engram/contracts/action-receipt.js +82 -0
- package/src/engram/contracts/capability-index.js +259 -0
- package/src/engram/contracts/capability.js +377 -0
- package/src/engram/contracts/content-hash.js +8 -0
- package/src/engram/contracts/evidence.js +258 -0
- package/src/engram/contracts/graph.js +594 -0
- package/src/engram/contracts/identity.js +8 -0
- package/src/engram/contracts/index.js +149 -0
- package/src/engram/contracts/media-asset.js +85 -0
- package/src/engram/contracts/money.js +249 -0
- package/src/engram/contracts/source-snapshot.js +57 -0
- package/src/engram/contracts/task-context-pack.js +114 -0
- package/src/engram/contracts/temporal-segment.js +72 -0
- package/src/engram/contracts/versions.js +96 -0
- package/src/engram/extract-html.js +692 -0
- package/src/engram/graph-store.js +877 -0
- package/src/engram/index.js +98 -14
- package/src/engram/ingest-site.js +132 -0
- package/src/engram/live-state.js +1180 -0
- package/src/engram/namespace.js +34 -1
- package/src/engram/retrieve-site.js +753 -0
- package/src/engram/safe-reader.js +597 -0
- package/src/engram/source-intake.js +251 -0
- package/src/engram/store.js +227 -9
- package/src/ingest/engine.js +21 -28
- package/src/judge/verdict.js +305 -0
- package/src/legacy-cli.js +96 -19
- package/src/mcp/bridge-inputs.js +28 -4
- package/src/mcp/cli-command-tools.js +70 -0
- package/src/mcp/registry.js +17 -13
- package/src/mcp/session-stdio-server.js +297 -19
- package/src/memory/blackboard.js +5 -4
- package/src/net/gh-api-path.js +35 -9
- package/src/net/test-egress-guard.js +16 -4
- package/src/plugin/manifest.js +12 -8
- package/src/review/ai-review.js +110 -10
- package/src/review/investor-dd-devtestbot.js +17 -6
- package/src/review/investor-dd-orchestrator.js +21 -13
- package/src/review/local-review.js +26 -16
- package/src/review/omargate-cache.js +5 -5
- package/src/review/omargate-orchestrator.js +89 -17
- package/src/review/replay.js +9 -4
- package/src/review/report.js +22 -13
- package/src/review/typesafe-severity.js +201 -0
- package/src/session/admission-auth.js +34 -7
- package/src/session/admission.js +322 -71
- package/src/session/agent-access.js +137 -0
- package/src/session/agent-registry.js +2 -1
- package/src/session/attachment-summary.js +77 -0
- package/src/session/edit-summary.js +19 -0
- package/src/session/invitations.js +65 -1
- package/src/session/mentions.js +17 -9
- package/src/session/message-edits.js +5 -4
- package/src/session/preview.js +10 -2
- package/src/session/recap.js +3 -2
- package/src/session/room-files.js +519 -0
- package/src/session/route-classes.js +22 -8
- package/src/session/setup-guides.js +4 -0
- package/src/session/standup.js +192 -0
- package/src/session/sync.js +229 -10
- package/src/session/tickets.js +41 -0
- package/src/session/transcript.js +2 -1
- package/src/session/wake/resolve-target.js +7 -3
- package/src/skills/listener-runtime.cjs +92 -0
- package/src/skills/service.js +207 -0
- package/src/swarm/factory.js +5 -5
- package/src/swarm/pentest.js +9 -9
- package/src/swarm/report.js +4 -4
- package/src/swarm/runtime.js +15 -12
- package/src/swarm/scenario-dsl.js +7 -5
- package/src/telemetry/ledger.js +16 -7
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
recordProvisionedIdentity,
|
|
23
23
|
updateIdentityStatus,
|
|
24
24
|
} from "../../ai/identity-store.js";
|
|
25
|
-
import { resolveOutputRoot } from "../../config/service.js";
|
|
25
|
+
import { resolveOutputRoot, resolveOutputContext } from "../../config/service.js";
|
|
26
26
|
import {
|
|
27
27
|
delay,
|
|
28
28
|
hasExtractionSignal,
|
|
@@ -145,7 +145,7 @@ legalHold
|
|
|
145
145
|
.action(async (identityId, options, command) => {
|
|
146
146
|
const emitJson = shouldEmitJson(options, command);
|
|
147
147
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
148
|
-
const outputRoot = await
|
|
148
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
149
149
|
cwd: targetPath,
|
|
150
150
|
outputDirOverride: options.outputDir,
|
|
151
151
|
env: process.env,
|
|
@@ -172,7 +172,7 @@ legalHold
|
|
|
172
172
|
status,
|
|
173
173
|
underHold,
|
|
174
174
|
identity: identityRecord,
|
|
175
|
-
});
|
|
175
|
+
}, outputFs);
|
|
176
176
|
|
|
177
177
|
const payload = {
|
|
178
178
|
command: "ai identity legal-hold status",
|
|
@@ -204,7 +204,7 @@ identity
|
|
|
204
204
|
.action(async (options, command) => {
|
|
205
205
|
const emitJson = shouldEmitJson(options, command);
|
|
206
206
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
207
|
-
const outputRoot = await
|
|
207
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
208
208
|
cwd: targetPath,
|
|
209
209
|
outputDirOverride: options.outputDir,
|
|
210
210
|
env: process.env,
|
|
@@ -223,7 +223,7 @@ identity
|
|
|
223
223
|
staleCount: staleScan.stale.length,
|
|
224
224
|
totalCount: staleScan.identities.length,
|
|
225
225
|
identities,
|
|
226
|
-
});
|
|
226
|
+
}, outputFs);
|
|
227
227
|
|
|
228
228
|
const payload = {
|
|
229
229
|
command: "ai identity audit",
|
|
@@ -269,7 +269,7 @@ identity
|
|
|
269
269
|
throw new Error("At least one tag is required via --tags.");
|
|
270
270
|
}
|
|
271
271
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
272
|
-
const outputRoot = await
|
|
272
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
273
273
|
cwd: targetPath,
|
|
274
274
|
outputDirOverride: options.outputDir,
|
|
275
275
|
env: process.env,
|
|
@@ -293,7 +293,7 @@ identity
|
|
|
293
293
|
candidateIdentityIds: candidates.map((item) => item.identityId),
|
|
294
294
|
blockedIdentityIds: blocked.map((item) => item.identityId),
|
|
295
295
|
eligibleIdentityIds: eligible.map((item) => item.identityId),
|
|
296
|
-
});
|
|
296
|
+
}, outputFs);
|
|
297
297
|
|
|
298
298
|
if (!options.execute) {
|
|
299
299
|
const payload = {
|
|
@@ -345,6 +345,7 @@ identity
|
|
|
345
345
|
revokeResponse = revokeExecution.response || null;
|
|
346
346
|
}
|
|
347
347
|
const updated = await updateIdentityStatus({
|
|
348
|
+
outputFs,
|
|
348
349
|
outputRoot,
|
|
349
350
|
identityId: identityRecord.identityId,
|
|
350
351
|
status: "SQUASHED",
|
|
@@ -379,7 +380,7 @@ identity
|
|
|
379
380
|
updated: updates,
|
|
380
381
|
apiCalled: canCallApi,
|
|
381
382
|
credentialsMissing: resolvedCredentials.missing,
|
|
382
|
-
});
|
|
383
|
+
}, outputFs);
|
|
383
384
|
|
|
384
385
|
const payload = {
|
|
385
386
|
command: "ai identity kill-all",
|
|
@@ -426,7 +427,7 @@ identity
|
|
|
426
427
|
.action(async (identityId, options, command) => {
|
|
427
428
|
const emitJson = shouldEmitJson(options, command);
|
|
428
429
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
429
|
-
const outputRoot = await
|
|
430
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
430
431
|
cwd: targetPath,
|
|
431
432
|
outputDirOverride: options.outputDir,
|
|
432
433
|
env: process.env,
|
|
@@ -441,7 +442,7 @@ identity
|
|
|
441
442
|
apiUrl,
|
|
442
443
|
idempotencyKey,
|
|
443
444
|
identityId,
|
|
444
|
-
});
|
|
445
|
+
}, outputFs);
|
|
445
446
|
|
|
446
447
|
const { registryPath, identity: trackedIdentity } = await getIdentityById({
|
|
447
448
|
outputRoot,
|
|
@@ -472,7 +473,7 @@ identity
|
|
|
472
473
|
credentialsMissing: resolvedCredentials.missing,
|
|
473
474
|
trackedIdentity,
|
|
474
475
|
curlPreview: [
|
|
475
|
-
`curl -X POST ${apiUrl}/v1/identities/${urlPathSegment(identityId, { label: "identityId" })}/
|
|
476
|
+
`curl -X POST ${apiUrl}/v1/identities/${urlPathSegment(identityId, { label: "identityId" })}/squash \\`,
|
|
476
477
|
` -H \"Authorization: Bearer $AIDENID_API_KEY\" \\`,
|
|
477
478
|
` -H \"X-Org-Id: $AIDENID_ORG_ID\" \\`,
|
|
478
479
|
` -H \"X-Project-Id: $AIDENID_PROJECT_ID\" \\`,
|
|
@@ -517,10 +518,11 @@ identity
|
|
|
517
518
|
apiUrl,
|
|
518
519
|
idempotencyKey,
|
|
519
520
|
response: execution.response,
|
|
520
|
-
});
|
|
521
|
+
}, outputFs);
|
|
521
522
|
|
|
522
523
|
const revokedAt = String(execution.response?.revokedAt || "").trim() || new Date().toISOString();
|
|
523
524
|
const updated = await updateIdentityStatus({
|
|
525
|
+
outputFs,
|
|
524
526
|
outputRoot,
|
|
525
527
|
identityId,
|
|
526
528
|
status: String(execution.response?.status || "REVOKED"),
|
|
@@ -576,7 +578,7 @@ identity
|
|
|
576
578
|
.action(async (parentIdentityId, options, command) => {
|
|
577
579
|
const emitJson = shouldEmitJson(options, command);
|
|
578
580
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
579
|
-
const outputRoot = await
|
|
581
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
580
582
|
cwd: targetPath,
|
|
581
583
|
outputDirOverride: options.outputDir,
|
|
582
584
|
env: process.env,
|
|
@@ -617,7 +619,7 @@ identity
|
|
|
617
619
|
idempotencyKey,
|
|
618
620
|
parentIdentityId,
|
|
619
621
|
payload,
|
|
620
|
-
});
|
|
622
|
+
}, outputFs);
|
|
621
623
|
|
|
622
624
|
const resolvedCredentials = await resolveAidenIdCredentials({
|
|
623
625
|
apiKey: options.apiKey,
|
|
@@ -695,9 +697,10 @@ identity
|
|
|
695
697
|
idempotencyKey,
|
|
696
698
|
parentIdentityId,
|
|
697
699
|
response: execution.response,
|
|
698
|
-
});
|
|
700
|
+
}, outputFs);
|
|
699
701
|
|
|
700
702
|
const registryUpdate = await recordProvisionedIdentity({
|
|
703
|
+
outputFs,
|
|
701
704
|
outputRoot,
|
|
702
705
|
response: execution.response || {},
|
|
703
706
|
context: {
|
|
@@ -758,7 +761,7 @@ identity
|
|
|
758
761
|
.action(async (identityId, options, command) => {
|
|
759
762
|
const emitJson = shouldEmitJson(options, command);
|
|
760
763
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
761
|
-
const outputRoot = await
|
|
764
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
762
765
|
cwd: targetPath,
|
|
763
766
|
outputDirOverride: options.outputDir,
|
|
764
767
|
env: process.env,
|
|
@@ -796,7 +799,7 @@ identity
|
|
|
796
799
|
generatedAt: new Date().toISOString(),
|
|
797
800
|
identityId,
|
|
798
801
|
response: execution.response,
|
|
799
|
-
});
|
|
802
|
+
}, outputFs);
|
|
800
803
|
|
|
801
804
|
const rows = renderLineageRows({
|
|
802
805
|
nodes: execution.nodes,
|
|
@@ -843,7 +846,7 @@ identity
|
|
|
843
846
|
.action(async (identityId, options, command) => {
|
|
844
847
|
const emitJson = shouldEmitJson(options, command);
|
|
845
848
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
846
|
-
const outputRoot = await
|
|
849
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
847
850
|
cwd: targetPath,
|
|
848
851
|
outputDirOverride: options.outputDir,
|
|
849
852
|
env: process.env,
|
|
@@ -865,7 +868,7 @@ identity
|
|
|
865
868
|
apiUrl,
|
|
866
869
|
idempotencyKey,
|
|
867
870
|
identityId,
|
|
868
|
-
});
|
|
871
|
+
}, outputFs);
|
|
869
872
|
|
|
870
873
|
const resolvedCredentials = await resolveAidenIdCredentials({
|
|
871
874
|
apiKey: options.apiKey,
|
|
@@ -937,12 +940,13 @@ identity
|
|
|
937
940
|
idempotencyKey,
|
|
938
941
|
identityId,
|
|
939
942
|
response: execution.response,
|
|
940
|
-
});
|
|
943
|
+
}, outputFs);
|
|
941
944
|
|
|
942
945
|
const updateResults = await Promise.all(
|
|
943
946
|
execution.revokedIdentityIds.map(async (revokedIdentityId) => {
|
|
944
947
|
try {
|
|
945
948
|
const updated = await updateIdentityStatus({
|
|
949
|
+
outputFs,
|
|
946
950
|
outputRoot,
|
|
947
951
|
identityId: revokedIdentityId,
|
|
948
952
|
status: "SQUASHED",
|
|
@@ -1003,7 +1007,7 @@ identity
|
|
|
1003
1007
|
.action(async (identityId, options, command) => {
|
|
1004
1008
|
const emitJson = shouldEmitJson(options, command);
|
|
1005
1009
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
1006
|
-
const outputRoot = await
|
|
1010
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
1007
1011
|
cwd: targetPath,
|
|
1008
1012
|
outputDirOverride: options.outputDir,
|
|
1009
1013
|
env: process.env,
|
|
@@ -1048,7 +1052,7 @@ identity
|
|
|
1048
1052
|
cursor: String(options.cursor || "").trim() || null,
|
|
1049
1053
|
limit,
|
|
1050
1054
|
response: execution.response,
|
|
1051
|
-
});
|
|
1055
|
+
}, outputFs);
|
|
1052
1056
|
|
|
1053
1057
|
const payload = {
|
|
1054
1058
|
command: "ai identity events",
|
|
@@ -1096,7 +1100,7 @@ identity
|
|
|
1096
1100
|
.action(async (identityId, options, command) => {
|
|
1097
1101
|
const emitJson = shouldEmitJson(options, command);
|
|
1098
1102
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
1099
|
-
const outputRoot = await
|
|
1103
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
1100
1104
|
cwd: targetPath,
|
|
1101
1105
|
outputDirOverride: options.outputDir,
|
|
1102
1106
|
env: process.env,
|
|
@@ -1149,7 +1153,7 @@ identity
|
|
|
1149
1153
|
latestEvent,
|
|
1150
1154
|
extraction: latestExtraction.extraction,
|
|
1151
1155
|
extractionResponse: latestExtraction.response,
|
|
1152
|
-
});
|
|
1156
|
+
}, outputFs);
|
|
1153
1157
|
|
|
1154
1158
|
const payload = {
|
|
1155
1159
|
command: "ai identity latest",
|
|
@@ -1207,7 +1211,7 @@ identity
|
|
|
1207
1211
|
.action(async (identityId, options, command) => {
|
|
1208
1212
|
const emitJson = shouldEmitJson(options, command);
|
|
1209
1213
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
1210
|
-
const outputRoot = await
|
|
1214
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
1211
1215
|
cwd: targetPath,
|
|
1212
1216
|
outputDirOverride: options.outputDir,
|
|
1213
1217
|
env: process.env,
|
|
@@ -1309,7 +1313,7 @@ identity
|
|
|
1309
1313
|
extraction: lastExtraction,
|
|
1310
1314
|
},
|
|
1311
1315
|
};
|
|
1312
|
-
await writeArtifact(outputPath, artifactPayload);
|
|
1316
|
+
await writeArtifact(outputPath, artifactPayload, outputFs);
|
|
1313
1317
|
|
|
1314
1318
|
if (!success) {
|
|
1315
1319
|
throw new Error(
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "../../ai/domain-target-store.js";
|
|
25
25
|
import { listSites, recordTemporarySite } from "../../ai/site-store.js";
|
|
26
26
|
import { getIdentityById, recordProvisionedIdentity } from "../../ai/identity-store.js";
|
|
27
|
-
import { resolveOutputRoot } from "../../config/service.js";
|
|
27
|
+
import { resolveOutputRoot, resolveOutputContext } from "../../config/service.js";
|
|
28
28
|
import { fetchAidenIdCredentials, resolveActiveAuthSession } from "../../auth/service.js";
|
|
29
29
|
import {
|
|
30
30
|
buildCurlPreview,
|
|
@@ -76,7 +76,7 @@ async function provisionEmailAction(options, command) {
|
|
|
76
76
|
extractionTypes: options.extractionTypes,
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
-
const outputRoot = await
|
|
79
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
80
80
|
cwd: targetPath,
|
|
81
81
|
outputDirOverride: options.outputDir,
|
|
82
82
|
env: process.env,
|
|
@@ -90,7 +90,7 @@ async function provisionEmailAction(options, command) {
|
|
|
90
90
|
apiUrl,
|
|
91
91
|
idempotencyKey,
|
|
92
92
|
payload,
|
|
93
|
-
});
|
|
93
|
+
}, outputFs);
|
|
94
94
|
|
|
95
95
|
const session = await resolveActiveAuthSession({ cwd: process.cwd(), env: process.env, autoRotate: false }).catch(
|
|
96
96
|
() => null,
|
|
@@ -170,10 +170,11 @@ async function provisionEmailAction(options, command) {
|
|
|
170
170
|
apiUrl,
|
|
171
171
|
idempotencyKey,
|
|
172
172
|
response: execution.response,
|
|
173
|
-
});
|
|
173
|
+
}, outputFs);
|
|
174
174
|
|
|
175
175
|
const responseIdentity = execution.response || {};
|
|
176
176
|
const registryUpdate = await recordProvisionedIdentity({
|
|
177
|
+
outputFs,
|
|
177
178
|
outputRoot,
|
|
178
179
|
response: execution.response || {},
|
|
179
180
|
context: {
|
|
@@ -259,7 +260,7 @@ domain
|
|
|
259
260
|
.action(async (domainName, options, command) => {
|
|
260
261
|
const emitJson = shouldEmitJson(options, command);
|
|
261
262
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
262
|
-
const outputRoot = await
|
|
263
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
263
264
|
cwd: targetPath,
|
|
264
265
|
outputDirOverride: options.outputDir,
|
|
265
266
|
env: process.env,
|
|
@@ -287,7 +288,7 @@ domain
|
|
|
287
288
|
apiUrl,
|
|
288
289
|
idempotencyKey,
|
|
289
290
|
payload,
|
|
290
|
-
});
|
|
291
|
+
}, outputFs);
|
|
291
292
|
|
|
292
293
|
const resolvedCredentials = await resolveAidenIdCredentials({
|
|
293
294
|
apiKey: options.apiKey,
|
|
@@ -355,10 +356,11 @@ domain
|
|
|
355
356
|
apiUrl,
|
|
356
357
|
idempotencyKey,
|
|
357
358
|
response: execution.response,
|
|
358
|
-
});
|
|
359
|
+
}, outputFs);
|
|
359
360
|
|
|
360
361
|
const proofResponse = execution.response || {};
|
|
361
362
|
const registryUpdate = await recordDomainProofResponse({
|
|
363
|
+
outputFs,
|
|
362
364
|
outputRoot,
|
|
363
365
|
domain: proofResponse.domain || {},
|
|
364
366
|
proof: proofResponse,
|
|
@@ -416,7 +418,7 @@ domain
|
|
|
416
418
|
.action(async (domainId, options, command) => {
|
|
417
419
|
const emitJson = shouldEmitJson(options, command);
|
|
418
420
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
419
|
-
const outputRoot = await
|
|
421
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
420
422
|
cwd: targetPath,
|
|
421
423
|
outputDirOverride: options.outputDir,
|
|
422
424
|
env: process.env,
|
|
@@ -451,7 +453,7 @@ domain
|
|
|
451
453
|
idempotencyKey,
|
|
452
454
|
domainId,
|
|
453
455
|
payload,
|
|
454
|
-
});
|
|
456
|
+
}, outputFs);
|
|
455
457
|
|
|
456
458
|
const resolvedCredentials = await resolveAidenIdCredentials({
|
|
457
459
|
apiKey: options.apiKey,
|
|
@@ -511,10 +513,11 @@ domain
|
|
|
511
513
|
idempotencyKey,
|
|
512
514
|
domainId,
|
|
513
515
|
response: execution.response,
|
|
514
|
-
});
|
|
516
|
+
}, outputFs);
|
|
515
517
|
|
|
516
518
|
const proofResponse = execution.response || {};
|
|
517
519
|
const registryUpdate = await recordDomainProofResponse({
|
|
520
|
+
outputFs,
|
|
518
521
|
outputRoot,
|
|
519
522
|
domain: proofResponse.domain || {},
|
|
520
523
|
proof: proofResponse,
|
|
@@ -571,7 +574,7 @@ domain
|
|
|
571
574
|
.action(async (domainId, options, command) => {
|
|
572
575
|
const emitJson = shouldEmitJson(options, command);
|
|
573
576
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
574
|
-
const outputRoot = await
|
|
577
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
575
578
|
cwd: targetPath,
|
|
576
579
|
outputDirOverride: options.outputDir,
|
|
577
580
|
env: process.env,
|
|
@@ -593,7 +596,7 @@ domain
|
|
|
593
596
|
idempotencyKey,
|
|
594
597
|
domainId,
|
|
595
598
|
payload,
|
|
596
|
-
});
|
|
599
|
+
}, outputFs);
|
|
597
600
|
|
|
598
601
|
const resolvedCredentials = await resolveAidenIdCredentials({
|
|
599
602
|
apiKey: options.apiKey,
|
|
@@ -653,9 +656,10 @@ domain
|
|
|
653
656
|
idempotencyKey,
|
|
654
657
|
domainId,
|
|
655
658
|
response: execution.response,
|
|
656
|
-
});
|
|
659
|
+
}, outputFs);
|
|
657
660
|
|
|
658
661
|
const registryUpdate = await recordDomainProofResponse({
|
|
662
|
+
outputFs,
|
|
659
663
|
outputRoot,
|
|
660
664
|
domain: execution.response || {},
|
|
661
665
|
proof: {},
|
|
@@ -712,7 +716,7 @@ target
|
|
|
712
716
|
.action(async (host, options, command) => {
|
|
713
717
|
const emitJson = shouldEmitJson(options, command);
|
|
714
718
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
715
|
-
const outputRoot = await
|
|
719
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
716
720
|
cwd: targetPath,
|
|
717
721
|
outputDirOverride: options.outputDir,
|
|
718
722
|
env: process.env,
|
|
@@ -745,7 +749,7 @@ target
|
|
|
745
749
|
apiUrl,
|
|
746
750
|
idempotencyKey,
|
|
747
751
|
payload,
|
|
748
|
-
});
|
|
752
|
+
}, outputFs);
|
|
749
753
|
|
|
750
754
|
const resolvedCredentials = await resolveAidenIdCredentials({
|
|
751
755
|
apiKey: options.apiKey,
|
|
@@ -802,10 +806,11 @@ target
|
|
|
802
806
|
apiUrl,
|
|
803
807
|
idempotencyKey,
|
|
804
808
|
response: execution.response,
|
|
805
|
-
});
|
|
809
|
+
}, outputFs);
|
|
806
810
|
|
|
807
811
|
const proofResponse = execution.response || {};
|
|
808
812
|
const registryUpdate = await recordTargetProofResponse({
|
|
813
|
+
outputFs,
|
|
809
814
|
outputRoot,
|
|
810
815
|
target: proofResponse.target || {},
|
|
811
816
|
proof: proofResponse,
|
|
@@ -862,7 +867,7 @@ target
|
|
|
862
867
|
.action(async (targetId, options, command) => {
|
|
863
868
|
const emitJson = shouldEmitJson(options, command);
|
|
864
869
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
865
|
-
const outputRoot = await
|
|
870
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
866
871
|
cwd: targetPath,
|
|
867
872
|
outputDirOverride: options.outputDir,
|
|
868
873
|
env: process.env,
|
|
@@ -897,7 +902,7 @@ target
|
|
|
897
902
|
idempotencyKey,
|
|
898
903
|
targetId,
|
|
899
904
|
payload,
|
|
900
|
-
});
|
|
905
|
+
}, outputFs);
|
|
901
906
|
|
|
902
907
|
const resolvedCredentials = await resolveAidenIdCredentials({
|
|
903
908
|
apiKey: options.apiKey,
|
|
@@ -957,10 +962,11 @@ target
|
|
|
957
962
|
idempotencyKey,
|
|
958
963
|
targetId,
|
|
959
964
|
response: execution.response,
|
|
960
|
-
});
|
|
965
|
+
}, outputFs);
|
|
961
966
|
|
|
962
967
|
const proofResponse = execution.response || {};
|
|
963
968
|
const registryUpdate = await recordTargetProofResponse({
|
|
969
|
+
outputFs,
|
|
964
970
|
outputRoot,
|
|
965
971
|
target: proofResponse.target || {},
|
|
966
972
|
proof: proofResponse,
|
|
@@ -1012,7 +1018,7 @@ target
|
|
|
1012
1018
|
.action(async (targetId, options, command) => {
|
|
1013
1019
|
const emitJson = shouldEmitJson(options, command);
|
|
1014
1020
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
1015
|
-
const outputRoot = await
|
|
1021
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
1016
1022
|
cwd: targetPath,
|
|
1017
1023
|
outputDirOverride: options.outputDir,
|
|
1018
1024
|
env: process.env,
|
|
@@ -1041,9 +1047,10 @@ target
|
|
|
1041
1047
|
generatedAt: new Date().toISOString(),
|
|
1042
1048
|
targetId,
|
|
1043
1049
|
response: execution.response,
|
|
1044
|
-
});
|
|
1050
|
+
}, outputFs);
|
|
1045
1051
|
|
|
1046
1052
|
const registryUpdate = await recordTargetProofResponse({
|
|
1053
|
+
outputFs,
|
|
1047
1054
|
outputRoot,
|
|
1048
1055
|
target: execution.response || {},
|
|
1049
1056
|
proof: {},
|
|
@@ -1098,7 +1105,7 @@ site
|
|
|
1098
1105
|
.action(async (identityId, options, command) => {
|
|
1099
1106
|
const emitJson = shouldEmitJson(options, command);
|
|
1100
1107
|
const targetPath = path.resolve(process.cwd(), String(options.path || "."));
|
|
1101
|
-
const outputRoot = await
|
|
1108
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
1102
1109
|
cwd: targetPath,
|
|
1103
1110
|
outputDirOverride: options.outputDir,
|
|
1104
1111
|
env: process.env,
|
|
@@ -1132,7 +1139,7 @@ site
|
|
|
1132
1139
|
apiUrl,
|
|
1133
1140
|
idempotencyKey,
|
|
1134
1141
|
payload,
|
|
1135
|
-
});
|
|
1142
|
+
}, outputFs);
|
|
1136
1143
|
|
|
1137
1144
|
const resolvedCredentials = await resolveAidenIdCredentials({
|
|
1138
1145
|
apiKey: options.apiKey,
|
|
@@ -1190,9 +1197,10 @@ site
|
|
|
1190
1197
|
apiUrl,
|
|
1191
1198
|
idempotencyKey,
|
|
1192
1199
|
response: execution.response,
|
|
1193
|
-
});
|
|
1200
|
+
}, outputFs);
|
|
1194
1201
|
|
|
1195
1202
|
const registryUpdate = await recordTemporarySite({
|
|
1203
|
+
outputFs,
|
|
1196
1204
|
outputRoot,
|
|
1197
1205
|
site: execution.response || {},
|
|
1198
1206
|
context: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { requireOutputFileSystem } from "../../config/output-filesystem.js";
|
|
4
5
|
|
|
5
6
|
// Shared helper utilities for ai command modules.
|
|
6
7
|
|
|
@@ -128,9 +129,10 @@ export function renderLineageRows(lineage = {}) {
|
|
|
128
129
|
});
|
|
129
130
|
}
|
|
130
131
|
|
|
131
|
-
export async function writeArtifact(filePath, payload) {
|
|
132
|
-
|
|
133
|
-
await
|
|
132
|
+
export async function writeArtifact(filePath, payload, outputFs) {
|
|
133
|
+
requireOutputFileSystem(outputFs);
|
|
134
|
+
await outputFs.mkdir(path.dirname(filePath), { recursive: true });
|
|
135
|
+
await outputFs.writeFile(filePath, `${JSON.stringify(payload, null, 2)}\n`, "utf-8");
|
|
134
136
|
}
|
|
135
137
|
|
|
136
138
|
export function buildCurlPreview({ apiUrl, idempotencyKey, requestPath }) {
|
package/src/commands/audit.js
CHANGED
|
@@ -7,7 +7,7 @@ import { runAuditOrchestrator } from "../audit/orchestrator.js";
|
|
|
7
7
|
import { loadAuditRunReport, resolveAuditRunDirectory, writeDdPackage } from "../audit/package.js";
|
|
8
8
|
import { writeAuditComparisonArtifact } from "../audit/replay.js";
|
|
9
9
|
import { loadAuditRegistry, selectAuditAgents } from "../audit/registry.js";
|
|
10
|
-
import {
|
|
10
|
+
import { resolveOutputContext } from "../config/service.js";
|
|
11
11
|
import { createAgentEvent } from "../events/schema.js";
|
|
12
12
|
import { createAuditSessionReporter, resolveAuditSessionId } from "../session/audit-reporter.js";
|
|
13
13
|
import { resolveActionOptions } from "./action-options.js";
|
|
@@ -217,7 +217,7 @@ export function registerAuditCommand(program, invokeLegacy) {
|
|
|
217
217
|
const actionOptions = resolveActionOptions(options, command);
|
|
218
218
|
const emitJson = shouldEmitJson(actionOptions, command);
|
|
219
219
|
const targetPath = path.resolve(process.cwd(), String(actionOptions.path || "."));
|
|
220
|
-
const outputRoot = await
|
|
220
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
221
221
|
cwd: targetPath,
|
|
222
222
|
outputDirOverride: actionOptions.outputDir,
|
|
223
223
|
env: process.env,
|
|
@@ -228,6 +228,7 @@ export function registerAuditCommand(program, invokeLegacy) {
|
|
|
228
228
|
});
|
|
229
229
|
const { report } = await loadAuditRunReport(runDirectory);
|
|
230
230
|
const ddPackage = await writeDdPackage({
|
|
231
|
+
outputFs,
|
|
231
232
|
report,
|
|
232
233
|
runDirectory,
|
|
233
234
|
});
|
|
@@ -269,7 +270,7 @@ export function registerAuditCommand(program, invokeLegacy) {
|
|
|
269
270
|
const actionOptions = resolveActionOptions(options, command);
|
|
270
271
|
const emitJson = shouldEmitJson(actionOptions, command);
|
|
271
272
|
const initialTargetPath = path.resolve(process.cwd(), String(actionOptions.path || "."));
|
|
272
|
-
const outputRoot = await
|
|
273
|
+
const { outputRoot } = await resolveOutputContext({
|
|
273
274
|
cwd: initialTargetPath,
|
|
274
275
|
outputDirOverride: actionOptions.outputDir,
|
|
275
276
|
env: process.env,
|
|
@@ -306,6 +307,7 @@ export function registerAuditCommand(program, invokeLegacy) {
|
|
|
306
307
|
baseReport,
|
|
307
308
|
candidateReport: replayResult,
|
|
308
309
|
outputDirectory: replayResult.runDirectory,
|
|
310
|
+
outputFs: replayResult.outputFs,
|
|
309
311
|
});
|
|
310
312
|
|
|
311
313
|
const payload = {
|
|
@@ -347,7 +349,7 @@ export function registerAuditCommand(program, invokeLegacy) {
|
|
|
347
349
|
const actionOptions = resolveActionOptions(options, command);
|
|
348
350
|
const emitJson = shouldEmitJson(actionOptions, command);
|
|
349
351
|
const targetPath = path.resolve(process.cwd(), String(actionOptions.path || "."));
|
|
350
|
-
const outputRoot = await
|
|
352
|
+
const { outputRoot, outputFs } = await resolveOutputContext({
|
|
351
353
|
cwd: targetPath,
|
|
352
354
|
outputDirOverride: actionOptions.outputDir,
|
|
353
355
|
env: process.env,
|
|
@@ -366,6 +368,7 @@ export function registerAuditCommand(program, invokeLegacy) {
|
|
|
366
368
|
baseReport,
|
|
367
369
|
candidateReport,
|
|
368
370
|
outputDirectory: candidateRunDirectory,
|
|
371
|
+
outputFs,
|
|
369
372
|
});
|
|
370
373
|
|
|
371
374
|
const payload = {
|
|
@@ -869,14 +872,12 @@ export function registerAuditCommand(program, invokeLegacy) {
|
|
|
869
872
|
const { julesAuditLoop } = await import("../agents/jules/loop.js");
|
|
870
873
|
const { JULES_DEFINITION } = await import("../agents/jules/config/definition.js");
|
|
871
874
|
const { collectCodebaseIngest, generateCodebaseIngest } = await import("../ingest/engine.js");
|
|
872
|
-
const { resolveOutputRoot: resolveOut } = await import("../config/service.js");
|
|
873
875
|
const { createBlackboard } = await import("../memory/blackboard.js");
|
|
874
876
|
const { runDeterministicReviewPipeline } = await import("../review/local-review.js");
|
|
875
|
-
const fsp = await import("node:fs/promises");
|
|
876
877
|
|
|
877
|
-
const outputRoot = await
|
|
878
|
+
const { outputRoot, outputFs } = await resolveOutputContext({ cwd: targetPath, outputDirOverride: actionOptions.outputDir });
|
|
878
879
|
const artifactDir = path.join(outputRoot, "reports", "jules-" + Date.now());
|
|
879
|
-
await
|
|
880
|
+
await outputFs.mkdir(artifactDir, { recursive: true });
|
|
880
881
|
|
|
881
882
|
// Build event handler
|
|
882
883
|
const onEvent = buildEventHandler(emitStream, emitJson, JULES_DEFINITION);
|
|
@@ -888,7 +889,7 @@ export function registerAuditCommand(program, invokeLegacy) {
|
|
|
888
889
|
let ingest;
|
|
889
890
|
try {
|
|
890
891
|
ingest = await generateCodebaseIngest({
|
|
891
|
-
rootPath: targetPath, outputDir:
|
|
892
|
+
rootPath: targetPath, outputDir: actionOptions.outputDir,
|
|
892
893
|
refresh: Boolean(actionOptions.refresh),
|
|
893
894
|
});
|
|
894
895
|
} catch {
|
|
@@ -907,6 +908,7 @@ export function registerAuditCommand(program, invokeLegacy) {
|
|
|
907
908
|
targetPath,
|
|
908
909
|
mode: "full",
|
|
909
910
|
outputDir: artifactDir,
|
|
911
|
+
outputFs,
|
|
910
912
|
});
|
|
911
913
|
emitProgress(onEvent, JULES_DEFINITION,
|
|
912
914
|
"Baseline complete: P0=" + (omarBaseline?.summary?.P0 || 0) +
|
|
@@ -1085,21 +1087,21 @@ export function registerAuditCommand(program, invokeLegacy) {
|
|
|
1085
1087
|
signature: JULES_DEFINITION.signature,
|
|
1086
1088
|
};
|
|
1087
1089
|
|
|
1088
|
-
await
|
|
1090
|
+
await outputFs.writeFile(
|
|
1089
1091
|
path.join(artifactDir, "JULES_AUDIT.json"),
|
|
1090
1092
|
JSON.stringify(reportPayload, null, 2),
|
|
1091
1093
|
);
|
|
1092
1094
|
|
|
1093
1095
|
// Write baseline artifact if it exists
|
|
1094
1096
|
if (omarBaseline) {
|
|
1095
|
-
await
|
|
1097
|
+
await outputFs.writeFile(
|
|
1096
1098
|
path.join(artifactDir, "OMAR_BASELINE.json"),
|
|
1097
1099
|
JSON.stringify(omarBaseline, null, 2),
|
|
1098
1100
|
);
|
|
1099
1101
|
}
|
|
1100
1102
|
|
|
1101
1103
|
// Write reconciliation artifact
|
|
1102
|
-
await
|
|
1104
|
+
await outputFs.writeFile(
|
|
1103
1105
|
path.join(artifactDir, "RECONCILIATION.json"),
|
|
1104
1106
|
JSON.stringify(reconciliation, null, 2),
|
|
1105
1107
|
);
|
package/src/commands/auth.js
CHANGED
|
@@ -133,6 +133,14 @@ export function registerAuthCommand(program) {
|
|
|
133
133
|
tokenLabel: options.tokenLabel,
|
|
134
134
|
tokenTtlDays,
|
|
135
135
|
cliVersion: CLI_VERSION,
|
|
136
|
+
onAuthorize: ({ authorizeUrl }) => {
|
|
137
|
+
// A spawned opener does not prove a browser exists on a headless host.
|
|
138
|
+
if (!authorizeUrl) return;
|
|
139
|
+
const safeUrl = String(authorizeUrl).replace(/[\u0000-\u001f\u007f-\u009f]/g, "").slice(0, 4096);
|
|
140
|
+
const line = `Open this URL to approve sign-in:\n${safeUrl}\n`;
|
|
141
|
+
if (shouldEmitJson(options, command)) process.stderr.write(line);
|
|
142
|
+
else console.log(line.trimEnd());
|
|
143
|
+
},
|
|
136
144
|
});
|
|
137
145
|
} catch (error) {
|
|
138
146
|
throw new Error(formatApiError(error));
|
|
@@ -159,10 +167,6 @@ export function registerAuthCommand(program) {
|
|
|
159
167
|
if (result.filePath) {
|
|
160
168
|
console.log(pc.gray(`Session metadata: ${result.filePath}`));
|
|
161
169
|
}
|
|
162
|
-
if (!result.browserOpened && result.authorizeUrl) {
|
|
163
|
-
console.log(pc.yellow("Open this URL to approve sign-in:"));
|
|
164
|
-
console.log(result.authorizeUrl);
|
|
165
|
-
}
|
|
166
170
|
});
|
|
167
171
|
|
|
168
172
|
auth
|
|
@@ -199,6 +203,13 @@ export function registerAuthCommand(program) {
|
|
|
199
203
|
|
|
200
204
|
console.log(pc.bold("Authentication status"));
|
|
201
205
|
console.log(pc.gray(`API: ${status.apiUrl}`));
|
|
206
|
+
if (status.validation === "storage_unavailable") {
|
|
207
|
+
console.log(pc.yellow("Stored sign-in metadata exists, but its credential cannot be read. Authentication is unknown."));
|
|
208
|
+
if (status.filePath) console.log(pc.gray(`Session metadata: ${status.filePath}`));
|
|
209
|
+
console.log(pc.gray("Check the current user/home, keyring availability, encryption key and file permissions."));
|
|
210
|
+
console.log(pc.gray("Credentials were not cleared. Repair storage instead of logging out or signing in again for this error."));
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
202
213
|
if (!status.source) {
|
|
203
214
|
console.log(pc.yellow("No active session token found."));
|
|
204
215
|
printAuthHint();
|
|
@@ -254,6 +265,15 @@ export function registerAuthCommand(program) {
|
|
|
254
265
|
}`
|
|
255
266
|
)
|
|
256
267
|
);
|
|
268
|
+
if (status.validation === "unavailable") {
|
|
269
|
+
console.log(pc.yellow("Remote validation is temporarily unavailable; your existing credentials were not cleared."));
|
|
270
|
+
console.log(pc.gray("Retry auth status when the API is reachable. Do not sign in again solely for this validation error."));
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
if (["CREDENTIAL_DESTINATION_REFUSED", "CREDENTIAL_PATH_REFUSED"].includes(status.remoteError.code)) {
|
|
274
|
+
console.log(pc.yellow("Credential destination was refused. Check the configured API; signing in again does not change this boundary."));
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
257
277
|
} else {
|
|
258
278
|
console.log(pc.yellow("Remote validation was skipped (`--offline`)."));
|
|
259
279
|
}
|