@quantiya/codevibe-codex-plugin 2.0.22 → 2.0.24
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/node_modules/@quantiya/codevibe-core/dist/index.js +153 -153
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/shadow-protocol.d.ts +2 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/shadow-recovery.d.ts +11 -1
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/workspace-shadow.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.js +205 -38
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/reducer.d.ts +4 -5
- package/node_modules/@quantiya/codevibe-core/package.json +1 -1
- package/node_modules/fs-ext/build/Makefile +1 -1
- package/node_modules/fs-ext/build/Release/fs_ext.node +0 -0
- package/package.json +2 -2
|
@@ -294,6 +294,8 @@ export interface ShadowEnv {
|
|
|
294
294
|
afterQuotaReferenceMarkerEntry?: (filePath: string) => Promise<void> | void;
|
|
295
295
|
/** @internal deterministic replacement seam after a quota-reference marker is opened. */
|
|
296
296
|
afterQuotaReferenceMarkerStat?: (filePath: string) => Promise<void> | void;
|
|
297
|
+
/** @internal deterministic replacement seam after the final target lifecycle scan. */
|
|
298
|
+
afterQuotaRetirementTargetProof?: (shadowRoot: string) => Promise<void> | void;
|
|
297
299
|
/** @internal fail initial/retry shadow-root durability before acknowledgement. */
|
|
298
300
|
failShadowRootDirectorySyncStage?: 'target-child' | 'target-parent';
|
|
299
301
|
/** @internal fail initial/retry state-root durability before acknowledgement. */
|
|
@@ -255,7 +255,17 @@ interface RegisteredShadowRoot extends AnchoredFsIdentity {
|
|
|
255
255
|
* physical shadow root before copying, so the aggregate scan cannot be split by
|
|
256
256
|
* different temp-root configuration.
|
|
257
257
|
*/
|
|
258
|
-
export declare function registerAndListQuotaShadowRoots(stateRoot: string, stateRootIdentity: WorkspaceRootAuthority, currentShadowRoot: string, currentShadowRootIdentity: WorkspaceRootAuthority, publicationOwnerKey: string, maxStateMarkerBytes: number, afterQuotaReferenceTaskEntry?: (stateDir: string) => Promise<void> | void, afterQuotaReferenceMarkerEntry?: (filePath: string) => Promise<void> | void, afterQuotaReferenceMarkerStat?: (filePath: string) => Promise<void> | void, failDirectorySync?: boolean): Promise<RegisteredShadowRoot[]>;
|
|
258
|
+
export declare function registerAndListQuotaShadowRoots(stateRoot: string, stateRootIdentity: WorkspaceRootAuthority, currentShadowRoot: string, currentShadowRootIdentity: WorkspaceRootAuthority, publicationOwnerKey: string, maxStateMarkerBytes: number, afterQuotaReferenceTaskEntry?: (stateDir: string) => Promise<void> | void, afterQuotaReferenceMarkerEntry?: (filePath: string) => Promise<void> | void, afterQuotaReferenceMarkerStat?: (filePath: string) => Promise<void> | void, failDirectorySync?: boolean, mode?: 'register-current' | 'retire-current-if-unused', afterQuotaRetirementTargetProof?: (shadowRoot: string) => Promise<void> | void): Promise<RegisteredShadowRoot[]>;
|
|
259
|
+
/**
|
|
260
|
+
* Retire the exact current shadow-root authority after terminal cleanup.
|
|
261
|
+
*
|
|
262
|
+
* Registration and retirement share the same cross-process quota fence. The
|
|
263
|
+
* current root is removed only when the exact registered directory still
|
|
264
|
+
* exists, contains no generated snapshot/staging/tombstone, and is not named
|
|
265
|
+
* by any durable state or exposure marker. A missing, replaced, renamed, or
|
|
266
|
+
* referenced authority remains fail-closed in `registerAndListQuotaShadowRoots`.
|
|
267
|
+
*/
|
|
268
|
+
export declare function retireQuotaShadowRootIfUnused(stateRoot: string, stateRootIdentity: WorkspaceRootAuthority, currentShadowRoot: string, currentShadowRootIdentity: WorkspaceRootAuthority, publicationOwnerKey: string, maxStateMarkerBytes: number, afterQuotaReferenceTaskEntry?: (stateDir: string) => Promise<void> | void, afterQuotaReferenceMarkerEntry?: (filePath: string) => Promise<void> | void, afterQuotaReferenceMarkerStat?: (filePath: string) => Promise<void> | void, failDirectorySync?: boolean, afterQuotaRetirementTargetProof?: (shadowRoot: string) => Promise<void> | void): Promise<boolean>;
|
|
259
269
|
interface CleanupBlockAnchorRead {
|
|
260
270
|
present: boolean;
|
|
261
271
|
cleanupOwners: ProcessCleanupOwner[];
|
|
@@ -229,6 +229,7 @@ export declare class WorkspaceShadow {
|
|
|
229
229
|
*/
|
|
230
230
|
applyingAuthorityRetired?: boolean;
|
|
231
231
|
}): Promise<void>;
|
|
232
|
+
private retirePhysicalCopyRootIfUnused;
|
|
232
233
|
private retainExposureWriteAuthority;
|
|
233
234
|
private runOwnedStateFileWrite;
|
|
234
235
|
private acceptExposureSnapshot;
|
|
@@ -8410,9 +8410,10 @@ function reduceSessionTaskTerminal(state, event) {
|
|
|
8410
8410
|
if (terminal === null) return state;
|
|
8411
8411
|
let taskId = "taskId" in event ? event.taskId : void 0;
|
|
8412
8412
|
if (!taskId) return state;
|
|
8413
|
-
let existing = state.sessionTasks.get(taskId), sessionTasks = new Map(state.sessionTasks);
|
|
8413
|
+
let runningTasks = new Map(state.runningTasks), evictedRunningTask = runningTasks.delete(taskId), existing = state.sessionTasks.get(taskId), sessionTasks = new Map(state.sessionTasks);
|
|
8414
8414
|
if (existing) {
|
|
8415
|
-
if (existing.origin !== "single" || existing.status !== "running")
|
|
8415
|
+
if (existing.origin !== "single" || existing.status !== "running")
|
|
8416
|
+
return evictedRunningTask ? { ...state, runningTasks } : state;
|
|
8416
8417
|
sessionTasks.set(taskId, { ...existing, status: terminal });
|
|
8417
8418
|
} else
|
|
8418
8419
|
sessionTasks.set(taskId, {
|
|
@@ -8421,7 +8422,7 @@ function reduceSessionTaskTerminal(state, event) {
|
|
|
8421
8422
|
status: terminal,
|
|
8422
8423
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8423
8424
|
});
|
|
8424
|
-
return { ...state, sessionTasks };
|
|
8425
|
+
return { ...state, runningTasks, sessionTasks };
|
|
8425
8426
|
}
|
|
8426
8427
|
var REVIEWER_STATUS_PHASES = /* @__PURE__ */ new Set([
|
|
8427
8428
|
"reviewers_dispatched",
|
|
@@ -8724,9 +8725,9 @@ function reduceClarificationAnswered(state, answer) {
|
|
|
8724
8725
|
};
|
|
8725
8726
|
}
|
|
8726
8727
|
function reduceTaskLifecycle(state, task) {
|
|
8727
|
-
let next = new Map(state.runningTasks);
|
|
8728
|
-
|
|
8729
|
-
let history = new Map(state.sessionTasks)
|
|
8728
|
+
let existing = state.sessionTasks.get(task.taskId), existingIsTerminal = existing?.origin === "single" && (existing.status === "completed" || existing.status === "cancelled" || existing.status === "failed"), incomingIsTerminal = task.status === "completed" || task.status === "cancelled" || task.status === "failed", next = new Map(state.runningTasks);
|
|
8729
|
+
incomingIsTerminal || existingIsTerminal && !incomingIsTerminal ? next.delete(task.taskId) : next.set(task.taskId, task);
|
|
8730
|
+
let history = new Map(state.sessionTasks);
|
|
8730
8731
|
return history.set(task.taskId, {
|
|
8731
8732
|
taskId: task.taskId,
|
|
8732
8733
|
agentKind: task.agentKind,
|
|
@@ -33076,8 +33077,13 @@ function isSameRegisteredRootAuthority(prior, current) {
|
|
|
33076
33077
|
function isSameRootAfterDeviceReincarnation(prior, current) {
|
|
33077
33078
|
return prior.dev !== current.dev && prior.ino === current.ino && prior.version === current.version && prior.canonicalPath === current.canonicalPath && prior.birthtimeNs === current.birthtimeNs;
|
|
33078
33079
|
}
|
|
33079
|
-
async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority, maxStateMarkerBytes, registeredShadowRoots, afterTaskEntry, afterMarkerEntry, afterMarkerStat) {
|
|
33080
|
-
let
|
|
33080
|
+
async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority, maxStateMarkerBytes, registeredShadowRoots, afterTaskEntry, afterMarkerEntry, afterMarkerStat, allowUnrecognizedRegularFiles = !1, allowUnregisteredReferences = !1, allowConcurrentSiblingTeardown = !1) {
|
|
33081
|
+
let retryConcurrentSiblingTeardown = (error, target) => {
|
|
33082
|
+
let code = error?.code, message = error instanceof Error ? error.message : String(error), isSiblingChurn = code === "ENOENT" || message.includes("workspace root changed while opening") || message.includes("workspace root cwd identity mismatch") || message.includes("workspace root changed during authority capture") || message.includes("bounded-directory target identity mismatch") || message.includes("bounded-directory parent changed while opening") || message.includes("bounded-directory parent changed while descending") || message.includes("anchored read root authority unavailable") || message.includes("anchored read root identity mismatch") || message.includes("anchored read root incarnation mismatch") || message.includes("anchored read directory chain changed") || message.includes("anchored read directory changed while descending") || message.includes("anchored read cwd identity mismatch") || message.includes("anchored read file identity mismatch") || message.includes("anchored read file changed during read") || message.includes("anchored read file path changed") || message.includes("anchored read file changed after read");
|
|
33083
|
+
throw allowConcurrentSiblingTeardown && isSiblingChurn ? new Error(
|
|
33084
|
+
`bounded-directory target changed during enumeration: ${target}; ${message}`
|
|
33085
|
+
) : error;
|
|
33086
|
+
}, referenced = /* @__PURE__ */ new Set(), budget = createPathBudget(), taskEntries = await readDirectoryBounded(
|
|
33081
33087
|
stateRoot,
|
|
33082
33088
|
budget,
|
|
33083
33089
|
"physical-copy root reference enumeration",
|
|
@@ -33090,15 +33096,24 @@ async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority
|
|
|
33090
33096
|
);
|
|
33091
33097
|
for (let taskEntry of taskEntries) {
|
|
33092
33098
|
if (isStateRootInfrastructureDirectory(taskEntry.name) || taskEntry.name === SHADOW_ROOT_REGISTRY_FILE) continue;
|
|
33093
|
-
if (!taskEntry.isDirectory() || taskEntry.isSymbolicLink())
|
|
33099
|
+
if (!taskEntry.isDirectory() || taskEntry.isSymbolicLink()) {
|
|
33100
|
+
if (allowUnrecognizedRegularFiles && taskEntry.isFile() && !taskEntry.isSymbolicLink()) continue;
|
|
33094
33101
|
throw new Error("physical-copy root reference state entry changed type");
|
|
33102
|
+
}
|
|
33095
33103
|
let taskId = taskEntry.name, stateDir = path38.join(stateRoot, taskId), enumeratedStateDir = boundedDirectoryStat(taskEntry);
|
|
33096
33104
|
if (!enumeratedStateDir)
|
|
33097
33105
|
throw new Error("physical-copy root reference state entry lacks authority");
|
|
33098
33106
|
await afterTaskEntry?.(stateDir);
|
|
33099
|
-
let stateDirAuthority = await captureWorkspaceRootAuthority(stateDir)
|
|
33107
|
+
let stateDirAuthority = await captureWorkspaceRootAuthority(stateDir).catch(
|
|
33108
|
+
(error) => retryConcurrentSiblingTeardown(
|
|
33109
|
+
error,
|
|
33110
|
+
`sibling state directory ${taskId}`
|
|
33111
|
+
)
|
|
33112
|
+
);
|
|
33100
33113
|
if (stateDirAuthority.dev !== enumeratedStateDir.dev || stateDirAuthority.ino !== enumeratedStateDir.ino || stateDirAuthority.birthtimeNs !== enumeratedStateDir.birthtimeNs || stateDirAuthority.canonicalPath !== enumeratedStateDir.canonicalPath || path38.dirname(stateDirAuthority.canonicalPath) !== stateRoot || path38.basename(stateDirAuthority.canonicalPath) !== taskId)
|
|
33101
|
-
throw new Error(
|
|
33114
|
+
throw allowConcurrentSiblingTeardown ? new Error(
|
|
33115
|
+
`bounded-directory target changed during enumeration: sibling state directory ${taskId}`
|
|
33116
|
+
) : new Error("physical-copy root reference state directory changed after enumeration");
|
|
33102
33117
|
let markerEntries = await readDirectoryBounded(
|
|
33103
33118
|
stateDir,
|
|
33104
33119
|
budget,
|
|
@@ -33110,7 +33125,10 @@ async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority
|
|
|
33110
33125
|
rootAuthority: stateRootAuthority,
|
|
33111
33126
|
relativeDirectory: taskId
|
|
33112
33127
|
}
|
|
33113
|
-
)
|
|
33128
|
+
).catch((error) => retryConcurrentSiblingTeardown(
|
|
33129
|
+
error,
|
|
33130
|
+
`sibling state contents ${taskId}`
|
|
33131
|
+
));
|
|
33114
33132
|
for (let markerEntry of markerEntries) {
|
|
33115
33133
|
let isStateMarker = SHADOW_STATE_FILE_RE.test(markerEntry.name), isExposureRetention = SHADOW_EXPOSURE_RETENTION_FILE_RE.test(markerEntry.name);
|
|
33116
33134
|
if (!isStateMarker && !isExposureRetention) continue;
|
|
@@ -33120,38 +33138,55 @@ async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority
|
|
|
33120
33138
|
if (!enumeratedMarker)
|
|
33121
33139
|
throw new Error("physical-copy root reference marker lacks authority");
|
|
33122
33140
|
await afterMarkerEntry?.(stateFile);
|
|
33123
|
-
let read
|
|
33124
|
-
|
|
33125
|
-
|
|
33126
|
-
|
|
33127
|
-
|
|
33128
|
-
|
|
33129
|
-
|
|
33130
|
-
|
|
33141
|
+
let read;
|
|
33142
|
+
try {
|
|
33143
|
+
read = await anchoredReadFileWithinRoot(stateDir, markerEntry.name, {
|
|
33144
|
+
maxBytes: maxStateMarkerBytes,
|
|
33145
|
+
expectedRoot: stateDirAuthority,
|
|
33146
|
+
expectedFile: enumeratedMarker,
|
|
33147
|
+
requireSingleLink: !0,
|
|
33148
|
+
afterStat: () => afterMarkerStat?.(stateFile)
|
|
33149
|
+
});
|
|
33150
|
+
} catch (error) {
|
|
33151
|
+
retryConcurrentSiblingTeardown(
|
|
33152
|
+
error,
|
|
33153
|
+
`sibling marker ${taskId}/${markerEntry.name}`
|
|
33154
|
+
);
|
|
33155
|
+
}
|
|
33156
|
+
if (!read)
|
|
33157
|
+
throw allowConcurrentSiblingTeardown ? new Error(
|
|
33158
|
+
`bounded-directory target changed during enumeration: sibling marker ${taskId}/${markerEntry.name}`
|
|
33159
|
+
) : new Error("physical-copy root reference marker disappeared");
|
|
33131
33160
|
let decoded = read.bytes.toString("utf8");
|
|
33132
33161
|
if (!Buffer.from(decoded, "utf8").equals(read.bytes))
|
|
33133
33162
|
throw new Error("physical-copy root reference marker is not strict UTF-8");
|
|
33134
33163
|
let value = JSON.parse(decoded);
|
|
33135
33164
|
if (isStateMarker) {
|
|
33136
33165
|
let marker = validateMarkerShape(value, taskId), markerRoot2 = path38.dirname(marker.shadowDir);
|
|
33137
|
-
if (!registeredShadowRoots.has(markerRoot2))
|
|
33166
|
+
if (validateStateMarkerPlacement(marker, stateFile, stateDir, markerRoot2, stateRoot), !registeredShadowRoots.has(markerRoot2)) {
|
|
33167
|
+
if (allowUnregisteredReferences) continue;
|
|
33138
33168
|
throw new Error("physical-copy root reference marker names an unregistered root");
|
|
33139
|
-
|
|
33169
|
+
}
|
|
33170
|
+
referenced.add(markerRoot2);
|
|
33140
33171
|
continue;
|
|
33141
33172
|
}
|
|
33142
33173
|
let preliminary = value;
|
|
33143
33174
|
if (typeof preliminary.finalShadowDir != "string")
|
|
33144
33175
|
throw new Error("physical-copy root exposure marker lacks a shadow path");
|
|
33145
33176
|
let markerRoot = path38.dirname(preliminary.finalShadowDir);
|
|
33146
|
-
if (!registeredShadowRoots.has(markerRoot))
|
|
33177
|
+
if (assertExposureRetentionMarker(value, taskId, stateFile, markerRoot, stateRoot), !registeredShadowRoots.has(markerRoot)) {
|
|
33178
|
+
if (allowUnregisteredReferences) continue;
|
|
33147
33179
|
throw new Error("physical-copy root exposure marker names an unregistered root");
|
|
33148
|
-
|
|
33180
|
+
}
|
|
33181
|
+
referenced.add(markerRoot);
|
|
33149
33182
|
}
|
|
33150
33183
|
}
|
|
33151
33184
|
return referenced;
|
|
33152
33185
|
}
|
|
33153
|
-
async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, currentShadowRoot, currentShadowRootIdentity, publicationOwnerKey, maxStateMarkerBytes, afterQuotaReferenceTaskEntry, afterQuotaReferenceMarkerEntry, afterQuotaReferenceMarkerStat, failDirectorySync = !1) {
|
|
33154
|
-
let registryPath = path38.join(stateRoot, SHADOW_ROOT_REGISTRY_FILE), expected = await captureAnchoredWritePrecondition(registryPath, 1024 * 1024)
|
|
33186
|
+
async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, currentShadowRoot, currentShadowRootIdentity, publicationOwnerKey, maxStateMarkerBytes, afterQuotaReferenceTaskEntry, afterQuotaReferenceMarkerEntry, afterQuotaReferenceMarkerStat, failDirectorySync = !1, mode = "register-current", afterQuotaRetirementTargetProof) {
|
|
33187
|
+
let registryPath = path38.join(stateRoot, SHADOW_ROOT_REGISTRY_FILE), expected = await captureAnchoredWritePrecondition(registryPath, 1024 * 1024);
|
|
33188
|
+
if (mode === "retire-current-if-unused" && expected.kind === "absent") return [];
|
|
33189
|
+
let roots = [];
|
|
33155
33190
|
if (expected.kind === "existing") {
|
|
33156
33191
|
let read = await anchoredReadFileWithinRoot(stateRoot, SHADOW_ROOT_REGISTRY_FILE, {
|
|
33157
33192
|
maxBytes: 1048576
|
|
@@ -33171,13 +33206,16 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33171
33206
|
if (consumeMetadataPath(registryBudget, root.path, "physical-copy root registry"), byPath.has(root.path)) throw new Error("physical-copy root registry contains duplicates");
|
|
33172
33207
|
byPath.set(root.path, root);
|
|
33173
33208
|
}
|
|
33174
|
-
let priorCurrent = byPath.get(currentShadowRoot)
|
|
33209
|
+
let priorCurrent = byPath.get(currentShadowRoot);
|
|
33210
|
+
if (mode === "retire-current-if-unused" && !priorCurrent)
|
|
33211
|
+
return roots;
|
|
33212
|
+
let reincarnatedDevice = null;
|
|
33175
33213
|
if (priorCurrent && !isSameRegisteredRootAuthority(priorCurrent, currentShadowRootIdentity))
|
|
33176
33214
|
if (isSameRootAfterDeviceReincarnation(priorCurrent, currentShadowRootIdentity))
|
|
33177
33215
|
reincarnatedDevice = priorCurrent.dev;
|
|
33178
33216
|
else
|
|
33179
33217
|
throw new Error("physical-copy root changed identity while quota authority is retained");
|
|
33180
|
-
if (priorCurrent
|
|
33218
|
+
if (!priorCurrent && mode === "register-current" && consumeMetadataPath(registryBudget, currentShadowRoot, "physical-copy root registry"), mode === "register-current" && byPath.set(currentShadowRoot, { path: currentShadowRoot, ...currentShadowRootIdentity }), byPath.size > 256) throw new Error("physical-copy root registry exceeds 256 roots");
|
|
33181
33219
|
let retained = [], scanBudget = createPathBudget(), referencedShadowRoots = null, hasPhysicalCopyEntry = async (candidate) => {
|
|
33182
33220
|
let liveRoot;
|
|
33183
33221
|
try {
|
|
@@ -33192,7 +33230,7 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33192
33230
|
"physical-copy root retirement enumeration",
|
|
33193
33231
|
candidate.path,
|
|
33194
33232
|
{ rootAuthority: liveRoot, relativeDirectory: "" }
|
|
33195
|
-
)).some((entry) =>
|
|
33233
|
+
)).some((entry) => SHADOW_DIR_RE.test(entry.name) || SHADOW_STAGING_DIR_RE.test(entry.name) || SHADOW_TREE_TOMBSTONE_RE.test(entry.name));
|
|
33196
33234
|
return await assertWorkspaceRootAuthority(
|
|
33197
33235
|
liveRoot.canonicalPath,
|
|
33198
33236
|
liveRoot,
|
|
@@ -33207,6 +33245,42 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33207
33245
|
afterQuotaReferenceMarkerEntry,
|
|
33208
33246
|
afterQuotaReferenceMarkerStat
|
|
33209
33247
|
), !referencedShadowRoots.has(candidate.path));
|
|
33248
|
+
if (mode === "retire-current-if-unused") {
|
|
33249
|
+
let candidate = priorCurrent;
|
|
33250
|
+
if (await assertWorkspaceRootAuthority(
|
|
33251
|
+
currentShadowRoot,
|
|
33252
|
+
currentShadowRootIdentity,
|
|
33253
|
+
"physical-copy current-root retirement preflight"
|
|
33254
|
+
), await hasPhysicalCopyEntry(candidate) || (referencedShadowRoots = await collectDurablyReferencedShadowRoots(
|
|
33255
|
+
stateRoot,
|
|
33256
|
+
stateRootIdentity,
|
|
33257
|
+
maxStateMarkerBytes,
|
|
33258
|
+
new Set(byPath.keys()),
|
|
33259
|
+
afterQuotaReferenceTaskEntry,
|
|
33260
|
+
afterQuotaReferenceMarkerEntry,
|
|
33261
|
+
afterQuotaReferenceMarkerStat,
|
|
33262
|
+
!0,
|
|
33263
|
+
!0,
|
|
33264
|
+
!0
|
|
33265
|
+
), referencedShadowRoots.has(candidate.path))) return roots;
|
|
33266
|
+
let retirementPostimage = roots.filter((root) => root.path !== currentShadowRoot);
|
|
33267
|
+
return await hasPhysicalCopyEntry(candidate) ? roots : (await afterQuotaRetirementTargetProof?.(currentShadowRoot), await assertWorkspaceRootAuthority(
|
|
33268
|
+
currentShadowRoot,
|
|
33269
|
+
currentShadowRootIdentity,
|
|
33270
|
+
"physical-copy current-root retirement commit"
|
|
33271
|
+
), await anchoredAtomicWrite(
|
|
33272
|
+
registryPath,
|
|
33273
|
+
JSON.stringify({ version: 2, roots: retirementPostimage }),
|
|
33274
|
+
{
|
|
33275
|
+
expected,
|
|
33276
|
+
expectedParent: stateRootIdentity,
|
|
33277
|
+
mode: 384,
|
|
33278
|
+
maxTargetBytes: 1024 * 1024,
|
|
33279
|
+
failDirectorySync,
|
|
33280
|
+
publicationOwnerKey
|
|
33281
|
+
}
|
|
33282
|
+
), retirementPostimage);
|
|
33283
|
+
}
|
|
33210
33284
|
for (let candidate of byPath.values()) {
|
|
33211
33285
|
if (candidate.path === currentShadowRoot) {
|
|
33212
33286
|
retained.push(candidate);
|
|
@@ -33254,6 +33328,41 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33254
33328
|
}
|
|
33255
33329
|
), retained;
|
|
33256
33330
|
}
|
|
33331
|
+
async function retireQuotaShadowRootIfUnused(stateRoot, stateRootIdentity, currentShadowRoot, currentShadowRootIdentity, publicationOwnerKey, maxStateMarkerBytes, afterQuotaReferenceTaskEntry, afterQuotaReferenceMarkerEntry, afterQuotaReferenceMarkerStat, failDirectorySync = !1, afterQuotaRetirementTargetProof) {
|
|
33332
|
+
await assertWorkspaceRootAuthority(
|
|
33333
|
+
stateRoot,
|
|
33334
|
+
stateRootIdentity,
|
|
33335
|
+
"physical-copy root retirement state root"
|
|
33336
|
+
), await assertWorkspaceRootAuthority(
|
|
33337
|
+
currentShadowRoot,
|
|
33338
|
+
currentShadowRootIdentity,
|
|
33339
|
+
"physical-copy root retirement current root"
|
|
33340
|
+
);
|
|
33341
|
+
let quotaLockDir = path38.join(stateRoot, SHADOW_QUOTA_LOCK_DIR), quotaLockRootAuthority = await captureWorkspaceRootAuthority(quotaLockDir);
|
|
33342
|
+
if (path38.dirname(quotaLockRootAuthority.canonicalPath) !== stateRootIdentity.canonicalPath || path38.basename(quotaLockRootAuthority.canonicalPath) !== SHADOW_QUOTA_LOCK_DIR)
|
|
33343
|
+
throw new Error("physical-copy quota-lock directory escaped its state-root authority");
|
|
33344
|
+
return withAnchoredExclusiveLock(
|
|
33345
|
+
path38.join(quotaLockRootAuthority.canonicalPath, SHADOW_QUOTA_LOCK_FILE),
|
|
33346
|
+
async () => !(await withTransientDirectoryEnumerationRetry(() => registerAndListQuotaShadowRoots(
|
|
33347
|
+
stateRoot,
|
|
33348
|
+
stateRootIdentity,
|
|
33349
|
+
currentShadowRoot,
|
|
33350
|
+
currentShadowRootIdentity,
|
|
33351
|
+
publicationOwnerKey,
|
|
33352
|
+
maxStateMarkerBytes,
|
|
33353
|
+
afterQuotaReferenceTaskEntry,
|
|
33354
|
+
afterQuotaReferenceMarkerEntry,
|
|
33355
|
+
afterQuotaReferenceMarkerStat,
|
|
33356
|
+
failDirectorySync,
|
|
33357
|
+
"retire-current-if-unused",
|
|
33358
|
+
afterQuotaRetirementTargetProof
|
|
33359
|
+
), {
|
|
33360
|
+
maxAttempts: 8,
|
|
33361
|
+
retryDelaysMs: [10, 25, 50, 100, 200, 400, 800]
|
|
33362
|
+
})).some((candidate) => candidate.path === currentShadowRoot),
|
|
33363
|
+
{ expectedParent: quotaLockRootAuthority }
|
|
33364
|
+
);
|
|
33365
|
+
}
|
|
33257
33366
|
async function readCleanupBlockAnchor(shadowDir, expected) {
|
|
33258
33367
|
try {
|
|
33259
33368
|
if (shadowDir !== expected.snapshotRootAuthority.canonicalPath)
|
|
@@ -33792,6 +33901,24 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
33792
33901
|
stateRootAuthority,
|
|
33793
33902
|
resolveStateMarkerByteLimit(env)
|
|
33794
33903
|
).catch(() => {
|
|
33904
|
+
}), await registerAndListQuotaShadowRoots(
|
|
33905
|
+
stateRoot,
|
|
33906
|
+
stateRootIdentity,
|
|
33907
|
+
shadowRoot,
|
|
33908
|
+
shadowRootIdentity,
|
|
33909
|
+
publicationOwnerKey,
|
|
33910
|
+
resolveStateMarkerByteLimit(env),
|
|
33911
|
+
env.afterQuotaReferenceTaskEntry,
|
|
33912
|
+
env.afterQuotaReferenceMarkerEntry,
|
|
33913
|
+
env.afterQuotaReferenceMarkerStat,
|
|
33914
|
+
env.failQuotaRegistryDirectorySync === !0,
|
|
33915
|
+
"retire-current-if-unused"
|
|
33916
|
+
).catch((retirementErr) => {
|
|
33917
|
+
logger.warn("[WorkspaceShadow] failed-create root retirement deferred", {
|
|
33918
|
+
taskId,
|
|
33919
|
+
shadowRoot,
|
|
33920
|
+
err: retirementErr instanceof Error ? retirementErr.message : String(retirementErr)
|
|
33921
|
+
});
|
|
33795
33922
|
}), err;
|
|
33796
33923
|
}
|
|
33797
33924
|
},
|
|
@@ -34300,12 +34427,15 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
34300
34427
|
this.snapshotRootAuthority
|
|
34301
34428
|
);
|
|
34302
34429
|
if (displaced && displaced.canonicalPath !== this.shadowDir) {
|
|
34303
|
-
await this.discardDisplacedSnapshot(opts);
|
|
34430
|
+
await this.discardDisplacedSnapshot(opts), await this.retirePhysicalCopyRootIfUnused();
|
|
34304
34431
|
return;
|
|
34305
34432
|
}
|
|
34306
34433
|
if (snapshotPathError.code === "ENOENT") {
|
|
34307
|
-
if (await this.exactStateResourcesAreRetired())
|
|
34308
|
-
|
|
34434
|
+
if (await this.exactStateResourcesAreRetired()) {
|
|
34435
|
+
await this.retirePhysicalCopyRootIfUnused();
|
|
34436
|
+
return;
|
|
34437
|
+
}
|
|
34438
|
+
await this.discardDisplacedSnapshot(opts), await this.retirePhysicalCopyRootIfUnused();
|
|
34309
34439
|
return;
|
|
34310
34440
|
}
|
|
34311
34441
|
if (snapshotPathError.code !== "ENOENT")
|
|
@@ -34341,7 +34471,10 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
34341
34471
|
opts.applyingAuthorityRetired === !0,
|
|
34342
34472
|
snapshotAuthority
|
|
34343
34473
|
);
|
|
34344
|
-
if (!disposalSnapshot)
|
|
34474
|
+
if (!disposalSnapshot) {
|
|
34475
|
+
await this.retirePhysicalCopyRootIfUnused();
|
|
34476
|
+
return;
|
|
34477
|
+
}
|
|
34345
34478
|
let stateFileIdentity = disposalSnapshot.stateFileIdentity, exposureFile = path39.join(
|
|
34346
34479
|
this.stateDir,
|
|
34347
34480
|
exposureRetentionFileNameForShadow(this.shadowDir)
|
|
@@ -34453,6 +34586,35 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
34453
34586
|
expectedParent: disposalSnapshot.stateRootAuthority
|
|
34454
34587
|
}).catch(() => {
|
|
34455
34588
|
})), treeRemoved && releasePhysicalCopyBytes(this.physicalCopyScope, this.shadowDir), removeError) throw removeError;
|
|
34589
|
+
await this.retirePhysicalCopyRootIfUnused();
|
|
34590
|
+
}
|
|
34591
|
+
async retirePhysicalCopyRootIfUnused() {
|
|
34592
|
+
let shadowRoot = path39.dirname(this.shadowDir);
|
|
34593
|
+
try {
|
|
34594
|
+
let shadowRootAuthority = await captureWorkspaceRootAuthority(shadowRoot);
|
|
34595
|
+
await retireQuotaShadowRootIfUnused(
|
|
34596
|
+
this.stateRootAuthority.canonicalPath,
|
|
34597
|
+
this.stateRootAuthority,
|
|
34598
|
+
shadowRootAuthority.canonicalPath,
|
|
34599
|
+
shadowRootAuthority,
|
|
34600
|
+
workspacePublicationAuthorityOwnerKey(
|
|
34601
|
+
this.stateRootAuthority.canonicalPath,
|
|
34602
|
+
this.taskId
|
|
34603
|
+
),
|
|
34604
|
+
this.maxStateMarkerBytes,
|
|
34605
|
+
this.env.afterQuotaReferenceTaskEntry,
|
|
34606
|
+
this.env.afterQuotaReferenceMarkerEntry,
|
|
34607
|
+
this.env.afterQuotaReferenceMarkerStat,
|
|
34608
|
+
this.env.failQuotaRegistryDirectorySync === !0,
|
|
34609
|
+
this.env.afterQuotaRetirementTargetProof
|
|
34610
|
+
);
|
|
34611
|
+
} catch (err) {
|
|
34612
|
+
logger.warn("[WorkspaceShadow] physical-copy root retirement deferred", {
|
|
34613
|
+
taskId: this.taskId,
|
|
34614
|
+
shadowRoot,
|
|
34615
|
+
err: err instanceof Error ? err.message : String(err)
|
|
34616
|
+
});
|
|
34617
|
+
}
|
|
34456
34618
|
}
|
|
34457
34619
|
retainExposureWriteAuthority(fileAuthority, stateDirAuthority) {
|
|
34458
34620
|
if (!sameWorkspaceRootAuthority(stateDirAuthority, this.stateDirAuthority))
|
|
@@ -53232,12 +53394,17 @@ var QuorumLoop = class _QuorumLoop {
|
|
|
53232
53394
|
err: err.message
|
|
53233
53395
|
});
|
|
53234
53396
|
let reason = classifyImplementorRoundFailure(err);
|
|
53235
|
-
this.surfaceHalt(`The task could not proceed \u2014 ${reason}.`)
|
|
53236
|
-
{ phase: "round_failed", round: args.roundNumber, reason, taskId: args.taskId },
|
|
53237
|
-
originEpoch
|
|
53238
|
-
);
|
|
53397
|
+
this.surfaceHalt(`The task could not proceed \u2014 ${reason}.`);
|
|
53239
53398
|
let reviseFeedbackId = args.reviseFeedbackId, preserveResetForRetry = submissionStarted && args.reviewScopeReset === !0 && reviseFeedbackId !== void 0 && this.reviewScopeResetTasks.has(args.taskId);
|
|
53240
|
-
|
|
53399
|
+
this.emitProgress(
|
|
53400
|
+
{
|
|
53401
|
+
phase: "round_failed",
|
|
53402
|
+
round: args.roundNumber,
|
|
53403
|
+
reason,
|
|
53404
|
+
...preserveResetForRetry ? {} : { taskId: args.taskId }
|
|
53405
|
+
},
|
|
53406
|
+
originEpoch
|
|
53407
|
+
), preserveResetForRetry && this.seenReviseFeedbackIds.delete(reviseFeedbackId), await this.discardShadow(args.taskId, void 0, {
|
|
53241
53408
|
preserveReviseContext: preserveResetForRetry
|
|
53242
53409
|
});
|
|
53243
53410
|
} finally {
|
|
@@ -8,10 +8,9 @@ export declare const CONVERSATION_BUFFER_MAX = 500;
|
|
|
8
8
|
export declare function reducer(state: OrchestrationState, action: OrchestrationAction): OrchestrationState;
|
|
9
9
|
/**
|
|
10
10
|
* P10 E3 r6/r8 — "is a single-implementor task actually running?" from the
|
|
11
|
-
* TRUTHFUL `sessionTasks` lifecycle
|
|
12
|
-
* `
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* SET guard below.
|
|
11
|
+
* TRUTHFUL `sessionTasks` lifecycle. Shared by the `/status` running line,
|
|
12
|
+
* `deriveCurrentTaskState` (the planner packet), and the reviewer-line SET
|
|
13
|
+
* guard below. `runningTasks` is terminalized in parallel for its independent
|
|
14
|
+
* task-start size heuristic.
|
|
16
15
|
*/
|
|
17
16
|
export declare function hasRunningSingleTask(state: OrchestrationState): boolean;
|
|
@@ -332,7 +332,7 @@ endif
|
|
|
332
332
|
|
|
333
333
|
quiet_cmd_regen_makefile = ACTION Regenerating $@
|
|
334
334
|
cmd_regen_makefile = cd $(srcdir); /opt/homebrew/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/hendryyeh/Library/Caches/node-gyp/24.4.0" "-Dnode_gyp_dir=/opt/homebrew/lib/node_modules/npm/node_modules/node-gyp" "-Dnode_lib_file=/Users/hendryyeh/Library/Caches/node-gyp/24.4.0/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/hendryyeh/Workspace/CodeVibe/codevibe-codex-plugin/node_modules/fs-ext" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/Users/hendryyeh/Workspace/CodeVibe/codevibe-codex-plugin/node_modules/fs-ext/build/config.gypi -I/opt/homebrew/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/Users/hendryyeh/Library/Caches/node-gyp/24.4.0/include/node/common.gypi "--toplevel-dir=." binding.gyp
|
|
335
|
-
Makefile: $(srcdir)/binding.gyp $(srcdir)/../../../../../Library/Caches/node-gyp/24.4.0/include/node/common.gypi $(srcdir)/../../../../../../../opt/homebrew/lib/node_modules/npm/node_modules/node-gyp/addon.gypi
|
|
335
|
+
Makefile: $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../Library/Caches/node-gyp/24.4.0/include/node/common.gypi $(srcdir)/../../../../../../../opt/homebrew/lib/node_modules/npm/node_modules/node-gyp/addon.gypi
|
|
336
336
|
$(call do_cmd,regen_makefile)
|
|
337
337
|
|
|
338
338
|
# "all" is a concatenation of the "all" targets from all the included
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantiya/codevibe-codex-plugin",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.24",
|
|
4
4
|
"description": "Control OpenAI Codex CLI from your iPhone and Android — real-time sync, approve file edits, send prompts by voice. Part of CodeVibe.",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"codevibe": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"node": ">=22.0.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@quantiya/codevibe-core": "2.0.
|
|
50
|
+
"@quantiya/codevibe-core": "2.0.18",
|
|
51
51
|
"@quantiya/quorum-core": "^1.0.1",
|
|
52
52
|
"chokidar": "^4.0.0",
|
|
53
53
|
"dotenv": "^16.6.1",
|