@praxis.guard/auditor-cli 0.0.33 → 0.0.34

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.
Files changed (93) hide show
  1. package/dist/approval/argv-fingerprint.d.ts +10 -1
  2. package/dist/approval/argv-fingerprint.d.ts.map +1 -1
  3. package/dist/approval/argv-fingerprint.js +10 -1
  4. package/dist/approval/argv-fingerprint.js.map +1 -1
  5. package/dist/approval/hook-inline-approval.d.ts +2 -0
  6. package/dist/approval/hook-inline-approval.d.ts.map +1 -1
  7. package/dist/approval/hook-inline-approval.js +6 -2
  8. package/dist/approval/hook-inline-approval.js.map +1 -1
  9. package/dist/approval/mcp-flow.d.ts +4 -2
  10. package/dist/approval/mcp-flow.d.ts.map +1 -1
  11. package/dist/approval/mcp-flow.js +9 -3
  12. package/dist/approval/mcp-flow.js.map +1 -1
  13. package/dist/approval/redeem.d.ts +2 -0
  14. package/dist/approval/redeem.d.ts.map +1 -1
  15. package/dist/approval/redeem.js +7 -2
  16. package/dist/approval/redeem.js.map +1 -1
  17. package/dist/bridge/execution-ticket.d.ts +3 -0
  18. package/dist/bridge/execution-ticket.d.ts.map +1 -1
  19. package/dist/bridge/execution-ticket.js +38 -9
  20. package/dist/bridge/execution-ticket.js.map +1 -1
  21. package/dist/bridge/shell-approval-bridge.d.ts +14 -5
  22. package/dist/bridge/shell-approval-bridge.d.ts.map +1 -1
  23. package/dist/bridge/shell-approval-bridge.js +47 -24
  24. package/dist/bridge/shell-approval-bridge.js.map +1 -1
  25. package/dist/hooks/before-shell-io.d.ts +3 -0
  26. package/dist/hooks/before-shell-io.d.ts.map +1 -0
  27. package/dist/hooks/before-shell-io.js +26 -0
  28. package/dist/hooks/before-shell-io.js.map +1 -0
  29. package/dist/hooks/before-shell-mutate.d.ts +23 -0
  30. package/dist/hooks/before-shell-mutate.d.ts.map +1 -0
  31. package/dist/hooks/before-shell-mutate.js +74 -0
  32. package/dist/hooks/before-shell-mutate.js.map +1 -0
  33. package/dist/hooks/before-shell-skipped.d.ts +11 -0
  34. package/dist/hooks/before-shell-skipped.d.ts.map +1 -0
  35. package/dist/hooks/before-shell-skipped.js +49 -0
  36. package/dist/hooks/before-shell-skipped.js.map +1 -0
  37. package/dist/hooks/before-shell-types.d.ts +12 -0
  38. package/dist/hooks/before-shell-types.d.ts.map +1 -0
  39. package/dist/hooks/before-shell-types.js +2 -0
  40. package/dist/hooks/before-shell-types.js.map +1 -0
  41. package/dist/hooks/run-before-shell.d.ts +2 -10
  42. package/dist/hooks/run-before-shell.d.ts.map +1 -1
  43. package/dist/hooks/run-before-shell.js +63 -142
  44. package/dist/hooks/run-before-shell.js.map +1 -1
  45. package/dist/index.d.ts +2 -2
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +2 -2
  48. package/dist/index.js.map +1 -1
  49. package/dist/mcp/evaluate-guard.d.ts.map +1 -1
  50. package/dist/mcp/evaluate-guard.js +20 -9
  51. package/dist/mcp/evaluate-guard.js.map +1 -1
  52. package/dist/mcp/guard-approval-block.d.ts +1 -0
  53. package/dist/mcp/guard-approval-block.d.ts.map +1 -1
  54. package/dist/mcp/guard-approval-block.js +1 -0
  55. package/dist/mcp/guard-approval-block.js.map +1 -1
  56. package/dist/policies.v1.json +4 -0
  57. package/dist/policy/index.d.ts +4 -0
  58. package/dist/policy/index.d.ts.map +1 -1
  59. package/dist/policy/index.js +6 -0
  60. package/dist/policy/index.js.map +1 -1
  61. package/dist/shell/analyze-command-aggregate.d.ts +16 -0
  62. package/dist/shell/analyze-command-aggregate.d.ts.map +1 -0
  63. package/dist/shell/analyze-command-aggregate.js +89 -0
  64. package/dist/shell/analyze-command-aggregate.js.map +1 -0
  65. package/dist/shell/analyze-command-invocations.d.ts +11 -0
  66. package/dist/shell/analyze-command-invocations.d.ts.map +1 -0
  67. package/dist/shell/analyze-command-invocations.js +113 -0
  68. package/dist/shell/analyze-command-invocations.js.map +1 -0
  69. package/dist/shell/analyze-command.d.ts +7 -0
  70. package/dist/shell/analyze-command.d.ts.map +1 -0
  71. package/dist/shell/analyze-command.js +46 -0
  72. package/dist/shell/analyze-command.js.map +1 -0
  73. package/dist/shell/analyze-command.types.d.ts +38 -0
  74. package/dist/shell/analyze-command.types.d.ts.map +1 -0
  75. package/dist/shell/analyze-command.types.js +2 -0
  76. package/dist/shell/analyze-command.types.js.map +1 -0
  77. package/dist/shell/evaluate.d.ts +15 -18
  78. package/dist/shell/evaluate.d.ts.map +1 -1
  79. package/dist/shell/evaluate.js +57 -47
  80. package/dist/shell/evaluate.js.map +1 -1
  81. package/dist/shell/governed-tools.d.ts +18 -1
  82. package/dist/shell/governed-tools.d.ts.map +1 -1
  83. package/dist/shell/governed-tools.js +60 -1
  84. package/dist/shell/governed-tools.js.map +1 -1
  85. package/dist/shell/guard-eval.d.ts +15 -0
  86. package/dist/shell/guard-eval.d.ts.map +1 -0
  87. package/dist/shell/guard-eval.js +35 -0
  88. package/dist/shell/guard-eval.js.map +1 -0
  89. package/dist/shell/parse-segments.d.ts +14 -0
  90. package/dist/shell/parse-segments.d.ts.map +1 -0
  91. package/dist/shell/parse-segments.js +41 -0
  92. package/dist/shell/parse-segments.js.map +1 -0
  93. package/package.json +1 -1
