overlane 0.1.118 → 0.1.120
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 +1610 -408
- 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-context.mjs +19 -19
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-guard.mjs +25 -25
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-intake.mjs +22 -22
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-quota.mjs +20 -20
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-statusline.mjs +21 -21
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-stop.mjs +20 -20
- package/plugins/codex/plugins/mvrx-harness/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-context.mjs +19 -19
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-guard.mjs +25 -25
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-intake.mjs +22 -22
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-quota.mjs +20 -20
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-statusline.mjs +21 -21
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-stop.mjs +20 -20
- package/plugins/release-manifest.json +20 -20
package/dist/overlane.mjs
CHANGED
|
@@ -3502,15 +3502,15 @@ var init_schemas = __esm({
|
|
|
3502
3502
|
const syms = normalized.symbolKeys;
|
|
3503
3503
|
const doc = new Doc(["payload", "ctx"], { shape: shape2, inst, memo: memo3, syms });
|
|
3504
3504
|
const parseStr = (k) => `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
|
|
3505
|
-
const prefixStr = (
|
|
3506
|
-
let ${
|
|
3507
|
-
for (let i = 0; i < ${
|
|
3508
|
-
const iss = ${
|
|
3505
|
+
const prefixStr = (id2, k) => `
|
|
3506
|
+
let ${id2}_ab = false;
|
|
3507
|
+
for (let i = 0; i < ${id2}.issues.length; i++) {
|
|
3508
|
+
const iss = ${id2}.issues[i];
|
|
3509
3509
|
iss.path = iss.path ? [${k}, ...iss.path] : [${k}];
|
|
3510
3510
|
payload.issues.push(iss);
|
|
3511
|
-
if (iss.continue !== true) ${
|
|
3511
|
+
if (iss.continue !== true) ${id2}_ab = true;
|
|
3512
3512
|
}
|
|
3513
|
-
if (${
|
|
3513
|
+
if (${id2}_ab && ctx && ctx.abortEarly) {
|
|
3514
3514
|
payload.value = newResult;
|
|
3515
3515
|
return payload;
|
|
3516
3516
|
}`;
|
|
@@ -3524,34 +3524,34 @@ var init_schemas = __esm({
|
|
|
3524
3524
|
for (const key of normalized.allKeys) {
|
|
3525
3525
|
if (key === "__proto__")
|
|
3526
3526
|
continue;
|
|
3527
|
-
const
|
|
3527
|
+
const id2 = ids[key];
|
|
3528
3528
|
const k = typeof key === "symbol" ? `syms[${syms.indexOf(key)}]` : esc(key);
|
|
3529
3529
|
const isPresent = `${k} in input`;
|
|
3530
3530
|
const schema = shape2[key];
|
|
3531
3531
|
const optin = schema?._zod?.optin;
|
|
3532
3532
|
const isOptionalIn = optin !== void 0;
|
|
3533
3533
|
const isOptionalOut = schema?._zod?.optout === "optional";
|
|
3534
|
-
doc.write(`const ${
|
|
3534
|
+
doc.write(`const ${id2} = ${parseStr(k)};`);
|
|
3535
3535
|
if (isOptionalIn && isOptionalOut) {
|
|
3536
|
-
const assign = optin === "optional" ? `${
|
|
3536
|
+
const assign = optin === "optional" ? `${id2}_present` : `${id2}.value !== undefined || ${id2}_present`;
|
|
3537
3537
|
doc.write(`
|
|
3538
|
-
const ${
|
|
3539
|
-
if (!${
|
|
3540
|
-
if (${
|
|
3538
|
+
const ${id2}_present = ${isPresent};
|
|
3539
|
+
if (!${id2}.issues.length || ${id2}_present) {
|
|
3540
|
+
if (${id2}.issues.length) {${prefixStr(id2, k)}
|
|
3541
3541
|
}
|
|
3542
3542
|
|
|
3543
3543
|
if (${assign}) {
|
|
3544
|
-
newResult[${k}] = ${
|
|
3544
|
+
newResult[${k}] = ${id2}.value;
|
|
3545
3545
|
}
|
|
3546
3546
|
}
|
|
3547
3547
|
|
|
3548
3548
|
`);
|
|
3549
3549
|
} else if (!isOptionalIn) {
|
|
3550
3550
|
doc.write(`
|
|
3551
|
-
const ${
|
|
3552
|
-
if (${
|
|
3551
|
+
const ${id2}_present = ${isPresent};
|
|
3552
|
+
if (${id2}.issues.length) {${prefixStr(id2, k)}
|
|
3553
3553
|
}
|
|
3554
|
-
if (!${
|
|
3554
|
+
if (!${id2}_present && !${id2}.issues.length) {
|
|
3555
3555
|
payload.issues.push({
|
|
3556
3556
|
code: "invalid_type",
|
|
3557
3557
|
expected: "nonoptional",
|
|
@@ -3564,22 +3564,22 @@ var init_schemas = __esm({
|
|
|
3564
3564
|
}
|
|
3565
3565
|
}
|
|
3566
3566
|
|
|
3567
|
-
if (${
|
|
3568
|
-
newResult[${k}] = ${
|
|
3567
|
+
if (${id2}_present) {
|
|
3568
|
+
newResult[${k}] = ${id2}.value;
|
|
3569
3569
|
}
|
|
3570
3570
|
|
|
3571
3571
|
`);
|
|
3572
3572
|
} else {
|
|
3573
3573
|
doc.write(`
|
|
3574
|
-
if (${
|
|
3574
|
+
if (${id2}.issues.length) {${prefixStr(id2, k)}
|
|
3575
3575
|
}
|
|
3576
3576
|
`);
|
|
3577
3577
|
if (optin === "defaulted") {
|
|
3578
|
-
doc.write(`newResult[${k}] = ${
|
|
3578
|
+
doc.write(`newResult[${k}] = ${id2}.value;`);
|
|
3579
3579
|
} else {
|
|
3580
3580
|
doc.write(`
|
|
3581
|
-
if (${
|
|
3582
|
-
newResult[${k}] = ${
|
|
3581
|
+
if (${id2}.value !== undefined || ${isPresent}) {
|
|
3582
|
+
newResult[${k}] = ${id2}.value;
|
|
3583
3583
|
}
|
|
3584
3584
|
`);
|
|
3585
3585
|
}
|
|
@@ -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, resolve12) {
|
|
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, resolve11) {
|
|
|
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, resolve12);
|
|
4559
4559
|
if (answer > result)
|
|
4560
4560
|
result = answer;
|
|
4561
4561
|
}
|
|
@@ -4566,7 +4566,7 @@ function isRecursive(inst, stack, resolve11) {
|
|
|
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, resolve12) : NONE;
|
|
4570
4570
|
if (child > answer)
|
|
4571
4571
|
answer = child;
|
|
4572
4572
|
}
|
|
@@ -4630,7 +4630,7 @@ function isRecursive(inst, stack, resolve11) {
|
|
|
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 ?? (resolve12 ? 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 base4 = 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 base4(payload, ctx);
|
|
4740
4740
|
};
|
|
4741
4741
|
inst._zod.parse = wrapped;
|
|
4742
|
-
if (inst._zod.run ===
|
|
4742
|
+
if (inst._zod.run === base4)
|
|
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 base4 = 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 = base4;
|
|
4760
4760
|
if (inst._zod.run === wrapped)
|
|
4761
|
-
inst._zod.run =
|
|
4762
|
-
return
|
|
4761
|
+
inst._zod.run = base4;
|
|
4762
|
+
return base4(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 base4(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 = base4(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 === base4)
|
|
4816
4816
|
inst._zod.run = wrapped;
|
|
4817
4817
|
});
|
|
4818
4818
|
}
|
|
@@ -15677,26 +15677,26 @@ function extractDefs(ctx, schema) {
|
|
|
15677
15677
|
return;
|
|
15678
15678
|
const idToSchema = /* @__PURE__ */ new Map();
|
|
15679
15679
|
for (const entry of ctx.seen.entries()) {
|
|
15680
|
-
const
|
|
15681
|
-
if (
|
|
15682
|
-
const existing = idToSchema.get(
|
|
15680
|
+
const id2 = ctx.metadataRegistry.get(entry[0])?.id;
|
|
15681
|
+
if (id2) {
|
|
15682
|
+
const existing = idToSchema.get(id2);
|
|
15683
15683
|
if (existing && existing !== entry[0]) {
|
|
15684
|
-
throw new Error(`Duplicate schema id "${
|
|
15684
|
+
throw new Error(`Duplicate schema id "${id2}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);
|
|
15685
15685
|
}
|
|
15686
|
-
idToSchema.set(
|
|
15686
|
+
idToSchema.set(id2, entry[0]);
|
|
15687
15687
|
}
|
|
15688
15688
|
}
|
|
15689
15689
|
const makeURI = (entry) => {
|
|
15690
15690
|
const defsSegment = ctx.target === "draft-2020-12" ? "$defs" : "definitions";
|
|
15691
15691
|
if (ctx.external) {
|
|
15692
15692
|
const externalId = ctx.external.registry.get(entry[0])?.id;
|
|
15693
|
-
const uriGenerator = ctx.external.uri ?? ((
|
|
15693
|
+
const uriGenerator = ctx.external.uri ?? ((id3) => id3);
|
|
15694
15694
|
if (externalId) {
|
|
15695
15695
|
return { ref: uriGenerator(externalId) };
|
|
15696
15696
|
}
|
|
15697
|
-
const
|
|
15698
|
-
entry[1].defId =
|
|
15699
|
-
return { defId:
|
|
15697
|
+
const id2 = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;
|
|
15698
|
+
entry[1].defId = id2;
|
|
15699
|
+
return { defId: id2, ref: `${uriGenerator("__shared")}#/${defsSegment}/${encodeJSONPointerSegment(id2)}` };
|
|
15700
15700
|
}
|
|
15701
15701
|
const uriPrefix = `#`;
|
|
15702
15702
|
const defUriPrefix = `${uriPrefix}/${defsSegment}/`;
|
|
@@ -15744,8 +15744,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15744
15744
|
continue;
|
|
15745
15745
|
}
|
|
15746
15746
|
}
|
|
15747
|
-
const
|
|
15748
|
-
if (
|
|
15747
|
+
const id2 = ctx.metadataRegistry.get(entry[0])?.id;
|
|
15748
|
+
if (id2) {
|
|
15749
15749
|
extractToDef(entry);
|
|
15750
15750
|
continue;
|
|
15751
15751
|
}
|
|
@@ -15976,10 +15976,10 @@ function finalize(ctx, schema) {
|
|
|
15976
15976
|
} else {
|
|
15977
15977
|
}
|
|
15978
15978
|
if (ctx.external?.uri) {
|
|
15979
|
-
const
|
|
15980
|
-
if (!
|
|
15979
|
+
const id2 = ctx.external.registry.get(schema)?.id;
|
|
15980
|
+
if (!id2)
|
|
15981
15981
|
throw new Error("Schema is missing an `id` property");
|
|
15982
|
-
result.$id = ctx.external.uri(
|
|
15982
|
+
result.$id = ctx.external.uri(id2);
|
|
15983
15983
|
}
|
|
15984
15984
|
assignProps(result, root.defId ? root.schema : root.def ?? root.schema);
|
|
15985
15985
|
const rootMetaId = ctx.metadataRegistry.get(schema)?.id;
|
|
@@ -16165,7 +16165,7 @@ function stringifyKeyNames(bySchema, json2, visited) {
|
|
|
16165
16165
|
const values = json2.enum ?? (json2.const !== void 0 ? [json2.const] : void 0);
|
|
16166
16166
|
if (!numericType && !values?.some((v) => typeof v === "number"))
|
|
16167
16167
|
return json2;
|
|
16168
|
-
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id, ...rest } = json2;
|
|
16168
|
+
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id: id2, ...rest } = json2;
|
|
16169
16169
|
if (rest.enum)
|
|
16170
16170
|
rest.enum = rest.enum.map((v) => typeof v === "number" ? String(v) : v);
|
|
16171
16171
|
else if (typeof rest.const === "number")
|
|
@@ -21918,10 +21918,10 @@ var init_memory = __esm({
|
|
|
21918
21918
|
/** Retrieval API (spec 7.2). The tenant comes from the caller's credential. */
|
|
21919
21919
|
search: "/v1/memory/search",
|
|
21920
21920
|
collection: memoryBase2,
|
|
21921
|
-
one: (tenantId,
|
|
21922
|
-
confirm: (tenantId,
|
|
21923
|
-
promote: (tenantId,
|
|
21924
|
-
unlearn: (tenantId,
|
|
21921
|
+
one: (tenantId, id2) => `${memoryBase2(tenantId)}/${encodeURIComponent(id2)}`,
|
|
21922
|
+
confirm: (tenantId, id2) => `${memoryBase2(tenantId)}/${encodeURIComponent(id2)}/confirm`,
|
|
21923
|
+
promote: (tenantId, id2) => `${memoryBase2(tenantId)}/${encodeURIComponent(id2)}/promote`,
|
|
21924
|
+
unlearn: (tenantId, id2) => `${memoryBase2(tenantId)}/${encodeURIComponent(id2)}/unlearn`,
|
|
21925
21925
|
export: (tenantId) => `${memoryBase2(tenantId)}/export`,
|
|
21926
21926
|
purge: (tenantId) => `${memoryBase2(tenantId)}/purge`,
|
|
21927
21927
|
settings: (tenantId) => `${memoryBase2(tenantId)}/settings`,
|
|
@@ -22170,25 +22170,668 @@ var init_issues = __esm({
|
|
|
22170
22170
|
base2 = (tenantId, projectId) => `/v1/tenants/${encodeURIComponent(tenantId)}/projects/${encodeURIComponent(projectId)}`;
|
|
22171
22171
|
issuePaths = {
|
|
22172
22172
|
issues: (t, p) => `${base2(t, p)}/issues`,
|
|
22173
|
-
issue: (t, p,
|
|
22174
|
-
assign: (t, p,
|
|
22175
|
-
events: (t, p,
|
|
22173
|
+
issue: (t, p, id2) => `${base2(t, p)}/issues/${encodeURIComponent(id2)}`,
|
|
22174
|
+
assign: (t, p, id2) => `${base2(t, p)}/issues/${encodeURIComponent(id2)}/assign`,
|
|
22175
|
+
events: (t, p, id2) => `${base2(t, p)}/issues/${encodeURIComponent(id2)}/events`,
|
|
22176
22176
|
import: (t, p) => `${base2(t, p)}/issues-import`,
|
|
22177
22177
|
workProjects: (t, p) => `${base2(t, p)}/work-projects`,
|
|
22178
|
-
workProject: (t, p,
|
|
22178
|
+
workProject: (t, p, id2) => `${base2(t, p)}/work-projects/${encodeURIComponent(id2)}`,
|
|
22179
22179
|
cycles: (t, p) => `${base2(t, p)}/cycles`,
|
|
22180
22180
|
labels: (t, p) => `${base2(t, p)}/labels`,
|
|
22181
22181
|
views: (t, p) => `${base2(t, p)}/views`,
|
|
22182
|
-
viewRun: (t, p,
|
|
22182
|
+
viewRun: (t, p, id2) => `${base2(t, p)}/views/${encodeURIComponent(id2)}/run`,
|
|
22183
22183
|
loops: (t, p) => `${base2(t, p)}/loops`,
|
|
22184
|
-
loop: (t, p,
|
|
22185
|
-
loopFire: (t, p,
|
|
22184
|
+
loop: (t, p, id2) => `${base2(t, p)}/loops/${encodeURIComponent(id2)}`,
|
|
22185
|
+
loopFire: (t, p, id2) => `${base2(t, p)}/loops/${encodeURIComponent(id2)}/fire`,
|
|
22186
22186
|
sync: (t, p) => `${base2(t, p)}/issue-sync`,
|
|
22187
22187
|
syncDeliveries: (t, p) => `${base2(t, p)}/issue-sync/deliveries`
|
|
22188
22188
|
};
|
|
22189
22189
|
}
|
|
22190
22190
|
});
|
|
22191
22191
|
|
|
22192
|
+
// ../contracts/src/onboarding.ts
|
|
22193
|
+
function initialSteps() {
|
|
22194
|
+
return STEP_NAMES.map((step2, i2) => ({ step: step2, status: i2 === 0 ? "done" : i2 === 1 ? "active" : "pending" }));
|
|
22195
|
+
}
|
|
22196
|
+
function newProgress(tenantId, userId, at) {
|
|
22197
|
+
return { tenantId, userId, step: "agents", steps: initialSteps(), data: {}, version: 0, complete: false, updatedAt: at };
|
|
22198
|
+
}
|
|
22199
|
+
var STEP_NAMES, StepName, StepStatus, RepairAction, FAILURE_REPAIRS, FAILURE_CODES, FailureCodeSchema, StepState, Slug, RepoChoice, OnboardingData, OnboardingProgress, AdvanceRequest, AdvanceResponse, OnboardingEvent, FirstReview, onboardingPaths, PROGRESS_FIXTURE;
|
|
22200
|
+
var init_onboarding = __esm({
|
|
22201
|
+
"../contracts/src/onboarding.ts"() {
|
|
22202
|
+
"use strict";
|
|
22203
|
+
init_zod();
|
|
22204
|
+
init_common();
|
|
22205
|
+
STEP_NAMES = ["sign-up", "agents", "repo", "first-task", "first-review", "invite"];
|
|
22206
|
+
StepName = external_exports.enum(STEP_NAMES);
|
|
22207
|
+
StepStatus = external_exports.enum(["pending", "active", "failed", "done"]);
|
|
22208
|
+
RepairAction = external_exports.object({ id: external_exports.string().regex(/^[a-z][a-z0-9-]{1,48}$/), text: external_exports.string().min(1).max(300) }).strict();
|
|
22209
|
+
FAILURE_REPAIRS = {
|
|
22210
|
+
"sign-in-cancelled": { id: "retry-sign-in", text: "Sign-in was cancelled. Try again, or use the email link." },
|
|
22211
|
+
"agent-not-connected": { id: "retry-connect", text: "The agent has not connected yet. Run the plugin command shown, then check again." },
|
|
22212
|
+
"agent-oauth-denied": { id: "reauthorise", text: "Access was denied in the agent's own sign-in. Approve it there, then check again." },
|
|
22213
|
+
"install-cancelled": { id: "retry-install", text: "The GitHub App install was cancelled. Retry the install, or use a native repository." },
|
|
22214
|
+
"repo-unreachable": { id: "pick-another-repo", text: "That repository could not be read. Pick another, or re-run the install to grant access." },
|
|
22215
|
+
"task-failed": { id: "retry-task", text: "The first task did not finish. Retry it, or pick a smaller template." },
|
|
22216
|
+
"review-unavailable": { id: "reload-review", text: "The review is not ready. Reload it, or open the task to see its evidence." },
|
|
22217
|
+
"invite-failed": { id: "retry-invite", text: "An invitation could not be sent. Check the address and try again, or skip this step." }
|
|
22218
|
+
};
|
|
22219
|
+
FAILURE_CODES = Object.keys(FAILURE_REPAIRS);
|
|
22220
|
+
FailureCodeSchema = external_exports.enum(FAILURE_CODES);
|
|
22221
|
+
StepState = external_exports.object({
|
|
22222
|
+
step: StepName,
|
|
22223
|
+
status: StepStatus,
|
|
22224
|
+
failure: FailureCodeSchema.optional(),
|
|
22225
|
+
repair: RepairAction.optional()
|
|
22226
|
+
}).strict().refine((s) => s.status === "failed" === (s.repair !== void 0 && s.failure !== void 0), { message: "a failed step carries a failure code and a repair action, and no other step does" });
|
|
22227
|
+
Slug = external_exports.string().regex(/^[a-z0-9][a-z0-9-]{0,39}$/);
|
|
22228
|
+
RepoChoice = external_exports.object({
|
|
22229
|
+
kind: external_exports.enum(["github", "native"]),
|
|
22230
|
+
owner: external_exports.string().regex(/^[A-Za-z0-9-]{1,39}$/),
|
|
22231
|
+
name: external_exports.string().regex(/^[A-Za-z0-9._-]{1,100}$/),
|
|
22232
|
+
/** The GitHub App installation number; absent for a native repository. */
|
|
22233
|
+
installationId: external_exports.number().int().positive().optional()
|
|
22234
|
+
}).strict();
|
|
22235
|
+
OnboardingData = external_exports.object({
|
|
22236
|
+
agents: external_exports.array(Slug).max(20).optional(),
|
|
22237
|
+
bots: external_exports.array(Slug).max(20).optional(),
|
|
22238
|
+
repo: RepoChoice.optional(),
|
|
22239
|
+
task: external_exports.object({ templateId: Slug, title: external_exports.string().min(1).max(200) }).strict().optional(),
|
|
22240
|
+
invited: external_exports.number().int().min(0).max(100).optional()
|
|
22241
|
+
}).strict();
|
|
22242
|
+
OnboardingProgress = external_exports.object({
|
|
22243
|
+
tenantId: TenantId,
|
|
22244
|
+
userId: external_exports.string().min(1).max(100),
|
|
22245
|
+
/** The current step: the first one not done, or the last when all are done. */
|
|
22246
|
+
step: StepName,
|
|
22247
|
+
steps: external_exports.array(StepState).length(STEP_NAMES.length),
|
|
22248
|
+
data: OnboardingData,
|
|
22249
|
+
/** Bumped by every transition; a client sends the one it read (optimistic concurrency). */
|
|
22250
|
+
version: external_exports.number().int().min(0),
|
|
22251
|
+
complete: external_exports.boolean(),
|
|
22252
|
+
updatedAt: external_exports.string()
|
|
22253
|
+
}).strict();
|
|
22254
|
+
AdvanceRequest = external_exports.object({
|
|
22255
|
+
step: StepName,
|
|
22256
|
+
expectedVersion: external_exports.number().int().min(0),
|
|
22257
|
+
outcome: external_exports.enum(["done", "failed"]),
|
|
22258
|
+
failure: FailureCodeSchema.optional(),
|
|
22259
|
+
data: OnboardingData.optional()
|
|
22260
|
+
}).strict().refine((r) => r.outcome === "failed" === (r.failure !== void 0), { message: "failure is required with outcome failed, and only then" });
|
|
22261
|
+
AdvanceResponse = external_exports.object({ applied: external_exports.boolean(), progress: OnboardingProgress }).strict();
|
|
22262
|
+
OnboardingEvent = external_exports.object({
|
|
22263
|
+
type: external_exports.enum(["onboarding.step_done", "onboarding.step_failed", "onboarding.resumed"]),
|
|
22264
|
+
tenantId: TenantId,
|
|
22265
|
+
userId: external_exports.string(),
|
|
22266
|
+
step: StepName,
|
|
22267
|
+
at: external_exports.string()
|
|
22268
|
+
}).strict();
|
|
22269
|
+
FirstReview = external_exports.object({
|
|
22270
|
+
/** `fixture` until the review service (MS-A5) is live; the UI says so. */
|
|
22271
|
+
source: external_exports.enum(["fixture", "live"]),
|
|
22272
|
+
taskTitle: external_exports.string(),
|
|
22273
|
+
verdict: external_exports.enum(["approve", "changes_requested"]),
|
|
22274
|
+
summary: external_exports.string(),
|
|
22275
|
+
findings: external_exports.array(external_exports.object({ severity: external_exports.enum(["blocker", "major", "minor", "nit"]), file: external_exports.string(), line: external_exports.number().int().positive(), message: external_exports.string() }).strict()),
|
|
22276
|
+
evidence: external_exports.array(external_exports.object({ check: external_exports.string(), level: external_exports.string(), result: external_exports.enum(["pass", "fail"]) }).strict())
|
|
22277
|
+
}).strict();
|
|
22278
|
+
onboardingPaths = {
|
|
22279
|
+
progress: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/onboarding`,
|
|
22280
|
+
advance: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/onboarding/advance`,
|
|
22281
|
+
firstReview: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/onboarding/first-review`
|
|
22282
|
+
};
|
|
22283
|
+
PROGRESS_FIXTURE = newProgress("tm-fixture", "u-fixture", "2026-10-09T00:00:00.000Z");
|
|
22284
|
+
}
|
|
22285
|
+
});
|
|
22286
|
+
|
|
22287
|
+
// ../contracts/src/review.ts
|
|
22288
|
+
function base3(tenantId, projectId) {
|
|
22289
|
+
return `/v1/tenants/${encodeURIComponent(tenantId)}/projects/${encodeURIComponent(projectId)}/review`;
|
|
22290
|
+
}
|
|
22291
|
+
var SEVERITIES, Severity, FINDING_STATUSES, FindingStatus, counts, Finding, REVIEW_SKIP_REASONS, SkipEntry, SkipList, TokenCapNotice, REVIEW_MODES, ReviewMode, REVIEW_TRIGGERS, REVIEW_STATUSES, ReviewSummary, ReviewRun, REVIEW_PRIVACY_TEXT, ReviewSettings, UpdateReviewSettingsRequest, PullFile, PullRequestSnapshot, ReviewRunRequest, ReviewRunResponse, ReviewStatusResponse, ReviewFindingsResponse, FEEDBACK_KINDS, FeedbackRequest, LearnedRule, FeedbackResponse, AutofixRequest, AutofixResponse, RawFinding, reviewPaths;
|
|
22292
|
+
var init_review = __esm({
|
|
22293
|
+
"../contracts/src/review.ts"() {
|
|
22294
|
+
"use strict";
|
|
22295
|
+
init_zod();
|
|
22296
|
+
init_common();
|
|
22297
|
+
SEVERITIES = ["low", "medium", "high", "critical"];
|
|
22298
|
+
Severity = external_exports.enum(SEVERITIES);
|
|
22299
|
+
FINDING_STATUSES = ["open", "fixed", "dismissed"];
|
|
22300
|
+
FindingStatus = external_exports.enum(FINDING_STATUSES);
|
|
22301
|
+
counts = external_exports.object({ open: external_exports.number().int().nonnegative(), fixed: external_exports.number().int().nonnegative(), dismissed: external_exports.number().int().nonnegative() }).strict();
|
|
22302
|
+
Finding = external_exports.object({
|
|
22303
|
+
tenantId: TenantId,
|
|
22304
|
+
id: external_exports.string().min(1),
|
|
22305
|
+
projectId: ProjectId,
|
|
22306
|
+
repository: external_exports.string().min(1),
|
|
22307
|
+
pullNumber: external_exports.number().int().positive(),
|
|
22308
|
+
path: external_exports.string().min(1),
|
|
22309
|
+
line: external_exports.number().int().positive(),
|
|
22310
|
+
endLine: external_exports.number().int().positive().optional(),
|
|
22311
|
+
severity: Severity,
|
|
22312
|
+
rule: external_exports.string().min(1).optional(),
|
|
22313
|
+
reason: external_exports.string().min(1).max(1e3).optional(),
|
|
22314
|
+
message: external_exports.string().min(1).max(2e3),
|
|
22315
|
+
status: FindingStatus,
|
|
22316
|
+
/** Stable across pushes: path, rule and the normalised text of the flagged line. Never contains source text. */
|
|
22317
|
+
fingerprint: external_exports.string().regex(/^[0-9a-f]{64}$/),
|
|
22318
|
+
commentId: external_exports.string().optional(),
|
|
22319
|
+
firstSeenSha: CommitSha,
|
|
22320
|
+
lastSeenSha: CommitSha,
|
|
22321
|
+
autofixTaskId: TaskId.optional(),
|
|
22322
|
+
autofixAssignee: external_exports.string().min(1).optional(),
|
|
22323
|
+
createdAt: Timestamp,
|
|
22324
|
+
updatedAt: Timestamp
|
|
22325
|
+
}).strict().refine((finding) => finding.rule !== void 0 || finding.reason !== void 0, { message: "a finding needs a rule or a reason" });
|
|
22326
|
+
REVIEW_SKIP_REASONS = ["generated", "vendored", "lockfile", "minified", "binary", "rule"];
|
|
22327
|
+
SkipEntry = external_exports.object({ path: external_exports.string().min(1), reason: external_exports.enum(REVIEW_SKIP_REASONS) }).strict();
|
|
22328
|
+
SkipList = external_exports.array(SkipEntry);
|
|
22329
|
+
TokenCapNotice = external_exports.object({
|
|
22330
|
+
tenantId: TenantId,
|
|
22331
|
+
cap: external_exports.number().int().positive(),
|
|
22332
|
+
used: external_exports.number().int().nonnegative(),
|
|
22333
|
+
partial: external_exports.literal(true),
|
|
22334
|
+
covered: external_exports.number().int().nonnegative(),
|
|
22335
|
+
uncovered: external_exports.array(external_exports.string().min(1))
|
|
22336
|
+
}).strict();
|
|
22337
|
+
REVIEW_MODES = ["log_only", "comments"];
|
|
22338
|
+
ReviewMode = external_exports.enum(REVIEW_MODES);
|
|
22339
|
+
REVIEW_TRIGGERS = ["opened", "push", "manual"];
|
|
22340
|
+
REVIEW_STATUSES = ["completed", "partial", "failed"];
|
|
22341
|
+
ReviewSummary = external_exports.object({
|
|
22342
|
+
tenantId: TenantId,
|
|
22343
|
+
runId: external_exports.string().min(1),
|
|
22344
|
+
headSha: CommitSha,
|
|
22345
|
+
changes: external_exports.object({ files: external_exports.number().int().nonnegative(), additions: external_exports.number().int().nonnegative(), deletions: external_exports.number().int().nonnegative() }).strict(),
|
|
22346
|
+
risks: external_exports.array(external_exports.string()),
|
|
22347
|
+
checks: external_exports.array(external_exports.object({ name: external_exports.string().min(1), state: external_exports.enum(["pass", "fail", "pending"]) }).strict()),
|
|
22348
|
+
counts,
|
|
22349
|
+
skipped: SkipList,
|
|
22350
|
+
notice: TokenCapNotice.optional(),
|
|
22351
|
+
contextSymbols: external_exports.number().int().nonnegative(),
|
|
22352
|
+
/** The rendered comment body: one per PR, updated in place (REQ-REV-03). */
|
|
22353
|
+
body: external_exports.string().min(1)
|
|
22354
|
+
}).strict();
|
|
22355
|
+
ReviewRun = external_exports.object({
|
|
22356
|
+
tenantId: TenantId,
|
|
22357
|
+
id: external_exports.string().min(1),
|
|
22358
|
+
projectId: ProjectId,
|
|
22359
|
+
repository: external_exports.string().min(1),
|
|
22360
|
+
pullNumber: external_exports.number().int().positive(),
|
|
22361
|
+
headSha: CommitSha,
|
|
22362
|
+
trigger: external_exports.enum(REVIEW_TRIGGERS),
|
|
22363
|
+
fork: external_exports.boolean(),
|
|
22364
|
+
mode: ReviewMode,
|
|
22365
|
+
status: external_exports.enum(REVIEW_STATUSES),
|
|
22366
|
+
tokensUsed: external_exports.number().int().nonnegative(),
|
|
22367
|
+
tokenCap: external_exports.number().int().positive(),
|
|
22368
|
+
model: external_exports.string().min(1),
|
|
22369
|
+
posted: external_exports.boolean(),
|
|
22370
|
+
findings: counts,
|
|
22371
|
+
startedAt: Timestamp,
|
|
22372
|
+
completedAt: Timestamp
|
|
22373
|
+
}).strict();
|
|
22374
|
+
REVIEW_PRIVACY_TEXT = "Review sends the diff of a pull request, the code-map context around it and your review rules to a model provider only under terms that exclude training on that data. A fork pull request never receives your secrets.";
|
|
22375
|
+
ReviewSettings = external_exports.object({
|
|
22376
|
+
tenantId: TenantId,
|
|
22377
|
+
projectId: ProjectId,
|
|
22378
|
+
/** Log-only until the owner enables comments (REQ-REV-12). */
|
|
22379
|
+
mode: ReviewMode,
|
|
22380
|
+
tokenCap: external_exports.number().int().min(1e3).max(2e6),
|
|
22381
|
+
skipPatterns: external_exports.array(external_exports.string().min(1).max(256)).max(100),
|
|
22382
|
+
privacy: external_exports.literal(REVIEW_PRIVACY_TEXT),
|
|
22383
|
+
updatedAt: Timestamp.nullable()
|
|
22384
|
+
}).strict();
|
|
22385
|
+
UpdateReviewSettingsRequest = external_exports.object({
|
|
22386
|
+
mode: ReviewMode.optional(),
|
|
22387
|
+
tokenCap: external_exports.number().int().min(1e3).max(2e6).optional(),
|
|
22388
|
+
skipPatterns: external_exports.array(external_exports.string().min(1).max(256)).max(100).optional()
|
|
22389
|
+
}).strict();
|
|
22390
|
+
PullFile = external_exports.object({
|
|
22391
|
+
path: external_exports.string().min(1),
|
|
22392
|
+
status: external_exports.enum(["added", "modified", "removed", "renamed"]).default("modified"),
|
|
22393
|
+
additions: external_exports.number().int().nonnegative().default(0),
|
|
22394
|
+
deletions: external_exports.number().int().nonnegative().default(0),
|
|
22395
|
+
/** Unified diff hunks for the file; absent for binary files. */
|
|
22396
|
+
patch: external_exports.string().max(4e5).optional()
|
|
22397
|
+
}).strict();
|
|
22398
|
+
PullRequestSnapshot = external_exports.object({
|
|
22399
|
+
repository: external_exports.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/),
|
|
22400
|
+
number: external_exports.number().int().positive(),
|
|
22401
|
+
headSha: CommitSha,
|
|
22402
|
+
title: external_exports.string().max(500),
|
|
22403
|
+
body: external_exports.string().max(6e4).default(""),
|
|
22404
|
+
author: external_exports.string().min(1),
|
|
22405
|
+
/** The head comes from a fork: no secrets are ever handed to the run (REQ-REV-09). */
|
|
22406
|
+
fork: external_exports.boolean().default(false),
|
|
22407
|
+
files: external_exports.array(PullFile).max(3e3)
|
|
22408
|
+
}).strict();
|
|
22409
|
+
ReviewRunRequest = external_exports.object({
|
|
22410
|
+
requestId: external_exports.string().min(1).max(128),
|
|
22411
|
+
trigger: external_exports.enum(REVIEW_TRIGGERS).default("manual"),
|
|
22412
|
+
source: external_exports.discriminatedUnion("kind", [
|
|
22413
|
+
external_exports.object({ kind: external_exports.literal("github"), repository: external_exports.string().min(1), number: external_exports.number().int().positive() }).strict(),
|
|
22414
|
+
external_exports.object({ kind: external_exports.literal("inline"), pull: PullRequestSnapshot }).strict()
|
|
22415
|
+
])
|
|
22416
|
+
}).strict();
|
|
22417
|
+
ReviewRunResponse = external_exports.object({
|
|
22418
|
+
run: ReviewRun,
|
|
22419
|
+
summary: ReviewSummary,
|
|
22420
|
+
findings: external_exports.array(Finding),
|
|
22421
|
+
replay: external_exports.boolean()
|
|
22422
|
+
}).strict();
|
|
22423
|
+
ReviewStatusResponse = external_exports.object({ tenantId: TenantId, projectId: ProjectId, settings: ReviewSettings, runs: external_exports.array(ReviewRun), openFindings: external_exports.number().int().nonnegative() }).strict();
|
|
22424
|
+
ReviewFindingsResponse = external_exports.object({ tenantId: TenantId, findings: external_exports.array(Finding) }).strict();
|
|
22425
|
+
FEEDBACK_KINDS = ["accept", "dismiss", "reply"];
|
|
22426
|
+
FeedbackRequest = external_exports.object({ kind: external_exports.enum(FEEDBACK_KINDS), note: external_exports.string().max(1e3).optional(), requestId: external_exports.string().min(1).max(128) }).strict();
|
|
22427
|
+
LearnedRule = external_exports.object({
|
|
22428
|
+
tenantId: TenantId,
|
|
22429
|
+
rule: external_exports.string().min(1),
|
|
22430
|
+
direction: external_exports.enum(["suppress", "boost"]),
|
|
22431
|
+
evidence: external_exports.number().int().positive(),
|
|
22432
|
+
memoryId: external_exports.string().optional()
|
|
22433
|
+
}).strict();
|
|
22434
|
+
FeedbackResponse = external_exports.object({ finding: Finding, learned: LearnedRule.nullable() }).strict();
|
|
22435
|
+
AutofixRequest = external_exports.object({ requestId: external_exports.string().min(1).max(128), assignee: external_exports.string().min(1).max(128).optional() }).strict();
|
|
22436
|
+
AutofixResponse = external_exports.object({ finding: Finding, taskId: TaskId, assignee: external_exports.string().nullable(), replay: external_exports.boolean() }).strict();
|
|
22437
|
+
RawFinding = external_exports.object({
|
|
22438
|
+
path: external_exports.string().min(1),
|
|
22439
|
+
line: external_exports.number().int().positive(),
|
|
22440
|
+
endLine: external_exports.number().int().positive().optional(),
|
|
22441
|
+
severity: Severity,
|
|
22442
|
+
rule: external_exports.string().min(1).max(100).optional(),
|
|
22443
|
+
reason: external_exports.string().min(1).max(1e3).optional(),
|
|
22444
|
+
message: external_exports.string().min(1).max(2e3)
|
|
22445
|
+
}).strict();
|
|
22446
|
+
reviewPaths = {
|
|
22447
|
+
runs: (tenantId, projectId) => `${base3(tenantId, projectId)}/runs`,
|
|
22448
|
+
status: (tenantId, projectId) => `${base3(tenantId, projectId)}/status`,
|
|
22449
|
+
settings: (tenantId, projectId) => `${base3(tenantId, projectId)}/settings`,
|
|
22450
|
+
findings: (tenantId, projectId) => `${base3(tenantId, projectId)}/findings`,
|
|
22451
|
+
feedback: (tenantId, projectId, id2) => `${base3(tenantId, projectId)}/findings/${encodeURIComponent(id2)}/feedback`,
|
|
22452
|
+
autofix: (tenantId, projectId, id2) => `${base3(tenantId, projectId)}/findings/${encodeURIComponent(id2)}/autofix`
|
|
22453
|
+
};
|
|
22454
|
+
}
|
|
22455
|
+
});
|
|
22456
|
+
|
|
22457
|
+
// ../contracts/src/guardrails.ts
|
|
22458
|
+
function globToRegExp(pattern) {
|
|
22459
|
+
let source = "";
|
|
22460
|
+
for (let i2 = 0; i2 < pattern.length; i2 += 1) {
|
|
22461
|
+
const char = pattern[i2];
|
|
22462
|
+
if (char === "*") {
|
|
22463
|
+
if (pattern[i2 + 1] === "*") {
|
|
22464
|
+
source += ".*";
|
|
22465
|
+
i2 += 1;
|
|
22466
|
+
if (pattern[i2 + 1] === "/") i2 += 1;
|
|
22467
|
+
} else source += "[^/]*";
|
|
22468
|
+
} else if (char === "?") source += "[^/]";
|
|
22469
|
+
else source += char.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
22470
|
+
}
|
|
22471
|
+
return new RegExp(`^${source}$`);
|
|
22472
|
+
}
|
|
22473
|
+
function globMatches(pattern, value) {
|
|
22474
|
+
return globToRegExp(pattern).test(value);
|
|
22475
|
+
}
|
|
22476
|
+
function anyGlob(patterns, values) {
|
|
22477
|
+
if (patterns === void 0) return true;
|
|
22478
|
+
return values.some((value) => patterns.some((pattern) => globMatches(pattern, value)));
|
|
22479
|
+
}
|
|
22480
|
+
function inWindow(window3, at) {
|
|
22481
|
+
if (window3 === void 0) return true;
|
|
22482
|
+
const date5 = new Date(at);
|
|
22483
|
+
if (window3.days !== void 0 && !window3.days.includes(date5.getUTCDay())) return false;
|
|
22484
|
+
const hour = date5.getUTCHours();
|
|
22485
|
+
const from = window3.fromHour ?? 0;
|
|
22486
|
+
const to = window3.toHour ?? 24;
|
|
22487
|
+
return from <= to ? hour >= from && hour < to : hour >= from || hour < to;
|
|
22488
|
+
}
|
|
22489
|
+
function ruleMatches(rule, request) {
|
|
22490
|
+
const m = rule.match;
|
|
22491
|
+
if (m.principals !== void 0 && !anyGlob(m.principals, [`${request.principal.kind}:${request.principal.id}`, request.principal.id])) return false;
|
|
22492
|
+
if (m.roles !== void 0 && !m.roles.includes(request.principal.role)) return false;
|
|
22493
|
+
if (m.tools !== void 0 && !anyGlob(m.tools, [request.tool])) return false;
|
|
22494
|
+
if (m.paths !== void 0 && !anyGlob(m.paths, request.paths)) return false;
|
|
22495
|
+
if (m.branches !== void 0 && (request.branch === void 0 || !anyGlob(m.branches, [request.branch]))) return false;
|
|
22496
|
+
if (m.repositories !== void 0 && (request.repository === void 0 || !anyGlob(m.repositories, [request.repository]))) return false;
|
|
22497
|
+
if (m.environments !== void 0 && (request.environment === void 0 || !anyGlob(m.environments, [request.environment]))) return false;
|
|
22498
|
+
if (m.hosts !== void 0 && (request.host === void 0 || !anyGlob(m.hosts, [request.host]))) return false;
|
|
22499
|
+
if (!inWindow(m.time, request.at)) return false;
|
|
22500
|
+
if (m.usage !== void 0 && (request.usage[m.usage.metric] ?? 0) < m.usage.atLeast) return false;
|
|
22501
|
+
if (m.taskHeld !== void 0 && request.taskHeld !== m.taskHeld) return false;
|
|
22502
|
+
return true;
|
|
22503
|
+
}
|
|
22504
|
+
function describeFor(effect, ruleId, message) {
|
|
22505
|
+
if (message !== void 0) return message;
|
|
22506
|
+
return effect === "deny" ? `blocked by rule ${ruleId}` : `rule ${ruleId} requires approval before this runs`;
|
|
22507
|
+
}
|
|
22508
|
+
function composeDecision(tenantId, layers, request) {
|
|
22509
|
+
const matched = [];
|
|
22510
|
+
let winner = null;
|
|
22511
|
+
let dryWinner = null;
|
|
22512
|
+
const ordered = [...layers].sort((a, b) => GUARD_LAYERS.indexOf(a.layer) - GUARD_LAYERS.indexOf(b.layer));
|
|
22513
|
+
for (const { layer: layer2, rules } of ordered) {
|
|
22514
|
+
const live = rules.find((rule2) => !rule2.dryRun && ruleMatches(rule2, request));
|
|
22515
|
+
for (const rule2 of rules) {
|
|
22516
|
+
if (rule2.dryRun && ruleMatches(rule2, request)) {
|
|
22517
|
+
matched.push({ ruleId: rule2.id, layer: layer2, effect: rule2.effect, dryRun: true });
|
|
22518
|
+
if (rule2.effect !== "allow" && (dryWinner === null || EFFECT_STRENGTH[rule2.effect] > EFFECT_STRENGTH[dryWinner.rule.effect])) dryWinner = { layer: layer2, rule: rule2 };
|
|
22519
|
+
}
|
|
22520
|
+
}
|
|
22521
|
+
if (live === void 0) continue;
|
|
22522
|
+
matched.push({ ruleId: live.id, layer: layer2, effect: live.effect, dryRun: false });
|
|
22523
|
+
if (winner === null || EFFECT_STRENGTH[live.effect] > EFFECT_STRENGTH[winner.rule.effect]) winner = { layer: layer2, rule: live };
|
|
22524
|
+
}
|
|
22525
|
+
if (winner === null || winner.rule.effect === "allow") {
|
|
22526
|
+
const wouldBlock = dryWinner !== null;
|
|
22527
|
+
return {
|
|
22528
|
+
tenantId,
|
|
22529
|
+
effect: "allow",
|
|
22530
|
+
allowed: true,
|
|
22531
|
+
code: null,
|
|
22532
|
+
ruleId: winner?.rule.id ?? null,
|
|
22533
|
+
layer: winner?.layer ?? null,
|
|
22534
|
+
message: wouldBlock && dryWinner !== null ? `allowed; dry-run rule ${dryWinner.rule.id} would have blocked this` : "allowed",
|
|
22535
|
+
nextCommand: null,
|
|
22536
|
+
exitCode: 0,
|
|
22537
|
+
dryRun: wouldBlock,
|
|
22538
|
+
wouldBlock,
|
|
22539
|
+
matched
|
|
22540
|
+
};
|
|
22541
|
+
}
|
|
22542
|
+
const { rule, layer } = winner;
|
|
22543
|
+
return {
|
|
22544
|
+
tenantId,
|
|
22545
|
+
effect: rule.effect,
|
|
22546
|
+
allowed: false,
|
|
22547
|
+
code: rule.code ?? (rule.effect === "deny" ? "policy_denied" : "approval_required"),
|
|
22548
|
+
ruleId: rule.id,
|
|
22549
|
+
layer,
|
|
22550
|
+
message: describeFor(rule.effect, rule.id, rule.message),
|
|
22551
|
+
nextCommand: rule.nextCommand ?? DEFAULT_NEXT[rule.effect],
|
|
22552
|
+
exitCode: GUARD_EXIT_CODE,
|
|
22553
|
+
dryRun: false,
|
|
22554
|
+
wouldBlock: true,
|
|
22555
|
+
matched
|
|
22556
|
+
};
|
|
22557
|
+
}
|
|
22558
|
+
var GUARD_LAYERS, GuardLayer, GUARD_EFFECTS, GuardEffect, GUARD_CODES, GuardCode, GUARD_EXIT_CODE, glob, globs, GuardTimeWindow, GuardUsageMatch, GuardMatch, GuardRuleSource, GuardRuleFileSource, GuardRule, GuardRuleFileRecord, PutGuardRuleFileRequest, GuardRequest, GuardMatchedRule, GuardDecision, GUARD_APPROVAL_STATUSES, GUARD_AUTONOMY_MODES, GuardAutonomy, GuardApproval, AnswerGuardApprovalRequest, GuardEvaluateRequest, SECRET_SOURCES, SecretFinding, SecretScanResult, GuardEvaluateResponse, GuardRulesResponse, EFFECT_STRENGTH, DEFAULT_NEXT, guardPaths, APPROVAL_HEADER;
|
|
22559
|
+
var init_guardrails = __esm({
|
|
22560
|
+
"../contracts/src/guardrails.ts"() {
|
|
22561
|
+
"use strict";
|
|
22562
|
+
init_zod();
|
|
22563
|
+
init_common();
|
|
22564
|
+
init_identity();
|
|
22565
|
+
GUARD_LAYERS = ["platform", "team", "project"];
|
|
22566
|
+
GuardLayer = external_exports.enum(GUARD_LAYERS);
|
|
22567
|
+
GUARD_EFFECTS = ["allow", "deny", "require_approval"];
|
|
22568
|
+
GuardEffect = external_exports.enum(GUARD_EFFECTS);
|
|
22569
|
+
GUARD_CODES = [
|
|
22570
|
+
"policy_denied",
|
|
22571
|
+
"approval_required",
|
|
22572
|
+
"protected_branch",
|
|
22573
|
+
"path_protected",
|
|
22574
|
+
"spend_cap_reached",
|
|
22575
|
+
"plan_limit_reached",
|
|
22576
|
+
"egress_blocked",
|
|
22577
|
+
"deploy_blocked",
|
|
22578
|
+
"secret_detected",
|
|
22579
|
+
"task_required"
|
|
22580
|
+
];
|
|
22581
|
+
GuardCode = external_exports.enum(GUARD_CODES);
|
|
22582
|
+
GUARD_EXIT_CODE = 6;
|
|
22583
|
+
glob = external_exports.string().min(1).max(256);
|
|
22584
|
+
globs = external_exports.array(glob).min(1).max(64);
|
|
22585
|
+
GuardTimeWindow = external_exports.object({
|
|
22586
|
+
days: external_exports.array(external_exports.number().int().min(0).max(6)).min(1).max(7).optional(),
|
|
22587
|
+
fromHour: external_exports.number().int().min(0).max(23).optional(),
|
|
22588
|
+
toHour: external_exports.number().int().min(1).max(24).optional()
|
|
22589
|
+
}).strict();
|
|
22590
|
+
GuardUsageMatch = external_exports.object({ metric: external_exports.string().min(1).max(64), atLeast: external_exports.number().nonnegative() }).strict();
|
|
22591
|
+
GuardMatch = external_exports.object({
|
|
22592
|
+
principals: globs.optional(),
|
|
22593
|
+
roles: external_exports.array(Role).min(1).optional(),
|
|
22594
|
+
tools: globs.optional(),
|
|
22595
|
+
paths: globs.optional(),
|
|
22596
|
+
branches: globs.optional(),
|
|
22597
|
+
repositories: globs.optional(),
|
|
22598
|
+
environments: globs.optional(),
|
|
22599
|
+
hosts: globs.optional(),
|
|
22600
|
+
time: GuardTimeWindow.optional(),
|
|
22601
|
+
usage: GuardUsageMatch.optional(),
|
|
22602
|
+
/** The caller holds an active task (ADR 0038). */
|
|
22603
|
+
taskHeld: external_exports.boolean().optional()
|
|
22604
|
+
}).strict();
|
|
22605
|
+
GuardRuleSource = external_exports.object({
|
|
22606
|
+
id: external_exports.string().regex(/^[a-z0-9][a-z0-9._-]{1,63}$/, "use lowercase letters, digits, . _ -"),
|
|
22607
|
+
description: external_exports.string().min(1).max(400),
|
|
22608
|
+
effect: GuardEffect,
|
|
22609
|
+
match: GuardMatch,
|
|
22610
|
+
/** Report what the rule would block without blocking (REQ-GRD-08). */
|
|
22611
|
+
dryRun: external_exports.boolean().default(false),
|
|
22612
|
+
code: GuardCode.optional(),
|
|
22613
|
+
/** Plain-language reason shown to the person or agent that was refused. */
|
|
22614
|
+
message: external_exports.string().min(1).max(400).optional(),
|
|
22615
|
+
/** The exact next command or approval path (REQ-GRD-12). */
|
|
22616
|
+
nextCommand: external_exports.string().min(1).max(200).optional()
|
|
22617
|
+
}).strict();
|
|
22618
|
+
GuardRuleFileSource = external_exports.object({
|
|
22619
|
+
version: external_exports.literal("1"),
|
|
22620
|
+
rules: external_exports.array(GuardRuleSource).max(200)
|
|
22621
|
+
}).strict().superRefine((file2, ctx) => {
|
|
22622
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22623
|
+
file2.rules.forEach((rule, index) => {
|
|
22624
|
+
if (seen.has(rule.id)) ctx.addIssue({ code: "custom", path: ["rules", index, "id"], message: `duplicate rule id ${rule.id}` });
|
|
22625
|
+
seen.add(rule.id);
|
|
22626
|
+
});
|
|
22627
|
+
});
|
|
22628
|
+
GuardRule = GuardRuleSource.extend({
|
|
22629
|
+
tenantId: TenantId,
|
|
22630
|
+
layer: GuardLayer,
|
|
22631
|
+
projectId: ProjectId.optional(),
|
|
22632
|
+
fileVersion: external_exports.number().int().positive()
|
|
22633
|
+
}).strict();
|
|
22634
|
+
GuardRuleFileRecord = external_exports.object({
|
|
22635
|
+
tenantId: TenantId,
|
|
22636
|
+
layer: GuardLayer,
|
|
22637
|
+
projectId: ProjectId.optional(),
|
|
22638
|
+
version: external_exports.number().int().positive(),
|
|
22639
|
+
digest: Sha256Digest,
|
|
22640
|
+
ruleCount: external_exports.number().int().nonnegative(),
|
|
22641
|
+
author: external_exports.string().min(1),
|
|
22642
|
+
reason: external_exports.string().min(1).max(400).optional(),
|
|
22643
|
+
createdAt: Timestamp
|
|
22644
|
+
}).strict();
|
|
22645
|
+
PutGuardRuleFileRequest = external_exports.object({
|
|
22646
|
+
requestId: external_exports.string().min(1).max(128),
|
|
22647
|
+
layer: GuardLayer.exclude(["platform"]).default("team"),
|
|
22648
|
+
projectId: ProjectId.optional(),
|
|
22649
|
+
/** The rule file text (JSON). Kept as text so the digest and the reviewed file are the same bytes. */
|
|
22650
|
+
content: external_exports.string().min(2).max(256e3),
|
|
22651
|
+
reason: external_exports.string().min(1).max(400).optional()
|
|
22652
|
+
}).strict();
|
|
22653
|
+
GuardRequest = external_exports.object({
|
|
22654
|
+
tenantId: TenantId,
|
|
22655
|
+
projectId: ProjectId.optional(),
|
|
22656
|
+
principal: external_exports.object({ kind: external_exports.enum(["user", "agent", "bot", "system"]), id: external_exports.string().min(1), role: Role }).strict(),
|
|
22657
|
+
/** `api.write`, `git.push`, `git.merge`, `ci.run`, `deploy.run`, `egress.fetch`, `task.create`, `review.run`, ... */
|
|
22658
|
+
tool: external_exports.string().min(1).max(128),
|
|
22659
|
+
paths: external_exports.array(external_exports.string().min(1)).max(2e3).default([]),
|
|
22660
|
+
branch: external_exports.string().min(1).optional(),
|
|
22661
|
+
repository: external_exports.string().min(1).optional(),
|
|
22662
|
+
environment: external_exports.string().min(1).optional(),
|
|
22663
|
+
host: external_exports.string().min(1).optional(),
|
|
22664
|
+
at: Timestamp,
|
|
22665
|
+
usage: external_exports.record(external_exports.string(), external_exports.number().nonnegative()).default({}),
|
|
22666
|
+
taskHeld: external_exports.boolean().optional(),
|
|
22667
|
+
/** For approve-before-write: what the action does in plain language and the change it would make (REQ-GRD-09). */
|
|
22668
|
+
summary: external_exports.string().min(1).max(2e3).optional(),
|
|
22669
|
+
diff: external_exports.string().max(1e5).optional()
|
|
22670
|
+
}).strict();
|
|
22671
|
+
GuardMatchedRule = external_exports.object({ ruleId: external_exports.string().min(1), layer: GuardLayer, effect: GuardEffect, dryRun: external_exports.boolean() }).strict();
|
|
22672
|
+
GuardDecision = external_exports.object({
|
|
22673
|
+
tenantId: TenantId,
|
|
22674
|
+
effect: GuardEffect,
|
|
22675
|
+
allowed: external_exports.boolean(),
|
|
22676
|
+
code: GuardCode.nullable(),
|
|
22677
|
+
ruleId: external_exports.string().nullable(),
|
|
22678
|
+
layer: GuardLayer.nullable(),
|
|
22679
|
+
message: external_exports.string().min(1),
|
|
22680
|
+
nextCommand: external_exports.string().nullable(),
|
|
22681
|
+
exitCode: external_exports.union([external_exports.literal(0), external_exports.literal(GUARD_EXIT_CODE)]),
|
|
22682
|
+
/** True when a dry-run rule matched and would have blocked. */
|
|
22683
|
+
dryRun: external_exports.boolean(),
|
|
22684
|
+
wouldBlock: external_exports.boolean(),
|
|
22685
|
+
approvalId: external_exports.string().optional(),
|
|
22686
|
+
matched: external_exports.array(GuardMatchedRule)
|
|
22687
|
+
}).strict().superRefine((decision, ctx) => {
|
|
22688
|
+
if (decision.effect !== "allow" && decision.allowed) ctx.addIssue({ code: "custom", path: ["allowed"], message: "a deny or approval decision is not allowed" });
|
|
22689
|
+
if (!decision.allowed && (decision.code === null || decision.ruleId === null || decision.nextCommand === null)) {
|
|
22690
|
+
ctx.addIssue({ code: "custom", message: "a refusal carries a code, a rule ID and the next command" });
|
|
22691
|
+
}
|
|
22692
|
+
if (!decision.allowed && decision.exitCode !== GUARD_EXIT_CODE) ctx.addIssue({ code: "custom", path: ["exitCode"], message: "a refusal exits with 6" });
|
|
22693
|
+
});
|
|
22694
|
+
GUARD_APPROVAL_STATUSES = ["pending", "approved", "denied"];
|
|
22695
|
+
GUARD_AUTONOMY_MODES = ["autonomous", "supervised", "manual"];
|
|
22696
|
+
GuardAutonomy = external_exports.enum(GUARD_AUTONOMY_MODES);
|
|
22697
|
+
GuardApproval = external_exports.object({
|
|
22698
|
+
tenantId: TenantId,
|
|
22699
|
+
id: external_exports.string().min(1),
|
|
22700
|
+
projectId: ProjectId.optional(),
|
|
22701
|
+
ruleId: external_exports.string().min(1),
|
|
22702
|
+
tool: external_exports.string().min(1),
|
|
22703
|
+
requestedBy: external_exports.string().min(1),
|
|
22704
|
+
summary: external_exports.string().min(1),
|
|
22705
|
+
diff: external_exports.string().nullable(),
|
|
22706
|
+
status: external_exports.enum(GUARD_APPROVAL_STATUSES),
|
|
22707
|
+
/** Hash of the action the approval covers; a changed action needs a new approval. */
|
|
22708
|
+
actionDigest: Sha256Digest,
|
|
22709
|
+
decidedBy: external_exports.string().nullable(),
|
|
22710
|
+
/** Who approved: an independent second agent satisfies an approval; a person always can. */
|
|
22711
|
+
approverKind: external_exports.enum(["user", "agent"]).nullable(),
|
|
22712
|
+
evidence: external_exports.array(external_exports.string()),
|
|
22713
|
+
reason: external_exports.string().nullable(),
|
|
22714
|
+
decidedAt: Timestamp.nullable(),
|
|
22715
|
+
createdAt: Timestamp
|
|
22716
|
+
}).strict();
|
|
22717
|
+
AnswerGuardApprovalRequest = external_exports.object({ decision: external_exports.enum(["approve", "deny"]), reason: external_exports.string().min(1).max(400).optional(), evidence: external_exports.array(external_exports.string().min(1).max(400)).max(20).optional() }).strict();
|
|
22718
|
+
GuardEvaluateRequest = external_exports.object({
|
|
22719
|
+
tool: external_exports.string().min(1).max(128),
|
|
22720
|
+
paths: external_exports.array(external_exports.string().min(1)).max(2e3).optional(),
|
|
22721
|
+
branch: external_exports.string().optional(),
|
|
22722
|
+
repository: external_exports.string().optional(),
|
|
22723
|
+
environment: external_exports.string().optional(),
|
|
22724
|
+
host: external_exports.string().optional(),
|
|
22725
|
+
taskHeld: external_exports.boolean().optional(),
|
|
22726
|
+
summary: external_exports.string().min(1).max(2e3).optional(),
|
|
22727
|
+
diff: external_exports.string().max(1e5).optional(),
|
|
22728
|
+
/** Text the action would write (push content, log lines); scanned for secrets (REQ-GRD-05). */
|
|
22729
|
+
content: external_exports.string().max(1e6).optional(),
|
|
22730
|
+
/** Evaluate without recording an approval request or blocking. */
|
|
22731
|
+
dryRun: external_exports.boolean().optional(),
|
|
22732
|
+
/** Optional test overrides, honoured only for an explicit rule test. */
|
|
22733
|
+
principalOverride: external_exports.object({ kind: external_exports.enum(["user", "agent", "bot", "system"]), id: external_exports.string().min(1), role: Role }).strict().optional(),
|
|
22734
|
+
usage: external_exports.record(external_exports.string(), external_exports.number().nonnegative()).optional(),
|
|
22735
|
+
at: Timestamp.optional()
|
|
22736
|
+
}).strict();
|
|
22737
|
+
SECRET_SOURCES = ["push", "task", "evidence", "log", "memory", "api"];
|
|
22738
|
+
SecretFinding = external_exports.object({
|
|
22739
|
+
tenantId: TenantId,
|
|
22740
|
+
source: external_exports.enum(SECRET_SOURCES),
|
|
22741
|
+
rule: external_exports.string().min(1),
|
|
22742
|
+
/** Provider-prefixed keys block; generic high-entropy strings are reported only. */
|
|
22743
|
+
disposition: external_exports.enum(["blocked", "reported"]),
|
|
22744
|
+
path: external_exports.string().optional(),
|
|
22745
|
+
line: external_exports.number().int().positive().optional()
|
|
22746
|
+
}).strict();
|
|
22747
|
+
SecretScanResult = external_exports.object({ tenantId: TenantId, blocked: external_exports.boolean(), findings: external_exports.array(SecretFinding) }).strict();
|
|
22748
|
+
GuardEvaluateResponse = external_exports.object({ decision: GuardDecision, secrets: SecretScanResult.nullable() }).strict();
|
|
22749
|
+
GuardRulesResponse = external_exports.object({ tenantId: TenantId, files: external_exports.array(GuardRuleFileRecord), rules: external_exports.array(GuardRule) }).strict();
|
|
22750
|
+
EFFECT_STRENGTH = { allow: 0, require_approval: 1, deny: 2 };
|
|
22751
|
+
DEFAULT_NEXT = {
|
|
22752
|
+
allow: null,
|
|
22753
|
+
deny: "overlane guard rules list",
|
|
22754
|
+
require_approval: "overlane guard approvals list"
|
|
22755
|
+
};
|
|
22756
|
+
guardPaths = {
|
|
22757
|
+
base: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/guard`,
|
|
22758
|
+
rules: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/guard/rules`,
|
|
22759
|
+
evaluate: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/guard/evaluate`,
|
|
22760
|
+
approvals: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/guard/approvals`,
|
|
22761
|
+
approval: (tenantId, id2) => `/v1/tenants/${encodeURIComponent(tenantId)}/guard/approvals/${encodeURIComponent(id2)}`,
|
|
22762
|
+
answer: (tenantId, id2) => `/v1/tenants/${encodeURIComponent(tenantId)}/guard/approvals/${encodeURIComponent(id2)}/answer`,
|
|
22763
|
+
scan: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/guard/scan`
|
|
22764
|
+
};
|
|
22765
|
+
APPROVAL_HEADER = "x-overlane-approval";
|
|
22766
|
+
}
|
|
22767
|
+
});
|
|
22768
|
+
|
|
22769
|
+
// ../contracts/src/code-map.ts
|
|
22770
|
+
function codeMapDefault(setting, results = GATE_07_LATEST) {
|
|
22771
|
+
const result = results[setting];
|
|
22772
|
+
if (result.verdict === "failed") return { setting, on: false, basis: "gate-07-failed", reason: `off: ${result.summary} (${result.evidence})`, gate07: "failed" };
|
|
22773
|
+
if (result.verdict === "passed") return { setting, on: true, basis: "gate-07-passed", reason: `on: ${result.summary} (${result.evidence})`, gate07: "passed" };
|
|
22774
|
+
const on = SPEC_DEFAULT[setting];
|
|
22775
|
+
if (result.verdict === "pending") {
|
|
22776
|
+
return { setting, on, basis: "spec-default-provisional", reason: `${on ? "on" : "off"} by the spec default, provisional: ${result.summary} (${result.evidence})`, gate07: "pending" };
|
|
22777
|
+
}
|
|
22778
|
+
return { setting, on, basis: "spec-default", reason: `${on ? "on" : "off"} by the spec default: ${result.summary}`, gate07: "not-applicable" };
|
|
22779
|
+
}
|
|
22780
|
+
var CODE_MAP_SETTINGS, CodeMapSetting, GATE_07_VERDICTS, Gate07Verdict, GATE_07_LATEST, SPEC_DEFAULT, CODE_MAP_BASES, CodeMapDefault, CodeMapClientStatus, CodeMapStatus, codeMapPaths;
|
|
22781
|
+
var init_code_map = __esm({
|
|
22782
|
+
"../contracts/src/code-map.ts"() {
|
|
22783
|
+
"use strict";
|
|
22784
|
+
init_zod();
|
|
22785
|
+
init_clients();
|
|
22786
|
+
init_common();
|
|
22787
|
+
CODE_MAP_SETTINGS = ["local-agent-with-grep", "cloud-session", "bot", "review-service", "cross-repo", "wiki"];
|
|
22788
|
+
CodeMapSetting = external_exports.enum(CODE_MAP_SETTINGS);
|
|
22789
|
+
GATE_07_VERDICTS = ["passed", "failed", "pending", "not-applicable"];
|
|
22790
|
+
Gate07Verdict = external_exports.enum(GATE_07_VERDICTS);
|
|
22791
|
+
GATE_07_LATEST = {
|
|
22792
|
+
"local-agent-with-grep": {
|
|
22793
|
+
verdict: "failed",
|
|
22794
|
+
summary: "GATE-07 failed with a local checkout and grep: cueline 115% and afltables 109% of the native-search token cost",
|
|
22795
|
+
evidence: "ADR 0018, docs/findings/gate-07-preliminary.md, docs/findings/gate-07-realism-afltables.md"
|
|
22796
|
+
},
|
|
22797
|
+
"cloud-session": {
|
|
22798
|
+
verdict: "pending",
|
|
22799
|
+
summary: "re-run for agents without a checkout: the mechanical leg is recorded, the agent leg waits on a model",
|
|
22800
|
+
evidence: "docs/findings/MS-A5-results.md (MS-A5.6)"
|
|
22801
|
+
},
|
|
22802
|
+
bot: {
|
|
22803
|
+
verdict: "pending",
|
|
22804
|
+
summary: "re-run for agents without a checkout: the mechanical leg is recorded, the agent leg waits on a model",
|
|
22805
|
+
evidence: "docs/findings/MS-A5-results.md (MS-A5.6)"
|
|
22806
|
+
},
|
|
22807
|
+
"review-service": { verdict: "not-applicable", summary: "the review service has no grep to compare with; it uses the map as context", evidence: "ADR 0032 decision 3" },
|
|
22808
|
+
"cross-repo": { verdict: "not-applicable", summary: "cross-repository questions have no single checkout to search", evidence: "ADR 0032 decision 2" },
|
|
22809
|
+
wiki: { verdict: "not-applicable", summary: "the generated wiki is built from the map", evidence: "ADR 0032 decision 3" }
|
|
22810
|
+
};
|
|
22811
|
+
SPEC_DEFAULT = {
|
|
22812
|
+
"local-agent-with-grep": false,
|
|
22813
|
+
"cloud-session": true,
|
|
22814
|
+
bot: true,
|
|
22815
|
+
"review-service": true,
|
|
22816
|
+
"cross-repo": true,
|
|
22817
|
+
wiki: true
|
|
22818
|
+
};
|
|
22819
|
+
CODE_MAP_BASES = ["gate-07-failed", "gate-07-passed", "spec-default-provisional", "spec-default", "project-setting"];
|
|
22820
|
+
CodeMapDefault = external_exports.object({ setting: CodeMapSetting, on: external_exports.boolean(), basis: external_exports.enum(CODE_MAP_BASES), reason: external_exports.string().min(1), gate07: Gate07Verdict }).strict();
|
|
22821
|
+
CodeMapClientStatus = external_exports.object({ subject: external_exports.string().min(1), client: external_exports.string().min(1), setting: CodeMapSetting, on: external_exports.boolean(), basis: external_exports.enum(CODE_MAP_BASES), reason: external_exports.string().min(1), gate07: Gate07Verdict }).strict();
|
|
22822
|
+
CodeMapStatus = external_exports.object({
|
|
22823
|
+
tenantId: TenantId,
|
|
22824
|
+
projectId: ProjectId,
|
|
22825
|
+
/** ADR 0018: the Worker serves code routes and the MCP code tool only when the project turns the code layer on. */
|
|
22826
|
+
projectCodeLayer: external_exports.boolean(),
|
|
22827
|
+
clients: external_exports.array(CodeMapClientStatus)
|
|
22828
|
+
}).strict();
|
|
22829
|
+
codeMapPaths = {
|
|
22830
|
+
status: (tenantId, projectId) => `/v1/tenants/${encodeURIComponent(tenantId)}/projects/${encodeURIComponent(projectId)}/code-map/status`
|
|
22831
|
+
};
|
|
22832
|
+
}
|
|
22833
|
+
});
|
|
22834
|
+
|
|
22192
22835
|
// ../contracts/src/index.ts
|
|
22193
22836
|
var init_src = __esm({
|
|
22194
22837
|
"../contracts/src/index.ts"() {
|
|
@@ -22214,6 +22857,10 @@ var init_src = __esm({
|
|
|
22214
22857
|
init_clients();
|
|
22215
22858
|
init_memory();
|
|
22216
22859
|
init_issues();
|
|
22860
|
+
init_onboarding();
|
|
22861
|
+
init_review();
|
|
22862
|
+
init_guardrails();
|
|
22863
|
+
init_code_map();
|
|
22217
22864
|
}
|
|
22218
22865
|
});
|
|
22219
22866
|
|
|
@@ -29548,12 +30195,12 @@ var require_dist = __commonJS({
|
|
|
29548
30195
|
});
|
|
29549
30196
|
|
|
29550
30197
|
// src/assets.ts
|
|
29551
|
-
import { basename as basename3, join as join24, resolve as
|
|
30198
|
+
import { basename as basename3, join as join24, resolve as resolve9 } from "node:path";
|
|
29552
30199
|
import { fileURLToPath } from "node:url";
|
|
29553
30200
|
function packageRoot(env = process.env) {
|
|
29554
30201
|
const override = env["MVRX_PACKAGE_ROOT"];
|
|
29555
30202
|
if (override !== void 0 && override !== "") return override;
|
|
29556
|
-
return
|
|
30203
|
+
return resolve9(fileURLToPath(new URL(".", import.meta.url)), "..");
|
|
29557
30204
|
}
|
|
29558
30205
|
function assetDir(env = process.env) {
|
|
29559
30206
|
const override = env["MVRX_ASSET_DIR"];
|
|
@@ -29566,7 +30213,7 @@ var VERSION;
|
|
|
29566
30213
|
var init_assets = __esm({
|
|
29567
30214
|
"src/assets.ts"() {
|
|
29568
30215
|
"use strict";
|
|
29569
|
-
VERSION = true ? "0.1.
|
|
30216
|
+
VERSION = true ? "0.1.120" : "0.0.0-dev";
|
|
29570
30217
|
}
|
|
29571
30218
|
});
|
|
29572
30219
|
|
|
@@ -29661,13 +30308,13 @@ function int64FromString(dec) {
|
|
|
29661
30308
|
if (minus) {
|
|
29662
30309
|
dec = dec.slice(1);
|
|
29663
30310
|
}
|
|
29664
|
-
const
|
|
30311
|
+
const base4 = 1e6;
|
|
29665
30312
|
let lowBits = 0;
|
|
29666
30313
|
let highBits = 0;
|
|
29667
30314
|
function add1e6digit(begin, end) {
|
|
29668
30315
|
const digit1e6 = Number(dec.slice(begin, end));
|
|
29669
|
-
highBits *=
|
|
29670
|
-
lowBits = lowBits *
|
|
30316
|
+
highBits *= base4;
|
|
30317
|
+
lowBits = lowBits * base4 + digit1e6;
|
|
29671
30318
|
if (lowBits >= TWO_PWR_32_DBL) {
|
|
29672
30319
|
highBits = highBits + (lowBits / TWO_PWR_32_DBL | 0);
|
|
29673
30320
|
lowBits = lowBits % TWO_PWR_32_DBL;
|
|
@@ -29699,14 +30346,14 @@ function uInt64ToString(lo, hi) {
|
|
|
29699
30346
|
let digitA = low + mid * 6777216 + high * 6710656;
|
|
29700
30347
|
let digitB = mid + high * 8147497;
|
|
29701
30348
|
let digitC = high * 2;
|
|
29702
|
-
const
|
|
29703
|
-
if (digitA >=
|
|
29704
|
-
digitB += Math.floor(digitA /
|
|
29705
|
-
digitA %=
|
|
30349
|
+
const base4 = 1e7;
|
|
30350
|
+
if (digitA >= base4) {
|
|
30351
|
+
digitB += Math.floor(digitA / base4);
|
|
30352
|
+
digitA %= base4;
|
|
29706
30353
|
}
|
|
29707
|
-
if (digitB >=
|
|
29708
|
-
digitC += Math.floor(digitB /
|
|
29709
|
-
digitB %=
|
|
30354
|
+
if (digitB >= base4) {
|
|
30355
|
+
digitC += Math.floor(digitB / base4);
|
|
30356
|
+
digitB %= base4;
|
|
29710
30357
|
}
|
|
29711
30358
|
return digitC.toString() + decimalFrom1e7WithLeadingZeros(digitB) + decimalFrom1e7WithLeadingZeros(digitA);
|
|
29712
30359
|
}
|
|
@@ -30984,7 +31631,7 @@ function createFileRegistry(...args2) {
|
|
|
30984
31631
|
if (seen.has(protoFileName)) {
|
|
30985
31632
|
continue;
|
|
30986
31633
|
}
|
|
30987
|
-
const dep =
|
|
31634
|
+
const dep = resolve12(protoFileName);
|
|
30988
31635
|
if (!dep) {
|
|
30989
31636
|
throw new Error(`Unable to resolve ${protoFileName}, imported by ${file2.name}`);
|
|
30990
31637
|
}
|
|
@@ -30998,7 +31645,7 @@ function createFileRegistry(...args2) {
|
|
|
30998
31645
|
return deps.concat(...deps.map(recurseDeps));
|
|
30999
31646
|
};
|
|
31000
31647
|
const input2 = args2[0];
|
|
31001
|
-
const
|
|
31648
|
+
const resolve12 = args2[1];
|
|
31002
31649
|
const seen = /* @__PURE__ */ new Set();
|
|
31003
31650
|
for (const file2 of [input2, ...recurseDeps(input2)].reverse()) {
|
|
31004
31651
|
addFile(file2, registry2);
|
|
@@ -32531,7 +33178,7 @@ var init_codegenv2 = __esm({
|
|
|
32531
33178
|
});
|
|
32532
33179
|
|
|
32533
33180
|
// ../../node_modules/.pnpm/@scip-code+scip@0.10.0/node_modules/@scip-code/scip/dist/scip_pb.js
|
|
32534
|
-
var file_scip, IndexSchema, Descriptor_Suffix, SymbolInformation_Kind, ProtocolVersion, TextEncoding, PositionEncoding, SymbolRole, SyntaxKind,
|
|
33181
|
+
var file_scip, IndexSchema, Descriptor_Suffix, SymbolInformation_Kind, ProtocolVersion, TextEncoding, PositionEncoding, SymbolRole, SyntaxKind, Severity2, DiagnosticTag, Language;
|
|
32535
33182
|
var init_scip_pb = __esm({
|
|
32536
33183
|
"../../node_modules/.pnpm/@scip-code+scip@0.10.0/node_modules/@scip-code/scip/dist/scip_pb.js"() {
|
|
32537
33184
|
init_codegenv2();
|
|
@@ -32703,13 +33350,13 @@ var init_scip_pb = __esm({
|
|
|
32703
33350
|
SyntaxKind2[SyntaxKind2["TagAttribute"] = 35] = "TagAttribute";
|
|
32704
33351
|
SyntaxKind2[SyntaxKind2["TagDelimiter"] = 36] = "TagDelimiter";
|
|
32705
33352
|
})(SyntaxKind || (SyntaxKind = {}));
|
|
32706
|
-
(function(
|
|
32707
|
-
|
|
32708
|
-
|
|
32709
|
-
|
|
32710
|
-
|
|
32711
|
-
|
|
32712
|
-
})(
|
|
33353
|
+
(function(Severity3) {
|
|
33354
|
+
Severity3[Severity3["UnspecifiedSeverity"] = 0] = "UnspecifiedSeverity";
|
|
33355
|
+
Severity3[Severity3["Error"] = 1] = "Error";
|
|
33356
|
+
Severity3[Severity3["Warning"] = 2] = "Warning";
|
|
33357
|
+
Severity3[Severity3["Information"] = 3] = "Information";
|
|
33358
|
+
Severity3[Severity3["Hint"] = 4] = "Hint";
|
|
33359
|
+
})(Severity2 || (Severity2 = {}));
|
|
32713
33360
|
(function(DiagnosticTag2) {
|
|
32714
33361
|
DiagnosticTag2[DiagnosticTag2["UnspecifiedDiagnosticTag"] = 0] = "UnspecifiedDiagnosticTag";
|
|
32715
33362
|
DiagnosticTag2[DiagnosticTag2["Unnecessary"] = 1] = "Unnecessary";
|
|
@@ -32833,10 +33480,10 @@ var init_scip_pb = __esm({
|
|
|
32833
33480
|
|
|
32834
33481
|
// ../index-builder/src/languages.ts
|
|
32835
33482
|
function languageForPath(path) {
|
|
32836
|
-
const
|
|
32837
|
-
const dot =
|
|
33483
|
+
const base4 = path.slice(path.lastIndexOf("/") + 1);
|
|
33484
|
+
const dot = base4.lastIndexOf(".");
|
|
32838
33485
|
if (dot <= 0) return null;
|
|
32839
|
-
return BY_EXTENSION.get(
|
|
33486
|
+
return BY_EXTENSION.get(base4.slice(dot).toLowerCase()) ?? null;
|
|
32840
33487
|
}
|
|
32841
33488
|
var BY_EXTENSION;
|
|
32842
33489
|
var init_languages = __esm({
|
|
@@ -33256,9 +33903,9 @@ function marshalNode(node2, index = 0) {
|
|
|
33256
33903
|
C.setValue(address, node2[0], "i32");
|
|
33257
33904
|
}
|
|
33258
33905
|
function unmarshalNode(tree, address = TRANSFER_BUFFER) {
|
|
33259
|
-
const
|
|
33906
|
+
const id2 = C.getValue(address, "i32");
|
|
33260
33907
|
address += SIZE_OF_INT;
|
|
33261
|
-
if (
|
|
33908
|
+
if (id2 === 0) return null;
|
|
33262
33909
|
const index = C.getValue(address, "i32");
|
|
33263
33910
|
address += SIZE_OF_INT;
|
|
33264
33911
|
const row = C.getValue(address, "i32");
|
|
@@ -33267,7 +33914,7 @@ function unmarshalNode(tree, address = TRANSFER_BUFFER) {
|
|
|
33267
33914
|
address += SIZE_OF_INT;
|
|
33268
33915
|
const other = C.getValue(address, "i32");
|
|
33269
33916
|
const result = new Node(INTERNAL, {
|
|
33270
|
-
id,
|
|
33917
|
+
id: id2,
|
|
33271
33918
|
tree,
|
|
33272
33919
|
startIndex: index,
|
|
33273
33920
|
startPosition: { row, column },
|
|
@@ -33411,13 +34058,13 @@ async function Module2(moduleArg = {}) {
|
|
|
33411
34058
|
}
|
|
33412
34059
|
readAsync = /* @__PURE__ */ __name(async (url2) => {
|
|
33413
34060
|
if (isFileURI(url2)) {
|
|
33414
|
-
return new Promise((
|
|
34061
|
+
return new Promise((resolve12, reject) => {
|
|
33415
34062
|
var xhr = new XMLHttpRequest();
|
|
33416
34063
|
xhr.open("GET", url2, true);
|
|
33417
34064
|
xhr.responseType = "arraybuffer";
|
|
33418
34065
|
xhr.onload = () => {
|
|
33419
34066
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
33420
|
-
|
|
34067
|
+
resolve12(xhr.response);
|
|
33421
34068
|
return;
|
|
33422
34069
|
}
|
|
33423
34070
|
reject(xhr.status);
|
|
@@ -33613,9 +34260,9 @@ async function Module2(moduleArg = {}) {
|
|
|
33613
34260
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
33614
34261
|
var info2 = getWasmImports();
|
|
33615
34262
|
if (Module["instantiateWasm"]) {
|
|
33616
|
-
return new Promise((
|
|
34263
|
+
return new Promise((resolve12, reject) => {
|
|
33617
34264
|
Module["instantiateWasm"](info2, (mod, inst) => {
|
|
33618
|
-
|
|
34265
|
+
resolve12(receiveInstance(mod, inst));
|
|
33619
34266
|
});
|
|
33620
34267
|
});
|
|
33621
34268
|
}
|
|
@@ -34356,7 +35003,7 @@ async function Module2(moduleArg = {}) {
|
|
|
34356
35003
|
}, "reportUndefinedSymbols");
|
|
34357
35004
|
var runDependencies = 0;
|
|
34358
35005
|
var dependenciesFulfilled = null;
|
|
34359
|
-
var removeRunDependency = /* @__PURE__ */ __name((
|
|
35006
|
+
var removeRunDependency = /* @__PURE__ */ __name((id2) => {
|
|
34360
35007
|
runDependencies--;
|
|
34361
35008
|
Module["monitorRunDependencies"]?.(runDependencies);
|
|
34362
35009
|
if (runDependencies == 0) {
|
|
@@ -34367,7 +35014,7 @@ async function Module2(moduleArg = {}) {
|
|
|
34367
35014
|
}
|
|
34368
35015
|
}
|
|
34369
35016
|
}, "removeRunDependency");
|
|
34370
|
-
var addRunDependency = /* @__PURE__ */ __name((
|
|
35017
|
+
var addRunDependency = /* @__PURE__ */ __name((id2) => {
|
|
34371
35018
|
runDependencies++;
|
|
34372
35019
|
Module["monitorRunDependencies"]?.(runDependencies);
|
|
34373
35020
|
}, "addRunDependency");
|
|
@@ -34948,8 +35595,8 @@ async function Module2(moduleArg = {}) {
|
|
|
34948
35595
|
if (runtimeInitialized) {
|
|
34949
35596
|
moduleRtn = Module;
|
|
34950
35597
|
} else {
|
|
34951
|
-
moduleRtn = new Promise((
|
|
34952
|
-
readyPromiseResolve =
|
|
35598
|
+
moduleRtn = new Promise((resolve12, reject) => {
|
|
35599
|
+
readyPromiseResolve = resolve12;
|
|
34953
35600
|
readyPromiseReject = reject;
|
|
34954
35601
|
});
|
|
34955
35602
|
}
|
|
@@ -35287,9 +35934,9 @@ var init_web_tree_sitter = __esm({
|
|
|
35287
35934
|
* Returns `null` if the iterator is not positioned on a symbol.
|
|
35288
35935
|
*/
|
|
35289
35936
|
get currentType() {
|
|
35290
|
-
const
|
|
35291
|
-
if (
|
|
35292
|
-
return this.language.types[
|
|
35937
|
+
const id2 = this.currentTypeId;
|
|
35938
|
+
if (id2 === null) return null;
|
|
35939
|
+
return this.language.types[id2] ?? C.UTF8ToString(C._ts_language_symbol_name(this.language[0], id2));
|
|
35293
35940
|
}
|
|
35294
35941
|
/** Delete the lookahead iterator, freeing its resources. */
|
|
35295
35942
|
delete() {
|
|
@@ -35753,7 +36400,7 @@ var init_web_tree_sitter = __esm({
|
|
|
35753
36400
|
_namedChildren;
|
|
35754
36401
|
/** @internal */
|
|
35755
36402
|
constructor(internal, {
|
|
35756
|
-
id,
|
|
36403
|
+
id: id2,
|
|
35757
36404
|
tree,
|
|
35758
36405
|
startIndex,
|
|
35759
36406
|
startPosition,
|
|
@@ -35761,7 +36408,7 @@ var init_web_tree_sitter = __esm({
|
|
|
35761
36408
|
}) {
|
|
35762
36409
|
assertInternal(internal);
|
|
35763
36410
|
this[0] = other;
|
|
35764
|
-
this.id =
|
|
36411
|
+
this.id = id2;
|
|
35765
36412
|
this.tree = tree;
|
|
35766
36413
|
this.startIndex = startIndex;
|
|
35767
36414
|
this.startPosition = startPosition;
|
|
@@ -37283,19 +37930,19 @@ function collect(extract, nodes, scope, parentId, prefix, path, symbols2, occurr
|
|
|
37283
37930
|
for (const node2 of nodes) {
|
|
37284
37931
|
for (const decl of extract(node2, scope)) {
|
|
37285
37932
|
const qualified = prefix === "" ? decl.name : `${prefix}.${decl.name}`;
|
|
37286
|
-
const
|
|
37287
|
-
if (symbols2.has(
|
|
37933
|
+
const id2 = `decl ${path}#${qualified}`;
|
|
37934
|
+
if (symbols2.has(id2)) continue;
|
|
37288
37935
|
const range = rangeOf(decl.nameNode);
|
|
37289
|
-
symbols2.set(
|
|
37290
|
-
symbol:
|
|
37936
|
+
symbols2.set(id2, {
|
|
37937
|
+
symbol: id2,
|
|
37291
37938
|
name: decl.name,
|
|
37292
37939
|
kind: decl.kind,
|
|
37293
37940
|
range,
|
|
37294
37941
|
enclosingRange: rangeOf(decl.outer),
|
|
37295
37942
|
...parentId ? { parent: parentId } : {}
|
|
37296
37943
|
});
|
|
37297
|
-
occurrences.push({ symbol:
|
|
37298
|
-
if (decl.members.length > 0) collect(extract, decl.members, decl.memberScope,
|
|
37944
|
+
occurrences.push({ symbol: id2, range, definition: true, ...parentId ? { enclosingSymbol: parentId } : {} });
|
|
37945
|
+
if (decl.members.length > 0) collect(extract, decl.members, decl.memberScope, id2, qualified, path, symbols2, occurrences);
|
|
37299
37946
|
}
|
|
37300
37947
|
}
|
|
37301
37948
|
}
|
|
@@ -37605,7 +38252,7 @@ var init_snapshot = __esm({
|
|
|
37605
38252
|
// ../index-builder/src/upload.ts
|
|
37606
38253
|
async function uploadSnapshot(options) {
|
|
37607
38254
|
const doFetch = options.fetch ?? fetch;
|
|
37608
|
-
const
|
|
38255
|
+
const base4 = options.serviceUrl.replace(/\/+$/, "");
|
|
37609
38256
|
const manifest = SnapshotManifest.parse(options.manifest);
|
|
37610
38257
|
const { tenantId, repository, commitSha } = manifest;
|
|
37611
38258
|
const headers = { authorization: `Bearer ${options.token}`, "content-type": "application/json" };
|
|
@@ -37613,7 +38260,7 @@ async function uploadSnapshot(options) {
|
|
|
37613
38260
|
for (let attempt2 = 1; ; attempt2 += 1) {
|
|
37614
38261
|
let failure4;
|
|
37615
38262
|
try {
|
|
37616
|
-
const response = await doFetch(`${
|
|
38263
|
+
const response = await doFetch(`${base4}${path}`, { method: "POST", headers, body: body2 });
|
|
37617
38264
|
if (response.ok) return response;
|
|
37618
38265
|
const retryable = response.status === 429 || response.status >= 500;
|
|
37619
38266
|
if (!retryable || attempt2 >= ATTEMPTS) {
|
|
@@ -37625,7 +38272,7 @@ async function uploadSnapshot(options) {
|
|
|
37625
38272
|
failure4 = error62 instanceof Error ? error62.message : String(error62);
|
|
37626
38273
|
if (attempt2 >= ATTEMPTS) throw new Error(`POST ${path} failed: ${failure4}`);
|
|
37627
38274
|
}
|
|
37628
|
-
await new Promise((
|
|
38275
|
+
await new Promise((resolve12) => setTimeout(resolve12, (options.retryDelayMs ?? 500) * attempt2));
|
|
37629
38276
|
}
|
|
37630
38277
|
};
|
|
37631
38278
|
const manifestResponse = await send2(codePaths.uploadManifest(tenantId, repository.owner, repository.name), JSON.stringify(manifest));
|
|
@@ -37703,7 +38350,7 @@ var init_oidc = __esm({
|
|
|
37703
38350
|
// ../index-builder/src/run.ts
|
|
37704
38351
|
import { execFile as execFile2 } from "node:child_process";
|
|
37705
38352
|
import { mkdir as mkdir3, readdir as readdir4, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
|
|
37706
|
-
import { join as join26, resolve as
|
|
38353
|
+
import { join as join26, resolve as resolve10 } from "node:path";
|
|
37707
38354
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
37708
38355
|
import { promisify as promisify2 } from "node:util";
|
|
37709
38356
|
async function git3(root, args2) {
|
|
@@ -37724,7 +38371,7 @@ async function repositoryFromRemote(root) {
|
|
|
37724
38371
|
}
|
|
37725
38372
|
}
|
|
37726
38373
|
async function snapshotFromArgs(values, env) {
|
|
37727
|
-
const root =
|
|
38374
|
+
const root = resolve10(typeof values["root"] === "string" ? values["root"] : process.cwd());
|
|
37728
38375
|
const repoText = (typeof values["repo"] === "string" ? values["repo"] : void 0) ?? env["GITHUB_REPOSITORY"] ?? await repositoryFromRemote(root);
|
|
37729
38376
|
if (!repoText) throw new UsageError2("cannot determine the repository; pass --repo owner/name");
|
|
37730
38377
|
const commit = (typeof values["commit"] === "string" ? values["commit"] : void 0) ?? env["GITHUB_SHA"] ?? await git3(root, ["rev-parse", "HEAD"]);
|
|
@@ -37734,7 +38381,7 @@ async function snapshotFromArgs(values, env) {
|
|
|
37734
38381
|
const scip = Array.isArray(values["scip"]) ? values["scip"] : [];
|
|
37735
38382
|
return buildSnapshot({
|
|
37736
38383
|
repoRoot: root,
|
|
37737
|
-
scipFiles: scip.map((file2) =>
|
|
38384
|
+
scipFiles: scip.map((file2) => resolve10(file2)),
|
|
37738
38385
|
tenantId: tenant,
|
|
37739
38386
|
repository: parseRepository(repoText),
|
|
37740
38387
|
commitSha: commit,
|
|
@@ -37749,8 +38396,8 @@ async function runCli2(argv, env, out2 = console.log, err2 = console.error) {
|
|
|
37749
38396
|
const outDir = values.out;
|
|
37750
38397
|
if (!outDir) throw new UsageError2("build needs --out DIR");
|
|
37751
38398
|
const built = await snapshotFromArgs({ ...values, tenant: values.tenant ?? env["HARNESS_TENANT"] ?? "local" }, env);
|
|
37752
|
-
await writeSnapshot(
|
|
37753
|
-
out2(`built ${built.shards.length} shards (${built.uncovered.length} files uncovered) into ${
|
|
38399
|
+
await writeSnapshot(resolve10(outDir), built);
|
|
38400
|
+
out2(`built ${built.shards.length} shards (${built.uncovered.length} files uncovered) into ${resolve10(outDir)}`);
|
|
37754
38401
|
return 0;
|
|
37755
38402
|
}
|
|
37756
38403
|
if (command === "upload") {
|
|
@@ -39835,8 +40482,8 @@ function buildSchemas2025() {
|
|
|
39835
40482
|
function isNonObjectJsonSchemaRoot(json2) {
|
|
39836
40483
|
return json2["type"] !== "object";
|
|
39837
40484
|
}
|
|
39838
|
-
function establishesNewBase(
|
|
39839
|
-
return
|
|
40485
|
+
function establishesNewBase(id2) {
|
|
40486
|
+
return id2 !== void 0 && !(typeof id2 === "string" && id2.startsWith("#"));
|
|
39840
40487
|
}
|
|
39841
40488
|
function wrapOutputSchemaForLegacy(natural) {
|
|
39842
40489
|
const $schema = typeof natural["$schema"] === "string" ? natural["$schema"] : void 0;
|
|
@@ -41378,14 +42025,14 @@ function inputRequiredRoundsExceededMessage(method, maxRounds) {
|
|
|
41378
42025
|
return `Multi-round-trip request '${method}' still required input after ${maxRounds} rounds (inputRequired.maxRounds)`;
|
|
41379
42026
|
}
|
|
41380
42027
|
function sleep2(ms, signal) {
|
|
41381
|
-
return new Promise((
|
|
42028
|
+
return new Promise((resolve12, reject) => {
|
|
41382
42029
|
if (signal?.aborted) {
|
|
41383
42030
|
reject(signal.reason instanceof SdkError ? signal.reason : new SdkError(SdkErrorCode.RequestTimeout, String(signal.reason)));
|
|
41384
42031
|
return;
|
|
41385
42032
|
}
|
|
41386
42033
|
const timer = setTimeout(() => {
|
|
41387
42034
|
signal?.removeEventListener("abort", onAbort);
|
|
41388
|
-
|
|
42035
|
+
resolve12();
|
|
41389
42036
|
}, ms);
|
|
41390
42037
|
const onAbort = () => {
|
|
41391
42038
|
clearTimeout(timer);
|
|
@@ -41491,8 +42138,8 @@ function setNegotiatedProtocolVersion(instance2, version2) {
|
|
|
41491
42138
|
function isPlainObject$1(value) {
|
|
41492
42139
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
41493
42140
|
}
|
|
41494
|
-
function mergeCapabilities(
|
|
41495
|
-
const result = { ...
|
|
42141
|
+
function mergeCapabilities(base4, additional) {
|
|
42142
|
+
const result = { ...base4 };
|
|
41496
42143
|
for (const key in additional) {
|
|
41497
42144
|
const k = key;
|
|
41498
42145
|
const addValue = additional[k];
|
|
@@ -43181,7 +43828,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
43181
43828
|
const flowStartedAt = Date.now();
|
|
43182
43829
|
let onAbort;
|
|
43183
43830
|
let cleanupMessageId;
|
|
43184
|
-
return new Promise((
|
|
43831
|
+
return new Promise((resolve12, reject) => {
|
|
43185
43832
|
const earlyReject = (error62) => {
|
|
43186
43833
|
reject(error62);
|
|
43187
43834
|
};
|
|
@@ -43249,7 +43896,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
43249
43896
|
}
|
|
43250
43897
|
if (decoded.kind === "invalid") return reject(decoded.error);
|
|
43251
43898
|
if (decoded.kind === "input_required") {
|
|
43252
|
-
if (options?.allowInputRequired === true) return
|
|
43899
|
+
if (options?.allowInputRequired === true) return resolve12(manualInputRequiredValue(decoded));
|
|
43253
43900
|
const flow = {
|
|
43254
43901
|
codec: codec2,
|
|
43255
43902
|
request,
|
|
@@ -43261,11 +43908,11 @@ var init_src_CX2iR2pK = __esm({
|
|
|
43261
43908
|
params
|
|
43262
43909
|
}, resultSchema2, legOptions)
|
|
43263
43910
|
};
|
|
43264
|
-
return
|
|
43911
|
+
return resolve12(this._resolveNonCompleteResult(decoded, flow));
|
|
43265
43912
|
}
|
|
43266
43913
|
const result = decoded.result;
|
|
43267
43914
|
validateStandardSchema(resultSchema2, result).then((parseResult) => {
|
|
43268
|
-
if (parseResult.success)
|
|
43915
|
+
if (parseResult.success) resolve12(parseResult.data);
|
|
43269
43916
|
else reject(new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${request.method}: ${parseResult.error}`));
|
|
43270
43917
|
}, reject);
|
|
43271
43918
|
});
|
|
@@ -45456,9 +46103,9 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
45456
46103
|
}
|
|
45457
46104
|
return count;
|
|
45458
46105
|
}
|
|
45459
|
-
function getFullPath(resolver,
|
|
45460
|
-
if (normalize !== false)
|
|
45461
|
-
return _getFullPath(resolver, resolver.parse(
|
|
46106
|
+
function getFullPath(resolver, id2 = "", normalize) {
|
|
46107
|
+
if (normalize !== false) id2 = normalizeId(id2);
|
|
46108
|
+
return _getFullPath(resolver, resolver.parse(id2));
|
|
45462
46109
|
}
|
|
45463
46110
|
exports.getFullPath = getFullPath;
|
|
45464
46111
|
function _getFullPath(resolver, p) {
|
|
@@ -45466,13 +46113,13 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
45466
46113
|
}
|
|
45467
46114
|
exports._getFullPath = _getFullPath;
|
|
45468
46115
|
const TRAILING_SLASH_HASH = /#\/?$/;
|
|
45469
|
-
function normalizeId(
|
|
45470
|
-
return
|
|
46116
|
+
function normalizeId(id2) {
|
|
46117
|
+
return id2 ? id2.replace(TRAILING_SLASH_HASH, "") : "";
|
|
45471
46118
|
}
|
|
45472
46119
|
exports.normalizeId = normalizeId;
|
|
45473
|
-
function resolveUrl(resolver, baseId,
|
|
45474
|
-
|
|
45475
|
-
return resolver.resolve(baseId,
|
|
46120
|
+
function resolveUrl(resolver, baseId, id2) {
|
|
46121
|
+
id2 = normalizeId(id2);
|
|
46122
|
+
return resolver.resolve(baseId, id2);
|
|
45476
46123
|
}
|
|
45477
46124
|
exports.resolveUrl = resolveUrl;
|
|
45478
46125
|
const ANCHOR = /^[a-z_][-a-z0-9._]*$/i;
|
|
@@ -46081,7 +46728,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
46081
46728
|
ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
|
|
46082
46729
|
const schOrFunc = root.refs[ref];
|
|
46083
46730
|
if (schOrFunc) return schOrFunc;
|
|
46084
|
-
let _sch =
|
|
46731
|
+
let _sch = resolve12.call(this, root, ref);
|
|
46085
46732
|
if (_sch === void 0) {
|
|
46086
46733
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
46087
46734
|
const { schemaId } = this.opts;
|
|
@@ -46107,7 +46754,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
46107
46754
|
function sameSchemaEnv(s1, s2) {
|
|
46108
46755
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
46109
46756
|
}
|
|
46110
|
-
function
|
|
46757
|
+
function resolve12(root, ref) {
|
|
46111
46758
|
let sch;
|
|
46112
46759
|
while (typeof (sch = this.refs[ref]) == "string") ref = sch;
|
|
46113
46760
|
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
|
|
@@ -46117,8 +46764,8 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
46117
46764
|
const refPath = (0, resolve_1._getFullPath)(this.opts.uriResolver, p);
|
|
46118
46765
|
let baseId = (0, resolve_1.getFullPath)(this.opts.uriResolver, root.baseId, void 0);
|
|
46119
46766
|
if (Object.keys(root.schema).length > 0 && refPath === baseId) return getJsonPointer.call(this, p, root);
|
|
46120
|
-
const
|
|
46121
|
-
const schOrRef = this.refs[
|
|
46767
|
+
const id2 = (0, resolve_1.normalizeId)(refPath);
|
|
46768
|
+
const schOrRef = this.refs[id2] || this.schemas[id2];
|
|
46122
46769
|
if (typeof schOrRef == "string") {
|
|
46123
46770
|
const sch = resolveSchema.call(this, root, schOrRef);
|
|
46124
46771
|
if (typeof (sch === null || sch === void 0 ? void 0 : sch.schema) !== "object") return;
|
|
@@ -46126,7 +46773,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
46126
46773
|
}
|
|
46127
46774
|
if (typeof (schOrRef === null || schOrRef === void 0 ? void 0 : schOrRef.schema) !== "object") return;
|
|
46128
46775
|
if (!schOrRef.validate) compileSchema.call(this, schOrRef);
|
|
46129
|
-
if (
|
|
46776
|
+
if (id2 === (0, resolve_1.normalizeId)(ref)) {
|
|
46130
46777
|
const { schema } = schOrRef;
|
|
46131
46778
|
const { schemaId } = this.opts;
|
|
46132
46779
|
const schId = schema[schemaId];
|
|
@@ -46557,16 +47204,16 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
46557
47204
|
else if (typeof uri === "object") uri = parse5(serialize(uri, options), options);
|
|
46558
47205
|
return uri;
|
|
46559
47206
|
}
|
|
46560
|
-
function
|
|
47207
|
+
function resolve12(baseURI, relativeURI, options) {
|
|
46561
47208
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
46562
47209
|
const resolved = resolveComponent(parse5(baseURI, schemelessOptions), parse5(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
46563
47210
|
schemelessOptions.skipEscape = true;
|
|
46564
47211
|
return serialize(resolved, schemelessOptions);
|
|
46565
47212
|
}
|
|
46566
|
-
function resolveComponent(
|
|
47213
|
+
function resolveComponent(base4, relative4, options, skipNormalization) {
|
|
46567
47214
|
const target = {};
|
|
46568
47215
|
if (!skipNormalization) {
|
|
46569
|
-
|
|
47216
|
+
base4 = parse5(serialize(base4, options), options);
|
|
46570
47217
|
relative4 = parse5(serialize(relative4, options), options);
|
|
46571
47218
|
}
|
|
46572
47219
|
options = options || {};
|
|
@@ -46586,24 +47233,24 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
46586
47233
|
target.query = relative4.query;
|
|
46587
47234
|
} else {
|
|
46588
47235
|
if (!relative4.path) {
|
|
46589
|
-
target.path =
|
|
47236
|
+
target.path = base4.path;
|
|
46590
47237
|
if (relative4.query !== void 0) target.query = relative4.query;
|
|
46591
|
-
else target.query =
|
|
47238
|
+
else target.query = base4.query;
|
|
46592
47239
|
} else {
|
|
46593
47240
|
if (relative4.path[0] === "/") target.path = removeDotSegments(relative4.path);
|
|
46594
47241
|
else {
|
|
46595
|
-
if ((
|
|
46596
|
-
else if (!
|
|
46597
|
-
else target.path =
|
|
47242
|
+
if ((base4.userinfo !== void 0 || base4.host !== void 0 || base4.port !== void 0) && !base4.path) target.path = "/" + relative4.path;
|
|
47243
|
+
else if (!base4.path) target.path = relative4.path;
|
|
47244
|
+
else target.path = base4.path.slice(0, base4.path.lastIndexOf("/") + 1) + relative4.path;
|
|
46598
47245
|
target.path = removeDotSegments(target.path);
|
|
46599
47246
|
}
|
|
46600
47247
|
target.query = relative4.query;
|
|
46601
47248
|
}
|
|
46602
|
-
target.userinfo =
|
|
46603
|
-
target.host =
|
|
46604
|
-
target.port =
|
|
47249
|
+
target.userinfo = base4.userinfo;
|
|
47250
|
+
target.host = base4.host;
|
|
47251
|
+
target.port = base4.port;
|
|
46605
47252
|
}
|
|
46606
|
-
target.scheme =
|
|
47253
|
+
target.scheme = base4.scheme;
|
|
46607
47254
|
}
|
|
46608
47255
|
target.fragment = relative4.fragment;
|
|
46609
47256
|
return target;
|
|
@@ -46731,7 +47378,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
46731
47378
|
const fastUri = {
|
|
46732
47379
|
SCHEMES,
|
|
46733
47380
|
normalize,
|
|
46734
|
-
resolve:
|
|
47381
|
+
resolve: resolve12,
|
|
46735
47382
|
resolveComponent,
|
|
46736
47383
|
equal,
|
|
46737
47384
|
serialize,
|
|
@@ -46994,13 +47641,13 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
46994
47641
|
for (const sch of schema) this.addSchema(sch, void 0, _meta, _validateSchema);
|
|
46995
47642
|
return this;
|
|
46996
47643
|
}
|
|
46997
|
-
let
|
|
47644
|
+
let id2;
|
|
46998
47645
|
if (typeof schema === "object") {
|
|
46999
47646
|
const { schemaId } = this.opts;
|
|
47000
|
-
|
|
47001
|
-
if (
|
|
47647
|
+
id2 = schema[schemaId];
|
|
47648
|
+
if (id2 !== void 0 && typeof id2 != "string") throw new Error(`schema ${schemaId} must be string`);
|
|
47002
47649
|
}
|
|
47003
|
-
key = (0, resolve_1.normalizeId)(key ||
|
|
47650
|
+
key = (0, resolve_1.normalizeId)(key || id2);
|
|
47004
47651
|
this._checkUnique(key);
|
|
47005
47652
|
this.schemas[key] = this._addSchema(schema, _meta, key, _validateSchema, true);
|
|
47006
47653
|
return this;
|
|
@@ -47065,11 +47712,11 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
47065
47712
|
case "object": {
|
|
47066
47713
|
const cacheKey = schemaKeyRef;
|
|
47067
47714
|
this._cache.delete(cacheKey);
|
|
47068
|
-
let
|
|
47069
|
-
if (
|
|
47070
|
-
|
|
47071
|
-
delete this.schemas[
|
|
47072
|
-
delete this.refs[
|
|
47715
|
+
let id2 = schemaKeyRef[this.opts.schemaId];
|
|
47716
|
+
if (id2) {
|
|
47717
|
+
id2 = (0, resolve_1.normalizeId)(id2);
|
|
47718
|
+
delete this.schemas[id2];
|
|
47719
|
+
delete this.refs[id2];
|
|
47073
47720
|
}
|
|
47074
47721
|
return this;
|
|
47075
47722
|
}
|
|
@@ -47161,14 +47808,14 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
47161
47808
|
}
|
|
47162
47809
|
}
|
|
47163
47810
|
_addSchema(schema, meta3, baseId, validateSchema = this.opts.validateSchema, addSchema = this.opts.addUsedSchema) {
|
|
47164
|
-
let
|
|
47811
|
+
let id2;
|
|
47165
47812
|
const { schemaId } = this.opts;
|
|
47166
|
-
if (typeof schema == "object")
|
|
47813
|
+
if (typeof schema == "object") id2 = schema[schemaId];
|
|
47167
47814
|
else if (this.opts.jtd) throw new Error("schema must be object");
|
|
47168
47815
|
else if (typeof schema != "boolean") throw new Error("schema must be object or boolean");
|
|
47169
47816
|
let sch = this._cache.get(schema);
|
|
47170
47817
|
if (sch !== void 0) return sch;
|
|
47171
|
-
baseId = (0, resolve_1.normalizeId)(
|
|
47818
|
+
baseId = (0, resolve_1.normalizeId)(id2 || baseId);
|
|
47172
47819
|
const localRefs = resolve_1.getSchemaRefs.call(this, schema, baseId);
|
|
47173
47820
|
sch = new compile_1.SchemaEnv({
|
|
47174
47821
|
schema,
|
|
@@ -47185,8 +47832,8 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
47185
47832
|
if (validateSchema) this.validateSchema(schema, true);
|
|
47186
47833
|
return sch;
|
|
47187
47834
|
}
|
|
47188
|
-
_checkUnique(
|
|
47189
|
-
if (this.schemas[
|
|
47835
|
+
_checkUnique(id2) {
|
|
47836
|
+
if (this.schemas[id2] || this.refs[id2]) throw new Error(`schema with key or id "${id2}" already exists`);
|
|
47190
47837
|
}
|
|
47191
47838
|
_compileSchemaEnv(sch) {
|
|
47192
47839
|
if (sch.meta) this._compileMetaSchema(sch);
|
|
@@ -50720,8 +51367,8 @@ var init_mcp_DXXb3Vv3 = __esm({
|
|
|
50720
51367
|
if (serverInfo !== void 0) this._serverInfo = serverInfo;
|
|
50721
51368
|
}
|
|
50722
51369
|
/** Whether `id` is an active listen subscription on this connection. */
|
|
50723
|
-
has(
|
|
50724
|
-
return this._subs.has(
|
|
51370
|
+
has(id2) {
|
|
51371
|
+
return this._subs.has(id2);
|
|
50725
51372
|
}
|
|
50726
51373
|
/**
|
|
50727
51374
|
* Serve one inbound `subscriptions/listen` request: registers the
|
|
@@ -50765,8 +51412,8 @@ var init_mcp_DXXb3Vv3 = __esm({
|
|
|
50765
51412
|
* `true` when a subscription was removed. After this call NOTHING further
|
|
50766
51413
|
* is delivered for that subscription id (the post-cancel hardening).
|
|
50767
51414
|
*/
|
|
50768
|
-
cancel(
|
|
50769
|
-
return this._subs.delete(
|
|
51415
|
+
cancel(id2) {
|
|
51416
|
+
return this._subs.delete(id2);
|
|
50770
51417
|
}
|
|
50771
51418
|
/**
|
|
50772
51419
|
* Route an outbound notification through the active subscriptions.
|
|
@@ -50798,13 +51445,13 @@ var init_mcp_DXXb3Vv3 = __esm({
|
|
|
50798
51445
|
*/
|
|
50799
51446
|
teardownAll() {
|
|
50800
51447
|
const out2 = [];
|
|
50801
|
-
for (const
|
|
51448
|
+
for (const id2 of this._subs.keys()) out2.push({
|
|
50802
51449
|
jsonrpc: "2.0",
|
|
50803
|
-
id,
|
|
51450
|
+
id: id2,
|
|
50804
51451
|
result: {
|
|
50805
51452
|
resultType: "complete",
|
|
50806
51453
|
_meta: {
|
|
50807
|
-
[SUBSCRIPTION_ID_META_KEY]:
|
|
51454
|
+
[SUBSCRIPTION_ID_META_KEY]: id2,
|
|
50808
51455
|
...this._serverInfo !== void 0 && { [SERVER_INFO_META_KEY]: this._serverInfo }
|
|
50809
51456
|
}
|
|
50810
51457
|
}
|
|
@@ -51372,7 +52019,7 @@ var init_mcp_DXXb3Vv3 = __esm({
|
|
|
51372
52019
|
if (hasPreviousToolUse) {
|
|
51373
52020
|
const toolUseIds = new Set(previousContent.filter((c) => c.type === "tool_use").map((c) => c.id));
|
|
51374
52021
|
const toolResultIds = new Set(lastContent.filter((c) => c.type === "tool_result").map((c) => c.toolUseId));
|
|
51375
|
-
if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((
|
|
52022
|
+
if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((id2) => toolResultIds.has(id2))) throw new ProtocolError(ProtocolErrorCode.InvalidParams, "ids of tool_result blocks and tool_use blocks from previous message do not match");
|
|
51376
52023
|
}
|
|
51377
52024
|
}
|
|
51378
52025
|
const hasTools = Boolean(params.tools || params.toolChoice);
|
|
@@ -52096,9 +52743,9 @@ function serveStdio(factory, options = {}) {
|
|
|
52096
52743
|
} catch {
|
|
52097
52744
|
}
|
|
52098
52745
|
};
|
|
52099
|
-
const writeErrorResponse = (
|
|
52746
|
+
const writeErrorResponse = (id2, code2, message, data) => wire.send({
|
|
52100
52747
|
jsonrpc: "2.0",
|
|
52101
|
-
id,
|
|
52748
|
+
id: id2,
|
|
52102
52749
|
error: {
|
|
52103
52750
|
code: code2,
|
|
52104
52751
|
message,
|
|
@@ -52428,7 +53075,7 @@ var init_stdio = __esm({
|
|
|
52428
53075
|
}
|
|
52429
53076
|
send(message) {
|
|
52430
53077
|
if (this._closed) return Promise.reject(/* @__PURE__ */ new Error("StdioServerTransport is closed"));
|
|
52431
|
-
return new Promise((
|
|
53078
|
+
return new Promise((resolve12, reject) => {
|
|
52432
53079
|
const json2 = serializeMessage(message);
|
|
52433
53080
|
let settled = false;
|
|
52434
53081
|
const onError = (error62) => {
|
|
@@ -52443,14 +53090,14 @@ var init_stdio = __esm({
|
|
|
52443
53090
|
settled = true;
|
|
52444
53091
|
this._stdout.off("error", onError);
|
|
52445
53092
|
this._stdout.off("drain", onDrain);
|
|
52446
|
-
|
|
53093
|
+
resolve12();
|
|
52447
53094
|
};
|
|
52448
53095
|
this._stdout.once("error", onError);
|
|
52449
53096
|
if (this._stdout.write(json2)) {
|
|
52450
53097
|
if (settled) return;
|
|
52451
53098
|
settled = true;
|
|
52452
53099
|
this._stdout.off("error", onError);
|
|
52453
|
-
|
|
53100
|
+
resolve12();
|
|
52454
53101
|
} else if (!settled) this._stdout.once("drain", onDrain);
|
|
52455
53102
|
});
|
|
52456
53103
|
}
|
|
@@ -52473,8 +53120,8 @@ var init_stdio = __esm({
|
|
|
52473
53120
|
}
|
|
52474
53121
|
async send(message, options) {
|
|
52475
53122
|
if (isJSONRPCResultResponse(message) || isJSONRPCErrorResponse(message)) {
|
|
52476
|
-
const { id } = message;
|
|
52477
|
-
if (
|
|
53123
|
+
const { id: id2 } = message;
|
|
53124
|
+
if (id2 !== void 0) this._settle(id2);
|
|
52478
53125
|
}
|
|
52479
53126
|
if (this._closed) return;
|
|
52480
53127
|
if (this._outboundIntercept?.(message) === "handled") return;
|
|
@@ -52504,14 +53151,14 @@ var init_stdio = __esm({
|
|
|
52504
53151
|
*/
|
|
52505
53152
|
async whenRequestsAnswered(timeoutMs) {
|
|
52506
53153
|
if (this._closed || this._pendingRequests.size === 0) return true;
|
|
52507
|
-
return await new Promise((
|
|
53154
|
+
return await new Promise((resolve12) => {
|
|
52508
53155
|
const waiter = () => {
|
|
52509
53156
|
clearTimeout(timer);
|
|
52510
|
-
|
|
53157
|
+
resolve12(true);
|
|
52511
53158
|
};
|
|
52512
53159
|
const timer = setTimeout(() => {
|
|
52513
53160
|
this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
|
|
52514
|
-
|
|
53161
|
+
resolve12(false);
|
|
52515
53162
|
}, timeoutMs);
|
|
52516
53163
|
this._drainWaiters.push(waiter);
|
|
52517
53164
|
});
|
|
@@ -52527,8 +53174,8 @@ var init_stdio = __esm({
|
|
|
52527
53174
|
this.onclose?.();
|
|
52528
53175
|
}
|
|
52529
53176
|
}
|
|
52530
|
-
_settle(
|
|
52531
|
-
this._pendingRequests.delete(
|
|
53177
|
+
_settle(id2) {
|
|
53178
|
+
this._pendingRequests.delete(id2);
|
|
52532
53179
|
if (this._pendingRequests.size === 0) this._releaseDrainWaiters();
|
|
52533
53180
|
}
|
|
52534
53181
|
_releaseDrainWaiters() {
|
|
@@ -52690,18 +53337,18 @@ var init_git = __esm({
|
|
|
52690
53337
|
});
|
|
52691
53338
|
|
|
52692
53339
|
// ../code-shim/src/config.ts
|
|
52693
|
-
import { readFileSync as
|
|
53340
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
52694
53341
|
import { homedir as homedir2 } from "node:os";
|
|
52695
53342
|
import { join as join31 } from "node:path";
|
|
52696
53343
|
function configDir(env) {
|
|
52697
|
-
const
|
|
52698
|
-
return join31(
|
|
53344
|
+
const base4 = env["XDG_CONFIG_HOME"] ?? (process.platform === "win32" ? env["APPDATA"] : void 0) ?? join31(homedir2(), ".config");
|
|
53345
|
+
return join31(base4, "mvrx-harness");
|
|
52699
53346
|
}
|
|
52700
53347
|
function findToken2(env, serviceUrl, now) {
|
|
52701
53348
|
const fromEnv = env["HARNESS_TOKEN"];
|
|
52702
53349
|
if (fromEnv !== void 0 && fromEnv.length > 0) return fromEnv;
|
|
52703
53350
|
try {
|
|
52704
|
-
const file2 = JSON.parse(
|
|
53351
|
+
const file2 = JSON.parse(readFileSync11(join31(configDir(env), "credentials.json"), "utf8"));
|
|
52705
53352
|
const stored = file2[serviceUrl];
|
|
52706
53353
|
if (stored === void 0 || typeof stored.accessToken !== "string" || stored.accessToken.length === 0) return null;
|
|
52707
53354
|
if (typeof stored.expiresAt === "number" && stored.expiresAt <= now) return null;
|
|
@@ -52713,7 +53360,7 @@ function findToken2(env, serviceUrl, now) {
|
|
|
52713
53360
|
function resolveCloudConfig(root, env, now) {
|
|
52714
53361
|
let binding;
|
|
52715
53362
|
try {
|
|
52716
|
-
const parsed = ProjectBinding.safeParse(JSON.parse(
|
|
53363
|
+
const parsed = ProjectBinding.safeParse(JSON.parse(readFileSync11(join31(root, ".harness", "project.json"), "utf8")));
|
|
52717
53364
|
if (!parsed.success) return null;
|
|
52718
53365
|
binding = parsed.data;
|
|
52719
53366
|
} catch {
|
|
@@ -52735,10 +53382,10 @@ var init_config = __esm({
|
|
|
52735
53382
|
});
|
|
52736
53383
|
|
|
52737
53384
|
// ../code-shim/src/local.ts
|
|
52738
|
-
import { readFileSync as
|
|
52739
|
-
import { isAbsolute as isAbsolute2, relative as relative3, resolve as
|
|
53385
|
+
import { readFileSync as readFileSync12, statSync as statSync2 } from "node:fs";
|
|
53386
|
+
import { isAbsolute as isAbsolute2, relative as relative3, resolve as resolve11, sep as sep2 } from "node:path";
|
|
52740
53387
|
function resolveInside(root, path) {
|
|
52741
|
-
const absolute =
|
|
53388
|
+
const absolute = resolve11(root, path);
|
|
52742
53389
|
const rel = relative3(root, absolute);
|
|
52743
53390
|
if (rel.length === 0 || rel.startsWith("..") || isAbsolute2(rel)) return null;
|
|
52744
53391
|
return absolute;
|
|
@@ -52855,7 +53502,7 @@ var init_local = __esm({
|
|
|
52855
53502
|
let shard;
|
|
52856
53503
|
try {
|
|
52857
53504
|
this.parses += 1;
|
|
52858
|
-
shard = await this.parse(path,
|
|
53505
|
+
shard = await this.parse(path, readFileSync12(absolute, "utf8"));
|
|
52859
53506
|
} catch {
|
|
52860
53507
|
shard = null;
|
|
52861
53508
|
}
|
|
@@ -52867,7 +53514,7 @@ var init_local = __esm({
|
|
|
52867
53514
|
const absolute = resolveInside(this.root, path);
|
|
52868
53515
|
if (absolute === null) return null;
|
|
52869
53516
|
try {
|
|
52870
|
-
return
|
|
53517
|
+
return readFileSync12(absolute, "utf8");
|
|
52871
53518
|
} catch {
|
|
52872
53519
|
return null;
|
|
52873
53520
|
}
|
|
@@ -52877,7 +53524,7 @@ var init_local = __esm({
|
|
|
52877
53524
|
const absolute = resolveInside(this.root, path);
|
|
52878
53525
|
if (absolute === null) return void 0;
|
|
52879
53526
|
try {
|
|
52880
|
-
const lines =
|
|
53527
|
+
const lines = readFileSync12(absolute, "utf8").split("\n");
|
|
52881
53528
|
const start2 = range[0];
|
|
52882
53529
|
if (start2 >= lines.length) return void 0;
|
|
52883
53530
|
const end = Math.min(Math.max(range[2], start2), start2 + maxLines - 1, lines.length - 1);
|
|
@@ -52998,8 +53645,8 @@ async function symbolsOverview(deps, args2) {
|
|
|
52998
53645
|
const dirty2 = await parseDirty(deps.index, state, (p) => isUnder(p, scope));
|
|
52999
53646
|
const cloud = await deps.cloud.query("symbols_overview", state.head, args2, SymbolAnswer);
|
|
53000
53647
|
const local2 = localSymbolHits(dirty2.shards, (shard, i2) => shard.symbols[i2]?.parent === void 0);
|
|
53001
|
-
const
|
|
53002
|
-
const merged = uniqueBy([...
|
|
53648
|
+
const base4 = cloud.kind === "ok" ? cloudSymbols(cloud.data.symbols, state).filter((hit) => isUnder(hit.path, scope)) : [];
|
|
53649
|
+
const merged = uniqueBy([...base4, ...local2], (h) => `${h.path}\0${h.symbol}\0${h.range.join(",")}`);
|
|
53003
53650
|
const limited = limitByTokens(merged, args2.max_tokens ?? 4e3);
|
|
53004
53651
|
return {
|
|
53005
53652
|
provenance: mergeProvenance(state.head, cloud.kind === "ok" ? cloud.data.provenance : null, state, { overlaid: [...dirty2.shards.keys()], unparsed: dirty2.unparsed }),
|
|
@@ -53016,8 +53663,8 @@ async function findSymbol(deps, args2) {
|
|
|
53016
53663
|
const symbol2 = shard.symbols[i2];
|
|
53017
53664
|
return symbol2 !== void 0 && matchesNamePath(shard, symbol2, wanted);
|
|
53018
53665
|
});
|
|
53019
|
-
const
|
|
53020
|
-
const merged = uniqueBy([...
|
|
53666
|
+
const base4 = cloud.kind === "ok" ? cloudSymbols(cloud.data.symbols, state) : [];
|
|
53667
|
+
const merged = uniqueBy([...base4, ...local2], (h) => `${h.path}\0${h.symbol}\0${h.range.join(",")}`);
|
|
53021
53668
|
return {
|
|
53022
53669
|
provenance: mergeProvenance(state.head, cloud.kind === "ok" ? cloud.data.provenance : null, state, { overlaid: [...dirty2.shards.keys()], unparsed: dirty2.unparsed }),
|
|
53023
53670
|
symbols: withSnippets(deps.index, merged, args2.include_snippet === true)
|
|
@@ -53037,14 +53684,14 @@ async function findReferences(deps, args2) {
|
|
|
53037
53684
|
local2.push({ path, symbol: args2.name, range, source: "local" });
|
|
53038
53685
|
}
|
|
53039
53686
|
}
|
|
53040
|
-
const
|
|
53687
|
+
const base4 = [];
|
|
53041
53688
|
if (cloud.kind === "ok") {
|
|
53042
53689
|
for (const hit of cloud.data.references) {
|
|
53043
53690
|
const path = keepCloudPath(hit.path, state);
|
|
53044
|
-
if (path !== null)
|
|
53691
|
+
if (path !== null) base4.push({ ...hit, path, source: "cloud" });
|
|
53045
53692
|
}
|
|
53046
53693
|
}
|
|
53047
|
-
const merged = uniqueBy([...
|
|
53694
|
+
const merged = uniqueBy([...base4, ...local2], (h) => `${h.path}\0${h.range.join(",")}`);
|
|
53048
53695
|
return {
|
|
53049
53696
|
provenance: mergeProvenance(state.head, cloud.kind === "ok" ? cloud.data.provenance : null, state, { overlaid: [...dirty2.shards.keys()], unparsed: dirty2.unparsed }),
|
|
53050
53697
|
references: withSnippets(deps.index, merged, args2.include_snippet === true)
|
|
@@ -53104,7 +53751,7 @@ var init_nav = __esm({
|
|
|
53104
53751
|
|
|
53105
53752
|
// ../code-shim/src/edit.ts
|
|
53106
53753
|
import { createHash as createHash8 } from "node:crypto";
|
|
53107
|
-
import { readFileSync as
|
|
53754
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
|
|
53108
53755
|
function lineStarts(text) {
|
|
53109
53756
|
const starts = [0];
|
|
53110
53757
|
for (let i2 = 0; i2 < text.length; i2 += 1) if (text[i2] === "\n") starts.push(i2 + 1);
|
|
@@ -53145,7 +53792,7 @@ async function editSymbol(index, args2) {
|
|
|
53145
53792
|
if (!found.ok) return found;
|
|
53146
53793
|
const absolute = resolveInside(index.root, args2.path);
|
|
53147
53794
|
if (absolute === null) return { ok: false, reason: `path ${args2.path} is outside the repository` };
|
|
53148
|
-
const original =
|
|
53795
|
+
const original = readFileSync13(absolute, "utf8");
|
|
53149
53796
|
const starts = lineStarts(original);
|
|
53150
53797
|
const range = found.symbol.enclosingRange ?? found.symbol.range;
|
|
53151
53798
|
const from = offsetOf(starts, original, range[0], range[1]);
|
|
@@ -53212,7 +53859,7 @@ async function renameSymbol(deps, args2) {
|
|
|
53212
53859
|
if (absolute === null) return { ok: false, reason: `reference path ${path} is outside the repository` };
|
|
53213
53860
|
let text;
|
|
53214
53861
|
try {
|
|
53215
|
-
text =
|
|
53862
|
+
text = readFileSync13(absolute, "utf8");
|
|
53216
53863
|
} catch {
|
|
53217
53864
|
return { ok: false, reason: `cannot read ${path}` };
|
|
53218
53865
|
}
|
|
@@ -53355,6 +54002,30 @@ var init_server = __esm({
|
|
|
53355
54002
|
}
|
|
53356
54003
|
});
|
|
53357
54004
|
|
|
54005
|
+
// ../code-shim/src/defaults.ts
|
|
54006
|
+
function shimSetting(env) {
|
|
54007
|
+
const remote = env["CLAUDE_CODE_REMOTE"] === "true" || env["CODEX_CLOUD"] === "1" || env["HARNESS_SETTING"] === "cloud-session";
|
|
54008
|
+
return remote ? "cloud-session" : "local-agent-with-grep";
|
|
54009
|
+
}
|
|
54010
|
+
function codeMapSwitch(env, results) {
|
|
54011
|
+
const setting = shimSetting(env);
|
|
54012
|
+
const base4 = results === void 0 ? codeMapDefault(setting) : codeMapDefault(setting, results);
|
|
54013
|
+
const forced = env["HARNESS_CODE_MAP"];
|
|
54014
|
+
if (forced === "on" || forced === "off") {
|
|
54015
|
+
return { ...base4, on: forced === "on", basis: "project-setting", reason: `${forced}: set by HARNESS_CODE_MAP (the default for this setting is ${base4.on ? "on" : "off"}: ${base4.reason})`, source: "env" };
|
|
54016
|
+
}
|
|
54017
|
+
return { ...base4, source: "default" };
|
|
54018
|
+
}
|
|
54019
|
+
function describeSwitch(state) {
|
|
54020
|
+
return `code-shim: code map ${state.on ? "on" : "off"} for ${state.setting} (${state.source}). ${state.reason}`;
|
|
54021
|
+
}
|
|
54022
|
+
var init_defaults = __esm({
|
|
54023
|
+
"../code-shim/src/defaults.ts"() {
|
|
54024
|
+
"use strict";
|
|
54025
|
+
init_src();
|
|
54026
|
+
}
|
|
54027
|
+
});
|
|
54028
|
+
|
|
53358
54029
|
// ../code-shim/src/index.ts
|
|
53359
54030
|
var src_exports = {};
|
|
53360
54031
|
__export(src_exports, {
|
|
@@ -53363,8 +54034,10 @@ __export(src_exports, {
|
|
|
53363
54034
|
callHierarchy: () => callHierarchy,
|
|
53364
54035
|
changeImpact: () => changeImpact,
|
|
53365
54036
|
cloudArgs: () => cloudArgs,
|
|
54037
|
+
codeMapSwitch: () => codeMapSwitch,
|
|
53366
54038
|
createDeps: () => createDeps,
|
|
53367
54039
|
createServer: () => createServer2,
|
|
54040
|
+
describeSwitch: () => describeSwitch,
|
|
53368
54041
|
editSymbol: () => editSymbol,
|
|
53369
54042
|
findReferences: () => findReferences,
|
|
53370
54043
|
findSymbol: () => findSymbol,
|
|
@@ -53375,6 +54048,7 @@ __export(src_exports, {
|
|
|
53375
54048
|
readWorkingCopyState: () => readWorkingCopyState,
|
|
53376
54049
|
renameSymbol: () => renameSymbol,
|
|
53377
54050
|
resolveCloudConfig: () => resolveCloudConfig,
|
|
54051
|
+
shimSetting: () => shimSetting,
|
|
53378
54052
|
symbolsOverview: () => symbolsOverview
|
|
53379
54053
|
});
|
|
53380
54054
|
var init_src3 = __esm({
|
|
@@ -53388,6 +54062,7 @@ var init_src3 = __esm({
|
|
|
53388
54062
|
init_merge2();
|
|
53389
54063
|
init_nav();
|
|
53390
54064
|
init_server();
|
|
54065
|
+
init_defaults();
|
|
53391
54066
|
}
|
|
53392
54067
|
});
|
|
53393
54068
|
|
|
@@ -53645,8 +54320,8 @@ var AuthRequiredError = class extends MvrxError {
|
|
|
53645
54320
|
super(message, { code: "auth_required", exit: EXIT.auth }, { hint: "overlane auth status", ...options });
|
|
53646
54321
|
}
|
|
53647
54322
|
};
|
|
53648
|
-
function unreachable(
|
|
53649
|
-
return new CliError(`cannot reach ${
|
|
54323
|
+
function unreachable(base4, cause) {
|
|
54324
|
+
return new CliError(`cannot reach ${base4}: ${cause instanceof Error ? cause.message : String(cause)}`, {
|
|
53650
54325
|
code: "unreachable",
|
|
53651
54326
|
exit: EXIT.unreachable,
|
|
53652
54327
|
retryable: true,
|
|
@@ -53677,6 +54352,19 @@ var SERVICE_CODES = {
|
|
|
53677
54352
|
promotion_blocked: { exit: EXIT.blocked, hint: "overlane release list" },
|
|
53678
54353
|
no_previous_release: { exit: EXIT.conflict, hint: "overlane release status" },
|
|
53679
54354
|
managed_file_edited: { exit: EXIT.conflict, hint: "overlane release status" },
|
|
54355
|
+
// guardrails and review (MS-A5): a refusal by policy exits 6 with the rule and the next command (REQ-GRD-12)
|
|
54356
|
+
policy_denied: { exit: EXIT.blocked, hint: "overlane guard rules list" },
|
|
54357
|
+
protected_branch: { exit: EXIT.blocked, hint: "overlane guard approvals list" },
|
|
54358
|
+
path_protected: { exit: EXIT.blocked, hint: "overlane guard approvals list" },
|
|
54359
|
+
spend_cap_reached: { exit: EXIT.blocked, hint: "overlane guard rules list" },
|
|
54360
|
+
plan_limit_reached: { exit: EXIT.blocked, hint: "overlane guard rules list" },
|
|
54361
|
+
egress_blocked: { exit: EXIT.blocked, hint: "overlane guard rules list" },
|
|
54362
|
+
deploy_blocked: { exit: EXIT.blocked, hint: "overlane guard rules list" },
|
|
54363
|
+
secret_detected: { exit: EXIT.blocked, hint: "overlane guard scan --path <file>" },
|
|
54364
|
+
task_required: { exit: EXIT.blocked, hint: 'overlane task new "<title>"' },
|
|
54365
|
+
invalid_rules: { exit: EXIT.usage, hint: "overlane guard rules test --file <rules.json> --tool <tool>" },
|
|
54366
|
+
finding_not_open: { exit: EXIT.conflict, hint: "overlane review findings --status open" },
|
|
54367
|
+
live_leg_pending: { exit: EXIT.failure, hint: "overlane review status" },
|
|
53680
54368
|
// generic
|
|
53681
54369
|
unauthorized: { exit: EXIT.auth, hint: "overlane auth login" },
|
|
53682
54370
|
// identity (MS-A1): a revoked or expired token needs a new sign-in; a role that may not do this is blocked by policy
|
|
@@ -54165,19 +54853,19 @@ function pkcePair() {
|
|
|
54165
54853
|
return { verifier, challenge: base64url3(createHash("sha256").update(verifier).digest()) };
|
|
54166
54854
|
}
|
|
54167
54855
|
function listen(server, port) {
|
|
54168
|
-
return new Promise((
|
|
54856
|
+
return new Promise((resolve12, reject) => {
|
|
54169
54857
|
const onError = (error62) => reject(error62);
|
|
54170
54858
|
server.once("error", onError);
|
|
54171
54859
|
server.listen(port, "127.0.0.1", () => {
|
|
54172
54860
|
server.off("error", onError);
|
|
54173
|
-
|
|
54861
|
+
resolve12();
|
|
54174
54862
|
});
|
|
54175
54863
|
});
|
|
54176
54864
|
}
|
|
54177
54865
|
async function startLoopback(preferredPort, state) {
|
|
54178
54866
|
let settle2;
|
|
54179
|
-
const code2 = new Promise((
|
|
54180
|
-
settle2 = { resolve:
|
|
54867
|
+
const code2 = new Promise((resolve12, reject) => {
|
|
54868
|
+
settle2 = { resolve: resolve12, reject };
|
|
54181
54869
|
});
|
|
54182
54870
|
code2.catch(() => void 0);
|
|
54183
54871
|
const server = createServer((request, response) => {
|
|
@@ -54524,10 +55212,10 @@ async function failure2(response) {
|
|
|
54524
55212
|
}
|
|
54525
55213
|
return { code: void 0, text: `status ${response.status}` };
|
|
54526
55214
|
}
|
|
54527
|
-
async function call(deps,
|
|
55215
|
+
async function call(deps, base4, token, schema, method, path, body2) {
|
|
54528
55216
|
let response;
|
|
54529
55217
|
try {
|
|
54530
|
-
response = await deps.fetch(`${
|
|
55218
|
+
response = await deps.fetch(`${base4}${path}`, {
|
|
54531
55219
|
method,
|
|
54532
55220
|
headers: {
|
|
54533
55221
|
accept: "application/json",
|
|
@@ -54537,7 +55225,7 @@ async function call(deps, base3, token, schema, method, path, body2) {
|
|
|
54537
55225
|
...body2 === void 0 ? {} : { body: JSON.stringify(body2) }
|
|
54538
55226
|
});
|
|
54539
55227
|
} catch (error62) {
|
|
54540
|
-
throw unreachable(
|
|
55228
|
+
throw unreachable(base4, error62);
|
|
54541
55229
|
}
|
|
54542
55230
|
if (!response.ok) {
|
|
54543
55231
|
const failed = await failure2(response);
|
|
@@ -54554,12 +55242,12 @@ async function call(deps, base3, token, schema, method, path, body2) {
|
|
|
54554
55242
|
return parsed.data;
|
|
54555
55243
|
}
|
|
54556
55244
|
function releaseClient(deps, binding, token, serviceUrl = binding.serviceUrl) {
|
|
54557
|
-
const
|
|
55245
|
+
const base4 = serviceUrl.replace(/\/+$/, "");
|
|
54558
55246
|
return {
|
|
54559
|
-
list: () => call(deps,
|
|
54560
|
-
get: (digest) => call(deps,
|
|
54561
|
-
pin: (digest) => call(deps,
|
|
54562
|
-
rollback: () => call(deps,
|
|
55247
|
+
list: () => call(deps, base4, token, external_exports.array(ReleaseRecord), "GET", releasePaths.list(binding.tenantId)),
|
|
55248
|
+
get: (digest) => call(deps, base4, token, ReleaseRecord, "GET", releasePaths.one(binding.tenantId, digest)),
|
|
55249
|
+
pin: (digest) => call(deps, base4, token, ProjectRecord, "PUT", releasePaths.pin(binding.tenantId, binding.projectId), { digest }),
|
|
55250
|
+
rollback: () => call(deps, base4, token, ProjectRecord, "POST", releasePaths.rollback(binding.tenantId, binding.projectId), {})
|
|
54563
55251
|
};
|
|
54564
55252
|
}
|
|
54565
55253
|
async function fetchServicePublicKey(deps, serviceUrl, token) {
|
|
@@ -54631,6 +55319,32 @@ async function probeService(deps, serviceUrl, token) {
|
|
|
54631
55319
|
|
|
54632
55320
|
// ../cli/src/connect.ts
|
|
54633
55321
|
var DEFAULT_SERVICE_URL = "https://api.overlane.dev";
|
|
55322
|
+
var CONNECT_STEPS = {
|
|
55323
|
+
"sign-up": "sign in through the browser (OAuth with PKCE), or use HARNESS_TOKEN",
|
|
55324
|
+
agents: "register the plugin with each agent's own commands (no vendor token is asked for)",
|
|
55325
|
+
repo: "bind this GitHub project to the service",
|
|
55326
|
+
"first-task": 'start your first task with `overlane task new "<title>"`',
|
|
55327
|
+
"first-review": "read the first review in the web app",
|
|
55328
|
+
invite: "invite teammates from the web app (optional, never blocks)"
|
|
55329
|
+
};
|
|
55330
|
+
async function reportStep(deps, serviceUrl, token, tenantId, step2, data) {
|
|
55331
|
+
try {
|
|
55332
|
+
const headers = { authorization: `Bearer ${token}`, accept: "application/json" };
|
|
55333
|
+
const read = await deps.fetch(`${serviceUrl}${onboardingPaths.progress(tenantId)}`, { headers });
|
|
55334
|
+
if (!read.ok) return null;
|
|
55335
|
+
const progress = OnboardingProgress.parse(await read.json());
|
|
55336
|
+
if (progress.step !== step2 || progress.complete) return progress.step;
|
|
55337
|
+
const write = await deps.fetch(`${serviceUrl}${onboardingPaths.advance(tenantId)}`, {
|
|
55338
|
+
method: "POST",
|
|
55339
|
+
headers: { ...headers, "content-type": "application/json" },
|
|
55340
|
+
body: JSON.stringify({ step: step2, expectedVersion: progress.version, outcome: "done", data })
|
|
55341
|
+
});
|
|
55342
|
+
if (!write.ok) return progress.step;
|
|
55343
|
+
return OnboardingProgress.parse((await write.json()).progress).step;
|
|
55344
|
+
} catch {
|
|
55345
|
+
return null;
|
|
55346
|
+
}
|
|
55347
|
+
}
|
|
54634
55348
|
var MANIFESTS = {
|
|
54635
55349
|
claude: join6(".claude-plugin", "marketplace.json"),
|
|
54636
55350
|
codex: join6(".agents", "plugins", "marketplace.json")
|
|
@@ -54705,6 +55419,7 @@ async function connect(deps, options) {
|
|
|
54705
55419
|
const bindingMissing = existing.kind !== "ok";
|
|
54706
55420
|
const existingToken = await findToken(deps, serviceUrl);
|
|
54707
55421
|
say(deps);
|
|
55422
|
+
say(deps, `Steps (the same names as the web onboarding): ${STEP_NAMES.join(", ")}`);
|
|
54708
55423
|
say(deps, "Plan");
|
|
54709
55424
|
say(deps, ` sign-in: ${existingToken === null ? `browser sign-in to ${serviceUrl} (OAuth with PKCE), token kept in the OS keychain or a 0600 file in your user config directory` : `${describeStore(deps, existingToken.source)}`}`);
|
|
54710
55425
|
say(deps, ` service: GET ${serviceUrl}/v1/me, then create or look up the project for ${repository.owner}/${repository.name}`);
|
|
@@ -54759,6 +55474,7 @@ async function connect(deps, options) {
|
|
|
54759
55474
|
}
|
|
54760
55475
|
}
|
|
54761
55476
|
const token = await ensureToken(deps, serviceUrl);
|
|
55477
|
+
say(deps, `[sign-up] ${CONNECT_STEPS["sign-up"]}: done`);
|
|
54762
55478
|
say(deps, `Signed in; token source: ${describeStore(deps, token.source)}`);
|
|
54763
55479
|
const wrote = [];
|
|
54764
55480
|
const applied = [];
|
|
@@ -54793,6 +55509,8 @@ async function connect(deps, options) {
|
|
|
54793
55509
|
entry.configLines = { text: codexEdit.block, createdFile: !codexEdit.fileExisted };
|
|
54794
55510
|
}
|
|
54795
55511
|
verify(deps, root, active);
|
|
55512
|
+
say(deps, `[agents] ${CONNECT_STEPS.agents}: done`);
|
|
55513
|
+
await reportStep(deps, serviceUrl, token.token, me.tenantId, "agents", { agents: active.map((info2) => info2.agent === "claude" ? "claude-code" : info2.agent) });
|
|
54796
55514
|
if (writeIfDifferent(join6(root, BINDING_FILE), bindingText(binding))) {
|
|
54797
55515
|
say(deps, `Wrote ${BINDING_FILE}`);
|
|
54798
55516
|
wrote.push(BINDING_FILE);
|
|
@@ -54800,6 +55518,9 @@ async function connect(deps, options) {
|
|
|
54800
55518
|
if (codexEdit !== null) wrote.push(CODEX_CONFIG_FILE);
|
|
54801
55519
|
owned.binding = true;
|
|
54802
55520
|
if (excludeNeeded && await addExclude(deps, root)) owned.excludeLine = true;
|
|
55521
|
+
say(deps, `[repo] ${CONNECT_STEPS.repo}: done`);
|
|
55522
|
+
const next = await reportStep(deps, serviceUrl, token.token, me.tenantId, "repo", { repo: { kind: "github", owner: repository.owner, name: repository.name } });
|
|
55523
|
+
if (next !== null) say(deps, `Next in onboarding: ${next === "repo" ? "first-task" : next} (${CONNECT_STEPS[next === "repo" ? "first-task" : next]})`);
|
|
54803
55524
|
} finally {
|
|
54804
55525
|
if (previousOwned !== null || owned.binding || owned.claude !== void 0 || owned.codex !== void 0) writeOwned(root, owned);
|
|
54805
55526
|
}
|
|
@@ -54891,8 +55612,8 @@ function withTimeout(deps, ms) {
|
|
|
54891
55612
|
}
|
|
54892
55613
|
async function attempt(deps, ms, work) {
|
|
54893
55614
|
let timer;
|
|
54894
|
-
const deadline = new Promise((
|
|
54895
|
-
timer = setTimeout(() =>
|
|
55615
|
+
const deadline = new Promise((resolve12) => {
|
|
55616
|
+
timer = setTimeout(() => resolve12("unreachable"), ms);
|
|
54896
55617
|
});
|
|
54897
55618
|
try {
|
|
54898
55619
|
return await Promise.race([work(withTimeout(deps, ms)).catch((error62) => error62 instanceof ServiceError && error62.exit === EXIT.auth ? "unauthenticated" : "unreachable"), deadline]);
|
|
@@ -55130,13 +55851,13 @@ function render(op, existing) {
|
|
|
55130
55851
|
case "block":
|
|
55131
55852
|
return withBlock(existing, op.content);
|
|
55132
55853
|
case "json": {
|
|
55133
|
-
let
|
|
55854
|
+
let base4 = op.base ?? {};
|
|
55134
55855
|
if (existing !== null && existing.trim() !== "") {
|
|
55135
55856
|
const parsed = JSON.parse(existing);
|
|
55136
55857
|
if (!isRecord(parsed)) throw new Error(`${op.path} is not a JSON object; fix it by hand, then run the command again`);
|
|
55137
|
-
|
|
55858
|
+
base4 = parsed;
|
|
55138
55859
|
}
|
|
55139
|
-
return `${JSON.stringify(setAt(
|
|
55860
|
+
return `${JSON.stringify(setAt(base4, op.key, op.value), null, 2)}
|
|
55140
55861
|
`;
|
|
55141
55862
|
}
|
|
55142
55863
|
}
|
|
@@ -55536,9 +56257,9 @@ function updateSteps(agent) {
|
|
|
55536
56257
|
];
|
|
55537
56258
|
}
|
|
55538
56259
|
function kindOfEachFile(diff) {
|
|
55539
|
-
const
|
|
55540
|
-
for (const file2 of [...diff.added, ...diff.changed, ...diff.removed])
|
|
55541
|
-
return
|
|
56260
|
+
const counts2 = /* @__PURE__ */ new Map();
|
|
56261
|
+
for (const file2 of [...diff.added, ...diff.changed, ...diff.removed]) counts2.set(file2.kind, (counts2.get(file2.kind) ?? 0) + 1);
|
|
56262
|
+
return counts2.size === 0 ? "no file changes" : [...counts2].map(([kind, count]) => `${count} ${kind}`).join(", ");
|
|
55542
56263
|
}
|
|
55543
56264
|
function showDiff(deps, diff) {
|
|
55544
56265
|
say(deps, ` files: ${diff.added.length} added, ${diff.changed.length} changed, ${diff.removed.length} removed (${kindOfEachFile(diff)})`);
|
|
@@ -55675,17 +56396,20 @@ async function failure3(response) {
|
|
|
55675
56396
|
const text = await response.text();
|
|
55676
56397
|
try {
|
|
55677
56398
|
const parsed = ApiError.safeParse(JSON.parse(text));
|
|
55678
|
-
if (parsed.success)
|
|
56399
|
+
if (parsed.success) {
|
|
56400
|
+
const { code: code2, message, ruleId, hint } = parsed.data.error;
|
|
56401
|
+
return { text: `${code2}: ${message}${ruleId === void 0 ? "" : ` [rule ${ruleId}]`}`, code: code2, hint };
|
|
56402
|
+
}
|
|
55679
56403
|
} catch {
|
|
55680
56404
|
}
|
|
55681
|
-
return { text: `status ${response.status}`, code: void 0 };
|
|
56405
|
+
return { text: `status ${response.status}`, code: void 0, hint: void 0 };
|
|
55682
56406
|
}
|
|
55683
56407
|
function serviceCall(deps, serviceUrl, token) {
|
|
55684
|
-
const
|
|
56408
|
+
const base4 = serviceUrl.replace(/\/+$/, "");
|
|
55685
56409
|
return async (schema, method, path, body2, extraHeaders) => {
|
|
55686
56410
|
let response;
|
|
55687
56411
|
try {
|
|
55688
|
-
response = await deps.fetch(`${
|
|
56412
|
+
response = await deps.fetch(`${base4}${path}`, {
|
|
55689
56413
|
method,
|
|
55690
56414
|
headers: {
|
|
55691
56415
|
accept: "application/json",
|
|
@@ -55696,11 +56420,11 @@ function serviceCall(deps, serviceUrl, token) {
|
|
|
55696
56420
|
...body2 === void 0 ? {} : { body: JSON.stringify(body2) }
|
|
55697
56421
|
});
|
|
55698
56422
|
} catch (error62) {
|
|
55699
|
-
throw unreachable(
|
|
56423
|
+
throw unreachable(base4, error62);
|
|
55700
56424
|
}
|
|
55701
56425
|
if (!response.ok) {
|
|
55702
56426
|
const failed = await failure3(response);
|
|
55703
|
-
throw new ServiceError(`${method} ${path} failed (${failed.text})`, failed.code, response.status);
|
|
56427
|
+
throw new ServiceError(`${method} ${path} failed (${failed.text})`, failed.code, response.status, failed.hint);
|
|
55704
56428
|
}
|
|
55705
56429
|
let json2;
|
|
55706
56430
|
try {
|
|
@@ -55881,7 +56605,7 @@ function slugify2(value) {
|
|
|
55881
56605
|
var PLAN_DIR = ".harness/plan";
|
|
55882
56606
|
var planPaths = (repoDir) => {
|
|
55883
56607
|
const root = join15(repoDir, PLAN_DIR);
|
|
55884
|
-
return { root, project: join15(root, "project.md"), milestones: join15(root, "milestones.md"), tasks: join15(root, "tasks"), task: (
|
|
56608
|
+
return { root, project: join15(root, "project.md"), milestones: join15(root, "milestones.md"), tasks: join15(root, "tasks"), task: (id2) => join15(root, "tasks", `${id2}.md`) };
|
|
55885
56609
|
};
|
|
55886
56610
|
function parsePlan(input2, where) {
|
|
55887
56611
|
const result = Plan.safeParse(input2);
|
|
@@ -55982,7 +56706,7 @@ function parseMilestones(text, where) {
|
|
|
55982
56706
|
}
|
|
55983
56707
|
if (line2.trim() === "") continue;
|
|
55984
56708
|
const depends = /^Depends on: (.+)$/.exec(line2);
|
|
55985
|
-
if (depends && !inAcceptance) current2.dependsOn = (depends[1] ?? "").split(",").map((
|
|
56709
|
+
if (depends && !inAcceptance) current2.dependsOn = (depends[1] ?? "").split(",").map((id2) => id2.trim());
|
|
55986
56710
|
else if (inAcceptance && line2.startsWith("- ")) current2.acceptance.push(line2.slice(2));
|
|
55987
56711
|
else throw new KitError(`${where}: unexpected line under ${current2.id}: "${line2}"`);
|
|
55988
56712
|
}
|
|
@@ -56184,9 +56908,9 @@ async function draftPlanForExisting(repoDir, opts = {}) {
|
|
|
56184
56908
|
const allowedPaths = opts.allowedPaths ?? ["."];
|
|
56185
56909
|
const tasks = [];
|
|
56186
56910
|
const starter = (title, outcome, verification, dependsOn) => {
|
|
56187
|
-
const
|
|
56188
|
-
tasks.push({ id, title, milestone, outcome, allowedPaths, acceptance: verification.map((command) => `\`${command}\` exits 0`), verification, evidenceLevel: "L2", dependsOn, requiresConnections: [] });
|
|
56189
|
-
return
|
|
56911
|
+
const id2 = `T${String(tasks.length + 1).padStart(3, "0")}`;
|
|
56912
|
+
tasks.push({ id: id2, title, milestone, outcome, allowedPaths, acceptance: verification.map((command) => `\`${command}\` exits 0`), verification, evidenceLevel: "L2", dependsOn, requiresConnections: [] });
|
|
56913
|
+
return id2;
|
|
56190
56914
|
};
|
|
56191
56915
|
const installId = detected.install ? starter("Install dependencies", "Dependencies install cleanly from the lockfile.", [detected.install], []) : void 0;
|
|
56192
56916
|
const after = installId ? [installId] : [];
|
|
@@ -56380,9 +57104,9 @@ async function importSpecKit(repoDir) {
|
|
|
56380
57104
|
const name2 = (parsedConstitution?.name ?? basename2(root)).slice(0, 100);
|
|
56381
57105
|
const goal = (parsedConstitution?.goal ?? firstInput ?? `Deliver ${name2}.`).slice(0, 2e3);
|
|
56382
57106
|
const multi = features.length > 1;
|
|
56383
|
-
const
|
|
56384
|
-
for (const feature of features) for (const phase of feature.phases) for (const task of phase.tasks)
|
|
56385
|
-
const prefixTasks = [...
|
|
57107
|
+
const counts2 = /* @__PURE__ */ new Map();
|
|
57108
|
+
for (const feature of features) for (const phase of feature.phases) for (const task of phase.tasks) counts2.set(task.id, (counts2.get(task.id) ?? 0) + 1);
|
|
57109
|
+
const prefixTasks = [...counts2.values()].some((count) => count > 1);
|
|
56386
57110
|
const detected = await detectCommands(root);
|
|
56387
57111
|
const milestones = [];
|
|
56388
57112
|
const tasks = [];
|
|
@@ -56400,17 +57124,17 @@ async function importSpecKit(repoDir) {
|
|
|
56400
57124
|
let storyRun = [];
|
|
56401
57125
|
feature.phases.forEach((phase, index) => {
|
|
56402
57126
|
const defaultId = `${multi ? `F${feature.key}-` : ""}P${phase.number ?? index + 1}`;
|
|
56403
|
-
const
|
|
57127
|
+
const id2 = phase.id ?? defaultId;
|
|
56404
57128
|
const story = isStoryTitle(phase.title);
|
|
56405
57129
|
const derivedDeps = story !== void 0 ? lastNonStory ? [lastNonStory] : [] : storyRun.length > 0 ? [...storyRun] : lastNonStory ? [lastNonStory] : [];
|
|
56406
|
-
if (story !== void 0) storyRun.push(
|
|
57130
|
+
if (story !== void 0) storyRun.push(id2);
|
|
56407
57131
|
else {
|
|
56408
|
-
lastNonStory =
|
|
57132
|
+
lastNonStory = id2;
|
|
56409
57133
|
storyRun = [];
|
|
56410
57134
|
}
|
|
56411
|
-
const stored = feature.block.milestones[
|
|
57135
|
+
const stored = feature.block.milestones[id2];
|
|
56412
57136
|
const derivedAcceptance = story !== void 0 ? feature.stories.get(story) ?? [] : phase.checkpoint ? [phase.checkpoint] : [];
|
|
56413
|
-
milestones.push({ id, title: phase.title || `Phase ${phase.number ?? index + 1}`, acceptance: stored?.acceptance ?? derivedAcceptance, dependsOn: stored?.dependsOn ?? derivedDeps });
|
|
57137
|
+
milestones.push({ id: id2, title: phase.title || `Phase ${phase.number ?? index + 1}`, acceptance: stored?.acceptance ?? derivedAcceptance, dependsOn: stored?.dependsOn ?? derivedDeps });
|
|
56414
57138
|
let previousGroup = [];
|
|
56415
57139
|
let group = [];
|
|
56416
57140
|
let groupParallel = false;
|
|
@@ -56431,7 +57155,7 @@ async function importSpecKit(repoDir) {
|
|
|
56431
57155
|
tasks.push({
|
|
56432
57156
|
id: taskId,
|
|
56433
57157
|
title: parsed.title,
|
|
56434
|
-
milestone:
|
|
57158
|
+
milestone: id2,
|
|
56435
57159
|
outcome: storedTask?.outcome ?? parsed.title,
|
|
56436
57160
|
allowedPaths: storedTask?.allowedPaths ?? (paths.length > 0 ? paths : ["."]),
|
|
56437
57161
|
acceptance: storedTask?.acceptance ?? (storyAcceptance && storyAcceptance.length > 0 ? storyAcceptance : [`Completed: ${parsed.title}`]),
|
|
@@ -57754,12 +58478,12 @@ init_zod();
|
|
|
57754
58478
|
init_src();
|
|
57755
58479
|
init_zod();
|
|
57756
58480
|
var ErrorBody = external_exports.object({ error: external_exports.object({ code: external_exports.string(), message: external_exports.string() }).passthrough() }).passthrough();
|
|
57757
|
-
async function post(deps,
|
|
58481
|
+
async function post(deps, base4, path, body2) {
|
|
57758
58482
|
let response;
|
|
57759
58483
|
try {
|
|
57760
|
-
response = await deps.fetch(`${
|
|
58484
|
+
response = await deps.fetch(`${base4}${path}`, { method: "POST", headers: { "content-type": "application/json", accept: "application/json" }, body: JSON.stringify(body2) });
|
|
57761
58485
|
} catch (error62) {
|
|
57762
|
-
throw unreachable(
|
|
58486
|
+
throw unreachable(base4, error62);
|
|
57763
58487
|
}
|
|
57764
58488
|
let json2 = null;
|
|
57765
58489
|
try {
|
|
@@ -57770,7 +58494,7 @@ async function post(deps, base3, path, body2) {
|
|
|
57770
58494
|
return { status: response.status, json: json2 };
|
|
57771
58495
|
}
|
|
57772
58496
|
function sleep(ms) {
|
|
57773
|
-
return new Promise((
|
|
58497
|
+
return new Promise((resolve12) => setTimeout(resolve12, ms));
|
|
57774
58498
|
}
|
|
57775
58499
|
async function deviceLogin(deps, service, options) {
|
|
57776
58500
|
const started = await post(deps, service, "/auth/device", {});
|
|
@@ -58110,28 +58834,302 @@ var tokenRevokeCommand = defineCommand({
|
|
|
58110
58834
|
keywords: ["revoke", "delete token", "disable token", "kill credentials", "remove access", "leaked token"],
|
|
58111
58835
|
result: TokenRevokeResult,
|
|
58112
58836
|
handler: async (inv) => {
|
|
58113
|
-
const
|
|
58114
|
-
if (
|
|
58837
|
+
const id2 = inv.positionals[0];
|
|
58838
|
+
if (id2 === void 0) throw new UsageError("a token ID is required", { hint: "overlane token list" });
|
|
58115
58839
|
if (inv.dryRun) {
|
|
58116
58840
|
const target = await resolveTarget(inv.deps, textFlag(inv, "service"));
|
|
58117
|
-
return planOutcome(inv.deps, dryRunPlan({ service: target.service, requests: [{ method: "DELETE", path: `/v1/tenants/${textFlag(inv, "team") ?? ":your-team"}/tokens/${
|
|
58841
|
+
return planOutcome(inv.deps, dryRunPlan({ service: target.service, requests: [{ method: "DELETE", path: `/v1/tenants/${textFlag(inv, "team") ?? ":your-team"}/tokens/${id2}` }] }));
|
|
58118
58842
|
}
|
|
58119
58843
|
const { call: call2 } = await authed(inv);
|
|
58120
58844
|
const tenantId = await tenantOf(call2, inv);
|
|
58121
|
-
await call2(external_exports.object({ ok: external_exports.literal(true) }).passthrough(), "DELETE", `/v1/tenants/${encodeURIComponent(tenantId)}/tokens/${encodeURIComponent(
|
|
58122
|
-
say(inv.deps, `Revoked ${
|
|
58123
|
-
return { data: { tenantId, tokenId:
|
|
58845
|
+
await call2(external_exports.object({ ok: external_exports.literal(true) }).passthrough(), "DELETE", `/v1/tenants/${encodeURIComponent(tenantId)}/tokens/${encodeURIComponent(id2)}`);
|
|
58846
|
+
say(inv.deps, `Revoked ${id2}.`);
|
|
58847
|
+
return { data: { tenantId, tokenId: id2, revoked: true } };
|
|
58124
58848
|
}
|
|
58125
58849
|
});
|
|
58126
58850
|
var identityCommands = [authLoginCommand, authLogoutCommand, authTokenCommand, teamListCommand, teamInviteCommand, tokenCreateCommand, tokenListCommand, tokenRevokeCommand];
|
|
58127
58851
|
|
|
58128
|
-
// ../cli/src/commands/
|
|
58852
|
+
// ../cli/src/commands/guard.ts
|
|
58129
58853
|
init_src();
|
|
58130
58854
|
init_zod();
|
|
58131
58855
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
58856
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
58857
|
+
import { resolve as resolve7 } from "node:path";
|
|
58858
|
+
var common = { needsAuth: true, needsNetwork: true };
|
|
58859
|
+
var requestId3 = () => `cli-${randomUUID3()}`;
|
|
58860
|
+
async function connected(inv) {
|
|
58861
|
+
const project = await connectedProject(inv.deps, "guard");
|
|
58862
|
+
return { project, call: serviceCall(inv.deps, project.serviceUrl, project.token), tenantId: project.binding.tenantId, projectId: project.binding.projectId };
|
|
58863
|
+
}
|
|
58864
|
+
async function planned(inv, method, path, body2, note) {
|
|
58865
|
+
const project = await offlineProject(inv.deps, "guard");
|
|
58866
|
+
return planOutcome(inv.deps, dryRunPlan({ service: project.serviceUrl, requests: [{ method, path: path(project.binding.tenantId), ...body2 === void 0 ? {} : { body: body2 }, ...note === void 0 ? {} : { note } }] }));
|
|
58867
|
+
}
|
|
58868
|
+
function readText3(inv, path) {
|
|
58869
|
+
try {
|
|
58870
|
+
return readFileSync7(resolve7(inv.deps.paths.cwd, path), "utf8");
|
|
58871
|
+
} catch {
|
|
58872
|
+
throw new UsageError(`could not read ${path}`, { hint: "overlane guard rules test --file rules.json --tool git.push" });
|
|
58873
|
+
}
|
|
58874
|
+
}
|
|
58875
|
+
var ACTION_FLAGS = [
|
|
58876
|
+
{ name: "tool", type: "string", required: true, value: "TOOL", description: "The action, for example git.push, deploy.run, egress.fetch or api.write" },
|
|
58877
|
+
{ name: "path", type: "string", multiple: true, value: "PATH", description: "A path the action touches; repeat for more" },
|
|
58878
|
+
{ name: "branch", type: "string", value: "BRANCH", description: "The branch the action targets" },
|
|
58879
|
+
{ name: "repo", type: "string", value: "OWNER/NAME", description: "The repository the action targets" },
|
|
58880
|
+
{ name: "environment", type: "string", value: "NAME", description: "The environment, for example production" },
|
|
58881
|
+
{ name: "host", type: "string", value: "HOST", description: "The host, for an egress action" }
|
|
58882
|
+
];
|
|
58883
|
+
function actionOf(inv) {
|
|
58884
|
+
const tool = textFlag(inv, "tool");
|
|
58885
|
+
if (tool === void 0) throw new UsageError("this command needs --tool", { hint: "overlane guard dry-run --tool git.push --branch main" });
|
|
58886
|
+
const branch = textFlag(inv, "branch");
|
|
58887
|
+
const repo = textFlag(inv, "repo");
|
|
58888
|
+
const environment = textFlag(inv, "environment");
|
|
58889
|
+
const host = textFlag(inv, "host");
|
|
58890
|
+
const paths = listFlag(inv, "path");
|
|
58891
|
+
return { tool, ...paths.length === 0 ? {} : { paths }, ...branch === void 0 ? {} : { branch }, ...repo === void 0 ? {} : { repository: repo }, ...environment === void 0 ? {} : { environment }, ...host === void 0 ? {} : { host } };
|
|
58892
|
+
}
|
|
58893
|
+
function describeDecision(decision) {
|
|
58894
|
+
const lines = [`${decision.allowed ? decision.wouldBlock ? "ALLOWED (dry-run: would block)" : "ALLOWED" : decision.effect === "require_approval" ? "APPROVAL REQUIRED" : "DENIED"} ${decision.message}`];
|
|
58895
|
+
if (decision.ruleId !== null) lines.push(`rule: ${decision.ruleId}${decision.layer === null ? "" : ` (${decision.layer})`}${decision.code === null ? "" : `, code: ${decision.code}`}`);
|
|
58896
|
+
if (decision.nextCommand !== null) lines.push(`next: ${decision.nextCommand}`);
|
|
58897
|
+
return lines;
|
|
58898
|
+
}
|
|
58899
|
+
function refusalOutcome(data, decision) {
|
|
58900
|
+
const error62 = new CliError(`${decision.message}${decision.ruleId === null ? "" : ` [rule ${decision.ruleId}]`}`, {
|
|
58901
|
+
code: decision.code ?? "policy_denied",
|
|
58902
|
+
exit: EXIT.blocked,
|
|
58903
|
+
...decision.nextCommand === null ? {} : { hint: decision.nextCommand }
|
|
58904
|
+
});
|
|
58905
|
+
return { data, exit: EXIT.blocked, error: error62 };
|
|
58906
|
+
}
|
|
58907
|
+
var guardRulesListCommand = defineCommand({
|
|
58908
|
+
path: ["guard", "rules", "list"],
|
|
58909
|
+
summary: "List the guardrail rules in force and the versions of the rule files",
|
|
58910
|
+
description: "Lists the platform rules (always in force), then the team and project rule files and their rules. A rule change is an audit event; every file version is listed with its digest and author.",
|
|
58911
|
+
examples: ["overlane guard rules list", "overlane guard rules list --json"],
|
|
58912
|
+
effect: "read",
|
|
58913
|
+
...common,
|
|
58914
|
+
keywords: ["guardrails", "policy as code", "rules in force", "protected branches", "what is blocked", "rule files"],
|
|
58915
|
+
result: GuardRulesResponse,
|
|
58916
|
+
text: (d) => [...d.rules.map((rule) => `${rule.layer.padEnd(8)} ${rule.effect.padEnd(16)} ${rule.id}${rule.dryRun ? " [dry-run]" : ""} ${rule.description}`), ...d.files.map((file2) => `file ${file2.layer} v${file2.version} ${file2.digest.slice(0, 19)} by ${file2.author}`)],
|
|
58917
|
+
handler: async (inv) => {
|
|
58918
|
+
const { call: call2, tenantId, projectId } = await connected(inv);
|
|
58919
|
+
return { data: await call2(GuardRulesResponse, "GET", `${guardPaths.rules(tenantId)}?projectId=${encodeURIComponent(projectId)}`) };
|
|
58920
|
+
}
|
|
58921
|
+
});
|
|
58922
|
+
var RuleTestResult = external_exports.object({ decision: GuardDecision, rules: external_exports.number().int().nonnegative(), note: external_exports.string() }).strict();
|
|
58923
|
+
var guardRulesTestCommand = defineCommand({
|
|
58924
|
+
path: ["guard", "rules", "test"],
|
|
58925
|
+
summary: "Test a rule file against an action, locally, before it is merged",
|
|
58926
|
+
description: "Loads a rule file (JSON, version 1) and evaluates one action against it as the team layer, with no network. The server also applies the platform rules, which a team file cannot weaken; use `overlane guard dry-run` to see the combined decision. Exits 6 when the file would refuse the action.",
|
|
58927
|
+
flags: [
|
|
58928
|
+
{ name: "file", type: "string", required: true, value: "PATH", description: "The rule file to test" },
|
|
58929
|
+
...ACTION_FLAGS,
|
|
58930
|
+
{ name: "role", type: "string", enum: ["owner", "admin", "member", "viewer", "agent"], default: "agent", description: "The role of the principal" },
|
|
58931
|
+
{ name: "usage", type: "string", multiple: true, value: "METRIC=N", description: "Measured usage, for example usd=12.5 or reviews=50" }
|
|
58932
|
+
],
|
|
58933
|
+
examples: ["overlane guard rules test --file rules.json --tool git.push --branch main --role agent", "overlane guard rules test --file rules.json --tool review.run --usage reviews=50"],
|
|
58934
|
+
effect: "read",
|
|
58935
|
+
needsAuth: false,
|
|
58936
|
+
needsNetwork: false,
|
|
58937
|
+
keywords: ["test rules", "check rule file", "validate policy", "rule test", "try a rule"],
|
|
58938
|
+
result: RuleTestResult,
|
|
58939
|
+
text: (d) => [...describeDecision(d.decision), d.note],
|
|
58940
|
+
handler: async (inv) => {
|
|
58941
|
+
const file2 = textFlag(inv, "file");
|
|
58942
|
+
if (file2 === void 0) throw new UsageError("rules test needs --file", { hint: "overlane guard rules test --file rules.json --tool git.push" });
|
|
58943
|
+
let json2;
|
|
58944
|
+
try {
|
|
58945
|
+
json2 = JSON.parse(readText3(inv, file2));
|
|
58946
|
+
} catch (error62) {
|
|
58947
|
+
if (error62 instanceof UsageError) throw error62;
|
|
58948
|
+
throw new UsageError(`${file2} is not valid JSON`);
|
|
58949
|
+
}
|
|
58950
|
+
const parsed = GuardRuleFileSource.safeParse(json2);
|
|
58951
|
+
if (!parsed.success) throw new UsageError(`${file2} is not a valid rule file: ${parsed.error.issues.map((issue2) => `${issue2.path.join(".") || "file"}: ${issue2.message}`).join("; ")}`);
|
|
58952
|
+
const usage = {};
|
|
58953
|
+
for (const entry of listFlag(inv, "usage")) {
|
|
58954
|
+
const [metric, value] = entry.split("=");
|
|
58955
|
+
if (metric === void 0 || value === void 0 || Number.isNaN(Number(value))) throw new UsageError("--usage must be METRIC=NUMBER", { hint: "overlane guard rules test --file rules.json --tool ci.run --usage usd=12.5" });
|
|
58956
|
+
usage[metric] = Number(value);
|
|
58957
|
+
}
|
|
58958
|
+
const role = textFlag(inv, "role") ?? "agent";
|
|
58959
|
+
const action = actionOf(inv);
|
|
58960
|
+
const request = GuardRequest.parse({
|
|
58961
|
+
tenantId: "local",
|
|
58962
|
+
principal: { kind: role === "agent" ? "agent" : "user", id: "local-test", role },
|
|
58963
|
+
tool: action.tool,
|
|
58964
|
+
paths: action.paths ?? [],
|
|
58965
|
+
...action.branch === void 0 ? {} : { branch: action.branch },
|
|
58966
|
+
...action.repository === void 0 ? {} : { repository: action.repository },
|
|
58967
|
+
...action.environment === void 0 ? {} : { environment: action.environment },
|
|
58968
|
+
...action.host === void 0 ? {} : { host: action.host },
|
|
58969
|
+
at: new Date(inv.deps.now()).toISOString(),
|
|
58970
|
+
usage
|
|
58971
|
+
});
|
|
58972
|
+
const decision = composeDecision("local", [{ layer: "team", rules: parsed.data.rules }], request);
|
|
58973
|
+
const result = { decision, rules: parsed.data.rules.length, note: "Tested as the team layer only. The platform rules also apply on the server." };
|
|
58974
|
+
return decision.allowed ? { data: result } : refusalOutcome(result, decision);
|
|
58975
|
+
}
|
|
58976
|
+
});
|
|
58977
|
+
var guardRulesPutCommand = defineCommand({
|
|
58978
|
+
path: ["guard", "rules", "put"],
|
|
58979
|
+
summary: "Publish a new version of the team or project rule file",
|
|
58980
|
+
description: "Uploads a rule file as the next version. The file is validated whole, scanned for credentials and recorded as an audit event with its digest and author. Keep the file in version control and review it by pull request; this command publishes what was reviewed.",
|
|
58981
|
+
flags: [
|
|
58982
|
+
{ name: "file", type: "string", required: true, value: "PATH", description: "The rule file (JSON, version 1)" },
|
|
58983
|
+
{ name: "layer", type: "string", enum: ["team", "project"], default: "team", description: "team applies to every project; project applies to this one" },
|
|
58984
|
+
{ name: "reason", type: "string", value: "TEXT", description: "Why the rules changed; kept in the audit event" }
|
|
58985
|
+
],
|
|
58986
|
+
examples: ['overlane guard rules put --file rules.json --reason "freeze deploys on Fridays"', "overlane guard rules put --file rules.json --layer project --dry-run"],
|
|
58987
|
+
effect: "write",
|
|
58988
|
+
...common,
|
|
58989
|
+
keywords: ["publish rules", "update guardrails", "change policy", "upload rule file", "freeze deploys"],
|
|
58990
|
+
result: withDryRun(GuardRuleFileRecord),
|
|
58991
|
+
text: (d) => "version" in d ? [`Published ${d.layer} rule file v${d.version} (${d.ruleCount} rules, ${d.digest.slice(0, 19)}).`] : [],
|
|
58992
|
+
handler: async (inv) => {
|
|
58993
|
+
const file2 = textFlag(inv, "file");
|
|
58994
|
+
if (file2 === void 0) throw new UsageError("rules put needs --file", { hint: "overlane guard rules put --file rules.json" });
|
|
58995
|
+
const layer = textFlag(inv, "layer") ?? "team";
|
|
58996
|
+
const reason = textFlag(inv, "reason");
|
|
58997
|
+
if (inv.dryRun) {
|
|
58998
|
+
const offline = await offlineProject(inv.deps, "guard");
|
|
58999
|
+
return planOutcome(inv.deps, dryRunPlan({ service: offline.serviceUrl, requests: [{ method: "PUT", path: guardPaths.rules(offline.binding.tenantId), body: { requestId: "<generated>", layer, ...layer === "project" ? { projectId: offline.binding.projectId } : {}, content: `<contents of ${file2}>`, ...reason === void 0 ? {} : { reason } }, note: "the file is validated and scanned for credentials on the server" }] }));
|
|
59000
|
+
}
|
|
59001
|
+
const content = readText3(inv, file2);
|
|
59002
|
+
const { call: call2, tenantId, projectId } = await connected(inv);
|
|
59003
|
+
return { data: await call2(GuardRuleFileRecord, "PUT", guardPaths.rules(tenantId), { requestId: requestId3(), layer, ...layer === "project" ? { projectId } : {}, content, ...reason === void 0 ? {} : { reason } }) };
|
|
59004
|
+
}
|
|
59005
|
+
});
|
|
59006
|
+
async function evaluate(inv, dryRun) {
|
|
59007
|
+
const { call: call2, tenantId, projectId } = await connected(inv);
|
|
59008
|
+
const contentFile = textFlag(inv, "content-file");
|
|
59009
|
+
const body2 = {
|
|
59010
|
+
...actionOf(inv),
|
|
59011
|
+
...textFlag(inv, "task") === void 0 ? {} : { taskHeld: textFlag(inv, "task") === "held" },
|
|
59012
|
+
...textFlag(inv, "summary") === void 0 ? {} : { summary: textFlag(inv, "summary") },
|
|
59013
|
+
...contentFile === void 0 ? {} : { content: readText3(inv, contentFile) },
|
|
59014
|
+
...dryRun ? { dryRun: true } : {}
|
|
59015
|
+
};
|
|
59016
|
+
const approval = textFlag(inv, "approval");
|
|
59017
|
+
const reply = await call2(GuardEvaluateResponse, "POST", `${guardPaths.evaluate(tenantId)}?projectId=${encodeURIComponent(projectId)}`, body2, approval === void 0 ? void 0 : { [APPROVAL_HEADER]: approval });
|
|
59018
|
+
return reply;
|
|
59019
|
+
}
|
|
59020
|
+
var DECISION_FLAGS = [
|
|
59021
|
+
...ACTION_FLAGS,
|
|
59022
|
+
{ name: "task", type: "string", enum: ["held", "none"], value: "held|none", description: "Whether the caller holds an active task (the task rule needs it)" },
|
|
59023
|
+
{ name: "summary", type: "string", value: "TEXT", description: "A plain-language summary shown to the approver if the action needs approval" },
|
|
59024
|
+
{ name: "content-file", type: "string", value: "PATH", description: "A file whose text the action would write; scanned for credentials" }
|
|
59025
|
+
];
|
|
59026
|
+
var guardCheckCommand = defineCommand({
|
|
59027
|
+
path: ["guard", "check"],
|
|
59028
|
+
summary: "Ask the server to decide an action now; exits 6 when it is refused",
|
|
59029
|
+
description: "The hook point for the git layer and CI: sends the action to the guardrail engine and exits 0 when allowed, or 6 with the code, the rule ID and the exact next command. An action that needs approval opens one with your summary and prints its ID; run it again with --approval <id> after a person approves.",
|
|
59030
|
+
flags: [...DECISION_FLAGS, { name: "approval", type: "string", value: "ID", description: "An approval that covers exactly this action" }],
|
|
59031
|
+
examples: ["overlane guard check --tool git.push --branch main --task held", 'overlane guard check --tool deploy.run --environment production --summary "Deploy build 42" --dry-run'],
|
|
59032
|
+
effect: "write",
|
|
59033
|
+
...common,
|
|
59034
|
+
keywords: ["check action", "pre push check", "ci gate", "is this allowed", "approval required", "blocked by policy"],
|
|
59035
|
+
result: withDryRun(GuardEvaluateResponse),
|
|
59036
|
+
text: (d) => "decision" in d ? describeDecision(d.decision) : [],
|
|
59037
|
+
handler: async (inv) => {
|
|
59038
|
+
if (inv.dryRun) return planned(inv, "POST", guardPaths.evaluate, { ...actionOf(inv) }, "the decision is recorded; a rule that needs approval opens one");
|
|
59039
|
+
const reply = await evaluate(inv, false);
|
|
59040
|
+
return reply.decision.allowed ? { data: reply } : refusalOutcome(reply, reply.decision);
|
|
59041
|
+
}
|
|
59042
|
+
});
|
|
59043
|
+
var guardDryRunCommand = defineCommand({
|
|
59044
|
+
path: ["guard", "dry-run"],
|
|
59045
|
+
summary: "Report what the guardrails would decide for an action, without blocking or recording",
|
|
59046
|
+
description: "Asks the server for the combined decision (platform, team and project rules) and prints it without recording an audit entry or opening an approval. A rule in dry-run mode shows as would-block. An agent or a person sees exactly what a rule change would do before it is enforced.",
|
|
59047
|
+
flags: DECISION_FLAGS,
|
|
59048
|
+
examples: ["overlane guard dry-run --tool git.push --branch main --task held", "overlane guard dry-run --tool egress.fetch --host registry.example.com --json"],
|
|
59049
|
+
effect: "read",
|
|
59050
|
+
...common,
|
|
59051
|
+
keywords: ["dry run rules", "what would block", "test policy", "simulate", "would be refused"],
|
|
59052
|
+
result: GuardEvaluateResponse,
|
|
59053
|
+
text: (d) => describeDecision(d.decision),
|
|
59054
|
+
handler: async (inv) => ({ data: await evaluate(inv, true) })
|
|
59055
|
+
});
|
|
59056
|
+
var guardScanCommand = defineCommand({
|
|
59057
|
+
path: ["guard", "scan"],
|
|
59058
|
+
summary: "Scan a file for credentials the way a push would be scanned",
|
|
59059
|
+
description: "Sends the text of a file to the secret scanner and reports the rule and line of each finding, never the matched text. Provider-prefixed keys block; generic high-entropy strings are reported only. Exits 6 when something would block.",
|
|
59060
|
+
flags: [
|
|
59061
|
+
{ name: "path", type: "string", required: true, value: "PATH", description: "The file to scan" },
|
|
59062
|
+
{ name: "source", type: "string", enum: SECRET_SOURCES, default: "push", description: "What the text would be: a push, task record, evidence, log or memory" }
|
|
59063
|
+
],
|
|
59064
|
+
examples: ["overlane guard scan --path src/config.ts", "overlane guard scan --path ci.log --source log --json"],
|
|
59065
|
+
effect: "read",
|
|
59066
|
+
...common,
|
|
59067
|
+
keywords: ["secret scan", "find credentials", "leaked key", "push protection", "scan file"],
|
|
59068
|
+
result: SecretScanResult,
|
|
59069
|
+
text: (d) => d.findings.length === 0 ? ["No credentials found."] : d.findings.map((finding) => `${finding.disposition.padEnd(8)} ${finding.rule}${finding.path === void 0 ? "" : ` ${finding.path}`}${finding.line === void 0 ? "" : `:${finding.line}`}`),
|
|
59070
|
+
handler: async (inv) => {
|
|
59071
|
+
const path = textFlag(inv, "path");
|
|
59072
|
+
if (path === void 0) throw new UsageError("scan needs --path", { hint: "overlane guard scan --path src/config.ts" });
|
|
59073
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
59074
|
+
const result = await call2(SecretScanResult, "POST", guardPaths.scan(tenantId), { source: textFlag(inv, "source") ?? "push", content: readText3(inv, path), path });
|
|
59075
|
+
return result.blocked ? { data: result, exit: EXIT.blocked, error: new CliError("a credential was found; nothing should be pushed until it is removed and rotated", { code: "secret_detected", exit: EXIT.blocked, hint: "overlane guard scan --path <file>" }) } : { data: result };
|
|
59076
|
+
}
|
|
59077
|
+
});
|
|
59078
|
+
var ApprovalList2 = external_exports.object({ tenantId: external_exports.string(), approvals: external_exports.array(GuardApproval) }).strict();
|
|
59079
|
+
var guardApprovalsListCommand = defineCommand({
|
|
59080
|
+
path: ["guard", "approvals", "list"],
|
|
59081
|
+
summary: "List approvals waiting for an answer, with the summary and diff of each",
|
|
59082
|
+
description: "Lists approvals the guardrails opened for actions that need a person. Each shows who asked, the rule, a plain-language summary and the change it would make. Nothing runs until an approval is approved.",
|
|
59083
|
+
flags: [{ name: "status", type: "string", enum: ["pending", "approved", "denied"], description: "Only approvals with this status" }],
|
|
59084
|
+
examples: ["overlane guard approvals list", "overlane guard approvals list --status pending --json"],
|
|
59085
|
+
effect: "read",
|
|
59086
|
+
...common,
|
|
59087
|
+
keywords: ["pending approvals", "approve before write", "who needs to approve", "approval queue"],
|
|
59088
|
+
result: ApprovalList2,
|
|
59089
|
+
text: (d) => d.approvals.length === 0 ? ["No approvals."] : d.approvals.flatMap((a) => [`${a.status.padEnd(9)} ${a.id} ${a.tool} by ${a.requestedBy} (rule ${a.ruleId})`, ` ${a.summary}`]),
|
|
59090
|
+
handler: async (inv) => {
|
|
59091
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
59092
|
+
const status = textFlag(inv, "status");
|
|
59093
|
+
return { data: await call2(ApprovalList2, "GET", `${guardPaths.approvals(tenantId)}${status === void 0 ? "" : `?status=${status}`}`) };
|
|
59094
|
+
}
|
|
59095
|
+
});
|
|
59096
|
+
var guardApprovalsAnswerCommand = defineCommand({
|
|
59097
|
+
path: ["guard", "approvals", "answer"],
|
|
59098
|
+
summary: "Approve or deny an action waiting for approval, as an independent agent or a person",
|
|
59099
|
+
description: "Answers one approval. An independent second agent satisfies an approval (a different principal from the one that asked, listing the evidence it checked); a person always can. Under manual autonomy only a person can. An approval covers exactly the action it describes; a changed action needs a new approval. An answered approval does not change.",
|
|
59100
|
+
args: [{ name: "approval-id", required: true, description: "The approval to answer" }],
|
|
59101
|
+
flags: [
|
|
59102
|
+
{ name: "decision", type: "string", required: true, enum: ["approve", "deny"], description: "approve lets the action run; deny keeps it refused" },
|
|
59103
|
+
{ name: "reason", type: "string", value: "TEXT", description: "Why; kept in the approval record" },
|
|
59104
|
+
{ name: "evidence", type: "string", multiple: true, value: "TEXT", description: "What you checked; repeat for more (required for an agent approver)" }
|
|
59105
|
+
],
|
|
59106
|
+
examples: ["overlane guard approvals answer apr_1 --decision approve", 'overlane guard approvals answer apr_1 --decision approve --evidence "diff reviewed" --reason "matches the task" --dry-run'],
|
|
59107
|
+
effect: "write",
|
|
59108
|
+
...common,
|
|
59109
|
+
keywords: ["approve action", "deny action", "answer approval", "allow push", "sign off"],
|
|
59110
|
+
result: withDryRun(GuardApproval),
|
|
59111
|
+
text: (d) => "status" in d ? [`${d.id} is ${d.status}.`] : [],
|
|
59112
|
+
handler: async (inv) => {
|
|
59113
|
+
const approvalId = inv.positionals[0];
|
|
59114
|
+
if (approvalId === void 0) throw new UsageError("answer needs an approval ID", { hint: "overlane guard approvals list --status pending" });
|
|
59115
|
+
const reason = textFlag(inv, "reason");
|
|
59116
|
+
const evidence = listFlag(inv, "evidence");
|
|
59117
|
+
const parsed = AnswerGuardApprovalRequest.safeParse({ decision: textFlag(inv, "decision"), ...reason === void 0 ? {} : { reason }, ...evidence.length === 0 ? {} : { evidence } });
|
|
59118
|
+
if (!parsed.success) throw new UsageError("--decision must be approve or deny", { hint: `overlane guard approvals answer ${approvalId} --decision approve` });
|
|
59119
|
+
if (inv.dryRun) return planned(inv, "POST", (tenantId2) => guardPaths.answer(tenantId2, approvalId), parsed.data);
|
|
59120
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
59121
|
+
return { data: await call2(GuardApproval, "POST", guardPaths.answer(tenantId, approvalId), parsed.data) };
|
|
59122
|
+
}
|
|
59123
|
+
});
|
|
59124
|
+
var guardCommands = [guardRulesListCommand, guardRulesTestCommand, guardRulesPutCommand, guardCheckCommand, guardDryRunCommand, guardScanCommand, guardApprovalsListCommand, guardApprovalsAnswerCommand];
|
|
59125
|
+
|
|
59126
|
+
// ../cli/src/commands/memory.ts
|
|
59127
|
+
init_src();
|
|
59128
|
+
init_zod();
|
|
59129
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
58132
59130
|
var SERVICE_FLAG2 = { name: "service", type: "string", value: "URL", description: "The service address (default: HARNESS_SERVICE_URL, then the project's binding, then the hosted service)" };
|
|
58133
59131
|
var TEAM_FLAG2 = { name: "team", type: "string", value: "TENANT_ID", description: "The team (tenant) to act on (default: the one your token belongs to)" };
|
|
58134
|
-
var
|
|
59132
|
+
var common2 = { needsAuth: true, needsNetwork: true };
|
|
58135
59133
|
async function authed2(inv) {
|
|
58136
59134
|
const target = await resolveTarget(inv.deps, textFlag(inv, "service"));
|
|
58137
59135
|
const token = await requireToken(inv.deps, target.storeKey);
|
|
@@ -58141,16 +59139,16 @@ async function tenantOf2(call2, inv) {
|
|
|
58141
59139
|
return textFlag(inv, "team") ?? (await call2(WhoAmI, "GET", apiPaths.whoami)).tenantId;
|
|
58142
59140
|
}
|
|
58143
59141
|
function idArg(inv, what) {
|
|
58144
|
-
const
|
|
58145
|
-
if (
|
|
58146
|
-
return
|
|
59142
|
+
const id2 = inv.positionals[0];
|
|
59143
|
+
if (id2 === void 0) throw new UsageError(`${what} needs a memory ID`, { hint: "overlane memory search <query>" });
|
|
59144
|
+
return id2;
|
|
58147
59145
|
}
|
|
58148
59146
|
async function plan(inv, method, path, body2, note) {
|
|
58149
59147
|
const target = await resolveTarget(inv.deps, textFlag(inv, "service"));
|
|
58150
59148
|
const tenant = textFlag(inv, "team") ?? ":your-team";
|
|
58151
59149
|
return planOutcome(inv.deps, dryRunPlan({ service: target.service, requests: [{ method, path: path(tenant), ...body2 === void 0 ? {} : { body: body2 }, ...note === void 0 ? {} : { note } }] }));
|
|
58152
59150
|
}
|
|
58153
|
-
var
|
|
59151
|
+
var requestId4 = () => `cli-${randomUUID4()}`;
|
|
58154
59152
|
var memorySearchCommand = defineCommand({
|
|
58155
59153
|
path: ["memory", "search"],
|
|
58156
59154
|
summary: "Search memory across project, team, user and global scopes",
|
|
@@ -58165,7 +59163,7 @@ var memorySearchCommand = defineCommand({
|
|
|
58165
59163
|
],
|
|
58166
59164
|
examples: ['overlane memory search "how do we deploy"', 'overlane memory search "indentation" --scope team --json'],
|
|
58167
59165
|
effect: "read",
|
|
58168
|
-
...
|
|
59166
|
+
...common2,
|
|
58169
59167
|
keywords: ["recall", "remember", "what do we know", "find memory", "lookup", "notes", "conventions", "decisions"],
|
|
58170
59168
|
result: MemorySearchResponse,
|
|
58171
59169
|
text: (d) => d.items.length === 0 ? ["No memories match."] : d.items.map((i2) => `${i2.scope.padEnd(7)} ${i2.status.padEnd(9)} ${i2.id} ${i2.title}${i2.stale ? " [stale]" : ""}${i2.overriddenBy === null ? "" : ` [overridden by ${i2.overriddenBy}]`}`),
|
|
@@ -58199,7 +59197,7 @@ var memoryAddCommand = defineCommand({
|
|
|
58199
59197
|
],
|
|
58200
59198
|
examples: ['overlane memory add --title "Deploy day" "Deploys go out on Tuesdays" --project prj_1', 'overlane memory add --title "Editor" --scope user "I prefer a dark theme" --dry-run'],
|
|
58201
59199
|
effect: "write",
|
|
58202
|
-
...
|
|
59200
|
+
...common2,
|
|
58203
59201
|
keywords: ["remember this", "save a note", "record a decision", "store convention", "candidate"],
|
|
58204
59202
|
result: AddResult,
|
|
58205
59203
|
handler: async (inv) => {
|
|
@@ -58207,7 +59205,7 @@ var memoryAddCommand = defineCommand({
|
|
|
58207
59205
|
if (title === void 0) throw new UsageError("add needs --title", { hint: 'overlane memory add --title "..." "<text>"' });
|
|
58208
59206
|
const project = textFlag(inv, "project");
|
|
58209
59207
|
const parsed = MemoryCandidate.safeParse({
|
|
58210
|
-
requestId:
|
|
59208
|
+
requestId: requestId4(),
|
|
58211
59209
|
scope: textFlag(inv, "scope") ?? "project",
|
|
58212
59210
|
...project === void 0 ? {} : { projectId: project },
|
|
58213
59211
|
category: textFlag(inv, "category") ?? "fact",
|
|
@@ -58238,18 +59236,18 @@ var memoryConfirmCommand = defineCommand({
|
|
|
58238
59236
|
],
|
|
58239
59237
|
examples: ["overlane memory confirm mem_ab12", "overlane memory confirm mem_ab12 --basis ci_evidence --evidence 0123abc:unit_tests --dry-run"],
|
|
58240
59238
|
effect: "write",
|
|
58241
|
-
...
|
|
59239
|
+
...common2,
|
|
58242
59240
|
keywords: ["approve memory", "verify", "promote candidate", "second observer", "ci evidence"],
|
|
58243
59241
|
result: ConfirmResult,
|
|
58244
59242
|
handler: async (inv) => {
|
|
58245
|
-
const
|
|
59243
|
+
const id2 = idArg(inv, "confirm");
|
|
58246
59244
|
const evidence = textFlag(inv, "evidence");
|
|
58247
59245
|
const parsed = MemoryConfirmRequest.safeParse({ basis: textFlag(inv, "basis") ?? "human", ...evidence === void 0 ? {} : { evidenceRef: evidence } });
|
|
58248
59246
|
if (!parsed.success) throw new UsageError(parsed.error.issues.map((issue2) => issue2.message).join("; "));
|
|
58249
|
-
if (inv.dryRun) return plan(inv, "POST", (tenant) => memoryPaths.confirm(tenant,
|
|
59247
|
+
if (inv.dryRun) return plan(inv, "POST", (tenant) => memoryPaths.confirm(tenant, id2), parsed.data);
|
|
58250
59248
|
const { call: call2 } = await authed2(inv);
|
|
58251
59249
|
const tenantId = await tenantOf2(call2, inv);
|
|
58252
|
-
const item = await call2(MemoryItem, "POST", memoryPaths.confirm(tenantId,
|
|
59250
|
+
const item = await call2(MemoryItem, "POST", memoryPaths.confirm(tenantId, id2), parsed.data);
|
|
58253
59251
|
say(inv.deps, `${item.id} is ${item.status}.`);
|
|
58254
59252
|
return { data: item };
|
|
58255
59253
|
}
|
|
@@ -58262,17 +59260,17 @@ var memoryPromoteCommand = defineCommand({
|
|
|
58262
59260
|
flags: [SERVICE_FLAG2, TEAM_FLAG2, { name: "to", type: "string", enum: ["team", "global"], default: "team", description: "Where to promote it" }],
|
|
58263
59261
|
examples: ["overlane memory promote mem_ab12 --to team", "overlane memory promote mem_cd34 --to global --dry-run"],
|
|
58264
59262
|
effect: "write",
|
|
58265
|
-
...
|
|
59263
|
+
...common2,
|
|
58266
59264
|
keywords: ["share with team", "contribute", "global memory", "make team wide"],
|
|
58267
59265
|
result: withDryRun(MemoryPromoteResponse),
|
|
58268
59266
|
handler: async (inv) => {
|
|
58269
|
-
const
|
|
59267
|
+
const id2 = idArg(inv, "promote");
|
|
58270
59268
|
const parsed = MemoryPromoteRequest.safeParse({ to: textFlag(inv, "to") ?? "team" });
|
|
58271
59269
|
if (!parsed.success) throw new UsageError("--to must be team or global");
|
|
58272
|
-
if (inv.dryRun) return plan(inv, "POST", (tenant) => memoryPaths.promote(tenant,
|
|
59270
|
+
if (inv.dryRun) return plan(inv, "POST", (tenant) => memoryPaths.promote(tenant, id2), parsed.data);
|
|
58273
59271
|
const { call: call2 } = await authed2(inv);
|
|
58274
59272
|
const tenantId = await tenantOf2(call2, inv);
|
|
58275
|
-
const out2 = await call2(MemoryPromoteResponse, "POST", memoryPaths.promote(tenantId,
|
|
59273
|
+
const out2 = await call2(MemoryPromoteResponse, "POST", memoryPaths.promote(tenantId, id2), parsed.data);
|
|
58276
59274
|
say(inv.deps, out2.contribution === null ? `Promoted to team as ${out2.item?.id ?? "?"}.` : `Contribution ${out2.contribution.id} is ${out2.contribution.status} (${out2.contribution.tenantsSeen} of ${out2.contribution.k} teams).`);
|
|
58277
59275
|
return { data: out2 };
|
|
58278
59276
|
}
|
|
@@ -58290,7 +59288,7 @@ var memoryExportCommand = defineCommand({
|
|
|
58290
59288
|
],
|
|
58291
59289
|
examples: ["overlane memory export --json", "overlane memory export --scope user --user usr_1 --json"],
|
|
58292
59290
|
effect: "read",
|
|
58293
|
-
...
|
|
59291
|
+
...common2,
|
|
58294
59292
|
keywords: ["download memory", "backup", "data portability", "gdpr", "subject access"],
|
|
58295
59293
|
result: MemoryExportRecord,
|
|
58296
59294
|
text: (d) => [`${d.items.length} memories exported at ${d.exportedAt}. Use --json for the full content.`],
|
|
@@ -58314,15 +59312,15 @@ var memoryDeleteCommand = defineCommand({
|
|
|
58314
59312
|
flags: [SERVICE_FLAG2, TEAM_FLAG2],
|
|
58315
59313
|
examples: ["overlane memory delete mem_ab12 --force", "overlane memory delete mem_ab12 --dry-run"],
|
|
58316
59314
|
effect: "destructive",
|
|
58317
|
-
...
|
|
59315
|
+
...common2,
|
|
58318
59316
|
keywords: ["remove memory", "forget", "erase", "wrong memory", "gdpr deletion"],
|
|
58319
59317
|
result: withDryRun(MemoryDeleteResponse),
|
|
58320
59318
|
handler: async (inv) => {
|
|
58321
|
-
const
|
|
58322
|
-
if (inv.dryRun) return plan(inv, "DELETE", (tenant) => memoryPaths.one(tenant,
|
|
59319
|
+
const id2 = idArg(inv, "delete");
|
|
59320
|
+
if (inv.dryRun) return plan(inv, "DELETE", (tenant) => memoryPaths.one(tenant, id2));
|
|
58323
59321
|
const { call: call2 } = await authed2(inv);
|
|
58324
59322
|
const tenantId = await tenantOf2(call2, inv);
|
|
58325
|
-
const out2 = await call2(MemoryDeleteResponse, "DELETE", memoryPaths.one(tenantId,
|
|
59323
|
+
const out2 = await call2(MemoryDeleteResponse, "DELETE", memoryPaths.one(tenantId, id2));
|
|
58326
59324
|
say(inv.deps, `Deleted ${out2.removedIds.length} memory (${out2.vectorsRemoved} vectors, ${out2.derivedRemoved} derived records).`);
|
|
58327
59325
|
return { data: out2 };
|
|
58328
59326
|
}
|
|
@@ -58335,15 +59333,15 @@ var memoryUnlearnCommand = defineCommand({
|
|
|
58335
59333
|
flags: [SERVICE_FLAG2, TEAM_FLAG2],
|
|
58336
59334
|
examples: ["overlane memory unlearn mem_ab12 --force", "overlane memory unlearn mem_ab12 --dry-run"],
|
|
58337
59335
|
effect: "destructive",
|
|
58338
|
-
...
|
|
59336
|
+
...common2,
|
|
58339
59337
|
keywords: ["unlearn", "forget everything derived", "retract", "poisoned memory", "bad memory"],
|
|
58340
59338
|
result: withDryRun(MemoryUnlearnRecord),
|
|
58341
59339
|
handler: async (inv) => {
|
|
58342
|
-
const
|
|
58343
|
-
if (inv.dryRun) return plan(inv, "POST", (tenant) => memoryPaths.unlearn(tenant,
|
|
59340
|
+
const id2 = idArg(inv, "unlearn");
|
|
59341
|
+
if (inv.dryRun) return plan(inv, "POST", (tenant) => memoryPaths.unlearn(tenant, id2), {});
|
|
58344
59342
|
const { call: call2 } = await authed2(inv);
|
|
58345
59343
|
const tenantId = await tenantOf2(call2, inv);
|
|
58346
|
-
const out2 = await call2(MemoryUnlearnRecord, "POST", memoryPaths.unlearn(tenantId,
|
|
59344
|
+
const out2 = await call2(MemoryUnlearnRecord, "POST", memoryPaths.unlearn(tenantId, id2), {});
|
|
58347
59345
|
say(inv.deps, `Unlearned ${out2.removedIds.length} memories (record ${out2.id}).`);
|
|
58348
59346
|
return { data: out2 };
|
|
58349
59347
|
}
|
|
@@ -58355,7 +59353,7 @@ var memoryStatusCommand = defineCommand({
|
|
|
58355
59353
|
flags: [SERVICE_FLAG2, TEAM_FLAG2],
|
|
58356
59354
|
examples: ["overlane memory status", "overlane memory status --json"],
|
|
58357
59355
|
effect: "read",
|
|
58358
|
-
...
|
|
59356
|
+
...common2,
|
|
58359
59357
|
keywords: ["memory health", "stale memory", "how many memories", "contribution", "opt in"],
|
|
58360
59358
|
result: MemoryStatusResponse,
|
|
58361
59359
|
text: (d) => [...Object.entries(d.counts).map(([key, n]) => `${key}: ${n}`), `stale: ${d.stale}`, `global contribution: ${d.settings.globalContribution ? "on" : "off"}`, `pending jobs: ${d.pendingJobs}`],
|
|
@@ -58373,7 +59371,7 @@ var memoryContributionCommand = defineCommand({
|
|
|
58373
59371
|
flags: [SERVICE_FLAG2, TEAM_FLAG2],
|
|
58374
59372
|
examples: ["overlane memory contribution on", "overlane memory contribution off --dry-run"],
|
|
58375
59373
|
effect: "write",
|
|
58376
|
-
...
|
|
59374
|
+
...common2,
|
|
58377
59375
|
keywords: ["opt in", "opt out", "share patterns", "global pool", "contribute"],
|
|
58378
59376
|
result: withDryRun(MemorySettings),
|
|
58379
59377
|
handler: async (inv) => {
|
|
@@ -58393,10 +59391,10 @@ var memoryCommands = [memorySearchCommand, memoryAddCommand, memoryConfirmComman
|
|
|
58393
59391
|
// ../cli/src/commands/issue.ts
|
|
58394
59392
|
init_src();
|
|
58395
59393
|
init_zod();
|
|
58396
|
-
import { randomUUID as
|
|
58397
|
-
import { readFileSync as
|
|
58398
|
-
var
|
|
58399
|
-
var
|
|
59394
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
59395
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
59396
|
+
var common3 = { needsAuth: true, needsNetwork: true };
|
|
59397
|
+
var requestId5 = () => `cli-${randomUUID5()}`;
|
|
58400
59398
|
var PRIORITIES = ["P0", "P1", "P2", "P3"];
|
|
58401
59399
|
var STATUSES = ["backlog", "todo", "in_progress", "in_review", "cancelled"];
|
|
58402
59400
|
async function send(deps, label, schema, method, path, body2, dryRun) {
|
|
@@ -58433,7 +59431,7 @@ var issueListCommand = defineCommand({
|
|
|
58433
59431
|
flags: [{ name: "status", type: "string", enum: ["backlog", "todo", "in_progress", "in_review", "done", "cancelled"], description: "Only issues in this status" }],
|
|
58434
59432
|
examples: ["overlane issue list", "overlane issue list --status todo --json"],
|
|
58435
59433
|
effect: "read",
|
|
58436
|
-
...
|
|
59434
|
+
...common3,
|
|
58437
59435
|
keywords: ["issues", "backlog", "tickets", "work items", "what is open", "list issues"],
|
|
58438
59436
|
result: external_exports.object({ issues: external_exports.array(IssueShown) }),
|
|
58439
59437
|
handler: async (inv) => {
|
|
@@ -58454,14 +59452,14 @@ var issueShowCommand = defineCommand({
|
|
|
58454
59452
|
args: [{ name: "issue-id", required: true, description: "The issue ID, for example iss_ab12cd34ef56gh78" }],
|
|
58455
59453
|
examples: ["overlane issue show iss_ab12cd34ef56gh78"],
|
|
58456
59454
|
effect: "read",
|
|
58457
|
-
...
|
|
59455
|
+
...common3,
|
|
58458
59456
|
keywords: ["issue details", "ticket", "view issue", "who is working on"],
|
|
58459
59457
|
result: IssueShown,
|
|
58460
59458
|
handler: async (inv) => {
|
|
58461
|
-
const
|
|
58462
|
-
if (
|
|
59459
|
+
const id2 = inv.positionals[0];
|
|
59460
|
+
if (id2 === void 0) throw new UsageError("show needs an ISSUE_ID");
|
|
58463
59461
|
const project = await connectedProject(inv.deps, "issue");
|
|
58464
|
-
const issue2 = shown(inv.deps, await serviceCall(inv.deps, project.serviceUrl, project.token)(Issue, "GET", issuePaths.issue(project.binding.tenantId, project.binding.projectId,
|
|
59462
|
+
const issue2 = shown(inv.deps, await serviceCall(inv.deps, project.serviceUrl, project.token)(Issue, "GET", issuePaths.issue(project.binding.tenantId, project.binding.projectId, id2)));
|
|
58465
59463
|
if (isAgent(inv.deps)) say(inv.deps, UNTRUSTED_NOTICE);
|
|
58466
59464
|
say(inv.deps, line(issue2));
|
|
58467
59465
|
const active = issue2.links.tasks.find((link) => link.state === "active");
|
|
@@ -58477,14 +59475,14 @@ var issueEventsCommand = defineCommand({
|
|
|
58477
59475
|
args: [{ name: "issue-id", required: true, description: "The issue ID" }],
|
|
58478
59476
|
examples: ["overlane issue events iss_ab12cd34ef56gh78"],
|
|
58479
59477
|
effect: "read",
|
|
58480
|
-
...
|
|
59478
|
+
...common3,
|
|
58481
59479
|
keywords: ["audit", "history", "who changed", "field changes", "issue log"],
|
|
58482
59480
|
result: IssueEventList,
|
|
58483
59481
|
handler: async (inv) => {
|
|
58484
|
-
const
|
|
58485
|
-
if (
|
|
59482
|
+
const id2 = inv.positionals[0];
|
|
59483
|
+
if (id2 === void 0) throw new UsageError("events needs an ISSUE_ID");
|
|
58486
59484
|
const project = await connectedProject(inv.deps, "issue");
|
|
58487
|
-
const events = await serviceCall(inv.deps, project.serviceUrl, project.token)(IssueEventList, "GET", issuePaths.events(project.binding.tenantId, project.binding.projectId,
|
|
59485
|
+
const events = await serviceCall(inv.deps, project.serviceUrl, project.token)(IssueEventList, "GET", issuePaths.events(project.binding.tenantId, project.binding.projectId, id2));
|
|
58488
59486
|
for (const event of events.events) say(inv.deps, `${event.sequence} ${event.at} ${event.field} by ${event.actor.type}:${event.actor.id}`);
|
|
58489
59487
|
return { data: events };
|
|
58490
59488
|
}
|
|
@@ -58502,12 +59500,12 @@ var issueNewCommand = defineCommand({
|
|
|
58502
59500
|
],
|
|
58503
59501
|
examples: ['overlane issue new "Back-time drifts by a second"', 'overlane issue new "Fix export" --priority P0 --description "Fails on empty notes"'],
|
|
58504
59502
|
effect: "write",
|
|
58505
|
-
...
|
|
59503
|
+
...common3,
|
|
58506
59504
|
keywords: ["create issue", "new issue", "file a ticket", "add work item", "report bug"],
|
|
58507
59505
|
result: withDryRun(Issue),
|
|
58508
59506
|
handler: async (inv) => {
|
|
58509
59507
|
const estimate = textFlag(inv, "estimate");
|
|
58510
|
-
const body2 = { requestId:
|
|
59508
|
+
const body2 = { requestId: requestId5(), title: inv.positionals.join(" "), description: textFlag(inv, "description") ?? "", priority: priorityFlag(inv) ?? "P1", status: textFlag(inv, "status") ?? "backlog", ...estimate === void 0 ? {} : { estimate: Number(estimate) } };
|
|
58511
59509
|
const result = await send(inv.deps, "issue", Issue, "POST", issuePaths.issues, body2, inv.dryRun);
|
|
58512
59510
|
if (result.value !== void 0) say(inv.deps, `Created #${result.value.number} ${result.value.issueId}`);
|
|
58513
59511
|
return result;
|
|
@@ -58527,15 +59525,15 @@ var issueUpdateCommand = defineCommand({
|
|
|
58527
59525
|
],
|
|
58528
59526
|
examples: ["overlane issue update iss_ab12cd34ef56gh78 --priority P0", 'overlane issue update iss_ab12cd34ef56gh78 --status in_progress --title "New title"'],
|
|
58529
59527
|
effect: "write",
|
|
58530
|
-
...
|
|
59528
|
+
...common3,
|
|
58531
59529
|
keywords: ["edit issue", "change status", "change priority", "rename issue", "update ticket"],
|
|
58532
59530
|
result: withDryRun(Issue),
|
|
58533
59531
|
handler: async (inv) => {
|
|
58534
|
-
const
|
|
58535
|
-
if (
|
|
59532
|
+
const id2 = inv.positionals[0];
|
|
59533
|
+
if (id2 === void 0) throw new UsageError("update needs an ISSUE_ID");
|
|
58536
59534
|
const estimate = textFlag(inv, "estimate");
|
|
58537
59535
|
const body2 = {
|
|
58538
|
-
requestId:
|
|
59536
|
+
requestId: requestId5(),
|
|
58539
59537
|
...textFlag(inv, "title") === void 0 ? {} : { title: textFlag(inv, "title") },
|
|
58540
59538
|
...textFlag(inv, "description") === void 0 ? {} : { description: textFlag(inv, "description") },
|
|
58541
59539
|
...textFlag(inv, "status") === void 0 ? {} : { status: textFlag(inv, "status") },
|
|
@@ -58543,7 +59541,7 @@ var issueUpdateCommand = defineCommand({
|
|
|
58543
59541
|
...estimate === void 0 ? {} : { estimate: Number(estimate) }
|
|
58544
59542
|
};
|
|
58545
59543
|
if (Object.keys(body2).length === 1) throw new UsageError("update needs at least one of --title, --description, --status, --priority, --estimate");
|
|
58546
|
-
return send(inv.deps, "issue", Issue, "PATCH", (t, p) => issuePaths.issue(t, p,
|
|
59544
|
+
return send(inv.deps, "issue", Issue, "PATCH", (t, p) => issuePaths.issue(t, p, id2), body2, inv.dryRun);
|
|
58547
59545
|
}
|
|
58548
59546
|
});
|
|
58549
59547
|
var issueAssignCommand = defineCommand({
|
|
@@ -58556,14 +59554,14 @@ var issueAssignCommand = defineCommand({
|
|
|
58556
59554
|
],
|
|
58557
59555
|
examples: ["overlane issue assign iss_ab12cd34ef56gh78 agent:claude-code", "overlane issue assign iss_ab12cd34ef56gh78 none"],
|
|
58558
59556
|
effect: "write",
|
|
58559
|
-
...
|
|
59557
|
+
...common3,
|
|
58560
59558
|
keywords: ["assign", "give to agent", "hand to bot", "delegate", "who works on this", "unassign"],
|
|
58561
59559
|
result: withDryRun(AssignResult),
|
|
58562
59560
|
handler: async (inv) => {
|
|
58563
|
-
const
|
|
58564
|
-
if (
|
|
59561
|
+
const id2 = inv.positionals[0];
|
|
59562
|
+
if (id2 === void 0) throw new UsageError("assign needs an ISSUE_ID and an assignee");
|
|
58565
59563
|
const assignee = parseAssignee(inv.positionals[1]);
|
|
58566
|
-
const result = await send(inv.deps, "issue", AssignResult, "POST", (t, p) => issuePaths.assign(t, p,
|
|
59564
|
+
const result = await send(inv.deps, "issue", AssignResult, "POST", (t, p) => issuePaths.assign(t, p, id2), { requestId: requestId5(), assignee }, inv.dryRun);
|
|
58567
59565
|
if (result.value !== void 0) say(inv.deps, result.value.taskId === null ? "Assigned." : `Assigned. Task: ${result.value.taskId}${result.value.createdTask ? " (new)" : ""}`);
|
|
58568
59566
|
return result;
|
|
58569
59567
|
}
|
|
@@ -58579,7 +59577,7 @@ var issueImportCommand = defineCommand({
|
|
|
58579
59577
|
flags: [{ name: "preview", type: "boolean", description: "Report what the import would create or update, and write nothing" }],
|
|
58580
59578
|
examples: ["overlane issue import linear ./linear-export.json --preview", "overlane issue import jira ./jira-search.json"],
|
|
58581
59579
|
effect: "write",
|
|
58582
|
-
...
|
|
59580
|
+
...common3,
|
|
58583
59581
|
keywords: ["import", "migrate from linear", "migrate from jira", "github projects import", "bring issues in"],
|
|
58584
59582
|
result: withDryRun(ImportReport),
|
|
58585
59583
|
handler: async (inv) => {
|
|
@@ -58588,11 +59586,11 @@ var issueImportCommand = defineCommand({
|
|
|
58588
59586
|
if (file2 === void 0) throw new UsageError("import needs the path of the export file");
|
|
58589
59587
|
let data;
|
|
58590
59588
|
try {
|
|
58591
|
-
data = JSON.parse(
|
|
59589
|
+
data = JSON.parse(readFileSync8(file2, "utf8"));
|
|
58592
59590
|
} catch {
|
|
58593
59591
|
throw new UsageError(`${file2} is not a readable JSON file`);
|
|
58594
59592
|
}
|
|
58595
|
-
const result = await send(inv.deps, "issue", ImportReport, "POST", issuePaths.import, { requestId:
|
|
59593
|
+
const result = await send(inv.deps, "issue", ImportReport, "POST", issuePaths.import, { requestId: requestId5(), source, dryRun: boolFlag(inv, "preview"), data }, inv.dryRun);
|
|
58596
59594
|
if (result.value !== void 0) {
|
|
58597
59595
|
const r = result.value;
|
|
58598
59596
|
say(inv.deps, `${r.dryRun ? "Would import" : "Imported"} from ${r.source}: ${r.created} new, ${r.updated} updated, ${r.unchanged} unchanged, ${r.skipped.length} skipped.`);
|
|
@@ -58606,7 +59604,7 @@ var issueSyncCommand = defineCommand({
|
|
|
58606
59604
|
description: "Shows the repository and mode: off (default), read_only (GitHub changes flow in, nothing is written to GitHub) or write_back (an owner or admin opted in).",
|
|
58607
59605
|
examples: ["overlane issue sync"],
|
|
58608
59606
|
effect: "read",
|
|
58609
|
-
...
|
|
59607
|
+
...common3,
|
|
58610
59608
|
keywords: ["github sync", "sync status", "two-way sync", "write back"],
|
|
58611
59609
|
result: SyncConfig,
|
|
58612
59610
|
handler: async (inv) => {
|
|
@@ -58626,13 +59624,13 @@ var issueSyncSetCommand = defineCommand({
|
|
|
58626
59624
|
],
|
|
58627
59625
|
examples: ["overlane issue sync set acme/app read_only", "overlane issue sync set acme/app off"],
|
|
58628
59626
|
effect: "write",
|
|
58629
|
-
...
|
|
59627
|
+
...common3,
|
|
58630
59628
|
keywords: ["enable github sync", "write back", "turn off sync", "read only sync"],
|
|
58631
59629
|
result: withDryRun(SyncConfig),
|
|
58632
59630
|
handler: async (inv) => {
|
|
58633
59631
|
const [repository, mode] = inv.positionals;
|
|
58634
59632
|
if (repository === void 0 || mode === void 0) throw new UsageError("sync set needs REPOSITORY and MODE");
|
|
58635
|
-
return send(inv.deps, "issue", SyncConfig, "PUT", issuePaths.sync, { requestId:
|
|
59633
|
+
return send(inv.deps, "issue", SyncConfig, "PUT", issuePaths.sync, { requestId: requestId5(), repository, mode }, inv.dryRun);
|
|
58636
59634
|
}
|
|
58637
59635
|
});
|
|
58638
59636
|
var issueCommands = [issueListCommand, issueShowCommand, issueEventsCommand, issueNewCommand, issueUpdateCommand, issueAssignCommand, issueImportCommand, issueSyncCommand, issueSyncSetCommand];
|
|
@@ -58640,7 +59638,7 @@ var issueCommands = [issueListCommand, issueShowCommand, issueEventsCommand, iss
|
|
|
58640
59638
|
// ../cli/src/commands/issue-views.ts
|
|
58641
59639
|
init_src();
|
|
58642
59640
|
init_zod();
|
|
58643
|
-
var
|
|
59641
|
+
var common4 = { needsAuth: true, needsNetwork: true };
|
|
58644
59642
|
var Deleted = external_exports.object({ deleted: external_exports.literal(true) });
|
|
58645
59643
|
var FIELDS = ["status", "priority", "assigneeType", "assignee", "labelId", "workProjectId", "cycleId", "estimate", "source", "title", "number", "createdAt", "updatedAt"];
|
|
58646
59644
|
function parseCondition(text) {
|
|
@@ -58656,7 +59654,7 @@ var viewListCommand = defineCommand({
|
|
|
58656
59654
|
description: "Lists saved views: a filter plus a group-by and sort over any issue field.",
|
|
58657
59655
|
examples: ["overlane view list"],
|
|
58658
59656
|
effect: "read",
|
|
58659
|
-
...
|
|
59657
|
+
...common4,
|
|
58660
59658
|
keywords: ["saved views", "filters", "board", "group by"],
|
|
58661
59659
|
result: ViewList,
|
|
58662
59660
|
handler: async (inv) => {
|
|
@@ -58674,14 +59672,14 @@ var viewRunCommand = defineCommand({
|
|
|
58674
59672
|
args: [{ name: "view-id", required: true, description: "The saved view ID" }],
|
|
58675
59673
|
examples: ["overlane view run viw_ab12cd34ef56gh78"],
|
|
58676
59674
|
effect: "read",
|
|
58677
|
-
...
|
|
59675
|
+
...common4,
|
|
58678
59676
|
keywords: ["run view", "show board", "group issues"],
|
|
58679
59677
|
result: ViewResult,
|
|
58680
59678
|
handler: async (inv) => {
|
|
58681
|
-
const
|
|
58682
|
-
if (
|
|
59679
|
+
const id2 = inv.positionals[0];
|
|
59680
|
+
if (id2 === void 0) throw new UsageError("run needs a VIEW_ID");
|
|
58683
59681
|
const project = await connectedProject(inv.deps, "view");
|
|
58684
|
-
const result = await serviceCall(inv.deps, project.serviceUrl, project.token)(ViewResult, "GET", issuePaths.viewRun(project.binding.tenantId, project.binding.projectId,
|
|
59682
|
+
const result = await serviceCall(inv.deps, project.serviceUrl, project.token)(ViewResult, "GET", issuePaths.viewRun(project.binding.tenantId, project.binding.projectId, id2));
|
|
58685
59683
|
for (const group of result.groups) {
|
|
58686
59684
|
say(inv.deps, `${group.key} (${group.issues.length})`);
|
|
58687
59685
|
for (const issue2 of group.issues) say(inv.deps, ` #${issue2.number} ${issue2.status} ${issue2.priority}`);
|
|
@@ -58702,12 +59700,12 @@ var viewNewCommand = defineCommand({
|
|
|
58702
59700
|
],
|
|
58703
59701
|
examples: ["overlane view new Urgent --filter priority=P0 --group-by status", 'overlane view new "Agent work" --filter assigneeType=agent --group-by status'],
|
|
58704
59702
|
effect: "write",
|
|
58705
|
-
...
|
|
59703
|
+
...common4,
|
|
58706
59704
|
keywords: ["create view", "save filter", "board", "group by status"],
|
|
58707
59705
|
result: withDryRun(SavedView),
|
|
58708
59706
|
handler: async (inv) => {
|
|
58709
59707
|
const definition = { filter: listFlag(inv, "filter").map(parseCondition), groupBy: textFlag(inv, "group-by") ?? null, sortBy: textFlag(inv, "sort-by") ?? "number", sortDirection: boolFlag(inv, "desc") ? "desc" : "asc" };
|
|
58710
|
-
return send(inv.deps, "view", SavedView, "POST", issuePaths.views, { requestId:
|
|
59708
|
+
return send(inv.deps, "view", SavedView, "POST", issuePaths.views, { requestId: requestId5(), name: inv.positionals.join(" "), definition }, inv.dryRun);
|
|
58711
59709
|
}
|
|
58712
59710
|
});
|
|
58713
59711
|
var viewDeleteCommand = defineCommand({
|
|
@@ -58717,13 +59715,13 @@ var viewDeleteCommand = defineCommand({
|
|
|
58717
59715
|
args: [{ name: "view-id", required: false, description: "The saved view ID (required; checked after the --force confirmation)" }],
|
|
58718
59716
|
examples: ["overlane view delete viw_ab12cd34ef56gh78 --force"],
|
|
58719
59717
|
effect: "destructive",
|
|
58720
|
-
...
|
|
59718
|
+
...common4,
|
|
58721
59719
|
keywords: ["remove view", "delete filter"],
|
|
58722
59720
|
result: withDryRun(Deleted),
|
|
58723
59721
|
handler: async (inv) => {
|
|
58724
|
-
const
|
|
58725
|
-
if (
|
|
58726
|
-
return send(inv.deps, "view", Deleted, "DELETE", (t, p) => `${issuePaths.views(t, p)}/${encodeURIComponent(
|
|
59722
|
+
const id2 = inv.positionals[0];
|
|
59723
|
+
if (id2 === void 0) throw new UsageError("delete needs a VIEW_ID");
|
|
59724
|
+
return send(inv.deps, "view", Deleted, "DELETE", (t, p) => `${issuePaths.views(t, p)}/${encodeURIComponent(id2)}`, void 0, inv.dryRun);
|
|
58727
59725
|
}
|
|
58728
59726
|
});
|
|
58729
59727
|
var loopListCommand = defineCommand({
|
|
@@ -58732,7 +59730,7 @@ var loopListCommand = defineCommand({
|
|
|
58732
59730
|
description: "Lists loops: a trigger (schedule or event), a filter over issues and the executor they dispatch.",
|
|
58733
59731
|
examples: ["overlane loop list"],
|
|
58734
59732
|
effect: "read",
|
|
58735
|
-
...
|
|
59733
|
+
...common4,
|
|
58736
59734
|
keywords: ["loops", "scheduled work", "recurring", "automation"],
|
|
58737
59735
|
result: LoopList,
|
|
58738
59736
|
handler: async (inv) => {
|
|
@@ -58756,7 +59754,7 @@ var loopNewCommand = defineCommand({
|
|
|
58756
59754
|
],
|
|
58757
59755
|
examples: ["overlane loop new Nightly --every 1440 --filter priority=P0", "overlane loop new OnAssign --on issue.assigned"],
|
|
58758
59756
|
effect: "write",
|
|
58759
|
-
...
|
|
59757
|
+
...common4,
|
|
58760
59758
|
keywords: ["schedule agent", "recurring work", "event trigger", "automation", "nightly"],
|
|
58761
59759
|
result: withDryRun(LoopDefinition),
|
|
58762
59760
|
handler: async (inv) => {
|
|
@@ -58764,7 +59762,7 @@ var loopNewCommand = defineCommand({
|
|
|
58764
59762
|
const on = textFlag(inv, "on");
|
|
58765
59763
|
if (every === void 0 === (on === void 0)) throw new UsageError("pass exactly one of --every MINUTES or --on EVENT");
|
|
58766
59764
|
const trigger = every !== void 0 ? { kind: "schedule", everyMinutes: Number(every) } : { kind: "event", on };
|
|
58767
|
-
return send(inv.deps, "loop", LoopDefinition, "POST", issuePaths.loops, { requestId:
|
|
59765
|
+
return send(inv.deps, "loop", LoopDefinition, "POST", issuePaths.loops, { requestId: requestId5(), name: inv.positionals.join(" "), trigger, filter: listFlag(inv, "filter").map(parseCondition), executor: textFlag(inv, "executor") ?? "claude-code" }, inv.dryRun);
|
|
58768
59766
|
}
|
|
58769
59767
|
});
|
|
58770
59768
|
var loopSetCommand = defineCommand({
|
|
@@ -58777,13 +59775,13 @@ var loopSetCommand = defineCommand({
|
|
|
58777
59775
|
],
|
|
58778
59776
|
examples: ["overlane loop set lop_ab12cd34ef56gh78 off"],
|
|
58779
59777
|
effect: "write",
|
|
58780
|
-
...
|
|
59778
|
+
...common4,
|
|
58781
59779
|
keywords: ["disable loop", "enable loop", "stop schedule"],
|
|
58782
59780
|
result: withDryRun(LoopDefinition),
|
|
58783
59781
|
handler: async (inv) => {
|
|
58784
|
-
const [
|
|
58785
|
-
if (
|
|
58786
|
-
return send(inv.deps, "loop", LoopDefinition, "PATCH", (t, p) => issuePaths.loop(t, p,
|
|
59782
|
+
const [id2, state] = inv.positionals;
|
|
59783
|
+
if (id2 === void 0 || state !== "on" && state !== "off") throw new UsageError("set needs a LOOP_ID and on or off");
|
|
59784
|
+
return send(inv.deps, "loop", LoopDefinition, "PATCH", (t, p) => issuePaths.loop(t, p, id2), { requestId: requestId5(), enabled: state === "on" }, inv.dryRun);
|
|
58787
59785
|
}
|
|
58788
59786
|
});
|
|
58789
59787
|
var loopFireCommand = defineCommand({
|
|
@@ -58793,13 +59791,13 @@ var loopFireCommand = defineCommand({
|
|
|
58793
59791
|
args: [{ name: "loop-id", required: true, description: "The loop ID" }],
|
|
58794
59792
|
examples: ["overlane loop fire lop_ab12cd34ef56gh78"],
|
|
58795
59793
|
effect: "write",
|
|
58796
|
-
...
|
|
59794
|
+
...common4,
|
|
58797
59795
|
keywords: ["run loop", "trigger loop", "dispatch agent"],
|
|
58798
59796
|
result: withDryRun(LoopRun),
|
|
58799
59797
|
handler: async (inv) => {
|
|
58800
|
-
const
|
|
58801
|
-
if (
|
|
58802
|
-
const result = await send(inv.deps, "loop", LoopRun, "POST", (t, p) => issuePaths.loopFire(t, p,
|
|
59798
|
+
const id2 = inv.positionals[0];
|
|
59799
|
+
if (id2 === void 0) throw new UsageError("fire needs a LOOP_ID");
|
|
59800
|
+
const result = await send(inv.deps, "loop", LoopRun, "POST", (t, p) => issuePaths.loopFire(t, p, id2), { requestId: requestId5(), trigger: "schedule" }, inv.dryRun);
|
|
58803
59801
|
if (result.value !== void 0) say(inv.deps, `Loop run ${result.value.runId ?? "(none)"}: ${result.value.claimed.length} claimed, stopped: ${result.value.stopReason}.`);
|
|
58804
59802
|
return result;
|
|
58805
59803
|
}
|
|
@@ -58811,18 +59809,220 @@ var loopDeleteCommand = defineCommand({
|
|
|
58811
59809
|
args: [{ name: "loop-id", required: false, description: "The loop ID (required; checked after the --force confirmation)" }],
|
|
58812
59810
|
examples: ["overlane loop delete lop_ab12cd34ef56gh78 --force"],
|
|
58813
59811
|
effect: "destructive",
|
|
58814
|
-
...
|
|
59812
|
+
...common4,
|
|
58815
59813
|
keywords: ["remove loop", "delete schedule"],
|
|
58816
59814
|
result: withDryRun(Deleted),
|
|
58817
59815
|
handler: async (inv) => {
|
|
58818
|
-
const
|
|
58819
|
-
if (
|
|
58820
|
-
return send(inv.deps, "loop", Deleted, "DELETE", (t, p) => issuePaths.loop(t, p,
|
|
59816
|
+
const id2 = inv.positionals[0];
|
|
59817
|
+
if (id2 === void 0) throw new UsageError("delete needs a LOOP_ID");
|
|
59818
|
+
return send(inv.deps, "loop", Deleted, "DELETE", (t, p) => issuePaths.loop(t, p, id2), void 0, inv.dryRun);
|
|
58821
59819
|
}
|
|
58822
59820
|
});
|
|
58823
59821
|
var viewCommands = [viewListCommand, viewRunCommand, viewNewCommand, viewDeleteCommand];
|
|
58824
59822
|
var loopCommands = [loopListCommand, loopNewCommand, loopSetCommand, loopFireCommand, loopDeleteCommand];
|
|
58825
59823
|
|
|
59824
|
+
// ../cli/src/commands/review.ts
|
|
59825
|
+
init_src();
|
|
59826
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
59827
|
+
var common5 = { needsAuth: true, needsNetwork: true };
|
|
59828
|
+
var requestId6 = () => `cli-${randomUUID6()}`;
|
|
59829
|
+
async function connected2(inv) {
|
|
59830
|
+
const project = await connectedProject(inv.deps, "review");
|
|
59831
|
+
return { project, call: serviceCall(inv.deps, project.serviceUrl, project.token), tenantId: project.binding.tenantId, projectId: project.binding.projectId };
|
|
59832
|
+
}
|
|
59833
|
+
async function planned2(inv, method, path, body2, note) {
|
|
59834
|
+
const project = await offlineProject(inv.deps, "review");
|
|
59835
|
+
return planOutcome(inv.deps, dryRunPlan({ service: project.serviceUrl, requests: [{ method, path: path(project.binding.tenantId, project.binding.projectId), ...body2 === void 0 ? {} : { body: body2 }, ...note === void 0 ? {} : { note } }] }));
|
|
59836
|
+
}
|
|
59837
|
+
async function repositoryOf(inv) {
|
|
59838
|
+
const flag = textFlag(inv, "repo");
|
|
59839
|
+
if (flag !== void 0) {
|
|
59840
|
+
if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(flag)) throw new UsageError("--repo must be OWNER/NAME", { hint: "overlane review run 7 --repo acme/app" });
|
|
59841
|
+
return flag;
|
|
59842
|
+
}
|
|
59843
|
+
const remote = await inv.deps.exec("git", ["remote", "get-url", "origin"], { cwd: inv.deps.paths.cwd });
|
|
59844
|
+
const match = /github\.com[:/]([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?\s*$/.exec(remote.stdout.trim());
|
|
59845
|
+
if (remote.code !== 0 || match === null) throw new UsageError("could not read the repository from the origin remote", { hint: "overlane review run 7 --repo OWNER/NAME" });
|
|
59846
|
+
return `${match[1]}/${match[2]}`;
|
|
59847
|
+
}
|
|
59848
|
+
function id(inv, what) {
|
|
59849
|
+
const value = inv.positionals[0];
|
|
59850
|
+
if (value === void 0) throw new UsageError(`${what} needs a finding ID`, { hint: "overlane review findings" });
|
|
59851
|
+
return value;
|
|
59852
|
+
}
|
|
59853
|
+
var FINDING_LINE = (finding) => `${finding.status.padEnd(9)} ${finding.severity.padEnd(8)} ${finding.path}:${finding.line} ${finding.rule ?? "see reason"} ${finding.id}`;
|
|
59854
|
+
var reviewRunCommand = defineCommand({
|
|
59855
|
+
path: ["review", "run"],
|
|
59856
|
+
summary: "Review a GitHub pull request now and report the findings",
|
|
59857
|
+
description: "Runs the review service on a pull request: triage, review passes under the per-PR token cap, inline findings and one updated summary. Until the project owner enables comments (`overlane review settings set --mode comments`) the run is log-only and posts nothing. Pull request text and code are data, never instructions. Needs the GitHub App's pull-request access; without it the command says the live leg is pending.",
|
|
59858
|
+
args: [{ name: "pull", required: true, description: "The pull request number" }],
|
|
59859
|
+
flags: [{ name: "repo", type: "string", value: "OWNER/NAME", description: "The repository (default: the origin remote of this working copy)" }],
|
|
59860
|
+
examples: ["overlane review run 7", "overlane review run 7 --repo acme/app --dry-run"],
|
|
59861
|
+
effect: "write",
|
|
59862
|
+
...common5,
|
|
59863
|
+
keywords: ["code review", "review pull request", "review pr", "ai review", "check my pr", "findings"],
|
|
59864
|
+
result: withDryRun(ReviewRunResponse),
|
|
59865
|
+
text: (d) => "run" in d ? [`${d.run.status} review of ${d.run.repository}#${d.run.pullNumber} (${d.run.mode}${d.run.posted ? ", posted" : ", nothing posted"}): ${d.run.findings.open} open, ${d.run.findings.fixed} fixed, ${d.run.findings.dismissed} dismissed.`, ...d.findings.filter((finding) => finding.status === "open").map(FINDING_LINE)] : [],
|
|
59866
|
+
handler: async (inv) => {
|
|
59867
|
+
const number4 = Number(inv.positionals[0]);
|
|
59868
|
+
if (!Number.isInteger(number4) || number4 < 1) throw new UsageError("run needs a pull request number", { hint: "overlane review run 7" });
|
|
59869
|
+
const repository = await repositoryOf(inv);
|
|
59870
|
+
const body2 = { requestId: requestId6(), trigger: "manual", source: { kind: "github", repository, number: number4 } };
|
|
59871
|
+
if (inv.dryRun) return planned2(inv, "POST", reviewPaths.runs, body2, "reads the pull request through the GitHub App and runs the review");
|
|
59872
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
59873
|
+
const result = await call2(ReviewRunResponse, "POST", reviewPaths.runs(tenantId, projectId), body2);
|
|
59874
|
+
if (result.run.status === "partial") say(inv.deps, "Partial review: the token cap was reached. The summary lists what was not covered.");
|
|
59875
|
+
return { data: result };
|
|
59876
|
+
}
|
|
59877
|
+
});
|
|
59878
|
+
var reviewStatusCommand = defineCommand({
|
|
59879
|
+
path: ["review", "status"],
|
|
59880
|
+
summary: "Show the review mode, recent runs and open findings",
|
|
59881
|
+
description: "Shows whether review posts comments or is log-only, the token cap, the latest runs and the number of open findings. States the data-use terms: diffs go to model providers only under terms that exclude training.",
|
|
59882
|
+
examples: ["overlane review status", "overlane review status --json"],
|
|
59883
|
+
effect: "read",
|
|
59884
|
+
...common5,
|
|
59885
|
+
keywords: ["review mode", "log only", "review settings", "recent reviews", "how is review doing"],
|
|
59886
|
+
result: ReviewStatusResponse,
|
|
59887
|
+
text: (d) => [`Review mode: ${d.settings.mode}. Token cap per pull request: ${d.settings.tokenCap}. Open findings: ${d.openFindings}.`, d.settings.privacy, ...d.runs.slice(0, 5).map((run3) => `${run3.startedAt} ${run3.repository}#${run3.pullNumber} ${run3.status} ${run3.tokensUsed} tokens ${run3.model}`)],
|
|
59888
|
+
handler: async (inv) => {
|
|
59889
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
59890
|
+
return { data: await call2(ReviewStatusResponse, "GET", reviewPaths.status(tenantId, projectId)) };
|
|
59891
|
+
}
|
|
59892
|
+
});
|
|
59893
|
+
var reviewFindingsCommand = defineCommand({
|
|
59894
|
+
path: ["review", "findings"],
|
|
59895
|
+
summary: "List review findings, optionally for one pull request or status",
|
|
59896
|
+
description: "Lists findings tracked across pushes with their status (open, fixed, dismissed), severity, file and line, and the rule or reason.",
|
|
59897
|
+
flags: [
|
|
59898
|
+
{ name: "pull", type: "string", value: "N", description: "Only this pull request number" },
|
|
59899
|
+
{ name: "repo", type: "string", value: "OWNER/NAME", description: "Only this repository" },
|
|
59900
|
+
{ name: "status", type: "string", enum: ["open", "fixed", "dismissed"], description: "Only findings with this status" }
|
|
59901
|
+
],
|
|
59902
|
+
examples: ["overlane review findings --status open", "overlane review findings --pull 7 --json"],
|
|
59903
|
+
effect: "read",
|
|
59904
|
+
...common5,
|
|
59905
|
+
keywords: ["list findings", "open comments", "review comments", "what did review find", "defects"],
|
|
59906
|
+
result: ReviewFindingsResponse,
|
|
59907
|
+
text: (d) => d.findings.length === 0 ? ["No findings."] : d.findings.map(FINDING_LINE),
|
|
59908
|
+
handler: async (inv) => {
|
|
59909
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
59910
|
+
const params = new URLSearchParams();
|
|
59911
|
+
for (const name2 of ["pull", "repo", "status"]) {
|
|
59912
|
+
const value = textFlag(inv, name2);
|
|
59913
|
+
if (value !== void 0) params.set(name2 === "repo" ? "repository" : name2, value);
|
|
59914
|
+
}
|
|
59915
|
+
const query = params.size === 0 ? "" : `?${params.toString()}`;
|
|
59916
|
+
return { data: await call2(ReviewFindingsResponse, "GET", `${reviewPaths.findings(tenantId, projectId)}${query}`) };
|
|
59917
|
+
}
|
|
59918
|
+
});
|
|
59919
|
+
var reviewDismissCommand = defineCommand({
|
|
59920
|
+
path: ["review", "dismiss"],
|
|
59921
|
+
summary: "Dismiss a finding, which teaches the reviewer",
|
|
59922
|
+
description: "Marks a finding dismissed so it is not raised again on this pull request. Repeated dismissals of the same rule become a learned rule held as team memory, and the reviewer stops reporting that rule until feedback changes. Use --accept to tell the reviewer a finding was right instead.",
|
|
59923
|
+
args: [{ name: "finding-id", required: true, description: "The finding to dismiss" }],
|
|
59924
|
+
flags: [
|
|
59925
|
+
{ name: "accept", type: "boolean", description: "Record that the finding was right instead of dismissing it" },
|
|
59926
|
+
{ name: "note", type: "string", value: "TEXT", description: "Why; kept with the feedback" }
|
|
59927
|
+
],
|
|
59928
|
+
examples: ['overlane review dismiss fnd_1 --note "intended"', "overlane review dismiss fnd_2 --accept"],
|
|
59929
|
+
effect: "write",
|
|
59930
|
+
...common5,
|
|
59931
|
+
keywords: ["dismiss finding", "ignore comment", "false positive", "accept finding", "teach reviewer", "feedback"],
|
|
59932
|
+
result: withDryRun(FeedbackResponse),
|
|
59933
|
+
text: (d) => "finding" in d ? [`${d.finding.id} is ${d.finding.status}.${d.learned === null ? "" : ` Learned: ${d.learned.direction} ${d.learned.rule} (${d.learned.evidence} reviews).`}`] : [],
|
|
59934
|
+
handler: async (inv) => {
|
|
59935
|
+
const findingId = id(inv, "dismiss");
|
|
59936
|
+
const note = textFlag(inv, "note");
|
|
59937
|
+
const body2 = { kind: inv.values["accept"] === true ? "accept" : "dismiss", ...note === void 0 ? {} : { note }, requestId: requestId6() };
|
|
59938
|
+
if (inv.dryRun) return planned2(inv, "POST", (tenantId2, projectId2) => reviewPaths.feedback(tenantId2, projectId2, findingId), body2);
|
|
59939
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
59940
|
+
return { data: await call2(FeedbackResponse, "POST", reviewPaths.feedback(tenantId, projectId, findingId), body2) };
|
|
59941
|
+
}
|
|
59942
|
+
});
|
|
59943
|
+
var reviewAutofixCommand = defineCommand({
|
|
59944
|
+
path: ["review", "autofix"],
|
|
59945
|
+
summary: "Create a fix task from a finding and optionally assign it",
|
|
59946
|
+
description: "Turns an open finding into a task whose scope is the finding's file and whose criteria say the finding no longer applies. The task text treats the finding as data. Repeating the command returns the same task.",
|
|
59947
|
+
args: [{ name: "finding-id", required: true, description: "The open finding to fix" }],
|
|
59948
|
+
flags: [{ name: "assign", type: "string", value: "AGENT", description: "The agent or bot to assign, for example agent:fixer" }],
|
|
59949
|
+
examples: ["overlane review autofix fnd_1", "overlane review autofix fnd_1 --assign agent:fixer --dry-run"],
|
|
59950
|
+
effect: "write",
|
|
59951
|
+
...common5,
|
|
59952
|
+
keywords: ["auto fix", "autofix", "fix finding", "create task from finding", "assign to agent"],
|
|
59953
|
+
result: withDryRun(AutofixResponse),
|
|
59954
|
+
text: (d) => "taskId" in d ? [`Task ${d.taskId} created${d.assignee === null ? "" : ` for ${d.assignee}`}. Start it with: overlane task start ${d.taskId}`] : [],
|
|
59955
|
+
handler: async (inv) => {
|
|
59956
|
+
const findingId = id(inv, "autofix");
|
|
59957
|
+
const assignee = textFlag(inv, "assign");
|
|
59958
|
+
const body2 = { requestId: requestId6(), ...assignee === void 0 ? {} : { assignee } };
|
|
59959
|
+
if (inv.dryRun) return planned2(inv, "POST", (tenantId2, projectId2) => reviewPaths.autofix(tenantId2, projectId2, findingId), body2);
|
|
59960
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
59961
|
+
return { data: await call2(AutofixResponse, "POST", reviewPaths.autofix(tenantId, projectId, findingId), body2) };
|
|
59962
|
+
}
|
|
59963
|
+
});
|
|
59964
|
+
var reviewSettingsCommand = defineCommand({
|
|
59965
|
+
path: ["review", "settings"],
|
|
59966
|
+
summary: "Show the review settings, including the data-use terms",
|
|
59967
|
+
description: "Shows the mode (log-only until comments are enabled), the per-PR token cap, extra skip patterns and the statement that diffs go to model providers only under terms that exclude training.",
|
|
59968
|
+
examples: ["overlane review settings"],
|
|
59969
|
+
effect: "read",
|
|
59970
|
+
...common5,
|
|
59971
|
+
keywords: ["review configuration", "token cap", "skip patterns", "privacy", "no training", "data use"],
|
|
59972
|
+
result: ReviewSettings,
|
|
59973
|
+
text: (d) => [`Mode: ${d.mode}. Token cap: ${d.tokenCap}. Extra skip patterns: ${d.skipPatterns.length === 0 ? "none" : d.skipPatterns.join(", ")}.`, d.privacy],
|
|
59974
|
+
handler: async (inv) => {
|
|
59975
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
59976
|
+
return { data: await call2(ReviewSettings, "GET", reviewPaths.settings(tenantId, projectId)) };
|
|
59977
|
+
}
|
|
59978
|
+
});
|
|
59979
|
+
var reviewSettingsSetCommand = defineCommand({
|
|
59980
|
+
path: ["review", "settings", "set"],
|
|
59981
|
+
summary: "Change the review mode, token cap or skip patterns",
|
|
59982
|
+
description: "Sets how review behaves for the project. Enabling comments (`--mode comments`) lets review post inline comments and the summary on GitHub; it is log-only until then. An agent or a person can change them; a read-only viewer cannot.",
|
|
59983
|
+
flags: [
|
|
59984
|
+
{ name: "mode", type: "string", enum: ["log_only", "comments"], description: "log_only records findings only; comments posts them" },
|
|
59985
|
+
{ name: "token-cap", type: "string", value: "N", description: "Most tokens one pull request may use (1,000 to 2,000,000)" },
|
|
59986
|
+
{ name: "skip", type: "string", multiple: true, value: "GLOB", description: "A path pattern to skip in addition to generated and vendored paths; repeat for more" }
|
|
59987
|
+
],
|
|
59988
|
+
examples: ["overlane review settings set --mode comments", "overlane review settings set --token-cap 40000 --skip 'docs/**' --dry-run"],
|
|
59989
|
+
effect: "write",
|
|
59990
|
+
...common5,
|
|
59991
|
+
keywords: ["enable review comments", "turn on review", "log only", "set token cap", "skip files"],
|
|
59992
|
+
result: withDryRun(ReviewSettings),
|
|
59993
|
+
text: (d) => "mode" in d ? [`Review is ${d.mode}. Token cap ${d.tokenCap}.`] : [],
|
|
59994
|
+
handler: async (inv) => {
|
|
59995
|
+
const cap = textFlag(inv, "token-cap");
|
|
59996
|
+
const skip = inv.values["skip"];
|
|
59997
|
+
const parsed = UpdateReviewSettingsRequest.safeParse({
|
|
59998
|
+
...textFlag(inv, "mode") === void 0 ? {} : { mode: textFlag(inv, "mode") },
|
|
59999
|
+
...cap === void 0 ? {} : { tokenCap: Number(cap) },
|
|
60000
|
+
...Array.isArray(skip) ? { skipPatterns: skip } : typeof skip === "string" ? { skipPatterns: [skip] } : {}
|
|
60001
|
+
});
|
|
60002
|
+
if (!parsed.success) throw new UsageError(parsed.error.issues.map((issue2) => issue2.message).join("; "), { hint: "overlane review settings set --mode comments" });
|
|
60003
|
+
if (Object.keys(parsed.data).length === 0) throw new UsageError("nothing to change", { hint: "overlane review settings set --mode comments" });
|
|
60004
|
+
if (inv.dryRun) return planned2(inv, "PUT", reviewPaths.settings, parsed.data);
|
|
60005
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
60006
|
+
return { data: await call2(ReviewSettings, "PUT", reviewPaths.settings(tenantId, projectId), parsed.data) };
|
|
60007
|
+
}
|
|
60008
|
+
});
|
|
60009
|
+
var codeMapStatusCommand = defineCommand({
|
|
60010
|
+
path: ["code-map", "status"],
|
|
60011
|
+
summary: "Show, per client, whether the code map is on and why",
|
|
60012
|
+
description: "Lists every supported client in its local and cloud setting, and the bots, review service, cross-repository questions and wiki, with whether the code map is on and the reason. The default for a setting follows the latest GATE-07 result for that setting: off for a local agent with grep (the local run failed, ADR 0018), on where there is no checkout until a re-run says otherwise.",
|
|
60013
|
+
examples: ["overlane code-map status", "overlane code-map status --json"],
|
|
60014
|
+
effect: "read",
|
|
60015
|
+
...common5,
|
|
60016
|
+
keywords: ["code map", "code tools", "is the code map on", "gate-07", "code layer", "per client"],
|
|
60017
|
+
result: CodeMapStatus,
|
|
60018
|
+
text: (d) => d.clients.map((row) => `${row.on ? "on " : "off"} ${row.subject}: ${row.reason}`),
|
|
60019
|
+
handler: async (inv) => {
|
|
60020
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
60021
|
+
return { data: await call2(CodeMapStatus, "GET", codeMapPaths.status(tenantId, projectId)) };
|
|
60022
|
+
}
|
|
60023
|
+
});
|
|
60024
|
+
var reviewCommands = [reviewRunCommand, reviewStatusCommand, reviewFindingsCommand, reviewDismissCommand, reviewAutofixCommand, reviewSettingsCommand, reviewSettingsSetCommand, codeMapStatusCommand];
|
|
60025
|
+
|
|
58826
60026
|
// ../cli/src/commands/discovery.ts
|
|
58827
60027
|
init_zod();
|
|
58828
60028
|
|
|
@@ -59321,7 +60521,7 @@ async function disconnect(deps, options) {
|
|
|
59321
60521
|
}
|
|
59322
60522
|
|
|
59323
60523
|
// ../cli/src/doctor.ts
|
|
59324
|
-
import { resolve as
|
|
60524
|
+
import { resolve as resolve8 } from "node:path";
|
|
59325
60525
|
init_zod();
|
|
59326
60526
|
var DoctorResult = external_exports.object({
|
|
59327
60527
|
project: external_exports.object({ owner: external_exports.string(), name: external_exports.string(), root: external_exports.string() }),
|
|
@@ -59341,7 +60541,7 @@ async function doctor(deps, options) {
|
|
|
59341
60541
|
const root = project.root;
|
|
59342
60542
|
const binding = readBindingFile(root);
|
|
59343
60543
|
const owned = readOwned(root);
|
|
59344
|
-
const marketplaceRoot2 =
|
|
60544
|
+
const marketplaceRoot2 = resolve8(options.marketplaceRoot ?? owned?.marketplaceRoot ?? deps.paths.defaultMarketplaceRoot);
|
|
59345
60545
|
const infos = await detectAgents(deps, options.agents, root);
|
|
59346
60546
|
let service = "reachable";
|
|
59347
60547
|
let hasToken = false;
|
|
@@ -59401,7 +60601,7 @@ async function doctor(deps, options) {
|
|
|
59401
60601
|
|
|
59402
60602
|
// ../cli/src/kit/setup.ts
|
|
59403
60603
|
init_src();
|
|
59404
|
-
import { randomUUID as
|
|
60604
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
59405
60605
|
import { existsSync as existsSync5, readdirSync as readdirSync2 } from "node:fs";
|
|
59406
60606
|
import { join as join22 } from "node:path";
|
|
59407
60607
|
|
|
@@ -59581,19 +60781,19 @@ async function connectKit(deps, options) {
|
|
|
59581
60781
|
if (options.dryRun) {
|
|
59582
60782
|
const inner = await connect(deps, { ...options, dryRun: true });
|
|
59583
60783
|
say(deps, "Dry run: no file was written and no branch, commit or service change was made.");
|
|
59584
|
-
const
|
|
60784
|
+
const base4 = inner.data !== void 0 && "dryRun" in inner.data ? inner.data : dryRunPlan({});
|
|
59585
60785
|
const writes = [
|
|
59586
60786
|
...planExists ? [] : [{ path: `${PLAN_DIR}/`, action: "write", description: planSource }],
|
|
59587
60787
|
...workflow === null ? [] : [{ path: CI_FILE, action: "write", description: "CI workflow with pinned actions" }],
|
|
59588
60788
|
...blockChanges.map((entry) => ({ path: entry.file, action: entry.before === null ? "write" : "append", description: "the run-step block" })),
|
|
59589
|
-
...
|
|
60789
|
+
...base4.writes
|
|
59590
60790
|
];
|
|
59591
60791
|
return {
|
|
59592
60792
|
data: {
|
|
59593
|
-
...
|
|
59594
|
-
commands: [`git switch -c ${KIT_BRANCH}`, ...
|
|
60793
|
+
...base4,
|
|
60794
|
+
commands: [`git switch -c ${KIT_BRANCH}`, ...base4.commands, `git commit -m "Set up the project kit"`],
|
|
59595
60795
|
writes,
|
|
59596
|
-
notes: [...
|
|
60796
|
+
notes: [...base4.notes, `Plan: ${planSource} (${summary.milestones} milestone(s), ${summary.tasks} task(s)); CI: ${ciSummary}; then the run policy is set, the plan synced and one pull request opened (or its commands printed).`]
|
|
59597
60797
|
}
|
|
59598
60798
|
};
|
|
59599
60799
|
}
|
|
@@ -59617,11 +60817,11 @@ async function connectKit(deps, options) {
|
|
|
59617
60817
|
const agentConfig = [join22(".claude", "settings.json"), join22(".codex", "config.toml")];
|
|
59618
60818
|
const preDirty = new Set(await dirty(deps, root, agentConfig));
|
|
59619
60819
|
const preExisting = new Set(agentConfig.filter((file2) => existsSync5(join22(root, file2))));
|
|
59620
|
-
const
|
|
59621
|
-
if (
|
|
60820
|
+
const connected3 = await connect(deps, { ...options, yes: true });
|
|
60821
|
+
if (connected3.error !== void 0 || readBindingFile(root).kind !== "ok") {
|
|
59622
60822
|
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" });
|
|
59623
60823
|
}
|
|
59624
|
-
const connectData =
|
|
60824
|
+
const connectData = connected3.data !== void 0 && !("dryRun" in connected3.data) ? connected3.data : void 0;
|
|
59625
60825
|
for (const file2 of agentConfig) {
|
|
59626
60826
|
if (!existsSync5(join22(root, file2)) || preDirty.has(file2) || preExisting.has(file2) && (await dirty(deps, root, [file2])).length === 0) continue;
|
|
59627
60827
|
if ((await gitOut(deps, root, "check-ignore", "-q", "--", file2)).code === 0) continue;
|
|
@@ -59640,7 +60840,7 @@ async function connectKit(deps, options) {
|
|
|
59640
60840
|
const kit = kitClient(deps, serviceUrl, binding.binding, token.token);
|
|
59641
60841
|
await kit.putPolicy({ ...DEFAULT_RUN_POLICY, buildAheadLimit: firstMilestone });
|
|
59642
60842
|
say(deps, `Run policy set (build-ahead limit ${firstMilestone}).`);
|
|
59643
|
-
const synced = await kit.syncPlan(PlanSyncRequest.parse({ requestId: `cli-${
|
|
60843
|
+
const synced = await kit.syncPlan(PlanSyncRequest.parse({ requestId: `cli-${randomUUID7()}`, sourceCommit: sha, plan: await readPlan(root) }));
|
|
59644
60844
|
say(deps, `Plan synced: ${synced.created.length} created, ${synced.updated.length} updated, ${synced.unchanged.length} unchanged, ${synced.deferred.length} deferred.`);
|
|
59645
60845
|
const pr = await openPullRequest(deps, root, repository.name);
|
|
59646
60846
|
say(deps);
|
|
@@ -59705,7 +60905,7 @@ var connectCommand = defineCommand({
|
|
|
59705
60905
|
keywords: ["setup", "install", "bind", "link", "onboard", "register plugin", "bootstrap", "autonomous", "plan", "kit", "get started", "initialise", "enable harness", "ci workflow", "pull request"],
|
|
59706
60906
|
result: external_exports.union([ConnectAny, ConnectKitResult]),
|
|
59707
60907
|
handler: async (inv) => {
|
|
59708
|
-
const
|
|
60908
|
+
const base4 = {
|
|
59709
60909
|
service: textFlag(inv, "service"),
|
|
59710
60910
|
marketplaceRoot: textFlag(inv, "marketplace-root"),
|
|
59711
60911
|
agents: parseAgentList(textFlag(inv, "agents")),
|
|
@@ -59716,10 +60916,10 @@ var connectCommand = defineCommand({
|
|
|
59716
60916
|
const goal = textFlag(inv, "goal");
|
|
59717
60917
|
if (kit === void 0) {
|
|
59718
60918
|
if (goal !== void 0) throw new UsageError("--goal belongs to --kit new", { hint: "overlane schema connect" });
|
|
59719
|
-
return connect(inv.deps,
|
|
60919
|
+
return connect(inv.deps, base4);
|
|
59720
60920
|
}
|
|
59721
60921
|
if (kit !== "existing" && kit !== "new") throw new UsageError("--kit must be existing or new");
|
|
59722
|
-
return connectKit(inv.deps, { ...
|
|
60922
|
+
return connectKit(inv.deps, { ...base4, mode: kit, goal });
|
|
59723
60923
|
}
|
|
59724
60924
|
});
|
|
59725
60925
|
var doctorCommand = defineCommand({
|
|
@@ -59788,7 +60988,7 @@ async function listReleases(deps) {
|
|
|
59788
60988
|
record3.manifest.changeKinds.length === 0 ? "-" : record3.manifest.changeKinds.join(","),
|
|
59789
60989
|
record3.manifest.restart,
|
|
59790
60990
|
compatSummary(record3),
|
|
59791
|
-
record3.pinnedBy.length === 0 ? "-" : record3.pinnedBy.map((
|
|
60991
|
+
record3.pinnedBy.length === 0 ? "-" : record3.pinnedBy.map((id2) => id2 === ctx.binding.projectId ? `${id2} (this)` : id2).join(",")
|
|
59792
60992
|
]);
|
|
59793
60993
|
for (const line2 of table([header, ...rows])) say(deps, line2);
|
|
59794
60994
|
return { data };
|
|
@@ -59924,7 +61124,7 @@ var ReleaseRollbackResult = external_exports.union([
|
|
|
59924
61124
|
]);
|
|
59925
61125
|
|
|
59926
61126
|
// ../cli/src/commands/release.ts
|
|
59927
|
-
var
|
|
61127
|
+
var common6 = { needsAuth: true, needsNetwork: true };
|
|
59928
61128
|
var APPROVE = { name: "approve", type: "string", value: "DIGEST", description: "Approve this exact release digest when it changes executable files or policy" };
|
|
59929
61129
|
var releaseListCommand = defineCommand({
|
|
59930
61130
|
path: ["release", "list"],
|
|
@@ -59932,7 +61132,7 @@ var releaseListCommand = defineCommand({
|
|
|
59932
61132
|
description: "Lists releases with version, short digest, channel, change kinds, restart rule, compatibility and which projects pin them.",
|
|
59933
61133
|
examples: ["overlane release list"],
|
|
59934
61134
|
effect: "read",
|
|
59935
|
-
...
|
|
61135
|
+
...common6,
|
|
59936
61136
|
keywords: ["releases", "versions", "available", "published", "what versions", "all releases"],
|
|
59937
61137
|
result: ReleaseListResult,
|
|
59938
61138
|
handler: async (inv) => listReleases(inv.deps)
|
|
@@ -59943,7 +61143,7 @@ var releaseStatusCommand = defineCommand({
|
|
|
59943
61143
|
description: `Compares the installed release (.harness/release.json) with the project binding and the service's pin, and lists approvals recorded on this machine. Works when the service is down (the pin then reads "unreachable").`,
|
|
59944
61144
|
examples: ["overlane release status"],
|
|
59945
61145
|
effect: "read",
|
|
59946
|
-
...
|
|
61146
|
+
...common6,
|
|
59947
61147
|
keywords: ["installed", "version", "in sync", "update available", "which release", "pinned", "am i up to date", "current release"],
|
|
59948
61148
|
result: ReleaseStatusResult,
|
|
59949
61149
|
handler: async (inv) => releaseStatus(inv.deps)
|
|
@@ -59955,7 +61155,7 @@ var releaseUpdateCommand = defineCommand({
|
|
|
59955
61155
|
flags: [{ name: "to", type: "string", value: "DIGEST", description: "Install this release instead of the project's pin" }, APPROVE],
|
|
59956
61156
|
examples: ["overlane release update --dry-run", "overlane release update", "overlane release update --approve sha256:..."],
|
|
59957
61157
|
effect: "write",
|
|
59958
|
-
...
|
|
61158
|
+
...common6,
|
|
59959
61159
|
keywords: ["upgrade", "install release", "new version", "pull latest", "plugin update", "approve", "update plugin", "get newest"],
|
|
59960
61160
|
result: ReleaseUpdateResult,
|
|
59961
61161
|
handler: async (inv) => updateRelease(inv.deps, { to: textFlag(inv, "to"), approve: textFlag(inv, "approve"), dryRun: inv.dryRun })
|
|
@@ -59967,7 +61167,7 @@ var releaseRollbackCommand = defineCommand({
|
|
|
59967
61167
|
flags: [APPROVE],
|
|
59968
61168
|
examples: ["overlane release rollback --dry-run", "overlane release rollback --force"],
|
|
59969
61169
|
effect: "destructive",
|
|
59970
|
-
...
|
|
61170
|
+
...common6,
|
|
59971
61171
|
keywords: ["roll back", "revert", "undo update", "previous version", "downgrade", "go back", "restore", "undo release", "bad release"],
|
|
59972
61172
|
result: ReleaseRollbackResult,
|
|
59973
61173
|
handler: async (inv) => rollbackRelease(inv.deps, { approve: textFlag(inv, "approve"), dryRun: inv.dryRun })
|
|
@@ -60034,7 +61234,7 @@ var RunStatusResult = external_exports.object({
|
|
|
60034
61234
|
var RunPolicyChangeResult = withDryRun(external_exports.object({ changed: external_exports.boolean(), policy: PolicyShape }));
|
|
60035
61235
|
|
|
60036
61236
|
// ../cli/src/commands/run.ts
|
|
60037
|
-
var
|
|
61237
|
+
var common7 = { needsAuth: true, needsNetwork: true };
|
|
60038
61238
|
var EXECUTOR = { name: "executor", type: "string", enum: ["claude-code", "codex"], description: "Which agent this is (default: detected from the environment)" };
|
|
60039
61239
|
var STOP_NOTE = "A stop (policy paused, a budget spent, nothing runnable) exits 6 with the reason in the error code and the exact `overlane run end --reason ...` as the hint.";
|
|
60040
61240
|
var runStartCommand = defineCommand({
|
|
@@ -60044,7 +61244,7 @@ var runStartCommand = defineCommand({
|
|
|
60044
61244
|
flags: [{ name: "trigger", type: "string", enum: ["schedule", "interactive", "event"], default: "interactive", description: "What started the run" }, EXECUTOR],
|
|
60045
61245
|
examples: ["overlane run start --trigger schedule", "overlane run start --dry-run"],
|
|
60046
61246
|
effect: "write",
|
|
60047
|
-
...
|
|
61247
|
+
...common7,
|
|
60048
61248
|
keywords: ["begin run", "bounded step", "autonomous", "start working", "new run", "schedule", "kick off"],
|
|
60049
61249
|
result: RunStartResult,
|
|
60050
61250
|
handler: async (inv) => startRun(inv.deps, { trigger: textFlag(inv, "trigger"), executor: textFlag(inv, "executor"), dryRun: inv.dryRun })
|
|
@@ -60056,7 +61256,7 @@ var runNextCommand = defineCommand({
|
|
|
60056
61256
|
flags: [EXECUTOR],
|
|
60057
61257
|
examples: ["overlane run next"],
|
|
60058
61258
|
effect: "read",
|
|
60059
|
-
...
|
|
61259
|
+
...common7,
|
|
60060
61260
|
keywords: ["what should I work on next", "next task", "runnable", "what to do", "pick a task", "which task", "what's next", "work on", "what is next", "todo"],
|
|
60061
61261
|
result: RunNextResult,
|
|
60062
61262
|
handler: async (inv) => nextTask(inv.deps, { executor: textFlag(inv, "executor") })
|
|
@@ -60068,7 +61268,7 @@ var runClaimCommand = defineCommand({
|
|
|
60068
61268
|
args: [{ name: "task-id", required: false, description: "The task to claim (default: the next runnable one)" }],
|
|
60069
61269
|
examples: ["overlane run claim", "overlane run claim T003"],
|
|
60070
61270
|
effect: "write",
|
|
60071
|
-
...
|
|
61271
|
+
...common7,
|
|
60072
61272
|
keywords: ["take task", "lease task", "grab", "assign", "pick up task", "get a task"],
|
|
60073
61273
|
result: RunClaimResult,
|
|
60074
61274
|
handler: async (inv) => claimTask(inv.deps, { positionals: inv.positionals, dryRun: inv.dryRun })
|
|
@@ -60085,7 +61285,7 @@ var runDecideCommand = defineCommand({
|
|
|
60085
61285
|
],
|
|
60086
61286
|
examples: ['overlane run decide --question "Which date library?" --decision "Use the built-in Intl" --evidence "package.json has no date library"'],
|
|
60087
61287
|
effect: "write",
|
|
60088
|
-
...
|
|
61288
|
+
...common7,
|
|
60089
61289
|
keywords: ["record decision", "question", "unblocked", "owner override", "judgement call", "log choice", "do not ask", "decide"],
|
|
60090
61290
|
result: RunDecideResult,
|
|
60091
61291
|
handler: async (inv) => decide(inv.deps, { question: textFlag(inv, "question"), decision: textFlag(inv, "decision"), evidence: listFlag(inv, "evidence"), task: textFlag(inv, "task"), dryRun: inv.dryRun })
|
|
@@ -60097,7 +61297,7 @@ var runEndCommand = defineCommand({
|
|
|
60097
61297
|
flags: [{ name: "reason", type: "string", required: true, enum: RUN_STOP_REASONS, description: "Why the run ended" }],
|
|
60098
61298
|
examples: ["overlane run end --reason nothing_runnable", "overlane run end --reason error"],
|
|
60099
61299
|
effect: "write",
|
|
60100
|
-
...
|
|
61300
|
+
...common7,
|
|
60101
61301
|
keywords: ["finish run", "stop", "wrap up", "close run", "release leases", "done with run", "end the run"],
|
|
60102
61302
|
result: RunEndResult,
|
|
60103
61303
|
handler: async (inv) => endRun(inv.deps, { reason: textFlag(inv, "reason"), dryRun: inv.dryRun })
|
|
@@ -60109,7 +61309,7 @@ var runStatusCommand = defineCommand({
|
|
|
60109
61309
|
flags: [EXECUTOR],
|
|
60110
61310
|
examples: ["overlane run status"],
|
|
60111
61311
|
effect: "read",
|
|
60112
|
-
...
|
|
61312
|
+
...common7,
|
|
60113
61313
|
keywords: ["policy", "budget", "limits", "how much left", "remaining", "state of run", "is it paused", "run policy"],
|
|
60114
61314
|
result: RunStatusResult,
|
|
60115
61315
|
handler: async (inv) => runStatus(inv.deps, { executor: textFlag(inv, "executor") })
|
|
@@ -60120,7 +61320,7 @@ var runPauseCommand = defineCommand({
|
|
|
60120
61320
|
description: "Sets the project's run policy to paused. Every run then stops at its next check (`STOP paused`). Undo with `overlane run resume`. Safe to repeat.",
|
|
60121
61321
|
examples: ["overlane run pause", "overlane run pause --dry-run"],
|
|
60122
61322
|
effect: "write",
|
|
60123
|
-
...
|
|
61323
|
+
...common7,
|
|
60124
61324
|
keywords: ["pause", "halt", "freeze", "stop all", "emergency brake", "disable autonomous runs", "policy", "no new runs", "stop agents", "turn off", "suspend"],
|
|
60125
61325
|
result: RunPolicyChangeResult,
|
|
60126
61326
|
handler: async (inv) => setPolicyStatus(inv.deps, "paused", inv.dryRun)
|
|
@@ -60131,7 +61331,7 @@ var runResumeCommand = defineCommand({
|
|
|
60131
61331
|
description: "Sets the project's run policy back to active so runs can start and tasks can be claimed again. Safe to repeat.",
|
|
60132
61332
|
examples: ["overlane run resume", "overlane run resume --dry-run"],
|
|
60133
61333
|
effect: "write",
|
|
60134
|
-
...
|
|
61334
|
+
...common7,
|
|
60135
61335
|
keywords: ["unpause", "re-enable", "continue autonomous", "reactivate", "policy active", "turn on", "restart runs", "lift the pause"],
|
|
60136
61336
|
result: RunPolicyChangeResult,
|
|
60137
61337
|
handler: async (inv) => setPolicyStatus(inv.deps, "active", inv.dryRun)
|
|
@@ -60141,7 +61341,7 @@ var runCommands = [runStartCommand, runNextCommand, runClaimCommand, runDecideCo
|
|
|
60141
61341
|
// ../cli/src/task/queue.ts
|
|
60142
61342
|
init_src();
|
|
60143
61343
|
init_zod();
|
|
60144
|
-
import { randomUUID as
|
|
61344
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
60145
61345
|
import { mkdirSync as mkdirSync8, renameSync as renameSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
60146
61346
|
import { dirname as dirname8, join as join23 } from "node:path";
|
|
60147
61347
|
var TASK_POLICY_PATH = join23(".harness", "task-policy.json");
|
|
@@ -60161,7 +61361,7 @@ var TaskQueueResult = TaskQueue;
|
|
|
60161
61361
|
var TaskPrioritiseResult = withDryRun(external_exports.object({ ...PrioritiseResult.shape, next: external_exports.string() }));
|
|
60162
61362
|
var TaskPolicyResult = external_exports.object({ enforcement: TaskEnforcement, reason: external_exports.string().optional(), changedBy: external_exports.string().optional(), updatedAt: external_exports.string().optional(), localFile: external_exports.string() });
|
|
60163
61363
|
var TaskPolicySetResult = withDryRun(TaskPolicyResult);
|
|
60164
|
-
var
|
|
61364
|
+
var requestId7 = () => `cli-${randomUUID8()}`;
|
|
60165
61365
|
function priorityOf(value, fallback) {
|
|
60166
61366
|
const parsed = TaskPriority.safeParse(value ?? fallback);
|
|
60167
61367
|
if (!parsed.success) throw new UsageError(`--priority must be one of ${TASK_PRIORITIES.join(", ")}`);
|
|
@@ -60200,7 +61400,7 @@ async function prioritiseTask(deps, input2) {
|
|
|
60200
61400
|
const name2 = detectExecutorName(deps.env);
|
|
60201
61401
|
let request;
|
|
60202
61402
|
try {
|
|
60203
|
-
request = PrioritiseRequest.parse({ requestId:
|
|
61403
|
+
request = PrioritiseRequest.parse({ requestId: requestId7(), priority, top: input2.top, origin: name2 === "terminal" ? "user" : "agent", ...input2.reason === void 0 ? {} : { reason: input2.reason }, executor: executorFor(name2) });
|
|
60204
61404
|
} catch (error62) {
|
|
60205
61405
|
throw new UsageError(String(error62));
|
|
60206
61406
|
}
|
|
@@ -60229,7 +61429,7 @@ async function newTask(deps, input2) {
|
|
|
60229
61429
|
const begun = data;
|
|
60230
61430
|
const project = await connectedProject(deps, "task");
|
|
60231
61431
|
const name2 = detectExecutorName(deps.env);
|
|
60232
|
-
const request = PrioritiseRequest.parse({ requestId:
|
|
61432
|
+
const request = PrioritiseRequest.parse({ requestId: requestId7(), priority, top: input2.top, origin: name2 === "terminal" ? "user" : "agent", executor: executorFor(name2) });
|
|
60233
61433
|
try {
|
|
60234
61434
|
const ranked = await serviceCall(deps, project.serviceUrl, project.token)(PrioritiseResult, "POST", taskQueuePaths.prioritise(project.binding.tenantId, project.binding.projectId, begun.taskId), request);
|
|
60235
61435
|
say(deps, `Ranked ${begun.taskId} ${ranked.priority}${input2.top ? " (first)" : ""}.`);
|
|
@@ -60250,7 +61450,7 @@ async function setPolicy(deps, input2) {
|
|
|
60250
61450
|
const enforcement = TaskEnforcement.safeParse(input2.enforcement);
|
|
60251
61451
|
if (!enforcement.success) throw new UsageError(`set needs ${TASK_ENFORCEMENT.join(" or ")}`);
|
|
60252
61452
|
const name2 = detectExecutorName(deps.env);
|
|
60253
|
-
const parsed = SetTaskPolicyRequest.safeParse({ requestId:
|
|
61453
|
+
const parsed = SetTaskPolicyRequest.safeParse({ requestId: requestId7(), enforcement: enforcement.data, ...input2.reason === void 0 ? {} : { reason: input2.reason }, executor: executorFor(name2) });
|
|
60254
61454
|
if (!parsed.success) throw new UsageError(parsed.error.issues.map((issue2) => issue2.message).join("; "));
|
|
60255
61455
|
if (input2.dryRun) {
|
|
60256
61456
|
const project2 = await offlineProject(deps, "task");
|
|
@@ -60277,7 +61477,7 @@ async function startExisting(deps, taskId, dryRun) {
|
|
|
60277
61477
|
}
|
|
60278
61478
|
|
|
60279
61479
|
// ../cli/src/commands/queue.ts
|
|
60280
|
-
var
|
|
61480
|
+
var common8 = { needsAuth: true, needsNetwork: true };
|
|
60281
61481
|
var PRIORITIES2 = ["P0", "P1", "P2", "P3"];
|
|
60282
61482
|
var taskNewCommand = defineCommand({
|
|
60283
61483
|
path: ["task", "new"],
|
|
@@ -60293,7 +61493,7 @@ var taskNewCommand = defineCommand({
|
|
|
60293
61493
|
],
|
|
60294
61494
|
examples: ['overlane task new "Fix login redirect"', 'overlane task new "Hotfix the build" --priority P0 --top'],
|
|
60295
61495
|
effect: "write",
|
|
60296
|
-
...
|
|
61496
|
+
...common8,
|
|
60297
61497
|
keywords: ["new task", "create task", "no active task", "blocked no task", "start work", "need a task", "begin", "quick task"],
|
|
60298
61498
|
result: TaskNewResult,
|
|
60299
61499
|
handler: async (inv) => newTask(inv.deps, {
|
|
@@ -60312,7 +61512,7 @@ var taskNextCommand = defineCommand({
|
|
|
60312
61512
|
description: "Picks the best ready or paused task: P0 before P3, then rank, then milestone and dependency order. When this working copy holds a task and the next one outranks it, says so (preempt) and prints the commands to checkpoint and switch; the preempted task comes back through this command afterwards.",
|
|
60313
61513
|
examples: ["overlane task next"],
|
|
60314
61514
|
effect: "read",
|
|
60315
|
-
...
|
|
61515
|
+
...common8,
|
|
60316
61516
|
keywords: ["what next", "next task", "priority", "what should i work on", "pick work", "resume after", "queue"],
|
|
60317
61517
|
result: TaskNextResult,
|
|
60318
61518
|
handler: async (inv) => taskNext(inv.deps)
|
|
@@ -60323,7 +61523,7 @@ var taskQueueCommand = defineCommand({
|
|
|
60323
61523
|
description: "Lists ready, running, paused and blocked tasks by priority, then rank, then plan order, with each task's priority.",
|
|
60324
61524
|
examples: ["overlane task queue"],
|
|
60325
61525
|
effect: "read",
|
|
60326
|
-
...
|
|
61526
|
+
...common8,
|
|
60327
61527
|
keywords: ["priority list", "ranking", "order", "backlog", "what is queued", "p0"],
|
|
60328
61528
|
result: TaskQueueResult,
|
|
60329
61529
|
handler: async (inv) => taskQueue(inv.deps)
|
|
@@ -60340,7 +61540,7 @@ var taskPrioritiseCommand = defineCommand({
|
|
|
60340
61540
|
],
|
|
60341
61541
|
examples: ["overlane task prioritise task-7 --priority P0 --top", 'overlane task prioritise task-9 --priority P2 --reason "user said later"'],
|
|
60342
61542
|
effect: "write",
|
|
60343
|
-
...
|
|
61543
|
+
...common8,
|
|
60344
61544
|
keywords: ["reprioritize", "reprioritise", "bump", "urgent", "move to top", "rank", "lower priority", "p0", "p1", "p2", "p3"],
|
|
60345
61545
|
result: TaskPrioritiseResult,
|
|
60346
61546
|
handler: async (inv) => prioritiseTask(inv.deps, { taskId: inv.positionals[0], priority: textFlag(inv, "priority"), top: boolFlag(inv, "top"), reason: textFlag(inv, "reason"), dryRun: inv.dryRun })
|
|
@@ -60351,7 +61551,7 @@ var taskPolicyCommand = defineCommand({
|
|
|
60351
61551
|
description: "Reads the project's task requirement (default `required`: edits and mutating shell commands are refused without an active task) and writes it to .harness/task-policy.json for the hooks.",
|
|
60352
61552
|
examples: ["overlane task policy"],
|
|
60353
61553
|
effect: "read",
|
|
60354
|
-
...
|
|
61554
|
+
...common8,
|
|
60355
61555
|
keywords: ["enforcement", "require task", "task gate", "relax", "blocked", "policy"],
|
|
60356
61556
|
result: TaskPolicyResult,
|
|
60357
61557
|
handler: async (inv) => showPolicy2(inv.deps)
|
|
@@ -60364,7 +61564,7 @@ var taskPolicySetCommand = defineCommand({
|
|
|
60364
61564
|
flags: [{ name: "reason", type: "string", value: "TEXT", description: "Why the rule is relaxed (required for relaxed)" }],
|
|
60365
61565
|
examples: ["overlane task policy set required", 'overlane task policy set relaxed --reason "docs-only repository"'],
|
|
60366
61566
|
effect: "write",
|
|
60367
|
-
...
|
|
61567
|
+
...common8,
|
|
60368
61568
|
keywords: ["relax", "turn off task requirement", "require tasks", "allow edits without task", "enforcement"],
|
|
60369
61569
|
result: TaskPolicySetResult,
|
|
60370
61570
|
handler: async (inv) => setPolicy(inv.deps, { enforcement: inv.positionals[0], reason: textFlag(inv, "reason"), dryRun: inv.dryRun })
|
|
@@ -60409,14 +61609,14 @@ var TaskHandoffResult = withDryRun(
|
|
|
60409
61609
|
);
|
|
60410
61610
|
|
|
60411
61611
|
// ../cli/src/commands/task.ts
|
|
60412
|
-
var
|
|
61612
|
+
var common9 = { needsAuth: true, needsNetwork: true };
|
|
60413
61613
|
var taskListCommand = defineCommand({
|
|
60414
61614
|
path: ["task", "list"],
|
|
60415
61615
|
summary: "List the project's tasks and their states",
|
|
60416
61616
|
description: "Lists every task of the connected project with its state, pause reason, version, lease holder, checks and latest checkpoint.",
|
|
60417
61617
|
examples: ["overlane task list"],
|
|
60418
61618
|
effect: "read",
|
|
60419
|
-
...
|
|
61619
|
+
...common9,
|
|
60420
61620
|
keywords: ["tasks", "show all tasks", "see tasks", "backlog", "what tasks exist", "work items"],
|
|
60421
61621
|
result: TaskListResult,
|
|
60422
61622
|
handler: async (inv) => listTasks(inv.deps)
|
|
@@ -60434,7 +61634,7 @@ var taskStartCommand = defineCommand({
|
|
|
60434
61634
|
],
|
|
60435
61635
|
examples: ["overlane task start task-7", 'overlane task start --outcome "Add CSV export" --criterion "export works" --check unit_tests:L2 --path "src/**"', 'overlane task start --outcome "Fix login" --criterion "login passes" --path "src/auth/**" --dry-run'],
|
|
60436
61636
|
effect: "write",
|
|
60437
|
-
...
|
|
61637
|
+
...common9,
|
|
60438
61638
|
keywords: ["begin", "create task", "new task", "open", "claim new", "work item", "contract", "acceptance criteria", "start working"],
|
|
60439
61639
|
result: TaskStartResult,
|
|
60440
61640
|
handler: async (inv) => inv.positionals[0] !== void 0 ? startExisting(inv.deps, inv.positionals[0], inv.dryRun) : startTask(inv.deps, { outcome: textFlag(inv, "outcome"), criteria: listFlag(inv, "criterion"), paths: listFlag(inv, "path"), checks: listFlag(inv, "check"), dryRun: inv.dryRun })
|
|
@@ -60445,7 +61645,7 @@ var taskStatusCommand = defineCommand({
|
|
|
60445
61645
|
description: "Shows the held task from the service: state, lease, acceptance criteria, checks, evidence count and the latest checkpoint. Says so when nothing is held or the lease was lost.",
|
|
60446
61646
|
examples: ["overlane task status"],
|
|
60447
61647
|
effect: "read",
|
|
60448
|
-
...
|
|
61648
|
+
...common9,
|
|
60449
61649
|
keywords: ["current task", "what am i working on", "lease", "active task", "progress", "held task"],
|
|
60450
61650
|
result: TaskStatusResult,
|
|
60451
61651
|
handler: async (inv) => taskStatus(inv.deps)
|
|
@@ -60461,7 +61661,7 @@ var taskCheckpointCommand = defineCommand({
|
|
|
60461
61661
|
],
|
|
60462
61662
|
examples: ['overlane task checkpoint --summary "Parser done" --next "Write the tests"', 'overlane task checkpoint --summary "Out of budget" --next "Resume" --pause quota'],
|
|
60463
61663
|
effect: "write",
|
|
60464
|
-
...
|
|
61664
|
+
...common9,
|
|
60465
61665
|
keywords: ["save", "progress", "pause", "stop work", "park", "quota", "limit reached", "remember place", "snapshot", "save state", "out of budget"],
|
|
60466
61666
|
result: TaskCheckpointResult,
|
|
60467
61667
|
handler: async (inv) => checkpointTask(inv.deps, { summary: textFlag(inv, "summary"), next: textFlag(inv, "next"), pause: textFlag(inv, "pause"), dryRun: inv.dryRun })
|
|
@@ -60473,7 +61673,7 @@ var taskResumeCommand = defineCommand({
|
|
|
60473
61673
|
args: [{ name: "task-id", required: true, description: "The task to resume" }],
|
|
60474
61674
|
examples: ["overlane task resume task-1"],
|
|
60475
61675
|
effect: "write",
|
|
60476
|
-
...
|
|
61676
|
+
...common9,
|
|
60477
61677
|
keywords: ["continue", "pick up", "restart", "reclaim", "after pause", "take over", "carry on"],
|
|
60478
61678
|
result: TaskResumeResult,
|
|
60479
61679
|
handler: async (inv) => resumeTask(inv.deps, { taskId: inv.positionals[0], dryRun: inv.dryRun })
|
|
@@ -60484,7 +61684,7 @@ var taskSubmitCommand = defineCommand({
|
|
|
60484
61684
|
description: "Asks for verification at HEAD. The task is verified only when evidence at or above each required check's level exists for that commit: L2 comes from CI on the pushed commit, L1 from `overlane task evidence`.",
|
|
60485
61685
|
examples: ["overlane task submit", "overlane task submit --dry-run"],
|
|
60486
61686
|
effect: "write",
|
|
60487
|
-
...
|
|
61687
|
+
...common9,
|
|
60488
61688
|
keywords: ["finish", "done", "complete", "verify", "ready for review", "request verification", "hand in", "turn in"],
|
|
60489
61689
|
result: TaskSubmitResult,
|
|
60490
61690
|
handler: async (inv) => submitTask(inv.deps, { dryRun: inv.dryRun })
|
|
@@ -60500,7 +61700,7 @@ var taskEvidenceCommand = defineCommand({
|
|
|
60500
61700
|
],
|
|
60501
61701
|
examples: ["overlane task evidence --level L1 -- pnpm test"],
|
|
60502
61702
|
effect: "write",
|
|
60503
|
-
...
|
|
61703
|
+
...common9,
|
|
60504
61704
|
keywords: ["tests", "prove", "record test result", "verification", "run checks", "L1", "attest", "run the tests and record"],
|
|
60505
61705
|
result: TaskEvidenceResult,
|
|
60506
61706
|
handler: async (inv) => recordEvidence(inv.deps, { level: textFlag(inv, "level"), task: textFlag(inv, "task"), words: inv.positionals, dryRun: inv.dryRun })
|
|
@@ -60516,7 +61716,7 @@ var taskHandoffCommand = defineCommand({
|
|
|
60516
61716
|
],
|
|
60517
61717
|
examples: ["overlane task handoff --to codex", 'overlane task handoff --to claude --summary "API done" --next "Add tests"'],
|
|
60518
61718
|
effect: "write",
|
|
60519
|
-
...
|
|
61719
|
+
...common9,
|
|
60520
61720
|
keywords: ["hand off", "transfer", "give to", "switch agent", "other agent", "codex", "claude", "pass the task", "delegate", "move work", "swap agents"],
|
|
60521
61721
|
result: TaskHandoffResult,
|
|
60522
61722
|
handler: async (inv) => handoffTask(inv.deps, { summary: textFlag(inv, "summary"), next: textFlag(inv, "next"), to: textFlag(inv, "to"), dryRun: inv.dryRun })
|
|
@@ -60544,7 +61744,9 @@ function coreCommands() {
|
|
|
60544
61744
|
...viewCommands,
|
|
60545
61745
|
...loopCommands,
|
|
60546
61746
|
clientInstallCommand,
|
|
60547
|
-
...memoryCommands
|
|
61747
|
+
...memoryCommands,
|
|
61748
|
+
...reviewCommands,
|
|
61749
|
+
...guardCommands
|
|
60548
61750
|
];
|
|
60549
61751
|
}
|
|
60550
61752
|
function createRegistry(extra = []) {
|
|
@@ -60767,22 +61969,22 @@ import { join as join27 } from "node:path";
|
|
|
60767
61969
|
function dataDir(env = process.env, home = homedir()) {
|
|
60768
61970
|
const override = env["MVRX_DATA_DIR"];
|
|
60769
61971
|
if (override !== void 0 && override !== "") return override;
|
|
60770
|
-
const
|
|
60771
|
-
return join27(
|
|
61972
|
+
const base4 = env["XDG_DATA_HOME"] ?? (process.platform === "win32" ? env["LOCALAPPDATA"] : void 0) ?? (process.platform === "darwin" ? join27(home, "Library", "Application Support") : join27(home, ".local", "share"));
|
|
61973
|
+
return join27(base4, "mvrx-harness");
|
|
60772
61974
|
}
|
|
60773
61975
|
function marketplaceRoot(env = process.env, home = homedir()) {
|
|
60774
61976
|
return join27(dataDir(env, home), "marketplace");
|
|
60775
61977
|
}
|
|
60776
61978
|
|
|
60777
61979
|
// src/plugin.ts
|
|
60778
|
-
import { readFileSync as
|
|
61980
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
60779
61981
|
import { join as join29 } from "node:path";
|
|
60780
61982
|
import { parseArgs as parseArgs3 } from "node:util";
|
|
60781
61983
|
|
|
60782
61984
|
// src/marketplace.ts
|
|
60783
61985
|
init_src();
|
|
60784
61986
|
import { createHash as createHash7 } from "node:crypto";
|
|
60785
|
-
import { cpSync, existsSync as existsSync6, mkdirSync as mkdirSync9, readdirSync as readdirSync3, readFileSync as
|
|
61987
|
+
import { cpSync, existsSync as existsSync6, mkdirSync as mkdirSync9, readdirSync as readdirSync3, readFileSync as readFileSync9, renameSync as renameSync6, rmSync as rmSync4, statSync, writeFileSync as writeFileSync8 } from "node:fs";
|
|
60786
61988
|
import { dirname as dirname9, join as join28, relative as relative2, sep } from "node:path";
|
|
60787
61989
|
var CLIENT_DIRS = ["claude", "codex"];
|
|
60788
61990
|
var EMBEDDED_MANIFEST = "release-manifest.json";
|
|
@@ -60793,7 +61995,7 @@ function loadEmbedded(packageRoot2) {
|
|
|
60793
61995
|
const dir = join28(packageRoot2, "plugins");
|
|
60794
61996
|
const path = join28(dir, EMBEDDED_MANIFEST);
|
|
60795
61997
|
if (!existsSync6(path)) throw new MarketplaceError(`this package has no embedded plugin release (${path} is missing)`);
|
|
60796
|
-
const parsed = ReleaseManifest.safeParse(JSON.parse(
|
|
61998
|
+
const parsed = ReleaseManifest.safeParse(JSON.parse(readFileSync9(path, "utf8")));
|
|
60797
61999
|
if (!parsed.success) throw new MarketplaceError(`the embedded release manifest is invalid: ${parsed.error.message}`);
|
|
60798
62000
|
return { dir, manifest: parsed.data };
|
|
60799
62001
|
}
|
|
@@ -60821,7 +62023,7 @@ async function verifyTree(treeRoot, manifest) {
|
|
|
60821
62023
|
problems.push(`missing: ${file2.path}`);
|
|
60822
62024
|
continue;
|
|
60823
62025
|
}
|
|
60824
|
-
if (sha2562(
|
|
62026
|
+
if (sha2562(readFileSync9(path)) !== file2.digest) problems.push(`modified: ${file2.path}`);
|
|
60825
62027
|
}
|
|
60826
62028
|
for (const client of CLIENT_DIRS) {
|
|
60827
62029
|
for (const found of listFiles(join28(treeRoot, client))) {
|
|
@@ -60832,7 +62034,7 @@ async function verifyTree(treeRoot, manifest) {
|
|
|
60832
62034
|
}
|
|
60833
62035
|
function readInstalledManifest(target) {
|
|
60834
62036
|
try {
|
|
60835
|
-
const parsed = ReleaseManifest.safeParse(JSON.parse(
|
|
62037
|
+
const parsed = ReleaseManifest.safeParse(JSON.parse(readFileSync9(join28(target, INSTALLED_MANIFEST), "utf8")));
|
|
60836
62038
|
return parsed.success ? parsed.data : null;
|
|
60837
62039
|
} catch {
|
|
60838
62040
|
return null;
|
|
@@ -60896,7 +62098,7 @@ var PluginUsageError = class extends Error {
|
|
|
60896
62098
|
};
|
|
60897
62099
|
function readNames(treeRoot, client) {
|
|
60898
62100
|
const file2 = client === "claude" ? join29(treeRoot, "claude", ".claude-plugin", "marketplace.json") : join29(treeRoot, "codex", ".agents", "plugins", "marketplace.json");
|
|
60899
|
-
const parsed = JSON.parse(
|
|
62101
|
+
const parsed = JSON.parse(readFileSync10(file2, "utf8"));
|
|
60900
62102
|
const record3 = parsed;
|
|
60901
62103
|
const plugin = record3.plugins?.[0]?.name;
|
|
60902
62104
|
if (typeof record3.name !== "string" || typeof plugin !== "string") throw new MarketplaceError(`${file2} names no marketplace or plugin`);
|
|
@@ -61168,8 +62370,8 @@ async function confirm(question) {
|
|
|
61168
62370
|
}
|
|
61169
62371
|
}
|
|
61170
62372
|
function configDir2(env) {
|
|
61171
|
-
const
|
|
61172
|
-
return join32(
|
|
62373
|
+
const base4 = env["XDG_CONFIG_HOME"] ?? (process.platform === "win32" ? env["APPDATA"] : void 0) ?? join32(homedir3(), ".config");
|
|
62374
|
+
return join32(base4, "mvrx-harness");
|
|
61173
62375
|
}
|
|
61174
62376
|
function createDeps2(env = process.env) {
|
|
61175
62377
|
return {
|