wendkeep 0.38.2 → 0.38.3

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 CHANGED
@@ -4,6 +4,13 @@ All notable changes to **wendkeep** are documented here. Format based on
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project follows
5
5
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.38.3] — 2026-07-12
8
+
9
+ ### Fixed
10
+
11
+ - Sessões do Codex Desktop voltam a ser criadas quando `SessionStart` ou o primeiro `UserPromptSubmit` não fornecem `transcript_path`: o resolvedor usa o UUID canônico de `CODEX_THREAD_ID` e associa o rollout à mesma entrada assim que o transcript materializa.
12
+ - A barreira cross-provider permanece fail-closed: quando `CODEX_THREAD_ID` e `session_meta.payload.session_id` estão presentes, divergência entre eles adia a escrita em vez de contaminar outra sessão.
13
+
7
14
  ## [0.38.2] — 2026-07-12
8
15
 
9
16
  ### Fixed
@@ -39,10 +39,41 @@ function compatible(provider, transcriptProvider) {
39
39
  || (provider === 'claude' && transcriptProvider === 'anthropic');
40
40
  }
41
41
 
42
+ function canonicalUuid(value = '') {
43
+ const id = String(value || '').trim().toLowerCase();
44
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(id) ? id : '';
45
+ }
46
+
42
47
  export function resolveSessionIdentity(vaultBase, input = {}, provider = detectProvider()) {
43
48
  const transcriptPath = input.transcript_path || input.transcriptPath || '';
44
49
  const inspected = inspectTranscriptIdentity(transcriptPath);
45
50
  const hookId = input.session_id || input.sessionId || '';
51
+ const codexThreadId = canonicalUuid(input.codex_thread_id || input.codexThreadId || process.env.CODEX_THREAD_ID || '');
52
+
53
+ // Codex Desktop exposes the stable canonical conversation through
54
+ // CODEX_THREAD_ID even when SessionStart/UserPromptSubmit omit transcript_path.
55
+ // This is safer than the hook session_id (which may rotate on resume). Once the
56
+ // rollout materializes, require both canonical sources to agree.
57
+ const transcriptConversationId = canonicalUuid(inspected.canonicalConversationId);
58
+ if (provider === 'codex' && transcriptConversationId && codexThreadId
59
+ && transcriptConversationId !== codexThreadId) {
60
+ return {
61
+ state: 'deferred', provider, transcriptPath,
62
+ diagnostics: [`CODEX_THREAD_ID diverge do session_id do transcript (${codexThreadId} != ${transcriptConversationId})`],
63
+ };
64
+ }
65
+ if (provider === 'codex' && !inspected.canonicalConversationId && codexThreadId) {
66
+ return {
67
+ state: 'resolved',
68
+ provider,
69
+ canonicalConversationId: codexThreadId,
70
+ hookSessionId: hookId,
71
+ transcriptPath,
72
+ transcriptId: transcriptPath ? basename(transcriptPath, '.jsonl') : codexThreadId,
73
+ parentConversationId: '',
74
+ diagnostics: [],
75
+ };
76
+ }
46
77
 
47
78
  // Claude: input.session_id já é o id canônico e estável da conversa — idêntico
48
79
  // ao sessionId que cada linha do transcript grava. Numa sessão nova o arquivo
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wendkeep",
3
- "version": "0.38.2",
3
+ "version": "0.38.3",
4
4
  "description": "A persistent-memory harness for AI coding agents on your Obsidian vault: turn-by-turn session capture plus a native, zero-dependency spec→change→verify→archive loop (sensor-gated, independent verdict, mutation discrimination). Local-first, agent-agnostic (Claude Code, Codex, Cursor…).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -46,6 +46,6 @@
46
46
  "url": "https://github.com/rogersialves/wendkeep/issues"
47
47
  },
48
48
  "devDependencies": {
49
- "wendkeep": "^0.38.1"
49
+ "wendkeep": "^0.38.2"
50
50
  }
51
51
  }