@su-record/vibe 4.1.26 → 4.1.27

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.
@@ -6,14 +6,14 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "An AX/FDE harness for Claude Code, Codex CLI and ChatGPT desktop. Say what you need, approve the scenarios once; the harness proves the work by running the checks itself. Memory in plain files, human tokens for irreversible actions, a ledger instead of claims.",
9
- "version": "4.1.26"
9
+ "version": "4.1.27"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "vibe",
14
14
  "source": "./",
15
15
  "description": "An AX/FDE harness for Claude Code, Codex CLI and ChatGPT desktop. Say what you need, approve the scenarios once; the harness proves the work by running the checks itself. Memory in plain files, human tokens for irreversible actions, a ledger instead of claims.",
16
- "version": "4.1.26",
16
+ "version": "4.1.27",
17
17
  "category": "productivity"
18
18
  }
19
19
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe",
3
- "version": "4.1.26",
3
+ "version": "4.1.27",
4
4
  "description": "An AX/FDE harness for Claude Code, Codex CLI and ChatGPT desktop. Say what you need, approve the scenarios once; the harness proves the work by running the checks itself. Memory in plain files, human tokens for irreversible actions, a ledger instead of claims.",
5
5
  "author": {
6
6
  "name": "su-record",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe",
3
- "version": "4.1.26",
3
+ "version": "4.1.27",
4
4
  "description": "An AX/FDE harness for Claude Code, Codex CLI and ChatGPT desktop. Say what you need, approve the scenarios once; the harness proves the work by running the checks itself. Memory in plain files, human tokens for irreversible actions, a ledger instead of claims.",
5
5
  "author": {
6
6
  "name": "su-record",
@@ -92,6 +92,7 @@ function unavailableStatus(root, binding, proof) {
92
92
  try { currentRevision = revision(root); } catch { /* Only fixed diagnostic text leaves the hook. */ }
93
93
  try { waiting = workflow(root).waiting; } catch { /* An unavailable inbox cannot supply question ids. */ }
94
94
  return { root, revision: currentRevision, intent: proof.intentHash, complete: false, fresh: false, snapshotStatus: 'unavailable',
95
+ progress: digest(JSON.stringify({ run: proof.run, snapshotStatus: proof.snapshotStatus, revision: proof.revision })),
95
96
  remaining: proof.scenarios.map(s => s.id), repair: repairData(proof.repair), failures: proof.failures ?? [], waiting, handed: [], graph: binding.scenarios };
96
97
  }
97
98
  function structuralStatus(root, binding) {
@@ -145,10 +146,20 @@ function allHanded(view) {
145
146
  } while (changed);
146
147
  return view.remaining.every(id => covered.has(id));
147
148
  }
149
+ function oncePerState(view, status) {
150
+ try {
151
+ const key = view.progress;
152
+ const raw = readPrivate(view.root, name('guard', view.id), 4096);
153
+ const old = raw ? JSON.parse(raw) : {};
154
+ if (old.key === key) return {};
155
+ writePrivate(view.root, name('guard', view.id), JSON.stringify({ key, count: 1 }));
156
+ return { systemMessage: message(view, status) };
157
+ } catch { return { systemMessage: message(view, 'session guard unavailable; unmet') }; }
158
+ }
148
159
  function stopDecision(payload = {}, env = process.env, cwd = process.cwd()) {
149
160
  const view = sessionStatus(payload, env, cwd);
150
161
  if (view.status !== 'bound') return { systemMessage: message(view, `${view.status}; unmet; use explicit vibe session bind in the intended worktree`) };
151
- if (view.snapshotStatus === 'unavailable') return { systemMessage: message(view, 'explicit-check snapshot unavailable; unmet') };
162
+ if (view.snapshotStatus === 'unavailable') return oncePerState(view, 'explicit-check snapshot unavailable; unmet');
152
163
  if (view.complete) return { systemMessage: message(view, 'verified completion from an explicit check') };
153
164
  if (view.approvalWaiting) return { systemMessage: message(view, 'waiting for approval; unmet') };
154
165
  if (view.abandoned) return { systemMessage: message(view, 'intent abandoned; unmet') };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@su-record/vibe",
3
- "version": "4.1.26",
3
+ "version": "4.1.27",
4
4
  "description": "An AX/FDE harness for Claude Code, Codex CLI and ChatGPT desktop. Say what you need, approve the scenarios once; the harness proves the work by running the checks itself. Memory in plain files, human tokens for irreversible actions, a ledger instead of claims.",
5
5
  "type": "module",
6
6
  "bin": {