@quantiya/codevibe-core 2.0.73 → 2.0.74
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/appsync-client.d.ts +4 -1
- package/dist/appsync/sync-operation-journal.d.ts +7 -0
- package/dist/appsync/sync-prompt-retention.d.ts +1 -0
- package/dist/index.js +301 -301
- package/dist/orchestration-shell/cli.js +105 -71
- package/dist/orchestration-shell/task-progress-relay.d.ts +2 -2
- package/package.json +1 -1
|
@@ -10084,9 +10084,7 @@ function createPromptRetentionJournal(store) {
|
|
|
10084
10084
|
await fence(), receipt2.status === "RERAISE_REQUIRED" && (row3.entries.push({ ...receipt2, reRaiseToken: (0, import_node_crypto12.randomUUID)() }), await save(), await settle(promptId2));
|
|
10085
10085
|
}
|
|
10086
10086
|
});
|
|
10087
|
-
}, remove: () => store.
|
|
10088
|
-
await fence(), await store.remove(), await fence();
|
|
10089
|
-
}) });
|
|
10087
|
+
}, remove: () => store.remove() });
|
|
10090
10088
|
}
|
|
10091
10089
|
|
|
10092
10090
|
// src/appsync/sync-prompt-publication.ts
|
|
@@ -10534,19 +10532,10 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
10534
10532
|
let scope = this.sessionScope;
|
|
10535
10533
|
if (!scope) return invalid7();
|
|
10536
10534
|
let id5 = stableUuid("codevibe-sync-desktop-registration-v1\0", [scope.sessionId, scope.sessionGenerationId]);
|
|
10537
|
-
this.
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
let row3 = await this.readValue(id5, key, ".desktop", (value) => decodeDesktopSyncRegistration(value, invalid7));
|
|
10542
|
-
if (!row3) return !1;
|
|
10543
|
-
if (row3.operationId !== id5) return invalid7();
|
|
10544
|
-
if (this.requireScope(row3), this.options.assertAccount(), !await owner.reassertOwnership()) throw new SyncJournalError("SYNC_JOURNAL_LOCK_LOST");
|
|
10545
|
-
return await import_node_fs5.promises.unlink(this.file(id5, ".desktop")), await this.syncDirectory(this.directory), !0;
|
|
10546
|
-
});
|
|
10547
|
-
} finally {
|
|
10548
|
-
await owner.release();
|
|
10549
|
-
}
|
|
10535
|
+
return this.removeBookkeepingRecord(id5, ".desktop", [`registration-${id5}.lockdir`], async (key) => {
|
|
10536
|
+
let row3 = await this.readValue(id5, key, ".desktop", (value) => decodeDesktopSyncRegistration(value, invalid7));
|
|
10537
|
+
return row3 ? row3.operationId !== id5 ? invalid7() : (this.requireScope(row3), !0) : !1;
|
|
10538
|
+
});
|
|
10550
10539
|
}
|
|
10551
10540
|
/** Provider queues share the existing encrypted/account-fenced capacity.
|
|
10552
10541
|
* Native identity and generation are immutable: no automatic re-homing. */
|
|
@@ -10839,13 +10828,12 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
10839
10828
|
let sealed = this.seal(row3, key);
|
|
10840
10829
|
await this.checkCapacity(Buffer.byteLength(sealed), id5 + ".retention"), await this.write(id5, sealed, ".retention");
|
|
10841
10830
|
}),
|
|
10842
|
-
remove:
|
|
10843
|
-
|
|
10844
|
-
|
|
10845
|
-
|
|
10846
|
-
|
|
10847
|
-
|
|
10848
|
-
})
|
|
10831
|
+
remove: async () => {
|
|
10832
|
+
await this.removeBookkeepingRecord(id5, ".retention", ["prompt-retention-" + id5 + ".lockdir"], async (key) => {
|
|
10833
|
+
let row3 = await this.readValue(id5, key, ".retention", decodePromptRetention);
|
|
10834
|
+
return row3 ? row3.operationId !== id5 || !this.matchesScope(row3) ? invalid7() : !0 : !1;
|
|
10835
|
+
});
|
|
10836
|
+
}
|
|
10849
10837
|
});
|
|
10850
10838
|
}
|
|
10851
10839
|
/** Canonical INACTIVE proof and joined publication owners are prerequisites.
|
|
@@ -10909,23 +10897,11 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
10909
10897
|
}
|
|
10910
10898
|
return ids2.sort();
|
|
10911
10899
|
}), removed = 0;
|
|
10912
|
-
for (let id5 of ids)
|
|
10913
|
-
|
|
10914
|
-
|
|
10915
|
-
|
|
10916
|
-
|
|
10917
|
-
if (row3) {
|
|
10918
|
-
if (!deferredScopeMatches(row3, scope)) return invalid7();
|
|
10919
|
-
if (!row3.entries.some((entry5) => entry5.notice)) {
|
|
10920
|
-
if (this.options.assertAccount(), !await owner.reassertOwnership()) throw new SyncJournalError("SYNC_JOURNAL_LOCK_LOST");
|
|
10921
|
-
await import_node_fs5.promises.unlink(this.file(id5, ".deferred")), await this.syncDirectory(this.directory), removed++;
|
|
10922
|
-
}
|
|
10923
|
-
}
|
|
10924
|
-
});
|
|
10925
|
-
} finally {
|
|
10926
|
-
await owner.release();
|
|
10927
|
-
}
|
|
10928
|
-
}
|
|
10900
|
+
for (let id5 of ids)
|
|
10901
|
+
await this.removeBookkeepingRecord(id5, ".deferred", ["deferred-dispatch-" + id5 + ".lockdir"], async (key) => {
|
|
10902
|
+
let row3 = await read(id5, key);
|
|
10903
|
+
return row3 ? deferredScopeMatches(row3, scope) ? !row3.entries.some((entry5) => entry5.notice) : invalid7() : !1;
|
|
10904
|
+
}) && removed++;
|
|
10929
10905
|
return removed;
|
|
10930
10906
|
}
|
|
10931
10907
|
/** One small encrypted row for unresolved inbound inputs. Completed cloud
|
|
@@ -10975,23 +10951,30 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
10975
10951
|
let scope = this.sessionScope;
|
|
10976
10952
|
if (!scope) return invalid7();
|
|
10977
10953
|
let id5 = stableUuid("codevibe-sync-inbound-v1\0", [scope.sessionId, scope.sessionGenerationId]);
|
|
10954
|
+
return this.removeBookkeepingRecord(id5, ".inbox", [`inbound-dispatch-${id5}.lockdir`, `inbound-record-${id5}.lockdir`], async (key) => {
|
|
10955
|
+
let row3 = await this.readValue(id5, key, ".inbox", decodeDesktopInbound);
|
|
10956
|
+
return row3 ? row3.operationId !== id5 ? invalid7() : (this.requireScope(row3), !0) : !1;
|
|
10957
|
+
});
|
|
10958
|
+
}
|
|
10959
|
+
/** The encrypted record is also the recovery index for these outer locks.
|
|
10960
|
+
* Release them strictly BEFORE unlinking it, while the store stays fenced.
|
|
10961
|
+
* A failed release preserves the record and the caller's retirement intent. */
|
|
10962
|
+
async removeBookkeepingRecord(id5, suffix, names, removable) {
|
|
10978
10963
|
this.options.assertAccount(), await this.ensureDirectory();
|
|
10979
|
-
let
|
|
10964
|
+
let owners = [], release = async () => {
|
|
10965
|
+
let failed = (await Promise.allSettled(owners.splice(0).reverse().map((owner) => owner.release()))).find((result) => result.status === "rejected");
|
|
10966
|
+
if (failed?.status === "rejected") throw failed.reason;
|
|
10967
|
+
};
|
|
10980
10968
|
try {
|
|
10981
|
-
let
|
|
10982
|
-
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
return await import_node_fs5.promises.unlink(this.file(id5, ".inbox")), await this.syncDirectory(this.directory), !0;
|
|
10989
|
-
});
|
|
10990
|
-
} finally {
|
|
10991
|
-
await record2.release();
|
|
10992
|
-
}
|
|
10969
|
+
for (let name of names) owners.push(await this.lock(name, !0).acquire());
|
|
10970
|
+
return await this.withStore(async (key, storeFence) => {
|
|
10971
|
+
let remove = await removable(key);
|
|
10972
|
+
this.options.assertAccount();
|
|
10973
|
+
for (let owner of owners) if (!await owner.reassertOwnership()) throw new SyncJournalError("SYNC_JOURNAL_LOCK_LOST");
|
|
10974
|
+
return await release(), await storeFence(), remove ? (await import_node_fs5.promises.unlink(this.file(id5, suffix)), await this.syncDirectory(this.directory), await storeFence(), !0) : !1;
|
|
10975
|
+
});
|
|
10993
10976
|
} finally {
|
|
10994
|
-
await
|
|
10977
|
+
await release();
|
|
10995
10978
|
}
|
|
10996
10979
|
}
|
|
10997
10980
|
/** Exact empty-source GC only after the owner has joined all its emitters
|
|
@@ -11050,7 +11033,34 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11050
11033
|
if (errorCode(error) !== "ENOENT") throw error;
|
|
11051
11034
|
return this.options.assertAccount(), !1;
|
|
11052
11035
|
}
|
|
11053
|
-
return this.withStore(async (key) => (await this.retiredSourcePlan(key, expectedSessionKeyGen)).sources.length > 0);
|
|
11036
|
+
return await this.withStore(async (key) => (await this.retiredSourcePlan(key, expectedSessionKeyGen)).sources.length > 0) ? !0 : this.hasSessionRegistrationState();
|
|
11037
|
+
}
|
|
11038
|
+
/** Presence is not deletion authority. Callers still need their joined
|
|
11039
|
+
* terminal owner and fresh retirement confirmation before cleanup. */
|
|
11040
|
+
async hasSessionRegistrationState() {
|
|
11041
|
+
if (!this.sessionScope) return invalid7();
|
|
11042
|
+
this.options.assertAccount();
|
|
11043
|
+
try {
|
|
11044
|
+
await import_node_fs5.promises.lstat(this.directory);
|
|
11045
|
+
} catch (error) {
|
|
11046
|
+
if (errorCode(error) !== "ENOENT") throw error;
|
|
11047
|
+
return this.options.assertAccount(), !1;
|
|
11048
|
+
}
|
|
11049
|
+
return this.withStore(async (key) => {
|
|
11050
|
+
let records = [
|
|
11051
|
+
[".desktop", (value) => decodeDesktopSyncRegistration(value, invalid7)],
|
|
11052
|
+
[".inbox", decodeDesktopInbound],
|
|
11053
|
+
[".retention", decodePromptRetention],
|
|
11054
|
+
[".echo", decodeMobileEcho],
|
|
11055
|
+
[".deferred", decodeDeferredInputs]
|
|
11056
|
+
];
|
|
11057
|
+
for (let [suffix, decode] of records) for (let name of await this.recordNames(suffix)) {
|
|
11058
|
+
let row3 = await this.readValue(name.slice(0, -suffix.length), key, suffix, decode);
|
|
11059
|
+
if (!row3) return invalid7();
|
|
11060
|
+
if (this.matchesScope(row3)) return !0;
|
|
11061
|
+
}
|
|
11062
|
+
return !1;
|
|
11063
|
+
});
|
|
11054
11064
|
}
|
|
11055
11065
|
/** Durable stop/join intent -> confirmed source cleanup -> control ACKs ->
|
|
11056
11066
|
* intent removal. Network I/O never holds the account-store lock. */
|
|
@@ -11976,12 +11986,12 @@ var UUID9 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f
|
|
|
11976
11986
|
throw new SyncEventClientError("INVALID_SYNC_INPUT");
|
|
11977
11987
|
};
|
|
11978
11988
|
function toolWindow(scope, id5, value) {
|
|
11979
|
-
let envelope = ToolActivityOutboxEnvelopeSchema.parse(value);
|
|
11980
|
-
(id5 !== scope.sessionId || envelope.backendSessionId !== id5 || envelope.syncSessionGenerationId !== scope.sessionGenerationId || !/^[A-Za-z0-9_-]{1,128}$/.test(envelope.clientEventId) || !/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$/.test(
|
|
11989
|
+
let envelope = ToolActivityOutboxEnvelopeSchema.parse(value), timestamp5 = /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$/.test(envelope.windowStart) ? envelope.windowStart.slice(0, -1) + ".000Z" : envelope.windowStart;
|
|
11990
|
+
(id5 !== scope.sessionId || envelope.backendSessionId !== id5 || envelope.syncSessionGenerationId !== scope.sessionGenerationId || !/^[A-Za-z0-9_-]{1,128}$/.test(envelope.clientEventId) || !/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$/.test(timestamp5) || !Number.isFinite(Date.parse(timestamp5)) || new Date(timestamp5).toISOString() !== timestamp5) && invalid8();
|
|
11981
11991
|
let bytes = (0, import_node_crypto16.createHash)("sha256").update("codevibe-sync-tool-window-v1\0").update(JSON.stringify([scope.sessionId, scope.sessionGenerationId, envelope.clientEventId])).digest().subarray(0, 16);
|
|
11982
11992
|
bytes[6] = bytes[6] & 15 | 128, bytes[8] = bytes[8] & 63 | 128;
|
|
11983
11993
|
let hex = bytes.toString("hex"), operationId2 = [hex.slice(0, 8), hex.slice(8, 12), hex.slice(12, 16), hex.slice(16, 20), hex.slice(20)].join("-");
|
|
11984
|
-
return { envelope, operationId: operationId2 };
|
|
11994
|
+
return { envelope, operationId: operationId2, timestamp: timestamp5 };
|
|
11985
11995
|
}
|
|
11986
11996
|
async function retireToolActivityWindows(options) {
|
|
11987
11997
|
let scope = { ...options.sessionScope };
|
|
@@ -12004,7 +12014,7 @@ function createToolActivitySyncTransport(options) {
|
|
|
12004
12014
|
protocol: "SYNC_V2",
|
|
12005
12015
|
sessionGenerationId: scope.sessionGenerationId,
|
|
12006
12016
|
send: async (id5, value) => {
|
|
12007
|
-
let { envelope, operationId: operationId2 } = window(id5, value);
|
|
12017
|
+
let { envelope, operationId: operationId2, timestamp: timestamp5 } = window(id5, value);
|
|
12008
12018
|
try {
|
|
12009
12019
|
return await writer.retry(operationId2);
|
|
12010
12020
|
} catch (error) {
|
|
@@ -12017,7 +12027,7 @@ function createToolActivitySyncTransport(options) {
|
|
|
12017
12027
|
...scope,
|
|
12018
12028
|
clientOperationId: operationId2,
|
|
12019
12029
|
type: "TOOL_ACTIVITY",
|
|
12020
|
-
timestamp:
|
|
12030
|
+
timestamp: timestamp5,
|
|
12021
12031
|
expectedSessionKeyGen: context.sessionKeyGen ?? SESSION_KEY_GEN_ABSENT_SENTINEL,
|
|
12022
12032
|
isEncrypted: !0,
|
|
12023
12033
|
encryptionVersion: 1,
|
|
@@ -14503,6 +14513,13 @@ var AppSyncClient = class _AppSyncClient {
|
|
|
14503
14513
|
async retireDesktopSyncRegistration(options, retired) {
|
|
14504
14514
|
let userId = this.getCurrentUserId();
|
|
14505
14515
|
if (this.assertSyncAccount(userId), !retired || retired.userId !== userId || retired.sessionId !== options.sessionId || retired.status !== "INACTIVE" /* INACTIVE */ || retired.sessionGenerationId !== options.sessionGenerationId) throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
|
|
14516
|
+
return this.removeDesktopSyncRegistrationState(options);
|
|
14517
|
+
}
|
|
14518
|
+
/** Both callers have terminal authority and have joined their read owners:
|
|
14519
|
+
* the returned INACTIVE session above, or a freshly confirmed durable intent. */
|
|
14520
|
+
async removeDesktopSyncRegistrationState(options) {
|
|
14521
|
+
let userId = this.getCurrentUserId();
|
|
14522
|
+
this.assertSyncAccount(userId);
|
|
14506
14523
|
let writer = this.desktopSyncWriter({ root: options.root, sessionScope: options }), result = await writer.removeDesktopRegistration();
|
|
14507
14524
|
return await writer.removeInbound(), await writer.removeDeferredInputs(), await writer.removeMobileEchoes(), await writer.promptRetention().remove(), this.assertSyncAccount(userId), result;
|
|
14508
14525
|
}
|
|
@@ -14937,7 +14954,7 @@ var AppSyncClient = class _AppSyncClient {
|
|
|
14937
14954
|
return this.resolvePromptPublication({ sessionId: input.sessionId, promptId: input.promptId }, async () => (await fence(), _AppSyncClient.throwIfAborted(signal), await this.resolveDesktopSyncPrompt(input, signal), await fence(), !0), { ...options, signal });
|
|
14938
14955
|
}
|
|
14939
14956
|
/** Explicit session-owned restart recovery. Inventory is bounded by the
|
|
14940
|
-
* account store's
|
|
14957
|
+
* account store's file cap; empty inventory does no cloud I/O. Reuses
|
|
14941
14958
|
* original ownership/generation, not current Session or encryption state.
|
|
14942
14959
|
* No failure/age/quota condition deletes an outstanding intent. */
|
|
14943
14960
|
recoverPromptResolutions(options, signal) {
|
|
@@ -15108,12 +15125,12 @@ var AppSyncClient = class _AppSyncClient {
|
|
|
15108
15125
|
await work, this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal);
|
|
15109
15126
|
}
|
|
15110
15127
|
async finishRecordedSessionRetirement(record2, options, fence, signal) {
|
|
15111
|
-
let { input } = record2, { root } = options, userId = this.getCurrentUserId(), writer = this.desktopSyncWriter({ root, sessionScope: input })
|
|
15128
|
+
let { input } = record2, { root } = options, userId = this.getCurrentUserId(), writer = this.desktopSyncWriter({ root, sessionScope: input }), confirmed = !1, confirm = async (request3) => {
|
|
15129
|
+
let receipt2 = await this.confirmDesktopSyncRetirement(request3, signal);
|
|
15130
|
+
return confirmed = !0, receipt2;
|
|
15131
|
+
};
|
|
15112
15132
|
await fence(), _AppSyncClient.throwIfAborted(signal);
|
|
15113
|
-
let result = await writer.removeRetiredSources(
|
|
15114
|
-
input.expectedSessionKeyGen,
|
|
15115
|
-
(request3) => this.confirmDesktopSyncRetirement(request3, signal)
|
|
15116
|
-
), cleanupDeferred = !1;
|
|
15133
|
+
let result = await writer.removeRetiredSources(input.expectedSessionKeyGen, confirm), cleanupDeferred = !1;
|
|
15117
15134
|
if (record2.toolOutbox) {
|
|
15118
15135
|
await fence();
|
|
15119
15136
|
let tools = await retireToolActivityWindows({
|
|
@@ -15121,14 +15138,14 @@ var AppSyncClient = class _AppSyncClient {
|
|
|
15121
15138
|
writer,
|
|
15122
15139
|
outbox: new ToolActivityOutbox({ ...record2.toolOutbox, logger }),
|
|
15123
15140
|
expectedSessionKeyGen: input.expectedSessionKeyGen,
|
|
15124
|
-
confirm
|
|
15141
|
+
confirm,
|
|
15125
15142
|
deferIfPaged: options.deferOversizedTools
|
|
15126
15143
|
});
|
|
15127
15144
|
result.sourcesRemoved += tools.windowsRemoved, result.operationsRemoved += tools.operationsRemoved, cleanupDeferred = tools.hasMore === !0;
|
|
15128
15145
|
}
|
|
15129
15146
|
for (let input2 of await writer.promptResolutions())
|
|
15130
15147
|
await fence(), this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), await writer.runPromptResolution(input2, async (saved, fence2) => (await fence2(), await this.resolveDesktopSyncPrompt(saved, signal), await fence2(), !0), { existingOnly: !0 });
|
|
15131
|
-
return await fence(), this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), { ...result, ...cleanupDeferred && { cleanupDeferred: !0 } };
|
|
15148
|
+
return await fence(), this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), await writer.hasSessionRegistrationState() && (confirmed || await confirm(input), await fence(), _AppSyncClient.throwIfAborted(signal), await this.removeDesktopSyncRegistrationState({ ...input, root })), await fence(), this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), { ...result, ...cleanupDeferred && { cleanupDeferred: !0 } };
|
|
15132
15149
|
}
|
|
15133
15150
|
/** Wire-only PROMPT_OWNERSHIP transition. It cannot create an Event. Plugin
|
|
15134
15151
|
* preimage authority does not require the retired Session's encryption key;
|
|
@@ -69151,6 +69168,14 @@ ${section}`);
|
|
|
69151
69168
|
sessionId: this.deps.session.sessionId,
|
|
69152
69169
|
summary: summaryModel
|
|
69153
69170
|
}
|
|
69171
|
+
}).then((result) => {
|
|
69172
|
+
if (result.emitted) return;
|
|
69173
|
+
let code = result.error?.code;
|
|
69174
|
+
logger.warn("[QuorumLoop] Companion audit summary was not acknowledged (non-fatal)", {
|
|
69175
|
+
taskId,
|
|
69176
|
+
reason: result.reason,
|
|
69177
|
+
...typeof code == "string" && /^[A-Z][A-Z0-9_]{0,79}$/.test(code) ? { errorCode: code } : {}
|
|
69178
|
+
});
|
|
69154
69179
|
}).catch((wErr) => {
|
|
69155
69180
|
logger.warn("[QuorumLoop] Companion audit summary emission failed (non-fatal)", {
|
|
69156
69181
|
taskId,
|
|
@@ -81268,9 +81293,9 @@ function createTaskProgressRelay(deps) {
|
|
|
81268
81293
|
let minIntervalMs = deps.minIntervalMs ?? DEFAULT_MIN_RELAY_INTERVAL_MS, lastRelayedAt = 0, lastMessage = null, lastPhase = null, lastTaskId = null, pendingTimeout = null, pendingFlush = null, emit = async (event, message2) => {
|
|
81269
81294
|
pendingTimeout && (clearTimeout(pendingTimeout), pendingTimeout = null), pendingFlush = null;
|
|
81270
81295
|
let taskId = event.progressTaskId ?? ("taskId" in event && typeof event.taskId == "string" ? event.taskId : void 0);
|
|
81271
|
-
lastRelayedAt = Date.now(), lastMessage = message2, lastPhase = event.phase, lastTaskId = taskId ?? null
|
|
81296
|
+
lastRelayedAt = Date.now(), lastMessage = message2, lastPhase = event.phase, lastTaskId = taskId ?? null;
|
|
81272
81297
|
try {
|
|
81273
|
-
|
|
81298
|
+
let result = await deps.emitShellEvent({
|
|
81274
81299
|
sessionId: deps.sessionId,
|
|
81275
81300
|
type: "NOTIFICATION",
|
|
81276
81301
|
source: "DESKTOP",
|
|
@@ -81282,7 +81307,16 @@ function createTaskProgressRelay(deps) {
|
|
|
81282
81307
|
message: message2,
|
|
81283
81308
|
...taskId ? { taskId } : {}
|
|
81284
81309
|
}
|
|
81285
|
-
})
|
|
81310
|
+
});
|
|
81311
|
+
if (!result.emitted) {
|
|
81312
|
+
let code = result.error?.code;
|
|
81313
|
+
return logger.warn("[task-progress-relay] progress notification was not acknowledged", {
|
|
81314
|
+
phase: event.phase,
|
|
81315
|
+
reason: result.reason,
|
|
81316
|
+
...typeof code == "string" && /^[A-Z][A-Z0-9_]{0,79}$/.test(code) ? { errorCode: code } : {}
|
|
81317
|
+
}), !1;
|
|
81318
|
+
}
|
|
81319
|
+
return RUNTIME_LABELLED_PHASES.has(event.phase) ? logger.info("[task-progress-relay] relayed", { phase: event.phase, message: message2 }) : logger.debug("[task-progress-relay] relayed", { phase: event.phase }), !0;
|
|
81286
81320
|
} catch (err) {
|
|
81287
81321
|
return logger.debug("[task-progress-relay] failed to emit progress notification (non-fatal)", {
|
|
81288
81322
|
phase: event.phase,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { TaskProgressEvent } from './task-progress';
|
|
2
|
-
import type { ShellEventEmit } from './emit-shell-event';
|
|
2
|
+
import type { ShellEventEmit, ShellEventEmitResult } from './emit-shell-event';
|
|
3
3
|
export interface TaskProgressRelayDeps {
|
|
4
|
-
emitShellEvent: (args: ShellEventEmit) => Promise<
|
|
4
|
+
emitShellEvent: (args: ShellEventEmit) => Promise<ShellEventEmitResult>;
|
|
5
5
|
sessionId: string;
|
|
6
6
|
minIntervalMs?: number;
|
|
7
7
|
}
|
package/package.json
CHANGED