@open-product-primer/cli 2.12.0 → 2.12.1
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/lib/claude-mods.js +20 -17
- package/package.json +1 -1
package/dist/lib/claude-mods.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
// {decision, reason} protocol — cannot draw UI).
|
|
10
10
|
// - 'plugin': a Claude Code function-hooks plugin (manifest + hooks.json + a register(on) module)
|
|
11
11
|
// installed at .claude/skills/<id>/, loaded via the project-scope skills-directory auto-load
|
|
12
|
-
// convention. Can draw UI ($.ui.
|
|
13
|
-
//
|
|
12
|
+
// convention. Can draw UI ($.ui.log, $.ui.render) but requires CLAUDE_CODE_ENABLE_FUNCTION_HOOKS
|
|
13
|
+
// and is early access — its API may move between releases.
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.CLAUDE_MODS_REGISTRY = void 0;
|
|
16
16
|
exports.isPluginMod = isPluginMod;
|
|
@@ -20,20 +20,25 @@ function isPluginMod(mod) {
|
|
|
20
20
|
}
|
|
21
21
|
// register(on) module: on a Write/Edit tool.call to a bet's specs/<capability>/spec.md delta,
|
|
22
22
|
// shells out to `oprim validate --json` (already runs checkSpecDeltaDrift()) and surfaces any
|
|
23
|
-
// MODIFIED/REMOVED drift for that capability
|
|
24
|
-
// validate/CI time. Never denies the call — this is a write-time convenience on top of
|
|
23
|
+
// MODIFIED/REMOVED drift for that capability as a transcript line, at write time instead of only
|
|
24
|
+
// at validate/CI time. Never denies the call — this is a write-time convenience on top of
|
|
25
25
|
// `oprim validate`, never a second source of required failures. Silently no-ops on any failure
|
|
26
26
|
// (oprim not resolvable, malformed report, etc.).
|
|
27
27
|
const SPEC_DELTA_DRIFT_INTERCEPTOR_REGISTER = `// Function-hooks module for the spec-delta-drift-interceptor mod — see claude-mods.ts.
|
|
28
|
-
// EARLY ACCESS: register(on)/$.ui.
|
|
29
|
-
// may change shape between Claude Code releases.
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
// EARLY ACCESS: register(on)/$.ui.log/$.process.run are gated behind
|
|
29
|
+
// CLAUDE_CODE_ENABLE_FUNCTION_HOOKS and may change shape between Claude Code releases. A hooks
|
|
30
|
+
// module may only import its own files by relative path and "claude-code" — no Node builtins — so
|
|
31
|
+
// shelling out goes through $.process.run, not node:child_process.
|
|
32
|
+
//
|
|
33
|
+
// Surfaces the drift as a transcript line via $.ui.log rather than $.ui.toast: a toast is a
|
|
34
|
+
// transient overlay whose rendering depends on the session's UI surface, while $.ui.log's default
|
|
35
|
+
// destination ("to: transcript") always lands as a plain line every surface shows — see the
|
|
36
|
+
// anthropics/claude-code \`mods/diff\` example, which uses the same call for its panel-toggle
|
|
37
|
+
// messages ("Diff panel shown"/"Diff panel hidden").
|
|
32
38
|
|
|
33
39
|
export function register(on) {
|
|
34
|
-
on('tool.call', async ($, e, next) => {
|
|
40
|
+
on('tool.call', { tool: ['Write', 'Edit'] }, async ($, e, next) => {
|
|
35
41
|
const result = await next(e);
|
|
36
|
-
if (e.tool !== 'Write' && e.tool !== 'Edit') return result;
|
|
37
42
|
|
|
38
43
|
try {
|
|
39
44
|
const filePath = String(e.file_path || '').replace(/\\\\/g, '/');
|
|
@@ -43,13 +48,11 @@ export function register(on) {
|
|
|
43
48
|
|
|
44
49
|
let output;
|
|
45
50
|
try {
|
|
46
|
-
output = execSync('npx --no-install oprim validate --json', {
|
|
47
|
-
encoding: 'utf-8',
|
|
48
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
49
|
-
});
|
|
50
|
-
} catch (err) {
|
|
51
51
|
// validate exits non-zero when a required check fails — stdout still carries the report
|
|
52
|
-
|
|
52
|
+
const res = await $.process.run(['npx', '--no-install', 'oprim', 'validate', '--json']);
|
|
53
|
+
output = res.stdout;
|
|
54
|
+
} catch {
|
|
55
|
+
output = null;
|
|
53
56
|
}
|
|
54
57
|
if (!output) return result;
|
|
55
58
|
|
|
@@ -60,7 +63,7 @@ export function register(on) {
|
|
|
60
63
|
if (drift.length === 0) return result;
|
|
61
64
|
|
|
62
65
|
const reason = drift.map((c) => \`\${c.name}\${c.note ? \` (\${c.note})\` : ''}\`).join('; ');
|
|
63
|
-
$.ui.
|
|
66
|
+
$.ui.log(\`⚠ Spec-delta drift in \${capability}: \${reason}\`);
|
|
64
67
|
} catch {
|
|
65
68
|
// Graceful degradation — never error or block on interceptor failure.
|
|
66
69
|
}
|