instar 1.2.67 → 1.2.68

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.
Files changed (45) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +50 -1
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/PostUpdateMigrator.d.ts +12 -0
  5. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  6. package/dist/core/PostUpdateMigrator.js +138 -0
  7. package/dist/core/PostUpdateMigrator.js.map +1 -1
  8. package/dist/core/SessionManager.d.ts.map +1 -1
  9. package/dist/core/SessionManager.js +3 -0
  10. package/dist/core/SessionManager.js.map +1 -1
  11. package/dist/providers/adapters/anthropic-headless/transport/agenticSessionHeadless.d.ts.map +1 -1
  12. package/dist/providers/adapters/anthropic-headless/transport/agenticSessionHeadless.js +1 -0
  13. package/dist/providers/adapters/anthropic-headless/transport/agenticSessionHeadless.js.map +1 -1
  14. package/dist/providers/adapters/openai-codex/transport/agenticSessionHeadless.d.ts.map +1 -1
  15. package/dist/providers/adapters/openai-codex/transport/agenticSessionHeadless.js +1 -0
  16. package/dist/providers/adapters/openai-codex/transport/agenticSessionHeadless.js.map +1 -1
  17. package/dist/providers/adapters/openai-codex/transport/codexSpawn.d.ts +2 -0
  18. package/dist/providers/adapters/openai-codex/transport/codexSpawn.d.ts.map +1 -1
  19. package/dist/providers/adapters/openai-codex/transport/codexSpawn.js +4 -0
  20. package/dist/providers/adapters/openai-codex/transport/codexSpawn.js.map +1 -1
  21. package/dist/server/AgentServer.d.ts +4 -0
  22. package/dist/server/AgentServer.d.ts.map +1 -1
  23. package/dist/server/AgentServer.js +2 -0
  24. package/dist/server/AgentServer.js.map +1 -1
  25. package/dist/server/routes.d.ts +6 -0
  26. package/dist/server/routes.d.ts.map +1 -1
  27. package/dist/server/routes.js +60 -1
  28. package/dist/server/routes.js.map +1 -1
  29. package/dist/threadline/ConversationStore.d.ts +158 -0
  30. package/dist/threadline/ConversationStore.d.ts.map +1 -0
  31. package/dist/threadline/ConversationStore.js +341 -0
  32. package/dist/threadline/ConversationStore.js.map +1 -0
  33. package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
  34. package/dist/threadline/ThreadlineRouter.js +24 -0
  35. package/dist/threadline/ThreadlineRouter.js.map +1 -1
  36. package/dist/threadline/WarrantsReplyGate.d.ts +110 -0
  37. package/dist/threadline/WarrantsReplyGate.d.ts.map +1 -0
  38. package/dist/threadline/WarrantsReplyGate.js +263 -0
  39. package/dist/threadline/WarrantsReplyGate.js.map +1 -0
  40. package/dist/threadline/mcp-http-client.d.ts.map +1 -1
  41. package/dist/threadline/mcp-http-client.js +6 -0
  42. package/dist/threadline/mcp-http-client.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/data/builtin-manifest.json +63 -63
  45. package/upgrades/1.2.68.md +97 -0
