acuvo-code 0.2.0

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 (154) hide show
  1. package/CHANGELOG.md +328 -0
  2. package/ENTERPRISE.md +927 -0
  3. package/LICENSE +120 -0
  4. package/README.md +1245 -0
  5. package/ROADMAP.md +556 -0
  6. package/bin/acuvo-mcp.mjs +208 -0
  7. package/bin/acuvo.mjs +3108 -0
  8. package/lib/acceptance-consent.mjs +168 -0
  9. package/lib/acceptance.mjs +859 -0
  10. package/lib/account.mjs +226 -0
  11. package/lib/acuvo-dir.mjs +72 -0
  12. package/lib/acuvo-models.mjs +141 -0
  13. package/lib/apply-patch.mjs +570 -0
  14. package/lib/ask-user.mjs +173 -0
  15. package/lib/audit.mjs +530 -0
  16. package/lib/auto-lease.mjs +174 -0
  17. package/lib/background.mjs +842 -0
  18. package/lib/best-of.mjs +334 -0
  19. package/lib/board.mjs +232 -0
  20. package/lib/breaker.mjs +93 -0
  21. package/lib/budget.mjs +1375 -0
  22. package/lib/builtin-skills.mjs +135 -0
  23. package/lib/cache-floor.mjs +204 -0
  24. package/lib/chain.mjs +303 -0
  25. package/lib/changed-paths.mjs +84 -0
  26. package/lib/chat.mjs +434 -0
  27. package/lib/checkpoint.mjs +637 -0
  28. package/lib/child-lifetime.mjs +71 -0
  29. package/lib/cli-args.mjs +1255 -0
  30. package/lib/code-review.mjs +1382 -0
  31. package/lib/colour.mjs +82 -0
  32. package/lib/command.mjs +2847 -0
  33. package/lib/compact.mjs +1151 -0
  34. package/lib/completion.mjs +515 -0
  35. package/lib/creative-engines.mjs +779 -0
  36. package/lib/db-inspect.mjs +1624 -0
  37. package/lib/delete.mjs +111 -0
  38. package/lib/design-loop.mjs +570 -0
  39. package/lib/diff-preview.mjs +1044 -0
  40. package/lib/doctor.mjs +2139 -0
  41. package/lib/dropped.mjs +216 -0
  42. package/lib/edit-diagnostics.mjs +277 -0
  43. package/lib/edit.mjs +460 -0
  44. package/lib/env-file.mjs +250 -0
  45. package/lib/escalate.mjs +702 -0
  46. package/lib/evaluate.mjs +284 -0
  47. package/lib/fetch-text.mjs +952 -0
  48. package/lib/fleet-budget.mjs +256 -0
  49. package/lib/gh.mjs +1536 -0
  50. package/lib/git.mjs +1341 -0
  51. package/lib/github.mjs +261 -0
  52. package/lib/h2.mjs +194 -0
  53. package/lib/handoff.mjs +417 -0
  54. package/lib/hooks.mjs +626 -0
  55. package/lib/http-probe.mjs +907 -0
  56. package/lib/image-director.mjs +322 -0
  57. package/lib/image-edit.mjs +522 -0
  58. package/lib/imagegen.mjs +998 -0
  59. package/lib/interrupt.mjs +234 -0
  60. package/lib/learned.mjs +353 -0
  61. package/lib/lease-watch.mjs +115 -0
  62. package/lib/lease.mjs +868 -0
  63. package/lib/localize.mjs +834 -0
  64. package/lib/log-tail.mjs +1052 -0
  65. package/lib/login.mjs +157 -0
  66. package/lib/lsp.mjs +1613 -0
  67. package/lib/mcp-consent.mjs +377 -0
  68. package/lib/mcp-defaults.mjs +780 -0
  69. package/lib/mcp-server.mjs +1343 -0
  70. package/lib/mcp.mjs +1263 -0
  71. package/lib/media.mjs +1283 -0
  72. package/lib/memory-workspace.mjs +179 -0
  73. package/lib/model-json.mjs +132 -0
  74. package/lib/model-tier.mjs +171 -0
  75. package/lib/model.mjs +1445 -0
  76. package/lib/parallel.mjs +144 -0
  77. package/lib/perchance.mjs +210 -0
  78. package/lib/plan-coherence.mjs +1461 -0
  79. package/lib/plan-ledger.mjs +981 -0
  80. package/lib/plan.mjs +461 -0
  81. package/lib/policy.mjs +783 -0
  82. package/lib/prefix-order.mjs +38 -0
  83. package/lib/project-memory.mjs +127 -0
  84. package/lib/prompt.mjs +109 -0
  85. package/lib/python.mjs +862 -0
  86. package/lib/rcfile.mjs +853 -0
  87. package/lib/read-window.mjs +743 -0
  88. package/lib/refute-tools.mjs +34 -0
  89. package/lib/refute.mjs +806 -0
  90. package/lib/repl-driver.mjs +264 -0
  91. package/lib/repl.mjs +324 -0
  92. package/lib/replay.mjs +1218 -0
  93. package/lib/repo-map.mjs +1101 -0
  94. package/lib/report.mjs +419 -0
  95. package/lib/search-rank.mjs +99 -0
  96. package/lib/search.mjs +659 -0
  97. package/lib/secret-paths.mjs +54 -0
  98. package/lib/session.mjs +1017 -0
  99. package/lib/skills.mjs +703 -0
  100. package/lib/slash.mjs +356 -0
  101. package/lib/spawn-argv.mjs +1151 -0
  102. package/lib/spend.mjs +250 -0
  103. package/lib/steer.mjs +280 -0
  104. package/lib/stream.mjs +253 -0
  105. package/lib/stuck.mjs +712 -0
  106. package/lib/subagent.mjs +749 -0
  107. package/lib/terminal-graphics.mjs +171 -0
  108. package/lib/tool-prefix.mjs +226 -0
  109. package/lib/tool-shortlist.mjs +162 -0
  110. package/lib/tools.mjs +2333 -0
  111. package/lib/tsserver.mjs +423 -0
  112. package/lib/turn.mjs +5672 -0
  113. package/lib/untrusted-block.mjs +271 -0
  114. package/lib/verify-claim.mjs +299 -0
  115. package/lib/vision.mjs +330 -0
  116. package/lib/voice-task.mjs +561 -0
  117. package/lib/warm-provider.mjs +255 -0
  118. package/lib/websearch.mjs +401 -0
  119. package/lib/workspace.mjs +928 -0
  120. package/lib/write-approval.mjs +235 -0
  121. package/lib/write-many.mjs +162 -0
  122. package/package.json +62 -0
  123. package/scripts/bundle.mjs +768 -0
  124. package/scripts/cache-floor.mjs +176 -0
  125. package/scripts/machine.mjs +226 -0
  126. package/scripts/test.mjs +139 -0
  127. package/skills/accessibility.md +87 -0
  128. package/skills/acuvo-design-system.md +123 -0
  129. package/skills/animation.md +84 -0
  130. package/skills/api-design.md +82 -0
  131. package/skills/auth-and-sessions.md +78 -0
  132. package/skills/build-with-a-framework.md +101 -0
  133. package/skills/colour-and-contrast.md +112 -0
  134. package/skills/creative-engines.md +81 -0
  135. package/skills/css-layout.md +85 -0
  136. package/skills/data-and-charts.md +77 -0
  137. package/skills/debugging.md +76 -0
  138. package/skills/designing-by-looking.md +84 -0
  139. package/skills/error-handling.md +78 -0
  140. package/skills/forms-and-validation.md +93 -0
  141. package/skills/nextjs-app-router.md +75 -0
  142. package/skills/page-composition.md +103 -0
  143. package/skills/performance.md +77 -0
  144. package/skills/plan-before-building.md +52 -0
  145. package/skills/planning-and-delegating.md +72 -0
  146. package/skills/refactoring.md +70 -0
  147. package/skills/security-basics.md +76 -0
  148. package/skills/state-management.md +73 -0
  149. package/skills/supabase-multitenant.md +72 -0
  150. package/skills/typescript-strict.md +90 -0
  151. package/skills/typography.md +135 -0
  152. package/skills/verify-your-own-work.md +62 -0
  153. package/skills/web-app-quality.md +62 -0
  154. package/skills/working-in-the-background.md +64 -0
