@augurworks/augur 0.15.10 → 0.15.11
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/package.json +1 -1
- package/scripts/hook.mjs +6 -4
- package/scripts/lib/adapters.mjs +20 -5
- package/scripts/open.mjs +5 -3
- package/src/_worker.js +4 -3
package/package.json
CHANGED
package/scripts/hook.mjs
CHANGED
|
@@ -5,13 +5,15 @@
|
|
|
5
5
|
// JSON on stdin (docs/drafts-that-land.md §7). Both answer with an exit code: 0 lets the
|
|
6
6
|
// edit through, 2 refuses it and puts one sentence on stderr for the agent to read in its
|
|
7
7
|
// next tool result. NOTHING ELSE EXITS NON-ZERO: an unreadable payload, a missing
|
|
8
|
-
// registry, an exception — every accident exits 0 and says nothing, because the hook
|
|
9
|
-
// installed
|
|
8
|
+
// registry, an exception — every accident exits 0 and says nothing, because the hook runs
|
|
9
|
+
// around every edit in the folder it is installed for and a bug here would take that
|
|
10
|
+
// editor down with it.
|
|
10
11
|
//
|
|
11
12
|
// pre refuse a write into a read-only copy, or into a shared checkout's prototype
|
|
12
13
|
// post save the draft the edited file belongs to; refused saves fail with the reason
|
|
13
14
|
//
|
|
14
|
-
// `install|remove|status` manage the adapters
|
|
15
|
+
// `install|remove|status` manage the adapters for the folder they run in (the agent tool's
|
|
16
|
+
// project-local settings) — `augur open` installs them there the first time.
|
|
15
17
|
import fs from "node:fs";
|
|
16
18
|
import { ADAPTERS, denyDecision, saveDecision, installAdapters, removeAdapters } from "./lib/adapters.mjs";
|
|
17
19
|
import { registryList, readState, unitClient, doSave } from "./lib/draft.mjs";
|
|
@@ -24,7 +26,7 @@ if (event === "install" || event === "remove" || event === "status") {
|
|
|
24
26
|
const rows = event === "install" ? installAdapters() : event === "remove" ? removeAdapters() : installAdapters({ dryRun: true });
|
|
25
27
|
for (const r of rows) {
|
|
26
28
|
const verdict = event === "status" ? (r.result === "unchanged" ? "installed" : r.result === "absent" ? "absent" : "not installed") : r.result;
|
|
27
|
-
console.log(`${r.name}: ${verdict}${r.path ? ` (${r.path})` : ""}`);
|
|
29
|
+
console.log(`${r.name}: ${verdict}${r.path ? ` (${r.path})` : ""}${r.movedFrom ? ` — an older machine-wide entry in ${r.movedFrom} was removed` : ""}`);
|
|
28
30
|
}
|
|
29
31
|
process.exit(0);
|
|
30
32
|
}
|
package/scripts/lib/adapters.mjs
CHANGED
|
@@ -84,7 +84,14 @@ export const ADAPTERS = Object.freeze([
|
|
|
84
84
|
Object.freeze({
|
|
85
85
|
id: "claude-code",
|
|
86
86
|
name: "Claude Code",
|
|
87
|
-
|
|
87
|
+
// The hooks live in the PROJECT's local settings — the folder `augur open` runs in, which
|
|
88
|
+
// is where the draft folder is made — never in the account-wide file. Three cold agents
|
|
89
|
+
// in a row flagged a write to ~/.claude/settings.json and their person asked for it to be
|
|
90
|
+
// undone; a hook whose command carries this machine's absolute path belongs in the
|
|
91
|
+
// per-machine local file anyway. `legacyPath` is where older engines wrote it; an entry
|
|
92
|
+
// found there is removed on the next install so the two never fire together.
|
|
93
|
+
settingsPath: (cwd) => path.join(cwd, ".claude", "settings.local.json"),
|
|
94
|
+
legacyPath: (home) => path.join(home, ".claude", "settings.json"),
|
|
88
95
|
detect: (home) => fs.existsSync(path.join(home, ".claude")),
|
|
89
96
|
matcher: "Write|Edit|MultiEdit|NotebookEdit",
|
|
90
97
|
payload: (j) => {
|
|
@@ -154,20 +161,28 @@ function writeJson(p, v) {
|
|
|
154
161
|
fs.renameSync(p + ".tmp", p);
|
|
155
162
|
}
|
|
156
163
|
|
|
157
|
-
function applyToAdapters({ home = os.homedir(), dryRun = false } = {}, decide) {
|
|
164
|
+
function applyToAdapters({ home = os.homedir(), cwd = process.cwd(), dryRun = false } = {}, decide) {
|
|
158
165
|
const out = [];
|
|
159
166
|
for (const a of ADAPTERS) {
|
|
160
167
|
if (!a.detect(home)) { out.push({ id: a.id, name: a.name, result: "absent" }); continue; }
|
|
161
|
-
const p = a.settingsPath(
|
|
168
|
+
const p = a.settingsPath(cwd);
|
|
162
169
|
const cur = readJson(p);
|
|
163
170
|
const r = decide(a, cur);
|
|
164
171
|
if (r.changed && !dryRun) writeJson(p, r.settings);
|
|
165
|
-
|
|
172
|
+
// An entry an older engine left in the account-wide file: taken out, and said.
|
|
173
|
+
let movedFrom = null;
|
|
174
|
+
const lp = a.legacyPath ? a.legacyPath(home) : null;
|
|
175
|
+
const legacy = lp ? readJson(lp) : null;
|
|
176
|
+
if (legacy) {
|
|
177
|
+
const s = stripHooks(legacy);
|
|
178
|
+
if (s.changed) { movedFrom = lp; if (!dryRun) writeJson(lp, s.settings); }
|
|
179
|
+
}
|
|
180
|
+
out.push({ id: a.id, name: a.name, result: r.changed ? r.did : "unchanged", path: p, ...(movedFrom ? { movedFrom } : {}) });
|
|
166
181
|
}
|
|
167
182
|
return out;
|
|
168
183
|
}
|
|
169
184
|
|
|
170
|
-
/** Install the two hooks for every tool present on this machine. Idempotent; keeps every other hook. */
|
|
185
|
+
/** Install the two hooks, for the folder `cwd` (the agent tool's project-local settings), for every tool present on this machine. Idempotent; keeps every other hook. */
|
|
171
186
|
export function installAdapters(opts = {}) {
|
|
172
187
|
return applyToAdapters(opts, (a, cur) => {
|
|
173
188
|
const onPath = typeof opts.onPath === "boolean" ? opts.onPath : augurOnPath();
|
package/scripts/open.mjs
CHANGED
|
@@ -47,12 +47,14 @@ if (!r.ok) {
|
|
|
47
47
|
die(`could not open: ${r.error || r.status}${r.reason ? ` (${r.reason})` : ""}${r.message ? ` — ${r.message}` : ""}`);
|
|
48
48
|
}
|
|
49
49
|
log(r.isNew ? `draft ${r.draftId} on ${unit} — a NEW prototype; ${dir} is empty, write its index.html there` : `draft ${r.draftId} on ${unit} — ${r.files} file(s) in ${dir}`);
|
|
50
|
-
// The agent tool's hooks, installed for
|
|
51
|
-
// here (idempotent; `AUGUR_NO_ADAPTERS=1`
|
|
50
|
+
// The agent tool's hooks, installed for THIS folder (its project-local settings) the first
|
|
51
|
+
// time a draft is opened from here — never account-wide (idempotent; `AUGUR_NO_ADAPTERS=1`
|
|
52
|
+
// skips it — the suite and CI set it).
|
|
52
53
|
if (!process.env.AUGUR_NO_ADAPTERS) {
|
|
53
54
|
for (const a of installAdapters()) {
|
|
54
|
-
if (a.result === "installed") log(`${a.name}: a save hook is now in ${a.path} —
|
|
55
|
+
if (a.result === "installed") log(`${a.name}: a save hook is now in ${a.path} — for this folder only, nothing account-wide. After each edit inside a draft folder here it runs \`augur hook post\`, which saves that draft to ${origin}; before an edit it refuses writes into a shared checkout's prototypes. It does nothing else and talks to nothing else; \`augur hook remove\` run here takes it out.`);
|
|
55
56
|
else if (a.result === "updated") log(`${a.name}: editor hooks updated (${a.path}).`);
|
|
57
|
+
if (a.movedFrom) log(`${a.name}: an older machine-wide entry in ${a.movedFrom} was removed; the hook lives with the folder now.`);
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
60
|
if (r.others.length) {
|
package/src/_worker.js
CHANGED
|
@@ -9307,9 +9307,10 @@ function doorText(f) {
|
|
|
9307
9307
|
? `You need no source tree here: \`augur open <opportunity>/<prototype>\` fetches that one\n`
|
|
9308
9308
|
+ `prototype into a folder of its own (see below). Do not clone the workspace first.\n\n`
|
|
9309
9309
|
+ `Until \`npm i -g @augurworks/augur\`, every verb runs as \`npx @augurworks/augur <verb>\`.\n`
|
|
9310
|
-
+ `The first \`open\`
|
|
9311
|
-
+ `
|
|
9312
|
-
+ `
|
|
9310
|
+
+ `The first \`open\` in a folder also installs a save hook in the editor tool's settings\n`
|
|
9311
|
+
+ `for that folder only (.claude/settings.local.json there; it says so), never account-wide:\n`
|
|
9312
|
+
+ `after each edit inside a draft folder it saves that draft; it does nothing elsewhere,\n`
|
|
9313
|
+
+ `and \`augur hook remove\` in that folder takes it out.\n\n`
|
|
9313
9314
|
: `With no source tree yet, \`npx @augurworks/augur clone --space ${f.workspace}\` then fetches\n`
|
|
9314
9315
|
+ `one (it reads the origin from the pairing).\n\n`)
|
|
9315
9316
|
: `Device pairing is switched off on this workspace. Ask an admin for an invite;\n`
|