overlane 0.1.137 → 0.1.139
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/overlane.mjs +1272 -231
- package/package.json +1 -1
- package/plugins/claude/plugins/mvrx-harness/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-codemap.mjs +26 -26
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-context.mjs +24 -24
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-guard.mjs +17 -17
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-intake.mjs +27 -27
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-quota.mjs +22 -22
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-statusline.mjs +18 -18
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-stop.mjs +25 -25
- package/plugins/codex/plugins/mvrx-harness/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-codemap.mjs +26 -26
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-context.mjs +24 -24
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-guard.mjs +17 -17
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-intake.mjs +27 -27
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-quota.mjs +22 -22
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-statusline.mjs +18 -18
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-stop.mjs +25 -25
- package/plugins/release-manifest.json +22 -22
package/dist/overlane.mjs
CHANGED
|
@@ -4545,7 +4545,7 @@ function isRef(value) {
|
|
|
4545
4545
|
function cloneIssues(issues) {
|
|
4546
4546
|
return issues.map((iss) => iss.path ? { ...iss, path: iss.path.slice() } : { ...iss });
|
|
4547
4547
|
}
|
|
4548
|
-
function isRecursive(inst, stack,
|
|
4548
|
+
function isRecursive(inst, stack, resolve17) {
|
|
4549
4549
|
const cached2 = recursive.get(inst);
|
|
4550
4550
|
if (cached2 !== void 0)
|
|
4551
4551
|
return cached2 ? PROVEN : NONE;
|
|
@@ -4555,7 +4555,7 @@ function isRecursive(inst, stack, resolve16) {
|
|
|
4555
4555
|
let result = NONE;
|
|
4556
4556
|
const check2 = (child) => {
|
|
4557
4557
|
if (result !== PROVEN && child?._zod) {
|
|
4558
|
-
const answer = isRecursive(child, stack,
|
|
4558
|
+
const answer = isRecursive(child, stack, resolve17);
|
|
4559
4559
|
if (answer > result)
|
|
4560
4560
|
result = answer;
|
|
4561
4561
|
}
|
|
@@ -4566,7 +4566,7 @@ function isRecursive(inst, stack, resolve16) {
|
|
|
4566
4566
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
4567
4567
|
if (spread && !desc.enumerable)
|
|
4568
4568
|
continue;
|
|
4569
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
4569
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve17) : NONE;
|
|
4570
4570
|
if (child > answer)
|
|
4571
4571
|
answer = child;
|
|
4572
4572
|
}
|
|
@@ -4630,7 +4630,7 @@ function isRecursive(inst, stack, resolve16) {
|
|
|
4630
4630
|
break;
|
|
4631
4631
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
4632
4632
|
case "lazy": {
|
|
4633
|
-
const inner = def._cachedInner ?? (
|
|
4633
|
+
const inner = def._cachedInner ?? (resolve17 ? inst._zod.innerType : void 0);
|
|
4634
4634
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
4635
4635
|
break;
|
|
4636
4636
|
}
|
|
@@ -4732,14 +4732,14 @@ var init_memoizer = __esm({
|
|
|
4732
4732
|
var _a3;
|
|
4733
4733
|
(_a3 = inst._zod).deferred ?? (_a3.deferred = []);
|
|
4734
4734
|
inst._zod.deferred.push(() => {
|
|
4735
|
-
const
|
|
4735
|
+
const base5 = inst._zod.parse;
|
|
4736
4736
|
const wrapped = (payload, ctx) => {
|
|
4737
4737
|
if (ctx.direction !== "backward" && isBackEdge(ctx, payload.value))
|
|
4738
4738
|
throw new $ZodCyclicError();
|
|
4739
|
-
return
|
|
4739
|
+
return base5(payload, ctx);
|
|
4740
4740
|
};
|
|
4741
4741
|
inst._zod.parse = wrapped;
|
|
4742
|
-
if (inst._zod.run ===
|
|
4742
|
+
if (inst._zod.run === base5)
|
|
4743
4743
|
inst._zod.run = wrapped;
|
|
4744
4744
|
});
|
|
4745
4745
|
},
|
|
@@ -4751,15 +4751,15 @@ var init_memoizer = __esm({
|
|
|
4751
4751
|
let lastBucket;
|
|
4752
4752
|
(_a3 = inst._zod).deferred ?? (_a3.deferred = []);
|
|
4753
4753
|
inst._zod.deferred.push(() => {
|
|
4754
|
-
const
|
|
4754
|
+
const base5 = inst._zod.parse;
|
|
4755
4755
|
const wrapped = (payload, ctx) => {
|
|
4756
4756
|
if (isRecursiveInst === void 0) {
|
|
4757
4757
|
const walked = isRecursive(inst, /* @__PURE__ */ new Set(), false);
|
|
4758
4758
|
if (walked === NONE) {
|
|
4759
|
-
inst._zod.parse =
|
|
4759
|
+
inst._zod.parse = base5;
|
|
4760
4760
|
if (inst._zod.run === wrapped)
|
|
4761
|
-
inst._zod.run =
|
|
4762
|
-
return
|
|
4761
|
+
inst._zod.run = base5;
|
|
4762
|
+
return base5(payload, ctx);
|
|
4763
4763
|
}
|
|
4764
4764
|
if (walked === PROVEN || rechecked)
|
|
4765
4765
|
isRecursiveInst = true;
|
|
@@ -4768,7 +4768,7 @@ var init_memoizer = __esm({
|
|
|
4768
4768
|
}
|
|
4769
4769
|
const input2 = payload.value;
|
|
4770
4770
|
if (!isRef(input2))
|
|
4771
|
-
return
|
|
4771
|
+
return base5(payload, ctx);
|
|
4772
4772
|
let state = ctx[STATE];
|
|
4773
4773
|
if (!state) {
|
|
4774
4774
|
state = { buckets: /* @__PURE__ */ new WeakMap(), backEdges: void 0 };
|
|
@@ -4797,7 +4797,7 @@ var init_memoizer = __esm({
|
|
|
4797
4797
|
}
|
|
4798
4798
|
handoff = bucket;
|
|
4799
4799
|
const depth = open.length;
|
|
4800
|
-
const result =
|
|
4800
|
+
const result = base5(payload, ctx);
|
|
4801
4801
|
handoff = void 0;
|
|
4802
4802
|
const entry = open.length > depth ? open.pop() : void 0;
|
|
4803
4803
|
if (result instanceof Promise) {
|
|
@@ -4812,7 +4812,7 @@ var init_memoizer = __esm({
|
|
|
4812
4812
|
return result;
|
|
4813
4813
|
};
|
|
4814
4814
|
inst._zod.parse = wrapped;
|
|
4815
|
-
if (inst._zod.run ===
|
|
4815
|
+
if (inst._zod.run === base5)
|
|
4816
4816
|
inst._zod.run = wrapped;
|
|
4817
4817
|
});
|
|
4818
4818
|
}
|
|
@@ -22552,6 +22552,27 @@ function chainAuditEvent(prevHash, body2) {
|
|
|
22552
22552
|
const previous = prevHash ?? AUDIT_GENESIS_HASH;
|
|
22553
22553
|
return AuditEvent.parse({ ...body2, prevHash: previous, hash: auditHash(previous, body2) });
|
|
22554
22554
|
}
|
|
22555
|
+
function bodyOf(event) {
|
|
22556
|
+
const { prevHash: _p, hash: _h, ...body2 } = event;
|
|
22557
|
+
return body2;
|
|
22558
|
+
}
|
|
22559
|
+
function verifyAuditChain(tenantId, events, start2 = { prevHash: AUDIT_GENESIS_HASH, seq: 0 }) {
|
|
22560
|
+
let prev = start2.prevHash;
|
|
22561
|
+
let seq = start2.seq;
|
|
22562
|
+
let checked2 = 0;
|
|
22563
|
+
for (const event of events) {
|
|
22564
|
+
const fail = (reason) => ({ tenantId, ok: false, checked: checked2, head: checked2 === 0 ? null : prev, brokenAt: event.seq > 0 ? event.seq : seq + 1, reason });
|
|
22565
|
+
if (event.tenantId !== tenantId) return fail("wrong_tenant");
|
|
22566
|
+
if (event.seq !== seq + 1) return fail("bad_sequence");
|
|
22567
|
+
if (event.prevHash !== prev) return fail("bad_link");
|
|
22568
|
+
if (AUDIT_ACTIONS[event.action] !== event.category) return fail("bad_category");
|
|
22569
|
+
if (auditHash(prev, bodyOf(event)) !== event.hash) return fail("bad_hash");
|
|
22570
|
+
prev = event.hash;
|
|
22571
|
+
seq = event.seq;
|
|
22572
|
+
checked2 += 1;
|
|
22573
|
+
}
|
|
22574
|
+
return { tenantId, ok: true, checked: checked2, head: checked2 === 0 && start2.seq === 0 ? null : prev };
|
|
22575
|
+
}
|
|
22555
22576
|
var AUDIT_CATEGORIES, AuditCategory, AUDIT_ACTIONS, AUDIT_ACTION_NAMES, AuditActionName, AUDIT_RESULTS, AuditResult, AuditPrincipalType, AuditTarget, Hash, AUDIT_GENESIS_HASH, AuditEventBody, AuditEvent, AuditList, AuditVerification, K, FIXTURE_AT, fixtureBodies, AUDIT_FIXTURE;
|
|
22556
22577
|
var init_audit = __esm({
|
|
22557
22578
|
"../contracts/src/audit.ts"() {
|
|
@@ -22583,7 +22604,57 @@ var init_audit = __esm({
|
|
|
22583
22604
|
"bot.revoked": "policy",
|
|
22584
22605
|
"bot.key_rotated": "policy",
|
|
22585
22606
|
"token.created": "token",
|
|
22586
|
-
"token.revoked": "token"
|
|
22607
|
+
"token.revoked": "token",
|
|
22608
|
+
// MS-B6 enterprise (additive)
|
|
22609
|
+
"sso.portal_link_issued": "admin",
|
|
22610
|
+
"directory.synced": "admin",
|
|
22611
|
+
"group_mapping.updated": "admin",
|
|
22612
|
+
"audit.exported": "admin",
|
|
22613
|
+
"siem_target.created": "policy",
|
|
22614
|
+
"siem_target.deleted": "policy",
|
|
22615
|
+
"residency.pinned": "policy",
|
|
22616
|
+
"residency.migration_requested": "policy",
|
|
22617
|
+
"byok.key_added": "token",
|
|
22618
|
+
"byok.key_tested": "token",
|
|
22619
|
+
"byok.key_rotated": "token",
|
|
22620
|
+
"byok.key_revoked": "token",
|
|
22621
|
+
"retention.updated": "policy",
|
|
22622
|
+
"retention.purged": "policy",
|
|
22623
|
+
"data.exported": "admin",
|
|
22624
|
+
"data.deleted": "admin",
|
|
22625
|
+
"restore.drill_run": "admin",
|
|
22626
|
+
"mcp_allowlist.updated": "policy",
|
|
22627
|
+
// Admin, policy and token routes added by MS-A6, MS-A8, MS-A9 and MS-C1 that wrote no row until the platform end-to-end check found it (additive)
|
|
22628
|
+
"repo.mirror_set": "policy",
|
|
22629
|
+
"repo.deleted": "admin",
|
|
22630
|
+
"branch_protection.updated": "policy",
|
|
22631
|
+
"ci_settings.updated": "policy",
|
|
22632
|
+
"ci_secret.set": "token",
|
|
22633
|
+
"ci_secret.deleted": "token",
|
|
22634
|
+
"deploy_target.created": "policy",
|
|
22635
|
+
"deploy_environment.created": "policy",
|
|
22636
|
+
"deploy_secret.set": "token",
|
|
22637
|
+
"decision_settings.updated": "policy",
|
|
22638
|
+
"claim_policy.updated": "policy",
|
|
22639
|
+
"budget.set": "policy",
|
|
22640
|
+
"budget.removed": "policy",
|
|
22641
|
+
"pr_routing_policy.updated": "policy",
|
|
22642
|
+
"egress_policy.updated": "policy",
|
|
22643
|
+
"agent_readonly.changed": "policy",
|
|
22644
|
+
"connector.connected": "token",
|
|
22645
|
+
"connector.revoked": "token",
|
|
22646
|
+
"mcp_server.added": "policy",
|
|
22647
|
+
"mcp_server.removed": "policy",
|
|
22648
|
+
"chat_user.mapped": "admin",
|
|
22649
|
+
"api_key.created": "token",
|
|
22650
|
+
"api_key.revoked": "token",
|
|
22651
|
+
"api_key.rotated": "token",
|
|
22652
|
+
"webhook.created": "policy",
|
|
22653
|
+
"webhook.deleted": "policy",
|
|
22654
|
+
"webhook.rotated": "token",
|
|
22655
|
+
"alert_rule.updated": "policy",
|
|
22656
|
+
"alert_rule.deleted": "policy",
|
|
22657
|
+
"observe_retention.purged": "policy"
|
|
22587
22658
|
};
|
|
22588
22659
|
AUDIT_ACTION_NAMES = Object.keys(AUDIT_ACTIONS);
|
|
22589
22660
|
AuditActionName = external_exports.enum(Object.keys(AUDIT_ACTIONS));
|
|
@@ -25646,7 +25717,39 @@ var init_route_commands = __esm({
|
|
|
25646
25717
|
"webhooks.delete": c("webhook delete"),
|
|
25647
25718
|
"webhooks.rotate": c("webhook rotate"),
|
|
25648
25719
|
"webhooks.test": c("webhook test"),
|
|
25649
|
-
"webhooks.deliveries": c("webhook deliveries")
|
|
25720
|
+
"webhooks.deliveries": c("webhook deliveries"),
|
|
25721
|
+
// Enterprise (MS-B6)
|
|
25722
|
+
"enterprise.entitlements": c("enterprise status"),
|
|
25723
|
+
"enterprise.identity.get": c("enterprise sso show"),
|
|
25724
|
+
"enterprise.identity.portal-link": c("enterprise sso link"),
|
|
25725
|
+
"enterprise.identity.test": c("enterprise sso test"),
|
|
25726
|
+
"enterprise.identity.sync": c("enterprise sso sync"),
|
|
25727
|
+
"enterprise.identity.mappings.get": c("enterprise sso show"),
|
|
25728
|
+
"enterprise.identity.mappings.put": c("enterprise sso groups set"),
|
|
25729
|
+
"enterprise.audit-exports.create": c("enterprise audit export"),
|
|
25730
|
+
"enterprise.streams.list": c("enterprise audit stream list"),
|
|
25731
|
+
"enterprise.streams.create": c("enterprise audit stream add"),
|
|
25732
|
+
"enterprise.streams.delete": c("enterprise audit stream remove"),
|
|
25733
|
+
"enterprise.streams.run": c("enterprise audit stream run"),
|
|
25734
|
+
"enterprise.residency.get": c("enterprise region show"),
|
|
25735
|
+
"enterprise.residency.put": c("enterprise region set"),
|
|
25736
|
+
"enterprise.residency.migrate": c("enterprise region set"),
|
|
25737
|
+
"enterprise.residency.stores": c("enterprise region show"),
|
|
25738
|
+
"enterprise.byok.list": c("enterprise keys list"),
|
|
25739
|
+
"enterprise.byok.create": c("enterprise keys add"),
|
|
25740
|
+
"enterprise.byok.revoke": c("enterprise keys revoke"),
|
|
25741
|
+
"enterprise.byok.test": c("enterprise keys test"),
|
|
25742
|
+
"enterprise.byok.rotate": c("enterprise keys rotate"),
|
|
25743
|
+
"enterprise.retention.get": c("enterprise retention show"),
|
|
25744
|
+
"enterprise.retention.put": c("enterprise retention set"),
|
|
25745
|
+
"enterprise.retention.purge": c("enterprise retention purge"),
|
|
25746
|
+
"enterprise.retention.reports": c("enterprise retention reports"),
|
|
25747
|
+
"enterprise.data.export": c("enterprise data export"),
|
|
25748
|
+
"enterprise.data.delete": c("enterprise data delete"),
|
|
25749
|
+
"enterprise.backups.drill": c("enterprise backups drill"),
|
|
25750
|
+
"enterprise.mcp-allowlist.get": c("enterprise mcp-allowlist show"),
|
|
25751
|
+
"enterprise.mcp-allowlist.put": c("enterprise mcp-allowlist set"),
|
|
25752
|
+
"enterprise.evidence-pack": c("enterprise evidence-pack")
|
|
25650
25753
|
};
|
|
25651
25754
|
}
|
|
25652
25755
|
});
|
|
@@ -26027,49 +26130,49 @@ function describeLine(text) {
|
|
|
26027
26130
|
return clean2.length > 80 ? `${clean2.slice(0, 77)}...` : clean2;
|
|
26028
26131
|
}
|
|
26029
26132
|
function inspectRegionTarget(target2, fileText, source) {
|
|
26030
|
-
const
|
|
26031
|
-
if (fileText === null) return { ...
|
|
26133
|
+
const base5 = { id: target2.id, path: target2.path };
|
|
26134
|
+
if (fileText === null) return { ...base5, state: "missing", detail: `${target2.path} does not exist; sync creates it`, syncable: true };
|
|
26032
26135
|
const scan = scanRegion(fileText);
|
|
26033
|
-
if (scan.kind === "damaged") return { ...
|
|
26034
|
-
if (scan.kind === "none") return { ...
|
|
26136
|
+
if (scan.kind === "damaged") return { ...base5, state: "damaged", detail: `${target2.path}: ${scan.problem}; fix the markers by hand, then run sync`, syncable: false };
|
|
26137
|
+
if (scan.kind === "none") return { ...base5, state: "unmanaged", detail: `${target2.path} has no managed region; sync appends one and keeps every existing line`, syncable: true };
|
|
26035
26138
|
const { region } = scan;
|
|
26036
26139
|
if (digestOf(region.body) !== region.digest) {
|
|
26037
26140
|
const expected = regionBody(source.text);
|
|
26038
26141
|
const diff = firstDifference(region.body, region.revision === source.revision ? expected : region.body);
|
|
26039
26142
|
const where2 = region.revision === source.revision ? `line ${diff.line} of the region` : "the region";
|
|
26040
26143
|
return {
|
|
26041
|
-
...
|
|
26144
|
+
...base5,
|
|
26042
26145
|
state: "edited",
|
|
26043
26146
|
detail: `${target2.path}: ${where2} was edited by hand${region.revision === source.revision ? ` (found "${describeLine(diff.found)}", the source says "${describeLine(diff.expected)}")` : ""}; move the change into ${RULES_SOURCE_PATH}, or run sync --overwrite-edits to replace it`,
|
|
26044
26147
|
...region.revision === source.revision ? { firstDifference: diff } : {},
|
|
26045
26148
|
syncable: false
|
|
26046
26149
|
};
|
|
26047
26150
|
}
|
|
26048
|
-
if (region.revision !== source.revision) return { ...
|
|
26049
|
-
return { ...
|
|
26151
|
+
if (region.revision !== source.revision) return { ...base5, state: "stale", detail: `${target2.path} was written from revision ${region.revision}; the source is ${source.revision}; sync updates it`, syncable: true };
|
|
26152
|
+
return { ...base5, state: "in_sync", detail: `${target2.path} matches revision ${source.revision}`, syncable: true };
|
|
26050
26153
|
}
|
|
26051
26154
|
function planRegionSync(target2, fileText, source, force) {
|
|
26052
26155
|
const report2 = inspectRegionTarget(target2, fileText, source);
|
|
26053
26156
|
const region = renderRegion(source.text);
|
|
26054
|
-
const
|
|
26157
|
+
const base5 = { id: target2.id, path: target2.path };
|
|
26055
26158
|
switch (report2.state) {
|
|
26056
26159
|
case "in_sync":
|
|
26057
|
-
return { ...
|
|
26160
|
+
return { ...base5, action: "none", next: null, reason: report2.detail };
|
|
26058
26161
|
case "missing":
|
|
26059
|
-
return { ...
|
|
26162
|
+
return { ...base5, action: "create", next: `${target2.preamble}${region}`, reason: "created" };
|
|
26060
26163
|
case "unmanaged": {
|
|
26061
26164
|
const text = normaliseText(fileText);
|
|
26062
26165
|
const joined = text === "" ? "" : text.endsWith("\n\n") ? text : text.endsWith("\n") ? `${text}
|
|
26063
26166
|
` : `${text}
|
|
26064
26167
|
|
|
26065
26168
|
`;
|
|
26066
|
-
return { ...
|
|
26169
|
+
return { ...base5, action: "append", next: `${joined}${region}`, reason: "appended a managed region at the end; every existing line is kept" };
|
|
26067
26170
|
}
|
|
26068
26171
|
case "stale":
|
|
26069
26172
|
case "edited": {
|
|
26070
|
-
if (report2.state === "edited" && !force) return { ...
|
|
26173
|
+
if (report2.state === "edited" && !force) return { ...base5, action: "refuse", next: null, reason: report2.detail };
|
|
26071
26174
|
const scan = scanRegion(fileText);
|
|
26072
|
-
if (scan.kind !== "one") return { ...
|
|
26175
|
+
if (scan.kind !== "one") return { ...base5, action: "refuse", next: null, reason: report2.detail };
|
|
26073
26176
|
const lines = normaliseText(fileText).split("\n");
|
|
26074
26177
|
const before = lines.slice(0, scan.region.startLine).join("\n");
|
|
26075
26178
|
const after = lines.slice(scan.region.endLine + 1).join("\n");
|
|
@@ -26079,7 +26182,7 @@ function planRegionSync(target2, fileText, source, force) {
|
|
|
26079
26182
|
const written = new Set(regionBody(source.text).split("\n"));
|
|
26080
26183
|
const going = replaced.filter((l) => l.trim() !== "" && !written.has(l));
|
|
26081
26184
|
return {
|
|
26082
|
-
...
|
|
26185
|
+
...base5,
|
|
26083
26186
|
action: report2.state === "edited" ? "force_replace" : "replace",
|
|
26084
26187
|
next: next.endsWith("\n") ? next : `${next}
|
|
26085
26188
|
`,
|
|
@@ -26088,7 +26191,7 @@ function planRegionSync(target2, fileText, source, force) {
|
|
|
26088
26191
|
};
|
|
26089
26192
|
}
|
|
26090
26193
|
case "damaged":
|
|
26091
|
-
return { ...
|
|
26194
|
+
return { ...base5, action: "refuse", next: null, reason: report2.detail };
|
|
26092
26195
|
}
|
|
26093
26196
|
}
|
|
26094
26197
|
function parseSettings(text) {
|
|
@@ -26110,23 +26213,23 @@ function contextFileNames(settings) {
|
|
|
26110
26213
|
return { names: [], shape: fileName === void 0 ? "none" : "other" };
|
|
26111
26214
|
}
|
|
26112
26215
|
function inspectGeminiSettings(target2, fileText) {
|
|
26113
|
-
const
|
|
26114
|
-
if (fileText === null) return { ...
|
|
26216
|
+
const base5 = { id: target2.id, path: target2.path };
|
|
26217
|
+
if (fileText === null) return { ...base5, state: "missing", detail: `${target2.path} does not exist; sync creates it`, syncable: true };
|
|
26115
26218
|
const parsed = parseSettings(fileText);
|
|
26116
|
-
if (!parsed.ok) return { ...
|
|
26219
|
+
if (!parsed.ok) return { ...base5, state: "damaged", detail: `${target2.path} ${parsed.problem}; fix it by hand, then run sync`, syncable: false };
|
|
26117
26220
|
const { names, shape: shape2 } = contextFileNames(parsed.value);
|
|
26118
|
-
if (shape2 === "other") return { ...
|
|
26221
|
+
if (shape2 === "other") return { ...base5, state: "damaged", detail: `${target2.path}: context.fileName is neither a string nor a list of strings; fix it by hand, then run sync`, syncable: false };
|
|
26119
26222
|
const missing = GEMINI_CONTEXT_FILES.filter((name2) => !names.includes(name2));
|
|
26120
|
-
if (missing.length === 0) return { ...
|
|
26121
|
-
return { ...
|
|
26223
|
+
if (missing.length === 0) return { ...base5, state: "in_sync", detail: `${target2.path} lists ${GEMINI_CONTEXT_FILES.join(" and ")}`, syncable: true };
|
|
26224
|
+
return { ...base5, state: "unmanaged", detail: `${target2.path}: context.fileName does not list ${missing.join(" and ")}; sync adds it and keeps every other setting`, syncable: true };
|
|
26122
26225
|
}
|
|
26123
26226
|
function planGeminiSettingsSync(target2, fileText) {
|
|
26124
26227
|
const report2 = inspectGeminiSettings(target2, fileText);
|
|
26125
|
-
const
|
|
26126
|
-
if (report2.state === "in_sync") return { ...
|
|
26127
|
-
if (report2.state === "damaged") return { ...
|
|
26228
|
+
const base5 = { id: target2.id, path: target2.path };
|
|
26229
|
+
if (report2.state === "in_sync") return { ...base5, action: "none", next: null, reason: report2.detail };
|
|
26230
|
+
if (report2.state === "damaged") return { ...base5, action: "refuse", next: null, reason: report2.detail };
|
|
26128
26231
|
const parsed = parseSettings(fileText);
|
|
26129
|
-
if (!parsed.ok) return { ...
|
|
26232
|
+
if (!parsed.ok) return { ...base5, action: "refuse", next: null, reason: report2.detail };
|
|
26130
26233
|
const settings = { ...parsed.value };
|
|
26131
26234
|
const existing = contextFileNames(settings).names;
|
|
26132
26235
|
const context4 = settings["context"] !== null && typeof settings["context"] === "object" && !Array.isArray(settings["context"]) ? { ...settings["context"] } : {};
|
|
@@ -26134,7 +26237,7 @@ function planGeminiSettingsSync(target2, fileText) {
|
|
|
26134
26237
|
for (const name2 of GEMINI_CONTEXT_FILES) if (!names.includes(name2)) names.push(name2);
|
|
26135
26238
|
context4["fileName"] = names;
|
|
26136
26239
|
settings["context"] = context4;
|
|
26137
|
-
return { ...
|
|
26240
|
+
return { ...base5, action: fileText === null ? "create" : "append", next: `${JSON.stringify(settings, null, 2)}
|
|
26138
26241
|
`, reason: fileText === null ? "created" : "added the missing names to context.fileName; nothing else changed" };
|
|
26139
26242
|
}
|
|
26140
26243
|
function checkRules(source, input2) {
|
|
@@ -26523,6 +26626,281 @@ var init_egress = __esm({
|
|
|
26523
26626
|
}
|
|
26524
26627
|
});
|
|
26525
26628
|
|
|
26629
|
+
// ../contracts/src/enterprise.ts
|
|
26630
|
+
function parseCsv(text) {
|
|
26631
|
+
const rows = [];
|
|
26632
|
+
let row = [];
|
|
26633
|
+
let cell = "";
|
|
26634
|
+
let quoted = false;
|
|
26635
|
+
for (let i2 = 0; i2 < text.length; i2 += 1) {
|
|
26636
|
+
const ch = text[i2];
|
|
26637
|
+
if (quoted) {
|
|
26638
|
+
if (ch === '"' && text[i2 + 1] === '"') {
|
|
26639
|
+
cell += '"';
|
|
26640
|
+
i2 += 1;
|
|
26641
|
+
} else if (ch === '"') quoted = false;
|
|
26642
|
+
else cell += ch;
|
|
26643
|
+
} else if (ch === '"') quoted = true;
|
|
26644
|
+
else if (ch === ",") {
|
|
26645
|
+
row.push(cell);
|
|
26646
|
+
cell = "";
|
|
26647
|
+
} else if (ch === "\n" || ch === "\r") {
|
|
26648
|
+
if (ch === "\r" && text[i2 + 1] === "\n") i2 += 1;
|
|
26649
|
+
row.push(cell);
|
|
26650
|
+
rows.push(row);
|
|
26651
|
+
row = [];
|
|
26652
|
+
cell = "";
|
|
26653
|
+
} else cell += ch;
|
|
26654
|
+
}
|
|
26655
|
+
if (cell !== "" || row.length > 0) {
|
|
26656
|
+
row.push(cell);
|
|
26657
|
+
rows.push(row);
|
|
26658
|
+
}
|
|
26659
|
+
return rows;
|
|
26660
|
+
}
|
|
26661
|
+
function parseAuditCsv(csv) {
|
|
26662
|
+
const rows = parseCsv(csv);
|
|
26663
|
+
const header = rows[0] ?? [];
|
|
26664
|
+
if (header.join(",") !== AUDIT_CSV_COLUMNS.join(",")) throw new Error("unexpected header");
|
|
26665
|
+
return rows.slice(1).map((cells) => {
|
|
26666
|
+
if (cells.length !== AUDIT_CSV_COLUMNS.length) throw new Error("wrong column count");
|
|
26667
|
+
const value = (name2) => {
|
|
26668
|
+
const raw = cells[AUDIT_CSV_COLUMNS.indexOf(name2)] ?? "";
|
|
26669
|
+
return /^'[=+\-@\t\r]/.test(raw) ? raw.slice(1) : raw;
|
|
26670
|
+
};
|
|
26671
|
+
return AuditEvent.parse({
|
|
26672
|
+
tenantId: value("tenantId"),
|
|
26673
|
+
seq: Number(value("seq")),
|
|
26674
|
+
eventId: value("eventId"),
|
|
26675
|
+
at: value("at"),
|
|
26676
|
+
actor: value("actor"),
|
|
26677
|
+
principalType: value("principalType"),
|
|
26678
|
+
role: value("role") === "" ? null : value("role"),
|
|
26679
|
+
action: value("action"),
|
|
26680
|
+
category: value("category"),
|
|
26681
|
+
target: { type: value("targetType"), id: value("targetId") },
|
|
26682
|
+
result: value("result"),
|
|
26683
|
+
prevHash: value("prevHash"),
|
|
26684
|
+
hash: value("hash")
|
|
26685
|
+
});
|
|
26686
|
+
});
|
|
26687
|
+
}
|
|
26688
|
+
function verifyAuditExport(tenantId, csv, manifest) {
|
|
26689
|
+
let events;
|
|
26690
|
+
try {
|
|
26691
|
+
events = parseAuditCsv(csv);
|
|
26692
|
+
} catch {
|
|
26693
|
+
return { tenantId, ok: false, checked: 0, head: null, reason: "bad_hash", manifestOk: false };
|
|
26694
|
+
}
|
|
26695
|
+
const chain = verifyAuditChain(tenantId, events, { prevHash: manifest.firstSeq === null || manifest.firstSeq === 1 ? AUDIT_GENESIS_HASH : events[0]?.prevHash ?? AUDIT_GENESIS_HASH, seq: (manifest.firstSeq ?? 1) - 1 });
|
|
26696
|
+
const manifestOk = manifest.tenantId === tenantId && manifest.count === events.length && manifest.lastSeq === (events.at(-1)?.seq ?? null) && manifest.head === (events.at(-1)?.hash ?? null) && manifest.firstSeq === (events[0]?.seq ?? null);
|
|
26697
|
+
return { ...chain, ok: chain.ok && manifestOk, manifestOk };
|
|
26698
|
+
}
|
|
26699
|
+
var ENTERPRISE_FEATURES, EnterpriseFeature, EnterpriseEntitlements, roleName, shortId, SSO_PROTOCOLS, SsoProtocol, IDENTITY_CONNECTION_STATUSES, ConnectionStatus, SsoConnection, ScimDirectory, PORTAL_INTENTS, PortalIntent, PortalLinkRequest, PortalLink, TestConnectionResult, EnterpriseIdentityStatus, GroupRoleMapping, GROUP_ROLE_CAPS, GroupRoleCap, GroupMappingSet, PutGroupMappingsRequest, DirectorySyncReport, AUDIT_CSV_COLUMNS, AuditExportManifest, AuditExport, STREAM_STATUSES, AuditStreamTarget, CreateAuditStreamTargetRequest, AuditStreamTargetList, AuditStreamDelivery, StreamRunReport, REGIONS, Region, STORE_KINDS, StoreKind, StoreLocation, ResidencyPolicy, PinRegionRequest, RegionMigrationRequest, StoreLocationReport, BYOK_PROVIDERS, ByokProvider, BYOK_STATUSES, ByokStatus, ByokAlias, ByokKey, ByokKeyList, CreateByokKeyRequest, RotateByokKeyRequest, ByokTestResult, RETENTION_CLASSES, RetentionClass, RetentionRule, EnterpriseRetentionPolicy, PutRetentionPolicyRequest, PurgeLine, PurgeReport, PurgeReportList, ExportScope, DataRequest, DataExportReport, DataDeletionReport, RestoreDrillReport, EnterpriseMcpAllowlistEntry, McpAllowlist, PutMcpAllowlistRequest, EvidencePack, base4, enterprisePaths, FIXTURE_AT2, ENTERPRISE_FIXTURES;
|
|
26700
|
+
var init_enterprise = __esm({
|
|
26701
|
+
"../contracts/src/enterprise.ts"() {
|
|
26702
|
+
"use strict";
|
|
26703
|
+
init_zod();
|
|
26704
|
+
init_audit();
|
|
26705
|
+
init_common();
|
|
26706
|
+
init_plans();
|
|
26707
|
+
ENTERPRISE_FEATURES = ["sso", "scim", "audit_export", "siem_stream", "data_residency", "byok", "retention", "policy_as_code", "mcp_allowlist"];
|
|
26708
|
+
EnterpriseFeature = external_exports.enum(ENTERPRISE_FEATURES);
|
|
26709
|
+
EnterpriseEntitlements = external_exports.object({ tenantId: TenantId, plan: BillingPlanId, features: external_exports.record(EnterpriseFeature, external_exports.boolean()) }).strict();
|
|
26710
|
+
roleName = external_exports.enum(["owner", "admin", "member", "viewer"]);
|
|
26711
|
+
shortId = external_exports.string().min(1).max(64);
|
|
26712
|
+
SSO_PROTOCOLS = ["saml", "oidc"];
|
|
26713
|
+
SsoProtocol = external_exports.enum(SSO_PROTOCOLS);
|
|
26714
|
+
IDENTITY_CONNECTION_STATUSES = ["not_configured", "pending", "active", "failed", "disabled"];
|
|
26715
|
+
ConnectionStatus = external_exports.enum(IDENTITY_CONNECTION_STATUSES);
|
|
26716
|
+
SsoConnection = external_exports.object({
|
|
26717
|
+
tenantId: TenantId,
|
|
26718
|
+
connectionId: shortId.nullable(),
|
|
26719
|
+
protocol: SsoProtocol.nullable(),
|
|
26720
|
+
status: ConnectionStatus,
|
|
26721
|
+
domains: external_exports.array(external_exports.string().min(1).max(253)).max(20),
|
|
26722
|
+
lastTestedAt: Timestamp.nullable(),
|
|
26723
|
+
lastTestOk: external_exports.boolean().nullable()
|
|
26724
|
+
}).strict();
|
|
26725
|
+
ScimDirectory = external_exports.object({
|
|
26726
|
+
tenantId: TenantId,
|
|
26727
|
+
directoryId: shortId.nullable(),
|
|
26728
|
+
status: ConnectionStatus,
|
|
26729
|
+
userCount: external_exports.number().int().nonnegative(),
|
|
26730
|
+
groupCount: external_exports.number().int().nonnegative(),
|
|
26731
|
+
lastSyncAt: Timestamp.nullable()
|
|
26732
|
+
}).strict();
|
|
26733
|
+
PORTAL_INTENTS = ["sso", "dsync"];
|
|
26734
|
+
PortalIntent = external_exports.enum(PORTAL_INTENTS);
|
|
26735
|
+
PortalLinkRequest = external_exports.object({ intent: PortalIntent }).strict();
|
|
26736
|
+
PortalLink = external_exports.object({ tenantId: TenantId, intent: PortalIntent, url: external_exports.string().url(), expiresAt: Timestamp }).strict();
|
|
26737
|
+
TestConnectionResult = external_exports.object({ tenantId: TenantId, intent: PortalIntent, ok: external_exports.boolean(), checkedAt: Timestamp, detail: external_exports.string().max(300) }).strict();
|
|
26738
|
+
EnterpriseIdentityStatus = external_exports.object({ tenantId: TenantId, sso: SsoConnection, scim: ScimDirectory }).strict();
|
|
26739
|
+
GroupRoleMapping = external_exports.object({ tenantId: TenantId, groupName: external_exports.string().min(1).max(200), role: roleName }).strict();
|
|
26740
|
+
GROUP_ROLE_CAPS = ["admin", "member", "viewer"];
|
|
26741
|
+
GroupRoleCap = external_exports.enum(GROUP_ROLE_CAPS);
|
|
26742
|
+
GroupMappingSet = external_exports.object({ tenantId: TenantId, cap: GroupRoleCap, mappings: external_exports.array(GroupRoleMapping).max(200), updatedAt: Timestamp.nullable() }).strict();
|
|
26743
|
+
PutGroupMappingsRequest = external_exports.object({ cap: GroupRoleCap.default("admin"), mappings: external_exports.array(external_exports.object({ groupName: external_exports.string().min(1).max(200), role: roleName }).strict()).max(200) }).strict();
|
|
26744
|
+
DirectorySyncReport = external_exports.object({
|
|
26745
|
+
tenantId: TenantId,
|
|
26746
|
+
syncedAt: Timestamp,
|
|
26747
|
+
rolesChanged: external_exports.number().int().nonnegative(),
|
|
26748
|
+
deprovisioned: external_exports.number().int().nonnegative(),
|
|
26749
|
+
/** Seconds from the directory marking a user inactive to this sync applying it, per deprovisioned user. */
|
|
26750
|
+
deprovisionLatencySeconds: external_exports.array(external_exports.number().nonnegative()),
|
|
26751
|
+
withinDeadline: external_exports.boolean()
|
|
26752
|
+
}).strict();
|
|
26753
|
+
AUDIT_CSV_COLUMNS = ["tenantId", "seq", "eventId", "at", "actor", "principalType", "role", "action", "category", "targetType", "targetId", "result", "prevHash", "hash"];
|
|
26754
|
+
AuditExportManifest = external_exports.object({
|
|
26755
|
+
tenantId: TenantId,
|
|
26756
|
+
exportId: shortId,
|
|
26757
|
+
format: external_exports.literal("csv"),
|
|
26758
|
+
count: external_exports.number().int().nonnegative(),
|
|
26759
|
+
firstSeq: external_exports.number().int().positive().nullable(),
|
|
26760
|
+
lastSeq: external_exports.number().int().positive().nullable(),
|
|
26761
|
+
head: external_exports.string().regex(/^[0-9a-f]{64}$/).nullable(),
|
|
26762
|
+
exportedAt: Timestamp
|
|
26763
|
+
}).strict();
|
|
26764
|
+
AuditExport = external_exports.object({ manifest: AuditExportManifest, csv: external_exports.string() }).strict();
|
|
26765
|
+
STREAM_STATUSES = ["active", "paused", "failing"];
|
|
26766
|
+
AuditStreamTarget = external_exports.object({
|
|
26767
|
+
tenantId: TenantId,
|
|
26768
|
+
targetId: shortId,
|
|
26769
|
+
/** Where deliveries go. https only. */
|
|
26770
|
+
url: external_exports.string().url().refine((u) => u.startsWith("https://"), "must be https"),
|
|
26771
|
+
status: external_exports.enum(STREAM_STATUSES),
|
|
26772
|
+
/** The newest chain sequence the target has acknowledged. */
|
|
26773
|
+
deliveredThroughSeq: external_exports.number().int().nonnegative(),
|
|
26774
|
+
lastError: external_exports.string().max(200).nullable(),
|
|
26775
|
+
createdAt: Timestamp
|
|
26776
|
+
}).strict();
|
|
26777
|
+
CreateAuditStreamTargetRequest = external_exports.object({ url: external_exports.string().url().refine((u) => u.startsWith("https://"), "must be https"), signingSecret: external_exports.string().min(16).max(200) }).strict();
|
|
26778
|
+
AuditStreamTargetList = external_exports.object({ tenantId: TenantId, targets: external_exports.array(AuditStreamTarget) }).strict();
|
|
26779
|
+
AuditStreamDelivery = external_exports.object({
|
|
26780
|
+
tenantId: TenantId,
|
|
26781
|
+
targetId: shortId,
|
|
26782
|
+
idempotencyKey: external_exports.string().min(1).max(200),
|
|
26783
|
+
batchSeq: external_exports.number().int().positive(),
|
|
26784
|
+
events: external_exports.array(AuditEvent).min(1).max(500)
|
|
26785
|
+
}).strict();
|
|
26786
|
+
StreamRunReport = external_exports.object({ tenantId: TenantId, targetId: shortId, delivered: external_exports.number().int().nonnegative(), batches: external_exports.number().int().nonnegative(), failed: external_exports.boolean(), deliveredThroughSeq: external_exports.number().int().nonnegative() }).strict();
|
|
26787
|
+
REGIONS = ["global", "eu", "us"];
|
|
26788
|
+
Region = external_exports.enum(REGIONS);
|
|
26789
|
+
STORE_KINDS = ["d1", "r2", "kv", "durable_objects", "vectors", "logs", "backups"];
|
|
26790
|
+
StoreKind = external_exports.enum(STORE_KINDS);
|
|
26791
|
+
StoreLocation = external_exports.object({ store: StoreKind, region: Region, detail: external_exports.string().max(200) }).strict();
|
|
26792
|
+
ResidencyPolicy = external_exports.object({
|
|
26793
|
+
tenantId: TenantId,
|
|
26794
|
+
region: Region,
|
|
26795
|
+
pinnedAt: Timestamp.nullable(),
|
|
26796
|
+
/** Supported pin targets, so a refusal and the settings screen show the same list. */
|
|
26797
|
+
supportedRegions: external_exports.array(Region),
|
|
26798
|
+
pendingMigration: external_exports.object({ from: Region, to: Region, requestedAt: Timestamp, requestedBy: external_exports.string().min(1).max(200), status: external_exports.enum(["requested", "running", "done", "failed"]) }).strict().nullable()
|
|
26799
|
+
}).strict();
|
|
26800
|
+
PinRegionRequest = external_exports.object({ region: Region }).strict();
|
|
26801
|
+
RegionMigrationRequest = external_exports.object({ to: Region, reason: external_exports.string().min(1).max(300) }).strict();
|
|
26802
|
+
StoreLocationReport = external_exports.object({ tenantId: TenantId, region: Region, checkedAt: Timestamp, stores: external_exports.array(StoreLocation), ok: external_exports.boolean(), violations: external_exports.array(external_exports.string().max(200)) }).strict();
|
|
26803
|
+
BYOK_PROVIDERS = ["anthropic", "openai", "google"];
|
|
26804
|
+
ByokProvider = external_exports.enum(BYOK_PROVIDERS);
|
|
26805
|
+
BYOK_STATUSES = ["untested", "active", "failed", "revoked"];
|
|
26806
|
+
ByokStatus = external_exports.enum(BYOK_STATUSES);
|
|
26807
|
+
ByokAlias = external_exports.string().min(1).max(60).regex(/^[a-z0-9][a-z0-9-]*$/, "lowercase letters, digits and hyphens");
|
|
26808
|
+
ByokKey = external_exports.object({
|
|
26809
|
+
tenantId: TenantId,
|
|
26810
|
+
alias: ByokAlias,
|
|
26811
|
+
provider: ByokProvider,
|
|
26812
|
+
status: ByokStatus,
|
|
26813
|
+
/** Increments on each rotation. */
|
|
26814
|
+
version: external_exports.number().int().positive(),
|
|
26815
|
+
/** No fingerprint and no last characters are kept: the alias is the only reference. */
|
|
26816
|
+
lastTestedAt: Timestamp.nullable(),
|
|
26817
|
+
createdAt: Timestamp,
|
|
26818
|
+
revokedAt: Timestamp.nullable()
|
|
26819
|
+
}).strict();
|
|
26820
|
+
ByokKeyList = external_exports.object({ tenantId: TenantId, keys: external_exports.array(ByokKey) }).strict();
|
|
26821
|
+
CreateByokKeyRequest = external_exports.object({ alias: ByokAlias, provider: ByokProvider, value: external_exports.string().min(8).max(500) }).strict();
|
|
26822
|
+
RotateByokKeyRequest = external_exports.object({ value: external_exports.string().min(8).max(500) }).strict();
|
|
26823
|
+
ByokTestResult = external_exports.object({ tenantId: TenantId, alias: ByokAlias, ok: external_exports.boolean(), checkedAt: Timestamp, detail: external_exports.string().max(200) }).strict();
|
|
26824
|
+
RETENTION_CLASSES = ["memory", "derived_data", "agent_conversations", "ci_artifacts", "run_logs"];
|
|
26825
|
+
RetentionClass = external_exports.enum(RETENTION_CLASSES);
|
|
26826
|
+
RetentionRule = external_exports.object({ dataClass: RetentionClass, days: external_exports.number().int().min(1).max(3650) }).strict();
|
|
26827
|
+
EnterpriseRetentionPolicy = external_exports.object({ tenantId: TenantId, rules: external_exports.array(RetentionRule).max(RETENTION_CLASSES.length), updatedAt: Timestamp.nullable() }).strict();
|
|
26828
|
+
PutRetentionPolicyRequest = external_exports.object({ rules: external_exports.array(RetentionRule).max(RETENTION_CLASSES.length) }).strict();
|
|
26829
|
+
PurgeLine = external_exports.object({ dataClass: RetentionClass, store: StoreKind, cutoff: Timestamp, purged: external_exports.number().int().nonnegative() }).strict();
|
|
26830
|
+
PurgeReport = external_exports.object({ tenantId: TenantId, purgeId: shortId, ranAt: Timestamp, trigger: external_exports.enum(["schedule", "manual"]), lines: external_exports.array(PurgeLine), totalPurged: external_exports.number().int().nonnegative() }).strict();
|
|
26831
|
+
PurgeReportList = external_exports.object({ tenantId: TenantId, reports: external_exports.array(PurgeReport) }).strict();
|
|
26832
|
+
ExportScope = external_exports.enum(["tenant", "project", "user"]);
|
|
26833
|
+
DataRequest = external_exports.object({ scope: ExportScope, subjectId: external_exports.string().min(1).max(128).optional() }).strict();
|
|
26834
|
+
DataExportReport = external_exports.object({ tenantId: TenantId, scope: ExportScope, exportedAt: Timestamp, stores: external_exports.array(external_exports.object({ store: StoreKind, dataClass: external_exports.string().max(60), rows: external_exports.number().int().nonnegative() }).strict()), totalRows: external_exports.number().int().nonnegative(), ndjson: external_exports.string() }).strict();
|
|
26835
|
+
DataDeletionReport = external_exports.object({
|
|
26836
|
+
tenantId: TenantId,
|
|
26837
|
+
scope: ExportScope,
|
|
26838
|
+
deletedAt: Timestamp,
|
|
26839
|
+
stores: external_exports.array(external_exports.object({ store: StoreKind, dataClass: external_exports.string().max(60), rows: external_exports.number().int().nonnegative() }).strict()),
|
|
26840
|
+
totalRows: external_exports.number().int().nonnegative(),
|
|
26841
|
+
backupsPurgedBy: Timestamp
|
|
26842
|
+
}).strict();
|
|
26843
|
+
RestoreDrillReport = external_exports.object({
|
|
26844
|
+
tenantId: TenantId,
|
|
26845
|
+
drillId: shortId,
|
|
26846
|
+
ranAt: Timestamp,
|
|
26847
|
+
restoredFrom: Timestamp,
|
|
26848
|
+
tables: external_exports.array(external_exports.object({ name: external_exports.string().min(1).max(80), expected: external_exports.number().int().nonnegative(), restored: external_exports.number().int().nonnegative() }).strict()),
|
|
26849
|
+
ok: external_exports.boolean(),
|
|
26850
|
+
durationMs: external_exports.number().int().nonnegative()
|
|
26851
|
+
}).strict();
|
|
26852
|
+
EnterpriseMcpAllowlistEntry = external_exports.object({ server: external_exports.string().min(1).max(253), note: external_exports.string().max(200).optional() }).strict();
|
|
26853
|
+
McpAllowlist = external_exports.object({ tenantId: TenantId, mode: external_exports.enum(["off", "allowlist"]), entries: external_exports.array(EnterpriseMcpAllowlistEntry).max(200), updatedAt: Timestamp.nullable() }).strict();
|
|
26854
|
+
PutMcpAllowlistRequest = external_exports.object({ mode: external_exports.enum(["off", "allowlist"]), entries: external_exports.array(EnterpriseMcpAllowlistEntry).max(200) }).strict();
|
|
26855
|
+
EvidencePack = external_exports.object({
|
|
26856
|
+
tenantId: TenantId,
|
|
26857
|
+
generatedAt: Timestamp,
|
|
26858
|
+
chain: external_exports.object({ ok: external_exports.boolean(), checked: external_exports.number().int().nonnegative(), head: external_exports.string().nullable() }).strict(),
|
|
26859
|
+
agentActions: external_exports.object({ total: external_exports.number().int().nonnegative(), byAction: external_exports.record(external_exports.string(), external_exports.number().int().nonnegative()), denied: external_exports.number().int().nonnegative() }).strict(),
|
|
26860
|
+
controls: external_exports.array(external_exports.object({ id: external_exports.string().max(40), title: external_exports.string().max(120), state: external_exports.enum(["enabled", "not_configured"]), evidence: external_exports.string().max(200) }).strict())
|
|
26861
|
+
}).strict();
|
|
26862
|
+
base4 = (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/enterprise`;
|
|
26863
|
+
enterprisePaths = {
|
|
26864
|
+
entitlements: (t2) => `${base4(t2)}/entitlements`,
|
|
26865
|
+
identity: (t2) => `${base4(t2)}/identity`,
|
|
26866
|
+
portalLink: (t2) => `${base4(t2)}/identity/portal-link`,
|
|
26867
|
+
testConnection: (t2) => `${base4(t2)}/identity/test`,
|
|
26868
|
+
syncDirectory: (t2) => `${base4(t2)}/identity/sync`,
|
|
26869
|
+
groupMappings: (t2) => `${base4(t2)}/identity/group-mappings`,
|
|
26870
|
+
auditExports: (t2) => `${base4(t2)}/audit-exports`,
|
|
26871
|
+
streamTargets: (t2) => `${base4(t2)}/audit-streams`,
|
|
26872
|
+
streamTarget: (t2, id2) => `${base4(t2)}/audit-streams/${encodeURIComponent(id2)}`,
|
|
26873
|
+
streamRun: (t2, id2) => `${base4(t2)}/audit-streams/${encodeURIComponent(id2)}/run`,
|
|
26874
|
+
residency: (t2) => `${base4(t2)}/residency`,
|
|
26875
|
+
residencyMigrations: (t2) => `${base4(t2)}/residency/migrations`,
|
|
26876
|
+
storeLocations: (t2) => `${base4(t2)}/residency/stores`,
|
|
26877
|
+
byokKeys: (t2) => `${base4(t2)}/byok/keys`,
|
|
26878
|
+
byokKey: (t2, alias) => `${base4(t2)}/byok/keys/${encodeURIComponent(alias)}`,
|
|
26879
|
+
byokTest: (t2, alias) => `${base4(t2)}/byok/keys/${encodeURIComponent(alias)}/test`,
|
|
26880
|
+
byokRotate: (t2, alias) => `${base4(t2)}/byok/keys/${encodeURIComponent(alias)}/rotate`,
|
|
26881
|
+
retention: (t2) => `${base4(t2)}/retention`,
|
|
26882
|
+
purge: (t2) => `${base4(t2)}/retention/purge`,
|
|
26883
|
+
purgeReports: (t2) => `${base4(t2)}/retention/reports`,
|
|
26884
|
+
dataExport: (t2) => `${base4(t2)}/data/export`,
|
|
26885
|
+
dataDelete: (t2) => `${base4(t2)}/data/delete`,
|
|
26886
|
+
restoreDrill: (t2) => `${base4(t2)}/backups/drill`,
|
|
26887
|
+
mcpAllowlist: (t2) => `${base4(t2)}/mcp-allowlist`,
|
|
26888
|
+
evidencePack: (t2) => `${base4(t2)}/evidence-pack`
|
|
26889
|
+
};
|
|
26890
|
+
FIXTURE_AT2 = "2026-10-10T00:00:00.000Z";
|
|
26891
|
+
ENTERPRISE_FIXTURES = {
|
|
26892
|
+
sso: SsoConnection.parse({ tenantId: "tm-1", connectionId: "conn_1", protocol: "saml", status: "active", domains: ["example.com"], lastTestedAt: FIXTURE_AT2, lastTestOk: true }),
|
|
26893
|
+
scim: ScimDirectory.parse({ tenantId: "tm-1", directoryId: "dir_1", status: "active", userCount: 12, groupCount: 3, lastSyncAt: FIXTURE_AT2 }),
|
|
26894
|
+
groupMappings: GroupMappingSet.parse({ tenantId: "tm-1", cap: "admin", mappings: [{ tenantId: "tm-1", groupName: "Engineering", role: "member" }, { tenantId: "tm-1", groupName: "Platform", role: "admin" }], updatedAt: FIXTURE_AT2 }),
|
|
26895
|
+
residency: ResidencyPolicy.parse({ tenantId: "tm-1", region: "eu", pinnedAt: FIXTURE_AT2, supportedRegions: ["global", "eu", "us"], pendingMigration: null }),
|
|
26896
|
+
byok: ByokKey.parse({ tenantId: "tm-1", alias: "team-anthropic", provider: "anthropic", status: "active", version: 1, lastTestedAt: FIXTURE_AT2, createdAt: FIXTURE_AT2, revokedAt: null }),
|
|
26897
|
+
retention: EnterpriseRetentionPolicy.parse({ tenantId: "tm-1", rules: [{ dataClass: "run_logs", days: 90 }], updatedAt: FIXTURE_AT2 }),
|
|
26898
|
+
streamTarget: AuditStreamTarget.parse({ tenantId: "tm-1", targetId: "tgt_1", url: "https://siem.example.com/ingest", status: "active", deliveredThroughSeq: 3, lastError: null, createdAt: FIXTURE_AT2 }),
|
|
26899
|
+
mcpAllowlist: McpAllowlist.parse({ tenantId: "tm-1", mode: "allowlist", entries: [{ server: "mcp.example.com" }], updatedAt: FIXTURE_AT2 })
|
|
26900
|
+
};
|
|
26901
|
+
}
|
|
26902
|
+
});
|
|
26903
|
+
|
|
26526
26904
|
// ../contracts/src/observability.ts
|
|
26527
26905
|
var RUN_EVENT_TYPES, RunEventType, OBS_RUN_STATUSES, ObsRunStatus, REVIEW_OUTCOMES, ReviewOutcome, Name2, Level, RunEventFields, RunEvent, RunEventInput, IngestRunEventsRequest, RunResume, LogRecord, LogInput, Span, SpanInput, IngestTelemetryRequest, IngestTelemetryResult, LogRecordList, ObsRun, TraceBundle, METRIC_KINDS, MetricKind, METRIC_DIMENSIONS, MetricDimension, MetricDimensions, MetricInput, Metric, IngestMetricsRequest, IngestMetricsResult, MetricTotal, MetricTotals, CostRowV1, CostSummaryV1, CostReport, ReconcileLine, Reconciliation, ALERT_KINDS, AlertKind, ALERT_CHANNELS, AlertChannel, AlertTarget, AlertThreshold, AlertRule, PutAlertRuleRequest, DeleteAlertRuleRequest, AlertDelivery, Incident, AlertOverview, EvaluateAlertsResult, AlertNotice, RETENTION_COVERS, RETENTION_KEEPS, RetentionPolicy, RetentionPurgeResult, ComparisonEntry, ComparisonReport, ReplayResult, EvalRow, EvalReport, RunEvalRequest, DecisionSummary, ObserveStatus, t, p, observePaths;
|
|
26528
26906
|
var init_observability = __esm({
|
|
@@ -26825,6 +27203,7 @@ var init_src = __esm({
|
|
|
26825
27203
|
init_rules_sync();
|
|
26826
27204
|
init_pr_routing();
|
|
26827
27205
|
init_egress();
|
|
27206
|
+
init_enterprise();
|
|
26828
27207
|
init_observability();
|
|
26829
27208
|
}
|
|
26830
27209
|
});
|
|
@@ -34160,12 +34539,12 @@ var require_dist = __commonJS({
|
|
|
34160
34539
|
});
|
|
34161
34540
|
|
|
34162
34541
|
// src/assets.ts
|
|
34163
|
-
import { basename as basename5, join as join25, resolve as
|
|
34542
|
+
import { basename as basename5, join as join25, resolve as resolve14 } from "node:path";
|
|
34164
34543
|
import { fileURLToPath } from "node:url";
|
|
34165
34544
|
function packageRoot(env = process.env) {
|
|
34166
34545
|
const override = env["MVRX_PACKAGE_ROOT"];
|
|
34167
34546
|
if (override !== void 0 && override !== "") return override;
|
|
34168
|
-
return
|
|
34547
|
+
return resolve14(fileURLToPath(new URL(".", import.meta.url)), "..");
|
|
34169
34548
|
}
|
|
34170
34549
|
function assetDir(env = process.env) {
|
|
34171
34550
|
const override = env["MVRX_ASSET_DIR"];
|
|
@@ -34178,7 +34557,7 @@ var VERSION;
|
|
|
34178
34557
|
var init_assets = __esm({
|
|
34179
34558
|
"src/assets.ts"() {
|
|
34180
34559
|
"use strict";
|
|
34181
|
-
VERSION = true ? "0.1.
|
|
34560
|
+
VERSION = true ? "0.1.139" : "0.0.0-dev";
|
|
34182
34561
|
}
|
|
34183
34562
|
});
|
|
34184
34563
|
|
|
@@ -34273,13 +34652,13 @@ function int64FromString(dec) {
|
|
|
34273
34652
|
if (minus) {
|
|
34274
34653
|
dec = dec.slice(1);
|
|
34275
34654
|
}
|
|
34276
|
-
const
|
|
34655
|
+
const base5 = 1e6;
|
|
34277
34656
|
let lowBits = 0;
|
|
34278
34657
|
let highBits = 0;
|
|
34279
34658
|
function add1e6digit(begin, end) {
|
|
34280
34659
|
const digit1e6 = Number(dec.slice(begin, end));
|
|
34281
|
-
highBits *=
|
|
34282
|
-
lowBits = lowBits *
|
|
34660
|
+
highBits *= base5;
|
|
34661
|
+
lowBits = lowBits * base5 + digit1e6;
|
|
34283
34662
|
if (lowBits >= TWO_PWR_32_DBL) {
|
|
34284
34663
|
highBits = highBits + (lowBits / TWO_PWR_32_DBL | 0);
|
|
34285
34664
|
lowBits = lowBits % TWO_PWR_32_DBL;
|
|
@@ -34311,14 +34690,14 @@ function uInt64ToString(lo, hi) {
|
|
|
34311
34690
|
let digitA = low + mid * 6777216 + high * 6710656;
|
|
34312
34691
|
let digitB = mid + high * 8147497;
|
|
34313
34692
|
let digitC = high * 2;
|
|
34314
|
-
const
|
|
34315
|
-
if (digitA >=
|
|
34316
|
-
digitB += Math.floor(digitA /
|
|
34317
|
-
digitA %=
|
|
34693
|
+
const base5 = 1e7;
|
|
34694
|
+
if (digitA >= base5) {
|
|
34695
|
+
digitB += Math.floor(digitA / base5);
|
|
34696
|
+
digitA %= base5;
|
|
34318
34697
|
}
|
|
34319
|
-
if (digitB >=
|
|
34320
|
-
digitC += Math.floor(digitB /
|
|
34321
|
-
digitB %=
|
|
34698
|
+
if (digitB >= base5) {
|
|
34699
|
+
digitC += Math.floor(digitB / base5);
|
|
34700
|
+
digitB %= base5;
|
|
34322
34701
|
}
|
|
34323
34702
|
return digitC.toString() + decimalFrom1e7WithLeadingZeros(digitB) + decimalFrom1e7WithLeadingZeros(digitA);
|
|
34324
34703
|
}
|
|
@@ -35596,7 +35975,7 @@ function createFileRegistry(...args2) {
|
|
|
35596
35975
|
if (seen.has(protoFileName)) {
|
|
35597
35976
|
continue;
|
|
35598
35977
|
}
|
|
35599
|
-
const dep =
|
|
35978
|
+
const dep = resolve17(protoFileName);
|
|
35600
35979
|
if (!dep) {
|
|
35601
35980
|
throw new Error(`Unable to resolve ${protoFileName}, imported by ${file2.name}`);
|
|
35602
35981
|
}
|
|
@@ -35610,7 +35989,7 @@ function createFileRegistry(...args2) {
|
|
|
35610
35989
|
return deps.concat(...deps.map(recurseDeps));
|
|
35611
35990
|
};
|
|
35612
35991
|
const input2 = args2[0];
|
|
35613
|
-
const
|
|
35992
|
+
const resolve17 = args2[1];
|
|
35614
35993
|
const seen = /* @__PURE__ */ new Set();
|
|
35615
35994
|
for (const file2 of [input2, ...recurseDeps(input2)].reverse()) {
|
|
35616
35995
|
addFile(file2, registry2);
|
|
@@ -37445,10 +37824,10 @@ var init_scip_pb = __esm({
|
|
|
37445
37824
|
|
|
37446
37825
|
// ../index-builder/src/languages.ts
|
|
37447
37826
|
function languageForPath(path) {
|
|
37448
|
-
const
|
|
37449
|
-
const dot =
|
|
37827
|
+
const base5 = path.slice(path.lastIndexOf("/") + 1);
|
|
37828
|
+
const dot = base5.lastIndexOf(".");
|
|
37450
37829
|
if (dot <= 0) return null;
|
|
37451
|
-
return BY_EXTENSION.get(
|
|
37830
|
+
return BY_EXTENSION.get(base5.slice(dot).toLowerCase()) ?? null;
|
|
37452
37831
|
}
|
|
37453
37832
|
var BY_EXTENSION;
|
|
37454
37833
|
var init_languages = __esm({
|
|
@@ -38023,13 +38402,13 @@ async function Module2(moduleArg = {}) {
|
|
|
38023
38402
|
}
|
|
38024
38403
|
readAsync = /* @__PURE__ */ __name(async (url2) => {
|
|
38025
38404
|
if (isFileURI(url2)) {
|
|
38026
|
-
return new Promise((
|
|
38405
|
+
return new Promise((resolve17, reject) => {
|
|
38027
38406
|
var xhr = new XMLHttpRequest();
|
|
38028
38407
|
xhr.open("GET", url2, true);
|
|
38029
38408
|
xhr.responseType = "arraybuffer";
|
|
38030
38409
|
xhr.onload = () => {
|
|
38031
38410
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
38032
|
-
|
|
38411
|
+
resolve17(xhr.response);
|
|
38033
38412
|
return;
|
|
38034
38413
|
}
|
|
38035
38414
|
reject(xhr.status);
|
|
@@ -38225,9 +38604,9 @@ async function Module2(moduleArg = {}) {
|
|
|
38225
38604
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
38226
38605
|
var info2 = getWasmImports();
|
|
38227
38606
|
if (Module["instantiateWasm"]) {
|
|
38228
|
-
return new Promise((
|
|
38607
|
+
return new Promise((resolve17, reject) => {
|
|
38229
38608
|
Module["instantiateWasm"](info2, (mod, inst) => {
|
|
38230
|
-
|
|
38609
|
+
resolve17(receiveInstance(mod, inst));
|
|
38231
38610
|
});
|
|
38232
38611
|
});
|
|
38233
38612
|
}
|
|
@@ -39560,8 +39939,8 @@ async function Module2(moduleArg = {}) {
|
|
|
39560
39939
|
if (runtimeInitialized) {
|
|
39561
39940
|
moduleRtn = Module;
|
|
39562
39941
|
} else {
|
|
39563
|
-
moduleRtn = new Promise((
|
|
39564
|
-
readyPromiseResolve =
|
|
39942
|
+
moduleRtn = new Promise((resolve17, reject) => {
|
|
39943
|
+
readyPromiseResolve = resolve17;
|
|
39565
39944
|
readyPromiseReject = reject;
|
|
39566
39945
|
});
|
|
39567
39946
|
}
|
|
@@ -42218,7 +42597,7 @@ var init_snapshot = __esm({
|
|
|
42218
42597
|
// ../index-builder/src/upload.ts
|
|
42219
42598
|
async function uploadSnapshot(options) {
|
|
42220
42599
|
const doFetch = options.fetch ?? fetch;
|
|
42221
|
-
const
|
|
42600
|
+
const base5 = options.serviceUrl.replace(/\/+$/, "");
|
|
42222
42601
|
const manifest = SnapshotManifest.parse(options.manifest);
|
|
42223
42602
|
const { tenantId, repository, projectId, commitSha } = manifest;
|
|
42224
42603
|
const byProject = projectId !== void 0 && (repository === void 0 || options.byProject === true);
|
|
@@ -42228,7 +42607,7 @@ async function uploadSnapshot(options) {
|
|
|
42228
42607
|
for (let attempt2 = 1; ; attempt2 += 1) {
|
|
42229
42608
|
let failure4;
|
|
42230
42609
|
try {
|
|
42231
|
-
const response = await doFetch(`${
|
|
42610
|
+
const response = await doFetch(`${base5}${path}`, { method: "POST", headers, body: body2 });
|
|
42232
42611
|
if (response.ok) return response;
|
|
42233
42612
|
const retryable = response.status === 429 || response.status >= 500;
|
|
42234
42613
|
if (!retryable || attempt2 >= ATTEMPTS) {
|
|
@@ -42240,7 +42619,7 @@ async function uploadSnapshot(options) {
|
|
|
42240
42619
|
failure4 = error62 instanceof Error ? error62.message : String(error62);
|
|
42241
42620
|
if (attempt2 >= ATTEMPTS) throw new Error(`POST ${path} failed: ${failure4}`);
|
|
42242
42621
|
}
|
|
42243
|
-
await new Promise((
|
|
42622
|
+
await new Promise((resolve17) => setTimeout(resolve17, (options.retryDelayMs ?? 500) * attempt2));
|
|
42244
42623
|
}
|
|
42245
42624
|
};
|
|
42246
42625
|
const manifestPath = byProject ? codePaths.projectUploadManifest(tenantId, projectId ?? "") : codePaths.uploadManifest(tenantId, repository?.owner ?? "", repository?.name ?? "");
|
|
@@ -42637,7 +43016,7 @@ async function buildRepoIndex(files) {
|
|
|
42637
43016
|
}
|
|
42638
43017
|
const heritage = /* @__PURE__ */ new Map();
|
|
42639
43018
|
const heirs = /* @__PURE__ */ new Map();
|
|
42640
|
-
const
|
|
43019
|
+
const resolve17 = (from, name2) => {
|
|
42641
43020
|
const visible = imports.get(from.path) ?? /* @__PURE__ */ new Set();
|
|
42642
43021
|
return (byName.get(baseName(name2)) ?? []).find((candidate) => candidate.path === from.path || reaches(visible, candidate.path));
|
|
42643
43022
|
};
|
|
@@ -42646,8 +43025,8 @@ async function buildRepoIndex(files) {
|
|
|
42646
43025
|
const stem2 = header.slice(header.indexOf(entry.name) + entry.name.length).replace(/^<[^>]*>/, "").replace(/\{.*$/, "");
|
|
42647
43026
|
const ext = /\bextends\s+([A-Za-z_$][\w$.]*)/.exec(stem2)?.[1];
|
|
42648
43027
|
const impl = /\bimplements\s+(.+)$/.exec(stem2)?.[1];
|
|
42649
|
-
const extendsIds = ext === void 0 ? [] : [
|
|
42650
|
-
const implementsIds = (impl === void 0 ? [] : impl.split(/,(?![^<]*>)/).map((part) =>
|
|
43028
|
+
const extendsIds = ext === void 0 ? [] : [resolve17(entry, ext)?.id].filter((value) => value !== void 0);
|
|
43029
|
+
const implementsIds = (impl === void 0 ? [] : impl.split(/,(?![^<]*>)/).map((part) => resolve17(entry, part.trim()))).filter((value) => value !== void 0).map((value) => value.id);
|
|
42651
43030
|
if (extendsIds.length === 0 && implementsIds.length === 0) continue;
|
|
42652
43031
|
heritage.set(id2, { extends: extendsIds, implements: implementsIds });
|
|
42653
43032
|
for (const target2 of extendsIds) heirs.set(target2, { extendedBy: [...heirs.get(target2)?.extendedBy ?? [], id2], implementedBy: heirs.get(target2)?.implementedBy ?? [] });
|
|
@@ -42740,7 +43119,7 @@ var init_context_map_build = __esm({
|
|
|
42740
43119
|
// ../index-builder/src/run.ts
|
|
42741
43120
|
import { execFile as execFile3 } from "node:child_process";
|
|
42742
43121
|
import { mkdir as mkdir4, readdir as readdir4, rm as rm2, writeFile as writeFile4 } from "node:fs/promises";
|
|
42743
|
-
import { join as join28, resolve as
|
|
43122
|
+
import { join as join28, resolve as resolve15 } from "node:path";
|
|
42744
43123
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
42745
43124
|
import { promisify as promisify3 } from "node:util";
|
|
42746
43125
|
async function git6(root, args2) {
|
|
@@ -42761,7 +43140,7 @@ async function repositoryFromRemote(root) {
|
|
|
42761
43140
|
}
|
|
42762
43141
|
}
|
|
42763
43142
|
async function snapshotFromArgs(values, env) {
|
|
42764
|
-
const root =
|
|
43143
|
+
const root = resolve15(typeof values["root"] === "string" ? values["root"] : process.cwd());
|
|
42765
43144
|
const projectId = typeof values["project"] === "string" ? values["project"] : void 0;
|
|
42766
43145
|
if (projectId !== void 0 && !ProjectId.safeParse(projectId).success) throw new UsageError2(`--project must be a project identifier, got "${projectId}"`);
|
|
42767
43146
|
const repoText = projectId !== void 0 ? typeof values["repo"] === "string" ? values["repo"] : void 0 : (typeof values["repo"] === "string" ? values["repo"] : void 0) ?? env["GITHUB_REPOSITORY"] ?? await repositoryFromRemote(root);
|
|
@@ -42773,7 +43152,7 @@ async function snapshotFromArgs(values, env) {
|
|
|
42773
43152
|
const scip = Array.isArray(values["scip"]) ? values["scip"] : [];
|
|
42774
43153
|
return buildSnapshot({
|
|
42775
43154
|
repoRoot: root,
|
|
42776
|
-
scipFiles: scip.map((file2) =>
|
|
43155
|
+
scipFiles: scip.map((file2) => resolve15(file2)),
|
|
42777
43156
|
tenantId: tenant,
|
|
42778
43157
|
...repoText ? { repository: parseRepository(repoText) } : {},
|
|
42779
43158
|
...projectId !== void 0 ? { projectId } : {},
|
|
@@ -42789,14 +43168,14 @@ async function runCli2(argv, env, out2 = console.log, err2 = console.error) {
|
|
|
42789
43168
|
const outDir = values.out;
|
|
42790
43169
|
if (!outDir) throw new UsageError2("build needs --out DIR");
|
|
42791
43170
|
const built = await snapshotFromArgs({ ...values, tenant: values.tenant ?? env["HARNESS_TENANT"] ?? "local" }, env);
|
|
42792
|
-
await writeSnapshot(
|
|
42793
|
-
out2(`built ${built.shards.length} shards (${built.uncovered.length} files uncovered) into ${
|
|
43171
|
+
await writeSnapshot(resolve15(outDir), built);
|
|
43172
|
+
out2(`built ${built.shards.length} shards (${built.uncovered.length} files uncovered) into ${resolve15(outDir)}`);
|
|
42794
43173
|
return 0;
|
|
42795
43174
|
}
|
|
42796
43175
|
if (command === "map") {
|
|
42797
|
-
const root =
|
|
43176
|
+
const root = resolve15(values.root ?? process.cwd());
|
|
42798
43177
|
const { digest, indexFile } = await buildArtifactsForCheckout({ root, ...values.task === void 0 ? {} : { task: values.task } });
|
|
42799
|
-
const path = await writeDigest(root, digest, values.out === void 0 ? void 0 :
|
|
43178
|
+
const path = await writeDigest(root, digest, values.out === void 0 ? void 0 : resolve15(values.out));
|
|
42800
43179
|
const indexPath = values.out === void 0 ? await writeIndexFile(root, indexFile) : null;
|
|
42801
43180
|
out2(`wrote the code map digest for ${digest.revision.commitSha.slice(0, 12)} (${digest.coverage.files} files, ${digest.coverage.symbols} symbols, ${digest.lines.length} lines) to ${path}${indexPath === null ? "" : `, and the ranking index to ${indexPath}`}`);
|
|
42802
43181
|
return 0;
|
|
@@ -46436,14 +46815,14 @@ function inputRequiredRoundsExceededMessage(method, maxRounds) {
|
|
|
46436
46815
|
return `Multi-round-trip request '${method}' still required input after ${maxRounds} rounds (inputRequired.maxRounds)`;
|
|
46437
46816
|
}
|
|
46438
46817
|
function sleep2(ms, signal) {
|
|
46439
|
-
return new Promise((
|
|
46818
|
+
return new Promise((resolve17, reject) => {
|
|
46440
46819
|
if (signal?.aborted) {
|
|
46441
46820
|
reject(signal.reason instanceof SdkError ? signal.reason : new SdkError(SdkErrorCode.RequestTimeout, String(signal.reason)));
|
|
46442
46821
|
return;
|
|
46443
46822
|
}
|
|
46444
46823
|
const timer = setTimeout(() => {
|
|
46445
46824
|
signal?.removeEventListener("abort", onAbort);
|
|
46446
|
-
|
|
46825
|
+
resolve17();
|
|
46447
46826
|
}, ms);
|
|
46448
46827
|
const onAbort = () => {
|
|
46449
46828
|
clearTimeout(timer);
|
|
@@ -46549,8 +46928,8 @@ function setNegotiatedProtocolVersion(instance2, version2) {
|
|
|
46549
46928
|
function isPlainObject$1(value) {
|
|
46550
46929
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
46551
46930
|
}
|
|
46552
|
-
function mergeCapabilities(
|
|
46553
|
-
const result = { ...
|
|
46931
|
+
function mergeCapabilities(base5, additional) {
|
|
46932
|
+
const result = { ...base5 };
|
|
46554
46933
|
for (const key in additional) {
|
|
46555
46934
|
const k = key;
|
|
46556
46935
|
const addValue = additional[k];
|
|
@@ -48239,7 +48618,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
48239
48618
|
const flowStartedAt = Date.now();
|
|
48240
48619
|
let onAbort;
|
|
48241
48620
|
let cleanupMessageId;
|
|
48242
|
-
return new Promise((
|
|
48621
|
+
return new Promise((resolve17, reject) => {
|
|
48243
48622
|
const earlyReject = (error62) => {
|
|
48244
48623
|
reject(error62);
|
|
48245
48624
|
};
|
|
@@ -48307,7 +48686,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
48307
48686
|
}
|
|
48308
48687
|
if (decoded.kind === "invalid") return reject(decoded.error);
|
|
48309
48688
|
if (decoded.kind === "input_required") {
|
|
48310
|
-
if (options?.allowInputRequired === true) return
|
|
48689
|
+
if (options?.allowInputRequired === true) return resolve17(manualInputRequiredValue(decoded));
|
|
48311
48690
|
const flow = {
|
|
48312
48691
|
codec: codec2,
|
|
48313
48692
|
request,
|
|
@@ -48319,11 +48698,11 @@ var init_src_CX2iR2pK = __esm({
|
|
|
48319
48698
|
params
|
|
48320
48699
|
}, resultSchema2, legOptions)
|
|
48321
48700
|
};
|
|
48322
|
-
return
|
|
48701
|
+
return resolve17(this._resolveNonCompleteResult(decoded, flow));
|
|
48323
48702
|
}
|
|
48324
48703
|
const result = decoded.result;
|
|
48325
48704
|
validateStandardSchema(resultSchema2, result).then((parseResult) => {
|
|
48326
|
-
if (parseResult.success)
|
|
48705
|
+
if (parseResult.success) resolve17(parseResult.data);
|
|
48327
48706
|
else reject(new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${request.method}: ${parseResult.error}`));
|
|
48328
48707
|
}, reject);
|
|
48329
48708
|
});
|
|
@@ -51139,7 +51518,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
51139
51518
|
ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
|
|
51140
51519
|
const schOrFunc = root.refs[ref];
|
|
51141
51520
|
if (schOrFunc) return schOrFunc;
|
|
51142
|
-
let _sch =
|
|
51521
|
+
let _sch = resolve17.call(this, root, ref);
|
|
51143
51522
|
if (_sch === void 0) {
|
|
51144
51523
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
51145
51524
|
const { schemaId } = this.opts;
|
|
@@ -51165,7 +51544,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
51165
51544
|
function sameSchemaEnv(s1, s2) {
|
|
51166
51545
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
51167
51546
|
}
|
|
51168
|
-
function
|
|
51547
|
+
function resolve17(root, ref) {
|
|
51169
51548
|
let sch;
|
|
51170
51549
|
while (typeof (sch = this.refs[ref]) == "string") ref = sch;
|
|
51171
51550
|
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
|
|
@@ -51615,16 +51994,16 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
51615
51994
|
else if (typeof uri === "object") uri = parse5(serialize(uri, options), options);
|
|
51616
51995
|
return uri;
|
|
51617
51996
|
}
|
|
51618
|
-
function
|
|
51997
|
+
function resolve17(baseURI, relativeURI, options) {
|
|
51619
51998
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
51620
51999
|
const resolved = resolveComponent(parse5(baseURI, schemelessOptions), parse5(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
51621
52000
|
schemelessOptions.skipEscape = true;
|
|
51622
52001
|
return serialize(resolved, schemelessOptions);
|
|
51623
52002
|
}
|
|
51624
|
-
function resolveComponent(
|
|
52003
|
+
function resolveComponent(base5, relative4, options, skipNormalization) {
|
|
51625
52004
|
const target2 = {};
|
|
51626
52005
|
if (!skipNormalization) {
|
|
51627
|
-
|
|
52006
|
+
base5 = parse5(serialize(base5, options), options);
|
|
51628
52007
|
relative4 = parse5(serialize(relative4, options), options);
|
|
51629
52008
|
}
|
|
51630
52009
|
options = options || {};
|
|
@@ -51644,24 +52023,24 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
51644
52023
|
target2.query = relative4.query;
|
|
51645
52024
|
} else {
|
|
51646
52025
|
if (!relative4.path) {
|
|
51647
|
-
target2.path =
|
|
52026
|
+
target2.path = base5.path;
|
|
51648
52027
|
if (relative4.query !== void 0) target2.query = relative4.query;
|
|
51649
|
-
else target2.query =
|
|
52028
|
+
else target2.query = base5.query;
|
|
51650
52029
|
} else {
|
|
51651
52030
|
if (relative4.path[0] === "/") target2.path = removeDotSegments(relative4.path);
|
|
51652
52031
|
else {
|
|
51653
|
-
if ((
|
|
51654
|
-
else if (!
|
|
51655
|
-
else target2.path =
|
|
52032
|
+
if ((base5.userinfo !== void 0 || base5.host !== void 0 || base5.port !== void 0) && !base5.path) target2.path = "/" + relative4.path;
|
|
52033
|
+
else if (!base5.path) target2.path = relative4.path;
|
|
52034
|
+
else target2.path = base5.path.slice(0, base5.path.lastIndexOf("/") + 1) + relative4.path;
|
|
51656
52035
|
target2.path = removeDotSegments(target2.path);
|
|
51657
52036
|
}
|
|
51658
52037
|
target2.query = relative4.query;
|
|
51659
52038
|
}
|
|
51660
|
-
target2.userinfo =
|
|
51661
|
-
target2.host =
|
|
51662
|
-
target2.port =
|
|
52039
|
+
target2.userinfo = base5.userinfo;
|
|
52040
|
+
target2.host = base5.host;
|
|
52041
|
+
target2.port = base5.port;
|
|
51663
52042
|
}
|
|
51664
|
-
target2.scheme =
|
|
52043
|
+
target2.scheme = base5.scheme;
|
|
51665
52044
|
}
|
|
51666
52045
|
target2.fragment = relative4.fragment;
|
|
51667
52046
|
return target2;
|
|
@@ -51789,7 +52168,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
51789
52168
|
const fastUri = {
|
|
51790
52169
|
SCHEMES,
|
|
51791
52170
|
normalize,
|
|
51792
|
-
resolve:
|
|
52171
|
+
resolve: resolve17,
|
|
51793
52172
|
resolveComponent,
|
|
51794
52173
|
equal,
|
|
51795
52174
|
serialize,
|
|
@@ -57486,7 +57865,7 @@ var init_stdio = __esm({
|
|
|
57486
57865
|
}
|
|
57487
57866
|
send(message) {
|
|
57488
57867
|
if (this._closed) return Promise.reject(/* @__PURE__ */ new Error("StdioServerTransport is closed"));
|
|
57489
|
-
return new Promise((
|
|
57868
|
+
return new Promise((resolve17, reject) => {
|
|
57490
57869
|
const json2 = serializeMessage(message);
|
|
57491
57870
|
let settled = false;
|
|
57492
57871
|
const onError = (error62) => {
|
|
@@ -57501,14 +57880,14 @@ var init_stdio = __esm({
|
|
|
57501
57880
|
settled = true;
|
|
57502
57881
|
this._stdout.off("error", onError);
|
|
57503
57882
|
this._stdout.off("drain", onDrain);
|
|
57504
|
-
|
|
57883
|
+
resolve17();
|
|
57505
57884
|
};
|
|
57506
57885
|
this._stdout.once("error", onError);
|
|
57507
57886
|
if (this._stdout.write(json2)) {
|
|
57508
57887
|
if (settled) return;
|
|
57509
57888
|
settled = true;
|
|
57510
57889
|
this._stdout.off("error", onError);
|
|
57511
|
-
|
|
57890
|
+
resolve17();
|
|
57512
57891
|
} else if (!settled) this._stdout.once("drain", onDrain);
|
|
57513
57892
|
});
|
|
57514
57893
|
}
|
|
@@ -57562,14 +57941,14 @@ var init_stdio = __esm({
|
|
|
57562
57941
|
*/
|
|
57563
57942
|
async whenRequestsAnswered(timeoutMs) {
|
|
57564
57943
|
if (this._closed || this._pendingRequests.size === 0) return true;
|
|
57565
|
-
return await new Promise((
|
|
57944
|
+
return await new Promise((resolve17) => {
|
|
57566
57945
|
const waiter = () => {
|
|
57567
57946
|
clearTimeout(timer);
|
|
57568
|
-
|
|
57947
|
+
resolve17(true);
|
|
57569
57948
|
};
|
|
57570
57949
|
const timer = setTimeout(() => {
|
|
57571
57950
|
this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
|
|
57572
|
-
|
|
57951
|
+
resolve17(false);
|
|
57573
57952
|
}, timeoutMs);
|
|
57574
57953
|
this._drainWaiters.push(waiter);
|
|
57575
57954
|
});
|
|
@@ -57748,18 +58127,18 @@ var init_git2 = __esm({
|
|
|
57748
58127
|
});
|
|
57749
58128
|
|
|
57750
58129
|
// ../code-shim/src/config.ts
|
|
57751
|
-
import { readFileSync as
|
|
58130
|
+
import { readFileSync as readFileSync17 } from "node:fs";
|
|
57752
58131
|
import { homedir as homedir2 } from "node:os";
|
|
57753
58132
|
import { join as join33 } from "node:path";
|
|
57754
58133
|
function configDir(env) {
|
|
57755
|
-
const
|
|
57756
|
-
return join33(
|
|
58134
|
+
const base5 = env["XDG_CONFIG_HOME"] ?? (process.platform === "win32" ? env["APPDATA"] : void 0) ?? join33(homedir2(), ".config");
|
|
58135
|
+
return join33(base5, "mvrx-harness");
|
|
57757
58136
|
}
|
|
57758
58137
|
function findToken2(env, serviceUrl, now) {
|
|
57759
58138
|
const fromEnv = env["HARNESS_TOKEN"];
|
|
57760
58139
|
if (fromEnv !== void 0 && fromEnv.length > 0) return fromEnv;
|
|
57761
58140
|
try {
|
|
57762
|
-
const file2 = JSON.parse(
|
|
58141
|
+
const file2 = JSON.parse(readFileSync17(join33(configDir(env), "credentials.json"), "utf8"));
|
|
57763
58142
|
const stored = file2[serviceUrl];
|
|
57764
58143
|
if (stored === void 0 || typeof stored.accessToken !== "string" || stored.accessToken.length === 0) return null;
|
|
57765
58144
|
if (typeof stored.expiresAt === "number" && stored.expiresAt <= now) return null;
|
|
@@ -57771,7 +58150,7 @@ function findToken2(env, serviceUrl, now) {
|
|
|
57771
58150
|
function resolveCloudConfig(root, env, now) {
|
|
57772
58151
|
let binding;
|
|
57773
58152
|
try {
|
|
57774
|
-
const parsed = ProjectBinding.safeParse(JSON.parse(
|
|
58153
|
+
const parsed = ProjectBinding.safeParse(JSON.parse(readFileSync17(join33(root, ".harness", "project.json"), "utf8")));
|
|
57775
58154
|
if (!parsed.success) return null;
|
|
57776
58155
|
binding = parsed.data;
|
|
57777
58156
|
} catch {
|
|
@@ -57793,10 +58172,10 @@ var init_config = __esm({
|
|
|
57793
58172
|
});
|
|
57794
58173
|
|
|
57795
58174
|
// ../code-shim/src/local.ts
|
|
57796
|
-
import { readFileSync as
|
|
57797
|
-
import { isAbsolute as isAbsolute2, relative as relative3, resolve as
|
|
58175
|
+
import { readFileSync as readFileSync18, statSync as statSync3 } from "node:fs";
|
|
58176
|
+
import { isAbsolute as isAbsolute2, relative as relative3, resolve as resolve16, sep as sep2 } from "node:path";
|
|
57798
58177
|
function resolveInside(root, path) {
|
|
57799
|
-
const absolute =
|
|
58178
|
+
const absolute = resolve16(root, path);
|
|
57800
58179
|
const rel = relative3(root, absolute);
|
|
57801
58180
|
if (rel.length === 0 || rel.startsWith("..") || isAbsolute2(rel)) return null;
|
|
57802
58181
|
return absolute;
|
|
@@ -57913,7 +58292,7 @@ var init_local = __esm({
|
|
|
57913
58292
|
let shard;
|
|
57914
58293
|
try {
|
|
57915
58294
|
this.parses += 1;
|
|
57916
|
-
shard = await this.parse(path,
|
|
58295
|
+
shard = await this.parse(path, readFileSync18(absolute, "utf8"));
|
|
57917
58296
|
} catch {
|
|
57918
58297
|
shard = null;
|
|
57919
58298
|
}
|
|
@@ -57925,7 +58304,7 @@ var init_local = __esm({
|
|
|
57925
58304
|
const absolute = resolveInside(this.root, path);
|
|
57926
58305
|
if (absolute === null) return null;
|
|
57927
58306
|
try {
|
|
57928
|
-
return
|
|
58307
|
+
return readFileSync18(absolute, "utf8");
|
|
57929
58308
|
} catch {
|
|
57930
58309
|
return null;
|
|
57931
58310
|
}
|
|
@@ -57935,7 +58314,7 @@ var init_local = __esm({
|
|
|
57935
58314
|
const absolute = resolveInside(this.root, path);
|
|
57936
58315
|
if (absolute === null) return void 0;
|
|
57937
58316
|
try {
|
|
57938
|
-
const lines =
|
|
58317
|
+
const lines = readFileSync18(absolute, "utf8").split("\n");
|
|
57939
58318
|
const start2 = range[0];
|
|
57940
58319
|
if (start2 >= lines.length) return void 0;
|
|
57941
58320
|
const end = Math.min(Math.max(range[2], start2), start2 + maxLines - 1, lines.length - 1);
|
|
@@ -58056,8 +58435,8 @@ async function symbolsOverview(deps, args2) {
|
|
|
58056
58435
|
const dirty2 = await parseDirty(deps.index, state, (p2) => isUnder(p2, scope));
|
|
58057
58436
|
const cloud = await deps.cloud.query("symbols_overview", state.head, args2, SymbolAnswer);
|
|
58058
58437
|
const local2 = localSymbolHits(dirty2.shards, (shard, i2) => shard.symbols[i2]?.parent === void 0);
|
|
58059
|
-
const
|
|
58060
|
-
const merged = uniqueBy([...
|
|
58438
|
+
const base5 = cloud.kind === "ok" ? cloudSymbols(cloud.data.symbols, state).filter((hit) => isUnder(hit.path, scope)) : [];
|
|
58439
|
+
const merged = uniqueBy([...base5, ...local2], (h) => `${h.path}\0${h.symbol}\0${h.range.join(",")}`);
|
|
58061
58440
|
const limited = limitByTokens(merged, args2.max_tokens ?? 4e3);
|
|
58062
58441
|
return {
|
|
58063
58442
|
provenance: mergeProvenance(state.head, cloud.kind === "ok" ? cloud.data.provenance : null, state, { overlaid: [...dirty2.shards.keys()], unparsed: dirty2.unparsed }),
|
|
@@ -58074,8 +58453,8 @@ async function findSymbol(deps, args2) {
|
|
|
58074
58453
|
const symbol2 = shard.symbols[i2];
|
|
58075
58454
|
return symbol2 !== void 0 && matchesNamePath(shard, symbol2, wanted);
|
|
58076
58455
|
});
|
|
58077
|
-
const
|
|
58078
|
-
const merged = uniqueBy([...
|
|
58456
|
+
const base5 = cloud.kind === "ok" ? cloudSymbols(cloud.data.symbols, state) : [];
|
|
58457
|
+
const merged = uniqueBy([...base5, ...local2], (h) => `${h.path}\0${h.symbol}\0${h.range.join(",")}`);
|
|
58079
58458
|
return {
|
|
58080
58459
|
provenance: mergeProvenance(state.head, cloud.kind === "ok" ? cloud.data.provenance : null, state, { overlaid: [...dirty2.shards.keys()], unparsed: dirty2.unparsed }),
|
|
58081
58460
|
symbols: withSnippets(deps.index, merged, args2.include_snippet === true)
|
|
@@ -58095,14 +58474,14 @@ async function findReferences(deps, args2) {
|
|
|
58095
58474
|
local2.push({ path, symbol: args2.name, range, source: "local" });
|
|
58096
58475
|
}
|
|
58097
58476
|
}
|
|
58098
|
-
const
|
|
58477
|
+
const base5 = [];
|
|
58099
58478
|
if (cloud.kind === "ok") {
|
|
58100
58479
|
for (const hit of cloud.data.references) {
|
|
58101
58480
|
const path = keepCloudPath(hit.path, state);
|
|
58102
|
-
if (path !== null)
|
|
58481
|
+
if (path !== null) base5.push({ ...hit, path, source: "cloud" });
|
|
58103
58482
|
}
|
|
58104
58483
|
}
|
|
58105
|
-
const merged = uniqueBy([...
|
|
58484
|
+
const merged = uniqueBy([...base5, ...local2], (h) => `${h.path}\0${h.range.join(",")}`);
|
|
58106
58485
|
return {
|
|
58107
58486
|
provenance: mergeProvenance(state.head, cloud.kind === "ok" ? cloud.data.provenance : null, state, { overlaid: [...dirty2.shards.keys()], unparsed: dirty2.unparsed }),
|
|
58108
58487
|
references: withSnippets(deps.index, merged, args2.include_snippet === true)
|
|
@@ -58162,7 +58541,7 @@ var init_nav = __esm({
|
|
|
58162
58541
|
|
|
58163
58542
|
// ../code-shim/src/edit.ts
|
|
58164
58543
|
import { createHash as createHash8 } from "node:crypto";
|
|
58165
|
-
import { readFileSync as
|
|
58544
|
+
import { readFileSync as readFileSync19, writeFileSync as writeFileSync11 } from "node:fs";
|
|
58166
58545
|
function lineStarts(text) {
|
|
58167
58546
|
const starts = [0];
|
|
58168
58547
|
for (let i2 = 0; i2 < text.length; i2 += 1) if (text[i2] === "\n") starts.push(i2 + 1);
|
|
@@ -58203,7 +58582,7 @@ async function editSymbol(index, args2) {
|
|
|
58203
58582
|
if (!found.ok) return found;
|
|
58204
58583
|
const absolute = resolveInside(index.root, args2.path);
|
|
58205
58584
|
if (absolute === null) return { ok: false, reason: `path ${args2.path} is outside the repository` };
|
|
58206
|
-
const original =
|
|
58585
|
+
const original = readFileSync19(absolute, "utf8");
|
|
58207
58586
|
const starts = lineStarts(original);
|
|
58208
58587
|
const range = found.symbol.enclosingRange ?? found.symbol.range;
|
|
58209
58588
|
const from = offsetOf(starts, original, range[0], range[1]);
|
|
@@ -58231,7 +58610,7 @@ ${args2.content.replace(/\n+$/, "")}`;
|
|
|
58231
58610
|
const before = positionAt(next, changedStart);
|
|
58232
58611
|
const after = positionAt(next, insertAt + inserted.length);
|
|
58233
58612
|
const bytes = Buffer.from(next, "utf8");
|
|
58234
|
-
|
|
58613
|
+
writeFileSync11(absolute, bytes);
|
|
58235
58614
|
return {
|
|
58236
58615
|
ok: true,
|
|
58237
58616
|
path: args2.path,
|
|
@@ -58270,7 +58649,7 @@ async function renameSymbol(deps, args2) {
|
|
|
58270
58649
|
if (absolute === null) return { ok: false, reason: `reference path ${path} is outside the repository` };
|
|
58271
58650
|
let text;
|
|
58272
58651
|
try {
|
|
58273
|
-
text =
|
|
58652
|
+
text = readFileSync19(absolute, "utf8");
|
|
58274
58653
|
} catch {
|
|
58275
58654
|
return { ok: false, reason: `cannot read ${path}` };
|
|
58276
58655
|
}
|
|
@@ -58292,7 +58671,7 @@ async function renameSymbol(deps, args2) {
|
|
|
58292
58671
|
let next = item.text;
|
|
58293
58672
|
for (const offset of offsets) next = next.slice(0, offset) + args2.new_name + next.slice(offset + oldName.length);
|
|
58294
58673
|
const bytes = Buffer.from(next, "utf8");
|
|
58295
|
-
|
|
58674
|
+
writeFileSync11(item.absolute, bytes);
|
|
58296
58675
|
filesChanged.push({ path: item.path, edits: offsets.length, sha256: sha2563(bytes) });
|
|
58297
58676
|
edits += offsets.length;
|
|
58298
58677
|
}
|
|
@@ -58420,12 +58799,12 @@ function shimSetting(env) {
|
|
|
58420
58799
|
}
|
|
58421
58800
|
function codeMapSwitch(env, results) {
|
|
58422
58801
|
const setting = shimSetting(env);
|
|
58423
|
-
const
|
|
58802
|
+
const base5 = results === void 0 ? codeMapDefault(setting) : codeMapDefault(setting, results);
|
|
58424
58803
|
const forced = env["HARNESS_CODE_MAP"];
|
|
58425
58804
|
if (forced === "on" || forced === "off") {
|
|
58426
|
-
return { ...
|
|
58805
|
+
return { ...base5, on: forced === "on", basis: "project-setting", reason: `${forced}: set by HARNESS_CODE_MAP (the default for this setting is ${base5.on ? "on" : "off"}: ${base5.reason})`, source: "env" };
|
|
58427
58806
|
}
|
|
58428
|
-
return { ...
|
|
58807
|
+
return { ...base5, source: "default" };
|
|
58429
58808
|
}
|
|
58430
58809
|
function describeSwitch(state) {
|
|
58431
58810
|
return `code-shim: code map ${state.on ? "on" : "off"} for ${state.setting} (${state.source}). ${state.reason}`;
|
|
@@ -58733,8 +59112,8 @@ var AuthRequiredError = class extends MvrxError {
|
|
|
58733
59112
|
super(message, { code: "auth_required", exit: EXIT.auth }, { hint: "overlane auth status", ...options });
|
|
58734
59113
|
}
|
|
58735
59114
|
};
|
|
58736
|
-
function unreachable(
|
|
58737
|
-
return new CliError(`cannot reach ${
|
|
59115
|
+
function unreachable(base5, cause) {
|
|
59116
|
+
return new CliError(`cannot reach ${base5}: ${cause instanceof Error ? cause.message : String(cause)}`, {
|
|
58738
59117
|
code: "unreachable",
|
|
58739
59118
|
exit: EXIT.unreachable,
|
|
58740
59119
|
retryable: true,
|
|
@@ -59313,19 +59692,19 @@ function pkcePair() {
|
|
|
59313
59692
|
return { verifier, challenge: base64url3(createHash("sha256").update(verifier).digest()) };
|
|
59314
59693
|
}
|
|
59315
59694
|
function listen(server2, port) {
|
|
59316
|
-
return new Promise((
|
|
59695
|
+
return new Promise((resolve17, reject) => {
|
|
59317
59696
|
const onError = (error62) => reject(error62);
|
|
59318
59697
|
server2.once("error", onError);
|
|
59319
59698
|
server2.listen(port, "127.0.0.1", () => {
|
|
59320
59699
|
server2.off("error", onError);
|
|
59321
|
-
|
|
59700
|
+
resolve17();
|
|
59322
59701
|
});
|
|
59323
59702
|
});
|
|
59324
59703
|
}
|
|
59325
59704
|
async function startLoopback(preferredPort, state) {
|
|
59326
59705
|
let settle2;
|
|
59327
|
-
const code2 = new Promise((
|
|
59328
|
-
settle2 = { resolve:
|
|
59706
|
+
const code2 = new Promise((resolve17, reject) => {
|
|
59707
|
+
settle2 = { resolve: resolve17, reject };
|
|
59329
59708
|
});
|
|
59330
59709
|
code2.catch(() => void 0);
|
|
59331
59710
|
const server2 = createServer((request, response) => {
|
|
@@ -59700,10 +60079,10 @@ async function failure2(response) {
|
|
|
59700
60079
|
}
|
|
59701
60080
|
return { code: void 0, text: `status ${response.status}` };
|
|
59702
60081
|
}
|
|
59703
|
-
async function call(deps,
|
|
60082
|
+
async function call(deps, base5, token, schema, method, path, body2) {
|
|
59704
60083
|
let response;
|
|
59705
60084
|
try {
|
|
59706
|
-
response = await deps.fetch(`${
|
|
60085
|
+
response = await deps.fetch(`${base5}${path}`, {
|
|
59707
60086
|
method,
|
|
59708
60087
|
headers: {
|
|
59709
60088
|
accept: "application/json",
|
|
@@ -59713,7 +60092,7 @@ async function call(deps, base4, token, schema, method, path, body2) {
|
|
|
59713
60092
|
...body2 === void 0 ? {} : { body: JSON.stringify(body2) }
|
|
59714
60093
|
});
|
|
59715
60094
|
} catch (error62) {
|
|
59716
|
-
throw unreachable(
|
|
60095
|
+
throw unreachable(base5, error62);
|
|
59717
60096
|
}
|
|
59718
60097
|
if (!response.ok) {
|
|
59719
60098
|
const failed = await failure2(response);
|
|
@@ -59730,12 +60109,12 @@ async function call(deps, base4, token, schema, method, path, body2) {
|
|
|
59730
60109
|
return parsed.data;
|
|
59731
60110
|
}
|
|
59732
60111
|
function releaseClient(deps, binding, token, serviceUrl = binding.serviceUrl) {
|
|
59733
|
-
const
|
|
60112
|
+
const base5 = serviceUrl.replace(/\/+$/, "");
|
|
59734
60113
|
return {
|
|
59735
|
-
list: () => call(deps,
|
|
59736
|
-
get: (digest) => call(deps,
|
|
59737
|
-
pin: (digest) => call(deps,
|
|
59738
|
-
rollback: () => call(deps,
|
|
60114
|
+
list: () => call(deps, base5, token, external_exports.array(ReleaseRecord), "GET", releasePaths.list(binding.tenantId)),
|
|
60115
|
+
get: (digest) => call(deps, base5, token, ReleaseRecord, "GET", releasePaths.one(binding.tenantId, digest)),
|
|
60116
|
+
pin: (digest) => call(deps, base5, token, ProjectRecord, "PUT", releasePaths.pin(binding.tenantId, binding.projectId), { digest }),
|
|
60117
|
+
rollback: () => call(deps, base5, token, ProjectRecord, "POST", releasePaths.rollback(binding.tenantId, binding.projectId), {})
|
|
59739
60118
|
};
|
|
59740
60119
|
}
|
|
59741
60120
|
async function fetchServicePublicKey(deps, serviceUrl, token) {
|
|
@@ -60102,8 +60481,8 @@ function withTimeout(deps, ms) {
|
|
|
60102
60481
|
}
|
|
60103
60482
|
async function attempt(deps, ms, work) {
|
|
60104
60483
|
let timer;
|
|
60105
|
-
const deadline = new Promise((
|
|
60106
|
-
timer = setTimeout(() =>
|
|
60484
|
+
const deadline = new Promise((resolve17) => {
|
|
60485
|
+
timer = setTimeout(() => resolve17("unreachable"), ms);
|
|
60107
60486
|
});
|
|
60108
60487
|
try {
|
|
60109
60488
|
return await Promise.race([work(withTimeout(deps, ms)).catch((error62) => error62 instanceof ServiceError && error62.exit === EXIT.auth ? "unauthenticated" : "unreachable"), deadline]);
|
|
@@ -60341,13 +60720,13 @@ function render(op, existing) {
|
|
|
60341
60720
|
case "block":
|
|
60342
60721
|
return withBlock(existing, op.content);
|
|
60343
60722
|
case "json": {
|
|
60344
|
-
let
|
|
60723
|
+
let base5 = op.base ?? {};
|
|
60345
60724
|
if (existing !== null && existing.trim() !== "") {
|
|
60346
60725
|
const parsed = JSON.parse(existing);
|
|
60347
60726
|
if (!isRecord(parsed)) throw new Error(`${op.path} is not a JSON object; fix it by hand, then run the command again`);
|
|
60348
|
-
|
|
60727
|
+
base5 = parsed;
|
|
60349
60728
|
}
|
|
60350
|
-
return `${JSON.stringify(setAt(
|
|
60729
|
+
return `${JSON.stringify(setAt(base5, op.key, op.value), null, 2)}
|
|
60351
60730
|
`;
|
|
60352
60731
|
}
|
|
60353
60732
|
}
|
|
@@ -60900,12 +61279,12 @@ async function failure3(response) {
|
|
|
60900
61279
|
return { text: `status ${response.status}`, code: void 0, hint: void 0 };
|
|
60901
61280
|
}
|
|
60902
61281
|
function serviceCall(deps, serviceUrl, token) {
|
|
60903
|
-
const
|
|
61282
|
+
const base5 = serviceUrl.replace(/\/+$/, "");
|
|
60904
61283
|
const approval = deps.env["OVERLANE_APPROVAL"];
|
|
60905
61284
|
return async (schema, method, path, body2, extraHeaders) => {
|
|
60906
61285
|
let response;
|
|
60907
61286
|
try {
|
|
60908
|
-
response = await deps.fetch(`${
|
|
61287
|
+
response = await deps.fetch(`${base5}${path}`, {
|
|
60909
61288
|
method,
|
|
60910
61289
|
headers: {
|
|
60911
61290
|
accept: "application/json",
|
|
@@ -60917,7 +61296,7 @@ function serviceCall(deps, serviceUrl, token) {
|
|
|
60917
61296
|
...body2 === void 0 ? {} : { body: JSON.stringify(body2) }
|
|
60918
61297
|
});
|
|
60919
61298
|
} catch (error62) {
|
|
60920
|
-
throw unreachable(
|
|
61299
|
+
throw unreachable(base5, error62);
|
|
60921
61300
|
}
|
|
60922
61301
|
if (!response.ok) {
|
|
60923
61302
|
const failed = await failure3(response);
|
|
@@ -63247,12 +63626,12 @@ init_zod();
|
|
|
63247
63626
|
init_src();
|
|
63248
63627
|
init_zod();
|
|
63249
63628
|
var ErrorBody = external_exports.object({ error: external_exports.object({ code: external_exports.string(), message: external_exports.string() }).passthrough() }).passthrough();
|
|
63250
|
-
async function post(deps,
|
|
63629
|
+
async function post(deps, base5, path, body2) {
|
|
63251
63630
|
let response;
|
|
63252
63631
|
try {
|
|
63253
|
-
response = await deps.fetch(`${
|
|
63632
|
+
response = await deps.fetch(`${base5}${path}`, { method: "POST", headers: { "content-type": "application/json", accept: "application/json" }, body: JSON.stringify(body2) });
|
|
63254
63633
|
} catch (error62) {
|
|
63255
|
-
throw unreachable(
|
|
63634
|
+
throw unreachable(base5, error62);
|
|
63256
63635
|
}
|
|
63257
63636
|
let json2 = null;
|
|
63258
63637
|
try {
|
|
@@ -63263,7 +63642,7 @@ async function post(deps, base4, path, body2) {
|
|
|
63263
63642
|
return { status: response.status, json: json2 };
|
|
63264
63643
|
}
|
|
63265
63644
|
function sleep(ms) {
|
|
63266
|
-
return new Promise((
|
|
63645
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
63267
63646
|
}
|
|
63268
63647
|
async function deviceLogin(deps, service, options) {
|
|
63269
63648
|
const started = await post(deps, service, "/auth/device", {});
|
|
@@ -63592,8 +63971,8 @@ var tokenListCommand = defineCommand({
|
|
|
63592
63971
|
});
|
|
63593
63972
|
var tokenRevokeCommand = defineCommand({
|
|
63594
63973
|
path: ["token", "revoke"],
|
|
63595
|
-
summary: "Revoke an agent token
|
|
63596
|
-
description: "
|
|
63974
|
+
summary: "Revoke a token: an agent token stops working within seconds",
|
|
63975
|
+
description: "Revoke a token that leaked or is no longer needed: the agent token stops working. The next call made with it fails with exit 3 (token_revoked). You can revoke your own tokens; a team-wide agent token can revoke any token. To revoke a token, give its token ID from `overlane token list`. This cannot be undone: mint a new token instead.",
|
|
63597
63976
|
args: [{ name: "token-id", required: false, description: "The token ID from `overlane token list` (required)" }],
|
|
63598
63977
|
flags: [SERVICE_FLAG2, TEAM_FLAG2],
|
|
63599
63978
|
examples: ["overlane token revoke tok_abc123 --force", "overlane token revoke tok_abc123 --dry-run"],
|
|
@@ -64382,9 +64761,9 @@ var prOpenCommand = defineCommand({
|
|
|
64382
64761
|
const head = textFlag(inv, "head");
|
|
64383
64762
|
const title = textFlag(inv, "title");
|
|
64384
64763
|
if (head === void 0 || title === void 0) throw new UsageError("--head and --title are required", { hint: 'overlane repo pr open app --head feature/x --title "Add x"' });
|
|
64385
|
-
const
|
|
64764
|
+
const base5 = textFlag(inv, "base");
|
|
64386
64765
|
const text = textFlag(inv, "body");
|
|
64387
|
-
const body2 = { requestId: requestId4(), title, head, ...
|
|
64766
|
+
const body2 = { requestId: requestId4(), title, head, ...base5 === void 0 ? {} : { base: base5 }, ...text === void 0 ? {} : { body: text }, draft: boolFlag(inv, "draft") };
|
|
64388
64767
|
if (inv.dryRun) return planned2(inv, "repo", "POST", (t2, p2) => gitPaths.pulls(t2, p2, repo), body2);
|
|
64389
64768
|
const { call: call2, tenantId, projectId } = await connected2(inv, "repo");
|
|
64390
64769
|
return { data: await call2(PullRequest, "POST", gitPaths.pulls(tenantId, projectId, repo), body2) };
|
|
@@ -67074,19 +67453,19 @@ async function connectKit(deps, options) {
|
|
|
67074
67453
|
if (options.dryRun) {
|
|
67075
67454
|
const inner = await connect(deps, { ...options, dryRun: true });
|
|
67076
67455
|
say(deps, "Dry run: no file was written and no branch, commit or service change was made.");
|
|
67077
|
-
const
|
|
67456
|
+
const base5 = inner.data !== void 0 && "dryRun" in inner.data ? inner.data : dryRunPlan({});
|
|
67078
67457
|
const writes = [
|
|
67079
67458
|
...planExists ? [] : [{ path: `${PLAN_DIR}/`, action: "write", description: planSource }],
|
|
67080
67459
|
...workflow === null ? [] : [{ path: CI_FILE, action: "write", description: "CI workflow with pinned actions" }],
|
|
67081
67460
|
...blockChanges.map((entry) => ({ path: entry.file, action: entry.before === null ? "write" : "append", description: "the run-step block" })),
|
|
67082
|
-
...
|
|
67461
|
+
...base5.writes
|
|
67083
67462
|
];
|
|
67084
67463
|
return {
|
|
67085
67464
|
data: {
|
|
67086
|
-
...
|
|
67087
|
-
commands: [`git switch -c ${KIT_BRANCH}`, ...
|
|
67465
|
+
...base5,
|
|
67466
|
+
commands: [`git switch -c ${KIT_BRANCH}`, ...base5.commands, `git commit -m "Set up the project kit"`],
|
|
67088
67467
|
writes,
|
|
67089
|
-
notes: [...
|
|
67468
|
+
notes: [...base5.notes, `Plan: ${planSource} (${summary2.milestones} milestone(s), ${summary2.tasks} task(s)); CI: ${ciSummary}; then the run policy is set, the plan synced and one pull request opened (or its commands printed).`]
|
|
67090
67469
|
}
|
|
67091
67470
|
};
|
|
67092
67471
|
}
|
|
@@ -67110,11 +67489,11 @@ async function connectKit(deps, options) {
|
|
|
67110
67489
|
const agentConfig = [join23(".claude", "settings.json"), join23(".codex", "config.toml")];
|
|
67111
67490
|
const preDirty = new Set(await dirty(deps, root, agentConfig));
|
|
67112
67491
|
const preExisting = new Set(agentConfig.filter((file2) => existsSync7(join23(root, file2))));
|
|
67113
|
-
const
|
|
67114
|
-
if (
|
|
67492
|
+
const connected11 = await connect(deps, { ...options, yes: true });
|
|
67493
|
+
if (connected11.error !== void 0 || readBindingFile(root).kind !== "ok") {
|
|
67115
67494
|
throw new CliError(`connect did not finish; the kit files are on ${KIT_BRANCH}, uncommitted. Fix the cause and run \`overlane connect\`, then commit`, { code: "connect_incomplete", hint: "overlane connect --yes" });
|
|
67116
67495
|
}
|
|
67117
|
-
const connectData =
|
|
67496
|
+
const connectData = connected11.data !== void 0 && !("dryRun" in connected11.data) ? connected11.data : void 0;
|
|
67118
67497
|
for (const file2 of agentConfig) {
|
|
67119
67498
|
if (!existsSync7(join23(root, file2)) || preDirty.has(file2) || preExisting.has(file2) && (await dirty(deps, root, [file2])).length === 0) continue;
|
|
67120
67499
|
if ((await gitOut(deps, root, "check-ignore", "-q", "--", file2)).code === 0) continue;
|
|
@@ -67200,7 +67579,7 @@ var connectCommand = defineCommand({
|
|
|
67200
67579
|
keywords: ["setup", "install", "bind", "link", "onboard", "register plugin", "bootstrap", "autonomous", "plan", "kit", "get started", "initialise", "enable harness", "ci workflow", "pull request"],
|
|
67201
67580
|
result: external_exports.union([ConnectAny, ConnectKitResult]),
|
|
67202
67581
|
handler: async (inv) => {
|
|
67203
|
-
const
|
|
67582
|
+
const base5 = {
|
|
67204
67583
|
service: textFlag(inv, "service"),
|
|
67205
67584
|
marketplaceRoot: textFlag(inv, "marketplace-root"),
|
|
67206
67585
|
agents: parseAgentList(textFlag(inv, "agents")),
|
|
@@ -67213,10 +67592,10 @@ var connectCommand = defineCommand({
|
|
|
67213
67592
|
const goal = textFlag(inv, "goal");
|
|
67214
67593
|
if (kit === void 0) {
|
|
67215
67594
|
if (goal !== void 0) throw new UsageError("--goal belongs to --kit new", { hint: "overlane schema connect" });
|
|
67216
|
-
return connect(inv.deps,
|
|
67595
|
+
return connect(inv.deps, base5);
|
|
67217
67596
|
}
|
|
67218
67597
|
if (kit !== "existing" && kit !== "new") throw new UsageError("--kit must be existing or new");
|
|
67219
|
-
return connectKit(inv.deps, { ...
|
|
67598
|
+
return connectKit(inv.deps, { ...base5, mode: kit, goal });
|
|
67220
67599
|
}
|
|
67221
67600
|
});
|
|
67222
67601
|
var doctorCommand = defineCommand({
|
|
@@ -69652,11 +70031,11 @@ async function planned7(inv, method, path, body2, note) {
|
|
|
69652
70031
|
var git4 = (deps, args2) => deps.exec("git", args2, { cwd: deps.paths.cwd });
|
|
69653
70032
|
var MAX_PATCH_FILES = 40;
|
|
69654
70033
|
var MAX_PATCH_CHARS = 8e3;
|
|
69655
|
-
async function snapshotOf(inv, head,
|
|
70034
|
+
async function snapshotOf(inv, head, base5) {
|
|
69656
70035
|
const sha = await git4(inv.deps, ["rev-parse", "--verify", "--quiet", `${head}^{commit}`]);
|
|
69657
70036
|
if (sha.code !== 0) throw new UsageError(`${head} is not a commit in this checkout`, { hint: "git fetch, then retry" });
|
|
69658
|
-
const stat = await git4(inv.deps, ["diff", "--numstat", "-z", "--no-renames", `${
|
|
69659
|
-
if (stat.code !== 0) throw new UsageError(`could not compare ${
|
|
70037
|
+
const stat = await git4(inv.deps, ["diff", "--numstat", "-z", "--no-renames", `${base5}...${head}`]);
|
|
70038
|
+
if (stat.code !== 0) throw new UsageError(`could not compare ${base5} with ${head}: ${stat.stderr.trim().split("\n")[0] ?? "git failed"}`, { hint: "pass --base with a branch that exists, for example --base origin/main" });
|
|
69660
70039
|
const files = [];
|
|
69661
70040
|
for (const entry of stat.stdout.split("\0")) {
|
|
69662
70041
|
const match = /^(\d+|-)\t(\d+|-)\t(.+)$/s.exec(entry);
|
|
@@ -69664,12 +70043,12 @@ async function snapshotOf(inv, head, base4) {
|
|
|
69664
70043
|
files.push({ path: match[3], status: "modified", additions: match[1] === "-" ? 0 : Number(match[1]), deletions: match[2] === "-" ? 0 : Number(match[2]) });
|
|
69665
70044
|
}
|
|
69666
70045
|
for (const file2 of files.slice(0, MAX_PATCH_FILES)) {
|
|
69667
|
-
const patch = await git4(inv.deps, ["diff", "--unified=2", `${
|
|
70046
|
+
const patch = await git4(inv.deps, ["diff", "--unified=2", `${base5}...${head}`, "--", file2.path]);
|
|
69668
70047
|
if (patch.code === 0 && patch.stdout !== "") file2.patch = patch.stdout.slice(0, MAX_PATCH_CHARS);
|
|
69669
70048
|
}
|
|
69670
70049
|
const project = await detectProject(inv.deps);
|
|
69671
70050
|
const repository = textFlag(inv, "repo") ?? (project.repository === void 0 ? `overlane/${project.name.replace(/[^A-Za-z0-9_.-]/g, "-").slice(0, 80) || "project"}` : `${project.repository.owner}/${project.repository.name}`);
|
|
69672
|
-
return { provider: project.provider === "github" ? "github" : "overlane", repository, headSha: sha.stdout.trim(), baseRef:
|
|
70051
|
+
return { provider: project.provider === "github" ? "github" : "overlane", repository, headSha: sha.stdout.trim(), baseRef: base5, files };
|
|
69673
70052
|
}
|
|
69674
70053
|
function numberOf(inv) {
|
|
69675
70054
|
const text = textFlag(inv, "number");
|
|
@@ -69721,11 +70100,11 @@ var prRouteCommand = defineCommand({
|
|
|
69721
70100
|
handler: async (inv) => {
|
|
69722
70101
|
const number4 = numberOf(inv);
|
|
69723
70102
|
const head = textFlag(inv, "head") ?? "HEAD";
|
|
69724
|
-
let
|
|
69725
|
-
if (
|
|
70103
|
+
let base5 = textFlag(inv, "base");
|
|
70104
|
+
if (base5 === void 0) base5 = (await git4(inv.deps, ["rev-parse", "--verify", "--quiet", "origin/main"])).code === 0 ? "origin/main" : "main";
|
|
69726
70105
|
const critical = textFlag(inv, "critical");
|
|
69727
70106
|
if (critical !== void 0 && !/^\d+$/.test(critical)) throw new UsageError("--critical is a whole number");
|
|
69728
|
-
const snapshot = await snapshotOf(inv, head,
|
|
70107
|
+
const snapshot = await snapshotOf(inv, head, base5);
|
|
69729
70108
|
const body2 = {
|
|
69730
70109
|
requestId: requestId12(),
|
|
69731
70110
|
pull: { provider: snapshot.provider, repository: snapshot.repository, number: number4, headSha: snapshot.headSha, title: textFlag(inv, "title") ?? `Pull request ${number4}`, body: "", author: textFlag(inv, "author") ?? "unknown", fork: boolFlag(inv, "fork"), files: snapshot.files },
|
|
@@ -70060,17 +70439,678 @@ var egressScanCommand = defineCommand({
|
|
|
70060
70439
|
});
|
|
70061
70440
|
var egressCommands = [egressPolicyShowCommand, egressPolicySetCommand, egressCheckCommand, egressEventsCommand, egressGrantCommand, egressGrantsCommand, egressRevokeCommand, egressScanCommand];
|
|
70062
70441
|
|
|
70442
|
+
// ../cli/src/commands/enterprise.ts
|
|
70443
|
+
init_src();
|
|
70444
|
+
init_zod();
|
|
70445
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "node:fs";
|
|
70446
|
+
import { resolve as resolve13 } from "node:path";
|
|
70447
|
+
var common20 = { needsAuth: true, needsNetwork: true };
|
|
70448
|
+
async function connected9(inv) {
|
|
70449
|
+
const project = await connectedProject(inv.deps, "enterprise");
|
|
70450
|
+
return { call: serviceCall(inv.deps, project.serviceUrl, project.token), tenantId: project.binding.tenantId };
|
|
70451
|
+
}
|
|
70452
|
+
async function planned9(inv, method, path, body2, note) {
|
|
70453
|
+
const project = await offlineProject(inv.deps, "enterprise");
|
|
70454
|
+
return planOutcome(inv.deps, dryRunPlan({ service: project.serviceUrl, requests: [{ method, path: path(project.binding.tenantId), ...body2 === void 0 ? {} : { body: body2 }, ...note === void 0 ? {} : { note } }] }));
|
|
70455
|
+
}
|
|
70456
|
+
async function secretValue2(inv, envFlag) {
|
|
70457
|
+
const name2 = textFlag(inv, envFlag);
|
|
70458
|
+
if (name2 !== void 0) {
|
|
70459
|
+
const value = inv.deps.env[name2];
|
|
70460
|
+
if (value === void 0 || value === "") throw new UsageError(`${name2} is not set`, { hint: `export ${name2}=... then run the command again` });
|
|
70461
|
+
return value;
|
|
70462
|
+
}
|
|
70463
|
+
if (inv.deps.stdin !== void 0 && !inv.deps.stdin.isTTY) {
|
|
70464
|
+
const text = (await inv.deps.stdin.read()).trim();
|
|
70465
|
+
if (text !== "") return text;
|
|
70466
|
+
}
|
|
70467
|
+
throw new UsageError("give the key through --value-env NAME or on standard input; it is never an argument", { hint: "overlane enterprise keys add --alias team-anthropic --provider anthropic --value-env PROVIDER_KEY" });
|
|
70468
|
+
}
|
|
70469
|
+
var enterpriseStatusCommand = defineCommand({
|
|
70470
|
+
path: ["enterprise", "status"],
|
|
70471
|
+
summary: "Show which enterprise features this team's plan includes",
|
|
70472
|
+
description: "Lists single sign-on, directory sync, audit export, SIEM stream, data region, bring-your-own-key, retention, policy as code and the MCP allowlist, each as included or not. All are Business and above.",
|
|
70473
|
+
examples: ["overlane enterprise status", "overlane enterprise status --json"],
|
|
70474
|
+
effect: "read",
|
|
70475
|
+
...common20,
|
|
70476
|
+
keywords: ["enterprise", "sso", "plan features", "what does my plan include"],
|
|
70477
|
+
result: EnterpriseEntitlements,
|
|
70478
|
+
text: (d) => [`plan: ${d.plan}`, ...Object.entries(d.features).map(([name2, on]) => `${on ? "included " : "not included"} ${name2}`)],
|
|
70479
|
+
handler: async (inv) => {
|
|
70480
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70481
|
+
return { data: await call2(EnterpriseEntitlements, "GET", enterprisePaths.entitlements(tenantId)) };
|
|
70482
|
+
}
|
|
70483
|
+
});
|
|
70484
|
+
var enterpriseSsoLinkCommand = defineCommand({
|
|
70485
|
+
path: ["enterprise", "sso", "link"],
|
|
70486
|
+
summary: "Print a short-lived link to the identity provider's hosted setup portal",
|
|
70487
|
+
description: "Issues a setup link for single sign-on (SAML or OpenID Connect) or for directory sync (SCIM). The link expires in minutes and is the credential: open it yourself or hand it to the person who administers the identity provider. Issuing a link is recorded in the audit log.",
|
|
70488
|
+
flags: [{ name: "intent", type: "string", enum: ["sso", "dsync"], default: "sso", value: "INTENT", description: "sso (default) or dsync for the directory" }],
|
|
70489
|
+
examples: ["overlane enterprise sso link", "overlane enterprise sso link --intent dsync"],
|
|
70490
|
+
effect: "write",
|
|
70491
|
+
...common20,
|
|
70492
|
+
keywords: ["saml", "oidc", "scim", "directory sync", "admin portal", "set up sso"],
|
|
70493
|
+
result: withDryRun(PortalLink),
|
|
70494
|
+
text: (d) => "url" in d ? [`open: ${d.url}`, `expires: ${d.expiresAt}`] : [],
|
|
70495
|
+
handler: async (inv) => {
|
|
70496
|
+
const intent = textFlag(inv, "intent") ?? "sso";
|
|
70497
|
+
if (inv.dryRun) return planned9(inv, "POST", enterprisePaths.portalLink, { intent }, "returns a short-lived link");
|
|
70498
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70499
|
+
return { data: await call2(PortalLink, "POST", enterprisePaths.portalLink(tenantId), { intent }) };
|
|
70500
|
+
}
|
|
70501
|
+
});
|
|
70502
|
+
var enterpriseSyncCommand = defineCommand({
|
|
70503
|
+
path: ["enterprise", "sso", "sync"],
|
|
70504
|
+
summary: "Sync the directory now: apply group roles and deprovision removed people",
|
|
70505
|
+
description: "Reads the directory and applies it. A person marked inactive loses access, their agent access ends and their leases are released. The same sync runs every five minutes on its own; the report says how long each removal took against the five-minute deadline.",
|
|
70506
|
+
examples: ["overlane enterprise sso sync"],
|
|
70507
|
+
effect: "write",
|
|
70508
|
+
...common20,
|
|
70509
|
+
keywords: ["scim sync", "deprovision", "directory"],
|
|
70510
|
+
result: withDryRun(DirectorySyncReport),
|
|
70511
|
+
text: (d) => "syncedAt" in d ? [`synced ${d.syncedAt}: ${d.rolesChanged} role changes, ${d.deprovisioned} removed${d.withinDeadline ? "" : " (some later than five minutes)"}`] : [],
|
|
70512
|
+
handler: async (inv) => {
|
|
70513
|
+
if (inv.dryRun) return planned9(inv, "POST", enterprisePaths.syncDirectory, {});
|
|
70514
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70515
|
+
return { data: await call2(DirectorySyncReport, "POST", enterprisePaths.syncDirectory(tenantId), {}) };
|
|
70516
|
+
}
|
|
70517
|
+
});
|
|
70518
|
+
var ExportResult = external_exports.object({ file: external_exports.string(), manifestFile: external_exports.string(), manifest: AuditExportManifest }).strict();
|
|
70519
|
+
var enterpriseAuditExportCommand = defineCommand({
|
|
70520
|
+
path: ["enterprise", "audit", "export"],
|
|
70521
|
+
summary: "Export the tamper-evident audit log as CSV, with a manifest, to files",
|
|
70522
|
+
description: "Writes the whole log as CSV (every row with the hashes that chain it) and a manifest with the row count and the head hash. Exporting is itself recorded in the audit log. Check the files later with `overlane enterprise audit verify`.",
|
|
70523
|
+
flags: [{ name: "out", type: "string", default: "audit.csv", value: "FILE", description: "Where to write the CSV (default audit.csv); the manifest goes beside it as FILE.manifest.json" }],
|
|
70524
|
+
examples: ["overlane enterprise audit export --out audit-2026-10.csv"],
|
|
70525
|
+
effect: "write",
|
|
70526
|
+
...common20,
|
|
70527
|
+
keywords: ["audit csv", "export audit log", "compliance export", "siem file"],
|
|
70528
|
+
result: withDryRun(ExportResult),
|
|
70529
|
+
text: (d) => "manifest" in d ? [`wrote ${d.manifest.count} rows to ${d.file}`, `manifest: ${d.manifestFile}`, `head: ${d.manifest.head ?? "none"}`] : [],
|
|
70530
|
+
handler: async (inv) => {
|
|
70531
|
+
if (inv.dryRun) return planned9(inv, "POST", enterprisePaths.auditExports, {}, "writes the CSV and the manifest to local files");
|
|
70532
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70533
|
+
const exported = await call2(AuditExport, "POST", enterprisePaths.auditExports(tenantId), {});
|
|
70534
|
+
const file2 = resolve13(inv.deps.paths.cwd, textFlag(inv, "out") ?? "audit.csv");
|
|
70535
|
+
const manifestFile = `${file2}.manifest.json`;
|
|
70536
|
+
writeFileSync9(file2, exported.csv);
|
|
70537
|
+
writeFileSync9(manifestFile, `${JSON.stringify(exported.manifest, null, 2)}
|
|
70538
|
+
`);
|
|
70539
|
+
return { data: { file: file2, manifestFile, manifest: exported.manifest } };
|
|
70540
|
+
}
|
|
70541
|
+
});
|
|
70542
|
+
var VerifyResult = external_exports.object({ ok: external_exports.boolean(), tenantId: external_exports.string(), checked: external_exports.number(), head: external_exports.string().nullable(), manifestOk: external_exports.boolean(), brokenAt: external_exports.number().optional(), reason: external_exports.string().optional() }).strict();
|
|
70543
|
+
var enterpriseAuditVerifyCommand = defineCommand({
|
|
70544
|
+
path: ["enterprise", "audit", "verify"],
|
|
70545
|
+
summary: "Check an exported audit CSV offline; exits 1 if any row was altered, removed or reordered",
|
|
70546
|
+
description: "Re-computes the hash chain of the file and compares the row count, last sequence and head hash with the manifest, so a removed newest row is found as well. Needs no network and no account.",
|
|
70547
|
+
args: [{ name: "file", required: true, description: "The exported CSV" }],
|
|
70548
|
+
flags: [{ name: "manifest", type: "string", value: "FILE", description: "The manifest (default FILE.manifest.json)" }],
|
|
70549
|
+
examples: ["overlane enterprise audit verify audit.csv"],
|
|
70550
|
+
effect: "read",
|
|
70551
|
+
needsAuth: false,
|
|
70552
|
+
needsNetwork: false,
|
|
70553
|
+
keywords: ["verify audit export", "tamper check", "audit chain"],
|
|
70554
|
+
result: VerifyResult,
|
|
70555
|
+
text: (d) => [d.ok ? `OK: ${d.checked} rows verified, head ${d.head ?? "none"}` : `FAILED${d.brokenAt === void 0 ? "" : ` at row ${d.brokenAt}`}${d.reason === void 0 ? "" : ` (${d.reason})`}${d.manifestOk ? "" : "; the manifest does not match the file"}`],
|
|
70556
|
+
handler: async (inv) => {
|
|
70557
|
+
const file2 = inv.positionals[0];
|
|
70558
|
+
if (file2 === void 0) throw new UsageError("give the exported CSV", { hint: "overlane enterprise audit verify audit.csv" });
|
|
70559
|
+
const path = resolve13(inv.deps.paths.cwd, file2);
|
|
70560
|
+
const manifestPath = resolve13(inv.deps.paths.cwd, textFlag(inv, "manifest") ?? `${file2}.manifest.json`);
|
|
70561
|
+
let manifest;
|
|
70562
|
+
let csv;
|
|
70563
|
+
try {
|
|
70564
|
+
csv = readFileSync14(path, "utf8");
|
|
70565
|
+
manifest = AuditExportManifest.parse(JSON.parse(readFileSync14(manifestPath, "utf8")));
|
|
70566
|
+
} catch {
|
|
70567
|
+
throw new UsageError(`could not read ${file2} and its manifest`, { hint: "overlane enterprise audit export --out audit.csv" });
|
|
70568
|
+
}
|
|
70569
|
+
const result = verifyAuditExport(manifest.tenantId, csv, manifest);
|
|
70570
|
+
const data = { ok: result.ok, tenantId: result.tenantId, checked: result.checked, head: result.head, manifestOk: result.manifestOk, ...result.brokenAt === void 0 ? {} : { brokenAt: result.brokenAt }, ...result.reason === void 0 ? {} : { reason: result.reason } };
|
|
70571
|
+
return result.ok ? { data } : { data, exit: EXIT.failure, error: new CliError("the audit export failed verification", { code: "audit_tampered", exit: EXIT.failure, quiet: true }) };
|
|
70572
|
+
}
|
|
70573
|
+
});
|
|
70574
|
+
var StreamAdded = external_exports.object({ target: AuditStreamTarget }).strict();
|
|
70575
|
+
var enterpriseStreamAddCommand = defineCommand({
|
|
70576
|
+
path: ["enterprise", "audit", "stream", "add"],
|
|
70577
|
+
summary: "Add a SIEM stream target: an https address and a signing secret you choose",
|
|
70578
|
+
description: "Deliveries are signed with HMAC-SHA-256 over `timestamp.body` using your secret and carry an idempotency key, so your SIEM can de-duplicate the at-least-once delivery. The secret is read from an environment variable or standard input, stored encrypted and never shown again.",
|
|
70579
|
+
flags: [
|
|
70580
|
+
{ name: "url", type: "string", required: true, value: "URL", description: "The https address that receives deliveries" },
|
|
70581
|
+
{ name: "secret-env", type: "string", value: "NAME", description: "Name of the environment variable holding the signing secret (16 characters or more)" }
|
|
70582
|
+
],
|
|
70583
|
+
examples: ["overlane enterprise audit stream add --url https://siem.example.com/ingest --secret-env SIEM_SECRET"],
|
|
70584
|
+
effect: "write",
|
|
70585
|
+
...common20,
|
|
70586
|
+
keywords: ["siem", "splunk", "stream audit", "log forwarding"],
|
|
70587
|
+
result: withDryRun(StreamAdded),
|
|
70588
|
+
text: (d) => "target" in d ? [`target ${d.target.targetId} -> ${d.target.url}`, "The signing secret is stored encrypted and will not be shown again."] : [],
|
|
70589
|
+
handler: async (inv) => {
|
|
70590
|
+
const url2 = textFlag(inv, "url");
|
|
70591
|
+
if (url2 === void 0) throw new UsageError("add needs --url", { hint: "overlane enterprise audit stream add --url https://siem.example.com/ingest --secret-env SIEM_SECRET" });
|
|
70592
|
+
if (inv.dryRun) return planned9(inv, "POST", enterprisePaths.streamTargets, { url: url2, signingSecret: "(read from the environment; not shown)" });
|
|
70593
|
+
const signingSecret = await secretValue2(inv, "secret-env");
|
|
70594
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70595
|
+
return { data: await call2(StreamAdded, "POST", enterprisePaths.streamTargets(tenantId), { url: url2, signingSecret }) };
|
|
70596
|
+
}
|
|
70597
|
+
});
|
|
70598
|
+
var ResidencyShow = external_exports.object({ policy: ResidencyPolicy, stores: StoreLocationReport.nullable() }).strict();
|
|
70599
|
+
var enterpriseRegionShowCommand = defineCommand({
|
|
70600
|
+
path: ["enterprise", "region", "show"],
|
|
70601
|
+
summary: "Show the data region and where each store holds the team's data",
|
|
70602
|
+
description: "Prints the pinned region, the supported regions and the store-location check: D1, R2, KV, Durable Objects, vectors, logs and backups, each with the region it holds.",
|
|
70603
|
+
examples: ["overlane enterprise region show"],
|
|
70604
|
+
effect: "read",
|
|
70605
|
+
...common20,
|
|
70606
|
+
keywords: ["data residency", "region", "where is my data"],
|
|
70607
|
+
result: ResidencyShow,
|
|
70608
|
+
text: (d) => [`region: ${d.policy.region} (supported: ${d.policy.supportedRegions.join(", ")})`, ...d.stores === null ? [] : [d.stores.ok ? "every store holds the data in the region" : `violations: ${d.stores.violations.join("; ")}`, ...d.stores.stores.map((s) => `${s.store.padEnd(16)} ${s.region}`)]],
|
|
70609
|
+
handler: async (inv) => {
|
|
70610
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70611
|
+
const policy = await call2(ResidencyPolicy, "GET", enterprisePaths.residency(tenantId));
|
|
70612
|
+
const stores = policy.pinnedAt === null ? null : await call2(StoreLocationReport, "GET", enterprisePaths.storeLocations(tenantId));
|
|
70613
|
+
return { data: { policy, stores } };
|
|
70614
|
+
}
|
|
70615
|
+
});
|
|
70616
|
+
var enterpriseRegionSetCommand = defineCommand({
|
|
70617
|
+
path: ["enterprise", "region", "set"],
|
|
70618
|
+
summary: "Pin the team's data to a region, or request a migration to another one",
|
|
70619
|
+
description: "The first call pins the region (the choice made at team creation). Once pinned, a change needs --reason and is an audited migration; data is never placed outside the chosen region. A region the stores cannot all hold is refused with the supported list.",
|
|
70620
|
+
flags: [
|
|
70621
|
+
{ name: "region", type: "string", required: true, enum: ["global", "eu", "us"], value: "REGION", description: "global (no pin), eu or us" },
|
|
70622
|
+
{ name: "reason", type: "string", value: "TEXT", description: "Why the region changes (needed when the team is already pinned)" }
|
|
70623
|
+
],
|
|
70624
|
+
examples: ["overlane enterprise region set --region eu", "overlane enterprise region set --region us --reason 'customer request'"],
|
|
70625
|
+
effect: "write",
|
|
70626
|
+
...common20,
|
|
70627
|
+
keywords: ["pin region", "move region", "eu data", "residency migration"],
|
|
70628
|
+
result: withDryRun(ResidencyPolicy),
|
|
70629
|
+
text: (d) => "region" in d ? [`region: ${d.region}${d.pendingMigration === null ? "" : ` last migration ${d.pendingMigration.from} to ${d.pendingMigration.to}: ${d.pendingMigration.status}`}`] : [],
|
|
70630
|
+
handler: async (inv) => {
|
|
70631
|
+
const region = textFlag(inv, "region");
|
|
70632
|
+
if (region === void 0) throw new UsageError("set needs --region", { hint: "overlane enterprise region set --region eu" });
|
|
70633
|
+
const reason = textFlag(inv, "reason");
|
|
70634
|
+
if (inv.dryRun) return planned9(inv, reason === void 0 ? "PUT" : "POST", (t2) => reason === void 0 ? enterprisePaths.residency(t2) : enterprisePaths.residencyMigrations(t2), reason === void 0 ? { region } : { to: region, reason });
|
|
70635
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70636
|
+
const current2 = await call2(ResidencyPolicy, "GET", enterprisePaths.residency(tenantId));
|
|
70637
|
+
if (current2.pinnedAt === null) return { data: await call2(ResidencyPolicy, "PUT", enterprisePaths.residency(tenantId), { region }) };
|
|
70638
|
+
if (reason === void 0) throw new UsageError("the team is already pinned; a change is a migration and needs --reason", { hint: `overlane enterprise region set --region ${region} --reason 'why'` });
|
|
70639
|
+
return { data: await call2(ResidencyPolicy, "POST", enterprisePaths.residencyMigrations(tenantId), { to: region, reason }) };
|
|
70640
|
+
}
|
|
70641
|
+
});
|
|
70642
|
+
var KeyList = external_exports.object({ tenantId: external_exports.string(), keys: external_exports.array(ByokKey) }).strict();
|
|
70643
|
+
var KeyOne = external_exports.object({ key: ByokKey }).strict();
|
|
70644
|
+
var KeyTested = external_exports.object({ result: ByokTestResult, key: ByokKey }).strict();
|
|
70645
|
+
var keyLine = (k) => `${k.alias.padEnd(24)} ${k.provider.padEnd(10)} ${k.status.padEnd(9)} v${k.version} tested ${k.lastTestedAt ?? "never"}`;
|
|
70646
|
+
var enterpriseKeysListCommand = defineCommand({
|
|
70647
|
+
path: ["enterprise", "keys", "list"],
|
|
70648
|
+
summary: "List bring-your-own inference keys by alias, provider and status",
|
|
70649
|
+
description: "Shows aliases and states only. A key value is never shown after it is added.",
|
|
70650
|
+
examples: ["overlane enterprise keys list"],
|
|
70651
|
+
effect: "read",
|
|
70652
|
+
...common20,
|
|
70653
|
+
keywords: ["byok", "inference keys", "api keys"],
|
|
70654
|
+
result: KeyList,
|
|
70655
|
+
text: (d) => d.keys.length === 0 ? ["No keys. Inference runs on the hosted models."] : d.keys.map(keyLine),
|
|
70656
|
+
handler: async (inv) => {
|
|
70657
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70658
|
+
return { data: await call2(KeyList, "GET", enterprisePaths.byokKeys(tenantId)) };
|
|
70659
|
+
}
|
|
70660
|
+
});
|
|
70661
|
+
var enterpriseKeysAddCommand = defineCommand({
|
|
70662
|
+
path: ["enterprise", "keys", "add"],
|
|
70663
|
+
summary: "Add an inference key under an alias; the value comes from the environment or stdin",
|
|
70664
|
+
description: "The value is read from the variable named by --value-env, or from standard input, sent once and stored encrypted. It is never an argument, never printed and never shown again. Test it with `overlane enterprise keys test`; inference uses the alias.",
|
|
70665
|
+
flags: [
|
|
70666
|
+
{ name: "alias", type: "string", required: true, value: "ALIAS", description: "Lowercase letters, digits and hyphens" },
|
|
70667
|
+
{ name: "provider", type: "string", required: true, enum: ["anthropic", "openai", "google"], value: "PROVIDER", description: "The key's provider" },
|
|
70668
|
+
{ name: "value-env", type: "string", value: "NAME", description: "Name of the environment variable holding the key (default: read standard input)" }
|
|
70669
|
+
],
|
|
70670
|
+
examples: ["overlane enterprise keys add --alias team-anthropic --provider anthropic --value-env PROVIDER_KEY", "overlane enterprise keys add --alias team-anthropic --provider anthropic < key.txt"],
|
|
70671
|
+
effect: "write",
|
|
70672
|
+
...common20,
|
|
70673
|
+
keywords: ["add byok key", "bring your own key", "provider key"],
|
|
70674
|
+
result: withDryRun(KeyOne),
|
|
70675
|
+
text: (d) => "key" in d ? [keyLine(d.key), "The value is stored encrypted and will not be shown again."] : [],
|
|
70676
|
+
handler: async (inv) => {
|
|
70677
|
+
const alias = textFlag(inv, "alias");
|
|
70678
|
+
const provider = textFlag(inv, "provider");
|
|
70679
|
+
if (alias === void 0 || provider === void 0) throw new UsageError("add needs --alias and --provider", { hint: "overlane enterprise keys add --alias team-anthropic --provider anthropic --value-env PROVIDER_KEY" });
|
|
70680
|
+
if (inv.dryRun) return planned9(inv, "POST", enterprisePaths.byokKeys, { alias, provider, value: "(read from the environment; not shown)" });
|
|
70681
|
+
const value = await secretValue2(inv, "value-env");
|
|
70682
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70683
|
+
return { data: await call2(KeyOne, "POST", enterprisePaths.byokKeys(tenantId), { alias, provider, value }) };
|
|
70684
|
+
}
|
|
70685
|
+
});
|
|
70686
|
+
var aliasArg = [{ name: "alias", required: false, description: "The key's alias (required)" }];
|
|
70687
|
+
var aliasOf = (inv) => {
|
|
70688
|
+
const alias = inv.positionals[0];
|
|
70689
|
+
if (alias === void 0) throw new UsageError("give the key's alias", { hint: "overlane enterprise keys test team-anthropic" });
|
|
70690
|
+
return alias;
|
|
70691
|
+
};
|
|
70692
|
+
var enterpriseKeysTestCommand = defineCommand({
|
|
70693
|
+
path: ["enterprise", "keys", "test"],
|
|
70694
|
+
summary: "Test a key against its provider; a key that fails is not used for inference",
|
|
70695
|
+
description: "Makes a minimal call to the provider with the stored key and records the result. The key is not printed.",
|
|
70696
|
+
args: aliasArg,
|
|
70697
|
+
examples: ["overlane enterprise keys test team-anthropic"],
|
|
70698
|
+
effect: "write",
|
|
70699
|
+
...common20,
|
|
70700
|
+
keywords: ["check key", "validate key"],
|
|
70701
|
+
result: withDryRun(KeyTested),
|
|
70702
|
+
text: (d) => "result" in d ? [`${d.result.ok ? "passed" : "failed"}: ${d.result.detail}`, keyLine(d.key)] : [],
|
|
70703
|
+
handler: async (inv) => {
|
|
70704
|
+
const alias = aliasOf(inv);
|
|
70705
|
+
if (inv.dryRun) return planned9(inv, "POST", (t2) => enterprisePaths.byokTest(t2, alias), {});
|
|
70706
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70707
|
+
const out2 = await call2(KeyTested, "POST", enterprisePaths.byokTest(tenantId, alias), {});
|
|
70708
|
+
return out2.result.ok ? { data: out2 } : { data: out2, exit: EXIT.failure, error: new CliError(`the provider refused ${alias}`, { code: "byok_test_failed", exit: EXIT.failure, quiet: true }) };
|
|
70709
|
+
}
|
|
70710
|
+
});
|
|
70711
|
+
var enterpriseKeysRotateCommand = defineCommand({
|
|
70712
|
+
path: ["enterprise", "keys", "rotate"],
|
|
70713
|
+
summary: "Replace a key's value under the same alias; the old value stays if the provider refuses the new one",
|
|
70714
|
+
description: "The new value is read like `keys add` reads it, checked with the provider first, then stored encrypted. The alias and everything that uses it stay the same.",
|
|
70715
|
+
args: aliasArg,
|
|
70716
|
+
flags: [{ name: "value-env", type: "string", value: "NAME", description: "Name of the environment variable holding the new key (default: read standard input)" }],
|
|
70717
|
+
examples: ["overlane enterprise keys rotate team-anthropic --value-env NEW_PROVIDER_KEY"],
|
|
70718
|
+
effect: "write",
|
|
70719
|
+
...common20,
|
|
70720
|
+
keywords: ["rotate key", "replace key"],
|
|
70721
|
+
result: withDryRun(KeyOne),
|
|
70722
|
+
text: (d) => "key" in d ? [keyLine(d.key)] : [],
|
|
70723
|
+
handler: async (inv) => {
|
|
70724
|
+
const alias = aliasOf(inv);
|
|
70725
|
+
if (inv.dryRun) return planned9(inv, "POST", (t2) => enterprisePaths.byokRotate(t2, alias), { value: "(read from the environment; not shown)" });
|
|
70726
|
+
const value = await secretValue2(inv, "value-env");
|
|
70727
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70728
|
+
return { data: await call2(KeyOne, "POST", enterprisePaths.byokRotate(tenantId, alias), { value }) };
|
|
70729
|
+
}
|
|
70730
|
+
});
|
|
70731
|
+
var enterpriseKeysRevokeCommand = defineCommand({
|
|
70732
|
+
path: ["enterprise", "keys", "revoke"],
|
|
70733
|
+
summary: "Disable a key for good: the stored value is deleted and inference by that alias is refused",
|
|
70734
|
+
description: "This cannot be undone; add a new key to use the provider again. Doing it twice changes nothing.",
|
|
70735
|
+
args: aliasArg,
|
|
70736
|
+
examples: ["overlane enterprise keys revoke team-anthropic"],
|
|
70737
|
+
effect: "destructive",
|
|
70738
|
+
...common20,
|
|
70739
|
+
keywords: ["delete key", "disable key"],
|
|
70740
|
+
result: withDryRun(KeyOne),
|
|
70741
|
+
text: (d) => "key" in d ? [keyLine(d.key)] : [],
|
|
70742
|
+
handler: async (inv) => {
|
|
70743
|
+
const alias = aliasOf(inv);
|
|
70744
|
+
if (inv.dryRun) return planned9(inv, "DELETE", (t2) => enterprisePaths.byokKey(t2, alias));
|
|
70745
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70746
|
+
return { data: await call2(KeyOne, "DELETE", enterprisePaths.byokKey(tenantId, alias)) };
|
|
70747
|
+
}
|
|
70748
|
+
});
|
|
70749
|
+
var enterpriseRetentionShowCommand = defineCommand({
|
|
70750
|
+
path: ["enterprise", "retention", "show"],
|
|
70751
|
+
summary: "Show the retention rules per data class",
|
|
70752
|
+
description: "Classes: memory, derived_data, agent_conversations, ci_artifacts and run_logs. The audit log is exported, never purged by age.",
|
|
70753
|
+
examples: ["overlane enterprise retention show"],
|
|
70754
|
+
effect: "read",
|
|
70755
|
+
...common20,
|
|
70756
|
+
keywords: ["retention policy", "how long is data kept"],
|
|
70757
|
+
result: EnterpriseRetentionPolicy,
|
|
70758
|
+
text: (d) => d.rules.length === 0 ? ["No rules: nothing is purged by age."] : d.rules.map((r) => `${r.dataClass.padEnd(20)} ${r.days} days`),
|
|
70759
|
+
handler: async (inv) => {
|
|
70760
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70761
|
+
return { data: await call2(EnterpriseRetentionPolicy, "GET", enterprisePaths.retention(tenantId)) };
|
|
70762
|
+
}
|
|
70763
|
+
});
|
|
70764
|
+
var enterpriseRetentionSetCommand = defineCommand({
|
|
70765
|
+
path: ["enterprise", "retention", "set"],
|
|
70766
|
+
summary: "Set retention rules, replacing the current ones",
|
|
70767
|
+
description: "Each --rule is CLASS=DAYS, for example memory=365. Records older than the days are purged on schedule and reported. Changing retention is a policy change.",
|
|
70768
|
+
flags: [{ name: "rule", type: "string", multiple: true, required: true, value: "CLASS=DAYS", description: "A rule; repeat for more" }],
|
|
70769
|
+
examples: ["overlane enterprise retention set --rule memory=365 --rule run_logs=90"],
|
|
70770
|
+
effect: "write",
|
|
70771
|
+
...common20,
|
|
70772
|
+
keywords: ["set retention", "purge after days"],
|
|
70773
|
+
result: withDryRun(EnterpriseRetentionPolicy),
|
|
70774
|
+
text: (d) => "rules" in d ? d.rules.map((r) => `${r.dataClass.padEnd(20)} ${r.days} days`) : [],
|
|
70775
|
+
handler: async (inv) => {
|
|
70776
|
+
const raw = inv.values["rule"];
|
|
70777
|
+
const texts = (Array.isArray(raw) ? raw : raw === void 0 ? [] : [raw]).filter((v) => typeof v === "string");
|
|
70778
|
+
const rules = texts.map((text) => {
|
|
70779
|
+
const [dataClass, days] = text.split("=");
|
|
70780
|
+
if (dataClass === void 0 || days === void 0 || !/^\d{1,4}$/.test(days)) throw new UsageError(`${text}: use CLASS=DAYS, for example memory=365`);
|
|
70781
|
+
return { dataClass, days: Number(days) };
|
|
70782
|
+
});
|
|
70783
|
+
if (inv.dryRun) return planned9(inv, "PUT", enterprisePaths.retention, { rules });
|
|
70784
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70785
|
+
return { data: await call2(EnterpriseRetentionPolicy, "PUT", enterprisePaths.retention(tenantId), { rules }) };
|
|
70786
|
+
}
|
|
70787
|
+
});
|
|
70788
|
+
var enterprisePurgeCommand = defineCommand({
|
|
70789
|
+
path: ["enterprise", "retention", "purge"],
|
|
70790
|
+
summary: "Run the retention purge now and print the report",
|
|
70791
|
+
description: "Removes records older than each class's days, and derived text and vectors whose item is gone. Idempotent. Purging is an irreversible deletion.",
|
|
70792
|
+
examples: ["overlane enterprise retention purge"],
|
|
70793
|
+
effect: "destructive",
|
|
70794
|
+
...common20,
|
|
70795
|
+
keywords: ["purge now", "delete old data"],
|
|
70796
|
+
result: withDryRun(PurgeReport),
|
|
70797
|
+
text: (d) => "lines" in d ? [`purge ${d.purgeId}: ${d.totalPurged} records removed`, ...d.lines.map((l) => `${l.dataClass.padEnd(20)} ${l.store.padEnd(8)} ${l.purged}`)] : [],
|
|
70798
|
+
handler: async (inv) => {
|
|
70799
|
+
if (inv.dryRun) return planned9(inv, "POST", enterprisePaths.purge, {});
|
|
70800
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70801
|
+
return { data: await call2(PurgeReport, "POST", enterprisePaths.purge(tenantId), {}) };
|
|
70802
|
+
}
|
|
70803
|
+
});
|
|
70804
|
+
var DataFlags = [
|
|
70805
|
+
{ name: "scope", type: "string", enum: ["tenant", "project", "user"], default: "tenant", value: "SCOPE", description: "tenant (default), project or user" },
|
|
70806
|
+
{ name: "subject", type: "string", value: "ID", description: "The project or user ID for a project or user scope" }
|
|
70807
|
+
];
|
|
70808
|
+
var dataBody = (inv) => {
|
|
70809
|
+
const scope = textFlag(inv, "scope") ?? "tenant";
|
|
70810
|
+
const subject = textFlag(inv, "subject");
|
|
70811
|
+
if (scope !== "tenant" && subject === void 0) throw new UsageError(`a ${scope} scope needs --subject`, { hint: `overlane enterprise data export --scope ${scope} --subject ID` });
|
|
70812
|
+
return { scope, ...subject === void 0 ? {} : { subjectId: subject } };
|
|
70813
|
+
};
|
|
70814
|
+
var DataExported = external_exports.object({ file: external_exports.string(), totalRows: external_exports.number(), stores: DataExportReport.shape.stores }).strict();
|
|
70815
|
+
var enterpriseDataExportCommand = defineCommand({
|
|
70816
|
+
path: ["enterprise", "data", "export"],
|
|
70817
|
+
summary: "Export the team's own data (or one project's or user's) as NDJSON",
|
|
70818
|
+
description: "Writes memory, derived text, vectors (metadata only), conversations, CI records, logs and, for the tenant scope, the audit log, one JSON record per line. Open to every plan.",
|
|
70819
|
+
flags: [...DataFlags, { name: "out", type: "string", default: "export.ndjson", value: "FILE", description: "Where to write the file" }],
|
|
70820
|
+
examples: ["overlane enterprise data export --out export.ndjson", "overlane enterprise data export --scope project --subject prj-1"],
|
|
70821
|
+
effect: "write",
|
|
70822
|
+
...common20,
|
|
70823
|
+
keywords: ["export my data", "data portability", "gdpr export"],
|
|
70824
|
+
result: withDryRun(DataExported),
|
|
70825
|
+
text: (d) => "file" in d ? [`wrote ${d.totalRows} records to ${d.file}`] : [],
|
|
70826
|
+
handler: async (inv) => {
|
|
70827
|
+
const body2 = dataBody(inv);
|
|
70828
|
+
if (inv.dryRun) return planned9(inv, "POST", enterprisePaths.dataExport, body2, "writes a local file");
|
|
70829
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70830
|
+
const report2 = await call2(DataExportReport, "POST", enterprisePaths.dataExport(tenantId), body2);
|
|
70831
|
+
const file2 = resolve13(inv.deps.paths.cwd, textFlag(inv, "out") ?? "export.ndjson");
|
|
70832
|
+
writeFileSync9(file2, report2.ndjson);
|
|
70833
|
+
return { data: { file: file2, totalRows: report2.totalRows, stores: report2.stores } };
|
|
70834
|
+
}
|
|
70835
|
+
});
|
|
70836
|
+
var enterpriseDataDeleteCommand = defineCommand({
|
|
70837
|
+
path: ["enterprise", "data", "delete"],
|
|
70838
|
+
summary: "Delete the team's own data (or one project's or user's) from every store",
|
|
70839
|
+
description: "Removes records, derived text, vectors, logs and backup snapshots written by the service. Point-in-time database copies age out within 30 days, and the report states the date. The audit log keeps identifiers only, including this deletion. Irreversible: it needs --force without a terminal, and an agent needs an independent agent's approval.",
|
|
70840
|
+
flags: DataFlags,
|
|
70841
|
+
examples: ["overlane enterprise data delete --scope project --subject prj-1 --dry-run"],
|
|
70842
|
+
effect: "destructive",
|
|
70843
|
+
...common20,
|
|
70844
|
+
keywords: ["delete my data", "erase", "right to erasure"],
|
|
70845
|
+
result: withDryRun(DataDeletionReport),
|
|
70846
|
+
text: (d) => "backupsPurgedBy" in d ? [`deleted ${d.totalRows} records`, `backups are purged by ${d.backupsPurgedBy}`] : [],
|
|
70847
|
+
handler: async (inv) => {
|
|
70848
|
+
const body2 = dataBody(inv);
|
|
70849
|
+
if (inv.dryRun) return planned9(inv, "POST", enterprisePaths.dataDelete, body2, "deletes from every store");
|
|
70850
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70851
|
+
return { data: await call2(DataDeletionReport, "POST", enterprisePaths.dataDelete(tenantId), body2) };
|
|
70852
|
+
}
|
|
70853
|
+
});
|
|
70854
|
+
var SsoShow = external_exports.object({ identity: EnterpriseIdentityStatus, groups: GroupMappingSet }).strict();
|
|
70855
|
+
var enterpriseSsoShowCommand = defineCommand({
|
|
70856
|
+
path: ["enterprise", "sso", "show"],
|
|
70857
|
+
summary: "Show the single sign-on and directory state, and the group to role mappings",
|
|
70858
|
+
description: "Prints each connection's status (not set up, setup in progress, active, failed), the protocol and domains, when it was last tested, the directory's people and group counts, and the mappings with the highest role a group may grant.",
|
|
70859
|
+
examples: ["overlane enterprise sso show"],
|
|
70860
|
+
effect: "read",
|
|
70861
|
+
...common20,
|
|
70862
|
+
keywords: ["sso status", "scim status", "group mappings", "connection state"],
|
|
70863
|
+
result: SsoShow,
|
|
70864
|
+
text: (d) => [
|
|
70865
|
+
`sso: ${d.identity.sso.status}${d.identity.sso.protocol === null ? "" : ` (${d.identity.sso.protocol})`} last test ${d.identity.sso.lastTestedAt ?? "never"}`,
|
|
70866
|
+
`directory: ${d.identity.scim.status} ${d.identity.scim.userCount} people in ${d.identity.scim.groupCount} groups last sync ${d.identity.scim.lastSyncAt ?? "never"}`,
|
|
70867
|
+
`groups (cap ${d.groups.cap}): ${d.groups.mappings.length === 0 ? "none mapped" : d.groups.mappings.map((m) => `${m.groupName}=${m.role}`).join(", ")}`
|
|
70868
|
+
],
|
|
70869
|
+
handler: async (inv) => {
|
|
70870
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70871
|
+
return { data: { identity: await call2(EnterpriseIdentityStatus, "GET", enterprisePaths.identity(tenantId)), groups: await call2(GroupMappingSet, "GET", enterprisePaths.groupMappings(tenantId)) } };
|
|
70872
|
+
}
|
|
70873
|
+
});
|
|
70874
|
+
var enterpriseSsoTestCommand = defineCommand({
|
|
70875
|
+
path: ["enterprise", "sso", "test"],
|
|
70876
|
+
summary: "Test the single sign-on or directory connection end to end; exits 1 when it fails",
|
|
70877
|
+
description: "Asks the identity provider to check the connection (a metadata fetch for sign-on, a directory read for the directory) and records the result.",
|
|
70878
|
+
flags: [{ name: "intent", type: "string", enum: ["sso", "dsync"], default: "sso", value: "INTENT", description: "sso (default) or dsync for the directory" }],
|
|
70879
|
+
examples: ["overlane enterprise sso test", "overlane enterprise sso test --intent dsync"],
|
|
70880
|
+
effect: "write",
|
|
70881
|
+
...common20,
|
|
70882
|
+
keywords: ["test sso", "check connection", "verify scim"],
|
|
70883
|
+
result: withDryRun(TestConnectionResult),
|
|
70884
|
+
text: (d) => "ok" in d ? [`${d.ok ? "passed" : "failed"}: ${d.detail}`] : [],
|
|
70885
|
+
handler: async (inv) => {
|
|
70886
|
+
const intent = textFlag(inv, "intent") ?? "sso";
|
|
70887
|
+
if (inv.dryRun) return planned9(inv, "POST", enterprisePaths.testConnection, { intent });
|
|
70888
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70889
|
+
const result = await call2(TestConnectionResult, "POST", enterprisePaths.testConnection(tenantId), { intent });
|
|
70890
|
+
return result.ok ? { data: result } : { data: result, exit: EXIT.failure, error: new CliError(`the ${intent} connection failed its test`, { code: "connection_test_failed", exit: EXIT.failure, quiet: true }) };
|
|
70891
|
+
}
|
|
70892
|
+
});
|
|
70893
|
+
var enterpriseSsoGroupsSetCommand = defineCommand({
|
|
70894
|
+
path: ["enterprise", "sso", "groups", "set"],
|
|
70895
|
+
summary: "Replace the group to role mappings and the highest role a group may grant",
|
|
70896
|
+
description: "Each --map is GROUP=ROLE with ROLE viewer, member or admin. A person in several mapped groups gets the highest role, up to --cap (default admin). A mapping above the cap is refused, and the owner role cannot be mapped. Changing mappings is a policy change.",
|
|
70897
|
+
flags: [
|
|
70898
|
+
{ name: "map", type: "string", multiple: true, value: "GROUP=ROLE", description: "A mapping; repeat for more (none clears them)" },
|
|
70899
|
+
{ name: "cap", type: "string", enum: GROUP_ROLE_CAPS, default: "admin", value: "ROLE", description: "The highest role any group may grant" }
|
|
70900
|
+
],
|
|
70901
|
+
examples: ["overlane enterprise sso groups set --map Engineering=member --map Platform=admin --cap admin"],
|
|
70902
|
+
effect: "write",
|
|
70903
|
+
...common20,
|
|
70904
|
+
keywords: ["group mapping", "idp groups", "roles from groups"],
|
|
70905
|
+
result: withDryRun(GroupMappingSet),
|
|
70906
|
+
text: (d) => "cap" in d ? [`cap: ${d.cap}`, ...d.mappings.map((m) => `${m.groupName} -> ${m.role}`)] : [],
|
|
70907
|
+
handler: async (inv) => {
|
|
70908
|
+
const raw = inv.values["map"];
|
|
70909
|
+
const texts = (Array.isArray(raw) ? raw : raw === void 0 ? [] : [raw]).filter((v) => typeof v === "string");
|
|
70910
|
+
const mappings = texts.map((text) => {
|
|
70911
|
+
const at = text.lastIndexOf("=");
|
|
70912
|
+
const groupName = at < 1 ? "" : text.slice(0, at);
|
|
70913
|
+
const role = text.slice(at + 1);
|
|
70914
|
+
if (groupName === "" || !["viewer", "member", "admin"].includes(role)) throw new UsageError(`${text}: use GROUP=ROLE with ROLE viewer, member or admin`, { hint: "overlane enterprise sso groups set --map Engineering=member" });
|
|
70915
|
+
return { groupName, role };
|
|
70916
|
+
});
|
|
70917
|
+
const body2 = { cap: textFlag(inv, "cap") ?? "admin", mappings };
|
|
70918
|
+
if (inv.dryRun) return planned9(inv, "PUT", enterprisePaths.groupMappings, body2);
|
|
70919
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70920
|
+
return { data: await call2(GroupMappingSet, "PUT", enterprisePaths.groupMappings(tenantId), body2) };
|
|
70921
|
+
}
|
|
70922
|
+
});
|
|
70923
|
+
var enterpriseStreamListCommand = defineCommand({
|
|
70924
|
+
path: ["enterprise", "audit", "stream", "list"],
|
|
70925
|
+
summary: "List SIEM stream targets with their status and how far each has been delivered",
|
|
70926
|
+
description: "Shows each target's address, whether it is active, paused or failing, the newest audit row it has acknowledged and the last error. The signing secret is never shown.",
|
|
70927
|
+
examples: ["overlane enterprise audit stream list"],
|
|
70928
|
+
effect: "read",
|
|
70929
|
+
...common20,
|
|
70930
|
+
keywords: ["siem targets", "stream status", "log forwarding status"],
|
|
70931
|
+
result: AuditStreamTargetList,
|
|
70932
|
+
text: (d) => d.targets.length === 0 ? ["No stream targets."] : d.targets.map((t2) => `${t2.targetId} ${t2.status.padEnd(8)} ${t2.url} through row ${t2.deliveredThroughSeq}${t2.lastError === null ? "" : ` error: ${t2.lastError}`}`),
|
|
70933
|
+
handler: async (inv) => {
|
|
70934
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70935
|
+
return { data: await call2(AuditStreamTargetList, "GET", enterprisePaths.streamTargets(tenantId)) };
|
|
70936
|
+
}
|
|
70937
|
+
});
|
|
70938
|
+
var TargetArg = [{ name: "target", required: false, description: "The target ID from `overlane enterprise audit stream list` (required)" }];
|
|
70939
|
+
var targetOf = (inv) => {
|
|
70940
|
+
const id2 = inv.positionals[0];
|
|
70941
|
+
if (id2 === void 0) throw new UsageError("give the stream target ID", { hint: "overlane enterprise audit stream list" });
|
|
70942
|
+
return id2;
|
|
70943
|
+
};
|
|
70944
|
+
var enterpriseStreamRunCommand = defineCommand({
|
|
70945
|
+
path: ["enterprise", "audit", "stream", "run"],
|
|
70946
|
+
summary: "Send the audit rows a target has not acknowledged yet, now",
|
|
70947
|
+
description: "Delivers the rows after the target's cursor in batches, signed and with idempotency keys. A refusal or error stops the run, keeps the cursor and marks the target failing; the next run resends the same batch. Runs also happen every five minutes on their own.",
|
|
70948
|
+
args: TargetArg,
|
|
70949
|
+
examples: ["overlane enterprise audit stream run tgt_abc123"],
|
|
70950
|
+
effect: "write",
|
|
70951
|
+
...common20,
|
|
70952
|
+
keywords: ["send audit now", "flush stream", "retry siem"],
|
|
70953
|
+
result: withDryRun(StreamRunReport),
|
|
70954
|
+
text: (d) => "delivered" in d ? [`${d.failed ? "failed" : "ok"}: ${d.delivered} rows in ${d.batches} batches, through row ${d.deliveredThroughSeq}`] : [],
|
|
70955
|
+
handler: async (inv) => {
|
|
70956
|
+
const id2 = targetOf(inv);
|
|
70957
|
+
if (inv.dryRun) return planned9(inv, "POST", (t2) => enterprisePaths.streamRun(t2, id2), {});
|
|
70958
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70959
|
+
const report2 = await call2(StreamRunReport, "POST", enterprisePaths.streamRun(tenantId, id2), {});
|
|
70960
|
+
return report2.failed ? { data: report2, exit: EXIT.failure, error: new CliError("the target did not accept the delivery", { code: "stream_delivery_failed", exit: EXIT.failure, quiet: true }) } : { data: report2 };
|
|
70961
|
+
}
|
|
70962
|
+
});
|
|
70963
|
+
var StreamRemoved = external_exports.object({ deleted: external_exports.literal(true) }).strict();
|
|
70964
|
+
var enterpriseStreamRemoveCommand = defineCommand({
|
|
70965
|
+
path: ["enterprise", "audit", "stream", "remove"],
|
|
70966
|
+
summary: "Remove a SIEM stream target; its stored signing secret goes with it",
|
|
70967
|
+
description: "Stops deliveries to the target and deletes the sealed signing secret. Rows already delivered stay in your SIEM. Add the target again to resume from the start.",
|
|
70968
|
+
args: TargetArg,
|
|
70969
|
+
examples: ["overlane enterprise audit stream remove tgt_abc123 --dry-run"],
|
|
70970
|
+
effect: "destructive",
|
|
70971
|
+
...common20,
|
|
70972
|
+
keywords: ["delete siem target", "stop streaming"],
|
|
70973
|
+
result: withDryRun(StreamRemoved),
|
|
70974
|
+
text: (d) => "deleted" in d ? ["Target removed."] : [],
|
|
70975
|
+
handler: async (inv) => {
|
|
70976
|
+
const id2 = targetOf(inv);
|
|
70977
|
+
if (inv.dryRun) return planned9(inv, "DELETE", (t2) => enterprisePaths.streamTarget(t2, id2));
|
|
70978
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70979
|
+
return { data: await call2(StreamRemoved, "DELETE", enterprisePaths.streamTarget(tenantId, id2)) };
|
|
70980
|
+
}
|
|
70981
|
+
});
|
|
70982
|
+
var enterpriseRetentionReportsCommand = defineCommand({
|
|
70983
|
+
path: ["enterprise", "retention", "reports"],
|
|
70984
|
+
summary: "List the purge reports, newest first",
|
|
70985
|
+
description: "Each report names the trigger (schedule or manual), when it ran, and for each class and store the cutoff and how many records it removed.",
|
|
70986
|
+
examples: ["overlane enterprise retention reports"],
|
|
70987
|
+
effect: "read",
|
|
70988
|
+
...common20,
|
|
70989
|
+
keywords: ["purge history", "what was deleted by retention"],
|
|
70990
|
+
result: PurgeReportList,
|
|
70991
|
+
text: (d) => d.reports.length === 0 ? ["No purge has run yet."] : d.reports.map((r) => `${r.ranAt} ${r.trigger.padEnd(8)} ${r.totalPurged} records removed (${r.purgeId})`),
|
|
70992
|
+
handler: async (inv) => {
|
|
70993
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
70994
|
+
return { data: await call2(PurgeReportList, "GET", enterprisePaths.purgeReports(tenantId)) };
|
|
70995
|
+
}
|
|
70996
|
+
});
|
|
70997
|
+
var enterpriseBackupsDrillCommand = defineCommand({
|
|
70998
|
+
path: ["enterprise", "backups", "drill"],
|
|
70999
|
+
summary: "Run the backup restore drill; exits 1 if any record count differs or the audit chain breaks",
|
|
71000
|
+
description: "Takes a snapshot of the team's data, reads it back from storage, restores it into a scratch target and compares every table's record count with the source. The restored audit rows must still verify as a chain. Snapshots expire after 30 days.",
|
|
71001
|
+
examples: ["overlane enterprise backups drill"],
|
|
71002
|
+
effect: "write",
|
|
71003
|
+
...common20,
|
|
71004
|
+
keywords: ["restore drill", "backup test", "disaster recovery"],
|
|
71005
|
+
result: withDryRun(RestoreDrillReport),
|
|
71006
|
+
text: (d) => "tables" in d ? [d.ok ? "restore drill passed" : "restore drill FAILED", ...d.tables.map((t2) => `${t2.name.padEnd(16)} expected ${t2.expected} restored ${t2.restored}`)] : [],
|
|
71007
|
+
handler: async (inv) => {
|
|
71008
|
+
if (inv.dryRun) return planned9(inv, "POST", enterprisePaths.restoreDrill, {}, "writes a snapshot and restores it into a scratch target");
|
|
71009
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
71010
|
+
const report2 = await call2(RestoreDrillReport, "POST", enterprisePaths.restoreDrill(tenantId), {});
|
|
71011
|
+
return report2.ok ? { data: report2 } : { data: report2, exit: EXIT.failure, error: new CliError("the restore drill failed", { code: "restore_drill_failed", exit: EXIT.failure, quiet: true }) };
|
|
71012
|
+
}
|
|
71013
|
+
});
|
|
71014
|
+
var enterpriseAllowlistShowCommand = defineCommand({
|
|
71015
|
+
path: ["enterprise", "mcp-allowlist", "show"],
|
|
71016
|
+
summary: "Show the MCP server allowlist for the team's agents",
|
|
71017
|
+
description: "With the allowlist on, an agent may connect only to a listed server host or a subdomain of one; any other server is refused before a connection is made.",
|
|
71018
|
+
examples: ["overlane enterprise mcp-allowlist show"],
|
|
71019
|
+
effect: "read",
|
|
71020
|
+
...common20,
|
|
71021
|
+
keywords: ["mcp servers allowed", "allowlist", "which mcp servers can agents use"],
|
|
71022
|
+
result: McpAllowlist,
|
|
71023
|
+
text: (d) => [`mode: ${d.mode}`, ...d.entries.map((e2) => `allow ${e2.server}${e2.note === void 0 ? "" : ` (${e2.note})`}`)],
|
|
71024
|
+
handler: async (inv) => {
|
|
71025
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
71026
|
+
return { data: await call2(McpAllowlist, "GET", enterprisePaths.mcpAllowlist(tenantId)) };
|
|
71027
|
+
}
|
|
71028
|
+
});
|
|
71029
|
+
var enterpriseAllowlistSetCommand = defineCommand({
|
|
71030
|
+
path: ["enterprise", "mcp-allowlist", "set"],
|
|
71031
|
+
summary: "Turn the MCP server allowlist on or off and set the listed hosts",
|
|
71032
|
+
description: "Replaces the list with the --allow hosts and sets the mode. Mode allowlist refuses any server not listed (a host or a subdomain of one); mode off allows every server. Changing the allowlist is a policy change.",
|
|
71033
|
+
flags: [
|
|
71034
|
+
{ name: "mode", type: "string", enum: ["off", "allowlist"], default: "allowlist", value: "MODE", description: "allowlist (default) or off" },
|
|
71035
|
+
{ name: "allow", type: "string", multiple: true, value: "HOST", description: "A host agents may connect to; repeat for more" }
|
|
71036
|
+
],
|
|
71037
|
+
examples: ["overlane enterprise mcp-allowlist set --allow mcp.example.com", "overlane enterprise mcp-allowlist set --mode off"],
|
|
71038
|
+
effect: "write",
|
|
71039
|
+
...common20,
|
|
71040
|
+
keywords: ["allow mcp server", "restrict mcp", "mcp gateway"],
|
|
71041
|
+
result: withDryRun(McpAllowlist),
|
|
71042
|
+
text: (d) => "mode" in d ? [`mode: ${d.mode}`, ...d.entries.map((e2) => `allow ${e2.server}`)] : [],
|
|
71043
|
+
handler: async (inv) => {
|
|
71044
|
+
const raw = inv.values["allow"];
|
|
71045
|
+
const hosts2 = (Array.isArray(raw) ? raw : raw === void 0 ? [] : [raw]).filter((v) => typeof v === "string");
|
|
71046
|
+
const body2 = { mode: textFlag(inv, "mode") ?? "allowlist", entries: hosts2.map((server2) => ({ server: server2 })) };
|
|
71047
|
+
if (inv.dryRun) return planned9(inv, "PUT", enterprisePaths.mcpAllowlist, body2);
|
|
71048
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
71049
|
+
return { data: await call2(McpAllowlist, "PUT", enterprisePaths.mcpAllowlist(tenantId), body2) };
|
|
71050
|
+
}
|
|
71051
|
+
});
|
|
71052
|
+
var enterpriseEvidencePackCommand = defineCommand({
|
|
71053
|
+
path: ["enterprise", "evidence-pack"],
|
|
71054
|
+
summary: "Print the security review evidence pack: chain state, agent action counts and controls",
|
|
71055
|
+
description: "Verifies the audit chain, counts the audited actions taken by agent tokens (and how many were denied), and lists the controls (single sign-on, directory sync, audit log, SIEM stream, data region, customer keys, retention, MCP allowlist) as enabled or not configured. Identifiers and counts only.",
|
|
71056
|
+
examples: ["overlane enterprise evidence-pack --json"],
|
|
71057
|
+
effect: "read",
|
|
71058
|
+
...common20,
|
|
71059
|
+
keywords: ["soc 2 evidence", "security review", "agent action audit"],
|
|
71060
|
+
result: EvidencePack,
|
|
71061
|
+
text: (d) => [
|
|
71062
|
+
`audit chain: ${d.chain.ok ? "verified" : "BROKEN"} (${d.chain.checked} rows)`,
|
|
71063
|
+
`agent actions: ${d.agentActions.total} (${d.agentActions.denied} denied)`,
|
|
71064
|
+
...d.controls.map((c2) => `${c2.state === "enabled" ? "enabled " : "not configured"} ${c2.id.padEnd(7)} ${c2.title}: ${c2.evidence}`)
|
|
71065
|
+
],
|
|
71066
|
+
handler: async (inv) => {
|
|
71067
|
+
const { call: call2, tenantId } = await connected9(inv);
|
|
71068
|
+
return { data: await call2(EvidencePack, "GET", enterprisePaths.evidencePack(tenantId)) };
|
|
71069
|
+
}
|
|
71070
|
+
});
|
|
71071
|
+
var enterpriseCommands = [
|
|
71072
|
+
enterpriseSsoShowCommand,
|
|
71073
|
+
enterpriseSsoTestCommand,
|
|
71074
|
+
enterpriseSsoGroupsSetCommand,
|
|
71075
|
+
enterpriseStreamListCommand,
|
|
71076
|
+
enterpriseStreamRunCommand,
|
|
71077
|
+
enterpriseStreamRemoveCommand,
|
|
71078
|
+
enterpriseRetentionReportsCommand,
|
|
71079
|
+
enterpriseBackupsDrillCommand,
|
|
71080
|
+
enterpriseAllowlistShowCommand,
|
|
71081
|
+
enterpriseAllowlistSetCommand,
|
|
71082
|
+
enterpriseEvidencePackCommand,
|
|
71083
|
+
enterpriseStatusCommand,
|
|
71084
|
+
enterpriseSsoLinkCommand,
|
|
71085
|
+
enterpriseSyncCommand,
|
|
71086
|
+
enterpriseAuditExportCommand,
|
|
71087
|
+
enterpriseAuditVerifyCommand,
|
|
71088
|
+
enterpriseStreamAddCommand,
|
|
71089
|
+
enterpriseRegionShowCommand,
|
|
71090
|
+
enterpriseRegionSetCommand,
|
|
71091
|
+
enterpriseKeysListCommand,
|
|
71092
|
+
enterpriseKeysAddCommand,
|
|
71093
|
+
enterpriseKeysTestCommand,
|
|
71094
|
+
enterpriseKeysRotateCommand,
|
|
71095
|
+
enterpriseKeysRevokeCommand,
|
|
71096
|
+
enterpriseRetentionShowCommand,
|
|
71097
|
+
enterpriseRetentionSetCommand,
|
|
71098
|
+
enterprisePurgeCommand,
|
|
71099
|
+
enterpriseDataExportCommand,
|
|
71100
|
+
enterpriseDataDeleteCommand
|
|
71101
|
+
];
|
|
71102
|
+
|
|
70063
71103
|
// ../cli/src/commands/observe.ts
|
|
70064
71104
|
init_src();
|
|
70065
71105
|
init_zod();
|
|
70066
71106
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
70067
|
-
var
|
|
71107
|
+
var common21 = { needsAuth: true, needsNetwork: true };
|
|
70068
71108
|
var requestId14 = () => `cli-${randomUUID15()}`;
|
|
70069
|
-
async function
|
|
71109
|
+
async function connected10(inv) {
|
|
70070
71110
|
const project = await connectedProject(inv.deps, "observe");
|
|
70071
71111
|
return { call: serviceCall(inv.deps, project.serviceUrl, project.token), tenantId: project.binding.tenantId, projectId: project.binding.projectId };
|
|
70072
71112
|
}
|
|
70073
|
-
async function
|
|
71113
|
+
async function planned10(inv, method, path, body2, note) {
|
|
70074
71114
|
const project = await offlineProject(inv.deps, "observe");
|
|
70075
71115
|
return planOutcome(inv.deps, dryRunPlan({ service: project.serviceUrl, requests: [{ method, path: path(project.binding.tenantId), ...body2 === void 0 ? {} : { body: body2 }, ...note === void 0 ? {} : { note } }] }));
|
|
70076
71116
|
}
|
|
@@ -70085,7 +71125,7 @@ var observeStatusCommand = defineCommand({
|
|
|
70085
71125
|
description: "One read of the team's observability: runs in the last 24 hours by status, open alert incidents, cost and tokens this billing period, the decision-model records (outcomes and latency), and how long telemetry is kept on the plan.",
|
|
70086
71126
|
examples: ["overlane observe status", "overlane observe status --json"],
|
|
70087
71127
|
effect: "read",
|
|
70088
|
-
...
|
|
71128
|
+
...common21,
|
|
70089
71129
|
keywords: ["observability", "run status", "open incidents", "how are my agents doing", "telemetry"],
|
|
70090
71130
|
result: ObserveStatus,
|
|
70091
71131
|
text: (d) => [
|
|
@@ -70096,7 +71136,7 @@ var observeStatusCommand = defineCommand({
|
|
|
70096
71136
|
`retention: ${d.retention.retentionDays === null ? "set by contract" : `${d.retention.retentionDays} days`} (${d.retention.plan})`
|
|
70097
71137
|
],
|
|
70098
71138
|
handler: async (inv) => {
|
|
70099
|
-
const { call: call2, tenantId } = await
|
|
71139
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70100
71140
|
return { data: await call2(ObserveStatus, "GET", observePaths.status(tenantId)) };
|
|
70101
71141
|
}
|
|
70102
71142
|
});
|
|
@@ -70110,12 +71150,12 @@ var observeLogsCommand = defineCommand({
|
|
|
70110
71150
|
],
|
|
70111
71151
|
examples: ["overlane observe logs", "overlane observe logs --run run-12 --limit 50"],
|
|
70112
71152
|
effect: "read",
|
|
70113
|
-
...
|
|
71153
|
+
...common21,
|
|
70114
71154
|
keywords: ["logs", "agent logs", "what happened in the run", "tool output"],
|
|
70115
71155
|
result: LogRecordList,
|
|
70116
71156
|
text: (d) => d.logs.length === 0 ? ["No log lines recorded."] : d.logs.map((l) => `${l.at} ${l.level.toUpperCase().padEnd(5)} ${l.runId} ${l.source} ${l.message}${l.redacted ? ` (${l.redactions} redacted)` : ""}`),
|
|
70117
71157
|
handler: async (inv) => {
|
|
70118
|
-
const { call: call2, tenantId, projectId } = await
|
|
71158
|
+
const { call: call2, tenantId, projectId } = await connected10(inv);
|
|
70119
71159
|
const run3 = textFlag(inv, "run");
|
|
70120
71160
|
const limit = textFlag(inv, "limit");
|
|
70121
71161
|
if (limit !== void 0 && !/^\d+$/.test(limit)) throw new UsageError("--limit is a whole number");
|
|
@@ -70130,7 +71170,7 @@ var observeTraceCommand = defineCommand({
|
|
|
70130
71170
|
flags: [{ name: "run", type: "string", required: true, value: "RUN", description: "The run ID" }],
|
|
70131
71171
|
examples: ["overlane observe trace --run run-12", "overlane observe trace --run run-12 --json"],
|
|
70132
71172
|
effect: "read",
|
|
70133
|
-
...
|
|
71173
|
+
...common21,
|
|
70134
71174
|
keywords: ["trace", "run trace", "stitched logs", "spans", "run id"],
|
|
70135
71175
|
result: TraceBundle,
|
|
70136
71176
|
text: (d) => [
|
|
@@ -70142,7 +71182,7 @@ var observeTraceCommand = defineCommand({
|
|
|
70142
71182
|
handler: async (inv) => {
|
|
70143
71183
|
const run3 = textFlag(inv, "run");
|
|
70144
71184
|
if (run3 === void 0) throw new UsageError("trace needs --run", { hint: "overlane observe trace --run <run id>" });
|
|
70145
|
-
const { call: call2, tenantId, projectId } = await
|
|
71185
|
+
const { call: call2, tenantId, projectId } = await connected10(inv);
|
|
70146
71186
|
return { data: await call2(TraceBundle, "GET", observePaths.trace(tenantId, projectId, run3)) };
|
|
70147
71187
|
}
|
|
70148
71188
|
});
|
|
@@ -70152,7 +71192,7 @@ var observeCostCommand = defineCommand({
|
|
|
70152
71192
|
description: "Cost in dollars, tokens and run counts grouped by agent, by project and for the team, from the metrics the runs reported. `overlane observe reconcile` compares the same figures with metered usage.",
|
|
70153
71193
|
examples: ["overlane observe cost", "overlane observe cost --json"],
|
|
70154
71194
|
effect: "read",
|
|
70155
|
-
...
|
|
71195
|
+
...common21,
|
|
70156
71196
|
keywords: ["cost per agent", "token usage", "spend per project", "how much did the run cost"],
|
|
70157
71197
|
result: CostReport,
|
|
70158
71198
|
text: (d) => [
|
|
@@ -70161,7 +71201,7 @@ var observeCostCommand = defineCommand({
|
|
|
70161
71201
|
...d.byProject.map((r) => ` project ${r.key.padEnd(18)} ${usd3(r.costMicros).padStart(10)} ${String(r.tokens).padStart(10)} tokens ${r.runs} runs`)
|
|
70162
71202
|
],
|
|
70163
71203
|
handler: async (inv) => {
|
|
70164
|
-
const { call: call2, tenantId } = await
|
|
71204
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70165
71205
|
return { data: await call2(CostReport, "GET", observePaths.cost(tenantId)) };
|
|
70166
71206
|
}
|
|
70167
71207
|
});
|
|
@@ -70171,7 +71211,7 @@ var observeReconcileCommand = defineCommand({
|
|
|
70171
71211
|
description: "Compares the cost the metrics report with the usage the billing ledger meters, per agent, per project and in total. A line outside the tolerance names the key and the error in basis points.",
|
|
70172
71212
|
examples: ["overlane observe reconcile", "overlane observe reconcile --json"],
|
|
70173
71213
|
effect: "read",
|
|
70174
|
-
...
|
|
71214
|
+
...common21,
|
|
70175
71215
|
keywords: ["reconcile cost", "metered usage", "cost matches billing", "metrics accuracy"],
|
|
70176
71216
|
result: Reconciliation,
|
|
70177
71217
|
text: (d) => [
|
|
@@ -70179,7 +71219,7 @@ var observeReconcileCommand = defineCommand({
|
|
|
70179
71219
|
...[...d.byAgent.map((l) => ({ ...l, key: `agent ${l.key}` })), ...d.byProject.map((l) => ({ ...l, key: `project ${l.key}` }))].filter((l) => !l.within).map((l) => ` ${l.key}: metered ${usd3(l.meteredMicros)}, observed ${usd3(l.observedMicros)}, error ${l.errorBps} bps`)
|
|
70180
71220
|
],
|
|
70181
71221
|
handler: async (inv) => {
|
|
70182
|
-
const { call: call2, tenantId } = await
|
|
71222
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70183
71223
|
return { data: await call2(Reconciliation, "GET", observePaths.reconcile(tenantId)) };
|
|
70184
71224
|
}
|
|
70185
71225
|
});
|
|
@@ -70190,7 +71230,7 @@ var observeCompareCommand = defineCommand({
|
|
|
70190
71230
|
flags: [{ name: "task", type: "string", required: true, value: "TASK", description: "The task ID" }],
|
|
70191
71231
|
examples: ["overlane observe compare --task task-77", "overlane observe compare --task task-77 --json"],
|
|
70192
71232
|
effect: "read",
|
|
70193
|
-
...
|
|
71233
|
+
...common21,
|
|
70194
71234
|
keywords: ["compare agents", "which agent is better", "claude vs codex", "agent report", "same task two agents"],
|
|
70195
71235
|
result: ComparisonReport,
|
|
70196
71236
|
text: (d) => d.entries.length === 0 ? [`No runs recorded for task ${d.taskId}.`] : [
|
|
@@ -70200,7 +71240,7 @@ var observeCompareCommand = defineCommand({
|
|
|
70200
71240
|
handler: async (inv) => {
|
|
70201
71241
|
const task = textFlag(inv, "task");
|
|
70202
71242
|
if (task === void 0) throw new UsageError("compare needs --task", { hint: "overlane observe compare --task <task id>" });
|
|
70203
|
-
const { call: call2, tenantId } = await
|
|
71243
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70204
71244
|
return { data: await call2(ComparisonReport, "GET", `${observePaths.compare(tenantId)}?task=${encodeURIComponent(task)}`) };
|
|
70205
71245
|
}
|
|
70206
71246
|
});
|
|
@@ -70210,12 +71250,12 @@ var observeEvalsCommand = defineCommand({
|
|
|
70210
71250
|
description: "Pass rate, mean cost and mean review time per agent and configuration, scored from the stored replays of your own merged pull requests. Scoring is arithmetic over checks, never a model's opinion.",
|
|
70211
71251
|
examples: ["overlane observe evals", "overlane observe evals --json"],
|
|
70212
71252
|
effect: "read",
|
|
70213
|
-
...
|
|
71253
|
+
...common21,
|
|
70214
71254
|
keywords: ["evals", "replay merged prs", "agent pass rate", "benchmark my repo", "which config works"],
|
|
70215
71255
|
result: EvalReport,
|
|
70216
71256
|
text: (d) => d.rows.length === 0 ? ["No replays recorded. Run some: overlane observe evals run --prs pr-1,pr-2 --agents codex --configs default"] : [...d.rows.map((r) => `${r.agent.padEnd(16)} ${r.config.padEnd(14)} pass ${(r.passRateBps / 100).toFixed(1)}% ${r.passed}/${r.prs} cost ${usd3(r.meanCostMicros)} review ${minutes(r.meanReviewMs)}`), `best: ${d.best === null ? "none" : `${d.best.agent} / ${d.best.config}`}`],
|
|
70217
71257
|
handler: async (inv) => {
|
|
70218
|
-
const { call: call2, tenantId } = await
|
|
71258
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70219
71259
|
return { data: await call2(EvalReport, "GET", observePaths.evals(tenantId)) };
|
|
70220
71260
|
}
|
|
70221
71261
|
});
|
|
@@ -70235,14 +71275,14 @@ var observeEvalsRunCommand = defineCommand({
|
|
|
70235
71275
|
],
|
|
70236
71276
|
examples: ["overlane observe evals run --prs pr-1,pr-2 --agents codex,claude-code --configs default,strict", "overlane observe evals run --prs pr-1 --agents codex --configs default --dry-run"],
|
|
70237
71277
|
effect: "write",
|
|
70238
|
-
...
|
|
71278
|
+
...common21,
|
|
70239
71279
|
keywords: ["run evals", "replay pull requests", "compare configs", "agent benchmark on my repo"],
|
|
70240
71280
|
result: withDryRun(EvalReport),
|
|
70241
71281
|
text: (d) => "rows" in d ? d.rows.map((r) => `${r.agent} / ${r.config}: pass ${(r.passRateBps / 100).toFixed(1)}%, cost ${usd3(r.meanCostMicros)}, review ${minutes(r.meanReviewMs)}`) : [],
|
|
70242
71282
|
handler: async (inv) => {
|
|
70243
71283
|
const body2 = { requestId: requestId14(), prs: list(textFlag(inv, "prs"), "prs"), agents: list(textFlag(inv, "agents"), "agents"), configs: list(textFlag(inv, "configs"), "configs") };
|
|
70244
|
-
if (inv.dryRun) return
|
|
70245
|
-
const { call: call2, tenantId } = await
|
|
71284
|
+
if (inv.dryRun) return planned10(inv, "POST", observePaths.evals, body2, "replays each pull request with each agent and configuration");
|
|
71285
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70246
71286
|
return { data: await call2(EvalReport, "POST", observePaths.evals(tenantId), body2) };
|
|
70247
71287
|
}
|
|
70248
71288
|
});
|
|
@@ -70252,7 +71292,7 @@ var observeAlertsCommand = defineCommand({
|
|
|
70252
71292
|
description: "Alert rules (spend cap reached, failing run, stuck lease, stale index) with where each one goes, and the incidents they opened. An incident fires once; resolving it is a separate notice.",
|
|
70253
71293
|
examples: ["overlane observe alerts", "overlane observe alerts --json"],
|
|
70254
71294
|
effect: "read",
|
|
70255
|
-
...
|
|
71295
|
+
...common21,
|
|
70256
71296
|
keywords: ["alerts", "incidents", "notifications", "who gets paged", "failing runs"],
|
|
70257
71297
|
result: AlertOverview,
|
|
70258
71298
|
text: (d) => [
|
|
@@ -70260,7 +71300,7 @@ var observeAlertsCommand = defineCommand({
|
|
|
70260
71300
|
...d.incidents.map((i2) => `${i2.state.padEnd(8)} ${i2.openedAt} ${i2.kind} ${i2.subject} next: ${i2.nextCommand}`)
|
|
70261
71301
|
],
|
|
70262
71302
|
handler: async (inv) => {
|
|
70263
|
-
const { call: call2, tenantId } = await
|
|
71303
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70264
71304
|
return { data: await call2(AlertOverview, "GET", observePaths.alerts(tenantId)) };
|
|
70265
71305
|
}
|
|
70266
71306
|
});
|
|
@@ -70290,7 +71330,7 @@ var observeAlertsSetCommand = defineCommand({
|
|
|
70290
71330
|
],
|
|
70291
71331
|
examples: ["overlane observe alerts set --kind failing_run --email ops@example.com --slack ops", "overlane observe alerts set --kind spend_cap --percent 80 --email ops@example.com --dry-run"],
|
|
70292
71332
|
effect: "write",
|
|
70293
|
-
...
|
|
71333
|
+
...common21,
|
|
70294
71334
|
keywords: ["add alert", "alert on failing runs", "alert on spend", "notify slack", "notify email"],
|
|
70295
71335
|
result: withDryRun(RuleSet),
|
|
70296
71336
|
text: (d) => "rule" in d ? [`rule ${d.rule.ruleId}: ${d.rule.kind}, ${d.rule.enabled ? "on" : "off"}, -> ${d.rule.targets.map((t2) => `${t2.channel}:${t2.destination}`).join(", ")}`] : [],
|
|
@@ -70312,8 +71352,8 @@ var observeAlertsSetCommand = defineCommand({
|
|
|
70312
71352
|
enabled: !boolFlag(inv, "off"),
|
|
70313
71353
|
...ruleId === void 0 ? {} : { ruleId }
|
|
70314
71354
|
};
|
|
70315
|
-
if (inv.dryRun) return
|
|
70316
|
-
const { call: call2, tenantId } = await
|
|
71355
|
+
if (inv.dryRun) return planned10(inv, "PUT", observePaths.alertRules, body2);
|
|
71356
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70317
71357
|
return { data: await call2(RuleSet, "PUT", observePaths.alertRules(tenantId), body2) };
|
|
70318
71358
|
}
|
|
70319
71359
|
});
|
|
@@ -70325,15 +71365,15 @@ var observeAlertsRemoveCommand = defineCommand({
|
|
|
70325
71365
|
flags: [{ name: "rule-id", type: "string", value: "ID", description: "The rule to remove (required)" }],
|
|
70326
71366
|
examples: ["overlane observe alerts remove --rule-id rule-1 --force", "overlane observe alerts remove --rule-id rule-1 --dry-run"],
|
|
70327
71367
|
effect: "destructive",
|
|
70328
|
-
...
|
|
71368
|
+
...common21,
|
|
70329
71369
|
keywords: ["delete alert", "remove alert rule", "stop alerts"],
|
|
70330
71370
|
result: withDryRun(RuleRemoved),
|
|
70331
71371
|
text: (d) => "removed" in d ? ["rule removed"] : [],
|
|
70332
71372
|
handler: async (inv) => {
|
|
70333
71373
|
const ruleId = textFlag(inv, "rule-id");
|
|
70334
71374
|
if (ruleId === void 0) throw new UsageError("remove needs --rule-id", { hint: "overlane observe alerts" });
|
|
70335
|
-
if (inv.dryRun) return
|
|
70336
|
-
const { call: call2, tenantId } = await
|
|
71375
|
+
if (inv.dryRun) return planned10(inv, "DELETE", observePaths.alertRules, { ruleId });
|
|
71376
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70337
71377
|
return { data: await call2(RuleRemoved, "DELETE", observePaths.alertRules(tenantId), { ruleId }) };
|
|
70338
71378
|
}
|
|
70339
71379
|
});
|
|
@@ -70343,13 +71383,13 @@ var observeAlertsEvaluateCommand = defineCommand({
|
|
|
70343
71383
|
description: "Looks at each enabled rule's condition, opens an incident for a new one, resolves one that cleared, and sends each notice once. The service also runs this on a schedule and when a run ends in failure.",
|
|
70344
71384
|
examples: ["overlane observe alerts evaluate", "overlane observe alerts evaluate --dry-run"],
|
|
70345
71385
|
effect: "write",
|
|
70346
|
-
...
|
|
71386
|
+
...common21,
|
|
70347
71387
|
keywords: ["check alerts now", "evaluate rules", "send alerts"],
|
|
70348
71388
|
result: withDryRun(EvaluateAlertsResult),
|
|
70349
71389
|
text: (d) => "opened" in d ? [`opened ${d.opened.length}, resolved ${d.resolved.length}, still open ${d.stillOpen}`, ...d.opened.map((i2) => ` ${i2.kind}: ${i2.subject}`)] : [],
|
|
70350
71390
|
handler: async (inv) => {
|
|
70351
|
-
if (inv.dryRun) return
|
|
70352
|
-
const { call: call2, tenantId } = await
|
|
71391
|
+
if (inv.dryRun) return planned10(inv, "POST", observePaths.alertsEvaluate, {}, "opens incidents and sends notices");
|
|
71392
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70353
71393
|
return { data: await call2(EvaluateAlertsResult, "POST", observePaths.alertsEvaluate(tenantId), {}) };
|
|
70354
71394
|
}
|
|
70355
71395
|
});
|
|
@@ -70359,12 +71399,12 @@ var observeRetentionCommand = defineCommand({
|
|
|
70359
71399
|
description: "The retention period for logs, spans, metrics and run events on the team's plan, and the records no purge ever touches: the task ledger, evidence, the audit log, billing and decision records.",
|
|
70360
71400
|
examples: ["overlane observe retention", "overlane observe retention --json"],
|
|
70361
71401
|
effect: "read",
|
|
70362
|
-
...
|
|
71402
|
+
...common21,
|
|
70363
71403
|
keywords: ["retention", "how long are logs kept", "data retention", "purge"],
|
|
70364
71404
|
result: RetentionPolicy,
|
|
70365
71405
|
text: (d) => [`plan ${d.plan}: ${d.retentionDays === null ? "no fixed period" : `${d.retentionDays} days`}`, `purged: ${d.covers.join(", ")}`, `never purged: ${d.keeps.join(", ")}`],
|
|
70366
71406
|
handler: async (inv) => {
|
|
70367
|
-
const { call: call2, tenantId } = await
|
|
71407
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70368
71408
|
return { data: await call2(RetentionPolicy, "GET", observePaths.retention(tenantId)) };
|
|
70369
71409
|
}
|
|
70370
71410
|
});
|
|
@@ -70374,13 +71414,13 @@ var observeRetentionPurgeCommand = defineCommand({
|
|
|
70374
71414
|
description: "Deletes logs, spans, metrics, run events and resolved incidents older than the plan's retention period and prints how many of each. The task ledger, evidence, audit log, billing and decision records are never touched. The service also runs this on a schedule. Destructive: it needs --force without a terminal.",
|
|
70375
71415
|
examples: ["overlane observe retention purge --force", "overlane observe retention purge --dry-run"],
|
|
70376
71416
|
effect: "destructive",
|
|
70377
|
-
...
|
|
71417
|
+
...common21,
|
|
70378
71418
|
keywords: ["purge logs", "delete old telemetry", "enforce retention"],
|
|
70379
71419
|
result: withDryRun(RetentionPurgeResult),
|
|
70380
71420
|
text: (d) => "deleted" in d ? [`plan ${d.plan}, cutoff ${d.cutoff ?? "none"}`, ...Object.entries(d.deleted).map(([k, v]) => ` ${k}: ${v}`)] : [],
|
|
70381
71421
|
handler: async (inv) => {
|
|
70382
|
-
if (inv.dryRun) return
|
|
70383
|
-
const { call: call2, tenantId } = await
|
|
71422
|
+
if (inv.dryRun) return planned10(inv, "POST", observePaths.retentionPurge, {}, "deletes telemetry older than the plan keeps");
|
|
71423
|
+
const { call: call2, tenantId } = await connected10(inv);
|
|
70384
71424
|
return { data: await call2(RetentionPurgeResult, "POST", observePaths.retentionPurge(tenantId), {}) };
|
|
70385
71425
|
}
|
|
70386
71426
|
});
|
|
@@ -70439,7 +71479,8 @@ function coreCommands() {
|
|
|
70439
71479
|
...observeCommands,
|
|
70440
71480
|
...repoCommands,
|
|
70441
71481
|
...ciCommands,
|
|
70442
|
-
...deployCommands
|
|
71482
|
+
...deployCommands,
|
|
71483
|
+
...enterpriseCommands
|
|
70443
71484
|
];
|
|
70444
71485
|
}
|
|
70445
71486
|
function createRegistry(extra = []) {
|
|
@@ -70664,22 +71705,22 @@ import { join as join29 } from "node:path";
|
|
|
70664
71705
|
function dataDir(env = process.env, home = homedir()) {
|
|
70665
71706
|
const override = env["MVRX_DATA_DIR"];
|
|
70666
71707
|
if (override !== void 0 && override !== "") return override;
|
|
70667
|
-
const
|
|
70668
|
-
return join29(
|
|
71708
|
+
const base5 = env["XDG_DATA_HOME"] ?? (process.platform === "win32" ? env["LOCALAPPDATA"] : void 0) ?? (process.platform === "darwin" ? join29(home, "Library", "Application Support") : join29(home, ".local", "share"));
|
|
71709
|
+
return join29(base5, "mvrx-harness");
|
|
70669
71710
|
}
|
|
70670
71711
|
function marketplaceRoot(env = process.env, home = homedir()) {
|
|
70671
71712
|
return join29(dataDir(env, home), "marketplace");
|
|
70672
71713
|
}
|
|
70673
71714
|
|
|
70674
71715
|
// src/plugin.ts
|
|
70675
|
-
import { readFileSync as
|
|
71716
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
70676
71717
|
import { join as join31 } from "node:path";
|
|
70677
71718
|
import { parseArgs as parseArgs3 } from "node:util";
|
|
70678
71719
|
|
|
70679
71720
|
// src/marketplace.ts
|
|
70680
71721
|
init_src();
|
|
70681
71722
|
import { createHash as createHash7 } from "node:crypto";
|
|
70682
|
-
import { cpSync, existsSync as existsSync8, mkdirSync as mkdirSync10, readdirSync as readdirSync3, readFileSync as
|
|
71723
|
+
import { cpSync, existsSync as existsSync8, mkdirSync as mkdirSync10, readdirSync as readdirSync3, readFileSync as readFileSync15, renameSync as renameSync7, rmSync as rmSync4, statSync as statSync2, writeFileSync as writeFileSync10 } from "node:fs";
|
|
70683
71724
|
import { dirname as dirname11, join as join30, relative as relative2, sep } from "node:path";
|
|
70684
71725
|
var CLIENT_DIRS = ["claude", "codex"];
|
|
70685
71726
|
var EMBEDDED_MANIFEST = "release-manifest.json";
|
|
@@ -70690,7 +71731,7 @@ function loadEmbedded(packageRoot2) {
|
|
|
70690
71731
|
const dir = join30(packageRoot2, "plugins");
|
|
70691
71732
|
const path = join30(dir, EMBEDDED_MANIFEST);
|
|
70692
71733
|
if (!existsSync8(path)) throw new MarketplaceError(`this package has no embedded plugin release (${path} is missing)`);
|
|
70693
|
-
const parsed = ReleaseManifest.safeParse(JSON.parse(
|
|
71734
|
+
const parsed = ReleaseManifest.safeParse(JSON.parse(readFileSync15(path, "utf8")));
|
|
70694
71735
|
if (!parsed.success) throw new MarketplaceError(`the embedded release manifest is invalid: ${parsed.error.message}`);
|
|
70695
71736
|
return { dir, manifest: parsed.data };
|
|
70696
71737
|
}
|
|
@@ -70718,7 +71759,7 @@ async function verifyTree(treeRoot, manifest) {
|
|
|
70718
71759
|
problems.push(`missing: ${file2.path}`);
|
|
70719
71760
|
continue;
|
|
70720
71761
|
}
|
|
70721
|
-
if (sha2562(
|
|
71762
|
+
if (sha2562(readFileSync15(path)) !== file2.digest) problems.push(`modified: ${file2.path}`);
|
|
70722
71763
|
}
|
|
70723
71764
|
for (const client of CLIENT_DIRS) {
|
|
70724
71765
|
for (const found of listFiles(join30(treeRoot, client))) {
|
|
@@ -70729,7 +71770,7 @@ async function verifyTree(treeRoot, manifest) {
|
|
|
70729
71770
|
}
|
|
70730
71771
|
function readInstalledManifest(target2) {
|
|
70731
71772
|
try {
|
|
70732
|
-
const parsed = ReleaseManifest.safeParse(JSON.parse(
|
|
71773
|
+
const parsed = ReleaseManifest.safeParse(JSON.parse(readFileSync15(join30(target2, INSTALLED_MANIFEST), "utf8")));
|
|
70733
71774
|
return parsed.success ? parsed.data : null;
|
|
70734
71775
|
} catch {
|
|
70735
71776
|
return null;
|
|
@@ -70760,7 +71801,7 @@ async function syncMarketplace(embedded, target2) {
|
|
|
70760
71801
|
if (existsSync8(join30(embedded.dir, client))) cpSync(join30(embedded.dir, client), join30(staging, client), { recursive: true });
|
|
70761
71802
|
}
|
|
70762
71803
|
mkdirSync10(join30(staging, ".release"), { recursive: true });
|
|
70763
|
-
|
|
71804
|
+
writeFileSync10(join30(staging, INSTALLED_MANIFEST), `${JSON.stringify(embedded.manifest, null, 2)}
|
|
70764
71805
|
`);
|
|
70765
71806
|
const after = await verifyTree(staging, embedded.manifest);
|
|
70766
71807
|
if (after.length > 0) throw new MarketplaceError(`the copied plugin files do not match the release manifest:
|
|
@@ -70793,7 +71834,7 @@ var PluginUsageError = class extends Error {
|
|
|
70793
71834
|
};
|
|
70794
71835
|
function readNames(treeRoot, client) {
|
|
70795
71836
|
const file2 = client === "claude" ? join31(treeRoot, "claude", ".claude-plugin", "marketplace.json") : join31(treeRoot, "codex", ".agents", "plugins", "marketplace.json");
|
|
70796
|
-
const parsed = JSON.parse(
|
|
71837
|
+
const parsed = JSON.parse(readFileSync16(file2, "utf8"));
|
|
70797
71838
|
const record3 = parsed;
|
|
70798
71839
|
const plugin = record3.plugins?.[0]?.name;
|
|
70799
71840
|
if (typeof record3.name !== "string" || typeof plugin !== "string") throw new MarketplaceError(`${file2} names no marketplace or plugin`);
|
|
@@ -71065,8 +72106,8 @@ async function confirm(question) {
|
|
|
71065
72106
|
}
|
|
71066
72107
|
}
|
|
71067
72108
|
function configDir2(env) {
|
|
71068
|
-
const
|
|
71069
|
-
return join34(
|
|
72109
|
+
const base5 = env["XDG_CONFIG_HOME"] ?? (process.platform === "win32" ? env["APPDATA"] : void 0) ?? join34(homedir3(), ".config");
|
|
72110
|
+
return join34(base5, "mvrx-harness");
|
|
71070
72111
|
}
|
|
71071
72112
|
function createDeps2(env = process.env) {
|
|
71072
72113
|
return {
|