@@ -0,0 +1,115 @@
1
+ /**
2
+ * ── ⚠️⚠️ A LEASE GUARDS THE FILE VERBS. IT CANNOT GUARD CODE THE AGENT RUNS ──
3
+ *
4
+ * `auto-lease.mjs` claims a path on every `write_file` and `delete_file`, so a
5
+ * second terminal is refused rather than silently overwriting the first. That
6
+ * is true, and it is not the whole truth.
7
+ *
8
+ * PROVEN 2026-08-13, two terminals, one checkout:
9
+ *
10
+ * terminal-1 holds src/app.ts
11
+ * terminal-2 write_file src/app.ts -> refused, "held by terminal-1" ✅
12
+ * terminal-2 evaluate (writes it) -> src/app.ts is now "CLOBBERED" ❌
13
+ *
14
+ * `evaluate` and `run_command` start a real process. A process can write
15
+ * anything the user can write, and no in-process guard can prevent that without
16
+ * removing the ability to run code — which is the product.
17
+ *
18
+ * ⭐ SO THE ANSWER IS NOT PREVENTION, IT IS DETECTION, and detection here is
19
+ * cheap for a reason worth stating: **the only files that matter are the ones
20
+ * another terminal has claimed**, and the lease directory lists exactly those.
21
+ * A handful of `statSync` calls, not a walk of the tree. Watching the whole
22
+ * workspace would cost more than the command usually does and would report
23
+ * every build artefact; watching four leased paths costs nothing and reports
24
+ * only the thing somebody needs to know.
25
+ *
26
+ * ⚠️ THIS DOES NOT MAKE THE WRITE SAFE. It makes it LOUD. The other terminal's
27
+ * work is already overwritten by the time this fires — what changes is that
28
+ * somebody finds out immediately, from the run that did it, instead of a week
29
+ * later from a git log. That is the honest thing this layer can offer, and
30
+ * claiming more would be the false-safety problem it exists to correct.
31
+ */
32
+
33
+ import { statSync } from 'node:fs';
34
+ import { join } from 'node:path';
35
+
36
+ import { inspect } from './lease.mjs';
37
+
38
+ /**
39
+ * Fingerprint every path another holder currently owns.
40
+ *
41
+ * @param {string} root
42
+ * @param {string|null} myHolder leases with this holder are OURS and ignored
43
+ * @param {{ inspectImpl?: Function, statImpl?: Function }} [opts]
44
+ * @returns {{ path: string, holder: string, mtimeMs: number|null, size: number|null }[]}
45
+ */
46
+ export function snapshotForeignLeases(root, myHolder, { inspectImpl = inspect, statImpl = statSync } = {}) {
47
+ let view;
48
+ try {
49
+ view = inspectImpl(root);
50
+ } catch {
51
+ // ⚠️ An unreadable lease directory means we cannot warn, not that the run
52
+ // should stop. This layer is a smoke alarm; a broken alarm does not
53
+ // condemn the building.
54
+ return [];
55
+ }
56
+ const mine = String(myHolder ?? '').trim();
57
+ const out = [];
58
+ for (const l of view?.leases ?? []) {
59
+ if (!l?.path) continue;
60
+ if (mine && l.holder === mine) continue;
61
+ let mtimeMs = null;
62
+ let size = null;
63
+ try {
64
+ const st = statImpl(join(root, l.path));
65
+ mtimeMs = st.mtimeMs;
66
+ size = st.size;
67
+ } catch {
68
+ // The path may not exist yet — a lease can be taken on a file about to be
69
+ // created. `null` records that, and a file appearing IS a change.
70
+ }
71
+ out.push({ path: l.path, holder: l.holder ?? '(unknown)', mtimeMs, size });
72
+ }
73
+ return out;
74
+ }
75
+
76
+ /**
77
+ * Which of those paths changed while the command ran?
78
+ *
79
+ * @returns {{ path: string, holder: string, what: 'modified'|'created'|'deleted' }[]}
80
+ */
81
+ export function detectForeignChanges(snapshot, root, { statImpl = statSync } = {}) {
82
+ const changed = [];
83
+ for (const before of snapshot ?? []) {
84
+ let after = null;
85
+ try {
86
+ const st = statImpl(join(root, before.path));
87
+ after = { mtimeMs: st.mtimeMs, size: st.size };
88
+ } catch { /* gone */ }
89
+
90
+ if (before.mtimeMs === null && after) { changed.push({ ...before, what: 'created' }); continue; }
91
+ if (before.mtimeMs !== null && !after) { changed.push({ ...before, what: 'deleted' }); continue; }
92
+ if (!after) continue;
93
+ /**
94
+ * ⚠️ SIZE **OR** MTIME. A same-length edit — flipping a digit, swapping a
95
+ * flag — leaves the size identical, and those are exactly the edits worth
96
+ * catching. Filesystems with coarse mtime granularity are the reason size
97
+ * is checked too, rather than instead.
98
+ */
99
+ if (after.mtimeMs !== before.mtimeMs || after.size !== before.size) {
100
+ changed.push({ ...before, what: 'modified' });
101
+ }
102
+ }
103
+ return changed;
104
+ }
105
+
106
+ /** The sentence somebody needs to read, once, loudly. */
107
+ export function formatForeignChanges(changes) {
108
+ if (!changes || changes.length === 0) return null;
109
+ const lines = [
110
+ `⚠️ a command this run started ${changes.length === 1 ? 'changed a file' : `changed ${changes.length} files`} another terminal is holding:`,
111
+ ];
112
+ for (const c of changes) lines.push(` ${c.what.padEnd(8)} ${c.path} ← held by ${c.holder}`);
113
+ lines.push(' A lease stops `write_file`; it cannot stop code the agent runs. Their work may be overwritten.');
114
+ return lines.join('\n');
115
+ }