@su-record/vibe 4.1.18 → 4.1.20

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 (59) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/README.md +14 -1
  5. package/card.md +2 -2
  6. package/dist/cli/common.js +3 -0
  7. package/dist/cli/common.js.map +1 -1
  8. package/dist/cli/context.js +11 -0
  9. package/dist/cli/context.js.map +1 -0
  10. package/dist/cli/conventions.js +13 -0
  11. package/dist/cli/conventions.js.map +1 -0
  12. package/dist/cli/map.js +59 -0
  13. package/dist/cli/map.js.map +1 -0
  14. package/dist/cli/memory.js +10 -8
  15. package/dist/cli/memory.js.map +1 -1
  16. package/dist/cli/setup.js +6 -2
  17. package/dist/cli/setup.js.map +1 -1
  18. package/dist/cli/work.js +6 -1
  19. package/dist/cli/work.js.map +1 -1
  20. package/dist/cli.js +18 -5
  21. package/dist/cli.js.map +1 -1
  22. package/dist/core/analyze.js +82 -0
  23. package/dist/core/analyze.js.map +1 -0
  24. package/dist/core/capabilities.js +60 -0
  25. package/dist/core/capabilities.js.map +1 -0
  26. package/dist/core/checks/changed.js +17 -3
  27. package/dist/core/checks/changed.js.map +1 -1
  28. package/dist/core/checks/source.js +2 -1
  29. package/dist/core/checks/source.js.map +1 -1
  30. package/dist/core/context.js +206 -0
  31. package/dist/core/context.js.map +1 -0
  32. package/dist/core/conventions.js +149 -0
  33. package/dist/core/conventions.js.map +1 -0
  34. package/dist/core/knowledge.js +9 -3
  35. package/dist/core/knowledge.js.map +1 -1
  36. package/dist/core/ledger.js +53 -3
  37. package/dist/core/ledger.js.map +1 -1
  38. package/dist/core/map/format.js +52 -0
  39. package/dist/core/map/format.js.map +1 -0
  40. package/dist/core/map/imports.js +152 -0
  41. package/dist/core/map/imports.js.map +1 -0
  42. package/dist/core/map/index.js +142 -0
  43. package/dist/core/map/index.js.map +1 -0
  44. package/dist/core/map/symbols.js +123 -0
  45. package/dist/core/map/symbols.js.map +1 -0
  46. package/dist/core/paths.js +4 -0
  47. package/dist/core/paths.js.map +1 -1
  48. package/dist/core/reader.js +17 -3
  49. package/dist/core/reader.js.map +1 -1
  50. package/dist/core/readerSession.js +30 -3
  51. package/dist/core/readerSession.js.map +1 -1
  52. package/dist/core/size.js +13 -9
  53. package/dist/core/size.js.map +1 -1
  54. package/hooks/notify.js +14 -9
  55. package/package.json +1 -1
  56. package/skills/vibe-build/SKILL.md +2 -2
  57. package/skills/vibe-discover/SKILL.md +2 -0
  58. package/skills/vibe-prove/SKILL.md +2 -0
  59. package/skills/vibe-scope/SKILL.md +1 -1
package/hooks/notify.js CHANGED
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Notification hook — it never judges. Always exits 0.
3
+ * Notification hook — it never judges the work; it gates one thing: an irreversible command without a token.
4
4
  *
5
5
  * post PostToolUse(Edit|Write): runs `vibe state --json` and tells the model about a voided DONE or open inbox items.
6
- * pre PreToolUse(Bash): warns on stderr when an irreversible command has no recent authorize record.
6
+ * pre PreToolUse(Bash): an irreversible command with no recent authorize record is blocked (exit 2) under the
7
+ * strict and irreversible token policies, and only warned about under off.
7
8
  * PreToolUse(Read): when the file is over READ_ADVISE_LINES, tells the model that `vibe read <file> --ask`
8
9
  * lets a low-reasoning model read it — advice only, the read goes ahead.
9
10
  *
