@quantiya/codevibe-core 2.0.75 → 2.0.77
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/appsync/sync-operation-journal.d.ts +2 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +485 -485
- package/dist/local-executor/authority.d.ts +46 -0
- package/dist/local-executor/implementor-argv.d.ts +33 -1
- package/dist/local-executor/index.d.ts +3 -2
- package/dist/local-executor/local-executor-impl.d.ts +1 -0
- package/dist/orchestration-shell/cli.js +724 -143
- package/dist/orchestration-shell/index.d.ts +21 -0
- package/dist/substrate/sandbox-exec.d.ts +6 -1
- package/dist/substrate/types.d.ts +5 -0
- package/dist/substrate-launch/engage-substrate.d.ts +5 -0
- package/package.json +1 -1
|
@@ -749,10 +749,10 @@ ${yaml}---
|
|
|
749
749
|
|
|
750
750
|
${prose}`;
|
|
751
751
|
}
|
|
752
|
-
function getTaskDirectoryPath(taskId, homeDir =
|
|
752
|
+
function getTaskDirectoryPath(taskId, homeDir = os39.homedir()) {
|
|
753
753
|
return path66.join(homeDir, ".codevibe", "tasks", taskId);
|
|
754
754
|
}
|
|
755
|
-
function getPacketFilePath(taskId, homeDir =
|
|
755
|
+
function getPacketFilePath(taskId, homeDir = os39.homedir()) {
|
|
756
756
|
return path66.join(getTaskDirectoryPath(taskId, homeDir), "CONTINUATION.md");
|
|
757
757
|
}
|
|
758
758
|
async function atomicWritePacket(taskDir, finalPath, bytes, pid, ts, randHex) {
|
|
@@ -802,7 +802,7 @@ async function atomicWritePacket(taskDir, finalPath, bytes, pid, ts, randHex) {
|
|
|
802
802
|
}
|
|
803
803
|
}
|
|
804
804
|
function createContinuationPacketWriter(deps) {
|
|
805
|
-
let perTaskMutex = /* @__PURE__ */ new Map(), homeDir = deps.homeDir ??
|
|
805
|
+
let perTaskMutex = /* @__PURE__ */ new Map(), homeDir = deps.homeDir ?? os39.homedir(), clock = deps.clock ?? Date.now, randomHex = deps.randomHex ?? defaultRandomHex, collector = deps.dirtyStateCollector ?? {
|
|
806
806
|
collect: async () => collectRepoStates(deps.authority, [], {}).catch(() => [])
|
|
807
807
|
}, getMutex = (taskId) => {
|
|
808
808
|
let m = perTaskMutex.get(taskId);
|
|
@@ -871,10 +871,10 @@ function createContinuationPacketWriter(deps) {
|
|
|
871
871
|
}
|
|
872
872
|
};
|
|
873
873
|
}
|
|
874
|
-
var import_node_fs28, path66,
|
|
874
|
+
var import_node_fs28, path66, os39, crypto26, import_json_freeze15, import_yaml, Mutex, WORK_NOT_ENUMERATED_SENTINEL, VERIFICATION_NOT_RECORDED_SENTINEL, init_packet_writer = __esm({
|
|
875
875
|
"src/continuation/packet-writer.ts"() {
|
|
876
876
|
"use strict";
|
|
877
|
-
import_node_fs28 = require("node:fs"), path66 = __toESM(require("node:path")),
|
|
877
|
+
import_node_fs28 = require("node:fs"), path66 = __toESM(require("node:path")), os39 = __toESM(require("node:os")), crypto26 = __toESM(require("node:crypto")), import_json_freeze15 = require("json-freeze"), import_yaml = require("yaml");
|
|
878
878
|
init_types();
|
|
879
879
|
init_dirty_state_collector();
|
|
880
880
|
Mutex = class {
|
|
@@ -943,7 +943,7 @@ var init_resolve_agent = __esm({
|
|
|
943
943
|
|
|
944
944
|
// src/companion-mode/persist-preference.ts
|
|
945
945
|
function resolveHome11() {
|
|
946
|
-
return (process.env.VITEST === "true" || process.env.NODE_ENV === "test") && process.env.CODEVIBE_HOME_OVERRIDE ? process.env.CODEVIBE_HOME_OVERRIDE :
|
|
946
|
+
return (process.env.VITEST === "true" || process.env.NODE_ENV === "test") && process.env.CODEVIBE_HOME_OVERRIDE ? process.env.CODEVIBE_HOME_OVERRIDE : os52.homedir();
|
|
947
947
|
}
|
|
948
948
|
function companionPreferenceFilePath() {
|
|
949
949
|
return path84.join(resolveHome11(), ".codevibe", "companion-preference.json");
|
|
@@ -991,10 +991,10 @@ async function persistCompanionPreference(pref) {
|
|
|
991
991
|
} catch {
|
|
992
992
|
}
|
|
993
993
|
}
|
|
994
|
-
var fs63, path84,
|
|
994
|
+
var fs63, path84, os52, import_zod16, CompanionPreferenceSchema, init_persist_preference = __esm({
|
|
995
995
|
"src/companion-mode/persist-preference.ts"() {
|
|
996
996
|
"use strict";
|
|
997
|
-
fs63 = __toESM(require("fs/promises")), path84 = __toESM(require("path")),
|
|
997
|
+
fs63 = __toESM(require("fs/promises")), path84 = __toESM(require("path")), os52 = __toESM(require("os")), import_zod16 = require("zod");
|
|
998
998
|
init_logger2();
|
|
999
999
|
CompanionPreferenceSchema = import_zod16.z.object({
|
|
1000
1000
|
lastAgent: import_zod16.z.union([
|
|
@@ -4319,15 +4319,15 @@ async function probeWorkspaceTreeFingerprint(workspaceRoot, options = {}) {
|
|
|
4319
4319
|
), fields = stdout.split("\0").filter((field2) => field2.length > 0), parts = [];
|
|
4320
4320
|
for (let i = 0; i < fields.length; i++) {
|
|
4321
4321
|
if (remaining() <= 0) return failed();
|
|
4322
|
-
let xy = fields[i].slice(0, 2),
|
|
4322
|
+
let xy = fields[i].slice(0, 2), relative23 = fields[i].slice(3);
|
|
4323
4323
|
/[RC]/.test(xy) && (i += 1);
|
|
4324
4324
|
let stat13 = "absent";
|
|
4325
4325
|
try {
|
|
4326
|
-
let st = await fs10.lstat(path13.join(root,
|
|
4326
|
+
let st = await fs10.lstat(path13.join(root, relative23));
|
|
4327
4327
|
stat13 = `${st.size}:${st.mtimeMs}`;
|
|
4328
4328
|
} catch {
|
|
4329
4329
|
}
|
|
4330
|
-
parts.push(`${xy} ${
|
|
4330
|
+
parts.push(`${xy} ${relative23} ${stat13}`);
|
|
4331
4331
|
}
|
|
4332
4332
|
return remaining() <= 0 ? failed() : {
|
|
4333
4333
|
kind: "fingerprint",
|
|
@@ -10294,7 +10294,7 @@ var SyncJournalError = class extends Error {
|
|
|
10294
10294
|
this.code = code;
|
|
10295
10295
|
this.name = "SyncJournalError";
|
|
10296
10296
|
}
|
|
10297
|
-
}, UUID8 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i, MAX_RECORD_BYTES = 1024 * 1024, MAX_ENVELOPE_BYTES = 2 * MAX_RECORD_BYTES, MAX_FILES = 256, MAX_STORE_BYTES = 32 * 1024 * 1024, MAX_RETIREMENT_INTENTS = 16, MAX_RETIREMENT_BYTES = 32 * 1024, invalid7 = () => {
|
|
10297
|
+
}, UUID8 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i, MAX_RECORD_BYTES = 1024 * 1024, MAX_ENVELOPE_BYTES = 2 * MAX_RECORD_BYTES, MAX_FILES = 256, MAX_STORE_BYTES = 32 * 1024 * 1024, MAX_RETIREMENT_INTENTS = 16, MAX_RETIREMENT_BYTES = 32 * 1024, MAX_INVENTORY_FILES = MAX_FILES * 4 + MAX_RETIREMENT_INTENTS * 2 + 8, MAX_DIRECTORY_ENTRIES = MAX_INVENTORY_FILES * 4 + MAX_FILES + MAX_RETIREMENT_INTENTS * 2 + 8, invalid7 = () => {
|
|
10298
10298
|
throw new SyncJournalError("SYNC_JOURNAL_INVALID");
|
|
10299
10299
|
}, errorCode = (error) => error?.code;
|
|
10300
10300
|
function operationId(value) {
|
|
@@ -10487,7 +10487,7 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
10487
10487
|
}) : (this.options.assertAccount(), []);
|
|
10488
10488
|
}
|
|
10489
10489
|
/** One encrypted intent/credential record per original desktop incarnation.
|
|
10490
|
-
*
|
|
10490
|
+
* Bookkeeping shares the 32-MiB bound, but not outbound-operation slots. */
|
|
10491
10491
|
desktopRegistration(register, now = Date.now) {
|
|
10492
10492
|
let scope = this.sessionScope;
|
|
10493
10493
|
if (!scope || typeof register != "function") return invalid7();
|
|
@@ -11123,6 +11123,14 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11123
11123
|
let plan = await this.withStore((key) => this.retiredSourcePlan(key, input.expectedSessionKeyGen));
|
|
11124
11124
|
if (!plan.sources.length) return { sourcesRemoved: 0, operationsRemoved: 0 };
|
|
11125
11125
|
parseSyncSessionRetirementReceipt(await confirm(input), input), this.options.assertAccount();
|
|
11126
|
+
let total = { sourcesRemoved: 0, operationsRemoved: 0 };
|
|
11127
|
+
for (let page = 0; page < MAX_INVENTORY_FILES; page++) {
|
|
11128
|
+
let removed = await this.removeRetiredSourceBatch(plan, input.expectedSessionKeyGen);
|
|
11129
|
+
if (total.sourcesRemoved += removed.sourcesRemoved, total.operationsRemoved += removed.operationsRemoved, plan = await this.withStore((key) => this.retiredSourcePlan(key, input.expectedSessionKeyGen)), !plan.sources.length) return total;
|
|
11130
|
+
}
|
|
11131
|
+
throw new SyncJournalError("SYNC_OPERATION_PENDING");
|
|
11132
|
+
}
|
|
11133
|
+
async removeRetiredSourceBatch(plan, expectedSessionKeyGen) {
|
|
11126
11134
|
let owners = [], fence = async () => {
|
|
11127
11135
|
this.options.assertAccount();
|
|
11128
11136
|
for (let owner of owners) if (!await owner.reassertOwnership()) throw new SyncJournalError("SYNC_JOURNAL_LOCK_LOST");
|
|
@@ -11137,7 +11145,7 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11137
11145
|
if (owners.push(owner), this.options.assertAccount(), !await owner.reassertOwnership()) throw new SyncJournalError("SYNC_JOURNAL_LOCK_LOST");
|
|
11138
11146
|
}
|
|
11139
11147
|
return await this.withStore(async (key, storeFence) => {
|
|
11140
|
-
let current = await this.retiredSourcePlan(key,
|
|
11148
|
+
let current = await this.retiredSourcePlan(key, expectedSessionKeyGen);
|
|
11141
11149
|
if (current.digest !== plan.digest) throw new SyncJournalError("SYNC_OPERATION_PENDING");
|
|
11142
11150
|
await fence();
|
|
11143
11151
|
for (let name of current.operations)
|
|
@@ -11196,15 +11204,20 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11196
11204
|
}
|
|
11197
11205
|
async retiredSourcePlan(key, expectedSessionKeyGen) {
|
|
11198
11206
|
if (!this.sessionScope) return invalid7();
|
|
11199
|
-
let sources = [], operations = [], images = [], linked = /* @__PURE__ */ new Set(), outer = /* @__PURE__ */ new Set(), inner = /* @__PURE__ */ new Set(), expectedInputs = /* @__PURE__ */ new Map(), bind = (value) => {
|
|
11207
|
+
let sources = [], operations = [], images = [], linked = /* @__PURE__ */ new Set(), outer = /* @__PURE__ */ new Set(), inner = /* @__PURE__ */ new Set(), selectedLinks = /* @__PURE__ */ new Set(), sourceCount = 0, linkedOperationCount = 0, expectedInputs = /* @__PURE__ */ new Map(), bind = (value) => {
|
|
11200
11208
|
let input = request2("CREATE_EVENT", value), digest2 = fingerprint("CREATE_EVENT", input), prior = expectedInputs.get(input.clientOperationId);
|
|
11201
11209
|
if (prior !== void 0 && prior !== digest2) return invalid7();
|
|
11202
11210
|
expectedInputs.set(input.clientOperationId, digest2);
|
|
11203
11211
|
}, add = (name, row3, links, locks, innerLocks = []) => {
|
|
11204
|
-
if (this.matchesScope(row3))
|
|
11205
|
-
|
|
11206
|
-
|
|
11207
|
-
|
|
11212
|
+
if (!this.matchesScope(row3)) return;
|
|
11213
|
+
sourceCount++, images.push([name, row3]);
|
|
11214
|
+
for (let id5 of links) linked.add(id5);
|
|
11215
|
+
if (sourceCount > MAX_INVENTORY_FILES || linked.size > MAX_INVENTORY_FILES * MAX_FILES)
|
|
11216
|
+
throw new SyncJournalError("SYNC_JOURNAL_FULL");
|
|
11217
|
+
let additionalLinks = links.filter((id5) => !selectedLinks.has(id5));
|
|
11218
|
+
if (!(sources.length >= MAX_FILES || selectedLinks.size + additionalLinks.length > MAX_FILES)) {
|
|
11219
|
+
sources.push(name);
|
|
11220
|
+
for (let id5 of links) selectedLinks.add(id5);
|
|
11208
11221
|
for (let lock of locks) outer.add(lock);
|
|
11209
11222
|
for (let lock of innerLocks) inner.add(lock);
|
|
11210
11223
|
}
|
|
@@ -11255,16 +11268,16 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11255
11268
|
let row3 = await this.read(id5, key);
|
|
11256
11269
|
if (row3) {
|
|
11257
11270
|
if (this.requireScope(row3), row3.action !== "CREATE_EVENT" || row3.state === "PENDING" && row3.input.expectedSessionKeyGen !== expectedSessionKeyGen || expectedInputs.has(id5) && expectedInputs.get(id5) !== row3.fingerprint) return invalid7();
|
|
11258
|
-
|
|
11271
|
+
linkedOperationCount++, images.push([id5 + ".json", row3]), selectedLinks.has(id5) && operations.push(id5 + ".json");
|
|
11259
11272
|
}
|
|
11260
11273
|
}
|
|
11261
|
-
if (
|
|
11274
|
+
if (linkedOperationCount > MAX_FILES) throw new SyncJournalError("SYNC_JOURNAL_FULL");
|
|
11262
11275
|
return {
|
|
11263
11276
|
sources: sources.sort(),
|
|
11264
11277
|
operations,
|
|
11265
11278
|
// Even a missing operation may retain its dead sender/GC lock after an
|
|
11266
11279
|
// interrupted unlink. The source's complete link set owns reclamation.
|
|
11267
|
-
locks: [...[...outer].sort(), ...[...inner].sort(), ...[...
|
|
11280
|
+
locks: [...[...outer].sort(), ...[...inner].sort(), ...[...selectedLinks].sort().map((id5) => `send-${id5}.lockdir`)],
|
|
11268
11281
|
digest: (0, import_node_crypto14.createHash)("sha256").update((0, import_json_freeze12.canonicalize)(images)).digest("hex")
|
|
11269
11282
|
};
|
|
11270
11283
|
}
|
|
@@ -11523,21 +11536,21 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11523
11536
|
async recordNames(suffix = ".json") {
|
|
11524
11537
|
let names = [], entries = 0, directory = await import_node_fs5.promises.opendir(this.directory);
|
|
11525
11538
|
for await (let entry5 of directory) {
|
|
11526
|
-
if (++entries >
|
|
11527
|
-
if (entry5.name.endsWith(suffix) && ((!entry5.isFile() || !UUID8.test(entry5.name.slice(0, -suffix.length))) && invalid7(), names.push(entry5.name), names.length > MAX_FILES))
|
|
11539
|
+
if (++entries > MAX_DIRECTORY_ENTRIES) throw new SyncJournalError("SYNC_JOURNAL_FULL");
|
|
11540
|
+
if (entry5.name.endsWith(suffix) && ((!entry5.isFile() || !UUID8.test(entry5.name.slice(0, -suffix.length))) && invalid7(), names.push(entry5.name), names.length > (suffix === ".json" ? MAX_FILES : MAX_INVENTORY_FILES)))
|
|
11528
11541
|
throw new SyncJournalError("SYNC_JOURNAL_FULL");
|
|
11529
11542
|
}
|
|
11530
11543
|
return names;
|
|
11531
11544
|
}
|
|
11532
11545
|
async checkCapacity(additionalBytes, replacedName, retirement = !1) {
|
|
11533
|
-
let
|
|
11546
|
+
let operations = 0, bookkeeping = 0, bytes = additionalBytes, entries = 0, retirements = 0, allocatesOperation = replacedName === void 0 || replacedName.endsWith(".json"), directory = await import_node_fs5.promises.opendir(this.directory);
|
|
11534
11547
|
for await (let entry5 of directory)
|
|
11535
|
-
if ((++entries >
|
|
11548
|
+
if ((++entries > MAX_DIRECTORY_ENTRIES || entry5.isSymbolicLink()) && invalid7(), entry5.isFile()) {
|
|
11536
11549
|
let stat13 = await import_node_fs5.promises.lstat(path18.join(this.directory, entry5.name));
|
|
11537
11550
|
if ((!stat13.isFile() || stat13.nlink !== 1) && invalid7(), entry5.name === replacedName) continue;
|
|
11538
|
-
entry5.name.endsWith(".retirement")
|
|
11551
|
+
bytes += stat13.size, entry5.name.endsWith(".json") ? operations++ : entry5.name.endsWith(".retirement") ? retirements++ : bookkeeping++;
|
|
11539
11552
|
}
|
|
11540
|
-
if (
|
|
11553
|
+
if (allocatesOperation && operations >= MAX_FILES || !allocatesOperation && !retirement && bookkeeping >= MAX_INVENTORY_FILES || bytes > MAX_STORE_BYTES + (retirement ? MAX_RETIREMENT_INTENTS * MAX_RETIREMENT_BYTES : 0) || retirement && retirements >= MAX_RETIREMENT_INTENTS) throw new SyncJournalError("SYNC_JOURNAL_FULL");
|
|
11541
11554
|
}
|
|
11542
11555
|
async ensureDirectory() {
|
|
11543
11556
|
let current = path18.parse(this.directory).root;
|
|
@@ -13138,10 +13151,10 @@ var DecisionAttemptReceiptStore = class _DecisionAttemptReceiptStore {
|
|
|
13138
13151
|
}
|
|
13139
13152
|
}
|
|
13140
13153
|
async assertNoSymlinkComponents(target2) {
|
|
13141
|
-
let
|
|
13142
|
-
if (
|
|
13154
|
+
let relative23 = path22.relative(this.rootDir, target2);
|
|
13155
|
+
if (relative23.startsWith("..") || path22.isAbsolute(relative23))
|
|
13143
13156
|
throw new Error("DecisionAttemptReceiptStore: path escaped receipt root");
|
|
13144
|
-
let components =
|
|
13157
|
+
let components = relative23 ? relative23.split(path22.sep) : [], current = this.rootDir;
|
|
13145
13158
|
for (let index = -1; index < components.length; index += 1) {
|
|
13146
13159
|
index >= 0 && (current = path22.join(current, components[index]));
|
|
13147
13160
|
try {
|
|
@@ -21231,9 +21244,9 @@ init_logger2();
|
|
|
21231
21244
|
function truncate(s, max) {
|
|
21232
21245
|
return max <= 0 ? "" : s.length <= max ? s : max === 1 ? "\u2026" : s.slice(0, max - 1) + "\u2026";
|
|
21233
21246
|
}
|
|
21234
|
-
function formatProjectPath(projectPath,
|
|
21247
|
+
function formatProjectPath(projectPath, homedir41, maxCols) {
|
|
21235
21248
|
let p = projectPath ?? "";
|
|
21236
|
-
if (
|
|
21249
|
+
if (homedir41 && (p === homedir41 || p.startsWith(homedir41 + "/")) && (p = "~" + p.slice(homedir41.length)), p.length > maxCols) {
|
|
21237
21250
|
if (maxCols <= 0) return "";
|
|
21238
21251
|
if (maxCols === 1) return "\u2026";
|
|
21239
21252
|
p = "\u2026" + p.slice(p.length - (maxCols - 1));
|
|
@@ -21250,7 +21263,7 @@ function plannerBadge(kind, label) {
|
|
|
21250
21263
|
return kind === "local_gemma_qat" ? { text: `${(label ?? "").trim() || "local model"} \xB7 local` } : kind === "local_unavailable" ? { text: `\u26A0 ${(label ?? "").trim() || "local model"} offline \u2014 NL disabled`, color: "yellow" } : kind === "hosted" ? { text: "Gemma \xB7 hosted" } : null;
|
|
21251
21264
|
}
|
|
21252
21265
|
function computeStatusLayout(args) {
|
|
21253
|
-
let { tier, homedir:
|
|
21266
|
+
let { tier, homedir: homedir41, columns, badge } = args, SEP = " \xB7 ", badgeText = badge ? truncate(badge.text, Math.max(0, columns - SEP.length - tier.length - 2)) : "", rightWidth = badgeText ? badgeText.length + 1 : 0, cwdMax = Math.max(0, columns - rightWidth - SEP.length - tier.length), cwd = formatProjectPath(args.cwd, homedir41, cwdMax), leftFull = cwd ? `${cwd}${SEP}${tier}` : tier;
|
|
21254
21267
|
return { leftText: truncate(leftFull, Math.max(0, columns - rightWidth)), badgeText };
|
|
21255
21268
|
}
|
|
21256
21269
|
|
|
@@ -21461,7 +21474,7 @@ async function clearRetiredPlannerCache(userId, cacheRoot = process.env.CODEVIBE
|
|
|
21461
21474
|
}
|
|
21462
21475
|
|
|
21463
21476
|
// src/orchestration-shell/index.ts
|
|
21464
|
-
var path78 = __toESM(require("path")),
|
|
21477
|
+
var path78 = __toESM(require("path")), os48 = __toESM(require("os")), import_promises = require("node:fs/promises"), import_node_fs37 = require("node:fs"), import_node_child_process10 = require("node:child_process"), import_node_util3 = require("node:util"), import_node_async_hooks = require("node:async_hooks");
|
|
21465
21478
|
|
|
21466
21479
|
// src/orchestration-shell/web/sanitize.ts
|
|
21467
21480
|
function sanitizeForTerminal(input) {
|
|
@@ -32818,17 +32831,17 @@ function sniffImageMime(head) {
|
|
|
32818
32831
|
return null;
|
|
32819
32832
|
}
|
|
32820
32833
|
var IMAGE_EXT_RE = /\.(png|jpe?g|gif|webp|bmp)$/i;
|
|
32821
|
-
function unescapeToken(raw,
|
|
32834
|
+
function unescapeToken(raw, homedir41) {
|
|
32822
32835
|
let s = raw.trim(), wasQuoted = !1;
|
|
32823
32836
|
if ((s.startsWith("'") && s.endsWith("'") || s.startsWith('"') && s.endsWith('"')) && (s = s.slice(1, -1), wasQuoted = !0), s.startsWith("file://"))
|
|
32824
32837
|
try {
|
|
32825
32838
|
return (0, import_node_url.fileURLToPath)(s);
|
|
32826
32839
|
} catch {
|
|
32827
32840
|
}
|
|
32828
|
-
return wasQuoted || (s = s.replace(/\\(.)/g, "$1")), expandHome(s,
|
|
32841
|
+
return wasQuoted || (s = s.replace(/\\(.)/g, "$1")), expandHome(s, homedir41);
|
|
32829
32842
|
}
|
|
32830
|
-
function expandHome(p,
|
|
32831
|
-
return p === "~" ?
|
|
32843
|
+
function expandHome(p, homedir41) {
|
|
32844
|
+
return p === "~" ? homedir41 : p.startsWith("~/") ? path33.join(homedir41, p.slice(2)) : p;
|
|
32832
32845
|
}
|
|
32833
32846
|
function extractImagePathSpans(text2) {
|
|
32834
32847
|
let spans = [], quoted = /'[^']*\.(?:png|jpe?g|gif|webp|bmp)'|"[^"]*\.(?:png|jpe?g|gif|webp|bmp)"/gi, m, masked = text2.split("");
|
|
@@ -34583,7 +34596,7 @@ function collapsedReducedTrustLine(actor) {
|
|
|
34583
34596
|
}
|
|
34584
34597
|
|
|
34585
34598
|
// src/orchestration-shell/quorum-loop.ts
|
|
34586
|
-
var path71 = __toESM(require("node:path")),
|
|
34599
|
+
var path71 = __toESM(require("node:path")), os43 = __toESM(require("node:os")), nodeCrypto = __toESM(require("node:crypto")), import_uuid12 = require("uuid"), import_ulid4 = require("ulid");
|
|
34587
34600
|
|
|
34588
34601
|
// src/audit-keys/index.ts
|
|
34589
34602
|
var import_node_crypto26 = require("node:crypto");
|
|
@@ -36477,6 +36490,255 @@ function enforceNetwork(scope) {
|
|
|
36477
36490
|
function redactSensitiveTokens(cmd) {
|
|
36478
36491
|
return cmd.replace(/--token\s+[0-9a-fA-F]+/g, "--token [REDACTED]").replace(/mcp_servers\.codevibe_web\.args=\S+/g, "mcp_servers.codevibe_web.args=[REDACTED]");
|
|
36479
36492
|
}
|
|
36493
|
+
function normalizeArgv(argv) {
|
|
36494
|
+
if (!Array.isArray(argv)) return [];
|
|
36495
|
+
let normalized = [];
|
|
36496
|
+
for (let token4 of argv)
|
|
36497
|
+
if (typeof token4 == "string")
|
|
36498
|
+
if (token4.startsWith("--") && token4.includes("=")) {
|
|
36499
|
+
let eqIdx = token4.indexOf("="), rawKey = token4.slice(0, eqIdx), val = token4.slice(eqIdx + 1), key = normalizeFlagName(rawKey);
|
|
36500
|
+
normalized.push(key, val);
|
|
36501
|
+
} else if (token4.startsWith("--"))
|
|
36502
|
+
normalized.push(normalizeFlagName(token4));
|
|
36503
|
+
else if (token4.startsWith("-s") && token4.length > 2) {
|
|
36504
|
+
let val = token4[2] === "=" ? token4.slice(3) : token4.slice(2);
|
|
36505
|
+
normalized.push("--sandbox", val);
|
|
36506
|
+
} else if (token4 === "-s")
|
|
36507
|
+
normalized.push("--sandbox");
|
|
36508
|
+
else if (token4.startsWith("-c") && token4.length > 2 && !token4.startsWith("--")) {
|
|
36509
|
+
let val = token4[2] === "=" ? token4.slice(3) : token4.slice(2);
|
|
36510
|
+
normalized.push("-c", val);
|
|
36511
|
+
} else
|
|
36512
|
+
normalized.push(token4);
|
|
36513
|
+
return normalized;
|
|
36514
|
+
}
|
|
36515
|
+
function normalizeFlagName(flag) {
|
|
36516
|
+
return flag.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
36517
|
+
}
|
|
36518
|
+
function parseToolRuleM8(rule) {
|
|
36519
|
+
let trimmed = rule.trim();
|
|
36520
|
+
if (trimmed.length === 0) return null;
|
|
36521
|
+
let firstParen = trimmed.indexOf("("), lastParen = trimmed.lastIndexOf(")");
|
|
36522
|
+
if (firstParen === -1 && lastParen === -1)
|
|
36523
|
+
return /^[A-Za-z0-9_]+$/.test(trimmed) ? { toolName: trimmed } : null;
|
|
36524
|
+
if (firstParen === -1 || lastParen <= firstParen || lastParen !== trimmed.length - 1)
|
|
36525
|
+
return null;
|
|
36526
|
+
let toolName = trimmed.substring(0, firstParen);
|
|
36527
|
+
if (!/^[A-Za-z0-9_]+$/.test(toolName)) return null;
|
|
36528
|
+
let rawContent = trimmed.substring(firstParen + 1, lastParen);
|
|
36529
|
+
return { toolName, rawContent };
|
|
36530
|
+
}
|
|
36531
|
+
function vendorBu(e) {
|
|
36532
|
+
let n = [];
|
|
36533
|
+
for (let t of e) {
|
|
36534
|
+
if (!t) continue;
|
|
36535
|
+
let r = "", o = !1;
|
|
36536
|
+
for (let s of t)
|
|
36537
|
+
switch (s) {
|
|
36538
|
+
case "(":
|
|
36539
|
+
o = !0, r += s;
|
|
36540
|
+
break;
|
|
36541
|
+
case ")":
|
|
36542
|
+
o = !1, r += s;
|
|
36543
|
+
break;
|
|
36544
|
+
case ",":
|
|
36545
|
+
o ? r += s : (r.trim() && n.push(r.trim()), r = "");
|
|
36546
|
+
break;
|
|
36547
|
+
case " ":
|
|
36548
|
+
o ? r += s : r.trim() && (n.push(r.trim()), r = "");
|
|
36549
|
+
break;
|
|
36550
|
+
default:
|
|
36551
|
+
(r || s.trim()) && (r += s);
|
|
36552
|
+
}
|
|
36553
|
+
r.trim() && n.push(r.trim());
|
|
36554
|
+
}
|
|
36555
|
+
return n;
|
|
36556
|
+
}
|
|
36557
|
+
function parseAllowedToolsRules(value) {
|
|
36558
|
+
let arr = Array.isArray(value) ? value : [value], rules = vendorBu(arr);
|
|
36559
|
+
return rules.length > 0 ? rules : null;
|
|
36560
|
+
}
|
|
36561
|
+
var ADVISORY_FORBIDDEN_TOOLS = /* @__PURE__ */ new Set([
|
|
36562
|
+
"Write",
|
|
36563
|
+
"Edit",
|
|
36564
|
+
"Bash",
|
|
36565
|
+
"NotebookEditCell",
|
|
36566
|
+
"KillShell"
|
|
36567
|
+
]), ADVISORY_PERMITTED_TOOLS = /* @__PURE__ */ new Set(["Read", "Grep", "Glob"]);
|
|
36568
|
+
function isStrictReadOnlyAdvisoryClaude(argv) {
|
|
36569
|
+
if (!Array.isArray(argv) || argv.length === 0) return !1;
|
|
36570
|
+
let norm = normalizeArgv(argv);
|
|
36571
|
+
if (norm.length === 0) return !1;
|
|
36572
|
+
let baseExe = path38.basename(norm[0] || "");
|
|
36573
|
+
if (baseExe !== "claude" && baseExe !== "claude.exe" || norm.some(
|
|
36574
|
+
(arg) => arg.startsWith("--dangerously") || arg.startsWith("--allow-dangerously") || arg === "--yolo" || arg === "--full-auto" || arg === "--approve-for-me" || arg === "--permission-mode" || arg.startsWith("--permission-mode=") || arg === "--plugin-dir" || arg.startsWith("--plugin-dir=") || arg === "--plugin-dir-no-mcp" || arg.startsWith("--plugin-dir-no-mcp=") || arg === "--plugin-url" || arg.startsWith("--plugin-url=") || arg === "--plugin" || arg.startsWith("--plugin=") || arg === "--plugins" || arg.startsWith("--plugins=") || arg === "--system-prompt" || arg.startsWith("--system-prompt=") || arg === "--append-system-prompt" || arg.startsWith("--append-system-prompt=") || arg === "--exec" || arg.startsWith("--exec=")
|
|
36575
|
+
) || norm.includes("--mcp-config") || norm.filter((a) => a === "--strict-mcp-config").length !== 1)
|
|
36576
|
+
return !1;
|
|
36577
|
+
let settingSourcesIndices = [];
|
|
36578
|
+
for (let i = 0; i < norm.length; i++)
|
|
36579
|
+
norm[i] === "--setting-sources" && settingSourcesIndices.push(i);
|
|
36580
|
+
if (settingSourcesIndices.length !== 1)
|
|
36581
|
+
return !1;
|
|
36582
|
+
let ssIdx = settingSourcesIndices[0];
|
|
36583
|
+
if (norm[ssIdx + 1] !== "user" || norm.filter((a) => a === "--tools").length !== 1 || norm.filter((a) => a === "--allowed-tools").length !== 1 || norm.filter((a) => a === "--settings").length !== 1) return !1;
|
|
36584
|
+
let settingsIdx = norm.indexOf("--settings"), settingsRaw = norm[settingsIdx + 1];
|
|
36585
|
+
if (!settingsRaw || !settingsRaw.startsWith("{")) return !1;
|
|
36586
|
+
let settingsObj;
|
|
36587
|
+
try {
|
|
36588
|
+
settingsObj = JSON.parse(settingsRaw);
|
|
36589
|
+
} catch {
|
|
36590
|
+
return !1;
|
|
36591
|
+
}
|
|
36592
|
+
if (!settingsObj || typeof settingsObj != "object" || Array.isArray(settingsObj))
|
|
36593
|
+
return !1;
|
|
36594
|
+
let topKeys = Object.keys(settingsObj);
|
|
36595
|
+
if (topKeys.length !== 1 || topKeys[0] !== "permissions")
|
|
36596
|
+
return !1;
|
|
36597
|
+
let permissionsObj = settingsObj.permissions;
|
|
36598
|
+
if (!permissionsObj || typeof permissionsObj != "object" || Array.isArray(permissionsObj))
|
|
36599
|
+
return !1;
|
|
36600
|
+
for (let pk of Object.keys(permissionsObj))
|
|
36601
|
+
if (pk !== "defaultMode" && pk !== "allow")
|
|
36602
|
+
return !1;
|
|
36603
|
+
if (permissionsObj.defaultMode !== "dontAsk" || !Array.isArray(permissionsObj.allow))
|
|
36604
|
+
return !1;
|
|
36605
|
+
let toolsIdx = norm.indexOf("--tools"), toolTokens = [];
|
|
36606
|
+
for (let i = toolsIdx + 1; i < norm.length && !norm[i].startsWith("-"); i++)
|
|
36607
|
+
toolTokens.push(norm[i]);
|
|
36608
|
+
if (toolTokens.length === 0) return !1;
|
|
36609
|
+
let firstTool = toolTokens[0], allowedToolsIdx = norm.indexOf("--allowed-tools");
|
|
36610
|
+
if (allowedToolsIdx === -1) return !1;
|
|
36611
|
+
let allowedToolsTokens = [];
|
|
36612
|
+
for (let i = allowedToolsIdx + 1; i < norm.length && !norm[i].startsWith("-"); i++)
|
|
36613
|
+
allowedToolsTokens.push(norm[i]);
|
|
36614
|
+
if (firstTool === "")
|
|
36615
|
+
return !(toolTokens.length !== 1 || allowedToolsTokens.length !== 1 || allowedToolsTokens[0] !== "" || permissionsObj.allow.length !== 0);
|
|
36616
|
+
let allToolNames = toolTokens.flatMap((t) => t.split(/[\s,]+/)).map((t) => t.trim()).filter(Boolean);
|
|
36617
|
+
if (allToolNames.length === 0) return !1;
|
|
36618
|
+
for (let t of allToolNames)
|
|
36619
|
+
if (!ADVISORY_PERMITTED_TOOLS.has(t) || ADVISORY_FORBIDDEN_TOOLS.has(t)) return !1;
|
|
36620
|
+
if (allowedToolsTokens.length === 0) return !1;
|
|
36621
|
+
let parsedAllowedRules = parseAllowedToolsRules(allowedToolsTokens);
|
|
36622
|
+
if (!parsedAllowedRules || parsedAllowedRules.length === 0) return !1;
|
|
36623
|
+
for (let rule of parsedAllowedRules) {
|
|
36624
|
+
let parsed = parseToolRuleM8(rule);
|
|
36625
|
+
if (!parsed || !ADVISORY_PERMITTED_TOOLS.has(parsed.toolName) || ADVISORY_FORBIDDEN_TOOLS.has(parsed.toolName) || parsed.rawContent === void 0) return !1;
|
|
36626
|
+
let p = parsed.rawContent;
|
|
36627
|
+
if (p === "/*" || p === "*" || !p.startsWith("//") || p === "//" || p === "//*" || p === "//**" || /[\r\n\0]/.test(p)) return !1;
|
|
36628
|
+
}
|
|
36629
|
+
if (permissionsObj.allow.length === 0) return !1;
|
|
36630
|
+
for (let rule of permissionsObj.allow) {
|
|
36631
|
+
if (typeof rule != "string") return !1;
|
|
36632
|
+
let parsed = parseToolRuleM8(rule);
|
|
36633
|
+
if (!parsed || !ADVISORY_PERMITTED_TOOLS.has(parsed.toolName) || ADVISORY_FORBIDDEN_TOOLS.has(parsed.toolName) || parsed.rawContent === void 0) return !1;
|
|
36634
|
+
let p = parsed.rawContent;
|
|
36635
|
+
if (p === "/*" || p === "*" || !p.startsWith("//") || p === "//" || p === "//*" || p === "//**" || /[\r\n\0]/.test(p)) return !1;
|
|
36636
|
+
}
|
|
36637
|
+
return !0;
|
|
36638
|
+
}
|
|
36639
|
+
var CODEX_LONG_OPTIONS_WITH_VALUE = /* @__PURE__ */ new Set([
|
|
36640
|
+
"config",
|
|
36641
|
+
"enable",
|
|
36642
|
+
"disable",
|
|
36643
|
+
"image",
|
|
36644
|
+
"model",
|
|
36645
|
+
"local-provider",
|
|
36646
|
+
"profile",
|
|
36647
|
+
"sandbox",
|
|
36648
|
+
"cd",
|
|
36649
|
+
"add-dir",
|
|
36650
|
+
"thread-source",
|
|
36651
|
+
"cyber-access-program",
|
|
36652
|
+
"output-schema",
|
|
36653
|
+
"color",
|
|
36654
|
+
"output-last-message"
|
|
36655
|
+
]), CODEX_SHORT_OPTIONS_WITH_VALUE = /* @__PURE__ */ new Set([
|
|
36656
|
+
"c",
|
|
36657
|
+
"i",
|
|
36658
|
+
"m",
|
|
36659
|
+
"p",
|
|
36660
|
+
"s",
|
|
36661
|
+
"C",
|
|
36662
|
+
"o"
|
|
36663
|
+
]);
|
|
36664
|
+
function extractConfigKey(cfg) {
|
|
36665
|
+
let s = (cfg || "").trim();
|
|
36666
|
+
s = s.replace(/^['"]|['"]$/g, "").trim(), s = s.replace(/^=+/, "").trim(), s = s.replace(/^['"]|['"]$/g, "").trim();
|
|
36667
|
+
let eqIdx = s.indexOf("=");
|
|
36668
|
+
return (eqIdx !== -1 ? s.slice(0, eqIdx) : s).replace(/^['"]|['"]$/g, "").trim().toLowerCase();
|
|
36669
|
+
}
|
|
36670
|
+
function isProtectedCodexConfigKey(key) {
|
|
36671
|
+
return key.startsWith("sandbox") || key.includes("sandbox") || key.startsWith("permissions") || key.includes("permission") || key.startsWith("shell_environment_policy") || key.includes("shell_environment") || key.startsWith("approval_policy") || key.includes("approval");
|
|
36672
|
+
}
|
|
36673
|
+
function isStrictReadOnlyAdvisoryCodex(argv) {
|
|
36674
|
+
if (!Array.isArray(argv) || argv.length === 0) return !1;
|
|
36675
|
+
let baseExe = path38.basename(argv[0] || "");
|
|
36676
|
+
if (baseExe !== "codex" && baseExe !== "codex.exe" || argv.some(
|
|
36677
|
+
(arg) => typeof arg == "string" && (arg.includes("workspace-write") || arg.includes("danger-full-access"))
|
|
36678
|
+
))
|
|
36679
|
+
return !1;
|
|
36680
|
+
let delimiterFound = !1, waitingForOption = null, structuredOptions = [], positionalBeforeDelimiter = [], positionalAfterDelimiter = [];
|
|
36681
|
+
for (let i = 1; i < argv.length; i++) {
|
|
36682
|
+
let rawToken = argv[i];
|
|
36683
|
+
if (typeof rawToken == "string") {
|
|
36684
|
+
if (delimiterFound) {
|
|
36685
|
+
positionalAfterDelimiter.push(rawToken);
|
|
36686
|
+
continue;
|
|
36687
|
+
}
|
|
36688
|
+
if (waitingForOption !== null) {
|
|
36689
|
+
waitingForOption.value = rawToken, waitingForOption = null;
|
|
36690
|
+
continue;
|
|
36691
|
+
}
|
|
36692
|
+
if (rawToken === "--") {
|
|
36693
|
+
delimiterFound = !0;
|
|
36694
|
+
continue;
|
|
36695
|
+
}
|
|
36696
|
+
if (rawToken.startsWith("--"))
|
|
36697
|
+
if (rawToken.includes("=")) {
|
|
36698
|
+
let eqIdx = rawToken.indexOf("="), flagName = normalizeFlagName(rawToken.slice(0, eqIdx)), flagVal = rawToken.slice(eqIdx + 1);
|
|
36699
|
+
structuredOptions.push({ name: flagName, value: flagVal });
|
|
36700
|
+
} else {
|
|
36701
|
+
let flagName = normalizeFlagName(rawToken), bareName = flagName.slice(2), optObj = { name: flagName };
|
|
36702
|
+
structuredOptions.push(optObj), CODEX_LONG_OPTIONS_WITH_VALUE.has(bareName) && (waitingForOption = optObj);
|
|
36703
|
+
}
|
|
36704
|
+
else if (rawToken.startsWith("-") && rawToken.length > 1) {
|
|
36705
|
+
let optChar = rawToken[1];
|
|
36706
|
+
if (CODEX_SHORT_OPTIONS_WITH_VALUE.has(optChar)) {
|
|
36707
|
+
let normOpt = optChar === "s" ? "--sandbox" : optChar === "c" ? "-c" : optChar === "C" ? "-C" : optChar === "m" ? "-m" : optChar === "o" ? "-o" : optChar === "i" ? "-i" : optChar === "p" ? "-p" : `-${optChar}`;
|
|
36708
|
+
if (rawToken.length > 2) {
|
|
36709
|
+
let val = rawToken[2] === "=" ? rawToken.slice(3) : rawToken.slice(2);
|
|
36710
|
+
structuredOptions.push({ name: normOpt, value: val });
|
|
36711
|
+
} else {
|
|
36712
|
+
let optObj = { name: normOpt };
|
|
36713
|
+
structuredOptions.push(optObj), waitingForOption = optObj;
|
|
36714
|
+
}
|
|
36715
|
+
} else
|
|
36716
|
+
structuredOptions.push({ name: rawToken });
|
|
36717
|
+
} else
|
|
36718
|
+
positionalBeforeDelimiter.push(rawToken);
|
|
36719
|
+
}
|
|
36720
|
+
}
|
|
36721
|
+
let isBypassFlag = (s) => s.startsWith("--dangerously") || s === "--yolo" || s === "--full-auto" || s === "--approve-for-me" || s === "--add-dir" || s === "-a" || s === "--ask-for-approval";
|
|
36722
|
+
if (structuredOptions.some((opt) => isBypassFlag(opt.name)) || positionalBeforeDelimiter.some(isBypassFlag) || positionalAfterDelimiter.some(isBypassFlag) || positionalBeforeDelimiter.length > 0 && positionalBeforeDelimiter[0] !== "exec")
|
|
36723
|
+
return !1;
|
|
36724
|
+
for (let opt of structuredOptions) {
|
|
36725
|
+
if (opt.name === "-c" || opt.name === "--config") {
|
|
36726
|
+
let cfgVal = opt.value || "", cfgKey = extractConfigKey(cfgVal);
|
|
36727
|
+
if (isProtectedCodexConfigKey(cfgKey))
|
|
36728
|
+
return !1;
|
|
36729
|
+
}
|
|
36730
|
+
if (opt.name === "--enable" || opt.name === "--disable") {
|
|
36731
|
+
let featVal = (opt.value || "").toLowerCase();
|
|
36732
|
+
if (isProtectedCodexConfigKey(featVal))
|
|
36733
|
+
return !1;
|
|
36734
|
+
}
|
|
36735
|
+
}
|
|
36736
|
+
let sandboxOptions = structuredOptions.filter((opt) => opt.name === "--sandbox");
|
|
36737
|
+
if (sandboxOptions.length === 0) return !1;
|
|
36738
|
+
for (let sOpt of sandboxOptions)
|
|
36739
|
+
if (sOpt.value !== "read-only") return !1;
|
|
36740
|
+
return !0;
|
|
36741
|
+
}
|
|
36480
36742
|
function enforceCommand(scope, argv) {
|
|
36481
36743
|
for (let entry5 of scope.commandAllowlist) {
|
|
36482
36744
|
let isTemplate = entry5.endsWith(" *"), containsSpace = entry5.includes(" ");
|
|
@@ -36505,6 +36767,96 @@ function enforceCommand(scope, argv) {
|
|
|
36505
36767
|
let expectedSessionsDir = path38.join(os25.homedir(), ".codevibe", "sessions");
|
|
36506
36768
|
return !!path38.resolve(remainder).startsWith(expectedSessionsDir + path38.sep);
|
|
36507
36769
|
}
|
|
36770
|
+
if (entry5.includes("--allowed-tools *")) {
|
|
36771
|
+
if (argv.includes("--mcp-config") || !argv.includes("--strict-mcp-config") || argv.includes("--dangerously-skip-permissions"))
|
|
36772
|
+
return !1;
|
|
36773
|
+
let allowedToolsIndex = argv.indexOf("--allowed-tools");
|
|
36774
|
+
if (allowedToolsIndex === -1 || allowedToolsIndex + 1 >= argv.length)
|
|
36775
|
+
return !1;
|
|
36776
|
+
let allowedToolsTokens = [];
|
|
36777
|
+
for (let i2 = allowedToolsIndex + 1; i2 < argv.length && !argv[i2].startsWith("-"); i2++)
|
|
36778
|
+
allowedToolsTokens.push(argv[i2]);
|
|
36779
|
+
if (allowedToolsTokens.length === 0) return !1;
|
|
36780
|
+
let parsedRules = parseAllowedToolsRules(allowedToolsTokens);
|
|
36781
|
+
if (!parsedRules || parsedRules.length === 0)
|
|
36782
|
+
return !1;
|
|
36783
|
+
let parsedRuleSet = /* @__PURE__ */ new Set();
|
|
36784
|
+
for (let rule of parsedRules) {
|
|
36785
|
+
let parsed = parseToolRuleM8(rule);
|
|
36786
|
+
if (!parsed || !ADVISORY_PERMITTED_TOOLS.has(parsed.toolName) || ADVISORY_FORBIDDEN_TOOLS.has(parsed.toolName) || parsed.rawContent === void 0)
|
|
36787
|
+
return !1;
|
|
36788
|
+
let pattern = parsed.rawContent;
|
|
36789
|
+
if (pattern === "/*" || pattern === "*" || !pattern.startsWith("//") || pattern === "//" || pattern === "//*" || pattern === "//**" || /[\r\n\0]/.test(pattern))
|
|
36790
|
+
return !1;
|
|
36791
|
+
parsedRuleSet.add(rule);
|
|
36792
|
+
}
|
|
36793
|
+
let settingsTokenIdx = remainderTokens.indexOf("--settings");
|
|
36794
|
+
if (settingsTokenIdx !== -1 && settingsTokenIdx + 1 < remainderTokens.length)
|
|
36795
|
+
try {
|
|
36796
|
+
let s = JSON.parse(remainderTokens[settingsTokenIdx + 1]);
|
|
36797
|
+
if (Array.isArray(s?.permissions?.allow))
|
|
36798
|
+
for (let rule of s.permissions.allow) {
|
|
36799
|
+
if (typeof rule != "string") return !1;
|
|
36800
|
+
let parsed = parseToolRuleM8(rule);
|
|
36801
|
+
if (!parsed || !ADVISORY_PERMITTED_TOOLS.has(parsed.toolName) || ADVISORY_FORBIDDEN_TOOLS.has(parsed.toolName) || parsed.rawContent === void 0) return !1;
|
|
36802
|
+
let pattern = parsed.rawContent;
|
|
36803
|
+
if (pattern === "/*" || pattern === "*" || !pattern.startsWith("//") || pattern === "//" || pattern === "//*" || pattern === "//**" || /[\r\n\0]/.test(pattern)) return !1;
|
|
36804
|
+
}
|
|
36805
|
+
} catch {
|
|
36806
|
+
return !1;
|
|
36807
|
+
}
|
|
36808
|
+
let seenStrictMcp = !1, seenSettings = !1, seenSettingSources = !1, i = 1;
|
|
36809
|
+
for (; i < remainderTokens.length; ) {
|
|
36810
|
+
let token4 = remainderTokens[i];
|
|
36811
|
+
if (token4 === "--strict-mcp-config") {
|
|
36812
|
+
if (seenStrictMcp) return !1;
|
|
36813
|
+
seenStrictMcp = !0, i += 1;
|
|
36814
|
+
} else if (token4 === "--setting-sources") {
|
|
36815
|
+
if (seenSettingSources || i + 1 >= remainderTokens.length || remainderTokens[i + 1] !== "user") return !1;
|
|
36816
|
+
seenSettingSources = !0, i += 2;
|
|
36817
|
+
} else if (token4 === "--settings") {
|
|
36818
|
+
if (seenSettings || i + 1 >= remainderTokens.length) return !1;
|
|
36819
|
+
let settingsRaw = remainderTokens[i + 1];
|
|
36820
|
+
if (!settingsRaw.startsWith("{"))
|
|
36821
|
+
return !1;
|
|
36822
|
+
let settingsObj;
|
|
36823
|
+
try {
|
|
36824
|
+
settingsObj = JSON.parse(settingsRaw);
|
|
36825
|
+
} catch {
|
|
36826
|
+
return !1;
|
|
36827
|
+
}
|
|
36828
|
+
if (!settingsObj || typeof settingsObj != "object" || Array.isArray(settingsObj))
|
|
36829
|
+
return !1;
|
|
36830
|
+
let topKeys = Object.keys(settingsObj);
|
|
36831
|
+
if (topKeys.length !== 1 || topKeys[0] !== "permissions")
|
|
36832
|
+
return !1;
|
|
36833
|
+
let permissionsObj = settingsObj.permissions;
|
|
36834
|
+
if (!permissionsObj || typeof permissionsObj != "object" || Array.isArray(permissionsObj))
|
|
36835
|
+
return !1;
|
|
36836
|
+
let permKeys = Object.keys(permissionsObj);
|
|
36837
|
+
for (let pk of permKeys)
|
|
36838
|
+
if (pk !== "defaultMode" && pk !== "allow")
|
|
36839
|
+
return !1;
|
|
36840
|
+
if (permissionsObj.defaultMode !== "dontAsk" || !Array.isArray(permissionsObj.allow))
|
|
36841
|
+
return !1;
|
|
36842
|
+
let allowList = permissionsObj.allow;
|
|
36843
|
+
if (allowList.length !== parsedRuleSet.size)
|
|
36844
|
+
return !1;
|
|
36845
|
+
for (let r of allowList)
|
|
36846
|
+
if (typeof r != "string" || !parsedRuleSet.has(r))
|
|
36847
|
+
return !1;
|
|
36848
|
+
seenSettings = !0, i += 2;
|
|
36849
|
+
} else if (token4 === "--add-dir") {
|
|
36850
|
+
if (i + 1 >= remainderTokens.length) return !1;
|
|
36851
|
+
let addDirVal = remainderTokens[i + 1];
|
|
36852
|
+
if (typeof addDirVal != "string" || addDirVal.length === 0 || addDirVal.startsWith("-"))
|
|
36853
|
+
return !1;
|
|
36854
|
+
i += 2;
|
|
36855
|
+
} else
|
|
36856
|
+
return !1;
|
|
36857
|
+
}
|
|
36858
|
+
return !(!seenStrictMcp || !seenSettings || !seenSettingSources);
|
|
36859
|
+
}
|
|
36508
36860
|
if (entry5.includes('mcp_servers.codevibe_web.command="node" *')) {
|
|
36509
36861
|
if (remainderTokens.length !== 5 || remainderTokens[0] !== "-c" || !remainderTokens[1]?.startsWith("mcp_servers.codevibe_web.args=") || remainderTokens[2] !== "--output-last-message" || !remainderTokens[3] || remainderTokens[3].startsWith("-") || remainderTokens[4] !== "-")
|
|
36510
36862
|
return !1;
|
|
@@ -37069,8 +37421,8 @@ async function readDirectoryBounded(dirPath, budget, label, relativePrefix = "",
|
|
|
37069
37421
|
}
|
|
37070
37422
|
if (value.type !== "entry" || typeof value.name != "string" || value.name.length === 0 || value.name === "." || value.name === ".." || value.name.includes("/") || value.name.includes("\\") || value.name.includes("\0") || !Number.isSafeInteger(value.kind))
|
|
37071
37423
|
throw new Error(`${label} helper returned an invalid entry`);
|
|
37072
|
-
let
|
|
37073
|
-
consumeMetadataPath(budget,
|
|
37424
|
+
let relative23 = relativePrefix ? path39.join(relativePrefix, value.name) : value.name;
|
|
37425
|
+
consumeMetadataPath(budget, relative23, label);
|
|
37074
37426
|
let stat13;
|
|
37075
37427
|
if (opts.includeStats === !0) {
|
|
37076
37428
|
let raw = value.stat;
|
|
@@ -38680,6 +39032,86 @@ function buildClaudeNoToolsPlanArgv() {
|
|
|
38680
39032
|
capture: { kind: "stdout" }
|
|
38681
39033
|
};
|
|
38682
39034
|
}
|
|
39035
|
+
function escapeClaudePathGlob(p) {
|
|
39036
|
+
return (process.platform === "win32" ? p.replace(/\\/g, "/") : p).replace(/\[/g, "\\[").replace(/\]/g, "\\]").replace(/\*/g, "\\*").replace(/\?/g, "\\?");
|
|
39037
|
+
}
|
|
39038
|
+
function formatClaudePermissionPath(p) {
|
|
39039
|
+
return p.startsWith("//") ? p : p.startsWith("/") ? "/" + p : p;
|
|
39040
|
+
}
|
|
39041
|
+
function buildClaudeReadOnlyAdvisoryPlanArgv(workdir, attachments) {
|
|
39042
|
+
let rulesList = [], argv = ["claude", "--print", "--output-format", "json"], addDirs = [];
|
|
39043
|
+
if (workdir) {
|
|
39044
|
+
let resolvedWorkdir = import_node_path.default.resolve(workdir);
|
|
39045
|
+
addDirs.push(resolvedWorkdir);
|
|
39046
|
+
let realWorkdir = null;
|
|
39047
|
+
try {
|
|
39048
|
+
realWorkdir = (0, import_node_fs19.realpathSync)(resolvedWorkdir);
|
|
39049
|
+
} catch {
|
|
39050
|
+
}
|
|
39051
|
+
let targetPatterns = /* @__PURE__ */ new Set(), escapedWorkdir = escapeClaudePathGlob(resolvedWorkdir);
|
|
39052
|
+
if (targetPatterns.add(formatClaudePermissionPath(`${escapedWorkdir}/**`)), realWorkdir && realWorkdir !== resolvedWorkdir) {
|
|
39053
|
+
let escapedRealWorkdir = escapeClaudePathGlob(realWorkdir);
|
|
39054
|
+
targetPatterns.add(formatClaudePermissionPath(`${escapedRealWorkdir}/**`));
|
|
39055
|
+
}
|
|
39056
|
+
if (attachments && attachments.length > 0)
|
|
39057
|
+
for (let att of attachments) {
|
|
39058
|
+
let resolvedAtt = import_node_path.default.resolve(att), stat13 = null;
|
|
39059
|
+
try {
|
|
39060
|
+
stat13 = (0, import_node_fs19.statSync)(resolvedAtt);
|
|
39061
|
+
} catch {
|
|
39062
|
+
}
|
|
39063
|
+
let isDir = !!stat13?.isDirectory(), escapedAtt = escapeClaudePathGlob(resolvedAtt);
|
|
39064
|
+
isDir ? (targetPatterns.add(formatClaudePermissionPath(`${escapedAtt}/**`)), addDirs.push(resolvedAtt)) : targetPatterns.add(formatClaudePermissionPath(escapedAtt));
|
|
39065
|
+
try {
|
|
39066
|
+
let realAtt = (0, import_node_fs19.realpathSync)(resolvedAtt);
|
|
39067
|
+
if (realAtt !== resolvedAtt) {
|
|
39068
|
+
let escapedRealAtt = escapeClaudePathGlob(realAtt);
|
|
39069
|
+
isDir ? targetPatterns.add(formatClaudePermissionPath(`${escapedRealAtt}/**`)) : targetPatterns.add(formatClaudePermissionPath(escapedRealAtt));
|
|
39070
|
+
}
|
|
39071
|
+
} catch {
|
|
39072
|
+
}
|
|
39073
|
+
}
|
|
39074
|
+
let readRules = Array.from(targetPatterns).map((p) => `Read(${p})`), grepRules = Array.from(targetPatterns).map((p) => `Grep(${p})`), globRules = Array.from(targetPatterns).map((p) => `Glob(${p})`);
|
|
39075
|
+
rulesList.push(...readRules, ...grepRules, ...globRules);
|
|
39076
|
+
}
|
|
39077
|
+
let hasRules = rulesList.length > 0, toolsValue = hasRules ? "Read,Grep,Glob" : "", allowedToolsValue = hasRules ? rulesList.join(",") : "";
|
|
39078
|
+
if (hasRules) {
|
|
39079
|
+
let parsedVendor = vendorBu([allowedToolsValue]);
|
|
39080
|
+
if (parsedVendor.length !== rulesList.length)
|
|
39081
|
+
throw new Error(
|
|
39082
|
+
`Ambiguous Claude allowed-tools path serialization: vendor tokenizer split ${rulesList.length} rules into ${parsedVendor.length} tokens for path: ${workdir}`
|
|
39083
|
+
);
|
|
39084
|
+
for (let token4 of parsedVendor) {
|
|
39085
|
+
let parsed = parseToolRuleM8(token4);
|
|
39086
|
+
if (!parsed || parsed.rawContent === void 0)
|
|
39087
|
+
throw new Error(
|
|
39088
|
+
`Ambiguous Claude allowed-tools path serialization: vendor tokenizer produced bare tool rule '${token4}' for path: ${workdir}`
|
|
39089
|
+
);
|
|
39090
|
+
}
|
|
39091
|
+
}
|
|
39092
|
+
argv.push(
|
|
39093
|
+
"--tools",
|
|
39094
|
+
toolsValue,
|
|
39095
|
+
"--allowed-tools",
|
|
39096
|
+
allowedToolsValue,
|
|
39097
|
+
"--settings",
|
|
39098
|
+
JSON.stringify({
|
|
39099
|
+
permissions: {
|
|
39100
|
+
defaultMode: "dontAsk",
|
|
39101
|
+
allow: rulesList
|
|
39102
|
+
}
|
|
39103
|
+
}),
|
|
39104
|
+
"--setting-sources",
|
|
39105
|
+
"user",
|
|
39106
|
+
"--strict-mcp-config"
|
|
39107
|
+
);
|
|
39108
|
+
for (let d of addDirs)
|
|
39109
|
+
argv.push("--add-dir", d);
|
|
39110
|
+
return {
|
|
39111
|
+
argv,
|
|
39112
|
+
capture: { kind: "stdout" }
|
|
39113
|
+
};
|
|
39114
|
+
}
|
|
38683
39115
|
var AGY_MODEL_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.:/-]*$/;
|
|
38684
39116
|
function resolveAgyModel(env = process.env) {
|
|
38685
39117
|
let raw = env.CODEVIBE_AGY_MODEL;
|
|
@@ -38692,15 +39124,8 @@ function resolveAgyModel(env = process.env) {
|
|
|
38692
39124
|
}
|
|
38693
39125
|
var AGY_IMPLEMENTOR_PRINT_TIMEOUT = "3600s";
|
|
38694
39126
|
function agyImplementorArgvPrefix(mode) {
|
|
38695
|
-
let model = resolveAgyModel();
|
|
38696
|
-
return
|
|
38697
|
-
"agy",
|
|
38698
|
-
...mode === "plan" ? ["--sandbox"] : ["--dangerously-skip-permissions"],
|
|
38699
|
-
...model !== null ? ["--model", model] : [],
|
|
38700
|
-
"--print-timeout",
|
|
38701
|
-
AGY_IMPLEMENTOR_PRINT_TIMEOUT,
|
|
38702
|
-
"--add-dir"
|
|
38703
|
-
];
|
|
39127
|
+
let model = resolveAgyModel(), argv = ["agy"];
|
|
39128
|
+
return mode === "plan" ? argv.push("--mode", "plan", "--sandbox") : argv.push("--dangerously-skip-permissions"), model !== null && argv.push("--model", model), argv.push("--print-timeout", AGY_IMPLEMENTOR_PRINT_TIMEOUT, "--add-dir"), argv;
|
|
38704
39129
|
}
|
|
38705
39130
|
function agyImplementorAllowlistEntries() {
|
|
38706
39131
|
return [
|
|
@@ -38948,6 +39373,8 @@ var IMPLEMENTOR_COMMAND_ALLOWLIST = [
|
|
|
38948
39373
|
// is part of the fixed argv → mirrored here or the drift test fails.
|
|
38949
39374
|
"claude --print --output-format json --allowed-tools Read,Grep,Glob",
|
|
38950
39375
|
buildClaudeNoToolsPlanArgv().argv.join(" "),
|
|
39376
|
+
buildClaudeReadOnlyAdvisoryPlanArgv().argv.join(" "),
|
|
39377
|
+
"claude --print --output-format json --tools Read,Grep,Glob --allowed-tools *",
|
|
38951
39378
|
"claude --print --bare --output-format json --allowed-tools Read,Grep,Glob --settings *",
|
|
38952
39379
|
"claude --print --output-format json --allowed-tools Read,Grep,Glob,Edit,Write,Bash",
|
|
38953
39380
|
// Agent web access allowlist templates (Phase 1 Claude Code)
|
|
@@ -39254,8 +39681,7 @@ var HookBridge = class {
|
|
|
39254
39681
|
};
|
|
39255
39682
|
|
|
39256
39683
|
// src/local-executor/local-executor-impl.ts
|
|
39257
|
-
var import_node_crypto34 = require("node:crypto"), syncFs = __toESM(require("node:fs"));
|
|
39258
|
-
var path60 = __toESM(require("node:path"));
|
|
39684
|
+
var import_node_crypto34 = require("node:crypto"), syncFs = __toESM(require("node:fs")), os37 = __toESM(require("node:os")), path60 = __toESM(require("node:path"));
|
|
39259
39685
|
|
|
39260
39686
|
// src/local-executor/class-a-emit.ts
|
|
39261
39687
|
var import_node_fs20 = require("node:fs"), import_ulid3 = require("ulid");
|
|
@@ -39484,17 +39910,17 @@ function pick(obj, camel, snake) {
|
|
|
39484
39910
|
}
|
|
39485
39911
|
function normalizeTrackAssignedWire(raw) {
|
|
39486
39912
|
if (!raw || typeof raw != "object") return {};
|
|
39487
|
-
let o = raw, osRaw = pick(o, "ownershipScope", "ownership_scope"),
|
|
39913
|
+
let o = raw, osRaw = pick(o, "ownershipScope", "ownership_scope"), os53 = osRaw && typeof osRaw == "object" ? osRaw : {}, sharedContracts = pick(os53, "sharedContracts", "shared_contracts"), ccRaw = pick(o, "conflictContext", "conflict_context"), conflictContext = ccRaw && typeof ccRaw == "object" ? normalizeConflictContext(ccRaw) : void 0;
|
|
39488
39914
|
return {
|
|
39489
39915
|
task_group_id: pick(o, "taskGroupId", "task_group_id"),
|
|
39490
39916
|
track_index: pick(o, "trackIndex", "track_index"),
|
|
39491
39917
|
task_id: pick(o, "taskId", "task_id"),
|
|
39492
39918
|
implementor_agent: upperAgentKind(pick(o, "implementorAgent", "implementor_agent")),
|
|
39493
39919
|
ownership_scope: {
|
|
39494
|
-
write_paths: pick(
|
|
39920
|
+
write_paths: pick(os53, "writePaths", "write_paths"),
|
|
39495
39921
|
shared_contracts: sharedContracts,
|
|
39496
|
-
test_surfaces: pick(
|
|
39497
|
-
auto_modified_files: pick(
|
|
39922
|
+
test_surfaces: pick(os53, "testSurfaces", "test_surfaces"),
|
|
39923
|
+
auto_modified_files: pick(os53, "autoModifiedFiles", "auto_modified_files")
|
|
39498
39924
|
},
|
|
39499
39925
|
is_shared_test_owner: pick(o, "isSharedTestOwner", "is_shared_test_owner"),
|
|
39500
39926
|
state_dir: pick(o, "stateDir", "state_dir"),
|
|
@@ -39600,8 +40026,8 @@ function isU32(value) {
|
|
|
39600
40026
|
}
|
|
39601
40027
|
function isValidTrackAssignedPayload(payload) {
|
|
39602
40028
|
if (!payload || typeof payload != "object" || typeof payload.task_group_id != "string" || payload.task_group_id.length === 0 || typeof payload.task_id != "string" || payload.task_id.length === 0 || typeof payload.state_dir != "string" || payload.state_dir.length === 0 || typeof payload.dispatch_id != "string" || payload.dispatch_id.length === 0 || !isU32(payload.track_index) || !isU32(payload.dispatch_generation) || typeof payload.implementor_agent != "string" || !VALID_IMPLEMENTOR_AGENTS.has(payload.implementor_agent) || typeof payload.is_shared_test_owner != "boolean") return !1;
|
|
39603
|
-
let
|
|
39604
|
-
return !(!
|
|
40029
|
+
let os53 = payload.ownership_scope;
|
|
40030
|
+
return !(!os53 || typeof os53 != "object" || !Array.isArray(os53.write_paths) || !Array.isArray(os53.auto_modified_files) || !Array.isArray(os53.shared_contracts) || !Array.isArray(os53.test_surfaces) || !os53.write_paths.every((p) => typeof p == "string") || !os53.auto_modified_files.every((p) => typeof p == "string") || !os53.test_surfaces.every((p) => typeof p == "string"));
|
|
39605
40031
|
}
|
|
39606
40032
|
function isValidMergeGateDispatchPayload(payload) {
|
|
39607
40033
|
if (!payload || typeof payload != "object" || typeof payload.task_group_id != "string" || payload.task_group_id.length === 0 || typeof payload.merge_gate_id != "string" || payload.merge_gate_id.length === 0 || typeof payload.dispatch_id != "string" || payload.dispatch_id.length === 0 || payload.integration_check_spec === void 0 || payload.integration_check_spec === null || !isU32(payload.owner_track_index) || !isU32(payload.dispatch_generation) || payload.decision_protocol_version !== void 0 && payload.decision_protocol_version !== 1 && payload.decision_protocol_version !== 2) return !1;
|
|
@@ -41554,9 +41980,9 @@ async function main(){
|
|
|
41554
41980
|
main().catch(err=>{process.stderr.write(String(err&&err.stack?err.stack:err));process.exitCode=1;});
|
|
41555
41981
|
`;
|
|
41556
41982
|
function safeRelative(root, candidate) {
|
|
41557
|
-
let
|
|
41558
|
-
if (
|
|
41559
|
-
return
|
|
41983
|
+
let relative23 = path45.relative(root, path45.resolve(candidate));
|
|
41984
|
+
if (relative23.length === 0 || path45.isAbsolute(relative23) || relative23 === ".." || relative23.startsWith(`..${path45.sep}`) || relative23.includes("\0") || relative23.split(path45.sep).some((part) => part.length === 0 || part === "." || part === "..")) throw new Error("workspace materializer path escaped its root");
|
|
41985
|
+
return relative23;
|
|
41560
41986
|
}
|
|
41561
41987
|
function createWorkspaceMaterializerSession(opts) {
|
|
41562
41988
|
assertWorkspaceRootAuthoritySchema(opts.sourceRoot), assertWorkspaceRootAuthoritySchema(opts.destinationRoot);
|
|
@@ -44171,29 +44597,29 @@ async function sealSnapshotTreeDurably(snapshotRoot, snapshotRootAuthority, env)
|
|
|
44171
44597
|
}
|
|
44172
44598
|
);
|
|
44173
44599
|
for (let entry5 of entries) {
|
|
44174
|
-
let
|
|
44600
|
+
let relative23 = current.relative ? path48.join(current.relative, entry5.name) : entry5.name, absolute = path48.join(snapshotRoot, relative23), stat13 = await fs39.lstat(absolute, { bigint: !0 });
|
|
44175
44601
|
if (stat13.isDirectory() && !stat13.isSymbolicLink()) {
|
|
44176
44602
|
let enumerated = boundedDirectoryStat(entry5);
|
|
44177
44603
|
if (!enumerated || enumerated.dev !== stat13.dev.toString() || enumerated.ino !== stat13.ino.toString())
|
|
44178
|
-
throw new Error(`snapshot directory changed after enumeration: ${
|
|
44179
|
-
pending2.push({ absolute, relative:
|
|
44604
|
+
throw new Error(`snapshot directory changed after enumeration: ${relative23}`);
|
|
44605
|
+
pending2.push({ absolute, relative: relative23, identity: enumerated });
|
|
44180
44606
|
continue;
|
|
44181
44607
|
}
|
|
44182
44608
|
if (stat13.isSymbolicLink())
|
|
44183
44609
|
continue;
|
|
44184
44610
|
if (!stat13.isFile())
|
|
44185
|
-
throw new Error(`snapshot durability seal refuses special file: ${
|
|
44611
|
+
throw new Error(`snapshot durability seal refuses special file: ${relative23}`);
|
|
44186
44612
|
let handle = await fs39.open(absolute, import_node_fs23.constants.O_RDONLY | import_node_fs23.constants.O_NOFOLLOW);
|
|
44187
44613
|
try {
|
|
44188
44614
|
let before = await handle.stat({ bigint: !0 });
|
|
44189
44615
|
if (!before.isFile() || before.dev !== stat13.dev || before.ino !== stat13.ino)
|
|
44190
|
-
throw new Error(`snapshot file changed before durability sync: ${
|
|
44616
|
+
throw new Error(`snapshot file changed before durability sync: ${relative23}`);
|
|
44191
44617
|
await env.beforeSnapshotDurabilitySync?.("file", absolute), await handle.sync();
|
|
44192
44618
|
let [after, live] = await Promise.all([
|
|
44193
44619
|
handle.stat({ bigint: !0 }),
|
|
44194
44620
|
fs39.lstat(absolute, { bigint: !0 })
|
|
44195
44621
|
]);
|
|
44196
|
-
if (!after.isFile() || !live.isFile() || live.isSymbolicLink() || after.dev !== before.dev || after.ino !== before.ino || live.dev !== before.dev || live.ino !== before.ino || after.size !== before.size || after.mtimeNs !== before.mtimeNs || after.ctimeNs !== before.ctimeNs) throw new Error(`snapshot file changed during durability sync: ${
|
|
44622
|
+
if (!after.isFile() || !live.isFile() || live.isSymbolicLink() || after.dev !== before.dev || after.ino !== before.ino || live.dev !== before.dev || live.ino !== before.ino || after.size !== before.size || after.mtimeNs !== before.mtimeNs || after.ctimeNs !== before.ctimeNs) throw new Error(`snapshot file changed during durability sync: ${relative23}`);
|
|
44197
44623
|
} finally {
|
|
44198
44624
|
await handle.close().catch(() => {
|
|
44199
44625
|
});
|
|
@@ -44702,12 +45128,12 @@ function assertStateMarkerLifecycleCapacity(marker, maxBytes) {
|
|
|
44702
45128
|
}, maxBytes);
|
|
44703
45129
|
}
|
|
44704
45130
|
async function retireFailedCreateStateMarker(stateFile, taskId, stateRootAuthority, maxBytes) {
|
|
44705
|
-
let
|
|
44706
|
-
if (parts.length !== 2 || parts[0] !== taskId || path48.isAbsolute(
|
|
45131
|
+
let relative23 = path48.relative(stateRootAuthority.canonicalPath, stateFile), parts = relative23.split(path48.sep);
|
|
45132
|
+
if (parts.length !== 2 || parts[0] !== taskId || path48.isAbsolute(relative23) || parts.some((part) => part === ".."))
|
|
44707
45133
|
throw new Error("failed-create marker is outside its state-root authority");
|
|
44708
45134
|
let read = await anchoredReadFileWithinRoot(
|
|
44709
45135
|
stateRootAuthority.canonicalPath,
|
|
44710
|
-
|
|
45136
|
+
relative23,
|
|
44711
45137
|
{
|
|
44712
45138
|
maxBytes,
|
|
44713
45139
|
expectedRoot: stateRootAuthority,
|
|
@@ -55716,14 +56142,14 @@ var LocalExecutorImpl = class {
|
|
|
55716
56142
|
deps.deviceSigningKey
|
|
55717
56143
|
)), this.bridge = new HookBridge({
|
|
55718
56144
|
emitter: this.emitter,
|
|
55719
|
-
emitShellEvent: this.emitShellEvent,
|
|
56145
|
+
emitShellEvent: this.emitShellEvent ?? (async () => ({ kind: "dropped", reason: "unwired" })),
|
|
55720
56146
|
getAuthorityScope: () => this.baseScope,
|
|
55721
56147
|
getCurrentTaskId: () => null,
|
|
55722
56148
|
getContextWithoutTask: () => this.baseCtx,
|
|
55723
56149
|
adapter: this.adapter
|
|
55724
56150
|
}), this.classBConsumer = new ClassBConsumer({
|
|
55725
56151
|
emitter: this.emitter,
|
|
55726
|
-
emitShellEvent: this.emitShellEvent,
|
|
56152
|
+
emitShellEvent: this.emitShellEvent ?? (async () => ({ kind: "dropped", reason: "unwired" })),
|
|
55727
56153
|
getContext: () => this.contextOrFallback(),
|
|
55728
56154
|
advanceAuthorityScope: (newScope, taskId) => {
|
|
55729
56155
|
this.scopeByTask.set(taskId, mergeAuthorityScope(this.baseScope, newScope));
|
|
@@ -55933,7 +56359,56 @@ var LocalExecutorImpl = class {
|
|
|
55933
56359
|
args: launchArgs,
|
|
55934
56360
|
onExit,
|
|
55935
56361
|
substrateEngaged
|
|
55936
|
-
} = await this.engageSubstrateForSpawn(promptBoundArgs, spawnTaskScope), outerBoundaryConfines = substrateEngaged || isTrustedContainerBoundary(),
|
|
56362
|
+
} = await this.engageSubstrateForSpawn(promptBoundArgs, spawnTaskScope), outerBoundaryConfines = substrateEngaged || isTrustedContainerBoundary(), claudeIsolatedConfigDir = null, claudeSecureStorageConfigDir = null, cleanupClaudeConfig = null;
|
|
56363
|
+
if ((launchArgs.agentKind ?? this.adapter) === "CLAUDE" && launchArgs.role === "implementor" && launchArgs.lifecycleAudit === "none" && isStrictReadOnlyAdvisoryClaude(launchArgs.argv) && !launchArgs.envOverrides?.CLAUDE_CONFIG_DIR && !outerBoundaryConfines) {
|
|
56364
|
+
claudeIsolatedConfigDir = syncFs.mkdtempSync(
|
|
56365
|
+
path60.join(os37.tmpdir(), `cv-claude-cfg-${process.pid}-${(0, import_node_crypto34.randomUUID)().slice(0, 8)}-`)
|
|
56366
|
+
);
|
|
56367
|
+
let ambientClaudeDir = process.env.CLAUDE_CONFIG_DIR || path60.join(os37.homedir(), ".claude");
|
|
56368
|
+
claudeSecureStorageConfigDir = process.env.CLAUDE_SECURESTORAGE_CONFIG_DIR !== void 0 ? process.env.CLAUDE_SECURESTORAGE_CONFIG_DIR : process.env.CLAUDE_CONFIG_DIR !== void 0 ? process.env.CLAUDE_CONFIG_DIR : "";
|
|
56369
|
+
try {
|
|
56370
|
+
let authFiles = [".credentials.json", "credentials.json", "config.json", "auth.json"];
|
|
56371
|
+
for (let f of authFiles) {
|
|
56372
|
+
let src = path60.join(ambientClaudeDir, f);
|
|
56373
|
+
if (syncFs.existsSync(src)) {
|
|
56374
|
+
let dest = path60.join(claudeIsolatedConfigDir, f);
|
|
56375
|
+
try {
|
|
56376
|
+
syncFs.copyFileSync(src, dest), syncFs.chmodSync(dest, 384);
|
|
56377
|
+
} catch (copyErr) {
|
|
56378
|
+
throw new Error(
|
|
56379
|
+
`failed to copy Claude credential file ${f}: ${copyErr?.message}`
|
|
56380
|
+
);
|
|
56381
|
+
}
|
|
56382
|
+
}
|
|
56383
|
+
}
|
|
56384
|
+
let settingsIdx = launchArgs.argv.indexOf("--settings"), settingsPayload = settingsIdx !== -1 && settingsIdx + 1 < launchArgs.argv.length ? launchArgs.argv[settingsIdx + 1] : "{}";
|
|
56385
|
+
syncFs.writeFileSync(
|
|
56386
|
+
path60.join(claudeIsolatedConfigDir, "settings.json"),
|
|
56387
|
+
settingsPayload,
|
|
56388
|
+
{ mode: 384 }
|
|
56389
|
+
);
|
|
56390
|
+
} catch (setupErr) {
|
|
56391
|
+
let cleanupErr = null;
|
|
56392
|
+
try {
|
|
56393
|
+
syncFs.rmSync(claudeIsolatedConfigDir, { recursive: !0, force: !0 }), syncFs.existsSync(claudeIsolatedConfigDir) && (cleanupErr = new Error(`setup cleanup failed: ${claudeIsolatedConfigDir} still exists`));
|
|
56394
|
+
} catch (err) {
|
|
56395
|
+
cleanupErr = err;
|
|
56396
|
+
}
|
|
56397
|
+
throw cleanupErr ? Object.assign(
|
|
56398
|
+
new Error(
|
|
56399
|
+
`ephemeral Claude config setup failed (${setupErr?.message}) and cleanup also failed (${cleanupErr?.message})`
|
|
56400
|
+
),
|
|
56401
|
+
{ cause: setupErr, cleanupCause: cleanupErr }
|
|
56402
|
+
) : setupErr;
|
|
56403
|
+
}
|
|
56404
|
+
cleanupClaudeConfig = async () => {
|
|
56405
|
+
if (claudeIsolatedConfigDir && syncFs.existsSync(claudeIsolatedConfigDir) && (syncFs.rmSync(claudeIsolatedConfigDir, { recursive: !0, force: !0 }), syncFs.existsSync(claudeIsolatedConfigDir)))
|
|
56406
|
+
throw new Error(
|
|
56407
|
+
`failed to cleanup ephemeral Claude config directory: ${claudeIsolatedConfigDir} still exists`
|
|
56408
|
+
);
|
|
56409
|
+
};
|
|
56410
|
+
}
|
|
56411
|
+
let finalArgs = {
|
|
55937
56412
|
...launchArgs,
|
|
55938
56413
|
argv: applyOuterBoundarySandbox(
|
|
55939
56414
|
relocateCodexLastMessageForSubstrate(
|
|
@@ -55943,11 +56418,24 @@ var LocalExecutorImpl = class {
|
|
|
55943
56418
|
),
|
|
55944
56419
|
launchArgs.agentKind ?? this.adapter,
|
|
55945
56420
|
outerBoundaryConfines
|
|
55946
|
-
)
|
|
55947
|
-
|
|
56421
|
+
),
|
|
56422
|
+
...claudeIsolatedConfigDir ? {
|
|
56423
|
+
envOverrides: {
|
|
56424
|
+
...launchArgs.envOverrides,
|
|
56425
|
+
CLAUDE_CONFIG_DIR: claudeIsolatedConfigDir,
|
|
56426
|
+
...claudeSecureStorageConfigDir !== null ? { CLAUDE_SECURESTORAGE_CONFIG_DIR: claudeSecureStorageConfigDir } : {}
|
|
56427
|
+
}
|
|
56428
|
+
} : {}
|
|
56429
|
+
}, spawnScope = outerBoundaryConfines ? withBoundaryConfinedCommandAuthority(spawnTaskScope) : spawnTaskScope, combinedOnExit = async () => {
|
|
56430
|
+
try {
|
|
56431
|
+
cleanupClaudeConfig && await cleanupClaudeConfig();
|
|
56432
|
+
} finally {
|
|
56433
|
+
onExit && await onExit();
|
|
56434
|
+
}
|
|
56435
|
+
}, handle = await this.spawnWithLifecycle(
|
|
55948
56436
|
finalArgs,
|
|
55949
56437
|
(a) => spawnImplementor(spawnScope, a),
|
|
55950
|
-
|
|
56438
|
+
combinedOnExit
|
|
55951
56439
|
);
|
|
55952
56440
|
return advisoryAdmission && this.bindAdvisorySpawn(advisoryAdmission, handle), handle;
|
|
55953
56441
|
} catch (error) {
|
|
@@ -56050,19 +56538,59 @@ var LocalExecutorImpl = class {
|
|
|
56050
56538
|
* takes the legacy path.
|
|
56051
56539
|
*/
|
|
56052
56540
|
async engageSubstrateForSpawn(args, scope) {
|
|
56541
|
+
let agentKind = args.agentKind ?? this.adapter;
|
|
56053
56542
|
if (args.role !== "implementor" || this.substrateEngager === void 0) {
|
|
56054
|
-
if (args.requireConfined)
|
|
56543
|
+
if (args.requireConfined) {
|
|
56544
|
+
if (args.lifecycleAudit === "none") {
|
|
56545
|
+
if (agentKind === "CLAUDE" && isStrictReadOnlyAdvisoryClaude(args.argv))
|
|
56546
|
+
return { args, substrateEngaged: !1 };
|
|
56547
|
+
if (agentKind === "CODEX" && isStrictReadOnlyAdvisoryCodex(args.argv))
|
|
56548
|
+
return { args, substrateEngaged: !1 };
|
|
56549
|
+
}
|
|
56055
56550
|
throw new SpawnConfinementUnavailable(
|
|
56056
56551
|
"requireConfined implementor spawn but no substrate engager is wired \u2014 fail closed"
|
|
56057
56552
|
);
|
|
56553
|
+
}
|
|
56058
56554
|
return { args, substrateEngaged: !1 };
|
|
56059
56555
|
}
|
|
56060
|
-
let agentKind = args.agentKind ?? this.adapter;
|
|
56061
56556
|
if (args.lifecycleAudit === "none") {
|
|
56062
|
-
if (
|
|
56557
|
+
if (agentKind === "ANTIGRAVITY") {
|
|
56558
|
+
if (args.requireConfined) {
|
|
56559
|
+
if (!this.substrateEngager)
|
|
56560
|
+
throw new SpawnConfinementUnavailable(
|
|
56561
|
+
"requireConfined advisory spawn for ANTIGRAVITY but no substrate engager is wired \u2014 fail closed"
|
|
56562
|
+
);
|
|
56563
|
+
let result2 = await this.substrateEngager({
|
|
56564
|
+
taskId: args.taskId ?? "advisory",
|
|
56565
|
+
agentKind,
|
|
56566
|
+
workdir: args.workingDir,
|
|
56567
|
+
role: args.role,
|
|
56568
|
+
requireConfined: !0,
|
|
56569
|
+
writableWorkdir: !1,
|
|
56570
|
+
...args.processTreeId ? { processTreeId: args.processTreeId } : {}
|
|
56571
|
+
});
|
|
56572
|
+
if (result2.mode === "substrate")
|
|
56573
|
+
return {
|
|
56574
|
+
args: { ...args, substrate: result2.substrateHandle },
|
|
56575
|
+
onExit: () => result2.teardown(),
|
|
56576
|
+
substrateEngaged: !0
|
|
56577
|
+
};
|
|
56578
|
+
throw await result2.teardown().catch(() => {
|
|
56579
|
+
}), new SpawnConfinementUnavailable(
|
|
56580
|
+
`requireConfined advisory spawn for ${agentKind} but substrate engaged reduced_trust (${result2.reducedTrustReason}) \u2014 fail closed`
|
|
56581
|
+
);
|
|
56582
|
+
}
|
|
56583
|
+
return { args, substrateEngaged: !1 };
|
|
56584
|
+
}
|
|
56585
|
+
if (args.requireConfined) {
|
|
56586
|
+
if (agentKind === "CLAUDE" && isStrictReadOnlyAdvisoryClaude(args.argv))
|
|
56587
|
+
return { args, substrateEngaged: !1 };
|
|
56588
|
+
if (agentKind === "CODEX" && isStrictReadOnlyAdvisoryCodex(args.argv))
|
|
56589
|
+
return { args, substrateEngaged: !1 };
|
|
56063
56590
|
throw new SpawnConfinementUnavailable(
|
|
56064
|
-
|
|
56591
|
+
`requireConfined advisory spawn for ${agentKind} requires a strictly validated read-only invocation \u2014 fail closed`
|
|
56065
56592
|
);
|
|
56593
|
+
}
|
|
56066
56594
|
return { args, substrateEngaged: !1 };
|
|
56067
56595
|
}
|
|
56068
56596
|
let effectiveTaskId = args.taskId ?? null;
|
|
@@ -58155,7 +58683,7 @@ var NO_OP_PASS = Object.freeze({
|
|
|
58155
58683
|
});
|
|
58156
58684
|
|
|
58157
58685
|
// src/local-executor/durable-store.ts
|
|
58158
|
-
var crypto24 = __toESM(require("node:crypto")),
|
|
58686
|
+
var crypto24 = __toESM(require("node:crypto")), os38 = __toESM(require("node:os")), path64 = __toESM(require("node:path"));
|
|
58159
58687
|
init_logger2();
|
|
58160
58688
|
var DIR_MODE8 = 448, FILE_MODE10 = 384, MAX_STORE_JSON_BYTES = 64 * 1024 * 1024, MAX_PREIMAGE_BYTES = MAX_REVIEW_FILE_BYTES, MAX_PREIMAGE_AGGREGATE_BYTES = MAX_PROMOTION_PREIMAGE_AGGREGATE_BYTES, REVERT_MANIFEST_VERSION = 1, ABSENT_PREIMAGE = "ABSENT", ORPHAN_TTL_MS = 2880 * 60 * 1e3, MANIFEST_FILE = "manifest.json", JOURNAL_FILE = "journal.json", PREIMAGE_DIR = "preimages", TRACK_TIPS_FILE = "track-tips.json", TRACK_TIPS_VERSION = 1, TRACK_BUNDLES_FILE = "track-bundles.json", TRACK_BUNDLES_VERSION = 1, OWNER_LEASE_RE = /^\.codevibe-owner-[0-9a-f]{64}\.json$/, STORE_HELPER_SOURCE_ENV = "CODEVIBE_STORE_HELPER_SOURCE_B64", STORE_HELPER_BOOTSTRAP = `const k=${JSON.stringify(STORE_HELPER_SOURCE_ENV)};const s=process.env[k];delete process.env[k];if(!s)throw new Error('missing store helper source');Function(Buffer.from(s,'base64').toString('utf8'))();`, STORE_HELPER_SOURCE = String.raw`
|
|
58161
58689
|
const fs = require('node:fs');
|
|
@@ -58367,7 +58895,7 @@ function validateTrackBundlesRecord(value, taskGroupId, limits = {
|
|
|
58367
58895
|
return value;
|
|
58368
58896
|
}
|
|
58369
58897
|
function defaultRoot4() {
|
|
58370
|
-
return path64.join(
|
|
58898
|
+
return path64.join(os38.homedir(), ".codevibe", "revert-state");
|
|
58371
58899
|
}
|
|
58372
58900
|
function hashContent2(content) {
|
|
58373
58901
|
return crypto24.createHash("sha256").update(Buffer.from(content, "utf8")).digest("hex");
|
|
@@ -58628,7 +59156,7 @@ var RevertManifestStore = class {
|
|
|
58628
59156
|
if (!this.rootDirectoryPromise) {
|
|
58629
59157
|
let creation = (async () => {
|
|
58630
59158
|
let durable = await ensureDurableDirectoryTree(root, {
|
|
58631
|
-
anchorPath: root === path64.resolve(
|
|
59159
|
+
anchorPath: root === path64.resolve(os38.homedir()) || root.startsWith(`${path64.resolve(os38.homedir())}${path64.sep}`) ? path64.resolve(os38.homedir()) : path64.dirname(root),
|
|
58632
59160
|
mode: DIR_MODE8,
|
|
58633
59161
|
enforceTargetMode: !0,
|
|
58634
59162
|
helperTimeoutMs: this.helperTimeoutMs,
|
|
@@ -61623,7 +62151,7 @@ function withImplementorCredentialPreflight(engage, store) {
|
|
|
61623
62151
|
}
|
|
61624
62152
|
|
|
61625
62153
|
// src/substrate/docker.ts
|
|
61626
|
-
var import_node_fs30 = require("node:fs"),
|
|
62154
|
+
var import_node_fs30 = require("node:fs"), os40 = __toESM(require("node:os")), path67 = __toESM(require("node:path"));
|
|
61627
62155
|
|
|
61628
62156
|
// src/substrate/command-runner.ts
|
|
61629
62157
|
var import_node_child_process9 = require("node:child_process");
|
|
@@ -61926,7 +62454,7 @@ var DockerHandle = class {
|
|
|
61926
62454
|
}
|
|
61927
62455
|
}, DockerSubstrate = class {
|
|
61928
62456
|
constructor(deps = {}) {
|
|
61929
|
-
this.runner = deps.runner ?? new ChildProcessCommandRunner(), this.forwarderFactory = deps.forwarderFactory ?? defaultForwarderFactory, this.onEgressDenied = deps.onEgressDenied ?? NOOP_EGRESS_HOOK, this.image = deps.image ?? DEFAULT_IMAGE, this.sessionRoot = deps.sessionRoot ??
|
|
62457
|
+
this.runner = deps.runner ?? new ChildProcessCommandRunner(), this.forwarderFactory = deps.forwarderFactory ?? defaultForwarderFactory, this.onEgressDenied = deps.onEgressDenied ?? NOOP_EGRESS_HOOK, this.image = deps.image ?? DEFAULT_IMAGE, this.sessionRoot = deps.sessionRoot ?? os40.tmpdir(), this.acquireWorkdirLease = deps.acquireWorkdirLease ?? acquireWorkspaceRootLease;
|
|
61930
62458
|
}
|
|
61931
62459
|
async launch(spec) {
|
|
61932
62460
|
await this.assertDockerAvailable();
|
|
@@ -62057,7 +62585,7 @@ function randomId() {
|
|
|
62057
62585
|
}
|
|
62058
62586
|
|
|
62059
62587
|
// src/substrate/sandbox-exec.ts
|
|
62060
|
-
var import_node_fs31 = require("node:fs"),
|
|
62588
|
+
var import_node_fs31 = require("node:fs"), os41 = __toESM(require("node:os")), path68 = __toESM(require("node:path"));
|
|
62061
62589
|
var import_node_path2 = require("node:path");
|
|
62062
62590
|
var NODE_PREFIXES = ["/opt/homebrew", "/usr/local", "/opt/local"], FILE_KEYCHAIN_DIR_NAME = ".codevibe", SYSCTL_READ_ALLOW = [
|
|
62063
62591
|
'(sysctl-name-prefix "hw.")',
|
|
@@ -62096,7 +62624,12 @@ function nodeReadDirs(execPath) {
|
|
|
62096
62624
|
}
|
|
62097
62625
|
return [...dirs];
|
|
62098
62626
|
}
|
|
62099
|
-
function
|
|
62627
|
+
function isInsideOrEqual2(child, parent) {
|
|
62628
|
+
if (child === parent) return !0;
|
|
62629
|
+
let rel = path68.relative(parent, child);
|
|
62630
|
+
return rel.length > 0 && !rel.startsWith("..") && !path68.isAbsolute(rel);
|
|
62631
|
+
}
|
|
62632
|
+
function buildSeatbeltProfile(workdir, execPath = process.execPath, extraReadDirs = [], homedir41 = os41.homedir(), auditDir = null, extraWriteDirs = [], networkPosture = "loopback", writableWorkdir = !0) {
|
|
62100
62633
|
let esc = (s) => s.replace(/"/g, '\\"'), wd = esc(workdir), lines = [
|
|
62101
62634
|
"(version 1)",
|
|
62102
62635
|
"(deny default)",
|
|
@@ -62208,7 +62741,14 @@ function buildSeatbeltProfile(workdir, execPath = process.execPath, extraReadDir
|
|
|
62208
62741
|
for (let dir of extraWriteDirs) subpathReadGrants.push(dir);
|
|
62209
62742
|
for (let dir of subpathReadGrants)
|
|
62210
62743
|
lines.push(`(allow file-read* (subpath "${esc(dir)}"))`);
|
|
62211
|
-
|
|
62744
|
+
if (!writableWorkdir) {
|
|
62745
|
+
for (let dir of extraWriteDirs)
|
|
62746
|
+
if (isInsideOrEqual2(dir, wd))
|
|
62747
|
+
throw new Error(
|
|
62748
|
+
`writable runtime grant "${dir}" is inside read-only workdir "${wd}" \u2014 conflicting boundary`
|
|
62749
|
+
);
|
|
62750
|
+
}
|
|
62751
|
+
writableWorkdir && lines.push(`(allow file-write* (subpath "${wd}"))`);
|
|
62212
62752
|
for (let dir of extraWriteDirs)
|
|
62213
62753
|
lines.push(`(allow file-write* (subpath "${esc(dir)}"))`);
|
|
62214
62754
|
let litReads = /* @__PURE__ */ new Set();
|
|
@@ -62220,11 +62760,11 @@ function buildSeatbeltProfile(workdir, execPath = process.execPath, extraReadDir
|
|
|
62220
62760
|
`(deny file-read* (subpath "${wd}/.git"))`,
|
|
62221
62761
|
`(deny file-write* (subpath "${wd}/.git"))`
|
|
62222
62762
|
);
|
|
62223
|
-
let fileKeychainDir = esc(path68.join(
|
|
62763
|
+
let fileKeychainDir = esc(path68.join(homedir41, FILE_KEYCHAIN_DIR_NAME));
|
|
62224
62764
|
if (lines.push(
|
|
62225
62765
|
`(deny file-read* (subpath "${fileKeychainDir}"))`,
|
|
62226
62766
|
`(deny file-write* (subpath "${fileKeychainDir}"))`
|
|
62227
|
-
), auditDir !== null) {
|
|
62767
|
+
), writableWorkdir || lines.push(`(deny file-write* (subpath "${wd}"))`), auditDir !== null) {
|
|
62228
62768
|
let ad = esc(auditDir);
|
|
62229
62769
|
lines.push(
|
|
62230
62770
|
`(deny file-read* (subpath "${ad}"))`,
|
|
@@ -62233,12 +62773,12 @@ function buildSeatbeltProfile(workdir, execPath = process.execPath, extraReadDir
|
|
|
62233
62773
|
}
|
|
62234
62774
|
return networkPosture === "open" ? lines.push(
|
|
62235
62775
|
// A1d resolver-confinement row: deny all network, then re-allow ALL
|
|
62236
|
-
// OUTBOUND (inbound stays denied).
|
|
62237
|
-
//
|
|
62238
|
-
// egress is NOT pinned on this row (the engage result badges it); the
|
|
62239
|
-
// row's confinement objective is the FS-write fence above.
|
|
62776
|
+
// OUTBOUND (external inbound stays denied). Loopback bind/inbound is permitted
|
|
62777
|
+
// for local IPC (e.g. Antigravity local RPC daemon on 127.0.0.1).
|
|
62240
62778
|
"(deny network*)",
|
|
62241
62779
|
"(allow network-outbound)",
|
|
62780
|
+
'(allow network-bind (local ip "localhost:*"))',
|
|
62781
|
+
'(allow network-inbound (local ip "localhost:*"))',
|
|
62242
62782
|
""
|
|
62243
62783
|
) : lines.push(
|
|
62244
62784
|
// Network: deny all, then re-allow loopback ONLY (the coarse tier).
|
|
@@ -62285,12 +62825,12 @@ var SandboxExecHandle = class {
|
|
|
62285
62825
|
`agent binary '${argv[0]}' not found on the host PATH \u2014 cannot exec in the sandbox`
|
|
62286
62826
|
);
|
|
62287
62827
|
let realArgv0 = await import_node_fs31.promises.realpath(resolvedArgv0).catch(() => resolvedArgv0), deniedRoots = [
|
|
62288
|
-
path68.join(
|
|
62828
|
+
path68.join(os41.homedir(), ".codevibe"),
|
|
62289
62829
|
path68.join(this.workdir, ".git"),
|
|
62290
62830
|
...this.auditDir !== null ? [this.auditDir] : []
|
|
62291
62831
|
], overlapsDeniedRoot = (d) => deniedRoots.some(
|
|
62292
62832
|
(root) => d === root || d.startsWith(root + path68.sep) || root.startsWith(d + path68.sep)
|
|
62293
|
-
), broadRoots = /* @__PURE__ */ new Set(["/", "/Users", "/home",
|
|
62833
|
+
), broadRoots = /* @__PURE__ */ new Set(["/", "/Users", "/home", os41.homedir()]), binDirs = /* @__PURE__ */ new Set([path68.dirname(resolvedArgv0), path68.dirname(realArgv0)]);
|
|
62294
62834
|
for (let d of binDirs)
|
|
62295
62835
|
if (overlapsDeniedRoot(d) || broadRoots.has(d))
|
|
62296
62836
|
throw new SubstrateLaunchError(
|
|
@@ -62337,7 +62877,7 @@ ${allowLines}
|
|
|
62337
62877
|
}
|
|
62338
62878
|
}, SandboxExecSubstrate = class {
|
|
62339
62879
|
constructor(deps = {}) {
|
|
62340
|
-
this.runner = deps.runner ?? new ChildProcessCommandRunner(), this.profileRoot = deps.profileRoot ??
|
|
62880
|
+
this.runner = deps.runner ?? new ChildProcessCommandRunner(), this.profileRoot = deps.profileRoot ?? os41.tmpdir(), this.platform = deps.platform ?? process.platform;
|
|
62341
62881
|
}
|
|
62342
62882
|
async launch(spec) {
|
|
62343
62883
|
if (this.platform !== "darwin")
|
|
@@ -62403,12 +62943,13 @@ ${allowLines}
|
|
|
62403
62943
|
canonicalWorkdir,
|
|
62404
62944
|
process.execPath,
|
|
62405
62945
|
extraReadDirs,
|
|
62406
|
-
|
|
62946
|
+
os41.homedir(),
|
|
62407
62947
|
resolvedAuditDir,
|
|
62408
62948
|
extraWriteDirs,
|
|
62409
62949
|
// A1d — the resolver-confinement row threads `'open'`; absent → loopback
|
|
62410
62950
|
// (the CP-7 broker tier, byte-identical profile).
|
|
62411
|
-
spec.networkPosture ?? "loopback"
|
|
62951
|
+
spec.networkPosture ?? "loopback",
|
|
62952
|
+
spec.writableWorkdir !== !1
|
|
62412
62953
|
), profilePath = path68.join(this.profileRoot, `codevibe-seatbelt-${id5}.sb`);
|
|
62413
62954
|
try {
|
|
62414
62955
|
await import_node_fs31.promises.writeFile(profilePath, profile, { encoding: "utf8", mode: 384 });
|
|
@@ -63089,7 +63630,7 @@ function formatReviewerError(detail) {
|
|
|
63089
63630
|
}
|
|
63090
63631
|
|
|
63091
63632
|
// src/reviewer/providers/codex.ts
|
|
63092
|
-
var fs51 = __toESM(require("fs")),
|
|
63633
|
+
var fs51 = __toESM(require("fs")), os42 = __toESM(require("os")), path70 = __toESM(require("path")), import_uuid11 = require("uuid");
|
|
63093
63634
|
|
|
63094
63635
|
// src/reviewer/output-parser.ts
|
|
63095
63636
|
var RESIDUAL_OBSERVATIONS_HEADING = "RESIDUAL OBSERVATIONS:";
|
|
@@ -63324,7 +63865,7 @@ function trimEnd(s) {
|
|
|
63324
63865
|
var FAILURE_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
63325
63866
|
"error",
|
|
63326
63867
|
"turn.failed"
|
|
63327
|
-
]), USAGE_LIMIT_RE = /usage
|
|
63868
|
+
]), USAGE_LIMIT_RE = /(?:usage|weekly|daily|monthly|rate).?limit|purchase more credits|try again at/i, AUTH_FAILED_RE = /unauthorized|not logged in|authenticat|invalid api key|\b401\b/i;
|
|
63328
63869
|
function classifyFailureMessage(message2) {
|
|
63329
63870
|
return USAGE_LIMIT_RE.test(message2) ? "usage_limit" : AUTH_FAILED_RE.test(message2) ? "auth_failed" : null;
|
|
63330
63871
|
}
|
|
@@ -63599,7 +64140,7 @@ function extractCodexUsageSnapshot(stdout, elapsedMs) {
|
|
|
63599
64140
|
}) : unavailableUsageSnapshot("usage_not_reported", elapsedMs);
|
|
63600
64141
|
}
|
|
63601
64142
|
function makeLastMessagePath() {
|
|
63602
|
-
return path70.join(
|
|
64143
|
+
return path70.join(os42.tmpdir(), `quorum-codex-last-${process.pid}-${(0, import_uuid11.v4)()}.txt`);
|
|
63603
64144
|
}
|
|
63604
64145
|
function makeLastMessageBasename() {
|
|
63605
64146
|
return `quorum-codex-last-${process.pid}-${(0, import_uuid11.v4)()}.txt`;
|
|
@@ -63944,7 +64485,7 @@ function classifyImplementorQuotaFailure(exitCode, text2) {
|
|
|
63944
64485
|
function defaultOutageNotificationRoot() {
|
|
63945
64486
|
if (process.env.CODEVIBE_OUTAGE_NOTIFICATION_ROOT)
|
|
63946
64487
|
return process.env.CODEVIBE_OUTAGE_NOTIFICATION_ROOT;
|
|
63947
|
-
let baseHome = process.env.CODEVIBE_HOME_OVERRIDE ||
|
|
64488
|
+
let baseHome = process.env.CODEVIBE_HOME_OVERRIDE || os43.homedir();
|
|
63948
64489
|
return path71.join(baseHome, ".codevibe", "outage-notifications");
|
|
63949
64490
|
}
|
|
63950
64491
|
function cleanDirectorySafely(dir) {
|
|
@@ -69927,7 +70468,7 @@ ${section}`);
|
|
|
69927
70468
|
oursCommit,
|
|
69928
70469
|
theirsCommit,
|
|
69929
70470
|
baseSha
|
|
69930
|
-
}), parentDir = await import_node_fs32.promises.mkdtemp(path71.join(
|
|
70471
|
+
}), parentDir = await import_node_fs32.promises.mkdtemp(path71.join(os43.tmpdir(), "codevibe-wb2-resolve-"));
|
|
69931
70472
|
return resolveAgenticSlot({
|
|
69932
70473
|
realRepoDir: this.deps.workingDir,
|
|
69933
70474
|
// canonical loop workdir == repo root
|
|
@@ -75150,10 +75691,10 @@ function destructiveConfirmationQuestion(text2) {
|
|
|
75150
75691
|
}
|
|
75151
75692
|
|
|
75152
75693
|
// src/orchestration-shell/advisory-attachment-journal.ts
|
|
75153
|
-
var import_node_crypto37 = require("node:crypto"),
|
|
75694
|
+
var import_node_crypto37 = require("node:crypto"), os44 = __toESM(require("node:os")), path72 = __toESM(require("node:path")), import_node_fs33 = require("node:fs");
|
|
75154
75695
|
var JOURNAL_DIR_NAME = "advisory-attachment-authority", JOURNAL_MAX_RECORD_BYTES = 32 * 1024, JOURNAL_MAX_ENTRIES = 1e4, JOURNAL_MAX_METADATA_BYTES = 16 * 1024 * 1024, BATCH_NAME_RE = /^batch-([0-9a-f]{64})\.json$/, ATTACHMENT_NAME_RE = /^attachment-([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})\.json$/i, PROCESS_NAME_RE = /^process-([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})\.json$/i, RETIREMENT_NAME_RE = /^\.codevibe-retire-([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})$/i, UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i, SHA256_RE = /^[0-9a-f]{64}$/;
|
|
75155
75696
|
function resolveHome10() {
|
|
75156
|
-
return (process.env.VITEST === "true" || process.env.NODE_ENV === "test") && process.env.CODEVIBE_HOME_OVERRIDE ? process.env.CODEVIBE_HOME_OVERRIDE :
|
|
75697
|
+
return (process.env.VITEST === "true" || process.env.NODE_ENV === "test") && process.env.CODEVIBE_HOME_OVERRIDE ? process.env.CODEVIBE_HOME_OVERRIDE : os44.homedir();
|
|
75157
75698
|
}
|
|
75158
75699
|
function advisoryAttachmentJournalRoot(home = resolveHome10()) {
|
|
75159
75700
|
return path72.join(home, ".codevibe", JOURNAL_DIR_NAME);
|
|
@@ -75340,8 +75881,8 @@ var AdvisoryAttachmentJournal = class {
|
|
|
75340
75881
|
opts.anchorPath ?? (opts.rootDir ? path72.dirname(this.rootPath) : resolveHome10())
|
|
75341
75882
|
), this.currentOwner = opts.currentProcessIdentityFn ?? currentProcessIdentity, this.ownerIsAlive = opts.isProcessIdentityAliveFn ?? isProcessIdentityAlive, this.retryProcessOwner = opts.retryProcessCleanupOwnerFn ?? retryProcessCleanupOwner, this.mintId = opts.newId ?? import_node_crypto37.randomUUID, this.now = opts.now ?? Date.now, this.retirementSettleMs = opts.retirementSettleMs ?? 1e3, !Number.isSafeInteger(this.retirementSettleMs) || this.retirementSettleMs < 0 || this.retirementSettleMs > 1e4)
|
|
75342
75883
|
throw new Error("invalid advisory attachment retirement settle window");
|
|
75343
|
-
let
|
|
75344
|
-
if (
|
|
75884
|
+
let relative23 = path72.relative(this.anchorPath, this.rootPath);
|
|
75885
|
+
if (relative23 === ".." || relative23.startsWith(`..${path72.sep}`) || path72.isAbsolute(relative23))
|
|
75345
75886
|
throw new Error("advisory attachment journal root escaped its private anchor");
|
|
75346
75887
|
}
|
|
75347
75888
|
async openRoot(create) {
|
|
@@ -76145,7 +76686,7 @@ function classifyDurableWorkspaceOutcome(event, displayedSessionId, decryptedMet
|
|
|
76145
76686
|
}
|
|
76146
76687
|
|
|
76147
76688
|
// src/orchestration-shell/workspace-terminal-coordinator.ts
|
|
76148
|
-
var crypto29 = __toESM(require("node:crypto")), import_node_fs34 = require("node:fs"),
|
|
76689
|
+
var crypto29 = __toESM(require("node:crypto")), import_node_fs34 = require("node:fs"), os45 = __toESM(require("node:os")), path73 = __toESM(require("node:path"));
|
|
76149
76690
|
init_logger2();
|
|
76150
76691
|
|
|
76151
76692
|
// src/orchestration-shell/emit-shell-event.ts
|
|
@@ -76768,7 +77309,7 @@ var WorkspaceTerminalCoordinator = class {
|
|
|
76768
77309
|
this.operationChain = Promise.resolve();
|
|
76769
77310
|
if (!options.session.sessionGenerationId || !UUID_RE5.test(options.session.sessionGenerationId))
|
|
76770
77311
|
throw new Error("WorkspaceTerminalCoordinator: session generation is unavailable");
|
|
76771
|
-
this.session = options.session, this.appsyncClient = options.appsyncClient, this.getSessionKey = options.getSessionKey, this.rootDir = options.rootDir ?? path73.join(
|
|
77312
|
+
this.session = options.session, this.appsyncClient = options.appsyncClient, this.getSessionKey = options.getSessionKey, this.rootDir = options.rootDir ?? path73.join(os45.homedir(), ".codevibe"), this.now = options.now ?? (() => /* @__PURE__ */ new Date()), this.onSyncIssue = options.onSyncIssue;
|
|
76772
77313
|
}
|
|
76773
77314
|
generation() {
|
|
76774
77315
|
return this.session.sessionGenerationId;
|
|
@@ -77330,7 +77871,7 @@ var WorkspaceTerminalCoordinator = class {
|
|
|
77330
77871
|
};
|
|
77331
77872
|
|
|
77332
77873
|
// src/orchestration-shell/decision-effect.ts
|
|
77333
|
-
var crypto30 = __toESM(require("node:crypto")), fs55 = __toESM(require("node:fs/promises")), import_node_fs35 = require("node:fs"),
|
|
77874
|
+
var crypto30 = __toESM(require("node:crypto")), fs55 = __toESM(require("node:fs/promises")), import_node_fs35 = require("node:fs"), os46 = __toESM(require("node:os")), path74 = __toESM(require("node:path"));
|
|
77334
77875
|
var RECEIPT_VERSION = 1, DIRECTORY_MODE2 = 448, FILE_MODE11 = 384, MAX_RECEIPT_BYTES2 = 64 * 1024, MAX_SESSION_RECEIPTS2 = 64, KNOWN_DECISIONS2 = /* @__PURE__ */ new Set([
|
|
77335
77876
|
"APPROVE",
|
|
77336
77877
|
"CANCEL",
|
|
@@ -77345,7 +77886,7 @@ function opaque(value) {
|
|
|
77345
77886
|
return crypto30.createHash("sha256").update(value, "utf8").digest("hex");
|
|
77346
77887
|
}
|
|
77347
77888
|
function defaultRoot5() {
|
|
77348
|
-
return path74.join(
|
|
77889
|
+
return path74.join(os46.homedir(), ".codevibe", "decision-effects");
|
|
77349
77890
|
}
|
|
77350
77891
|
function durableResolutionDescriptorHash(resolution) {
|
|
77351
77892
|
return crypto30.createHash("sha256").update(JSON.stringify({
|
|
@@ -77387,10 +77928,10 @@ var DecisionEffectReceiptStore = class {
|
|
|
77387
77928
|
return path74.join(this.rootDir, opaque(sessionId), `${opaque(decisionClaimId)}.json`);
|
|
77388
77929
|
}
|
|
77389
77930
|
async assertNoSymlinkComponents(target2) {
|
|
77390
|
-
let
|
|
77391
|
-
if (
|
|
77931
|
+
let relative23 = path74.relative(this.rootDir, target2);
|
|
77932
|
+
if (relative23.startsWith("..") || path74.isAbsolute(relative23))
|
|
77392
77933
|
throw new Error("DecisionEffectReceiptStore: path escaped root");
|
|
77393
|
-
let components =
|
|
77934
|
+
let components = relative23 ? relative23.split(path74.sep) : [], current = this.rootDir;
|
|
77394
77935
|
for (let index = -1; index < components.length; index += 1) {
|
|
77395
77936
|
index >= 0 && (current = path74.join(current, components[index]));
|
|
77396
77937
|
try {
|
|
@@ -79435,7 +79976,7 @@ ${notFoundMsg}`), fallbackSection && sections.push(fallbackSection);
|
|
|
79435
79976
|
}
|
|
79436
79977
|
|
|
79437
79978
|
// src/continuation/packet-reader.ts
|
|
79438
|
-
var import_node_fs36 = require("node:fs"), path76 = __toESM(require("node:path")),
|
|
79979
|
+
var import_node_fs36 = require("node:fs"), path76 = __toESM(require("node:path")), os47 = __toESM(require("node:os")), import_yaml2 = require("yaml");
|
|
79439
79980
|
init_types();
|
|
79440
79981
|
init_packet_writer();
|
|
79441
79982
|
init_packet_writer();
|
|
@@ -79506,7 +80047,7 @@ async function packetHashIsInAudit(appsync, packet, packetHash) {
|
|
|
79506
80047
|
}
|
|
79507
80048
|
}
|
|
79508
80049
|
function createContinuationPacketReader(deps) {
|
|
79509
|
-
let homeDir = deps.homeDir ??
|
|
80050
|
+
let homeDir = deps.homeDir ?? os47.homedir();
|
|
79510
80051
|
return {
|
|
79511
80052
|
async read(taskId, expectedHash) {
|
|
79512
80053
|
let filePath = getPacketFilePath(taskId, homeDir), stat13;
|
|
@@ -83969,12 +84510,11 @@ function readOnlyAgentPrompt(args) {
|
|
|
83969
84510
|
`);
|
|
83970
84511
|
return args.agent === "ANTIGRAVITY" && args.allowRepositoryTools ? `${agyReadOnlyWorkdirPreamble(args.workingDir)}${body}` : body;
|
|
83971
84512
|
}
|
|
83972
|
-
function readOnlyAdvisoryAllowsRepositoryTools(
|
|
83973
|
-
|
|
83974
|
-
return concreteRepositoryTarget && inspectionIntent;
|
|
84513
|
+
function readOnlyAdvisoryAllowsRepositoryTools(_input) {
|
|
84514
|
+
return !0;
|
|
83975
84515
|
}
|
|
83976
|
-
function applyReadOnlyAdvisoryToolPolicy(agent, plan, allowRepositoryTools) {
|
|
83977
|
-
return
|
|
84516
|
+
function applyReadOnlyAdvisoryToolPolicy(agent, plan, allowRepositoryTools, workingDir, attachments) {
|
|
84517
|
+
return agent !== "CLAUDE" ? plan : allowRepositoryTools ? buildClaudeReadOnlyAdvisoryPlanArgv(workingDir, attachments) : buildClaudeNoToolsPlanArgv();
|
|
83978
84518
|
}
|
|
83979
84519
|
async function readPlanModeOutput(args) {
|
|
83980
84520
|
try {
|
|
@@ -84028,7 +84568,11 @@ function syntheticReadOnlyAdvisoryTaskId() {
|
|
|
84028
84568
|
return (0, import_uuid15.v4)();
|
|
84029
84569
|
}
|
|
84030
84570
|
function classifyClaudeResultStdoutQuota(stdout) {
|
|
84031
|
-
let
|
|
84571
|
+
let env = firstResultEnvelope(stdout);
|
|
84572
|
+
if (!env) return !1;
|
|
84573
|
+
if (env.api_error === "usage_limit_reached" || env.api_error_status === 429 || typeof env.api_error == "string" && classifyFailureMessage(env.api_error) === "usage_limit")
|
|
84574
|
+
return !0;
|
|
84575
|
+
let result = env.result;
|
|
84032
84576
|
return typeof result == "string" && result.length > 0 && classifyFailureMessage(result) === "usage_limit";
|
|
84033
84577
|
}
|
|
84034
84578
|
function extractReadOnlyAdvisoryUsage(args) {
|
|
@@ -84080,10 +84624,14 @@ async function runReadOnlyAgentAdvisoryResult(args) {
|
|
|
84080
84624
|
args.attachmentBatch,
|
|
84081
84625
|
args.workingDir
|
|
84082
84626
|
) : await attachmentJournal.assertWorkspaceSafe(args.workingDir);
|
|
84083
|
-
let allowRepositoryTools = readOnlyAdvisoryAllowsRepositoryTools(args.advisoryBrief),
|
|
84627
|
+
let allowRepositoryTools = readOnlyAdvisoryAllowsRepositoryTools(args.advisoryBrief), attachmentPaths = [];
|
|
84628
|
+
args.attachmentBatch?.value.directory.canonicalPath && attachmentPaths.push(args.attachmentBatch.value.directory.canonicalPath);
|
|
84629
|
+
let plan = applyReadOnlyAdvisoryToolPolicy(
|
|
84084
84630
|
args.agent,
|
|
84085
84631
|
buildImplementorArgv(args.agent, "plan", args.workingDir),
|
|
84086
|
-
allowRepositoryTools
|
|
84632
|
+
allowRepositoryTools,
|
|
84633
|
+
args.workingDir,
|
|
84634
|
+
attachmentPaths
|
|
84087
84635
|
), processAuthority = null, bindProcessOwner = args.attachmentBatch ? async (owner) => {
|
|
84088
84636
|
if (processAuthority)
|
|
84089
84637
|
throw new Error("advisory process authority was already bound");
|
|
@@ -84096,13 +84644,27 @@ async function runReadOnlyAgentAdvisoryResult(args) {
|
|
|
84096
84644
|
throw new Error("advisory process retirement has no durable authority");
|
|
84097
84645
|
let authority = processAuthority;
|
|
84098
84646
|
await attachmentJournal.retireProcess(authority, owner), processAuthority = null;
|
|
84099
|
-
} : void 0, advisoryTaskId = syntheticReadOnlyAdvisoryTaskId(),
|
|
84647
|
+
} : void 0, advisoryTaskId = syntheticReadOnlyAdvisoryTaskId(), treeBefore = await probeWorkspaceTreeFingerprint(args.workingDir);
|
|
84648
|
+
if (treeBefore.kind !== "fingerprint")
|
|
84649
|
+
return logger.error("[orchestration-shell] workspace fingerprint unavailable before read-only advisory turn \u2014 failing closed", {
|
|
84650
|
+
agent: args.agent,
|
|
84651
|
+
workingDir: args.workingDir
|
|
84652
|
+
}), plan.capture.kind === "file" && await (0, import_promises.unlink)(plan.capture.path).catch(() => {
|
|
84653
|
+
}), {
|
|
84654
|
+
ok: !1,
|
|
84655
|
+
text: readOnlyRouteFallback({ agent: args.agent }),
|
|
84656
|
+
quotaWalled: !1,
|
|
84657
|
+
timedOut: !1,
|
|
84658
|
+
usage: unavailableUsageSnapshot("workspace_verification_unavailable")
|
|
84659
|
+
};
|
|
84660
|
+
let handle = await args.shellArgs.localExecutor.spawnImplementor({
|
|
84100
84661
|
argv: plan.argv,
|
|
84101
84662
|
workingDir: args.workingDir,
|
|
84102
84663
|
role: "implementor",
|
|
84103
84664
|
agentKind: args.agent,
|
|
84104
84665
|
taskId: advisoryTaskId,
|
|
84105
84666
|
lifecycleAudit: "none",
|
|
84667
|
+
requireConfined: !0,
|
|
84106
84668
|
timeoutMs: args.timeoutMs ?? READ_ONLY_ADVISORY_TIMEOUT_MS,
|
|
84107
84669
|
stdinTty: !0,
|
|
84108
84670
|
stdinPayload: readOnlyAgentPrompt({
|
|
@@ -84115,7 +84677,24 @@ async function runReadOnlyAgentAdvisoryResult(args) {
|
|
|
84115
84677
|
}),
|
|
84116
84678
|
...bindProcessOwner ? { onCleanupOwnerReady: bindProcessOwner } : {},
|
|
84117
84679
|
...retireProcessOwner ? { onCleanupOwnerRetired: retireProcessOwner } : {}
|
|
84118
|
-
}), exit = await handle.done,
|
|
84680
|
+
}), exit = await handle.done, treeAfter = await probeWorkspaceTreeFingerprint(args.workingDir);
|
|
84681
|
+
if (treeAfter.kind !== "fingerprint" || treeAfter.value !== treeBefore.value)
|
|
84682
|
+
return logger.error("[orchestration-shell] workspace mutation or verification failure detected during read-only advisory turn", {
|
|
84683
|
+
agent: args.agent,
|
|
84684
|
+
workingDir: args.workingDir,
|
|
84685
|
+
before: treeBefore.value,
|
|
84686
|
+
after: treeAfter.kind === "fingerprint" ? treeAfter.value : "probe-failed"
|
|
84687
|
+
}), plan.capture.kind === "file" && await (0, import_promises.unlink)(plan.capture.path).catch(() => {
|
|
84688
|
+
}), {
|
|
84689
|
+
ok: !1,
|
|
84690
|
+
text: readOnlyRouteFallback({ agent: args.agent }),
|
|
84691
|
+
quotaWalled: !1,
|
|
84692
|
+
timedOut: !1,
|
|
84693
|
+
usage: unavailableUsageSnapshot(
|
|
84694
|
+
treeAfter.kind === "fingerprint" ? "workspace_mutation_detected" : "workspace_verification_unavailable"
|
|
84695
|
+
)
|
|
84696
|
+
};
|
|
84697
|
+
let output = await readPlanModeOutput({
|
|
84119
84698
|
agent: args.agent,
|
|
84120
84699
|
plan,
|
|
84121
84700
|
handle,
|
|
@@ -86230,21 +86809,21 @@ async function handleShellUserInput(deps) {
|
|
|
86230
86809
|
store.getState().session.sessionId
|
|
86231
86810
|
), store.dispatch({ type: "CLEAR_PENDING_PLANNER_OFFER" });
|
|
86232
86811
|
}
|
|
86233
|
-
let pendingForIngest = store.getState().pendingClarification, isAnsweringPending = !!pendingForIngest && pendingForIngest.rounds.length > 0 && pendingForIngest.rounds[pendingForIngest.rounds.length - 1].answer === void 0, existingAttachments = !slashCommandText.startsWith("/") && isAnsweringPending ? pendingForIngest.attachments : void 0, cwd = args.cwd ?? process.cwd(),
|
|
86812
|
+
let pendingForIngest = store.getState().pendingClarification, isAnsweringPending = !!pendingForIngest && pendingForIngest.rounds.length > 0 && pendingForIngest.rounds[pendingForIngest.rounds.length - 1].answer === void 0, existingAttachments = !slashCommandText.startsWith("/") && isAnsweringPending ? pendingForIngest.attachments : void 0, cwd = args.cwd ?? process.cwd(), homedir41 = os48.homedir(), runAttachmentIngest = (existing) => {
|
|
86234
86813
|
if (deps.images && deps.images.length > 0) {
|
|
86235
86814
|
let carried = attachmentsFromPaths(
|
|
86236
86815
|
deps.images,
|
|
86237
86816
|
existing && existing.length ? { existing } : void 0
|
|
86238
86817
|
), fromText = detectImageAttachments(text2.replace(/\[Image #\d+\]/g, " "), {
|
|
86239
86818
|
cwd,
|
|
86240
|
-
homedir:
|
|
86819
|
+
homedir: homedir41,
|
|
86241
86820
|
existing: carried.attachments
|
|
86242
86821
|
});
|
|
86243
86822
|
return { attachments: fromText.attachments, rejects: [...carried.rejects, ...fromText.rejects] };
|
|
86244
86823
|
}
|
|
86245
86824
|
return detectImageAttachments(text2, {
|
|
86246
86825
|
cwd,
|
|
86247
|
-
homedir:
|
|
86826
|
+
homedir: homedir41,
|
|
86248
86827
|
...existing && existing.length ? { existing } : {}
|
|
86249
86828
|
});
|
|
86250
86829
|
}, ingest = runAttachmentIngest(existingAttachments), turnAttachments = ingest.attachments, currentTurnIngest = existingAttachments && existingAttachments.length > 0 ? runAttachmentIngest() : ingest, currentTurnAttachments = currentTurnIngest.attachments, turnImagePaths = (deps.images ?? []).map((p) => path78.resolve(p)), teamDurableStore = typeof args.quorumLoop?.getDurableStore == "function" ? args.quorumLoop.getDurableStore() : void 0, ingestRejectsSurfaced = !1, surfaceIngestRejects = (result) => {
|
|
@@ -88127,7 +88706,7 @@ async function runStructuralSummarySessionStart(deps) {
|
|
|
88127
88706
|
try {
|
|
88128
88707
|
let optIn = await readOptIn(args.tier), discovery = await discoverRepositoryRoots({ launchDir: process.cwd() }), summary = await generator.generate({
|
|
88129
88708
|
rootPaths: discovery.rootPaths,
|
|
88130
|
-
ignoreFile: path78.join(
|
|
88709
|
+
ignoreFile: path78.join(os48.homedir(), ".codevibe", "structural-summary.ignore"),
|
|
88131
88710
|
includeBodies: optIn?.bodyInclusionPaths ?? [],
|
|
88132
88711
|
userId: args.session.userId,
|
|
88133
88712
|
tier: args.tier
|
|
@@ -89495,7 +90074,7 @@ ${colors.green}\u2713${colors.reset} Cleared ${clearable.length} entr${clearable
|
|
|
89495
90074
|
}
|
|
89496
90075
|
|
|
89497
90076
|
// src/substrate-launch/engage-substrate.ts
|
|
89498
|
-
var import_node_fs38 = require("node:fs"),
|
|
90077
|
+
var import_node_fs38 = require("node:fs"), os49 = __toESM(require("node:os")), path80 = __toESM(require("node:path"));
|
|
89499
90078
|
|
|
89500
90079
|
// src/credential-broker/types.ts
|
|
89501
90080
|
var BROKER_ROUTES = [
|
|
@@ -91478,7 +92057,7 @@ function providerForAgent(agentKind) {
|
|
|
91478
92057
|
return agentKind === "CLAUDE" ? "anthropic" : agentKind === "CODEX" ? "openai" : null;
|
|
91479
92058
|
}
|
|
91480
92059
|
var AUDIT_SEGMENT = "audit", STATE_SEGMENT = "state", CODEVIBE_DIR = ".codevibe", AUDIT_FILE_NAME = "audit.jsonl";
|
|
91481
|
-
function
|
|
92060
|
+
function isInsideOrEqual3(child, parent) {
|
|
91482
92061
|
if (child === parent) return !0;
|
|
91483
92062
|
let rel = path80.relative(parent, child);
|
|
91484
92063
|
return rel.length > 0 && !rel.startsWith("..") && !path80.isAbsolute(rel);
|
|
@@ -91527,7 +92106,7 @@ async function assertAuditOutsideWorkdir(auditPath, workdir) {
|
|
|
91527
92106
|
`CP-7 W3: audit leaf "${resolvedAuditPath}" is a symlink that does not resolve (dangling) \u2014 refusing to launch (fail-closed). The audit file must be a regular file in the sibling .codevibe/audit/ tree.`
|
|
91528
92107
|
);
|
|
91529
92108
|
}
|
|
91530
|
-
if (
|
|
92109
|
+
if (isInsideOrEqual3(realAuditDir, realWorkdir) || isInsideOrEqual3(resolvedAuditPath, realWorkdir) || isInsideOrEqual3(resolvedLeafTarget, realWorkdir))
|
|
91531
92110
|
throw new Error(
|
|
91532
92111
|
`CP-7 W3: audit path "${resolvedAuditPath}" (resolved target "${resolvedLeafTarget}") is inside the agent workdir "${realWorkdir}" \u2014 the agent could truncate/forge the forensic record (Stage-1 r1 HIGH fail-closed). The audit MUST live in the sibling .codevibe/audit/ tree, never under .codevibe/state/<group>/<track>/.`
|
|
91533
92112
|
);
|
|
@@ -91653,7 +92232,8 @@ async function engageSubstrate(input) {
|
|
|
91653
92232
|
...agentScratchSpec !== null ? { agentScratch: agentScratchSpec } : {},
|
|
91654
92233
|
// CP-7 W3 — Stage-2 r1 HIGH. The resolved audit dir → A5 trailing deny.
|
|
91655
92234
|
// Undefined when a test injects its own in-memory sink (no real tree).
|
|
91656
|
-
...resolvedAuditDir !== null ? { auditDir: resolvedAuditDir } : {}
|
|
92235
|
+
...resolvedAuditDir !== null ? { auditDir: resolvedAuditDir } : {},
|
|
92236
|
+
...input.writableWorkdir !== void 0 ? { writableWorkdir: input.writableWorkdir } : {}
|
|
91657
92237
|
};
|
|
91658
92238
|
handle = await selection.substrate.launch(spec), logger.info(
|
|
91659
92239
|
`[CP-7] Substrate engaged (tier=${selection.tier}, egress=${handle.egressFidelity}) \u2014 agent is creditless, broker holds the key`,
|
|
@@ -91786,7 +92366,7 @@ async function engageSubstrate(input) {
|
|
|
91786
92366
|
}
|
|
91787
92367
|
var RESOLVER_AGENT_STATE_DIR_SEGMENTS = {
|
|
91788
92368
|
GEMINI: [".gemini"],
|
|
91789
|
-
ANTIGRAVITY: [".gemini"
|
|
92369
|
+
ANTIGRAVITY: [".gemini"]
|
|
91790
92370
|
};
|
|
91791
92371
|
async function engageWriteConfinedResolverSandbox(input) {
|
|
91792
92372
|
let agentKind = input.agentKind;
|
|
@@ -91811,14 +92391,14 @@ async function engageWriteConfinedResolverSandbox(input) {
|
|
|
91811
92391
|
teardown: async () => {
|
|
91812
92392
|
}
|
|
91813
92393
|
};
|
|
91814
|
-
let
|
|
91815
|
-
|
|
92394
|
+
let homedir41 = os49.homedir(), stateDir = path80.join(
|
|
92395
|
+
homedir41,
|
|
91816
92396
|
...RESOLVER_AGENT_STATE_DIR_SEGMENTS[agentKind]
|
|
91817
92397
|
);
|
|
91818
92398
|
await import_node_fs38.promises.mkdir(stateDir, { recursive: !0 }).catch(() => {
|
|
91819
92399
|
});
|
|
91820
92400
|
let env = {}, nodeDir = process.execPath.slice(0, process.execPath.lastIndexOf("/"));
|
|
91821
|
-
env.PATH = `${SANDBOX_DEFAULT_PATH}:${nodeDir}`, env.HOME =
|
|
92401
|
+
env.PATH = `${SANDBOX_DEFAULT_PATH}:${nodeDir}`, env.HOME = homedir41;
|
|
91822
92402
|
let safeSource = input.localeSource ?? {};
|
|
91823
92403
|
for (let key of SAFE_ENV_ALLOWLIST) {
|
|
91824
92404
|
let v = safeSource[key];
|
|
@@ -91838,7 +92418,8 @@ async function engageWriteConfinedResolverSandbox(input) {
|
|
|
91838
92418
|
// The agent's own auth/state home — writable, read-granted (A5: sandbox fs
|
|
91839
92419
|
// == host fs, so sandboxDir == hostDir).
|
|
91840
92420
|
agentConfig: { hostDir: stateDir, sandboxDir: stateDir },
|
|
91841
|
-
networkPosture: "open"
|
|
92421
|
+
networkPosture: "open",
|
|
92422
|
+
writableWorkdir: input.writableWorkdir !== !1
|
|
91842
92423
|
}, handle = await selection.substrate.launch(spec);
|
|
91843
92424
|
return logger.info(
|
|
91844
92425
|
`[A1d] Resolver-confinement row engaged (tier=sandbox_exec, egress=open) \u2014 writes fenced to the disposable workspace; ${agentKind} runs on its own file-based auth (no broker)`,
|
|
@@ -92513,8 +93094,8 @@ function isLocalModelEntitled(entitlement) {
|
|
|
92513
93094
|
}
|
|
92514
93095
|
function localModelArtifactPath(config) {
|
|
92515
93096
|
if (!config.artifactId || !isSafeArtifactId(config.artifactId)) return null;
|
|
92516
|
-
let cacheRoot = import_path5.default.resolve(config.cacheDir), artifactPath = import_path5.default.resolve(cacheRoot, config.artifactId),
|
|
92517
|
-
return !
|
|
93097
|
+
let cacheRoot = import_path5.default.resolve(config.cacheDir), artifactPath = import_path5.default.resolve(cacheRoot, config.artifactId), relative23 = import_path5.default.relative(cacheRoot, artifactPath);
|
|
93098
|
+
return !relative23 || relative23.startsWith("..") || import_path5.default.isAbsolute(relative23) ? null : artifactPath;
|
|
92518
93099
|
}
|
|
92519
93100
|
function isSafeArtifactId(artifactId) {
|
|
92520
93101
|
return artifactId === import_path5.default.basename(artifactId) && artifactId !== "." && artifactId !== ".." && !import_path5.default.isAbsolute(artifactId);
|