@@ -1,24 +1,19 @@
1
- import { classifyArgv, type PoliciesV1, type Tier } from "../policy/index.js";
1
+ import { type PoliciesV1 } from "../policy/index.js";
2
+ import { type ShellAnalysis } from "./analyze-command.js";
3
+ import { type GuardEvaluation } from "./guard-eval.js";
4
+ import { parseCommandToArgv } from "./parse.js";
2
5
  export type { PoliciesV1, Tier } from "../policy/index.js";
6
+ export type { GuardEvaluation, GuardReason } from "./guard-eval.js";
7
+ export { evaluateArgv } from "./guard-eval.js";
3
8
  export { parseCommandToArgv } from "./parse.js";
4
- export { DEFAULT_GOVERNED_SHELL_TOOLS } from "./governed-tools.js";
5
- export type GuardReason = {
6
- code: string;
7
- message: string;
8
- details?: Record<string, unknown>;
9
- };
10
- export type GuardEvaluation = {
11
- argv: string[];
12
- tier: Tier;
13
- reasons: GuardReason[];
14
- classification: ReturnType<typeof classifyArgv>["classification"];
15
- flags: ReturnType<typeof classifyArgv>["flags"];
16
- };
9
+ export { analyzeShellCommand, listShellGovernedTools, type ShellAnalysis, type ShellApprovalFingerprintPayload, type ShellInvocation, } from "./analyze-command.js";
10
+ export { commandMayContainGovernedTool, DEFAULT_GOVERNED_SHELL_TOOLS, } from "./governed-tools.js";
17
11
  export type ShellGateDecision = {
18
12
  permission: "allow" | "deny" | "ask";
19
13
  user_message?: string;
20
14
  agent_message?: string;
21
15
  evaluation: GuardEvaluation;
16
+ analysis?: ShellAnalysis;
22
17
  };
23
18
  /**
24
19
  * MCP proposals (`beforeMCPExecution` hook, MCP `guard` with `kind: "mcp"`): if argv does not match any
@@ -29,16 +24,18 @@ export declare function evaluateMcpProposal(policy: PoliciesV1, argv: string[]):
29
24
  evaluation: GuardEvaluation;
30
25
  };
31
26
  /**
32
- * Shell proposals only: outside governed CLIs pass-through (same scope as the Cursor hook).
27
+ * Shell proposals: analyze full command string for all governed invocations.
33
28
  */
