@soleri/cli 9.0.1 → 9.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/dist/commands/agent.js +116 -3
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/create.js +10 -3
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/hooks.js +43 -49
- package/dist/commands/hooks.js.map +1 -1
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.js +61 -12
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/pack.js +0 -1
- package/dist/commands/pack.js.map +1 -1
- package/dist/commands/staging.d.ts +2 -0
- package/dist/commands/staging.js +175 -0
- package/dist/commands/staging.js.map +1 -0
- package/dist/hook-packs/full/manifest.json +2 -2
- package/dist/hook-packs/installer.d.ts +4 -11
- package/dist/hook-packs/installer.js +192 -23
- package/dist/hook-packs/installer.js.map +1 -1
- package/dist/hook-packs/installer.ts +173 -60
- package/dist/hook-packs/registry.d.ts +16 -13
- package/dist/hook-packs/registry.js +13 -28
- package/dist/hook-packs/registry.js.map +1 -1
- package/dist/hook-packs/registry.ts +33 -46
- package/dist/hook-packs/yolo-safety/manifest.json +23 -0
- package/dist/hook-packs/yolo-safety/scripts/anti-deletion.sh +214 -0
- package/dist/hooks/templates.js +1 -1
- package/dist/hooks/templates.js.map +1 -1
- package/dist/main.js +2 -0
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/create.test.ts +6 -2
- package/src/__tests__/hook-packs.test.ts +66 -44
- package/src/__tests__/wizard-e2e.mjs +17 -11
- package/src/commands/agent.ts +146 -3
- package/src/commands/create.ts +8 -2
- package/src/commands/hooks.ts +88 -187
- package/src/commands/install.ts +62 -22
- package/src/commands/pack.ts +0 -1
- package/src/commands/staging.ts +208 -0
- package/src/hook-packs/full/manifest.json +2 -2
- package/src/hook-packs/installer.ts +173 -60
- package/src/hook-packs/registry.ts +33 -46
- package/src/hook-packs/yolo-safety/manifest.json +23 -0
- package/src/hook-packs/yolo-safety/scripts/anti-deletion.sh +214 -0
- package/src/hooks/templates.ts +1 -1
- package/src/main.ts +2 -0
- package/dist/commands/cognee.d.ts +0 -10
- package/dist/commands/cognee.js +0 -364
- package/dist/commands/cognee.js.map +0 -1
|
@@ -7,15 +7,8 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
import { homedir } from 'node:os';
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
9
|
const __dirname = dirname(__filename);
|
|
10
|
-
|
|
11
|
-
function
|
|
12
|
-
return __dirname;
|
|
13
|
-
}
|
|
14
|
-
/** Local custom packs directory. */
|
|
15
|
-
function getLocalRoot() {
|
|
16
|
-
return join(process.cwd(), '.soleri', 'hook-packs');
|
|
17
|
-
}
|
|
18
|
-
/** Scan a directory for pack manifests. */
|
|
10
|
+
function getBuiltinRoot() { return __dirname; }
|
|
11
|
+
function getLocalRoot() { return join(process.cwd(), '.soleri', 'hook-packs'); }
|
|
19
12
|
function scanPacksDir(root, source) {
|
|
20
13
|
if (!existsSync(root))
|
|
21
14
|
return [];
|
|
@@ -32,20 +25,13 @@ function scanPacksDir(root, source) {
|
|
|
32
25
|
manifest.source = source;
|
|
33
26
|
packs.push(manifest);
|
|
34
27
|
}
|
|
35
|
-
catch {
|
|
36
|
-
// Skip malformed manifests
|
|
37
|
-
}
|
|
28
|
+
catch { /* Skip malformed manifests */ }
|
|
38
29
|
}
|
|
39
30
|
return packs;
|
|
40
31
|
}
|
|
41
|
-
/**
|
|
42
|
-
* List all available hook packs (built-in + local custom).
|
|
43
|
-
* Local packs in .soleri/hook-packs/ override built-in packs with the same name.
|
|
44
|
-
*/
|
|
45
32
|
export function listPacks() {
|
|
46
33
|
const builtIn = scanPacksDir(getBuiltinRoot(), 'built-in');
|
|
47
34
|
const local = scanPacksDir(getLocalRoot(), 'local');
|
|
48
|
-
// Local packs override built-in packs with same name
|
|
49
35
|
const byName = new Map();
|
|
50
36
|
for (const pack of builtIn)
|
|
51
37
|
byName.set(pack.name, pack);
|
|
@@ -53,11 +39,7 @@ export function listPacks() {
|
|
|
53
39
|
byName.set(pack.name, pack);
|
|
54
40
|
return Array.from(byName.values());
|
|
55
41
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Get a specific pack by name. Local packs take precedence.
|
|
58
|
-
*/
|
|
59
42
|
export function getPack(name) {
|
|
60
|
-
// Check local first
|
|
61
43
|
const localDir = join(getLocalRoot(), name);
|
|
62
44
|
const localManifest = join(localDir, 'manifest.json');
|
|
63
45
|
if (existsSync(localManifest)) {
|
|
@@ -66,11 +48,8 @@ export function getPack(name) {
|
|
|
66
48
|
manifest.source = 'local';
|
|
67
49
|
return { manifest, dir: localDir };
|
|
68
50
|
}
|
|
69
|
-
catch {
|
|
70
|
-
// Fall through to built-in
|
|
71
|
-
}
|
|
51
|
+
catch { /* Fall through */ }
|
|
72
52
|
}
|
|
73
|
-
// Then built-in
|
|
74
53
|
const builtinDir = join(getBuiltinRoot(), name);
|
|
75
54
|
const builtinManifest = join(builtinDir, 'manifest.json');
|
|
76
55
|
if (!existsSync(builtinManifest))
|
|
@@ -84,14 +63,20 @@ export function getPack(name) {
|
|
|
84
63
|
return null;
|
|
85
64
|
}
|
|
86
65
|
}
|
|
87
|
-
/**
|
|
88
|
-
* Get names of packs that are fully installed in ~/.claude/.
|
|
89
|
-
*/
|
|
90
66
|
export function getInstalledPacks() {
|
|
91
67
|
const claudeDir = join(homedir(), '.claude');
|
|
92
68
|
const packs = listPacks();
|
|
93
69
|
const installed = [];
|
|
94
70
|
for (const pack of packs) {
|
|
71
|
+
if (pack.hooks.length === 0) {
|
|
72
|
+
if (pack.scripts && pack.scripts.length > 0) {
|
|
73
|
+
const allScripts = pack.scripts.every((script) => existsSync(join(claudeDir, script.targetDir, script.file)));
|
|
74
|
+
if (allScripts) {
|
|
75
|
+
installed.push(pack.name);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
95
80
|
const allPresent = pack.hooks.every((hook) => existsSync(join(claudeDir, `hookify.${hook}.local.md`)));
|
|
96
81
|
if (allPresent) {
|
|
97
82
|
installed.push(pack.name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/hook-packs/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/hook-packs/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,73 +6,65 @@ import { join, dirname } from 'node:path';
|
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { homedir } from 'node:os';
|
|
8
8
|
|
|
9
|
-
interface
|
|
9
|
+
export interface HookPackScript {
|
|
10
|
+
name: string;
|
|
11
|
+
file: string;
|
|
12
|
+
targetDir: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface HookPackLifecycleHook {
|
|
16
|
+
event: string;
|
|
17
|
+
matcher: string;
|
|
18
|
+
type: 'command';
|
|
19
|
+
command: string;
|
|
20
|
+
timeout?: number;
|
|
21
|
+
statusMessage?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface HookPackManifest {
|
|
10
25
|
name: string;
|
|
11
26
|
description: string;
|
|
12
27
|
hooks: string[];
|
|
13
28
|
composedFrom?: string[];
|
|
14
29
|
version?: string;
|
|
15
|
-
|
|
30
|
+
scripts?: HookPackScript[];
|
|
31
|
+
lifecycleHooks?: HookPackLifecycleHook[];
|
|
16
32
|
source?: 'built-in' | 'local';
|
|
17
33
|
}
|
|
18
34
|
|
|
19
35
|
const __filename = fileURLToPath(import.meta.url);
|
|
20
36
|
const __dirname = dirname(__filename);
|
|
21
37
|
|
|
22
|
-
|
|
23
|
-
function
|
|
24
|
-
return __dirname;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/** Local custom packs directory. */
|
|
28
|
-
function getLocalRoot(): string {
|
|
29
|
-
return join(process.cwd(), '.soleri', 'hook-packs');
|
|
30
|
-
}
|
|
38
|
+
function getBuiltinRoot(): string { return __dirname; }
|
|
39
|
+
function getLocalRoot(): string { return join(process.cwd(), '.soleri', 'hook-packs'); }
|
|
31
40
|
|
|
32
|
-
/** Scan a directory for pack manifests. */
|
|
33
41
|
function scanPacksDir(root: string, source: 'built-in' | 'local'): HookPackManifest[] {
|
|
34
42
|
if (!existsSync(root)) return [];
|
|
35
43
|
const entries = readdirSync(root, { withFileTypes: true });
|
|
36
44
|
const packs: HookPackManifest[] = [];
|
|
37
|
-
|
|
38
45
|
for (const entry of entries) {
|
|
39
46
|
if (!entry.isDirectory()) continue;
|
|
40
47
|
const manifestPath = join(root, entry.name, 'manifest.json');
|
|
41
48
|
if (!existsSync(manifestPath)) continue;
|
|
42
|
-
|
|
43
49
|
try {
|
|
44
50
|
const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8')) as HookPackManifest;
|
|
45
51
|
manifest.source = source;
|
|
46
52
|
packs.push(manifest);
|
|
47
|
-
} catch {
|
|
48
|
-
// Skip malformed manifests
|
|
49
|
-
}
|
|
53
|
+
} catch { /* Skip malformed manifests */ }
|
|
50
54
|
}
|
|
51
|
-
|
|
52
55
|
return packs;
|
|
53
56
|
}
|
|
54
57
|
|
|
55
|
-
/**
|
|
56
|
-
* List all available hook packs (built-in + local custom).
|
|
57
|
-
* Local packs in .soleri/hook-packs/ override built-in packs with the same name.
|
|
58
|
-
*/
|
|
59
58
|
export function listPacks(): HookPackManifest[] {
|
|
60
59
|
const builtIn = scanPacksDir(getBuiltinRoot(), 'built-in');
|
|
61
60
|
const local = scanPacksDir(getLocalRoot(), 'local');
|
|
62
|
-
|
|
63
|
-
// Local packs override built-in packs with same name
|
|
64
61
|
const byName = new Map<string, HookPackManifest>();
|
|
65
62
|
for (const pack of builtIn) byName.set(pack.name, pack);
|
|
66
63
|
for (const pack of local) byName.set(pack.name, pack);
|
|
67
|
-
|
|
68
64
|
return Array.from(byName.values());
|
|
69
65
|
}
|
|
70
66
|
|
|
71
|
-
/**
|
|
72
|
-
* Get a specific pack by name. Local packs take precedence.
|
|
73
|
-
*/
|
|
74
67
|
export function getPack(name: string): { manifest: HookPackManifest; dir: string } | null {
|
|
75
|
-
// Check local first
|
|
76
68
|
const localDir = join(getLocalRoot(), name);
|
|
77
69
|
const localManifest = join(localDir, 'manifest.json');
|
|
78
70
|
if (existsSync(localManifest)) {
|
|
@@ -80,41 +72,36 @@ export function getPack(name: string): { manifest: HookPackManifest; dir: string
|
|
|
80
72
|
const manifest = JSON.parse(readFileSync(localManifest, 'utf-8')) as HookPackManifest;
|
|
81
73
|
manifest.source = 'local';
|
|
82
74
|
return { manifest, dir: localDir };
|
|
83
|
-
} catch {
|
|
84
|
-
// Fall through to built-in
|
|
85
|
-
}
|
|
75
|
+
} catch { /* Fall through */ }
|
|
86
76
|
}
|
|
87
|
-
|
|
88
|
-
// Then built-in
|
|
89
77
|
const builtinDir = join(getBuiltinRoot(), name);
|
|
90
78
|
const builtinManifest = join(builtinDir, 'manifest.json');
|
|
91
79
|
if (!existsSync(builtinManifest)) return null;
|
|
92
|
-
|
|
93
80
|
try {
|
|
94
81
|
const manifest = JSON.parse(readFileSync(builtinManifest, 'utf-8')) as HookPackManifest;
|
|
95
82
|
manifest.source = 'built-in';
|
|
96
83
|
return { manifest, dir: builtinDir };
|
|
97
|
-
} catch {
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
84
|
+
} catch { return null; }
|
|
100
85
|
}
|
|
101
86
|
|
|
102
|
-
/**
|
|
103
|
-
* Get names of packs that are fully installed in ~/.claude/.
|
|
104
|
-
*/
|
|
105
87
|
export function getInstalledPacks(): string[] {
|
|
106
88
|
const claudeDir = join(homedir(), '.claude');
|
|
107
89
|
const packs = listPacks();
|
|
108
90
|
const installed: string[] = [];
|
|
109
|
-
|
|
110
91
|
for (const pack of packs) {
|
|
92
|
+
if (pack.hooks.length === 0) {
|
|
93
|
+
if (pack.scripts && pack.scripts.length > 0) {
|
|
94
|
+
const allScripts = pack.scripts.every((script) =>
|
|
95
|
+
existsSync(join(claudeDir, script.targetDir, script.file)),
|
|
96
|
+
);
|
|
97
|
+
if (allScripts) { installed.push(pack.name); }
|
|
98
|
+
}
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
111
101
|
const allPresent = pack.hooks.every((hook) =>
|
|
112
102
|
existsSync(join(claudeDir, `hookify.${hook}.local.md`)),
|
|
113
103
|
);
|
|
114
|
-
if (allPresent) {
|
|
115
|
-
installed.push(pack.name);
|
|
116
|
-
}
|
|
104
|
+
if (allPresent) { installed.push(pack.name); }
|
|
117
105
|
}
|
|
118
|
-
|
|
119
106
|
return installed;
|
|
120
107
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "yolo-safety",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Anti-deletion guardrail for YOLO mode — intercepts destructive commands, stages files for review",
|
|
5
|
+
"hooks": [],
|
|
6
|
+
"scripts": [
|
|
7
|
+
{
|
|
8
|
+
"name": "anti-deletion",
|
|
9
|
+
"file": "anti-deletion.sh",
|
|
10
|
+
"targetDir": "hooks"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"lifecycleHooks": [
|
|
14
|
+
{
|
|
15
|
+
"event": "PreToolUse",
|
|
16
|
+
"matcher": "Bash",
|
|
17
|
+
"type": "command",
|
|
18
|
+
"command": "bash ~/.claude/hooks/anti-deletion.sh",
|
|
19
|
+
"timeout": 10,
|
|
20
|
+
"statusMessage": "Checking for destructive commands..."
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Anti-Deletion Staging Hook for Claude Code (Soleri Hook Pack: yolo-safety)
|
|
3
|
+
# PreToolUse -> Bash: intercepts rm, rmdir, mv (of project dirs), git clean, reset --hard
|
|
4
|
+
# Copies target files to ~/.soleri/staging/<timestamp>/ then blocks the command.
|
|
5
|
+
#
|
|
6
|
+
# Catastrophic commands (rm -rf /, rm -rf ~) should stay in deny rules —
|
|
7
|
+
# this hook handles targeted deletes only.
|
|
8
|
+
#
|
|
9
|
+
# Dependencies: jq (required), perl (optional, for heredoc stripping)
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
STAGING_ROOT="$HOME/.soleri/staging"
|
|
14
|
+
PROJECTS_DIR="$HOME/projects"
|
|
15
|
+
INPUT=$(cat)
|
|
16
|
+
|
|
17
|
+
# Extract the command from stdin JSON
|
|
18
|
+
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
19
|
+
|
|
20
|
+
# No command found — let it through
|
|
21
|
+
if [ -z "$CMD" ]; then
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# --- Strip heredocs and quoted strings to avoid false positives ---
|
|
26
|
+
# Commands like: gh issue comment --body "$(cat <<'EOF' ... rmdir ... EOF)"
|
|
27
|
+
# contain destructive keywords in text, not as actual commands.
|
|
28
|
+
|
|
29
|
+
# Remove heredoc blocks: <<'EOF'...EOF and <<EOF...EOF (multiline)
|
|
30
|
+
STRIPPED=$(echo "$CMD" | perl -0777 -pe "s/<<'?\\w+'?.*?^\\w+$//gms" 2>/dev/null || echo "$CMD")
|
|
31
|
+
# Remove double-quoted strings (greedy but good enough for this check)
|
|
32
|
+
STRIPPED=$(echo "$STRIPPED" | sed -E 's/"[^"]*"//g' 2>/dev/null || echo "$STRIPPED")
|
|
33
|
+
# Remove single-quoted strings
|
|
34
|
+
STRIPPED=$(echo "$STRIPPED" | sed -E "s/'[^']*'//g" 2>/dev/null || echo "$STRIPPED")
|
|
35
|
+
|
|
36
|
+
# --- Detect destructive commands (on stripped command only) ---
|
|
37
|
+
|
|
38
|
+
IS_RM=false
|
|
39
|
+
IS_RMDIR=false
|
|
40
|
+
IS_MV_PROJECT=false
|
|
41
|
+
IS_GIT_CLEAN=false
|
|
42
|
+
IS_RESET_HARD=false
|
|
43
|
+
IS_GIT_CHECKOUT_DOT=false
|
|
44
|
+
IS_GIT_RESTORE_DOT=false
|
|
45
|
+
|
|
46
|
+
# Check for rm commands (but not git rm which is safe — it stages, doesn't destroy)
|
|
47
|
+
if echo "$STRIPPED" | grep -qE '(^|\s|;|&&|\|\|)rm\s'; then
|
|
48
|
+
if ! echo "$STRIPPED" | grep -qE '(^|\s)git\s+rm\s'; then
|
|
49
|
+
IS_RM=true
|
|
50
|
+
fi
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Check for rmdir commands
|
|
54
|
+
if echo "$STRIPPED" | grep -qE '(^|\s|;|&&|\|\|)rmdir\s'; then
|
|
55
|
+
IS_RMDIR=true
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Check for mv commands that move project directories or git repos
|
|
59
|
+
if echo "$STRIPPED" | grep -qE '(^|\s|;|&&|\|\|)mv\s'; then
|
|
60
|
+
MV_SOURCES=$(echo "$STRIPPED" | sed -E 's/^.*\bmv\s+//' | sed -E 's/-(f|i|n|v)\s+//g')
|
|
61
|
+
if echo "$MV_SOURCES" | grep -qE "(~/projects|$HOME/projects|\\\$HOME/projects|\\.git)"; then
|
|
62
|
+
IS_MV_PROJECT=true
|
|
63
|
+
fi
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Check for git clean
|
|
67
|
+
if echo "$STRIPPED" | grep -qE '(^|\s|;|&&|\|\|)git\s+clean\b'; then
|
|
68
|
+
IS_GIT_CLEAN=true
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Check for git reset --hard
|
|
72
|
+
if echo "$STRIPPED" | grep -qE '(^|\s|;|&&|\|\|)git\s+reset\s+--hard'; then
|
|
73
|
+
IS_RESET_HARD=true
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Check for git checkout -- . (restores all files, discards changes)
|
|
77
|
+
if echo "$STRIPPED" | grep -qE '(^|\s|;|&&|\|\|)git\s+checkout\s+--\s+\.'; then
|
|
78
|
+
IS_GIT_CHECKOUT_DOT=true
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Check for git restore . (restores all files, discards changes)
|
|
82
|
+
if echo "$STRIPPED" | grep -qE '(^|\s|;|&&|\|\|)git\s+restore\s+\.'; then
|
|
83
|
+
IS_GIT_RESTORE_DOT=true
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Not a destructive command — let it through
|
|
87
|
+
if [ "$IS_RM" = false ] && [ "$IS_RMDIR" = false ] && [ "$IS_MV_PROJECT" = false ] && \
|
|
88
|
+
[ "$IS_GIT_CLEAN" = false ] && [ "$IS_RESET_HARD" = false ] && \
|
|
89
|
+
[ "$IS_GIT_CHECKOUT_DOT" = false ] && [ "$IS_GIT_RESTORE_DOT" = false ]; then
|
|
90
|
+
exit 0
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# --- Handle git clean (block outright) ---
|
|
94
|
+
|
|
95
|
+
if [ "$IS_GIT_CLEAN" = true ]; then
|
|
96
|
+
jq -n '{
|
|
97
|
+
continue: false,
|
|
98
|
+
stopReason: "BLOCKED: git clean would remove untracked files. Use git stash --include-untracked to save them first, or ask the user to run git clean manually."
|
|
99
|
+
}'
|
|
100
|
+
exit 0
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# --- Handle git reset --hard (block outright) ---
|
|
104
|
+
|
|
105
|
+
if [ "$IS_RESET_HARD" = true ]; then
|
|
106
|
+
jq -n '{
|
|
107
|
+
continue: false,
|
|
108
|
+
stopReason: "BLOCKED: git reset --hard would discard uncommitted changes. Use git stash to save them first, or ask the user to run this manually."
|
|
109
|
+
}'
|
|
110
|
+
exit 0
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
# --- Handle git checkout -- . (block outright) ---
|
|
114
|
+
|
|
115
|
+
if [ "$IS_GIT_CHECKOUT_DOT" = true ]; then
|
|
116
|
+
jq -n '{
|
|
117
|
+
continue: false,
|
|
118
|
+
stopReason: "BLOCKED: git checkout -- . would discard all uncommitted changes. Use git stash to save them first, or ask the user to run this manually."
|
|
119
|
+
}'
|
|
120
|
+
exit 0
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# --- Handle git restore . (block outright) ---
|
|
124
|
+
|
|
125
|
+
if [ "$IS_GIT_RESTORE_DOT" = true ]; then
|
|
126
|
+
jq -n '{
|
|
127
|
+
continue: false,
|
|
128
|
+
stopReason: "BLOCKED: git restore . would discard all uncommitted changes. Use git stash to save them first, or ask the user to run this manually."
|
|
129
|
+
}'
|
|
130
|
+
exit 0
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# --- Handle mv of project directories (block outright) ---
|
|
134
|
+
|
|
135
|
+
if [ "$IS_MV_PROJECT" = true ]; then
|
|
136
|
+
jq -n '{
|
|
137
|
+
continue: false,
|
|
138
|
+
stopReason: "BLOCKED: mv of a project directory or git repo detected. Moving project directories can cause data loss if the operation fails midway. Ask the user to run this manually, or use cp + verify + rm instead."
|
|
139
|
+
}'
|
|
140
|
+
exit 0
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
# --- Handle rmdir (block outright) ---
|
|
144
|
+
|
|
145
|
+
if [ "$IS_RMDIR" = true ]; then
|
|
146
|
+
jq -n '{
|
|
147
|
+
continue: false,
|
|
148
|
+
stopReason: "BLOCKED: rmdir detected. Removing directories can break project structure. Ask the user to confirm this operation manually."
|
|
149
|
+
}'
|
|
150
|
+
exit 0
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
# --- Handle rm commands — copy to staging, then block ---
|
|
154
|
+
|
|
155
|
+
# Create timestamped staging directory
|
|
156
|
+
TIMESTAMP=$(date +%Y-%m-%d_%H%M%S)
|
|
157
|
+
STAGE_DIR="$STAGING_ROOT/$TIMESTAMP"
|
|
158
|
+
|
|
159
|
+
# Extract file paths from the rm command
|
|
160
|
+
# Strip rm and its flags, keeping only the file arguments
|
|
161
|
+
FILES=$(echo "$CMD" | sed -E 's/^.*\brm\s+//' | sed -E 's/-(r|f|rf|fr|v|i|rv|fv|rfv|frv)\s+//g' | tr ' ' '\n' | grep -v '^-' | grep -v '^$')
|
|
162
|
+
|
|
163
|
+
if [ -z "$FILES" ]; then
|
|
164
|
+
jq -n '{
|
|
165
|
+
continue: false,
|
|
166
|
+
stopReason: "BLOCKED: rm command detected but could not parse file targets. Please specify files explicitly."
|
|
167
|
+
}'
|
|
168
|
+
exit 0
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
STAGED=()
|
|
172
|
+
MISSING=()
|
|
173
|
+
|
|
174
|
+
mkdir -p "$STAGE_DIR"
|
|
175
|
+
|
|
176
|
+
while IFS= read -r filepath; do
|
|
177
|
+
# Expand path (handle ~, relative paths)
|
|
178
|
+
expanded=$(eval echo "$filepath" 2>/dev/null || echo "$filepath")
|
|
179
|
+
|
|
180
|
+
if [ -e "$expanded" ]; then
|
|
181
|
+
# Preserve directory structure in staging
|
|
182
|
+
target_dir="$STAGE_DIR/$(dirname "$expanded")"
|
|
183
|
+
mkdir -p "$target_dir"
|
|
184
|
+
# COPY instead of MOVE — originals stay intact, staging is a backup
|
|
185
|
+
if [ -d "$expanded" ]; then
|
|
186
|
+
cp -R "$expanded" "$target_dir/" 2>/dev/null && STAGED+=("$expanded") || MISSING+=("$expanded")
|
|
187
|
+
else
|
|
188
|
+
cp "$expanded" "$target_dir/" 2>/dev/null && STAGED+=("$expanded") || MISSING+=("$expanded")
|
|
189
|
+
fi
|
|
190
|
+
else
|
|
191
|
+
MISSING+=("$expanded")
|
|
192
|
+
fi
|
|
193
|
+
done <<< "$FILES"
|
|
194
|
+
|
|
195
|
+
# Build response
|
|
196
|
+
STAGED_COUNT=${#STAGED[@]}
|
|
197
|
+
MISSING_COUNT=${#MISSING[@]}
|
|
198
|
+
|
|
199
|
+
if [ "$STAGED_COUNT" -eq 0 ] && [ "$MISSING_COUNT" -gt 0 ]; then
|
|
200
|
+
# All files were missing — let the rm fail naturally
|
|
201
|
+
rmdir "$STAGE_DIR" 2>/dev/null || true
|
|
202
|
+
exit 0
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
STAGED_LIST=$(printf '%s, ' "${STAGED[@]}" | sed 's/, $//')
|
|
206
|
+
|
|
207
|
+
jq -n \
|
|
208
|
+
--arg staged "$STAGED_LIST" \
|
|
209
|
+
--arg dir "$STAGE_DIR" \
|
|
210
|
+
--argjson count "$STAGED_COUNT" \
|
|
211
|
+
'{
|
|
212
|
+
continue: false,
|
|
213
|
+
stopReason: ("BLOCKED & BACKED UP: " + ($count | tostring) + " item(s) copied to " + $dir + " — files: " + $staged + ". The originals are untouched. To proceed with deletion, ask the user to run the rm command manually.")
|
|
214
|
+
}'
|
package/dist/hooks/templates.js
CHANGED
|
@@ -105,7 +105,7 @@ function generateClaudeCodeSettings(dir) {
|
|
|
105
105
|
hooks: [
|
|
106
106
|
{
|
|
107
107
|
type: 'command',
|
|
108
|
-
command: `echo "[${agentId}] session started — register project: ${agentId}_core op:
|
|
108
|
+
command: `echo "[${agentId}] session started — register project: ${agentId}_core op:session_start params:{ projectPath: \\".\\" }" && echo "Check for active plans: ${agentId}_core op:get_plan"`,
|
|
109
109
|
},
|
|
110
110
|
],
|
|
111
111
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/hooks/templates.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAIxD,MAAM,CAAC,MAAM,iBAAiB,GAAe,CAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AAO9F,kFAAkF;AAClF,SAAS,UAAU,CAAC,EAAU;IAC5B,OAAO,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,YAAY,CAAC,GAAY;IAChC,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC;AAC5E,CAAC;AAED,oBAAoB;AAEpB;;;;;;;;;;;;;;;GAeG;AACH,SAAS,oBAAoB,CAAC,OAAe;IAC3C,mEAAmE;IACnE,mCAAmC;IACnC,oEAAoE;IACpE,MAAM,KAAK,GAAG;QACZ,8BAA8B;QAC9B,2CAA2C;QAC3C,kIAAkI;QAClI,0FAA0F;QAC1F,yJAAyJ;QACzJ,2FAA2F;QAC3F,wEAAwE;QACxE,2DAA2D;QAC3D;YACE,iKAAiK;YACjK,oMAAoM;YACpM,qMAAqM;YACrM,mKAAmK;YACnK,mKAAmK;YACnK,6JAA6J;YAC7J,+KAA+K;YAC/K,gLAAgL;YAChL,qLAAqL;YACrL,IAAI;SACL,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,oDAAoD;QACpD,cAAc,OAAO,uFAAuF;KAC7G,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,0BAA0B,CAAC,GAAY;IAC9C,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,UAAU,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAC7B;QACE,KAAK,EAAE;YACL,gBAAgB,EAAE;gBAChB;oBACE,KAAK,EAAE;wBACL;4BACE,IAAI,EAAE,SAAS;4BACf,OAAO,EAAE,oBAAoB,CAAC,OAAO,CAAC;yBACvC;qBACF;iBACF;aACF;YACD,UAAU,EAAE;gBACV;oBACE,OAAO,EAAE,GAAG;oBACZ,KAAK,EAAE;wBACL;4BACE,IAAI,EAAE,SAAS;4BACf,OAAO,EAAE,UAAU,OAAO,qBAAqB;yBAChD;qBACF;iBACF;aACF;YACD,WAAW,EAAE;gBACX;oBACE,OAAO,EAAE,YAAY;oBACrB,KAAK,EAAE;wBACL;4BACE,IAAI,EAAE,SAAS;4BACf,OAAO,EAAE,UAAU,OAAO,iBAAiB;yBAC5C;qBACF;iBACF;aACF;YACD,YAAY,EAAE;gBACZ;oBACE,KAAK,EAAE;wBACL;4BACE,IAAI,EAAE,SAAS;4BACf,OAAO,EAAE,UAAU,OAAO,yCAAyC,OAAO,
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/hooks/templates.ts"],"names":[],"mappings":"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"}
|
package/dist/main.js
CHANGED
|
@@ -19,6 +19,7 @@ import { registerPack } from './commands/pack.js';
|
|
|
19
19
|
import { registerSkills } from './commands/skills.js';
|
|
20
20
|
import { registerAgent } from './commands/agent.js';
|
|
21
21
|
import { registerTelegram } from './commands/telegram.js';
|
|
22
|
+
import { registerStaging } from './commands/staging.js';
|
|
22
23
|
const require = createRequire(import.meta.url);
|
|
23
24
|
const { version } = require('../package.json');
|
|
24
25
|
const RESET = '\x1b[0m';
|
|
@@ -73,5 +74,6 @@ registerPack(program);
|
|
|
73
74
|
registerSkills(program);
|
|
74
75
|
registerAgent(program);
|
|
75
76
|
registerTelegram(program);
|
|
77
|
+
registerStaging(program);
|
|
76
78
|
program.parse();
|
|
77
79
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ import { previewScaffold, scaffold } from '@soleri/forge/lib';
|
|
|
6
6
|
import type { AgentConfig } from '@soleri/forge/lib';
|
|
7
7
|
import { installPack } from '../hook-packs/installer.js';
|
|
8
8
|
|
|
9
|
-
describe('create command', () => {
|
|
9
|
+
describe('create command', { timeout: 30_000 }, () => {
|
|
10
10
|
let tempDir: string;
|
|
11
11
|
|
|
12
12
|
const testConfig: AgentConfig = {
|
|
@@ -81,7 +81,11 @@ describe('create command', () => {
|
|
|
81
81
|
),
|
|
82
82
|
);
|
|
83
83
|
expect(testingBundle.domain).toBe('testing');
|
|
84
|
-
expect(testingBundle.entries).
|
|
84
|
+
expect(testingBundle.entries.length).toBeGreaterThanOrEqual(0);
|
|
85
|
+
if (testingBundle.entries.length > 0) {
|
|
86
|
+
expect(testingBundle.entries[0].id).toBe('testing-seed');
|
|
87
|
+
expect(testingBundle.entries[0].tags).toContain('seed');
|
|
88
|
+
}
|
|
85
89
|
});
|
|
86
90
|
|
|
87
91
|
it('should read config from file for non-interactive mode', () => {
|