snipara-companion 3.7.3 → 3.7.4
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/CHANGELOG.md +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +17 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Release notes for `snipara-companion`, newest first.
|
|
4
4
|
|
|
5
|
+
## 3.7.4
|
|
6
|
+
|
|
7
|
+
- Fix hosted workflow session creation by separating logical workflow identity from the server-issued session ID. Reuse persisted IDs for claims and release, scope mappings by project, actor and worktree, and skip hosted claims when session creation fails.
|
|
8
|
+
- Cover session creation, repeated starts, distinct workflows/actors, refusal and lease release.
|
|
9
|
+
|
|
5
10
|
## Unreleased
|
|
6
11
|
|
|
7
12
|
## New In 3.7.3
|
package/dist/index.d.ts
CHANGED
|
@@ -3985,6 +3985,7 @@ interface CollaborationReviewOnlyAcknowledgement {
|
|
|
3985
3985
|
expiresAt: string;
|
|
3986
3986
|
}
|
|
3987
3987
|
interface CollaborationLocalState {
|
|
3988
|
+
workflowSessions?: Record<string, string>;
|
|
3988
3989
|
schemaVersion: "snipara.collaboration.v1";
|
|
3989
3990
|
updatedAt: string;
|
|
3990
3991
|
workSessionId?: string;
|
package/dist/index.js
CHANGED
|
@@ -21495,6 +21495,9 @@ function loadCollaborationState(rootDir = process.cwd()) {
|
|
|
21495
21495
|
schemaVersion: "snipara.collaboration.v1",
|
|
21496
21496
|
updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
21497
21497
|
workSessionId: normalizeOptionalString3(parsed.workSessionId),
|
|
21498
|
+
workflowSessions: Object.fromEntries(Object.entries(parsed.workflowSessions ?? {}).filter(
|
|
21499
|
+
([key, value]) => /^[a-f0-9]{64}$/.test(key) && typeof value === "string" && value.length > 0
|
|
21500
|
+
)),
|
|
21498
21501
|
sessionId: normalizeOptionalString3(parsed.sessionId),
|
|
21499
21502
|
actorId: normalizeOptionalString3(parsed.actorId),
|
|
21500
21503
|
actorType: normalizeActorType(parsed.actorType),
|
|
@@ -21723,26 +21726,32 @@ async function collaborationClaimCommand(options) {
|
|
|
21723
21726
|
}
|
|
21724
21727
|
async function workflowCollaborationStart(options) {
|
|
21725
21728
|
const rootDir = path25.resolve(options.rootDir ?? process.cwd());
|
|
21726
|
-
const
|
|
21729
|
+
const logicalSessionId = workflowWorkSessionId(options.workflowId);
|
|
21727
21730
|
const context = resolveCollaborationContext({
|
|
21728
21731
|
dir: rootDir,
|
|
21729
|
-
workSessionId,
|
|
21730
21732
|
client: "snipara-companion:workflow"
|
|
21731
21733
|
});
|
|
21732
21734
|
const state = loadCollaborationState(rootDir);
|
|
21735
|
+
const sessionKey = workflowSessionKey(context, options.workflowId);
|
|
21736
|
+
const persistedSessionId = state.workflowSessions?.[sessionKey];
|
|
21737
|
+
context.actor.sessionId = `${logicalSessionId}:${sessionKey}`;
|
|
21733
21738
|
const files = normalizeCollaborationFiles(options.files);
|
|
21734
21739
|
const resources = deriveLocalCollaborationResourcesFromFiles(files, rootDir);
|
|
21735
21740
|
const hostedSession = await maybeStartHostedSession(context, {
|
|
21736
|
-
workSessionId,
|
|
21741
|
+
workSessionId: persistedSessionId,
|
|
21737
21742
|
task: options.goal,
|
|
21738
21743
|
files,
|
|
21739
21744
|
resources
|
|
21740
21745
|
});
|
|
21741
21746
|
const session = hostedSession.status === "ok" ? hostedSession.data?.session : void 0;
|
|
21747
|
+
const workSessionId = session?.id ?? persistedSessionId ?? logicalSessionId;
|
|
21748
|
+
if (session) {
|
|
21749
|
+
state.workflowSessions = { ...state.workflowSessions, [sessionKey]: session.id };
|
|
21750
|
+
}
|
|
21742
21751
|
const effectiveResources = hostedSession.status === "ok" ? hostedSession.data?.resources ?? resources : resources;
|
|
21743
21752
|
let hostedClaim = { status: "skipped" };
|
|
21744
21753
|
const shouldClaim = options.mode === "full" || options.mode === "orchestrate";
|
|
21745
|
-
if (shouldClaim && (files.length > 0 || effectiveResources.length > 0)) {
|
|
21754
|
+
if (hostedSession.status === "ok" && shouldClaim && (files.length > 0 || effectiveResources.length > 0)) {
|
|
21746
21755
|
hostedClaim = await maybeCreateHostedLeases(context, {
|
|
21747
21756
|
workSessionId,
|
|
21748
21757
|
files,
|
|
@@ -21800,7 +21809,7 @@ async function workflowCollaborationRelease(options) {
|
|
|
21800
21809
|
client: "snipara-companion:workflow"
|
|
21801
21810
|
});
|
|
21802
21811
|
const state = loadCollaborationState(rootDir);
|
|
21803
|
-
const targetSessionId = options.workflowId ? workflowWorkSessionId(options.workflowId) : state.workSessionId;
|
|
21812
|
+
const targetSessionId = options.workflowId ? state.workflowSessions?.[workflowSessionKey(context, options.workflowId)] ?? workflowWorkSessionId(options.workflowId) : state.workSessionId;
|
|
21804
21813
|
const activeLeases = state.leases.filter(
|
|
21805
21814
|
(lease) => lease.status === "ACTIVE" && (lease.workSessionId === targetSessionId || !lease.workSessionId && Boolean(targetSessionId) && state.workSessionId === targetSessionId)
|
|
21806
21815
|
);
|
|
@@ -22767,6 +22776,9 @@ function expireLocalLeases(state, now = /* @__PURE__ */ new Date()) {
|
|
|
22767
22776
|
state.updatedAt = now.toISOString();
|
|
22768
22777
|
}
|
|
22769
22778
|
}
|
|
22779
|
+
function workflowSessionKey(context, workflowId) {
|
|
22780
|
+
return (0, import_node_crypto13.createHash)("sha256").update(JSON.stringify([context.config.apiUrl, context.config.projectId, context.actor.actorType, context.actor.actorId, context.worktree, workflowId])).digest("hex");
|
|
22781
|
+
}
|
|
22770
22782
|
function workflowWorkSessionId(workflowId) {
|
|
22771
22783
|
return `workflow:${workflowId}`;
|
|
22772
22784
|
}
|