claude-prism 1.7.0 → 1.7.2
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/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +14 -0
- package/lib/config.mjs +15 -1
- package/lib/pipeline.mjs +11 -7
- package/package.json +1 -1
- package/templates/rules.md +5 -0
- package/templates/runners/precompact.mjs +4 -2
- package/templates/runners/session-end.mjs +4 -2
- package/templates/runners/subagent-start.mjs +4 -2
- package/templates/runners/task-completed.mjs +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.7.2] — 2026-03-06
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **Plan template frontmatter** — EUDEC plan template now includes `status: draft` frontmatter, so plans created during DECOMPOSE phase participate in lifecycle management automatically
|
|
12
|
+
|
|
13
|
+
## [1.7.1] — 2026-03-06
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- **Monorepo hook compatibility** — hooks now use `input.cwd` from Claude Code instead of `process.cwd()` to resolve the correct project root
|
|
17
|
+
- `findProjectRoot()` upward search for nearest `.prism/config.json` — prevents wrong config in monorepo setups
|
|
18
|
+
- `config.projectRoot` injection for all hook rules — existing `config.projectRoot || process.cwd()` fallbacks now receive the correct value
|
|
19
|
+
- All 4 template runners (`precompact`, `session-end`, `subagent-start`, `task-completed`) updated to use `findProjectRoot(input.cwd)`
|
|
20
|
+
- `pipeline.mjs` — `runPipeline()`, `runPipelineAsync()`, `loadCustomRules()` all resolve project root from hook input
|
|
21
|
+
|
|
8
22
|
## [1.7.0] — 2026-03-06
|
|
9
23
|
|
|
10
24
|
### Added
|
package/lib/config.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { readFileSync, existsSync } from 'fs';
|
|
7
|
-
import { join } from 'path';
|
|
7
|
+
import { join, dirname } from 'path';
|
|
8
8
|
|
|
9
9
|
const DEFAULTS = {
|
|
10
10
|
rulesMode: 'full',
|
|
@@ -23,6 +23,20 @@ const DEFAULTS = {
|
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Search upward from startDir for nearest .prism/config.json
|
|
28
|
+
* @param {string} startDir - Directory to start searching from
|
|
29
|
+
* @returns {string} Project root with .prism/config.json, or startDir as fallback
|
|
30
|
+
*/
|
|
31
|
+
export function findProjectRoot(startDir) {
|
|
32
|
+
let current = startDir;
|
|
33
|
+
while (current !== dirname(current)) {
|
|
34
|
+
if (existsSync(join(current, '.prism', 'config.json'))) return current;
|
|
35
|
+
current = dirname(current);
|
|
36
|
+
}
|
|
37
|
+
return startDir;
|
|
38
|
+
}
|
|
39
|
+
|
|
26
40
|
export function loadConfig(projectRoot) {
|
|
27
41
|
const configPath = join(projectRoot, '.prism', 'config.json');
|
|
28
42
|
|
package/lib/pipeline.mjs
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { readFileSync } from 'fs';
|
|
7
7
|
import { join } from 'path';
|
|
8
8
|
import { sanitizeId } from './utils.mjs';
|
|
9
|
-
import { loadConfig } from './config.mjs';
|
|
9
|
+
import { loadConfig, findProjectRoot } from './config.mjs';
|
|
10
10
|
import { getStateDir } from './state.mjs';
|
|
11
11
|
import { logEvent } from './session.mjs';
|
|
12
12
|
|
|
@@ -68,8 +68,10 @@ export function runPipeline(rules, hookEventName) {
|
|
|
68
68
|
const input = parseInput();
|
|
69
69
|
if (!input) process.exit(0);
|
|
70
70
|
|
|
71
|
-
//
|
|
72
|
-
const
|
|
71
|
+
// Resolve project root from hook input's cwd (monorepo-safe)
|
|
72
|
+
const projectRoot = findProjectRoot(input.cwd || process.cwd());
|
|
73
|
+
const fullConfig = loadConfig(projectRoot);
|
|
74
|
+
fullConfig.projectRoot = projectRoot;
|
|
73
75
|
|
|
74
76
|
const ctx = toContext(input, hookEventName);
|
|
75
77
|
const stateDir = getStateDir(ctx.sessionId, ctx.agentId);
|
|
@@ -128,13 +130,13 @@ export function runPipeline(rules, hookEventName) {
|
|
|
128
130
|
* @param {string[]} customRulePaths - Paths relative to project root
|
|
129
131
|
* @returns {Promise<Array<{name: string, rule: Object}>>}
|
|
130
132
|
*/
|
|
131
|
-
export async function loadCustomRules(builtInRules, customRulePaths) {
|
|
133
|
+
export async function loadCustomRules(builtInRules, customRulePaths, projectRoot) {
|
|
132
134
|
if (!customRulePaths || customRulePaths.length === 0) return builtInRules;
|
|
133
135
|
|
|
134
136
|
const rules = [...builtInRules];
|
|
135
137
|
for (const rulePath of customRulePaths) {
|
|
136
138
|
try {
|
|
137
|
-
const absPath = join(process.cwd(), rulePath);
|
|
139
|
+
const absPath = join(projectRoot || process.cwd(), rulePath);
|
|
138
140
|
const mod = await import(absPath);
|
|
139
141
|
const rule = mod.default || mod[Object.keys(mod)[0]];
|
|
140
142
|
if (rule && typeof rule.evaluate === 'function') {
|
|
@@ -156,9 +158,11 @@ export async function runPipelineAsync(builtInRules, hookEventName) {
|
|
|
156
158
|
const input = parseInput();
|
|
157
159
|
if (!input) process.exit(0);
|
|
158
160
|
|
|
159
|
-
const
|
|
161
|
+
const projectRoot = findProjectRoot(input.cwd || process.cwd());
|
|
162
|
+
const fullConfig = loadConfig(projectRoot);
|
|
163
|
+
fullConfig.projectRoot = projectRoot;
|
|
160
164
|
const customRulePaths = fullConfig.customRules || [];
|
|
161
|
-
const rules = await loadCustomRules(builtInRules, customRulePaths);
|
|
165
|
+
const rules = await loadCustomRules(builtInRules, customRulePaths, projectRoot);
|
|
162
166
|
|
|
163
167
|
const ctx = toContext(input, hookEventName);
|
|
164
168
|
const stateDir = getStateDir(ctx.sessionId, ctx.agentId);
|
package/package.json
CHANGED
package/templates/rules.md
CHANGED
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { readFileSync } from 'fs';
|
|
7
7
|
import { precompactHandler } from '../rules/precompact-handler.mjs';
|
|
8
|
-
import { loadConfig } from '../lib/config.mjs';
|
|
8
|
+
import { loadConfig, findProjectRoot } from '../lib/config.mjs';
|
|
9
9
|
|
|
10
10
|
try {
|
|
11
11
|
const input = JSON.parse(readFileSync(0, 'utf8'));
|
|
12
|
-
const
|
|
12
|
+
const projectRoot = findProjectRoot(input.cwd || process.cwd());
|
|
13
|
+
const config = loadConfig(projectRoot);
|
|
14
|
+
config.projectRoot = projectRoot;
|
|
13
15
|
const result = precompactHandler.evaluate(input, config);
|
|
14
16
|
if (result) {
|
|
15
17
|
process.stdout.write(JSON.stringify(result));
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { readFileSync } from 'fs';
|
|
7
7
|
import { sessionEndHandler } from '../rules/session-end-handler.mjs';
|
|
8
|
-
import { loadConfig } from '../lib/config.mjs';
|
|
8
|
+
import { loadConfig, findProjectRoot } from '../lib/config.mjs';
|
|
9
9
|
|
|
10
10
|
try {
|
|
11
11
|
const input = JSON.parse(readFileSync(0, 'utf8'));
|
|
12
|
-
const
|
|
12
|
+
const projectRoot = findProjectRoot(input.cwd || process.cwd());
|
|
13
|
+
const config = loadConfig(projectRoot);
|
|
14
|
+
config.projectRoot = projectRoot;
|
|
13
15
|
const result = sessionEndHandler.evaluate(input, config);
|
|
14
16
|
if (result) {
|
|
15
17
|
process.stdout.write(JSON.stringify(result));
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { readFileSync } from 'fs';
|
|
7
7
|
import { scopeInjector } from '../rules/subagent-scope-injector.mjs';
|
|
8
|
-
import { loadConfig } from '../lib/config.mjs';
|
|
8
|
+
import { loadConfig, findProjectRoot } from '../lib/config.mjs';
|
|
9
9
|
|
|
10
10
|
try {
|
|
11
11
|
const input = JSON.parse(readFileSync(0, 'utf8'));
|
|
12
|
-
const
|
|
12
|
+
const projectRoot = findProjectRoot(input.cwd || process.cwd());
|
|
13
|
+
const config = loadConfig(projectRoot);
|
|
14
|
+
config.projectRoot = projectRoot;
|
|
13
15
|
const result = scopeInjector.evaluate(input, config);
|
|
14
16
|
if (result) {
|
|
15
17
|
process.stdout.write(JSON.stringify(result));
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { readFileSync } from 'fs';
|
|
7
7
|
import { planSync } from '../rules/task-plan-sync.mjs';
|
|
8
|
-
import { loadConfig } from '../lib/config.mjs';
|
|
8
|
+
import { loadConfig, findProjectRoot } from '../lib/config.mjs';
|
|
9
9
|
|
|
10
10
|
try {
|
|
11
11
|
const input = JSON.parse(readFileSync(0, 'utf8'));
|
|
12
|
-
const
|
|
12
|
+
const projectRoot = findProjectRoot(input.cwd || process.cwd());
|
|
13
|
+
const config = loadConfig(projectRoot);
|
|
14
|
+
config.projectRoot = projectRoot;
|
|
13
15
|
const result = planSync.evaluate(input, config);
|
|
14
16
|
if (result) {
|
|
15
17
|
process.stdout.write(JSON.stringify(result));
|