@quantiya/codevibe-claude-plugin 2.0.18 → 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 +176 -175
- 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 +202 -31
- 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;
|
|
@@ -3051,6 +3051,7 @@ var queries = {
|
|
|
3051
3051
|
sessionKeyGen
|
|
3052
3052
|
writerAttestationEligible
|
|
3053
3053
|
creatorSigningKeySha256
|
|
3054
|
+
sessionGenerationId
|
|
3054
3055
|
}
|
|
3055
3056
|
}
|
|
3056
3057
|
`
|
|
@@ -4986,8 +4987,12 @@ var AppSyncClient = class _AppSyncClient {
|
|
|
4986
4987
|
let preparedInput = {
|
|
4987
4988
|
...input,
|
|
4988
4989
|
metadata: input.metadata ? JSON.stringify(input.metadata) : void 0
|
|
4989
|
-
},
|
|
4990
|
-
return logger.info("[AppSyncClient] Session created", {
|
|
4990
|
+
}, session = (await this.graphqlRequest(mutations.createSession, { input: preparedInput })).data.createSession;
|
|
4991
|
+
return logger.info("[AppSyncClient] Session created", {
|
|
4992
|
+
sessionId: session.sessionId,
|
|
4993
|
+
sessionGenerationId: session.sessionGenerationId ?? null,
|
|
4994
|
+
writerAttestationEligible: session.writerAttestationEligible === !0
|
|
4995
|
+
}), session;
|
|
4991
4996
|
}
|
|
4992
4997
|
/**
|
|
4993
4998
|
* Blind-hold one canonical ContextItem. The mutation is idempotent only for
|
|
@@ -33071,8 +33076,13 @@ function isSameRegisteredRootAuthority(prior, current) {
|
|
|
33071
33076
|
function isSameRootAfterDeviceReincarnation(prior, current) {
|
|
33072
33077
|
return prior.dev !== current.dev && prior.ino === current.ino && prior.version === current.version && prior.canonicalPath === current.canonicalPath && prior.birthtimeNs === current.birthtimeNs;
|
|
33073
33078
|
}
|
|
33074
|
-
async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority, maxStateMarkerBytes, registeredShadowRoots, afterTaskEntry, afterMarkerEntry, afterMarkerStat) {
|
|
33075
|
-
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(
|
|
33076
33086
|
stateRoot,
|
|
33077
33087
|
budget,
|
|
33078
33088
|
"physical-copy root reference enumeration",
|
|
@@ -33085,15 +33095,24 @@ async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority
|
|
|
33085
33095
|
);
|
|
33086
33096
|
for (let taskEntry of taskEntries) {
|
|
33087
33097
|
if (isStateRootInfrastructureDirectory(taskEntry.name) || taskEntry.name === SHADOW_ROOT_REGISTRY_FILE) continue;
|
|
33088
|
-
if (!taskEntry.isDirectory() || taskEntry.isSymbolicLink())
|
|
33098
|
+
if (!taskEntry.isDirectory() || taskEntry.isSymbolicLink()) {
|
|
33099
|
+
if (allowUnrecognizedRegularFiles && taskEntry.isFile() && !taskEntry.isSymbolicLink()) continue;
|
|
33089
33100
|
throw new Error("physical-copy root reference state entry changed type");
|
|
33101
|
+
}
|
|
33090
33102
|
let taskId = taskEntry.name, stateDir = path38.join(stateRoot, taskId), enumeratedStateDir = boundedDirectoryStat(taskEntry);
|
|
33091
33103
|
if (!enumeratedStateDir)
|
|
33092
33104
|
throw new Error("physical-copy root reference state entry lacks authority");
|
|
33093
33105
|
await afterTaskEntry?.(stateDir);
|
|
33094
|
-
let stateDirAuthority = await captureWorkspaceRootAuthority(stateDir)
|
|
33106
|
+
let stateDirAuthority = await captureWorkspaceRootAuthority(stateDir).catch(
|
|
33107
|
+
(error) => retryConcurrentSiblingTeardown(
|
|
33108
|
+
error,
|
|
33109
|
+
`sibling state directory ${taskId}`
|
|
33110
|
+
)
|
|
33111
|
+
);
|
|
33095
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)
|
|
33096
|
-
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");
|
|
33097
33116
|
let markerEntries = await readDirectoryBounded(
|
|
33098
33117
|
stateDir,
|
|
33099
33118
|
budget,
|
|
@@ -33105,7 +33124,10 @@ async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority
|
|
|
33105
33124
|
rootAuthority: stateRootAuthority,
|
|
33106
33125
|
relativeDirectory: taskId
|
|
33107
33126
|
}
|
|
33108
|
-
)
|
|
33127
|
+
).catch((error) => retryConcurrentSiblingTeardown(
|
|
33128
|
+
error,
|
|
33129
|
+
`sibling state contents ${taskId}`
|
|
33130
|
+
));
|
|
33109
33131
|
for (let markerEntry of markerEntries) {
|
|
33110
33132
|
let isStateMarker = SHADOW_STATE_FILE_RE.test(markerEntry.name), isExposureRetention = SHADOW_EXPOSURE_RETENTION_FILE_RE.test(markerEntry.name);
|
|
33111
33133
|
if (!isStateMarker && !isExposureRetention) continue;
|
|
@@ -33115,38 +33137,55 @@ async function collectDurablyReferencedShadowRoots(stateRoot, stateRootAuthority
|
|
|
33115
33137
|
if (!enumeratedMarker)
|
|
33116
33138
|
throw new Error("physical-copy root reference marker lacks authority");
|
|
33117
33139
|
await afterMarkerEntry?.(stateFile);
|
|
33118
|
-
let read
|
|
33119
|
-
|
|
33120
|
-
|
|
33121
|
-
|
|
33122
|
-
|
|
33123
|
-
|
|
33124
|
-
|
|
33125
|
-
|
|
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");
|
|
33126
33159
|
let decoded = read.bytes.toString("utf8");
|
|
33127
33160
|
if (!Buffer.from(decoded, "utf8").equals(read.bytes))
|
|
33128
33161
|
throw new Error("physical-copy root reference marker is not strict UTF-8");
|
|
33129
33162
|
let value = JSON.parse(decoded);
|
|
33130
33163
|
if (isStateMarker) {
|
|
33131
33164
|
let marker = validateMarkerShape(value, taskId), markerRoot2 = path38.dirname(marker.shadowDir);
|
|
33132
|
-
if (!registeredShadowRoots.has(markerRoot2))
|
|
33165
|
+
if (validateStateMarkerPlacement(marker, stateFile, stateDir, markerRoot2, stateRoot), !registeredShadowRoots.has(markerRoot2)) {
|
|
33166
|
+
if (allowUnregisteredReferences) continue;
|
|
33133
33167
|
throw new Error("physical-copy root reference marker names an unregistered root");
|
|
33134
|
-
|
|
33168
|
+
}
|
|
33169
|
+
referenced.add(markerRoot2);
|
|
33135
33170
|
continue;
|
|
33136
33171
|
}
|
|
33137
33172
|
let preliminary = value;
|
|
33138
33173
|
if (typeof preliminary.finalShadowDir != "string")
|
|
33139
33174
|
throw new Error("physical-copy root exposure marker lacks a shadow path");
|
|
33140
33175
|
let markerRoot = path38.dirname(preliminary.finalShadowDir);
|
|
33141
|
-
if (!registeredShadowRoots.has(markerRoot))
|
|
33176
|
+
if (assertExposureRetentionMarker(value, taskId, stateFile, markerRoot, stateRoot), !registeredShadowRoots.has(markerRoot)) {
|
|
33177
|
+
if (allowUnregisteredReferences) continue;
|
|
33142
33178
|
throw new Error("physical-copy root exposure marker names an unregistered root");
|
|
33143
|
-
|
|
33179
|
+
}
|
|
33180
|
+
referenced.add(markerRoot);
|
|
33144
33181
|
}
|
|
33145
33182
|
}
|
|
33146
33183
|
return referenced;
|
|
33147
33184
|
}
|
|
33148
|
-
async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, currentShadowRoot, currentShadowRootIdentity, publicationOwnerKey, maxStateMarkerBytes, afterQuotaReferenceTaskEntry, afterQuotaReferenceMarkerEntry, afterQuotaReferenceMarkerStat, failDirectorySync = !1) {
|
|
33149
|
-
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 = [];
|
|
33150
33189
|
if (expected.kind === "existing") {
|
|
33151
33190
|
let read = await anchoredReadFileWithinRoot(stateRoot, SHADOW_ROOT_REGISTRY_FILE, {
|
|
33152
33191
|
maxBytes: 1048576
|
|
@@ -33166,13 +33205,16 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33166
33205
|
if (consumeMetadataPath(registryBudget, root.path, "physical-copy root registry"), byPath.has(root.path)) throw new Error("physical-copy root registry contains duplicates");
|
|
33167
33206
|
byPath.set(root.path, root);
|
|
33168
33207
|
}
|
|
33169
|
-
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;
|
|
33170
33212
|
if (priorCurrent && !isSameRegisteredRootAuthority(priorCurrent, currentShadowRootIdentity))
|
|
33171
33213
|
if (isSameRootAfterDeviceReincarnation(priorCurrent, currentShadowRootIdentity))
|
|
33172
33214
|
reincarnatedDevice = priorCurrent.dev;
|
|
33173
33215
|
else
|
|
33174
33216
|
throw new Error("physical-copy root changed identity while quota authority is retained");
|
|
33175
|
-
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");
|
|
33176
33218
|
let retained = [], scanBudget = createPathBudget(), referencedShadowRoots = null, hasPhysicalCopyEntry = async (candidate) => {
|
|
33177
33219
|
let liveRoot;
|
|
33178
33220
|
try {
|
|
@@ -33187,7 +33229,7 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33187
33229
|
"physical-copy root retirement enumeration",
|
|
33188
33230
|
candidate.path,
|
|
33189
33231
|
{ rootAuthority: liveRoot, relativeDirectory: "" }
|
|
33190
|
-
)).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));
|
|
33191
33233
|
return await assertWorkspaceRootAuthority(
|
|
33192
33234
|
liveRoot.canonicalPath,
|
|
33193
33235
|
liveRoot,
|
|
@@ -33202,6 +33244,42 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33202
33244
|
afterQuotaReferenceMarkerEntry,
|
|
33203
33245
|
afterQuotaReferenceMarkerStat
|
|
33204
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
|
+
}
|
|
33205
33283
|
for (let candidate of byPath.values()) {
|
|
33206
33284
|
if (candidate.path === currentShadowRoot) {
|
|
33207
33285
|
retained.push(candidate);
|
|
@@ -33249,6 +33327,41 @@ async function registerAndListQuotaShadowRoots(stateRoot, stateRootIdentity, cur
|
|
|
33249
33327
|
}
|
|
33250
33328
|
), retained;
|
|
33251
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
|
+
}
|
|
33252
33365
|
async function readCleanupBlockAnchor(shadowDir, expected) {
|
|
33253
33366
|
try {
|
|
33254
33367
|
if (shadowDir !== expected.snapshotRootAuthority.canonicalPath)
|
|
@@ -33787,6 +33900,24 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
33787
33900
|
stateRootAuthority,
|
|
33788
33901
|
resolveStateMarkerByteLimit(env)
|
|
33789
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
|
+
});
|
|
33790
33921
|
}), err;
|
|
33791
33922
|
}
|
|
33792
33923
|
},
|
|
@@ -34295,12 +34426,15 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
34295
34426
|
this.snapshotRootAuthority
|
|
34296
34427
|
);
|
|
34297
34428
|
if (displaced && displaced.canonicalPath !== this.shadowDir) {
|
|
34298
|
-
await this.discardDisplacedSnapshot(opts);
|
|
34429
|
+
await this.discardDisplacedSnapshot(opts), await this.retirePhysicalCopyRootIfUnused();
|
|
34299
34430
|
return;
|
|
34300
34431
|
}
|
|
34301
34432
|
if (snapshotPathError.code === "ENOENT") {
|
|
34302
|
-
if (await this.exactStateResourcesAreRetired())
|
|
34303
|
-
|
|
34433
|
+
if (await this.exactStateResourcesAreRetired()) {
|
|
34434
|
+
await this.retirePhysicalCopyRootIfUnused();
|
|
34435
|
+
return;
|
|
34436
|
+
}
|
|
34437
|
+
await this.discardDisplacedSnapshot(opts), await this.retirePhysicalCopyRootIfUnused();
|
|
34304
34438
|
return;
|
|
34305
34439
|
}
|
|
34306
34440
|
if (snapshotPathError.code !== "ENOENT")
|
|
@@ -34336,7 +34470,10 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
34336
34470
|
opts.applyingAuthorityRetired === !0,
|
|
34337
34471
|
snapshotAuthority
|
|
34338
34472
|
);
|
|
34339
|
-
if (!disposalSnapshot)
|
|
34473
|
+
if (!disposalSnapshot) {
|
|
34474
|
+
await this.retirePhysicalCopyRootIfUnused();
|
|
34475
|
+
return;
|
|
34476
|
+
}
|
|
34340
34477
|
let stateFileIdentity = disposalSnapshot.stateFileIdentity, exposureFile = path39.join(
|
|
34341
34478
|
this.stateDir,
|
|
34342
34479
|
exposureRetentionFileNameForShadow(this.shadowDir)
|
|
@@ -34448,6 +34585,35 @@ var WorkspaceShadow = class _WorkspaceShadow {
|
|
|
34448
34585
|
expectedParent: disposalSnapshot.stateRootAuthority
|
|
34449
34586
|
}).catch(() => {
|
|
34450
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
|
+
}
|
|
34451
34617
|
}
|
|
34452
34618
|
retainExposureWriteAuthority(fileAuthority, stateDirAuthority) {
|
|
34453
34619
|
if (!sameWorkspaceRootAuthority(stateDirAuthority, this.stateDirAuthority))
|
|
@@ -57683,7 +57849,7 @@ async function runOrchestrationShell(args) {
|
|
|
57683
57849
|
}), !0;
|
|
57684
57850
|
}, catchUpDurableGateTimeline = async (isReconnect) => {
|
|
57685
57851
|
if (typeof args.appsyncClient.listSupervisionEvents != "function") return;
|
|
57686
|
-
let nextToken, seenTokens = /* @__PURE__ */ new Set(), newestFirstEvents = [];
|
|
57852
|
+
let nextToken, seenTokens = /* @__PURE__ */ new Set(), newestFirstEvents = [], pageCount = 0;
|
|
57687
57853
|
do {
|
|
57688
57854
|
let page = await args.appsyncClient.listSupervisionEvents({
|
|
57689
57855
|
sessionId: args.session.sessionId,
|
|
@@ -57692,7 +57858,12 @@ async function runOrchestrationShell(args) {
|
|
|
57692
57858
|
...nextToken ? { nextToken } : {},
|
|
57693
57859
|
limit: 100
|
|
57694
57860
|
});
|
|
57695
|
-
if (
|
|
57861
|
+
if (pageCount += 1, pageCount === 1 && logger.info("[orchestration-shell] durable supervision catch-up first page accepted", {
|
|
57862
|
+
sessionId: args.session.sessionId,
|
|
57863
|
+
sessionGenerationId: args.session.sessionGenerationId ?? null,
|
|
57864
|
+
isReconnect,
|
|
57865
|
+
itemCount: page.items.length
|
|
57866
|
+
}), newestFirstEvents.push(...page.items), page.nextToken && seenTokens.has(page.nextToken))
|
|
57696
57867
|
throw new Error("listSupervisionEvents repeated a pagination token");
|
|
57697
57868
|
page.nextToken && seenTokens.add(page.nextToken), nextToken = page.nextToken ?? void 0;
|
|
57698
57869
|
} while (nextToken);
|
|
@@ -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-claude-plugin/node_modules/fs-ext" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/Users/hendryyeh/Workspace/CodeVibe/codevibe-claude-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)/build/config.gypi $(srcdir)/../../../../../../../opt/homebrew/lib/node_modules/npm/node_modules/node-gyp/addon.gypi $(srcdir)/../../../../../Library/Caches/node-gyp/24.4.0/include/node/common.gypi
|
|
335
|
+
Makefile: $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../opt/homebrew/lib/node_modules/npm/node_modules/node-gyp/addon.gypi $(srcdir)/../../../../../Library/Caches/node-gyp/24.4.0/include/node/common.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-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",
|