safeword 0.60.0 → 0.61.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/dist/{architecture-32CAOL4P.js → architecture-WFRA4ITA.js} +6 -6
- package/dist/{check-PO4TEYZQ.js → check-KHWH36AK.js} +10 -10
- package/dist/chunk-B6KVKEZA.js +65 -0
- package/dist/chunk-B6KVKEZA.js.map +1 -0
- package/dist/{chunk-K7QZ6W2K.js → chunk-C4LNUGHF.js} +7 -7
- package/dist/{chunk-UIRPUAPO.js → chunk-GEC7AHRF.js} +54 -5
- package/dist/chunk-GEC7AHRF.js.map +1 -0
- package/dist/{chunk-XDT3W5MH.js → chunk-ILTC7KBQ.js} +66 -27
- package/dist/chunk-ILTC7KBQ.js.map +1 -0
- package/dist/{chunk-HKX3Z32Y.js → chunk-LBFUREUF.js} +6 -6
- package/dist/{chunk-NWCBLTIE.js → chunk-O2ULQPXW.js} +2 -1
- package/dist/{chunk-GS3TBFXU.js → chunk-OY7F4YNQ.js} +2 -2
- package/dist/chunk-U2GSR4OM.js +144 -0
- package/dist/chunk-U2GSR4OM.js.map +1 -0
- package/dist/{chunk-MV7VNFO6.js → chunk-XTGWCHWI.js} +8 -8
- package/dist/cli.js +38 -18
- package/dist/cli.js.map +1 -1
- package/dist/{codify-S4DJVZ4R.js → codify-BXBG5XPK.js} +3 -3
- package/dist/{diff-43VUWWRJ.js → diff-K3SYBGB7.js} +9 -9
- package/dist/github-rest-36XJI5HD.js +78 -0
- package/dist/github-rest-36XJI5HD.js.map +1 -0
- package/dist/output-7MPCY3U7.js +23 -0
- package/dist/{reset-C423HHTK.js → reset-4IGPE6TD.js} +7 -7
- package/dist/retro-FCGFUDEA.js +603 -0
- package/dist/retro-FCGFUDEA.js.map +1 -0
- package/dist/retro-extract-XXZI3DFW.js +30 -0
- package/dist/retro-extract-XXZI3DFW.js.map +1 -0
- package/dist/{self-report-CQLAESVT.js → self-report-AQZKGDAS.js} +4 -3
- package/dist/{self-report-CQLAESVT.js.map → self-report-AQZKGDAS.js.map} +1 -1
- package/dist/self-report-XLBFP2NT.js +36 -0
- package/dist/self-report-XLBFP2NT.js.map +1 -0
- package/dist/{setup-YAIS4ZQA.js → setup-SECXSZ5K.js} +12 -12
- package/dist/{sync-config-IUOYVDVQ.js → sync-config-VJFZJATR.js} +3 -3
- package/dist/sync-config-VJFZJATR.js.map +1 -0
- package/dist/{sync-learnings-XTHHJDPR.js → sync-learnings-BVNUNLPD.js} +3 -3
- package/dist/{sync-tickets-IQ4AACIH.js → sync-tickets-4TOJBDHW.js} +3 -3
- package/dist/{sync-tracker-2TGUIMAB.js → sync-tracker-U4TKFX4R.js} +7 -7
- package/dist/{test-plan-6X56C5JZ.js → test-plan-VMQRP2WF.js} +3 -3
- package/dist/{ticket-new-UIOKBXK2.js → ticket-new-PIHZGZGG.js} +5 -5
- package/dist/{upgrade-WMWT2WXK.js → upgrade-S5DTXDLC.js} +18 -18
- package/package.json +3 -1
- package/templates/codex/config.toml +8 -0
- package/templates/commands/audit.md +4 -3
- package/templates/guides/retro.md +81 -0
- package/templates/guides/self-report-filing.md +26 -0
- package/templates/hooks/codex/stop.ts +102 -0
- package/templates/hooks/cursor/stop.ts +54 -10
- package/templates/hooks/lib/jsonl-spool.ts +107 -0
- package/templates/hooks/lib/quality-state.ts +10 -0
- package/templates/hooks/lib/retro-draft-spool.ts +160 -0
- package/templates/hooks/lib/retro-extract.ts +309 -0
- package/templates/hooks/lib/retro-nudge.ts +86 -0
- package/templates/hooks/lib/retro-trigger.ts +477 -0
- package/templates/hooks/lib/self-report.ts +12 -35
- package/templates/hooks/prompt-retro-nudge.ts +48 -0
- package/templates/hooks/stop-retro.ts +77 -0
- package/templates/hooks/write-review-stamp.ts +37 -17
- package/templates/skills/audit/SKILL.md +8 -7
- package/dist/chunk-UIRPUAPO.js.map +0 -1
- package/dist/chunk-XDT3W5MH.js.map +0 -1
- /package/dist/{architecture-32CAOL4P.js.map → architecture-WFRA4ITA.js.map} +0 -0
- /package/dist/{check-PO4TEYZQ.js.map → check-KHWH36AK.js.map} +0 -0
- /package/dist/{chunk-K7QZ6W2K.js.map → chunk-C4LNUGHF.js.map} +0 -0
- /package/dist/{chunk-HKX3Z32Y.js.map → chunk-LBFUREUF.js.map} +0 -0
- /package/dist/{chunk-NWCBLTIE.js.map → chunk-O2ULQPXW.js.map} +0 -0
- /package/dist/{chunk-GS3TBFXU.js.map → chunk-OY7F4YNQ.js.map} +0 -0
- /package/dist/{chunk-MV7VNFO6.js.map → chunk-XTGWCHWI.js.map} +0 -0
- /package/dist/{codify-S4DJVZ4R.js.map → codify-BXBG5XPK.js.map} +0 -0
- /package/dist/{diff-43VUWWRJ.js.map → diff-K3SYBGB7.js.map} +0 -0
- /package/dist/{sync-config-IUOYVDVQ.js.map → output-7MPCY3U7.js.map} +0 -0
- /package/dist/{reset-C423HHTK.js.map → reset-4IGPE6TD.js.map} +0 -0
- /package/dist/{setup-YAIS4ZQA.js.map → setup-SECXSZ5K.js.map} +0 -0
- /package/dist/{sync-learnings-XTHHJDPR.js.map → sync-learnings-BVNUNLPD.js.map} +0 -0
- /package/dist/{sync-tickets-IQ4AACIH.js.map → sync-tickets-4TOJBDHW.js.map} +0 -0
- /package/dist/{sync-tracker-2TGUIMAB.js.map → sync-tracker-U4TKFX4R.js.map} +0 -0
- /package/dist/{test-plan-6X56C5JZ.js.map → test-plan-VMQRP2WF.js.map} +0 -0
- /package/dist/{ticket-new-UIOKBXK2.js.map → ticket-new-PIHZGZGG.js.map} +0 -0
- /package/dist/{upgrade-WMWT2WXK.js.map → upgrade-S5DTXDLC.js.map} +0 -0
|
@@ -3,17 +3,17 @@ import {
|
|
|
3
3
|
isArchitectureDocumentEnforcementEnabled,
|
|
4
4
|
resolveGeneratedArchitecturePath
|
|
5
5
|
} from "./chunk-HI7ANNQI.js";
|
|
6
|
-
import {
|
|
7
|
-
error,
|
|
8
|
-
success,
|
|
9
|
-
warn
|
|
10
|
-
} from "./chunk-NWCBLTIE.js";
|
|
11
6
|
import {
|
|
12
7
|
exists,
|
|
13
8
|
isDirectory,
|
|
14
9
|
readFileSafe,
|
|
15
10
|
readJson
|
|
16
11
|
} from "./chunk-2KELQTLE.js";
|
|
12
|
+
import {
|
|
13
|
+
error,
|
|
14
|
+
success,
|
|
15
|
+
warn
|
|
16
|
+
} from "./chunk-O2ULQPXW.js";
|
|
17
17
|
|
|
18
18
|
// src/commands/architecture.ts
|
|
19
19
|
import { execFileSync } from "child_process";
|
|
@@ -976,4 +976,4 @@ function architectureCheck(cwd) {
|
|
|
976
976
|
export {
|
|
977
977
|
architecture
|
|
978
978
|
};
|
|
979
|
-
//# sourceMappingURL=architecture-
|
|
979
|
+
//# sourceMappingURL=architecture-WFRA4ITA.js.map
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildIndexConflictListMessage
|
|
3
3
|
} from "./chunk-ZESHX2BU.js";
|
|
4
|
-
import {
|
|
5
|
-
fetchRegistryLatestVersion,
|
|
6
|
-
isNewerVersion
|
|
7
|
-
} from "./chunk-LRYWFRPD.js";
|
|
8
4
|
import {
|
|
9
5
|
checkHealth,
|
|
10
6
|
reportHealthSummary
|
|
11
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-XTGWCHWI.js";
|
|
12
8
|
import "./chunk-HWOJR33A.js";
|
|
13
9
|
import "./chunk-XTLCJKGE.js";
|
|
14
|
-
import
|
|
10
|
+
import {
|
|
11
|
+
fetchRegistryLatestVersion,
|
|
12
|
+
isNewerVersion
|
|
13
|
+
} from "./chunk-LRYWFRPD.js";
|
|
14
|
+
import "./chunk-GEC7AHRF.js";
|
|
15
15
|
import {
|
|
16
16
|
detectPackageManager
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-OY7F4YNQ.js";
|
|
18
18
|
import {
|
|
19
19
|
syncTickets
|
|
20
20
|
} from "./chunk-D4UGNHLW.js";
|
|
@@ -22,14 +22,14 @@ import "./chunk-NHXVS5FL.js";
|
|
|
22
22
|
import "./chunk-HI7ANNQI.js";
|
|
23
23
|
import "./chunk-CXGL65PS.js";
|
|
24
24
|
import "./chunk-HSC7TELY.js";
|
|
25
|
+
import "./chunk-2KELQTLE.js";
|
|
25
26
|
import {
|
|
26
27
|
header,
|
|
27
28
|
info,
|
|
28
29
|
keyValue,
|
|
29
30
|
success,
|
|
30
31
|
warn
|
|
31
|
-
} from "./chunk-
|
|
32
|
-
import "./chunk-2KELQTLE.js";
|
|
32
|
+
} from "./chunk-O2ULQPXW.js";
|
|
33
33
|
|
|
34
34
|
// src/commands/check.ts
|
|
35
35
|
import process from "process";
|
|
@@ -125,4 +125,4 @@ async function check(options) {
|
|
|
125
125
|
export {
|
|
126
126
|
check
|
|
127
127
|
};
|
|
128
|
-
//# sourceMappingURL=check-
|
|
128
|
+
//# sourceMappingURL=check-KHWH36AK.js.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// templates/hooks/lib/jsonl-spool.ts
|
|
2
|
+
import { appendFileSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
3
|
+
import nodePath from "path";
|
|
4
|
+
function* iterateJsonlEntries(text) {
|
|
5
|
+
for (const line of text.split("\n")) {
|
|
6
|
+
if (line.trim().length === 0) continue;
|
|
7
|
+
let value;
|
|
8
|
+
try {
|
|
9
|
+
value = JSON.parse(line);
|
|
10
|
+
} catch {
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
yield value;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function countJsonlRecords(filePath) {
|
|
17
|
+
try {
|
|
18
|
+
return readFileSync(filePath, "utf8").split("\n").filter((line) => line.trim().length > 0).length;
|
|
19
|
+
} catch {
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function readJsonlRecords(filePath, parse) {
|
|
24
|
+
let raw;
|
|
25
|
+
try {
|
|
26
|
+
raw = readFileSync(filePath, "utf8");
|
|
27
|
+
} catch {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
const records = [];
|
|
31
|
+
for (const value of iterateJsonlEntries(raw)) {
|
|
32
|
+
try {
|
|
33
|
+
const record = parse(value);
|
|
34
|
+
if (record !== void 0) records.push(record);
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return records;
|
|
39
|
+
}
|
|
40
|
+
function appendJsonlRecords(filePath, lines, cap) {
|
|
41
|
+
try {
|
|
42
|
+
const room = cap - countJsonlRecords(filePath);
|
|
43
|
+
if (room <= 0) return;
|
|
44
|
+
const toWrite = lines.slice(0, room);
|
|
45
|
+
if (toWrite.length === 0) return;
|
|
46
|
+
mkdirSync(nodePath.dirname(filePath), { recursive: true });
|
|
47
|
+
appendFileSync(filePath, `${toWrite.join("\n")}
|
|
48
|
+
`);
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function atomicWriteFile(file, contents) {
|
|
53
|
+
const temporary = `${file}.${process.pid}.tmp`;
|
|
54
|
+
mkdirSync(nodePath.dirname(file), { recursive: true });
|
|
55
|
+
writeFileSync(temporary, contents);
|
|
56
|
+
renameSync(temporary, file);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export {
|
|
60
|
+
iterateJsonlEntries,
|
|
61
|
+
readJsonlRecords,
|
|
62
|
+
appendJsonlRecords,
|
|
63
|
+
atomicWriteFile
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=chunk-B6KVKEZA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../templates/hooks/lib/jsonl-spool.ts"],"sourcesContent":["// Per-session JSONL spool I/O — the shared machinery under the self-report spool\n// (lib/self-report.ts) and the retro draft spool (lib/retro-draft-spool.ts).\n//\n// Both persist sanitized, per-session records to `.safeword/<dir>/<session>.jsonl`\n// and had their own copy of: count non-blank lines, read-and-skip-torn-lines,\n// cap-aware append, and atomic (temp+rename) rewrite. That machinery is\n// correctness-sensitive (torn-tolerance, fail-open, whole-or-nothing writes), so it\n// lives here ONCE. Callers keep what genuinely differs — the subdir, the filename\n// sanitizer, the record schema (parse/serialize), and the cap value — and pass a\n// resolved file path in.\n//\n// Self-contained (node:* only) so the CLI's src/ and the customer-repo hooks can\n// both run it, like the two spools it backs.\n\nimport { appendFileSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport nodePath from 'node:path';\n\n/**\n * Yield the JSON-parsed value of each non-blank JSONL line in `text`, skipping any\n * blank or torn (unparseable) line — never throws. The single home for the\n * split / skip-blank / parse-or-skip skeleton shared by the spool reader here and\n * the transcript scanners (retro-trigger's counters, retro-extract's digest);\n * callers supply only their per-entry handling.\n */\nexport function* iterateJsonlEntries(text: string): Generator<unknown> {\n for (const line of text.split('\\n')) {\n if (line.trim().length === 0) continue;\n let value: unknown;\n try {\n value = JSON.parse(line);\n } catch {\n continue; // skip a torn/malformed JSONL line\n }\n yield value;\n }\n}\n\n/** Count non-blank JSONL records in a spool file (0 when absent/unreadable). */\nexport function countJsonlRecords(filePath: string): number {\n try {\n return readFileSync(filePath, 'utf8')\n .split('\\n')\n .filter(line => line.trim().length > 0).length;\n } catch {\n return 0;\n }\n}\n\n/**\n * Read every JSONL line, JSON.parse it, and map it through `parse` — skipping any\n * blank, torn (unparseable), or rejected (`parse` → undefined) line. Fail-open: a\n * missing or unreadable file yields `[]`, never a throw, so a filing/read path never\n * crashes on a bad spool.\n */\nexport function readJsonlRecords<T>(\n filePath: string,\n parse: (value: unknown) => T | undefined,\n): T[] {\n let raw: string;\n try {\n raw = readFileSync(filePath, 'utf8');\n } catch {\n return [];\n }\n const records: T[] = [];\n for (const value of iterateJsonlEntries(raw)) {\n try {\n const record = parse(value);\n if (record !== undefined) records.push(record);\n } catch {\n // a parse callback that rejects a malformed record is skipped, not fatal\n }\n }\n return records;\n}\n\n/**\n * Append pre-serialized JSONL lines, capped: once the file already holds `cap`\n * records, drop the overflow rather than growing unbounded (bounds a crash-looping\n * or runaway session). BEST-EFFORT — never throws, so a spool-write failure can't\n * break the host path that called it.\n */\nexport function appendJsonlRecords(filePath: string, lines: readonly string[], cap: number): void {\n try {\n const room = cap - countJsonlRecords(filePath);\n if (room <= 0) return;\n const toWrite = lines.slice(0, room);\n if (toWrite.length === 0) return;\n mkdirSync(nodePath.dirname(filePath), { recursive: true });\n appendFileSync(filePath, `${toWrite.join('\\n')}\\n`);\n } catch {\n // Self-observation must never break the host. Swallow.\n }\n}\n\n/**\n * Write `contents` to `file` atomically: write a pid-unique temp sibling, then\n * rename onto the target, so a concurrent reader sees the whole old or whole new\n * file — never a half-written one. Creates the parent dir. Throws on I/O error;\n * callers that must stay fail-open wrap it in their own try/catch.\n */\nexport function atomicWriteFile(file: string, contents: string): void {\n const temporary = `${file}.${process.pid}.tmp`;\n mkdirSync(nodePath.dirname(file), { recursive: true });\n writeFileSync(temporary, contents);\n renameSync(temporary, file);\n}\n"],"mappings":";AAcA,SAAS,gBAAgB,WAAW,cAAc,YAAY,qBAAqB;AACnF,OAAO,cAAc;AASd,UAAU,oBAAoB,MAAkC;AACrE,aAAW,QAAQ,KAAK,MAAM,IAAI,GAAG;AACnC,QAAI,KAAK,KAAK,EAAE,WAAW,EAAG;AAC9B,QAAI;AACJ,QAAI;AACF,cAAQ,KAAK,MAAM,IAAI;AAAA,IACzB,QAAQ;AACN;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAGO,SAAS,kBAAkB,UAA0B;AAC1D,MAAI;AACF,WAAO,aAAa,UAAU,MAAM,EACjC,MAAM,IAAI,EACV,OAAO,UAAQ,KAAK,KAAK,EAAE,SAAS,CAAC,EAAE;AAAA,EAC5C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,SAAS,iBACd,UACA,OACK;AACL,MAAI;AACJ,MAAI;AACF,UAAM,aAAa,UAAU,MAAM;AAAA,EACrC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,UAAe,CAAC;AACtB,aAAW,SAAS,oBAAoB,GAAG,GAAG;AAC5C,QAAI;AACF,YAAM,SAAS,MAAM,KAAK;AAC1B,UAAI,WAAW,OAAW,SAAQ,KAAK,MAAM;AAAA,IAC/C,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,mBAAmB,UAAkB,OAA0B,KAAmB;AAChG,MAAI;AACF,UAAM,OAAO,MAAM,kBAAkB,QAAQ;AAC7C,QAAI,QAAQ,EAAG;AACf,UAAM,UAAU,MAAM,MAAM,GAAG,IAAI;AACnC,QAAI,QAAQ,WAAW,EAAG;AAC1B,cAAU,SAAS,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACzD,mBAAe,UAAU,GAAG,QAAQ,KAAK,IAAI,CAAC;AAAA,CAAI;AAAA,EACpD,QAAQ;AAAA,EAER;AACF;AAQO,SAAS,gBAAgB,MAAc,UAAwB;AACpE,QAAM,YAAY,GAAG,IAAI,IAAI,QAAQ,GAAG;AACxC,YAAU,SAAS,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACrD,gBAAc,WAAW,QAAQ;AACjC,aAAW,WAAW,IAAI;AAC5B;","names":[]}
|
|
@@ -4,20 +4,20 @@ import {
|
|
|
4
4
|
detectLanguages,
|
|
5
5
|
isGitRepo,
|
|
6
6
|
isPackInstalled
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-GEC7AHRF.js";
|
|
8
8
|
import {
|
|
9
9
|
SAFEWORD_PEER_DEPENDENCIES
|
|
10
10
|
} from "./chunk-HSC7TELY.js";
|
|
11
|
+
import {
|
|
12
|
+
exists,
|
|
13
|
+
readJson
|
|
14
|
+
} from "./chunk-2KELQTLE.js";
|
|
11
15
|
import {
|
|
12
16
|
info,
|
|
13
17
|
listItem,
|
|
14
18
|
success,
|
|
15
19
|
warn
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import {
|
|
18
|
-
exists,
|
|
19
|
-
readJson
|
|
20
|
-
} from "./chunk-2KELQTLE.js";
|
|
20
|
+
} from "./chunk-O2ULQPXW.js";
|
|
21
21
|
|
|
22
22
|
// src/packs/install.ts
|
|
23
23
|
function installPack(packId, cwd) {
|
|
@@ -546,4 +546,4 @@ export {
|
|
|
546
546
|
getEslintPeerMismatchWarning,
|
|
547
547
|
maybeAutoPatchOrNudge
|
|
548
548
|
};
|
|
549
|
-
//# sourceMappingURL=chunk-
|
|
549
|
+
//# sourceMappingURL=chunk-C4LNUGHF.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MCP_SERVERS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OY7F4YNQ.js";
|
|
4
4
|
import {
|
|
5
5
|
NAMESPACE_ROOT_LEGACY,
|
|
6
6
|
readConfiguredPath,
|
|
@@ -2226,6 +2226,9 @@ function hook(command) {
|
|
|
2226
2226
|
function asyncRewakeHook(command) {
|
|
2227
2227
|
return { hooks: [{ type: "command", command, asyncRewake: true }] };
|
|
2228
2228
|
}
|
|
2229
|
+
function asyncHook(command) {
|
|
2230
|
+
return { hooks: [{ type: "command", command, async: true }] };
|
|
2231
|
+
}
|
|
2229
2232
|
function matchedHook(matcher, command) {
|
|
2230
2233
|
return { matcher, hooks: [{ type: "command", command }] };
|
|
2231
2234
|
}
|
|
@@ -2252,12 +2255,18 @@ var SETTINGS_HOOKS = {
|
|
|
2252
2255
|
],
|
|
2253
2256
|
UserPromptSubmit: [
|
|
2254
2257
|
hook(`bun ${HOOKS_DIR}/prompt-timestamp.ts`),
|
|
2255
|
-
hook(`bun ${HOOKS_DIR}/prompt-questions.ts`)
|
|
2258
|
+
hook(`bun ${HOOKS_DIR}/prompt-questions.ts`),
|
|
2259
|
+
// Cloud-retro filing nudge (BNGK9W): when the async Stop hook spooled unfiled
|
|
2260
|
+
// drafts (REST 401 in cloud), surface one factual line so the agent files them.
|
|
2261
|
+
hook(`bun ${HOOKS_DIR}/prompt-retro-nudge.ts`)
|
|
2256
2262
|
],
|
|
2257
2263
|
Stop: [
|
|
2258
2264
|
hook(`bun ${HOOKS_DIR}/stop-quality.ts`),
|
|
2259
2265
|
hook(`bun ${HOOKS_DIR}/stop-reentry.ts`),
|
|
2260
|
-
hook(`bun ${HOOKS_DIR}/stop-self-report.ts`)
|
|
2266
|
+
hook(`bun ${HOOKS_DIR}/stop-self-report.ts`),
|
|
2267
|
+
// Invisible retro (ZFGWS1): async so repeated delta fires never block Stop and
|
|
2268
|
+
// run fully in the background; the inner spawnSync stays sync within that tree.
|
|
2269
|
+
asyncHook(`bun ${HOOKS_DIR}/stop-retro.ts`)
|
|
2261
2270
|
],
|
|
2262
2271
|
PreToolUse: [
|
|
2263
2272
|
matchedHook("Bash", `bun ${HOOKS_DIR}/pre-tool-dependency-readiness.ts`),
|
|
@@ -2934,6 +2943,15 @@ command = 'bun "$(git rev-parse --show-toplevel)/.safeword/hooks/codex/pre-tool-
|
|
|
2934
2943
|
timeout = 30
|
|
2935
2944
|
statusMessage = "Checking safeword PreToolUse gates"
|
|
2936
2945
|
`;
|
|
2946
|
+
var CODEX_STOP_HOOK_PATCH = `
|
|
2947
|
+
[[hooks.Stop]]
|
|
2948
|
+
|
|
2949
|
+
[[hooks.Stop.hooks]]
|
|
2950
|
+
type = "command"
|
|
2951
|
+
command = 'bun "$(git rev-parse --show-toplevel)/.safeword/hooks/codex/stop.ts"'
|
|
2952
|
+
timeout = 30
|
|
2953
|
+
statusMessage = "Checking safeword Stop nudges"
|
|
2954
|
+
`;
|
|
2937
2955
|
var CODEX_POST_TOOL_SKILL_NUDGE_HOOK_PATCH = `
|
|
2938
2956
|
[[hooks.PostToolUse]]
|
|
2939
2957
|
matcher = "^(apply_patch|Edit|Write|MultiEdit|NotebookEdit)$"
|
|
@@ -3077,6 +3095,9 @@ var SAFEWORD_SCHEMA = {
|
|
|
3077
3095
|
preservedDirs: [
|
|
3078
3096
|
".safeword-project/learnings",
|
|
3079
3097
|
".safeword/logs",
|
|
3098
|
+
// Runtime cloud-filing spool (BNGK9W) — per-session drafts + nudge markers the
|
|
3099
|
+
// retro writes at runtime; user/runtime data the schema does not own.
|
|
3100
|
+
".safeword/retro-drafts",
|
|
3080
3101
|
".safeword-project/tickets",
|
|
3081
3102
|
".safeword-project/tickets/completed",
|
|
3082
3103
|
".safeword-project/tmp"
|
|
@@ -3258,7 +3279,12 @@ var SAFEWORD_SCHEMA = {
|
|
|
3258
3279
|
template: "hooks/lib/dependency-readiness.ts"
|
|
3259
3280
|
},
|
|
3260
3281
|
".safeword/hooks/lib/done-gate.ts": { template: "hooks/lib/done-gate.ts" },
|
|
3282
|
+
".safeword/hooks/lib/jsonl-spool.ts": { template: "hooks/lib/jsonl-spool.ts" },
|
|
3261
3283
|
".safeword/hooks/lib/namespace-root.ts": { template: "hooks/lib/namespace-root.ts" },
|
|
3284
|
+
".safeword/hooks/lib/retro-draft-spool.ts": { template: "hooks/lib/retro-draft-spool.ts" },
|
|
3285
|
+
".safeword/hooks/lib/retro-extract.ts": { template: "hooks/lib/retro-extract.ts" },
|
|
3286
|
+
".safeword/hooks/lib/retro-nudge.ts": { template: "hooks/lib/retro-nudge.ts" },
|
|
3287
|
+
".safeword/hooks/lib/retro-trigger.ts": { template: "hooks/lib/retro-trigger.ts" },
|
|
3262
3288
|
".safeword/hooks/lib/self-report.ts": { template: "hooks/lib/self-report.ts" },
|
|
3263
3289
|
".safeword/hooks/lib/skill-invocation-log.ts": {
|
|
3264
3290
|
template: "hooks/lib/skill-invocation-log.ts"
|
|
@@ -3329,6 +3355,9 @@ var SAFEWORD_SCHEMA = {
|
|
|
3329
3355
|
".safeword/hooks/prompt-questions.ts": {
|
|
3330
3356
|
template: "hooks/prompt-questions.ts"
|
|
3331
3357
|
},
|
|
3358
|
+
".safeword/hooks/prompt-retro-nudge.ts": {
|
|
3359
|
+
template: "hooks/prompt-retro-nudge.ts"
|
|
3360
|
+
},
|
|
3332
3361
|
".safeword/hooks/post-tool-lint.ts": {
|
|
3333
3362
|
template: "hooks/post-tool-lint.ts"
|
|
3334
3363
|
},
|
|
@@ -3356,6 +3385,9 @@ var SAFEWORD_SCHEMA = {
|
|
|
3356
3385
|
".safeword/hooks/codex/pre-tool-quality-helpers.ts": {
|
|
3357
3386
|
template: "hooks/codex/pre-tool-quality-helpers.ts"
|
|
3358
3387
|
},
|
|
3388
|
+
".safeword/hooks/codex/stop.ts": {
|
|
3389
|
+
template: "hooks/codex/stop.ts"
|
|
3390
|
+
},
|
|
3359
3391
|
".safeword/hooks/codex/post-tool-skill-nudge.ts": {
|
|
3360
3392
|
template: "hooks/codex/post-tool-skill-nudge.ts"
|
|
3361
3393
|
},
|
|
@@ -3382,6 +3414,7 @@ var SAFEWORD_SCHEMA = {
|
|
|
3382
3414
|
},
|
|
3383
3415
|
".safeword/hooks/stop-quality.ts": { template: "hooks/stop-quality.ts" },
|
|
3384
3416
|
".safeword/hooks/stop-reentry.ts": { template: "hooks/stop-reentry.ts" },
|
|
3417
|
+
".safeword/hooks/stop-retro.ts": { template: "hooks/stop-retro.ts" },
|
|
3385
3418
|
".safeword/hooks/stop-self-report.ts": { template: "hooks/stop-self-report.ts" },
|
|
3386
3419
|
".safeword/hooks/session-start-reentry.ts": {
|
|
3387
3420
|
template: "hooks/session-start-reentry.ts"
|
|
@@ -3399,6 +3432,9 @@ var SAFEWORD_SCHEMA = {
|
|
|
3399
3432
|
".safeword/guides/self-report-filing.md": {
|
|
3400
3433
|
template: "guides/self-report-filing.md"
|
|
3401
3434
|
},
|
|
3435
|
+
".safeword/guides/retro.md": {
|
|
3436
|
+
template: "guides/retro.md"
|
|
3437
|
+
},
|
|
3402
3438
|
".safeword/guides/cold-start-check.md": {
|
|
3403
3439
|
template: "guides/cold-start-check.md"
|
|
3404
3440
|
},
|
|
@@ -3778,10 +3814,23 @@ ${managedPrettierPaths(ctx).join("\n")}
|
|
|
3778
3814
|
unpatchContent: [
|
|
3779
3815
|
CODEX_SESSION_START_HOOK_PATCH,
|
|
3780
3816
|
CODEX_LEGACY_CONTEXT_SESSION_START_HOOK_PATCH,
|
|
3781
|
-
CODEX_PRE_TOOL_QUALITY_HOOK_PATCH
|
|
3817
|
+
CODEX_PRE_TOOL_QUALITY_HOOK_PATCH,
|
|
3818
|
+
CODEX_STOP_HOOK_PATCH
|
|
3782
3819
|
],
|
|
3783
3820
|
removeFileIfContentEquals: [CODEX_CONFIG_SCAFFOLD_WITHOUT_HOOKS]
|
|
3784
3821
|
},
|
|
3822
|
+
// Codex Stop hook retrofit (53DQJZ): add-if-missing, guarded to safeword
|
|
3823
|
+
// scaffolds. Marker is the adapter path so an existing entry suppresses the
|
|
3824
|
+
// append. Uninstall cleanup is owned by the primary patch's unpatchContent.
|
|
3825
|
+
{
|
|
3826
|
+
operation: "append",
|
|
3827
|
+
content: CODEX_STOP_HOOK_PATCH,
|
|
3828
|
+
marker: ".safeword/hooks/codex/stop.ts",
|
|
3829
|
+
applyWhenContentIncludes: [
|
|
3830
|
+
"# Safeword Codex project configuration.",
|
|
3831
|
+
".safeword/hooks/codex/pre-tool-quality.ts"
|
|
3832
|
+
]
|
|
3833
|
+
},
|
|
3785
3834
|
// Migrate existing installs (auto-upgrade-codex follow-up to #433): swap the
|
|
3786
3835
|
// legacy context-only SessionStart hook for the auto-upgrade dispatcher.
|
|
3787
3836
|
// Codex runs same-event hooks concurrently with no ordering, so this must
|
|
@@ -4166,4 +4215,4 @@ export {
|
|
|
4166
4215
|
untrackIgnoredFiles,
|
|
4167
4216
|
createProjectContext
|
|
4168
4217
|
};
|
|
4169
|
-
//# sourceMappingURL=chunk-
|
|
4218
|
+
//# sourceMappingURL=chunk-GEC7AHRF.js.map
|