@quantiya/codevibe-claude-plugin 2.0.19 → 2.0.20
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/.claude-plugin/plugin.json +1 -1
- 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 +188 -27
- package/node_modules/@quantiya/codevibe-core/package.json +1 -1
- 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;
|
|
@@ -33076,8 +33076,13 @@ function isSameRegisteredRootAuthority(prior, current) {
|
|
|
33076
33076
|
function isSameRootAfterDeviceReincarnation(prior, current) {
|
|
33077
33077
|
return prior.dev !== current.dev && prior.ino === current.ino && prior.version === current.version && prior.canonicalPath === current.canonicalPath && prior.birthtimeNs === current.birthtimeNs;
|
|
33078
33078
|
}
|
|
33079
|
-
async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority, maxStateMarkerBytes, registeredShadowRoots, afterTaskEntry, afterMarkerEntry, afterMarkerStat) {
|
|
33080
|
-
let
|
|
33079
|
+
async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority, maxStateMarkerBytes, registeredShadowRoots, afterTaskEntry, afterMarkerEntry, afterMarkerStat, allowUnrecognizedRegularFiles = !1, allowUnregisteredReferences = !1, allowConcurrentSiblingTeardown = !1) {
|
|
33080
|
+
let retryConcurrentSiblingTeardown = (error, target) => {
|
|
33081
|
+
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");
|
|
33082
|
+
throw allowConcurrentSiblingTeardown && isSiblingChurn ? new Error(
|
|
33083
|
+
`bounded-directory target changed during enumeration: ${target}; ${message}`
|
|
33084
|
+
) : error;
|
|
33085
|
+
}, referenced = /* @__PURE__ */ new Set(), budget = createPathBudget(), taskEntries = await readDirectoryBounded(
|
|
33081
33086
|
stateRoot,
|
|
33082
33087
|
budget,
|
|
33083
33088
|
"physical-copy root reference enumeration",
|
|
@@ -33090,15 +33095,24 @@ async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority
|
|
|
33090
33095
|
);
|
|
33091
33096
|
for (let taskEntry of taskEntries) {
|
|
33092
33097
|
if (isStateRootInfrastructureDirectory(taskEntry.name) || taskEntry.name === SHADOW_ROOT_REGISTRY_FILE) continue;
|
|
33093
|
-
if (!taskEntry.isDirectory() || taskEntry.isSymbolicLink())
|
|
33098
|
+
if (!taskEntry.isDirectory() || taskEntry.isSymbolicLink()) {
|
|
33099
|
+
if (allowUnrecognizedRegularFiles && taskEntry.isFile() && !taskEntry.isSymbolicLink()) continue;
|
|
33094
33100
|
throw new Error("physical-copy root reference state entry changed type");
|
|
33101
|
+
}
|
|
33095
33102
|
let taskId = taskEntry.name, stateDir = path38.join(stateRoot, taskId), enumeratedStateDir = boundedDirectoryStat(taskEntry);
|
|
33096
33103
|
if (!enumeratedStateDir)
|
|
33097
33104
|
throw new Error("physical-copy root reference state entry lacks authority");
|
|
33098
33105
|
await afterTaskEntry?.(stateDir);
|
|
33099
|
-
let stateDirAuthority = await captureWorkspaceRootAuthority(stateDir)
|
|
33106
|
+
let stateDirAuthority = await captureWorkspaceRootAuthority(stateDir).catch(
|
|
33107
|
+
(error) => retryConcurrentSiblingTeardown(
|
|
33108
|
+
error,
|
|
33109
|
+
`sibling state directory ${taskId}`
|
|
33110
|
+
)
|
|
33111
|
+
);
|
|
33100
33112
|
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(
|
|
33113
|
+
throw allowConcurrentSiblingTeardown ? new Error(
|
|
33114
|
+
`bounded-directory target changed during enumeration: sibling state directory ${taskId}`
|
|
33115
|
+
) : new Error("physical-copy root reference state directory changed after enumeration");
|
|
33102
33116
|
let markerEntries = await readDirectoryBounded(
|
|
33103
33117
|
stateDir,
|
|
33104
33118
|
budget,
|
|
@@ -33110,7 +33124,10 @@ async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority
|
|
|
33110
33124
|
rootAuthority: stateRootAuthority,
|
|
33111
33125
|
relativeDirectory: taskId
|
|
33112
33126
|
}
|
|
33113
|
-
)
|
|
33127
|
+
).catch((error) => retryConcurrentSiblingTeardown(
|
|
33128
|
+
error,
|
|
33129
|
+
`sibling state contents ${taskId}`
|
|
33130
|
+
));
|
|
33114
33131
|
for (let markerEntry of markerEntries) {
|
|
33115
33132
|
let isStateMarker = SHADOW_STATE_FILE_RE.test(markerEntry.name), isExposureRetention = SHADOW_EXPOSURE_RETENTION_FILE_RE.test(markerEntry.name);
|
|
33116
33133
|
if (!isStateMarker && !isExposureRetention) continue;
|
|
@@ -33120,38 +33137,55 @@ async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority
|
|
|
33120
33137
|
if (!enumeratedMarker)
|
|
33121
33138
|
throw new Error("physical-copy root reference marker lacks authority");
|
|
33122
33139
|
await afterMarkerEntry?.(stateFile);
|
|
33123
|
-
let read
|
|
33124
|
-
|
|
33125
|
-
|
|
33126
|
-
|
|
33127
|
-
|
|
33128
|
-
|
|
33129
|
-
|
|
33130
|
-
|
|
33140
|
+
let read;
|
|
33141
|
+
try {
|
|
33142
|
+
read = await anchoredReadFileWithinRoot(stateDir, markerEntry.name, {
|
|
33143
|
+
maxBytes: maxStateMarkerBytes,
|
|
33144
|
+
expectedRoot: stateDirAuthority,
|
|
33145
|
+
expectedFile: enumeratedMarker,
|
|
33146
|
+
requireSingleLink: !0,
|
|
33147
|
+
afterStat: () => afterMarkerStat?.(stateFile)
|
|
33148
|
+
});
|
|
33149
|
+
} catch (error) {
|
|
33150
|
+
retryConcurrentSiblingTeardown(
|
|
33151
|
+
error,
|
|
33152
|
+
`sibling marker ${taskId}/${markerEntry.name}`
|
|
33153
|
+
);
|
|
33154
|
+
}
|
|
33155
|
+
if (!read)
|
|
33156
|
+
throw allowConcurrentSiblingTeardown ? new Error(
|
|
33157
|
+
`bounded-directory target changed during enumeration: sibling marker ${taskId}/${markerEntry.name}`
|
|
33158
|
+
) : new Error("physical-copy root reference marker disappeared");
|
|
33131
33159
|
let decoded = read.bytes.toString("utf8");
|
|
33132
33160
|
if (!Buffer.from(decoded, "utf8").equals(read.bytes))
|
|
33133
33161
|
throw new Error("physical-copy root reference marker is not strict UTF-8");
|
|
33134
33162
|
let value = JSON.parse(decoded);
|
|
33135
33163
|
if (isStateMarker) {
|
|
33136
33164
|
let marker = validateMarkerShape(value, taskId), markerRoot2 = path38.dirname(marker.shadowDir);
|
|
33137
|
-
if (!registeredShadowRoots.has(markerRoot2))
|
|
33165
|
+
if (validateStateMarkerPlacement(marker, stateFile, stateDir, markerRoot2, stateRoot), !registeredShadowRoots.has(markerRoot2)) {
|
|
33166
|
+
if (allowUnregisteredReferences) continue;
|
|
33138
33167
|
throw new Error("physical-copy root reference marker names an unregistered root");
|
|
33139
|
-
|
|
33168
|
+
}
|
|
33169
|
+
referenced.add(markerRoot2);
|
|
33140
33170
|
continue;
|
|
33141
33171
|
}
|
|
33142
33172
|
let preliminary = value;
|
|
33143
33173
|
if (typeof preliminary.finalShadowDir != "string")
|
|
33144
33174
|
throw new Error("physical-copy root exposure marker lacks a shadow path");
|
|
33145
33175
|
let markerRoot = path38.dirname(preliminary.finalShadowDir);
|
|
33146
|
-
if (!registeredShadowRoots.has(markerRoot))
|
|
33176
|
+
if (assertExposureRetentionMarker(value, taskId, stateFile, markerRoot, stateRoot), !registeredShadowRoots.has(markerRoot)) {
|
|
33177
|
+
if (allowUnregisteredReferences) continue;
|
|
33147
33178
|
throw new Error("physical-copy root exposure marker names an unregistered root");
|
|
33148
|
-
|
|
33179
|
+
}
|
|
33180
|
+
referenced.add(markerRoot);
|
|
33149
33181
|
}
|
|
33150
33182
|
}
|
|
33151
33183
|
return referenced;
|
|
33152
33184
|
}
|
|
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)
|
|
33185
|
+
async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, currentShadowRoot, currentShadowRootIdentity, publicationOwnerKey, maxStateMarkerBytes, afterQuotaReferenceTaskEntry, afterQuotaReferenceMarkerEntry, afterQuotaReferenceMarkerStat, failDirectorySync = !1, mode = "register-current", afterQuotaRetirementTargetProof) {
|
|
33186
|
+
let registryPath = path38.join(stateRoot, SHADOW_ROOT_REGISTRY_FILE), expected = await captureAnchoredWritePrecondition(registryPath, 1024 * 1024);
|
|
33187
|
+
if (mode === "retire-current-if-unused" && expected.kind === "absent") return [];
|
|
33188
|
+
let roots = [];
|
|
33155
33189
|
if (expected.kind === "existing") {
|
|
33156
33190
|
let read = await anchoredReadFileWithinRoot(stateRoot, SHADOW_ROOT_REGISTRY_FILE, {
|
|
33157
33191
|
maxBytes: 1048576
|
|
@@ -33171,13 +33205,16 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33171
33205
|
if (consumeMetadataPath(registryBudget, root.path, "physical-copy root registry"), byPath.has(root.path)) throw new Error("physical-copy root registry contains duplicates");
|
|
33172
33206
|
byPath.set(root.path, root);
|
|
33173
33207
|
}
|
|
33174
|
-
let priorCurrent = byPath.get(currentShadowRoot)
|
|
33208
|
+
let priorCurrent = byPath.get(currentShadowRoot);
|
|
33209
|
+
if (mode === "retire-current-if-unused" && !priorCurrent)
|
|
33210
|
+
return roots;
|
|
33211
|
+
let reincarnatedDevice = null;
|
|
33175
33212
|
if (priorCurrent && !isSameRegisteredRootAuthority(priorCurrent, currentShadowRootIdentity))
|
|
33176
33213
|
if (isSameRootAfterDeviceReincarnation(priorCurrent, currentShadowRootIdentity))
|
|
33177
33214
|
reincarnatedDevice = priorCurrent.dev;
|
|
33178
33215
|
else
|
|
33179
33216
|
throw new Error("physical-copy root changed identity while quota authority is retained");
|
|
33180
|
-
if (priorCurrent
|
|
33217
|
+
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
33218
|
let retained = [], scanBudget = createPathBudget(), referencedShadowRoots = null, hasPhysicalCopyEntry = async (candidate) => {
|
|
33182
33219
|
let liveRoot;
|
|
33183
33220
|
try {
|
|
@@ -33192,7 +33229,7 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33192
33229
|
"physical-copy root retirement enumeration",
|
|
33193
33230
|
candidate.path,
|
|
33194
33231
|
{ rootAuthority: liveRoot, relativeDirectory: "" }
|
|
33195
|
-
)).some((entry) =>
|
|
33232
|
+
)).some((entry) => SHADOW_DIR_RE.test(entry.name) || SHADOW_STAGING_DIR_RE.test(entry.name) || SHADOW_TREE_TOMBSTONE_RE.test(entry.name));
|
|
33196
33233
|
return await assertWorkspaceRootAuthority(
|
|
33197
33234
|
liveRoot.canonicalPath,
|
|
33198
33235
|
liveRoot,
|
|
@@ -33207,6 +33244,42 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33207
33244
|
afterQuotaReferenceMarkerEntry,
|
|
33208
33245
|
afterQuotaReferenceMarkerStat
|
|
33209
33246
|
), !referencedShadowRoots.has(candidate.path));
|
|
33247
|
+
if (mode === "retire-current-if-unused") {
|
|
33248
|
+
let candidate = priorCurrent;
|
|
33249
|
+
if (await assertWorkspaceRootAuthority(
|
|
33250
|
+
currentShadowRoot,
|
|
33251
|
+
currentShadowRootIdentity,
|
|
33252
|
+
"physical-copy current-root retirement preflight"
|
|
33253
|
+
), await hasPhysicalCopyEntry(candidate) || (referencedShadowRoots = await collectDurablyReferencedShadowRoots(
|
|
33254
|
+
stateRoot,
|
|
33255
|
+
stateRootIdentity,
|
|
33256
|
+
maxStateMarkerBytes,
|
|
33257
|
+
new Set(byPath.keys()),
|
|
33258
|
+
afterQuotaReferenceTaskEntry,
|
|
33259
|
+
afterQuotaReferenceMarkerEntry,
|
|
33260
|
+
afterQuotaReferenceMarkerStat,
|
|
33261
|
+
!0,
|
|
33262
|
+
!0,
|
|
33263
|
+
!0
|
|
33264
|
+
), referencedShadowRoots.has(candidate.path))) return roots;
|
|
33265
|
+
let retirementPostimage = roots.filter((root) => root.path !== currentShadowRoot);
|
|
33266
|
+
return await hasPhysicalCopyEntry(candidate) ? roots : (await afterQuotaRetirementTargetProof?.(currentShadowRoot), await assertWorkspaceRootAuthority(
|
|
33267
|
+
currentShadowRoot,
|
|
33268
|
+
currentShadowRootIdentity,
|
|
33269
|
+
"physical-copy current-root retirement commit"
|
|
33270
|
+
), await anchoredAtomicWrite(
|
|
33271
|
+
registryPath,
|
|
33272
|
+
JSON.stringify({ version: 2, roots: retirementPostimage }),
|
|
33273
|
+
{
|
|
33274
|
+
expected,
|
|
33275
|
+
expectedParent: stateRootIdentity,
|
|
33276
|
+
mode: 384,
|
|
33277
|
+
maxTargetBytes: 1024 * 1024,
|
|
33278
|
+
failDirectorySync,
|
|
33279
|
+
publicationOwnerKey
|
|
33280
|
+
}
|
|
33281
|
+
), retirementPostimage);
|
|
33282
|
+
}
|
|
33210
33283
|
for (let candidate of byPath.values()) {
|
|
33211
33284
|
if (candidate.path === currentShadowRoot) {
|
|
33212
33285
|
retained.push(candidate);
|
|
@@ -33254,6 +33327,41 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33254
33327
|
}
|
|
33255
33328
|
), retained;
|
|
33256
33329
|
}
|
|
33330
|
+
async function retireQuotaShadowRootIfUnused(stateRoot, stateRootIdentity, currentShadowRoot, currentShadowRootIdentity, publicationOwnerKey, maxStateMarkerBytes, afterQuotaReferenceTaskEntry, afterQuotaReferenceMarkerEntry, afterQuotaReferenceMarkerStat, failDirectorySync = !1, afterQuotaRetirementTargetProof) {
|
|
33331
|
+
await assertWorkspaceRootAuthority(
|
|
33332
|
+
stateRoot,
|
|
33333
|
+
stateRootIdentity,
|
|
33334
|
+
"physical-copy root retirement state root"
|
|
33335
|
+
), await assertWorkspaceRootAuthority(
|
|
33336
|
+
currentShadowRoot,
|
|
33337
|
+
currentShadowRootIdentity,
|
|
33338
|
+
"physical-copy root retirement current root"
|
|
33339
|
+
);
|
|
33340
|
+
let quotaLockDir = path38.join(stateRoot, SHADOW_QUOTA_LOCK_DIR), quotaLockRootAuthority = await captureWorkspaceRootAuthority(quotaLockDir);
|
|
33341
|
+
if (path38.dirname(quotaLockRootAuthority.canonicalPath) !== stateRootIdentity.canonicalPath || path38.basename(quotaLockRootAuthority.canonicalPath) !== SHADOW_QUOTA_LOCK_DIR)
|
|
33342
|
+
throw new Error("physical-copy quota-lock directory escaped its state-root authority");
|
|
33343
|
+
return withAnchoredExclusiveLock(
|
|
33344
|
+
path38.join(quotaLockRootAuthority.canonicalPath, SHADOW_QUOTA_LOCK_FILE),
|
|
33345
|
+
async () => !(await withTransientDirectoryEnumerationRetry(() => registerAndListQuotaShadowRoots(
|
|
33346
|
+
stateRoot,
|
|
33347
|
+
stateRootIdentity,
|
|
33348
|
+
currentShadowRoot,
|
|
33349
|
+
currentShadowRootIdentity,
|
|
33350
|
+
publicationOwnerKey,
|
|
33351
|
+
maxStateMarkerBytes,
|
|
33352
|
+
afterQuotaReferenceTaskEntry,
|
|
33353
|
+
afterQuotaReferenceMarkerEntry,
|
|
33354
|
+
afterQuotaReferenceMarkerStat,
|
|
33355
|
+
failDirectorySync,
|
|
33356
|
+
"retire-current-if-unused",
|
|
33357
|
+
afterQuotaRetirementTargetProof
|
|
33358
|
+
), {
|
|
33359
|
+
maxAttempts: 8,
|
|
33360
|
+
retryDelaysMs: [10, 25, 50, 100, 200, 400, 800]
|
|
33361
|
+
})).some((candidate) => candidate.path === currentShadowRoot),
|
|
33362
|
+
{ expectedParent: quotaLockRootAuthority }
|
|
33363
|
+
);
|
|
33364
|
+
}
|
|
33257
33365
|
async function readCleanupBlockAnchor(shadowDir, expected) {
|
|
33258
33366
|
try {
|
|
33259
33367
|
if (shadowDir !== expected.snapshotRootAuthority.canonicalPath)
|
|
@@ -33792,6 +33900,24 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
33792
33900
|
stateRootAuthority,
|
|
33793
33901
|
resolveStateMarkerByteLimit(env)
|
|
33794
33902
|
).catch(() => {
|
|
33903
|
+
}), await registerAndListQuotaShadowRoots(
|
|
33904
|
+
stateRoot,
|
|
33905
|
+
stateRootIdentity,
|
|
33906
|
+
shadowRoot,
|
|
33907
|
+
shadowRootIdentity,
|
|
33908
|
+
publicationOwnerKey,
|
|
33909
|
+
resolveStateMarkerByteLimit(env),
|
|
33910
|
+
env.afterQuotaReferenceTaskEntry,
|
|
33911
|
+
env.afterQuotaReferenceMarkerEntry,
|
|
33912
|
+
env.afterQuotaReferenceMarkerStat,
|
|
33913
|
+
env.failQuotaRegistryDirectorySync === !0,
|
|
33914
|
+
"retire-current-if-unused"
|
|
33915
|
+
).catch((retirementErr) => {
|
|
33916
|
+
logger.warn("[WorkspaceShadow] failed-create root retirement deferred", {
|
|
33917
|
+
taskId,
|
|
33918
|
+
shadowRoot,
|
|
33919
|
+
err: retirementErr instanceof Error ? retirementErr.message : String(retirementErr)
|
|
33920
|
+
});
|
|
33795
33921
|
}), err;
|
|
33796
33922
|
}
|
|
33797
33923
|
},
|
|
@@ -34300,12 +34426,15 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
34300
34426
|
this.snapshotRootAuthority
|
|
34301
34427
|
);
|
|
34302
34428
|
if (displaced && displaced.canonicalPath !== this.shadowDir) {
|
|
34303
|
-
await this.discardDisplacedSnapshot(opts);
|
|
34429
|
+
await this.discardDisplacedSnapshot(opts), await this.retirePhysicalCopyRootIfUnused();
|
|
34304
34430
|
return;
|
|
34305
34431
|
}
|
|
34306
34432
|
if (snapshotPathError.code === "ENOENT") {
|
|
34307
|
-
if (await this.exactStateResourcesAreRetired())
|
|
34308
|
-
|
|
34433
|
+
if (await this.exactStateResourcesAreRetired()) {
|
|
34434
|
+
await this.retirePhysicalCopyRootIfUnused();
|
|
34435
|
+
return;
|
|
34436
|
+
}
|
|
34437
|
+
await this.discardDisplacedSnapshot(opts), await this.retirePhysicalCopyRootIfUnused();
|
|
34309
34438
|
return;
|
|
34310
34439
|
}
|
|
34311
34440
|
if (snapshotPathError.code !== "ENOENT")
|
|
@@ -34341,7 +34470,10 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
34341
34470
|
opts.applyingAuthorityRetired === !0,
|
|
34342
34471
|
snapshotAuthority
|
|
34343
34472
|
);
|
|
34344
|
-
if (!disposalSnapshot)
|
|
34473
|
+
if (!disposalSnapshot) {
|
|
34474
|
+
await this.retirePhysicalCopyRootIfUnused();
|
|
34475
|
+
return;
|
|
34476
|
+
}
|
|
34345
34477
|
let stateFileIdentity = disposalSnapshot.stateFileIdentity, exposureFile = path39.join(
|
|
34346
34478
|
this.stateDir,
|
|
34347
34479
|
exposureRetentionFileNameForShadow(this.shadowDir)
|
|
@@ -34453,6 +34585,35 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
34453
34585
|
expectedParent: disposalSnapshot.stateRootAuthority
|
|
34454
34586
|
}).catch(() => {
|
|
34455
34587
|
})), treeRemoved && releasePhysicalCopyBytes(this.physicalCopyScope, this.shadowDir), removeError) throw removeError;
|
|
34588
|
+
await this.retirePhysicalCopyRootIfUnused();
|
|
34589
|
+
}
|
|
34590
|
+
async retirePhysicalCopyRootIfUnused() {
|
|
34591
|
+
let shadowRoot = path39.dirname(this.shadowDir);
|
|
34592
|
+
try {
|
|
34593
|
+
let shadowRootAuthority = await captureWorkspaceRootAuthority(shadowRoot);
|
|
34594
|
+
await retireQuotaShadowRootIfUnused(
|
|
34595
|
+
this.stateRootAuthority.canonicalPath,
|
|
34596
|
+
this.stateRootAuthority,
|
|
34597
|
+
shadowRootAuthority.canonicalPath,
|
|
34598
|
+
shadowRootAuthority,
|
|
34599
|
+
workspacePublicationAuthorityOwnerKey(
|
|
34600
|
+
this.stateRootAuthority.canonicalPath,
|
|
34601
|
+
this.taskId
|
|
34602
|
+
),
|
|
34603
|
+
this.maxStateMarkerBytes,
|
|
34604
|
+
this.env.afterQuotaReferenceTaskEntry,
|
|
34605
|
+
this.env.afterQuotaReferenceMarkerEntry,
|
|
34606
|
+
this.env.afterQuotaReferenceMarkerStat,
|
|
34607
|
+
this.env.failQuotaRegistryDirectorySync === !0,
|
|
34608
|
+
this.env.afterQuotaRetirementTargetProof
|
|
34609
|
+
);
|
|
34610
|
+
} catch (err) {
|
|
34611
|
+
logger.warn("[WorkspaceShadow] physical-copy root retirement deferred", {
|
|
34612
|
+
taskId: this.taskId,
|
|
34613
|
+
shadowRoot,
|
|
34614
|
+
err: err instanceof Error ? err.message : String(err)
|
|
34615
|
+
});
|
|
34616
|
+
}
|
|
34456
34617
|
}
|
|
34457
34618
|
retainExposureWriteAuthority(fileAuthority, stateDirAuthority) {
|
|
34458
34619
|
if (!sameWorkspaceRootAuthority(stateDirAuthority, this.stateDirAuthority))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantiya/codevibe-claude-plugin",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.20",
|
|
4
4
|
"description": "Control Claude Code 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.17",
|
|
51
51
|
"@quantiya/quorum-core": "^1.0.1",
|
|
52
52
|
"dotenv": "^16.6.1",
|
|
53
53
|
"express": "^5.1.0",
|