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.
- package/CHANGELOG.md +328 -0
- package/ENTERPRISE.md +927 -0
- package/LICENSE +120 -0
- package/README.md +1245 -0
- package/ROADMAP.md +556 -0
- package/bin/acuvo-mcp.mjs +208 -0
- package/bin/acuvo.mjs +3108 -0
- package/lib/acceptance-consent.mjs +168 -0
- package/lib/acceptance.mjs +859 -0
- package/lib/account.mjs +226 -0
- package/lib/acuvo-dir.mjs +72 -0
- package/lib/acuvo-models.mjs +141 -0
- package/lib/apply-patch.mjs +570 -0
- package/lib/ask-user.mjs +173 -0
- package/lib/audit.mjs +530 -0
- package/lib/auto-lease.mjs +174 -0
- package/lib/background.mjs +842 -0
- package/lib/best-of.mjs +334 -0
- package/lib/board.mjs +232 -0
- package/lib/breaker.mjs +93 -0
- package/lib/budget.mjs +1375 -0
- package/lib/builtin-skills.mjs +135 -0
- package/lib/cache-floor.mjs +204 -0
- package/lib/chain.mjs +303 -0
- package/lib/changed-paths.mjs +84 -0
- package/lib/chat.mjs +434 -0
- package/lib/checkpoint.mjs +637 -0
- package/lib/child-lifetime.mjs +71 -0
- package/lib/cli-args.mjs +1255 -0
- package/lib/code-review.mjs +1382 -0
- package/lib/colour.mjs +82 -0
- package/lib/command.mjs +2847 -0
- package/lib/compact.mjs +1151 -0
- package/lib/completion.mjs +515 -0
- package/lib/creative-engines.mjs +779 -0
- package/lib/db-inspect.mjs +1624 -0
- package/lib/delete.mjs +111 -0
- package/lib/design-loop.mjs +570 -0
- package/lib/diff-preview.mjs +1044 -0
- package/lib/doctor.mjs +2139 -0
- package/lib/dropped.mjs +216 -0
- package/lib/edit-diagnostics.mjs +277 -0
- package/lib/edit.mjs +460 -0
- package/lib/env-file.mjs +250 -0
- package/lib/escalate.mjs +702 -0
- package/lib/evaluate.mjs +284 -0
- package/lib/fetch-text.mjs +952 -0
- package/lib/fleet-budget.mjs +256 -0
- package/lib/gh.mjs +1536 -0
- package/lib/git.mjs +1341 -0
- package/lib/github.mjs +261 -0
- package/lib/h2.mjs +194 -0
- package/lib/handoff.mjs +417 -0
- package/lib/hooks.mjs +626 -0
- package/lib/http-probe.mjs +907 -0
- package/lib/image-director.mjs +322 -0
- package/lib/image-edit.mjs +522 -0
- package/lib/imagegen.mjs +998 -0
- package/lib/interrupt.mjs +234 -0
- package/lib/learned.mjs +353 -0
- package/lib/lease-watch.mjs +115 -0
- package/lib/lease.mjs +868 -0
- package/lib/localize.mjs +834 -0
- package/lib/log-tail.mjs +1052 -0
- package/lib/login.mjs +157 -0
- package/lib/lsp.mjs +1613 -0
- package/lib/mcp-consent.mjs +377 -0
- package/lib/mcp-defaults.mjs +780 -0
- package/lib/mcp-server.mjs +1343 -0
- package/lib/mcp.mjs +1263 -0
- package/lib/media.mjs +1283 -0
- package/lib/memory-workspace.mjs +179 -0
- package/lib/model-json.mjs +132 -0
- package/lib/model-tier.mjs +171 -0
- package/lib/model.mjs +1445 -0
- package/lib/parallel.mjs +144 -0
- package/lib/perchance.mjs +210 -0
- package/lib/plan-coherence.mjs +1461 -0
- package/lib/plan-ledger.mjs +981 -0
- package/lib/plan.mjs +461 -0
- package/lib/policy.mjs +783 -0
- package/lib/prefix-order.mjs +38 -0
- package/lib/project-memory.mjs +127 -0
- package/lib/prompt.mjs +109 -0
- package/lib/python.mjs +862 -0
- package/lib/rcfile.mjs +853 -0
- package/lib/read-window.mjs +743 -0
- package/lib/refute-tools.mjs +34 -0
- package/lib/refute.mjs +806 -0
- package/lib/repl-driver.mjs +264 -0
- package/lib/repl.mjs +324 -0
- package/lib/replay.mjs +1218 -0
- package/lib/repo-map.mjs +1101 -0
- package/lib/report.mjs +419 -0
- package/lib/search-rank.mjs +99 -0
- package/lib/search.mjs +659 -0
- package/lib/secret-paths.mjs +54 -0
- package/lib/session.mjs +1017 -0
- package/lib/skills.mjs +703 -0
- package/lib/slash.mjs +356 -0
- package/lib/spawn-argv.mjs +1151 -0
- package/lib/spend.mjs +250 -0
- package/lib/steer.mjs +280 -0
- package/lib/stream.mjs +253 -0
- package/lib/stuck.mjs +712 -0
- package/lib/subagent.mjs +749 -0
- package/lib/terminal-graphics.mjs +171 -0
- package/lib/tool-prefix.mjs +226 -0
- package/lib/tool-shortlist.mjs +162 -0
- package/lib/tools.mjs +2333 -0
- package/lib/tsserver.mjs +423 -0
- package/lib/turn.mjs +5672 -0
- package/lib/untrusted-block.mjs +271 -0
- package/lib/verify-claim.mjs +299 -0
- package/lib/vision.mjs +330 -0
- package/lib/voice-task.mjs +561 -0
- package/lib/warm-provider.mjs +255 -0
- package/lib/websearch.mjs +401 -0
- package/lib/workspace.mjs +928 -0
- package/lib/write-approval.mjs +235 -0
- package/lib/write-many.mjs +162 -0
- package/package.json +62 -0
- package/scripts/bundle.mjs +768 -0
- package/scripts/cache-floor.mjs +176 -0
- package/scripts/machine.mjs +226 -0
- package/scripts/test.mjs +139 -0
- package/skills/accessibility.md +87 -0
- package/skills/acuvo-design-system.md +123 -0
- package/skills/animation.md +84 -0
- package/skills/api-design.md +82 -0
- package/skills/auth-and-sessions.md +78 -0
- package/skills/build-with-a-framework.md +101 -0
- package/skills/colour-and-contrast.md +112 -0
- package/skills/creative-engines.md +81 -0
- package/skills/css-layout.md +85 -0
- package/skills/data-and-charts.md +77 -0
- package/skills/debugging.md +76 -0
- package/skills/designing-by-looking.md +84 -0
- package/skills/error-handling.md +78 -0
- package/skills/forms-and-validation.md +93 -0
- package/skills/nextjs-app-router.md +75 -0
- package/skills/page-composition.md +103 -0
- package/skills/performance.md +77 -0
- package/skills/plan-before-building.md +52 -0
- package/skills/planning-and-delegating.md +72 -0
- package/skills/refactoring.md +70 -0
- package/skills/security-basics.md +76 -0
- package/skills/state-management.md +73 -0
- package/skills/supabase-multitenant.md +72 -0
- package/skills/typescript-strict.md +90 -0
- package/skills/typography.md +135 -0
- package/skills/verify-your-own-work.md +62 -0
- package/skills/web-app-quality.md +62 -0
- 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
|
+
}
|