@swarmdo/cli 1.37.0 → 1.45.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/README.md +7 -5
- package/dist/src/apply/apply.d.ts.map +1 -1
- package/dist/src/apply/apply.js +6 -1
- package/dist/src/apply/apply.js.map +1 -1
- package/dist/src/changelog/changelog.d.ts +21 -0
- package/dist/src/changelog/changelog.d.ts.map +1 -1
- package/dist/src/changelog/changelog.js +43 -0
- package/dist/src/changelog/changelog.js.map +1 -1
- package/dist/src/commands/changelog.d.ts.map +1 -1
- package/dist/src/commands/changelog.js +15 -4
- package/dist/src/commands/changelog.js.map +1 -1
- package/dist/src/commands/config.d.ts.map +1 -1
- package/dist/src/commands/config.js +6 -1
- package/dist/src/commands/config.js.map +1 -1
- package/dist/src/commands/coupling.d.ts +17 -0
- package/dist/src/commands/coupling.d.ts.map +1 -0
- package/dist/src/commands/coupling.js +85 -0
- package/dist/src/commands/coupling.js.map +1 -0
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +55 -0
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/hotspots.d.ts.map +1 -1
- package/dist/src/commands/hotspots.js +2 -1
- package/dist/src/commands/hotspots.js.map +1 -1
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +6 -3
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/redact.d.ts.map +1 -1
- package/dist/src/commands/redact.js +11 -0
- package/dist/src/commands/redact.js.map +1 -1
- package/dist/src/commands/release.d.ts.map +1 -1
- package/dist/src/commands/release.js +27 -5
- package/dist/src/commands/release.js.map +1 -1
- package/dist/src/commands/task.d.ts.map +1 -1
- package/dist/src/commands/task.js +57 -2
- package/dist/src/commands/task.js.map +1 -1
- package/dist/src/config-lint/agents-lint.d.ts +30 -0
- package/dist/src/config-lint/agents-lint.d.ts.map +1 -0
- package/dist/src/config-lint/agents-lint.js +87 -0
- package/dist/src/config-lint/agents-lint.js.map +1 -0
- package/dist/src/config-lint/lint.d.ts +3 -0
- package/dist/src/config-lint/lint.d.ts.map +1 -1
- package/dist/src/config-lint/lint.js +3 -0
- package/dist/src/config-lint/lint.js.map +1 -1
- package/dist/src/coupling/coupling.d.ts +56 -0
- package/dist/src/coupling/coupling.d.ts.map +1 -0
- package/dist/src/coupling/coupling.js +86 -0
- package/dist/src/coupling/coupling.js.map +1 -0
- package/dist/src/hooks-recipe/command-guard.d.ts +46 -0
- package/dist/src/hooks-recipe/command-guard.d.ts.map +1 -0
- package/dist/src/hooks-recipe/command-guard.js +120 -0
- package/dist/src/hooks-recipe/command-guard.js.map +1 -0
- package/dist/src/hooks-recipe/recipe.d.ts.map +1 -1
- package/dist/src/hooks-recipe/recipe.js +8 -0
- package/dist/src/hooks-recipe/recipe.js.map +1 -1
- package/dist/src/mcp-client.d.ts.map +1 -1
- package/dist/src/mcp-client.js +2 -0
- package/dist/src/mcp-client.js.map +1 -1
- package/dist/src/mcp-tools/coupling-tools.d.ts +14 -0
- package/dist/src/mcp-tools/coupling-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/coupling-tools.js +56 -0
- package/dist/src/mcp-tools/coupling-tools.js.map +1 -0
- package/dist/src/mcp-tools/index.d.ts +1 -0
- package/dist/src/mcp-tools/index.d.ts.map +1 -1
- package/dist/src/mcp-tools/index.js +1 -0
- package/dist/src/mcp-tools/index.js.map +1 -1
- package/dist/src/mcp-tools/profiles.d.ts.map +1 -1
- package/dist/src/mcp-tools/profiles.js +1 -0
- package/dist/src/mcp-tools/profiles.js.map +1 -1
- package/dist/src/mcp-tools/task-deps.d.ts +35 -0
- package/dist/src/mcp-tools/task-deps.d.ts.map +1 -1
- package/dist/src/mcp-tools/task-deps.js +87 -0
- package/dist/src/mcp-tools/task-deps.js.map +1 -1
- package/dist/src/redact/redact.d.ts.map +1 -1
- package/dist/src/redact/redact.js +22 -10
- package/dist/src/redact/redact.js.map +1 -1
- package/dist/src/redact/sarif.d.ts +28 -0
- package/dist/src/redact/sarif.d.ts.map +1 -0
- package/dist/src/redact/sarif.js +53 -0
- package/dist/src/redact/sarif.js.map +1 -0
- package/dist/src/release/release.d.ts +19 -0
- package/dist/src/release/release.d.ts.map +1 -1
- package/dist/src/release/release.js +28 -0
- package/dist/src/release/release.js.map +1 -1
- package/dist/src/usage/reflect.d.ts +9 -1
- package/dist/src/usage/reflect.d.ts.map +1 -1
- package/dist/src/usage/reflect.js +14 -4
- package/dist/src/usage/reflect.js.map +1 -1
- package/dist/src/util/since.d.ts +13 -0
- package/dist/src/util/since.d.ts.map +1 -0
- package/dist/src/util/since.js +21 -0
- package/dist/src/util/since.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -10,6 +10,7 @@ import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import { bridgeSearchEntries } from '../memory/memory-bridge.js';
|
|
12
12
|
import { selectInjectionMemories, mapSearchResultsToCandidates, extractPromptFromPayload, } from '../memory-inject/select.js';
|
|
13
|
+
import { classifyCommand, extractBashCommand, denyOutput } from '../hooks-recipe/command-guard.js';
|
|
13
14
|
/**
|
|
14
15
|
* #1686 — `?? 0` only defaults null/undefined; NaN slips through and
|
|
15
16
|
* surfaces as `"NaN"` (or earlier crashed `.toFixed`) in the metrics
|
|
@@ -849,6 +850,58 @@ const memoryInjectCommand = {
|
|
|
849
850
|
}
|
|
850
851
|
},
|
|
851
852
|
};
|
|
853
|
+
/**
|
|
854
|
+
* guard-bash — the #83 PreToolUse/Bash guardrail. Reads the hook payload from
|
|
855
|
+
* stdin (or --command), classifies the bash command against a conservative
|
|
856
|
+
* destructive-command denylist, and on a match emits Claude Code's
|
|
857
|
+
* `permissionDecision: "deny"` to hard-block it. This is the only safety net
|
|
858
|
+
* that still fires under headless `claude -p --dangerously-skip-permissions`.
|
|
859
|
+
* Hook-safe: it NEVER errors and stays silent (allow) for anything not on the
|
|
860
|
+
* denylist, so it can't break a legitimate command.
|
|
861
|
+
*/
|
|
862
|
+
const guardBashCommand = {
|
|
863
|
+
name: 'guard-bash',
|
|
864
|
+
description: 'Block dangerous bash commands (PreToolUse hook): emits permissionDecision:deny on a destructive-command denylist',
|
|
865
|
+
options: [
|
|
866
|
+
{ name: 'command', short: 'c', description: 'Command to classify (else read the hook JSON from stdin)', type: 'string' },
|
|
867
|
+
{ name: 'preview', description: 'Print the human-readable verdict instead of emitting hook JSON', type: 'boolean' },
|
|
868
|
+
],
|
|
869
|
+
examples: [
|
|
870
|
+
{ command: 'swarmdo hooks guard-bash -c "rm -rf /" --preview', description: 'Check whether a command would be blocked' },
|
|
871
|
+
{ command: 'echo \'{"tool_input":{"command":"rm -rf /"}}\' | swarmdo hooks guard-bash', description: 'Run as a PreToolUse/Bash hook' },
|
|
872
|
+
],
|
|
873
|
+
action: async (ctx) => {
|
|
874
|
+
const preview = Boolean(ctx.flags.preview);
|
|
875
|
+
// A hook must NEVER break a tool call by crashing: swallow everything, default to allow.
|
|
876
|
+
try {
|
|
877
|
+
if (process.env.SWARMDO_GUARD_BASH_DISABLE === '1')
|
|
878
|
+
return { success: true };
|
|
879
|
+
let command = (ctx.flags.command || ctx.args.join(' ')).trim();
|
|
880
|
+
if (!command)
|
|
881
|
+
command = extractBashCommand(await readHookStdin());
|
|
882
|
+
if (!command)
|
|
883
|
+
return { success: true }; // nothing to classify → allow
|
|
884
|
+
const verdict = classifyCommand(command);
|
|
885
|
+
if (preview) {
|
|
886
|
+
if (verdict.block)
|
|
887
|
+
output.printError(`BLOCK: ${verdict.reason} [${verdict.rule}]`);
|
|
888
|
+
else
|
|
889
|
+
output.printSuccess('allow — no destructive pattern matched');
|
|
890
|
+
return { success: true, data: verdict };
|
|
891
|
+
}
|
|
892
|
+
// Hook mode: emit the deny JSON only on a block; silence = allow.
|
|
893
|
+
if (verdict.block) {
|
|
894
|
+
process.stdout.write(JSON.stringify(denyOutput(verdict.reason)) + '\n');
|
|
895
|
+
}
|
|
896
|
+
return { success: true };
|
|
897
|
+
}
|
|
898
|
+
catch (err) {
|
|
899
|
+
if (preview)
|
|
900
|
+
output.printError(`guard-bash failed: ${String(err)}`);
|
|
901
|
+
return { success: true }; // never fail the hook (fail-open: a broken guard must not block work)
|
|
902
|
+
}
|
|
903
|
+
},
|
|
904
|
+
};
|
|
852
905
|
// Explain subcommand
|
|
853
906
|
const explainCommand = {
|
|
854
907
|
name: 'explain',
|
|
@@ -4672,6 +4725,7 @@ export const hooksCommand = {
|
|
|
4672
4725
|
sessionRestoreCommand,
|
|
4673
4726
|
routeCommand,
|
|
4674
4727
|
memoryInjectCommand,
|
|
4728
|
+
guardBashCommand,
|
|
4675
4729
|
explainCommand,
|
|
4676
4730
|
pretrainCommand,
|
|
4677
4731
|
buildAgentsCommand,
|
|
@@ -4730,6 +4784,7 @@ export const hooksCommand = {
|
|
|
4730
4784
|
`${output.highlight('session-restore')} - Restore a previous session`,
|
|
4731
4785
|
`${output.highlight('route')} - Route tasks to optimal agents`,
|
|
4732
4786
|
`${output.highlight('memory-inject')} - Inject relevant memories into the prompt (UserPromptSubmit)`,
|
|
4787
|
+
`${output.highlight('guard-bash')} - Block dangerous bash commands (PreToolUse deny)`,
|
|
4733
4788
|
`${output.highlight('explain')} - Explain routing decisions`,
|
|
4734
4789
|
`${output.highlight('pretrain')} - Bootstrap intelligence from repository`,
|
|
4735
4790
|
`${output.highlight('build-agents')} - Generate optimized agent configs`,
|