@@ -72,13 +73,16 @@ function recentAuthorize(action) {
72
73
 
73
74
  if (!fs.existsSync(path.join(root, '.vibe'))) process.exit(0);
74
75
 
75
- function tokensOff() {
76
+ function tokenPolicy() {
76
77
  try {
77
- return JSON.parse(fs.readFileSync(path.join(root, '.vibe', 'config.json'), 'utf-8')).tokens === 'off';
78
+ return JSON.parse(fs.readFileSync(path.join(root, '.vibe', 'config.json'), 'utf-8')).tokens || 'irreversible';
78
79
  } catch {
79
- return false;
80
+ return 'irreversible';
80
81
  }
81
82
  }
83
+ function tokensOff() {
84
+ return tokenPolicy() === 'off';
85
+ }
82
86
 
83
87
  const READ_ADVISE_LINES = Number(process.env.VIBE_READ_ADVISE_LINES || 400);
84
88
 
@@ -96,7 +100,7 @@ function adviseRead(payload) {
96
100
  if (!file) return;
97
101
  const lines = countLines(path.resolve(root, file));
98
102
  if (lines <= READ_ADVISE_LINES) return;
99
- const shown = path.isAbsolute(file) ? path.relative(root, file) || file : file;
103
+ const shown = (path.isAbsolute(file) ? path.relative(root, file) || file : file).split(path.sep).join('/');
100
104
  emitContext(`[vibe] ${shown} is ${lines} lines — when it only has to be understood, not edited or debugged, \`vibe read ${shown} --ask "<question>"\` lets a low-reasoning model read it and returns the answer with line numbers`);
101
105
  }
102
106
 
@@ -106,12 +110,13 @@ if (mode === 'pre') {
106
110
  adviseRead(payload);
107
111
  process.exit(0);
108
112
  }
109
- if (tokensOff()) process.exit(0);
110
113
  const command = String((payload.tool_input && payload.tool_input.command) || '');
114
+ // Under strict and irreversible the gate blocks (exit 2 stops the tool call in Claude Code); under off it only warns.
111
115
  for (const [action, re] of IRREVERSIBLE) {
112
116
  if (re.test(command) && !recentAuthorize(action)) {
113
- process.stderr.write(`[vibe] "${action}" is irreversible and no authorize record exists in the last 10 minutes — get a human token with \`vibe ask --needs authorize:${action}\` and run \`vibe authorize\` first\n`);
114
- break;
117
+ const blocking = tokenPolicy() !== 'off';
118
+ process.stderr.write(`[vibe] "${action}" is irreversible and no authorize record exists in the last 10 minutes — ${blocking ? 'blocked: ' : ''}get a human token with \`vibe ask --needs authorize:${action}\` and run \`vibe authorize\` first\n`);
119
+ process.exit(blocking ? 2 : 0);
115
120
  }
116
121
  }
117
122
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@su-record/vibe",
3
- "version": "4.1.18",
3
+ "version": "4.1.20",
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": {
@@ -9,8 +9,8 @@ user-invocable: false
9
9
  ## Procedure
10
10
 
11
11
  1. Take scenarios in the order of `remaining` from `vibe state --json` — parents before their `needs` dependents (`vibe state --graph` shows the edges). Put scenarios marked `irreversible` last.
12
- - Scenarios with no edge between them may be built by parallel agents, each in its own worktree, merged before `vibe check --all`. Never two agents in one working tree.
13
- 2. Build only what that scenario needs — code, a script, a document, configuration, whatever. Make sure the check itself (`check.cmd`, `check.path`) can actually run.
12
+ - Scenarios with no edge between them may be built by parallel agents, each in its own worktree, merged before `vibe check --all`. Never two agents in one working tree. Batch scenarios of one shape into one dispatch; never a nested subagent (a reviewer's reviewer counts for nothing). Hand artifacts to an agent as files, never pasted. When the context is nearly full, start a new session from `.vibe/` instead of compacting.
13
+ 2. Read `vibe context {id}` first — the files and symbols the check touches, the decisions and regressions that touched them, the conventions — then build only what that scenario needs. Make sure the check itself (`check.cmd`, `check.path`) can actually run.
14
14
  - Orientation reads ("what does this module do", "where is X handled") go through `vibe read <files> --ask "<question>"` — a low-reasoning model reads and answers with line numbers; read the file yourself only to edit or debug it.
15
15
  3. Run `vibe check {id} --json`.
16
16
  - Pass (`code 0`): next scenario.
@@ -8,6 +8,8 @@ user-invocable: false
8
8
 
9
9
  ## Procedure
10
10
 
11
+ Order the questions by impact: scope first, then security and privacy, then the reader's or user's experience, then technical detail. A question further down the list is asked only when the earlier ones are settled.
12
+
11
13
  1. Read what the user attached through the harness, so every client sees the same thing:
12
14
  - table (csv · tsv · jsonl · json · xlsx) → `vibe profile {file} --json` [`--sheet`]: columns, types, missing counts, duplicates, up to three anomalies with numbers
13
15
  - document (xlsx · docx · pptx · pdf · hwp · hwpx · html) → `vibe read {file} --json` [`--sheet` · `--pages`]; it says which reader it used (pdf: `pdftotext` when installed, else built-in)
@@ -17,3 +17,5 @@ user-invocable: false
17
17
  ## What DONE means
18
18
 
19
19
  DONE means every gate scenario passed on this exact tree. Changing any file sends the state back to RUNNING; run `vibe check --all` again.
20
+
21
+ On STUCK, read `vibe context {id}` before touching anything — the decisions and regressions around that scenario are usually the reason.
@@ -21,7 +21,7 @@ user-invocable: false
21
21
  3. Save with `vibe intent draft --stdin --json`, sending `{"intent": "...", "scenarios": "..."}` (both in English).
22
22
  - On rejection (`code 1`) fix the reasons and save again. Do not pass by deleting a rejected scenario — bind a check to it.
23
23
  - On success the response contains `token` when the project's token policy is `strict`; otherwise `token` is null and a plain yes in chat is enough.
24
- 4. Research and proposals, once, before the approval message: `vibe research --from-intent --json` (up to five candidates with an action each, what moved in the last 30 days first — `--days N` for another window; skip silently on exit 2 and say "no network") and `vibe skill suggest --json` (up to three). Show both in the approval message. Do not install anything — the user says "add 1" and you run the printed `vibe skill add …` (preview first, `--yes` after they have seen the commands).
24
+ 4. Run `vibe intent analyze` and resolve every `uncovered` bullet (add a scenario or cut the bullet) before asking; an `unrequested` scenario is cut or the bullet is written. Then research and proposals, once, before the approval message: `vibe research --from-intent --json` (up to five candidates with an action each, what moved in the last 30 days first — `--days N` for another window; skip silently on exit 2 and say "no network") and `vibe skill suggest --json` (up to three). Show both in the approval message. Do not install anything — the user says "add 1" and you run the printed `vibe skill add …` (preview first, `--yes` after they have seen the commands). `vibe status` lists the tools vibe would use if present; when the project would use one (a large repository → a symbol graph; a design review → a screenshot tool) put its one-line install in the approval message. A project-local skill is kept only if removing a line of it would make the model err.
25
25
  5. Send **one** approval message:
26
26
 
27
27
  ```