@@ -104,6 +104,18 @@ export declare class PostUpdateMigrator {
104
104
  */
105
105
  private migrateBootWrapperAbiCheck;
106
106
  private migrateStaleLifelineSignal;
107
+ /**
108
+ * Threadline Phase 1 keystone (THREADLINE-CONVERSATION-KEYSTONE-SPEC, Migration
109
+ * parity): fold the legacy thread-resume-map.json + context-thread-map.json
110
+ * into the unified conversations.json so in-flight conversations survive the
111
+ * update with their turn/binding context. Idempotent (skips a threadId already
112
+ * present in conversations.json — never clobbers runtime-written rows),
113
+ * atomic (tmp + rename), and field-preserving (sessionUuid, agentIdentity,
114
+ * pinned, lifecycle incl. failed/archived, cross-machine fields). Reconciliation
115
+ * rule: the resume entry is authoritative for session binding; the contextId
116
+ * index is attached from the context map (distinct fields, no conflict).
117
+ */
118
+ private migrateThreadlineConversationStore;
107
119
  private migrateBootWrapperToCjs;
108
120
  private migrateConversationalCatalogPlaybookManifest;
109
121
  private migrateWorktreeConvention;
@@ -1 +1 @@
1
- {"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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"}
@@ -156,6 +156,7 @@ export class PostUpdateMigrator {
156
156
  this.migrateBootWrapperToCjs(result);
157
157
  this.migrateBootWrapperAbiCheck(result);
158
158
  this.migrateStaleLifelineSignal(result);
159
+ this.migrateThreadlineConversationStore(result);
159
160
  return result;
160
161
  }
161
162
  /**
@@ -289,6 +290,143 @@ export class PostUpdateMigrator {
289
290
  result.errors.push(`stale-lifeline-signal: ${err instanceof Error ? err.message : String(err)}`);
290
291
  }
291
292
  }
293
+ /**
294
+ * Threadline Phase 1 keystone (THREADLINE-CONVERSATION-KEYSTONE-SPEC, Migration
295
+ * parity): fold the legacy thread-resume-map.json + context-thread-map.json
296
+ * into the unified conversations.json so in-flight conversations survive the
297
+ * update with their turn/binding context. Idempotent (skips a threadId already
298
+ * present in conversations.json — never clobbers runtime-written rows),
299
+ * atomic (tmp + rename), and field-preserving (sessionUuid, agentIdentity,
300
+ * pinned, lifecycle incl. failed/archived, cross-machine fields). Reconciliation
301
+ * rule: the resume entry is authoritative for session binding; the contextId
302
+ * index is attached from the context map (distinct fields, no conflict).
303
+ */
304
+ migrateThreadlineConversationStore(result) {
305
+ const dir = path.join(this.config.stateDir, 'threadline');
306
+ const resumePath = path.join(dir, 'thread-resume-map.json');
307
+ const ctxPath = path.join(dir, 'context-thread-map.json');
308
+ const convPath = path.join(dir, 'conversations.json');
309
+ if (!fs.existsSync(resumePath) && !fs.existsSync(ctxPath)) {
310
+ result.skipped.push('threadline-conversations: no legacy stores to fold');
311
+ return;
312
+ }
313
+ // Load existing unified store (idempotency — never overwrite live rows).
314
+ let store;
315
+ try {
316
+ if (fs.existsSync(convPath)) {
317
+ const parsed = JSON.parse(fs.readFileSync(convPath, 'utf-8'));
318
+ store = (parsed && parsed.version === 1 && parsed.conversations)
319
+ ? parsed
320
+ : { version: 1, conversations: {}, lastModified: new Date().toISOString() };
321
+ }
322
+ else {
323
+ store = { version: 1, conversations: {}, lastModified: new Date().toISOString() };
324
+ }
325
+ }
326
+ catch {
327
+ store = { version: 1, conversations: {}, lastModified: new Date().toISOString() };
328
+ }
329
+ const now = new Date().toISOString();
330
+ let folded = 0;
331
+ // 1) Fold ThreadResumeMap entries (authoritative for session binding).
332
+ try {
333
+ if (fs.existsSync(resumePath)) {
334
+ const resumeMap = JSON.parse(fs.readFileSync(resumePath, 'utf-8'));
335
+ for (const [threadId, e] of Object.entries(resumeMap)) {
336
+ if (!threadId || typeof e !== 'object' || e === null)
337
+ continue;
338
+ if (store.conversations[threadId])
339
+ continue; // idempotent — keep live row
340
+ const remoteAgent = typeof e.remoteAgent === 'string' ? e.remoteAgent : undefined;
341
+ store.conversations[threadId] = {
342
+ threadId,
343
+ version: 0,
344
+ participants: { peers: remoteAgent ? [remoteAgent] : [] },
345
+ remoteAgent,
346
+ state: typeof e.state === 'string' ? e.state : 'idle',
347
+ resolvedAt: e.resolvedAt,
348
+ sessionUuid: typeof e.uuid === 'string' ? e.uuid : undefined,
349
+ boundSessionName: typeof e.sessionName === 'string' ? e.sessionName : undefined,
350
+ boundTopicId: typeof e.originTopicId === 'number' ? e.originTopicId : undefined,
351
+ originSessionName: typeof e.originSessionName === 'string' ? e.originSessionName : undefined,
352
+ spawnMode: e.spawnMode,
353
+ subject: typeof e.subject === 'string' ? e.subject : undefined,
354
+ pinned: e.pinned === true,
355
+ messageCount: typeof e.messageCount === 'number' ? e.messageCount : 0,
356
+ machineOrigin: e.machineOrigin,
357
+ migratedTo: e.migratedTo,
358
+ turnCount: 0,
359
+ createdAt: typeof e.createdAt === 'string' ? e.createdAt : now,
360
+ savedAt: now,
361
+ lastActivityAt: typeof e.lastAccessedAt === 'string' ? e.lastAccessedAt : now,
362
+ };
363
+ folded++;
364
+ }
365
+ }
366
+ }
367
+ catch (err) {
368
+ result.errors.push(`threadline-conversations resume fold: ${err instanceof Error ? err.message : String(err)}`);
369
+ }
370
+ // 2) Attach ContextThreadMap identity bindings (reconciliation: resume entry
371
+ // is authoritative for session binding; contextId index rebuilt from here).
372
+ try {
373
+ if (fs.existsSync(ctxPath)) {
374
+ const ctxFile = JSON.parse(fs.readFileSync(ctxPath, 'utf-8'));
375
+ const mappings = Array.isArray(ctxFile.mappings) ? ctxFile.mappings : [];
376
+ for (const m of mappings) {
377
+ const threadId = typeof m.threadId === 'string' ? m.threadId : undefined;
378
+ if (!threadId)
379
+ continue;
380
+ const existing = store.conversations[threadId];
381
+ if (existing) {
382
+ if (existing.contextId === undefined && typeof m.contextId === 'string')
383
+ existing.contextId = m.contextId;
384
+ if (existing.agentIdentity === undefined && typeof m.agentIdentity === 'string')
385
+ existing.agentIdentity = m.agentIdentity;
386
+ }
387
+ else {
388
+ // Context-only thread (no resume entry) — create a minimal row so the
389
+ // identity binding (hijack guard) is not lost.
390
+ store.conversations[threadId] = {
391
+ threadId, version: 0, participants: { peers: [] },
392
+ state: 'idle', pinned: false, messageCount: 0, turnCount: 0,
393
+ contextId: typeof m.contextId === 'string' ? m.contextId : undefined,
394
+ agentIdentity: typeof m.agentIdentity === 'string' ? m.agentIdentity : undefined,
395
+ createdAt: typeof m.createdAt === 'string' ? m.createdAt : now,
396
+ savedAt: now,
397
+ lastActivityAt: typeof m.lastAccessedAt === 'string' ? m.lastAccessedAt : now,
398
+ };
399
+ folded++;
400
+ }
401
+ }
402
+ }
403
+ }
404
+ catch (err) {
405
+ result.errors.push(`threadline-conversations context fold: ${err instanceof Error ? err.message : String(err)}`);
406
+ }
407
+ if (folded === 0) {
408
+ result.skipped.push('threadline-conversations: nothing new to fold (already migrated)');
409
+ return;
410
+ }
411
+ // Atomic write (backup + tmp + rename).
412
+ try {
413
+ store.lastModified = now;
414
+ fs.mkdirSync(dir, { recursive: true });
415
+ if (fs.existsSync(convPath)) {
416
+ try {
417
+ fs.copyFileSync(convPath, `${convPath}.bak`);
418
+ }
419
+ catch { /* best-effort backup */ }
420
+ }
421
+ const tmp = `${convPath}.migrate-${process.pid}-${Date.now()}.tmp`;
422
+ fs.writeFileSync(tmp, JSON.stringify(store, null, 2) + '\n');
423
+ fs.renameSync(tmp, convPath);
424
+ result.upgraded.push(`threadline-conversations: folded ${folded} legacy thread(s) into conversations.json`);
425
+ }
426
+ catch (err) {
427
+ result.errors.push(`threadline-conversations write: ${err instanceof Error ? err.message : String(err)}`);
428
+ }
429
+ }
292
430
  migrateBootWrapperToCjs(result) {
293
431
  if (process.platform !== 'darwin') {
294
432
  result.skipped.push('boot-wrapper .cjs: non-darwin, no plist to migrate');