@slope-dev/slope 1.12.0 → 1.13.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/README.md +17 -2
- package/dist/adapters.d.ts +12 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +15 -0
- package/dist/adapters.js.map +1 -0
- package/dist/cli/commands/guard.d.ts.map +1 -1
- package/dist/cli/commands/guard.js +2 -0
- package/dist/cli/commands/guard.js.map +1 -1
- package/dist/cli/commands/hook.d.ts +4 -0
- package/dist/cli/commands/hook.d.ts.map +1 -1
- package/dist/cli/commands/hook.js +57 -83
- package/dist/cli/commands/hook.js.map +1 -1
- package/dist/cli/commands/init.d.ts +10 -3
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +78 -9
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/map.d.ts.map +1 -1
- package/dist/cli/commands/map.js +8 -19
- package/dist/cli/commands/map.js.map +1 -1
- package/dist/cli/commands/roadmap.d.ts.map +1 -1
- package/dist/cli/commands/roadmap.js +94 -1
- package/dist/cli/commands/roadmap.js.map +1 -1
- package/dist/cli/guards/branch-before-commit.d.ts +7 -0
- package/dist/cli/guards/branch-before-commit.d.ts.map +1 -0
- package/dist/cli/guards/branch-before-commit.js +43 -0
- package/dist/cli/guards/branch-before-commit.js.map +1 -0
- package/dist/cli/guards/stop-check.d.ts +4 -0
- package/dist/cli/guards/stop-check.d.ts.map +1 -1
- package/dist/cli/guards/stop-check.js +50 -16
- package/dist/cli/guards/stop-check.js.map +1 -1
- package/dist/cli/registry.d.ts +12 -0
- package/dist/cli/registry.d.ts.map +1 -0
- package/dist/cli/registry.js +40 -0
- package/dist/cli/registry.js.map +1 -0
- package/dist/core/adapters/claude-code.d.ts +25 -0
- package/dist/core/adapters/claude-code.d.ts.map +1 -0
- package/dist/core/adapters/claude-code.js +133 -0
- package/dist/core/adapters/claude-code.js.map +1 -0
- package/dist/core/adapters/cursor.d.ts +35 -0
- package/dist/core/adapters/cursor.d.ts.map +1 -0
- package/dist/core/adapters/cursor.js +138 -0
- package/dist/core/adapters/cursor.js.map +1 -0
- package/dist/core/adapters/generic.d.ts +26 -0
- package/dist/core/adapters/generic.d.ts.map +1 -0
- package/dist/core/adapters/generic.js +137 -0
- package/dist/core/adapters/generic.js.map +1 -0
- package/dist/core/adapters/windsurf.d.ts +34 -0
- package/dist/core/adapters/windsurf.d.ts.map +1 -0
- package/dist/core/adapters/windsurf.js +165 -0
- package/dist/core/adapters/windsurf.js.map +1 -0
- package/dist/core/config.d.ts +1 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/guard.d.ts +10 -3
- package/dist/core/guard.d.ts.map +1 -1
- package/dist/core/guard.js +33 -59
- package/dist/core/guard.js.map +1 -1
- package/dist/core/harness.d.ts +55 -0
- package/dist/core/harness.d.ts.map +1 -0
- package/dist/core/harness.js +88 -0
- package/dist/core/harness.js.map +1 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
|
@@ -2,26 +2,51 @@ import { execSync } from 'node:child_process';
|
|
|
2
2
|
/**
|
|
3
3
|
* Stop check guard: fires on Stop.
|
|
4
4
|
* Checks for uncommitted/unpushed work before session end.
|
|
5
|
+
*
|
|
6
|
+
* Modified/staged/deleted files → block (real uncommitted work).
|
|
7
|
+
* Untracked-only files → warn via context (may be orphaned/intentional).
|
|
8
|
+
* Unpushed commits → block (recovery point not preserved).
|
|
5
9
|
*/
|
|
6
10
|
export async function stopCheckGuard(input, cwd) {
|
|
7
|
-
const
|
|
11
|
+
const blockingIssues = [];
|
|
12
|
+
const warningIssues = [];
|
|
8
13
|
// Check for uncommitted changes (excluding gitignored files)
|
|
9
14
|
try {
|
|
10
15
|
const status = execSync('git status --porcelain 2>/dev/null', { cwd, encoding: 'utf8' }).trim();
|
|
11
16
|
if (status.length > 0) {
|
|
12
|
-
const
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
const lines = status.split('\n').filter(Boolean);
|
|
18
|
+
// Separate untracked (??) from modified/staged/deleted
|
|
19
|
+
const untrackedPaths = [];
|
|
20
|
+
const modifiedPaths = [];
|
|
21
|
+
for (const line of lines) {
|
|
22
|
+
const statusCode = line.slice(0, 2);
|
|
23
|
+
const path = line.slice(3);
|
|
24
|
+
if (statusCode === '??') {
|
|
25
|
+
untrackedPaths.push(path);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
modifiedPaths.push(path);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Filter out gitignored files from both lists
|
|
32
|
+
const allPaths = [...modifiedPaths, ...untrackedPaths];
|
|
33
|
+
const ignoredSet = new Set();
|
|
34
|
+
if (allPaths.length > 0) {
|
|
16
35
|
try {
|
|
17
|
-
const ignored = execSync(`git check-ignore ${
|
|
18
|
-
const
|
|
19
|
-
|
|
36
|
+
const ignored = execSync(`git check-ignore ${allPaths.map(p => `'${p}'`).join(' ')} 2>/dev/null`, { cwd, encoding: 'utf8' }).trim();
|
|
37
|
+
for (const p of ignored.split('\n').filter(Boolean)) {
|
|
38
|
+
ignoredSet.add(p);
|
|
39
|
+
}
|
|
20
40
|
}
|
|
21
41
|
catch { /* check-ignore exits 1 when no files are ignored — all files are real changes */ }
|
|
22
42
|
}
|
|
23
|
-
|
|
24
|
-
|
|
43
|
+
const filteredModified = modifiedPaths.filter(p => !ignoredSet.has(p));
|
|
44
|
+
const filteredUntracked = untrackedPaths.filter(p => !ignoredSet.has(p));
|
|
45
|
+
if (filteredModified.length > 0) {
|
|
46
|
+
blockingIssues.push(`${filteredModified.length} uncommitted change${filteredModified.length === 1 ? '' : 's'}`);
|
|
47
|
+
}
|
|
48
|
+
if (filteredUntracked.length > 0) {
|
|
49
|
+
warningIssues.push(`${filteredUntracked.length} untracked file${filteredUntracked.length === 1 ? '' : 's'}`);
|
|
25
50
|
}
|
|
26
51
|
}
|
|
27
52
|
}
|
|
@@ -32,15 +57,24 @@ export async function stopCheckGuard(input, cwd) {
|
|
|
32
57
|
if (unpushed) {
|
|
33
58
|
const lines = unpushed.split('\n').filter(Boolean);
|
|
34
59
|
if (lines.length > 0) {
|
|
35
|
-
|
|
60
|
+
blockingIssues.push(`${lines.length} unpushed commit${lines.length === 1 ? '' : 's'}`);
|
|
36
61
|
}
|
|
37
62
|
}
|
|
38
63
|
}
|
|
39
64
|
catch { /* no upstream */ }
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
65
|
+
// Blocking issues take priority
|
|
66
|
+
if (blockingIssues.length > 0) {
|
|
67
|
+
const allIssues = [...blockingIssues, ...warningIssues];
|
|
68
|
+
return {
|
|
69
|
+
blockReason: `SLOPE: ${allIssues.join(' and ')} detected. Commit and push before stopping to preserve your recovery point.`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Untracked-only: warn but don't block
|
|
73
|
+
if (warningIssues.length > 0) {
|
|
74
|
+
return {
|
|
75
|
+
context: `SLOPE: ${warningIssues.join(' and ')} detected. Consider committing or cleaning up untracked files.`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {};
|
|
45
79
|
}
|
|
46
80
|
//# sourceMappingURL=stop-check.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stop-check.js","sourceRoot":"","sources":["../../../src/cli/guards/stop-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C
|
|
1
|
+
{"version":3,"file":"stop-check.js","sourceRoot":"","sources":["../../../src/cli/guards/stop-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface CliCommandMeta {
|
|
2
|
+
/** Command name as invoked: e.g. "init", "auto-card" */
|
|
3
|
+
cmd: string;
|
|
4
|
+
/** Short description of the command */
|
|
5
|
+
desc: string;
|
|
6
|
+
/** Functional category */
|
|
7
|
+
category: 'lifecycle' | 'scoring' | 'analysis' | 'tooling' | 'planning';
|
|
8
|
+
}
|
|
9
|
+
/** Command files that are internal implementation modules, not user-invocable top-level commands. */
|
|
10
|
+
export declare const CLI_INTERNAL_MODULES: readonly ["review-state"];
|
|
11
|
+
export declare const CLI_COMMAND_REGISTRY: readonly CliCommandMeta[];
|
|
12
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/cli/registry.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,QAAQ,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;CACzE;AAED,qGAAqG;AACrG,eAAO,MAAM,oBAAoB,2BAA4B,CAAC;AAE9D,eAAO,MAAM,oBAAoB,EAAE,SAAS,cAAc,EAuCzD,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// CLI Command Registry — metadata for CLI commands (map generation, documentation, slope-web)
|
|
2
|
+
/** Command files that are internal implementation modules, not user-invocable top-level commands. */
|
|
3
|
+
export const CLI_INTERNAL_MODULES = ['review-state'];
|
|
4
|
+
export const CLI_COMMAND_REGISTRY = [
|
|
5
|
+
// ── Lifecycle ──────────────────────────────────────────────────
|
|
6
|
+
{ cmd: 'init', desc: 'Initialize .slope/ directory', category: 'lifecycle' },
|
|
7
|
+
{ cmd: 'session', desc: 'Manage live sessions', category: 'lifecycle' },
|
|
8
|
+
{ cmd: 'claim', desc: 'Claim a ticket or area for the sprint', category: 'lifecycle' },
|
|
9
|
+
{ cmd: 'release', desc: 'Release a claim by ID or target', category: 'lifecycle' },
|
|
10
|
+
{ cmd: 'status', desc: 'Show sprint course status and conflicts', category: 'lifecycle' },
|
|
11
|
+
{ cmd: 'next', desc: 'Show next sprint number (auto-detect)', category: 'lifecycle' },
|
|
12
|
+
// ── Scoring ────────────────────────────────────────────────────
|
|
13
|
+
{ cmd: 'card', desc: 'Display handicap card', category: 'scoring' },
|
|
14
|
+
{ cmd: 'validate', desc: 'Validate scorecard(s)', category: 'scoring' },
|
|
15
|
+
{ cmd: 'review', desc: 'Format sprint review or manage review state', category: 'scoring' },
|
|
16
|
+
{ cmd: 'auto-card', desc: 'Generate scorecard from git + CI signals', category: 'scoring' },
|
|
17
|
+
{ cmd: 'classify', desc: 'Classify a shot from execution trace', category: 'scoring' },
|
|
18
|
+
{ cmd: 'tournament', desc: 'Build tournament review from sprints', category: 'scoring' },
|
|
19
|
+
// ── Analysis ───────────────────────────────────────────────────
|
|
20
|
+
{ cmd: 'briefing', desc: 'Pre-round briefing with hazards and nutrition', category: 'analysis' },
|
|
21
|
+
{ cmd: 'plan', desc: 'Pre-shot advisor (club + training + hazards)', category: 'analysis' },
|
|
22
|
+
{ cmd: 'report', desc: 'Generate HTML performance report', category: 'analysis' },
|
|
23
|
+
{ cmd: 'dashboard', desc: 'Live local performance dashboard', category: 'analysis' },
|
|
24
|
+
{ cmd: 'standup', desc: 'Generate or ingest standup report', category: 'analysis' },
|
|
25
|
+
{ cmd: 'analyze', desc: 'Scan repo and generate profile', category: 'analysis' },
|
|
26
|
+
// ── Tooling ────────────────────────────────────────────────────
|
|
27
|
+
{ cmd: 'hook', desc: 'Manage lifecycle hooks', category: 'tooling' },
|
|
28
|
+
{ cmd: 'guard', desc: 'Run guard handler or manage guard activation', category: 'tooling' },
|
|
29
|
+
{ cmd: 'extract', desc: 'Extract events into SLOPE store', category: 'tooling' },
|
|
30
|
+
{ cmd: 'distill', desc: 'Promote event patterns to common issues', category: 'tooling' },
|
|
31
|
+
{ cmd: 'map', desc: 'Generate/update codebase map', category: 'tooling' },
|
|
32
|
+
{ cmd: 'flows', desc: 'Manage user flow definitions', category: 'tooling' },
|
|
33
|
+
{ cmd: 'plugin', desc: 'Manage custom plugins', category: 'tooling' },
|
|
34
|
+
{ cmd: 'escalate', desc: 'Escalate issues based on severity triggers', category: 'tooling' },
|
|
35
|
+
{ cmd: 'transcript', desc: 'View session transcript data', category: 'tooling' },
|
|
36
|
+
// ── Planning ───────────────────────────────────────────────────
|
|
37
|
+
{ cmd: 'roadmap', desc: 'Strategic planning and roadmap tools', category: 'planning' },
|
|
38
|
+
{ cmd: 'vision', desc: 'Display project vision document', category: 'planning' },
|
|
39
|
+
];
|
|
40
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/cli/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HarnessAdapter, ToolNameMap } from '../harness.js';
|
|
2
|
+
import type { GuardResult, AnyGuardDefinition, PreToolUseOutput, PostToolUseOutput, StopOutput } from '../guard.js';
|
|
3
|
+
/** Claude Code adapter — formats guard output for Claude Code's hook protocol. */
|
|
4
|
+
export declare class ClaudeCodeAdapter implements HarnessAdapter {
|
|
5
|
+
readonly id: "claude-code";
|
|
6
|
+
readonly displayName = "Claude Code";
|
|
7
|
+
readonly toolNames: ToolNameMap;
|
|
8
|
+
formatPreToolOutput(result: GuardResult): PreToolUseOutput;
|
|
9
|
+
formatPostToolOutput(result: GuardResult): PostToolUseOutput;
|
|
10
|
+
formatStopOutput(result: GuardResult): StopOutput;
|
|
11
|
+
generateHooksConfig(guards: AnyGuardDefinition[], guardScriptPath: string): Record<string, Array<{
|
|
12
|
+
matcher?: string;
|
|
13
|
+
hooks: Array<{
|
|
14
|
+
type: string;
|
|
15
|
+
command: string;
|
|
16
|
+
timeout?: number;
|
|
17
|
+
statusMessage?: string;
|
|
18
|
+
}>;
|
|
19
|
+
}>>;
|
|
20
|
+
installGuards(cwd: string, guards: AnyGuardDefinition[]): void;
|
|
21
|
+
detect(cwd: string): boolean;
|
|
22
|
+
}
|
|
23
|
+
/** Singleton instance */
|
|
24
|
+
export declare const claudeCodeAdapter: ClaudeCodeAdapter;
|
|
25
|
+
//# sourceMappingURL=claude-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/claude-code.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEpH,kFAAkF;AAClF,qBAAa,iBAAkB,YAAW,cAAc;IACtD,QAAQ,CAAC,EAAE,EAAG,aAAa,CAAU;IACrC,QAAQ,CAAC,WAAW,iBAAiB;IACrC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAqB;IAEpD,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB;IAW1D,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB;IAsB5D,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU;IAOjD,mBAAmB,CACjB,MAAM,EAAE,kBAAkB,EAAE,EAC5B,eAAe,EAAE,MAAM,GACtB,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAC;YAAC,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IA+BzI,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI;IA0D9D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;CAG7B;AAED,yBAAyB;AACzB,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// SLOPE ClaudeCodeAdapter — adapts guard framework to Claude Code's hook system.
|
|
2
|
+
import { existsSync, writeFileSync, readFileSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { CLAUDE_CODE_TOOLS, registerAdapter } from '../harness.js';
|
|
5
|
+
/** Claude Code adapter — formats guard output for Claude Code's hook protocol. */
|
|
6
|
+
export class ClaudeCodeAdapter {
|
|
7
|
+
id = 'claude-code';
|
|
8
|
+
displayName = 'Claude Code';
|
|
9
|
+
toolNames = CLAUDE_CODE_TOOLS;
|
|
10
|
+
formatPreToolOutput(result) {
|
|
11
|
+
return {
|
|
12
|
+
hookSpecificOutput: {
|
|
13
|
+
hookEventName: 'PreToolUse',
|
|
14
|
+
...(result.decision && { permissionDecision: result.decision }),
|
|
15
|
+
...(result.blockReason && { permissionDecisionReason: result.blockReason }),
|
|
16
|
+
...(result.context && { additionalContext: result.context }),
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
formatPostToolOutput(result) {
|
|
21
|
+
if (result.blockReason) {
|
|
22
|
+
return {
|
|
23
|
+
decision: 'block',
|
|
24
|
+
reason: result.blockReason,
|
|
25
|
+
hookSpecificOutput: {
|
|
26
|
+
hookEventName: 'PostToolUse',
|
|
27
|
+
...(result.context && { additionalContext: result.context }),
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (result.context) {
|
|
32
|
+
return {
|
|
33
|
+
hookSpecificOutput: {
|
|
34
|
+
hookEventName: 'PostToolUse',
|
|
35
|
+
additionalContext: result.context,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
formatStopOutput(result) {
|
|
42
|
+
if (result.blockReason) {
|
|
43
|
+
return { decision: 'block', reason: result.blockReason };
|
|
44
|
+
}
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
generateHooksConfig(guards, guardScriptPath) {
|
|
48
|
+
const config = {};
|
|
49
|
+
// Group guards by hookEvent + matcher
|
|
50
|
+
const groups = new Map();
|
|
51
|
+
for (const g of guards) {
|
|
52
|
+
const key = `${g.hookEvent}::${g.matcher ?? ''}`;
|
|
53
|
+
const list = groups.get(key) || [];
|
|
54
|
+
list.push(g);
|
|
55
|
+
groups.set(key, list);
|
|
56
|
+
}
|
|
57
|
+
for (const [key, defs] of groups) {
|
|
58
|
+
const [hookEvent, matcher] = key.split('::');
|
|
59
|
+
if (!config[hookEvent])
|
|
60
|
+
config[hookEvent] = [];
|
|
61
|
+
const hooks = defs.map(d => ({
|
|
62
|
+
type: 'command',
|
|
63
|
+
command: `${guardScriptPath} ${d.name}`,
|
|
64
|
+
timeout: 10,
|
|
65
|
+
statusMessage: `SLOPE: ${d.description}`,
|
|
66
|
+
}));
|
|
67
|
+
const entry = { hooks };
|
|
68
|
+
if (matcher)
|
|
69
|
+
entry.matcher = matcher;
|
|
70
|
+
config[hookEvent].push(entry);
|
|
71
|
+
}
|
|
72
|
+
return config;
|
|
73
|
+
}
|
|
74
|
+
installGuards(cwd, guards) {
|
|
75
|
+
const hooksDir = join(cwd, '.claude', 'hooks');
|
|
76
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
77
|
+
// Create the guard dispatcher script
|
|
78
|
+
const dispatcherPath = join(hooksDir, 'slope-guard.sh');
|
|
79
|
+
if (!existsSync(dispatcherPath)) {
|
|
80
|
+
const script = [
|
|
81
|
+
'#!/usr/bin/env bash',
|
|
82
|
+
'# SLOPE guard dispatcher — routes hook events to slope guard handlers',
|
|
83
|
+
'# Auto-generated by slope hook add --level=full',
|
|
84
|
+
'',
|
|
85
|
+
'# === SLOPE MANAGED (do not edit above this line) ===',
|
|
86
|
+
'slope guard "$@"',
|
|
87
|
+
'# === SLOPE END ===',
|
|
88
|
+
'',
|
|
89
|
+
].join('\n');
|
|
90
|
+
writeFileSync(dispatcherPath, script, { mode: 0o755 });
|
|
91
|
+
console.log(` Created ${dispatcherPath}`);
|
|
92
|
+
}
|
|
93
|
+
// Generate the hooks config for .claude/settings.json
|
|
94
|
+
const guardScript = '"$CLAUDE_PROJECT_DIR"/.claude/hooks/slope-guard.sh';
|
|
95
|
+
const hooksConfig = this.generateHooksConfig(guards, guardScript);
|
|
96
|
+
// Read and merge into .claude/settings.json
|
|
97
|
+
const settingsPath = join(cwd, '.claude', 'settings.json');
|
|
98
|
+
let settings = {};
|
|
99
|
+
if (existsSync(settingsPath)) {
|
|
100
|
+
try {
|
|
101
|
+
settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
|
|
102
|
+
}
|
|
103
|
+
catch { /* start fresh */ }
|
|
104
|
+
}
|
|
105
|
+
// Merge hooks — preserve existing non-SLOPE hooks
|
|
106
|
+
const existingHooks = (settings.hooks ?? {});
|
|
107
|
+
for (const [event, entries] of Object.entries(hooksConfig)) {
|
|
108
|
+
if (!existingHooks[event]) {
|
|
109
|
+
existingHooks[event] = [];
|
|
110
|
+
}
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
const entryWithMatcher = entry;
|
|
113
|
+
const existing = existingHooks[event];
|
|
114
|
+
const isDuplicate = existing.some(e => e.matcher === entryWithMatcher.matcher &&
|
|
115
|
+
e.hooks?.some(h => h.command?.includes('slope-guard.sh')));
|
|
116
|
+
if (!isDuplicate) {
|
|
117
|
+
existingHooks[event].push(entry);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
settings.hooks = existingHooks;
|
|
122
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
123
|
+
console.log(` Updated ${settingsPath} with guard hooks`);
|
|
124
|
+
}
|
|
125
|
+
detect(cwd) {
|
|
126
|
+
return existsSync(join(cwd, '.claude'));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/** Singleton instance */
|
|
130
|
+
export const claudeCodeAdapter = new ClaudeCodeAdapter();
|
|
131
|
+
// Auto-register on import
|
|
132
|
+
registerAdapter(claudeCodeAdapter);
|
|
133
|
+
//# sourceMappingURL=claude-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/core/adapters/claude-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { HarnessAdapter, ToolNameMap } from '../harness.js';
|
|
2
|
+
import type { GuardResult, AnyGuardDefinition } from '../guard.js';
|
|
3
|
+
/** Cursor hook entry in .cursor/hooks.json */
|
|
4
|
+
export interface CursorHookEntry {
|
|
5
|
+
event: string;
|
|
6
|
+
matcher?: string;
|
|
7
|
+
command: string;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
description?: string;
|
|
10
|
+
}
|
|
11
|
+
/** Cursor hooks config shape */
|
|
12
|
+
export interface CursorHooksConfig {
|
|
13
|
+
hooks: CursorHookEntry[];
|
|
14
|
+
}
|
|
15
|
+
/** Cursor hook output protocol */
|
|
16
|
+
export interface CursorHookOutput {
|
|
17
|
+
decision: 'allow' | 'block';
|
|
18
|
+
reason?: string;
|
|
19
|
+
context?: string;
|
|
20
|
+
}
|
|
21
|
+
/** Cursor adapter — formats guard output for Cursor's JSON hook protocol. */
|
|
22
|
+
export declare class CursorAdapter implements HarnessAdapter {
|
|
23
|
+
readonly id: "cursor";
|
|
24
|
+
readonly displayName = "Cursor";
|
|
25
|
+
readonly toolNames: ToolNameMap;
|
|
26
|
+
formatPreToolOutput(result: GuardResult): CursorHookOutput;
|
|
27
|
+
formatPostToolOutput(result: GuardResult): CursorHookOutput;
|
|
28
|
+
formatStopOutput(result: GuardResult): CursorHookOutput;
|
|
29
|
+
generateHooksConfig(guards: AnyGuardDefinition[], guardScriptPath: string): CursorHooksConfig;
|
|
30
|
+
installGuards(cwd: string, guards: AnyGuardDefinition[]): void;
|
|
31
|
+
detect(cwd: string): boolean;
|
|
32
|
+
}
|
|
33
|
+
/** Singleton instance */
|
|
34
|
+
export declare const cursorAdapter: CursorAdapter;
|
|
35
|
+
//# sourceMappingURL=cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/cursor.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAanE,8CAA8C;AAC9C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,gCAAgC;AAChC,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B;AAED,kCAAkC;AAClC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAYD,6EAA6E;AAC7E,qBAAa,aAAc,YAAW,cAAc;IAClD,QAAQ,CAAC,EAAE,EAAG,QAAQ,CAAU;IAChC,QAAQ,CAAC,WAAW,YAAY;IAChC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAgB;IAE/C,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB;IAe1D,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB;IAc3D,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB;IAUvD,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,EAAE,EAAE,eAAe,EAAE,MAAM,GAAG,iBAAiB;IAsB7F,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI;IAmD9D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;CAG7B;AAED,yBAAyB;AACzB,eAAO,MAAM,aAAa,eAAsB,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// SLOPE CursorAdapter — adapts guard framework to Cursor's hook system.
|
|
2
|
+
// Cursor (v1.7+) uses JSON stdin/stdout protocol with .cursor/hooks.json config.
|
|
3
|
+
import { existsSync, writeFileSync, readFileSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { registerAdapter, resolveToolMatcher } from '../harness.js';
|
|
6
|
+
/** Cursor tool name mappings */
|
|
7
|
+
const CURSOR_TOOLS = {
|
|
8
|
+
read_file: 'read_file',
|
|
9
|
+
write_file: 'file_edit|create_file',
|
|
10
|
+
search_files: 'list_directory',
|
|
11
|
+
search_content: 'grep_search',
|
|
12
|
+
execute_command: 'run_terminal_command',
|
|
13
|
+
create_subagent: 'create_subagent',
|
|
14
|
+
exit_plan: 'exit_plan',
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Map SLOPE hook events to Cursor hook events.
|
|
18
|
+
* PreCompact is intentionally omitted — Cursor has no pre-compaction hook.
|
|
19
|
+
*/
|
|
20
|
+
const HOOK_EVENT_MAP = {
|
|
21
|
+
PreToolUse: 'pre-tool-use',
|
|
22
|
+
PostToolUse: 'post-tool-use',
|
|
23
|
+
Stop: 'on-stop',
|
|
24
|
+
};
|
|
25
|
+
/** Cursor adapter — formats guard output for Cursor's JSON hook protocol. */
|
|
26
|
+
export class CursorAdapter {
|
|
27
|
+
id = 'cursor';
|
|
28
|
+
displayName = 'Cursor';
|
|
29
|
+
toolNames = CURSOR_TOOLS;
|
|
30
|
+
formatPreToolOutput(result) {
|
|
31
|
+
if (result.decision === 'deny' || result.blockReason) {
|
|
32
|
+
return {
|
|
33
|
+
decision: 'block',
|
|
34
|
+
...(result.blockReason && { reason: result.blockReason }),
|
|
35
|
+
...(result.context && { context: result.context }),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// 'ask' falls through to 'allow' — Cursor has no user-confirmation prompt
|
|
39
|
+
return {
|
|
40
|
+
decision: 'allow',
|
|
41
|
+
...(result.context && { context: result.context }),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
formatPostToolOutput(result) {
|
|
45
|
+
if (result.blockReason) {
|
|
46
|
+
return {
|
|
47
|
+
decision: 'block',
|
|
48
|
+
reason: result.blockReason,
|
|
49
|
+
...(result.context && { context: result.context }),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
decision: 'allow',
|
|
54
|
+
...(result.context && { context: result.context }),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
formatStopOutput(result) {
|
|
58
|
+
if (result.blockReason) {
|
|
59
|
+
return {
|
|
60
|
+
decision: 'block',
|
|
61
|
+
reason: result.blockReason,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return { decision: 'allow' };
|
|
65
|
+
}
|
|
66
|
+
generateHooksConfig(guards, guardScriptPath) {
|
|
67
|
+
const hooks = [];
|
|
68
|
+
for (const g of guards) {
|
|
69
|
+
const cursorEvent = HOOK_EVENT_MAP[g.hookEvent];
|
|
70
|
+
if (!cursorEvent)
|
|
71
|
+
continue; // Skip unsupported hook events
|
|
72
|
+
const matcher = resolveToolMatcher(this, 'toolCategories' in g ? g.toolCategories : undefined) ?? g.matcher;
|
|
73
|
+
const entry = {
|
|
74
|
+
event: cursorEvent,
|
|
75
|
+
command: `${guardScriptPath} ${g.name}`,
|
|
76
|
+
timeout: 10000,
|
|
77
|
+
description: `SLOPE: ${g.description}`,
|
|
78
|
+
};
|
|
79
|
+
if (matcher)
|
|
80
|
+
entry.matcher = matcher;
|
|
81
|
+
hooks.push(entry);
|
|
82
|
+
}
|
|
83
|
+
return { hooks };
|
|
84
|
+
}
|
|
85
|
+
installGuards(cwd, guards) {
|
|
86
|
+
const hooksDir = join(cwd, '.cursor', 'hooks');
|
|
87
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
88
|
+
// Create the guard dispatcher script
|
|
89
|
+
const dispatcherPath = join(hooksDir, 'slope-guard.sh');
|
|
90
|
+
if (!existsSync(dispatcherPath)) {
|
|
91
|
+
const script = [
|
|
92
|
+
'#!/usr/bin/env bash',
|
|
93
|
+
'# SLOPE guard dispatcher — routes hook events to slope guard handlers',
|
|
94
|
+
'# Auto-generated by slope hook add --level=full --harness=cursor',
|
|
95
|
+
'#',
|
|
96
|
+
'# Cursor passes JSON on stdin and reads JSON from stdout.',
|
|
97
|
+
'',
|
|
98
|
+
'# === SLOPE MANAGED (do not edit above this line) ===',
|
|
99
|
+
'slope guard "$@"',
|
|
100
|
+
'# === SLOPE END ===',
|
|
101
|
+
'',
|
|
102
|
+
].join('\n');
|
|
103
|
+
writeFileSync(dispatcherPath, script, { mode: 0o755 });
|
|
104
|
+
console.log(` Created ${dispatcherPath}`);
|
|
105
|
+
}
|
|
106
|
+
// Generate hooks config and merge into .cursor/hooks.json
|
|
107
|
+
// Command paths are relative to the project root (cwd), not the hooks.json file
|
|
108
|
+
const guardScript = '.cursor/hooks/slope-guard.sh';
|
|
109
|
+
const hooksConfig = this.generateHooksConfig(guards, guardScript);
|
|
110
|
+
const configPath = join(cwd, '.cursor', 'hooks.json');
|
|
111
|
+
let existing = { hooks: [] };
|
|
112
|
+
if (existsSync(configPath)) {
|
|
113
|
+
try {
|
|
114
|
+
existing = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
115
|
+
if (!Array.isArray(existing.hooks))
|
|
116
|
+
existing.hooks = [];
|
|
117
|
+
}
|
|
118
|
+
catch { /* start fresh */ }
|
|
119
|
+
}
|
|
120
|
+
// Merge — avoid duplicates by checking command
|
|
121
|
+
for (const entry of hooksConfig.hooks) {
|
|
122
|
+
const isDuplicate = existing.hooks.some(e => e.command === entry.command && e.event === entry.event);
|
|
123
|
+
if (!isDuplicate) {
|
|
124
|
+
existing.hooks.push(entry);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
writeFileSync(configPath, JSON.stringify(existing, null, 2) + '\n');
|
|
128
|
+
console.log(` Updated ${configPath} with guard hooks`);
|
|
129
|
+
}
|
|
130
|
+
detect(cwd) {
|
|
131
|
+
return existsSync(join(cwd, '.cursor'));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** Singleton instance */
|
|
135
|
+
export const cursorAdapter = new CursorAdapter();
|
|
136
|
+
// Auto-register on import
|
|
137
|
+
registerAdapter(cursorAdapter);
|
|
138
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../src/core/adapters/cursor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { HarnessAdapter, ToolNameMap } from '../harness.js';
|
|
2
|
+
import type { GuardResult, AnyGuardDefinition } from '../guard.js';
|
|
3
|
+
/** Guard manifest entry written to guards-manifest.json */
|
|
4
|
+
export interface GuardManifestEntry {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
hookEvent: string;
|
|
8
|
+
matcher?: string;
|
|
9
|
+
level: string;
|
|
10
|
+
command: string;
|
|
11
|
+
}
|
|
12
|
+
/** Generic adapter — works with any harness via shell scripts and JSON manifest. */
|
|
13
|
+
export declare class GenericAdapter implements HarnessAdapter {
|
|
14
|
+
readonly id: "generic";
|
|
15
|
+
readonly displayName = "Generic (Shell)";
|
|
16
|
+
readonly toolNames: ToolNameMap;
|
|
17
|
+
formatPreToolOutput(result: GuardResult): unknown;
|
|
18
|
+
formatPostToolOutput(result: GuardResult): unknown;
|
|
19
|
+
formatStopOutput(result: GuardResult): unknown;
|
|
20
|
+
generateHooksConfig(guards: AnyGuardDefinition[], guardScriptPath: string): GuardManifestEntry[];
|
|
21
|
+
installGuards(cwd: string, guards: AnyGuardDefinition[]): void;
|
|
22
|
+
detect(_cwd: string): boolean;
|
|
23
|
+
}
|
|
24
|
+
/** Singleton instance */
|
|
25
|
+
export declare const genericAdapter: GenericAdapter;
|
|
26
|
+
//# sourceMappingURL=generic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/generic.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAanE,2DAA2D;AAC3D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,oFAAoF;AACpF,qBAAa,cAAe,YAAW,cAAc;IACnD,QAAQ,CAAC,EAAE,EAAG,SAAS,CAAU;IACjC,QAAQ,CAAC,WAAW,qBAAqB;IACzC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAiB;IAEhD,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO;IAYjD,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO;IAQlD,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO;IAO9C,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,EAAE,EAAE,eAAe,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAehG,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI;IAyE9D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAI9B;AAED,yBAAyB;AACzB,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
|