@devrik-tools/claude-gates 0.1.2 → 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/.claude-plugin/marketplace.json +7 -1
- package/cli/__tests__/config.test.mjs +113 -101
- package/cli/__tests__/install.test.mjs +102 -0
- package/cli/__tests__/materialize.test.mjs +95 -0
- package/cli/__tests__/registry-gates-consistency.test.mjs +52 -44
- package/cli/__tests__/task.test.mjs +124 -0
- package/cli/__tests__/version-consistency.test.mjs +44 -0
- package/cli/config.mjs +124 -113
- package/cli/index.mjs +100 -97
- package/cli/init.mjs +259 -256
- package/cli/install.mjs +150 -80
- package/cli/materialize.mjs +102 -51
- package/cli/registry.mjs +136 -127
- package/cli/task.mjs +140 -0
- package/package.json +2 -1
- package/plugins/gates/.claude-plugin/plugin.json +8 -2
- package/plugins/gates/hooks/__tests__/ask-adoption.test.mjs +83 -0
- package/plugins/gates/hooks/__tests__/doctor.test.mjs +85 -0
- package/plugins/gates/hooks/__tests__/wiring-check.test.mjs +65 -0
- package/plugins/gates/hooks/ask-adoption.mjs +147 -0
- package/plugins/gates/hooks/doctor.mjs +207 -0
- package/plugins/gates/hooks/gates/audit-before-build/audit-before-build.edge.test.mjs +83 -0
- package/plugins/gates/hooks/gates/audit-before-build/index.mjs +88 -88
- package/plugins/gates/hooks/gates/audit-before-build/test.mjs +117 -92
- package/plugins/gates/hooks/gates/autonomous-mode/autonomous.edge.test.mjs +104 -0
- package/plugins/gates/hooks/gates/autonomous-mode/index.mjs +48 -45
- package/plugins/gates/hooks/gates/bash-commands/bash-commands.edge.test.mjs +165 -0
- package/plugins/gates/hooks/gates/bash-commands/index.mjs +285 -268
- package/plugins/gates/hooks/gates/brief-before-delegate/brief-before-delegate.edge.test.mjs +151 -0
- package/plugins/gates/hooks/gates/brief-before-delegate/index.mjs +265 -177
- package/plugins/gates/hooks/gates/circuit-breaker/circuit-breaker.edge.test.mjs +207 -0
- package/plugins/gates/hooks/gates/circuit-breaker/index.mjs +501 -456
- package/plugins/gates/hooks/gates/circuit-breaker/test.mjs +161 -143
- package/plugins/gates/hooks/gates/dependency-skills/dependency-skills.edge.test.mjs +69 -0
- package/plugins/gates/hooks/gates/dependency-skills/index.mjs +126 -118
- package/plugins/gates/hooks/gates/diagnosis-before-patch/diagnosis-before-patch.edge.test.mjs +68 -0
- package/plugins/gates/hooks/gates/diagnosis-before-patch/index.mjs +43 -49
- package/plugins/gates/hooks/gates/feature-catalog/edge.edge.test.mjs +83 -0
- package/plugins/gates/hooks/gates/feature-catalog/index.mjs +83 -100
- package/plugins/gates/hooks/gates/force-parallel/index.mjs +119 -0
- package/plugins/gates/hooks/gates/force-parallel/test.mjs +88 -0
- package/plugins/gates/hooks/gates/forge-flow/forge-flow.edge.test.mjs +155 -0
- package/plugins/gates/hooks/gates/forge-flow/index.mjs +134 -112
- package/plugins/gates/hooks/gates/implementation-pipeline/edge.edge.test.mjs +66 -0
- package/plugins/gates/hooks/gates/implementation-pipeline/index.mjs +187 -186
- package/plugins/gates/hooks/gates/intent-flow/index.mjs +260 -238
- package/plugins/gates/hooks/gates/intent-flow/intent-flow.edge.test.mjs +96 -0
- package/plugins/gates/hooks/gates/intent-flow/test.mjs +165 -136
- package/plugins/gates/hooks/gates/lint-commit/index.mjs +149 -0
- package/plugins/gates/hooks/gates/lint-commit/test.mjs +85 -0
- package/plugins/gates/hooks/gates/mandatory-flow/edge.edge.test.mjs +100 -0
- package/plugins/gates/hooks/gates/mandatory-flow/index.mjs +180 -166
- package/plugins/gates/hooks/gates/neutral-spanish/index.mjs +79 -85
- package/plugins/gates/hooks/gates/neutral-spanish/neutral-spanish.edge.test.mjs +80 -0
- package/plugins/gates/hooks/gates/never-assume/index.mjs +58 -55
- package/plugins/gates/hooks/gates/never-assume/never-assume.edge.test.mjs +71 -0
- package/plugins/gates/hooks/gates/never-assume/test.mjs +95 -78
- package/plugins/gates/hooks/gates/no-blocking/index.mjs +148 -142
- package/plugins/gates/hooks/gates/no-blocking/no-blocking.edge.test.mjs +109 -0
- package/plugins/gates/hooks/gates/no-memory-dependency/index.mjs +123 -120
- package/plugins/gates/hooks/gates/no-memory-dependency/no-memory-dependency.edge.test.mjs +83 -0
- package/plugins/gates/hooks/gates/no-reconfirm/no-reconfirm.edge.test.mjs +91 -0
- package/plugins/gates/hooks/gates/protected-paths/index.mjs +144 -147
- package/plugins/gates/hooks/gates/protected-paths/protected-paths.edge.test.mjs +126 -0
- package/plugins/gates/hooks/gates/recurrence-lock/index.mjs +89 -64
- package/plugins/gates/hooks/gates/recurrence-lock/recurrence-lock.edge.test.mjs +102 -0
- package/plugins/gates/hooks/gates/reuse-before-build/edge.edge.test.mjs +94 -0
- package/plugins/gates/hooks/gates/reuse-before-build/index.mjs +159 -150
- package/plugins/gates/hooks/gates/risk-level/index.mjs +263 -203
- package/plugins/gates/hooks/gates/risk-level/risk-level.edge.test.mjs +116 -0
- package/plugins/gates/hooks/gates/risk-level/test.mjs +153 -125
- package/plugins/gates/hooks/gates/root-cause-first/index.mjs +56 -50
- package/plugins/gates/hooks/gates/root-cause-first/root-cause-first.edge.test.mjs +58 -0
- package/plugins/gates/hooks/gates/root-whitelist/index.mjs +116 -111
- package/plugins/gates/hooks/gates/root-whitelist/root-whitelist.edge.test.mjs +97 -0
- package/plugins/gates/hooks/gates/rule-skill-autodiscovery/index.mjs +184 -99
- package/plugins/gates/hooks/gates/rule-skill-autodiscovery/rule-skill-autodiscovery.edge.test.mjs +126 -0
- package/plugins/gates/hooks/gates/sdd-specs/edge.edge.test.mjs +130 -0
- package/plugins/gates/hooks/gates/sdd-specs/index.mjs +256 -251
- package/plugins/gates/hooks/gates/stop-pending/index.mjs +159 -0
- package/plugins/gates/hooks/gates/stop-pending/test.mjs +114 -0
- package/plugins/gates/hooks/gates/test-after-implementation/index.mjs +101 -101
- package/plugins/gates/hooks/gates/test-after-implementation/test-after-implementation.edge.test.mjs +72 -0
- package/plugins/gates/hooks/gates/test-matrix/edge.edge.test.mjs +63 -0
- package/plugins/gates/hooks/gates/test-matrix/index.mjs +187 -181
- package/plugins/gates/hooks/gates/test-matrix/test.mjs +114 -87
- package/plugins/gates/hooks/gates/tool-map/edge.edge.test.mjs +62 -0
- package/plugins/gates/hooks/gates/tool-map/index.mjs +143 -140
- package/plugins/gates/hooks/hooks.json +346 -286
- package/plugins/gates/hooks/lib/__tests__/config.test.mjs +173 -154
- package/plugins/gates/hooks/lib/__tests__/hook-io.test.mjs +210 -154
- package/plugins/gates/hooks/lib/__tests__/signals.test.mjs +114 -0
- package/plugins/gates/hooks/lib/config.mjs +172 -165
- package/plugins/gates/hooks/lib/hook-io-config.edge.test.mjs +189 -0
- package/plugins/gates/hooks/lib/hook-io.mjs +318 -208
- package/plugins/gates/hooks/lib/signals.mjs +127 -0
- package/plugins/gates/hooks/wiring-check.mjs +227 -0
- package/plugins/tasks/.claude-plugin/plugin.json +14 -0
- package/plugins/tasks/hooks/__tests__/register-requests.test.mjs +100 -0
- package/plugins/tasks/hooks/__tests__/session-tasks.test.mjs +95 -0
- package/plugins/tasks/hooks/hooks.json +26 -0
- package/plugins/tasks/hooks/lib/__tests__/task-store.test.mjs +180 -132
- package/plugins/tasks/hooks/lib/task-store.mjs +197 -159
- package/plugins/tasks/hooks/register-requests.mjs +141 -108
- package/plugins/tasks/hooks/session-tasks.mjs +108 -0
- package/registry.json +793 -686
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// session-tasks — SessionStart hook. Runs once when a session opens. Lists this project's
|
|
2
|
+
// ACTIVE tasks (open/blocked/in_forge) so a fresh session (or one that just compacted) does
|
|
3
|
+
// not lose track of what was already registered. Silent when there is nothing active: this
|
|
4
|
+
// hook only speaks when it has something worth saying.
|
|
5
|
+
//
|
|
6
|
+
// Self-contained: Node built-ins + the task-store lib only, no npm at runtime.
|
|
7
|
+
//
|
|
8
|
+
// justification: no existing tool covers this. task-store.mjs (and its audit) already
|
|
9
|
+
// exists; this is the SessionStart wiring on top of it, mirroring register-requests.mjs's
|
|
10
|
+
// UserPromptSubmit wiring for the same store.
|
|
11
|
+
|
|
12
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
13
|
+
import { homedir } from 'node:os';
|
|
14
|
+
import { dirname, join } from 'node:path';
|
|
15
|
+
import { openTaskStore, STATUS } from './lib/task-store.mjs';
|
|
16
|
+
|
|
17
|
+
const STDIN_FILE_DESCRIPTOR = 0;
|
|
18
|
+
const SESSION_START_EVENT = 'SessionStart';
|
|
19
|
+
const CONFIG_KEY = 'listTasksOnSessionStart';
|
|
20
|
+
const MAX_TASKS_SHOWN = 20;
|
|
21
|
+
|
|
22
|
+
// Same config lookup as register-requests.mjs: project overrides global. Kept local so this
|
|
23
|
+
// plugin stays independent of the gates plugin.
|
|
24
|
+
const PROJECT_ROOT_MARKERS = ['.git', '.ai'];
|
|
25
|
+
const PROJECT_CONFIG = join('.ai', 'config.json');
|
|
26
|
+
const GLOBAL_CONFIG = join('.claude', 'claude-gates', 'config.json');
|
|
27
|
+
|
|
28
|
+
function readJson(path) {
|
|
29
|
+
try {
|
|
30
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function projectRootOf(startDirectory) {
|
|
37
|
+
let current = startDirectory;
|
|
38
|
+
while (true) {
|
|
39
|
+
if (
|
|
40
|
+
PROJECT_ROOT_MARKERS.some((marker) => existsSync(join(current, marker)))
|
|
41
|
+
) {
|
|
42
|
+
return current;
|
|
43
|
+
}
|
|
44
|
+
const parent = dirname(current);
|
|
45
|
+
if (parent === current) return null;
|
|
46
|
+
current = parent;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The tasks gate config entry (project overrides global), or null. */
|
|
51
|
+
function sessionTasksConfig(startDirectory) {
|
|
52
|
+
const root = projectRootOf(startDirectory);
|
|
53
|
+
const projectData = root ? readJson(join(root, PROJECT_CONFIG)) : null;
|
|
54
|
+
const globalData = readJson(join(homedir(), GLOBAL_CONFIG));
|
|
55
|
+
const layer = projectData?.gates ?? globalData?.gates ?? {};
|
|
56
|
+
const entry = layer[CONFIG_KEY];
|
|
57
|
+
if (typeof entry === 'boolean') return { enabled: entry };
|
|
58
|
+
if (entry && typeof entry === 'object') return entry;
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function readPayload() {
|
|
63
|
+
try {
|
|
64
|
+
return JSON.parse(readFileSync(STDIN_FILE_DESCRIPTOR, 'utf8'));
|
|
65
|
+
} catch {
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function formatActiveTasks(tasks) {
|
|
71
|
+
const shown = tasks.slice(0, MAX_TASKS_SHOWN);
|
|
72
|
+
const lines = shown.map((task) => {
|
|
73
|
+
const marker = task.status === STATUS.IN_FORGE ? ' (in_forge)' : '';
|
|
74
|
+
return ` - ${task.id}: ${task.title} [${task.status}]${marker}`;
|
|
75
|
+
});
|
|
76
|
+
const extra = tasks.length - shown.length;
|
|
77
|
+
if (extra > 0) lines.push(` - …and ${extra} more`);
|
|
78
|
+
return `[tasks] Active tasks for this project:\n${lines.join('\n')}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function speak(context) {
|
|
82
|
+
process.stdout.write(
|
|
83
|
+
JSON.stringify({
|
|
84
|
+
hookSpecificOutput: {
|
|
85
|
+
hookEventName: SESSION_START_EVENT,
|
|
86
|
+
additionalContext: context,
|
|
87
|
+
},
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function main() {
|
|
93
|
+
const payload = readPayload();
|
|
94
|
+
const cwd = payload.cwd || process.cwd();
|
|
95
|
+
|
|
96
|
+
const config = sessionTasksConfig(cwd);
|
|
97
|
+
if (config && config.enabled === false) return; // gate turned off for this project
|
|
98
|
+
|
|
99
|
+
const store = openTaskStore(cwd);
|
|
100
|
+
if (!store) return; // no project: nowhere to track
|
|
101
|
+
|
|
102
|
+
const tasks = store.active();
|
|
103
|
+
if (tasks.length === 0) return; // nothing active: stay silent
|
|
104
|
+
|
|
105
|
+
speak(formatActiveTasks(tasks));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
main();
|