34
- export declare function evaluateShellProposal(policy: PoliciesV1, argv: string[], governedTools?: string[]): {
29
+ export declare function evaluateShellProposal(policy: PoliciesV1, commandOrArgv: string | string[]): {
35
30
  skipped: boolean;
36
31
  evaluation: GuardEvaluation;
32
+ analysis: ShellAnalysis;
37
33
  };
38
- export declare function evaluateArgv(policy: PoliciesV1, argv: string[]): GuardEvaluation;
39
34
  export declare function gateShellCommand(opts: {
40
35
  policy: PoliciesV1;
41
36
  command: string;
42
- governedTools?: string[];
43
37
  }): ShellGateDecision;
38
+ /** @deprecated Prefer `analyzeShellCommand` — kept for callers that only have flat argv. */
39
+ export declare function evaluateShellProposalFromArgv(policy: PoliciesV1, argv: string[]): ReturnType<typeof evaluateShellProposal>;
40
+ export { parseCommandToArgv as parseCommandToArgvLegacy };
44
41
  //# sourceMappingURL=evaluate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/shell/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAK9E,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAEnE,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAE/F,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,cAAc,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAClE,KAAK,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;CAC7B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EAAE,GACb;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAE,CAoBnD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,aAAa,GAAE,MAAM,EAAsC,GAC1D;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAE,CAoBnD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CAkChF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,iBAAiB,CAmBpB"}
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/shell/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,UAAU,EAAa,MAAM,oBAAoB,CAAC;AAE9E,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAgB,KAAK,eAAe,EAAoB,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,aAAa,EAClB,KAAK,+BAA+B,EACpC,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;IAC5B,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EAAE,GACb;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAE,CAoBnD;AA+BD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAC/B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,CAkC5E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,iBAAiB,CAkBpB;AAED,4FAA4F;AAC5F,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EAAE,GACb,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAE1C;AAED,OAAO,EAAE,kBAAkB,IAAI,wBAAwB,EAAE,CAAC"}
@@ -1,8 +1,11 @@
1
1
  import { classifyArgv } from "../policy/index.js";
2
+ import { analyzeShellCommand } from "./analyze-command.js";
3
+ import { evaluateArgv } from "./guard-eval.js";
2
4
  import { parseCommandToArgv } from "./parse.js";
3
- import { DEFAULT_GOVERNED_SHELL_TOOLS } from "./governed-tools.js";
5
+ export { evaluateArgv } from "./guard-eval.js";
4
6
  export { parseCommandToArgv } from "./parse.js";
5
- export { DEFAULT_GOVERNED_SHELL_TOOLS } from "./governed-tools.js";
7
+ export { analyzeShellCommand, listShellGovernedTools, } from "./analyze-command.js";
8
+ export { commandMayContainGovernedTool, DEFAULT_GOVERNED_SHELL_TOOLS, } from "./governed-tools.js";
6
9
  /**
7
10
  * MCP proposals (`beforeMCPExecution` hook, MCP `guard` with `kind: "mcp"`): if argv does not match any
8
11
  * row under `policies.mcp`, pass-through (same idea as ungoverned shell tools).
@@ -28,69 +31,70 @@ export function evaluateMcpProposal(policy, argv) {
28
31
  }
29
32
  return { skipped: false, evaluation: evaluateArgv(policy, argv) };
30
33
  }
34
+ function analysisToEvaluation(analysis) {
35
+ const { primary, tier, raw_metacharacters, invocations } = analysis;
36
+ const evaluation = { ...primary.evaluation, tier };
37
+ if (raw_metacharacters && !evaluation.reasons.some((r) => r.code === "metacharacters")) {
38
+ evaluation.reasons = [
39
+ ...evaluation.reasons,
40
+ { code: "metacharacters", message: "Composition operators in raw command; treat as high-risk." },
41
+ ];
42
+ }
43
+ if (analysis.fail_closed) {
44
+ return evaluation;
45
+ }
46
+ if (invocations.length > 1) {
47
+ evaluation.reasons = [
48
+ ...evaluation.reasons,
49
+ {
50
+ code: "multiple_invocations",
51
+ message: `Found ${invocations.length} governed invocations; tier is max across all.`,
52
+ details: { invocation_count: invocations.length },
53
+ },
54
+ ];
55
+ }
56
+ return evaluation;
57
+ }
31
58
  /**
32
- * Shell proposals only: outside governed CLIs pass-through (same scope as the Cursor hook).
59
+ * Shell proposals: analyze full command string for all governed invocations.
33
60
  */
34
- export function evaluateShellProposal(policy, argv, governedTools = [...DEFAULT_GOVERNED_SHELL_TOOLS]) {
35
- const tool = argv[0];
36
- if (!tool || !governedTools.includes(tool)) {
61
+ export function evaluateShellProposal(policy, commandOrArgv) {
62
+ const command = Array.isArray(commandOrArgv) ? commandOrArgv.join(" ") : commandOrArgv;
63
+ const analysis = analyzeShellCommand(command, policy);
64
+ if (analysis.skipped) {
37
65
  return {
38
66
  skipped: true,
67
+ analysis,
39
68
  evaluation: {
40
- argv,
69
+ argv: analysis.segments[0]?.argv ?? [],
41
70
  tier: "READ",
42
71
  reasons: [
43
72
  {
44
73
  code: "skipped",
45
- message: "Not governed (tool not in policies.v1.json governed set); pass-through.",
74
+ message: "No governed invocation found in command; pass-through.",
46
75
  },
47
76
  ],
48
- classification: { tool: tool ?? null, command_path: null, verb: null, tier: "READ", matched: false },
77
+ classification: {
78
+ tool: null,
79
+ command_path: null,
80
+ verb: null,
81
+ tier: "READ",
82
+ matched: false,
83
+ },
49
84
  flags: { metacharacters: false, dangerous_flags: false },
50
85
  },
51
86
  };
52
87
  }
53
- return { skipped: false, evaluation: evaluateArgv(policy, argv) };
54
- }
55
- export function evaluateArgv(policy, argv) {
56
- const { classification, flags } = classifyArgv(policy, argv);
57
- let tier = classification.tier;
58
- const reasons = [];
59
- if (!classification.matched) {
60
- reasons.push({
61
- code: "unknown_command",
62
- message: "Command did not match any policy entry; default-deny applies.",
63
- details: { tool: classification.tool, command_path: classification.command_path, verb: classification.verb },
64
- });
65
- }
66
- else {
67
- reasons.push({
68
- code: "policy_match",
69
- message: "Matched policy entry.",
70
- details: { tool: classification.tool, command_path: classification.command_path, verb: classification.verb, tier },
71
- });
72
- }
73
- if (flags.metacharacters) {
74
- if (tier === "READ")
75
- tier = "MUTATE";
76
- reasons.push({ code: "metacharacters", message: "Metacharacters detected; treat as high-risk." });
77
- }
78
- if (flags.dangerous_flags && (tier === "MUTATE" || tier === "DESTRUCTIVE")) {
79
- reasons.push({
80
- code: "dangerous_flags",
81
- message: "Dangerous flags detected for mutating/destructive action; rejected.",
82
- details: { dangerous_flags: policy.dangerous_flags },
83
- });
84
- tier = "DESTRUCTIVE";
85
- }
86
- return { argv, tier, reasons, classification, flags };
88
+ return {
89
+ skipped: false,
90
+ analysis,
91
+ evaluation: analysisToEvaluation(analysis),
92
+ };
87
93
  }
88
94
  export function gateShellCommand(opts) {
89
- const governedTools = opts.governedTools ?? [...DEFAULT_GOVERNED_SHELL_TOOLS];
90
- const argv = parseCommandToArgv(opts.command);
91
- const { skipped, evaluation } = evaluateShellProposal(opts.policy, argv, governedTools);
95
+ const { skipped, evaluation, analysis } = evaluateShellProposal(opts.policy, opts.command);
92
96
  if (skipped) {
93
- return { permission: "allow", evaluation };
97
+ return { permission: "allow", evaluation, analysis };
94
98
  }
95
99
  const permission = evaluation.tier === "READ" ? "allow" : "deny";
96
100
  return {
@@ -100,6 +104,12 @@ export function gateShellCommand(opts) {
100
104
  ? `Blocked by guard. tier=${evaluation.tier}. argv=${JSON.stringify(evaluation.argv)}`
101
105
  : undefined,
102
106
  evaluation,
107
+ analysis,
103
108
  };
104
109
  }
110
+ /** @deprecated Prefer `analyzeShellCommand` — kept for callers that only have flat argv. */
111
+ export function evaluateShellProposalFromArgv(policy, argv) {
112
+ return evaluateShellProposal(policy, argv);
113
+ }
114
+ export { parseCommandToArgv as parseCommandToArgvLegacy };
105
115
  //# sourceMappingURL=evaluate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/shell/evaluate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/shell/evaluate.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,20 @@
1
- /** Tools whose argv is classified against `policies.v1.json` (same scope as the Cursor hook). */
1
+ import type { PoliciesV1 } from "../policy/index.js";
2
+ /** @deprecated Use `listShellGovernedTools(policy)` — policy keys are the source of truth. */
2
3
  export declare const DEFAULT_GOVERNED_SHELL_TOOLS: string[];
4
+ declare const DEFAULT_PRELUDE_VERBS: readonly ["cd", "pushd", "popd"];
5
+ declare const DEFAULT_PRIVILEGE_VERBS: readonly ["sudo", "doas"];
6
+ export type ShellPolicyConfig = {
7
+ prelude_verbs: readonly string[];
8
+ privilege_verbs: readonly string[];
9
+ };
10
+ export declare function policyExcludeSet(): Set<string>;
11
+ export declare function listShellGovernedTools(policy: PoliciesV1): readonly string[];
12
+ export declare function resolveShellPolicyConfig(policy: PoliciesV1): ShellPolicyConfig;
13
+ export declare function normalizeExecutableToken(token: string, governedTools: readonly string[]): string | null;
14
+ /**
15
+ * Fast path: scan parsed tokens without loading policy. Used before `loadPoliciesV1()`.
16
+ * When `governedToolNames` is omitted, checks against bundled default tool names.
17
+ */
18
+ export declare function commandMayContainGovernedTool(command: string, governedToolNames?: readonly string[]): boolean;
19
+ export { DEFAULT_PRELUDE_VERBS, DEFAULT_PRIVILEGE_VERBS };
3
20
  //# sourceMappingURL=governed-tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"governed-tools.d.ts","sourceRoot":"","sources":["../../src/shell/governed-tools.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,eAAO,MAAM,4BAA4B,EAAE,MAAM,EAAwC,CAAC"}
1
+ {"version":3,"file":"governed-tools.d.ts","sourceRoot":"","sources":["../../src/shell/governed-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,8FAA8F;AAC9F,eAAO,MAAM,4BAA4B,EAAE,MAAM,EAAwC,CAAC;AAI1F,QAAA,MAAM,qBAAqB,kCAAmC,CAAC;AAC/D,QAAA,MAAM,uBAAuB,2BAA4B,CAAC;AAE1D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,CAAC;AAEF,wBAAgB,gBAAgB,IAAI,GAAG,CAAC,MAAM,CAAC,CAI9C;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,MAAM,EAAE,CAG5E;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,UAAU,GAAG,iBAAiB,CAM9E;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAOvG;AAWD;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,EACf,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,GACpC,OAAO,CAUT;AAED,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,CAAC"}
@@ -1,3 +1,62 @@
1
- /** Tools whose argv is classified against `policies.v1.json` (same scope as the Cursor hook). */
1
+ import { parseShellTokens } from "./parse-segments.js";
2
+ /** @deprecated Use `listShellGovernedTools(policy)` — policy keys are the source of truth. */
2
3
  export const DEFAULT_GOVERNED_SHELL_TOOLS = ["gcloud", "firebase", "gh", "git"];
4
+ const DEFAULT_POLICY_EXCLUDE = new Set(["mcp"]);
5
+ const DEFAULT_PRELUDE_VERBS = ["cd", "pushd", "popd"];
6
+ const DEFAULT_PRIVILEGE_VERBS = ["sudo", "doas"];
7
+ export function policyExcludeSet() {
8
+ const fromEnv = process.env.PRAXIS_SHELL_POLICY_EXCLUDE?.trim();
9
+ if (!fromEnv)
10
+ return DEFAULT_POLICY_EXCLUDE;
11
+ return new Set(fromEnv.split(",").map((s) => s.trim()).filter(Boolean));
12
+ }
13
+ export function listShellGovernedTools(policy) {
14
+ const excluded = policyExcludeSet();
15
+ return Object.keys(policy.policies).filter((k) => !excluded.has(k));
16
+ }
17
+ export function resolveShellPolicyConfig(policy) {
18
+ const shell = policy.shell;
19
+ return {
20
+ prelude_verbs: shell?.prelude_verbs?.length ? shell.prelude_verbs : DEFAULT_PRELUDE_VERBS,
21
+ privilege_verbs: shell?.privilege_verbs?.length ? shell.privilege_verbs : DEFAULT_PRIVILEGE_VERBS,
22
+ };
23
+ }
24
+ export function normalizeExecutableToken(token, governedTools) {
25
+ if (governedTools.includes(token))
26
+ return token;
27
+ const isPathLike = token.includes("/") || token.startsWith(".");
28
+ if (!isPathLike)
29
+ return null;
30
+ const base = token.split("/").pop();
31
+ if (!base)
32
+ return null;
33
+ return governedTools.includes(base) ? base : null;
34
+ }
35
+ function tokenMightBeGoverned(token, governedSet) {
36
+ if (governedSet.has(token))
37
+ return true;
38
+ if (token.includes("/") || token.startsWith(".")) {
39
+ const base = token.split("/").pop();
40
+ if (base && governedSet.has(base))
41
+ return true;
42
+ }
43
+ return false;
44
+ }
45
+ /**
46
+ * Fast path: scan parsed tokens without loading policy. Used before `loadPoliciesV1()`.
47
+ * When `governedToolNames` is omitted, checks against bundled default tool names.
48
+ */
49
+ export function commandMayContainGovernedTool(command, governedToolNames) {
50
+ const governedSet = new Set(governedToolNames ?? DEFAULT_GOVERNED_SHELL_TOOLS);
51
+ const tokens = parseShellTokens(command);
52
+ if (tokens[0] === "<unparseable>")
53
+ return true;
54
+ for (const token of tokens) {
55
+ if (typeof token === "string" && tokenMightBeGoverned(token, governedSet)) {
56
+ return true;
57
+ }
58
+ }
59
+ return false;
60
+ }
61
+ export { DEFAULT_PRELUDE_VERBS, DEFAULT_PRIVILEGE_VERBS };
3
62
  //# sourceMappingURL=governed-tools.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"governed-tools.js","sourceRoot":"","sources":["../../src/shell/governed-tools.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,MAAM,CAAC,MAAM,4BAA4B,GAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"governed-tools.js","sourceRoot":"","sources":["../../src/shell/governed-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { classifyArgv, type PoliciesV1, type Tier } from "../policy/index.js";
2
+ export type GuardReason = {
3
+ code: string;
4
+ message: string;
5
+ details?: Record<string, unknown>;
6
+ };
7
+ export type GuardEvaluation = {
8
+ argv: string[];
9
+ tier: Tier;
10
+ reasons: GuardReason[];
11
+ classification: ReturnType<typeof classifyArgv>["classification"];
12
+ flags: ReturnType<typeof classifyArgv>["flags"];
13
+ };
14
+ export declare function evaluateArgv(policy: PoliciesV1, argv: string[]): GuardEvaluation;
15
+ //# sourceMappingURL=guard-eval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard-eval.d.ts","sourceRoot":"","sources":["../../src/shell/guard-eval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE9E,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAE/F,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,cAAc,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAClE,KAAK,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC;CACjD,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CAkChF"}
@@ -0,0 +1,35 @@
1
+ import { classifyArgv } from "../policy/index.js";
2
+ export function evaluateArgv(policy, argv) {
3
+ const { classification, flags } = classifyArgv(policy, argv);
4
+ let tier = classification.tier;
5
+ const reasons = [];
6
+ if (!classification.matched) {
7
+ reasons.push({
8
+ code: "unknown_command",
9
+ message: "Command did not match any policy entry; default-deny applies.",
10
+ details: { tool: classification.tool, command_path: classification.command_path, verb: classification.verb },
11
+ });
12
+ }
13
+ else {
14
+ reasons.push({
15
+ code: "policy_match",
16
+ message: "Matched policy entry.",
17
+ details: { tool: classification.tool, command_path: classification.command_path, verb: classification.verb, tier },
18
+ });
19
+ }
20
+ if (flags.metacharacters) {
21
+ if (tier === "READ")
22
+ tier = "MUTATE";
23
+ reasons.push({ code: "metacharacters", message: "Metacharacters detected; treat as high-risk." });
24
+ }
25
+ if (flags.dangerous_flags && (tier === "MUTATE" || tier === "DESTRUCTIVE")) {
26
+ reasons.push({
27
+ code: "dangerous_flags",
28
+ message: "Dangerous flags detected for mutating/destructive action; rejected.",
29
+ details: { dangerous_flags: policy.dangerous_flags },
30
+ });
31
+ tier = "DESTRUCTIVE";
32
+ }
33
+ return { argv, tier, reasons, classification, flags };
34
+ }
35
+ //# sourceMappingURL=guard-eval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard-eval.js","sourceRoot":"","sources":["../../src/shell/guard-eval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA8B,MAAM,oBAAoB,CAAC;AAY9E,MAAM,UAAU,YAAY,CAAC,MAAkB,EAAE,IAAc;IAC7D,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7D,IAAI,IAAI,GAAS,cAAc,CAAC,IAAI,CAAC;IAErC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,iBAAiB;YACvB,OAAO,EAAE,+DAA+D;YACxE,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC,YAAY,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE;SAC7G,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,uBAAuB;YAChC,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC,YAAY,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE;SACnH,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,MAAM;YAAE,IAAI,GAAG,QAAQ,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,aAAa,CAAC,EAAE,CAAC;QAC3E,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,iBAAiB;YACvB,OAAO,EAAE,qEAAqE;YAC9E,OAAO,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE;SACrD,CAAC,CAAC;QACH,IAAI,GAAG,aAAa,CAAC;IACvB,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;AACxD,CAAC"}
@@ -0,0 +1,14 @@
1
+ export type ShellOperator = "&&" | "||" | ";" | "|";
2
+ export type ShellParseToken = string | {
3
+ op: string;
4
+ };
5
+ export declare function parseShellTokens(command: string): ShellParseToken[];
6
+ export declare function isUnparseableTokens(tokens: ShellParseToken[]): boolean;
7
+ export declare function parseShellSegments(command: string): {
8
+ tokens: ShellParseToken[];
9
+ segments: {
10
+ argv: string[];
11
+ }[];
12
+ operators: ShellOperator[];
13
+ };
14
+ //# sourceMappingURL=parse-segments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-segments.d.ts","sourceRoot":"","sources":["../../src/shell/parse-segments.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC;AAIpD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CAInE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,OAAO,CAEtE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG;IACnD,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAC/B,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B,CA+BA"}
@@ -0,0 +1,41 @@
1
+ import { parse as shellParse } from "shell-quote";
2
+ const SEGMENT_OPERATORS = new Set(["&&", "||", ";", "|"]);
3
+ export function parseShellTokens(command) {
4
+ const parsed = shellParse(command);
5
+ if (parsed.length === 0)
6
+ return ["<unparseable>", command];
7
+ return parsed;
8
+ }
9
+ export function isUnparseableTokens(tokens) {
10
+ return tokens.length >= 1 && tokens[0] === "<unparseable>";
11
+ }
12
+ export function parseShellSegments(command) {
13
+ const tokens = parseShellTokens(command);
14
+ if (isUnparseableTokens(tokens)) {
15
+ return {
16
+ tokens,
17
+ segments: [{ argv: tokens }],
18
+ operators: [],
19
+ };
20
+ }
21
+ const segments = [];
22
+ const operators = [];
23
+ let current = [];
24
+ for (const token of tokens) {
25
+ if (typeof token === "object" && token !== null && "op" in token) {
26
+ const op = token.op;
27
+ if (SEGMENT_OPERATORS.has(op)) {
28
+ segments.push({ argv: current });
29
+ current = [];
30
+ operators.push(op);
31
+ continue;
32
+ }
33
+ current.push(op);
34
+ continue;
35
+ }
36
+ current.push(token);
37
+ }
38
+ segments.push({ argv: current });
39
+ return { tokens, segments, operators };
40
+ }
41
+ //# sourceMappingURL=parse-segments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-segments.js","sourceRoot":"","sources":["../../src/shell/parse-segments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAIlD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAIlE,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAC3D,OAAO,MAA2B,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAyB;IAC3D,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAKhD,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,OAAO;YACL,MAAM;YACN,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAkB,EAAE,CAAC;YACxC,SAAS,EAAE,EAAE;SACd,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAyB,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAoB,EAAE,CAAC;IACtC,IAAI,OAAO,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;YACjE,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;YACpB,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;gBACjC,OAAO,GAAG,EAAE,CAAC;gBACb,SAAS,CAAC,IAAI,CAAC,EAAmB,CAAC,CAAC;gBACpC,SAAS;YACX,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjB,SAAS;QACX,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAEjC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACzC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxis.guard/auditor-cli",
3
- "version": "0.0.33",
3
+ "version": "0.0.34",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "files": [