@seanmozeik/tripwire 0.8.0 → 0.9.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.
@@ -20,6 +20,11 @@ interface ShellWord {
20
20
  readonly variable?: string;
21
21
  }
22
22
  interface ShellRedirect {
23
+ /** Source bytes for a heredoc; never execute these bytes during inspection. */
24
+ readonly heredoc?: {
25
+ readonly content: string;
26
+ readonly quoted: boolean;
27
+ };
23
28
  readonly op: '>' | '>>' | '<' | '<<' | '<<<' | '<>' | '>&' | '<&' | '&>' | '&>>';
24
29
  readonly target: ShellWord;
25
30
  readonly range: SourceRange;
@@ -48,6 +53,7 @@ interface ShellDiagnostic {
48
53
  readonly range: SourceRange;
49
54
  }
50
55
  interface ShellProgram {
56
+ readonly environmentAssignments?: readonly string[];
51
57
  readonly source: string;
52
58
  readonly invocations: readonly ShellInvocation[];
53
59
  readonly redirects: readonly ShellRedirect[];
@@ -0,0 +1,3 @@
1
+ import type { CodeLanguage, CodeReport } from './types';
2
+ declare const analyzeCode: (language: CodeLanguage, source: string) => CodeReport;
3
+ export { analyzeCode };
@@ -0,0 +1,8 @@
1
+ import type { CodeLanguage, CodeOperation, CodeRange, Value } from './types';
2
+ interface CallContext {
3
+ readonly language: CodeLanguage;
4
+ readonly range: CodeRange;
5
+ readonly operations: CodeOperation[];
6
+ }
7
+ declare const resolveCall: (fn: Value, args: readonly Value[], context: CallContext) => Value;
8
+ export { resolveCall };
@@ -0,0 +1,18 @@
1
+ import type { ShellInvocation } from '../bash';
2
+ import type { CodeLanguage } from './types';
3
+ type CodeInput = {
4
+ readonly kind: 'source';
5
+ readonly language: CodeLanguage;
6
+ readonly source: string;
7
+ } | {
8
+ readonly kind: 'command';
9
+ readonly argv: readonly string[];
10
+ } | {
11
+ readonly kind: 'blocked';
12
+ readonly reason: string;
13
+ } | {
14
+ readonly kind: 'irrelevant';
15
+ };
16
+ declare const interpreterLanguage: (head: string) => CodeLanguage | null;
17
+ declare const interpreterInput: (invocation: ShellInvocation) => CodeInput;
18
+ export { interpreterInput, interpreterLanguage };
@@ -0,0 +1,4 @@
1
+ import type { SyntaxNode } from '@lezer/common';
2
+ import type { Value } from './types';
3
+ declare const containerValue: (node: SyntaxNode, evaluate: (node: SyntaxNode) => Value, text: (node: SyntaxNode) => string) => Value | null;
4
+ export { containerValue };
@@ -0,0 +1,13 @@
1
+ import type { SyntaxNode } from '@lezer/common';
2
+ import type { Value } from './types';
3
+ interface ControlContext {
4
+ readonly bindings: Map<string, Value>;
5
+ readonly text: (node: SyntaxNode) => string;
6
+ readonly evaluate: (node: SyntaxNode) => Value;
7
+ readonly statement: (node: SyntaxNode) => void;
8
+ }
9
+ declare const inspectBranches: (node: SyntaxNode, context: ControlContext) => void;
10
+ declare const inspectLoop: (node: SyntaxNode, context: ControlContext) => void;
11
+ declare const inspectComprehension: (parts: readonly SyntaxNode[], context: ControlContext) => Value;
12
+ export { inspectBranches, inspectComprehension, inspectLoop };
13
+ export type { ControlContext };
@@ -0,0 +1,9 @@
1
+ import type { CodeLanguage, Value } from './types';
2
+ declare const data: Value;
3
+ declare const fileText: (path: string) => Value;
4
+ declare const isData: (value: Value) => boolean;
5
+ declare const requireData: (values: readonly Value[]) => void;
6
+ declare const writeKind: (target: string, value: Value | undefined) => 'write' | 'truncate';
7
+ declare const dataMethod: (receiver: Value, name: string, args: readonly Value[], language: CodeLanguage) => Value;
8
+ declare const dataCall: (name: string, args: readonly Value[]) => Value | null;
9
+ export { data, dataCall, dataMethod, fileText, isData, requireData, writeKind };
@@ -0,0 +1,5 @@
1
+ import type { SyntaxNode } from '@lezer/common';
2
+ import type { CodeLanguage, Value } from './types';
3
+ declare const pythonImport: (parts: readonly SyntaxNode[], text: (node: SyntaxNode) => string) => ReadonlyMap<string, Value>;
4
+ declare const javascriptImport: (parts: readonly SyntaxNode[], text: (node: SyntaxNode) => string, language: CodeLanguage) => ReadonlyMap<string, Value>;
5
+ export { javascriptImport, pythonImport };
@@ -0,0 +1,4 @@
1
+ import type { CodeLanguage, Value } from './types';
2
+ declare const indexedValue: (value: Value, key: Value) => Value;
3
+ declare const namedMember: (value: Value, member: string, language: CodeLanguage) => Value;
4
+ export { indexedValue, namedMember };
@@ -0,0 +1,10 @@
1
+ import type { SyntaxNode } from '@lezer/common';
2
+ import type { CodeLanguage } from './types';
3
+ declare class CodeInspectionError extends Error {
4
+ name: string;
5
+ }
6
+ declare const failInspection: (message: string) => never;
7
+ declare const children: (node: SyntaxNode) => SyntaxNode[];
8
+ declare const parseCode: (language: CodeLanguage, source: string) => SyntaxNode;
9
+ declare const stringLiteral: (text: string, language?: CodeLanguage) => string;
10
+ export { CodeInspectionError, children, failInspection, parseCode, stringLiteral };
@@ -0,0 +1,51 @@
1
+ type CodeLanguage = 'python' | 'javascript' | 'typescript';
2
+ interface CodeRange {
3
+ readonly start: number;
4
+ readonly end: number;
5
+ }
6
+ type CodeOperation = {
7
+ readonly kind: 'read' | 'write' | 'delete' | 'truncate';
8
+ readonly path: string;
9
+ readonly range: CodeRange;
10
+ } | {
11
+ readonly kind: 'process';
12
+ readonly argv: readonly string[];
13
+ readonly range: CodeRange;
14
+ };
15
+ interface CodeReport {
16
+ readonly operations: readonly CodeOperation[];
17
+ /** Any gap blocks authorization, including parser recovery and budget exhaustion. */
18
+ readonly gap: string | null;
19
+ }
20
+ type Value = {
21
+ readonly kind: 'data';
22
+ } | {
23
+ readonly kind: 'text';
24
+ readonly path: string | null;
25
+ readonly preservesNonempty: boolean;
26
+ } | {
27
+ readonly kind: 'string';
28
+ readonly value: string;
29
+ } | {
30
+ readonly kind: 'number';
31
+ readonly value: number;
32
+ } | {
33
+ readonly kind: 'symbol';
34
+ readonly name: string;
35
+ } | {
36
+ readonly kind: 'path' | 'file';
37
+ readonly path: string;
38
+ } | {
39
+ readonly kind: 'method';
40
+ readonly receiver: Value;
41
+ readonly name: string;
42
+ } | {
43
+ readonly kind: 'list';
44
+ readonly items: readonly Value[];
45
+ } | {
46
+ readonly kind: 'object';
47
+ readonly entries: ReadonlyMap<string, Value>;
48
+ } | {
49
+ readonly kind: 'unknown';
50
+ };
51
+ export type { CodeLanguage, CodeOperation, CodeRange, CodeReport, Value };
@@ -0,0 +1,13 @@
1
+ import type { ShellInvocation } from '../bash';
2
+ type UvInvocation = {
3
+ readonly kind: 'command';
4
+ readonly argv: readonly string[];
5
+ readonly noSync: boolean;
6
+ } | {
7
+ readonly kind: 'blocked';
8
+ readonly reason: string;
9
+ } | {
10
+ readonly kind: 'irrelevant';
11
+ };
12
+ declare const uvInvocation: (invocation: ShellInvocation) => UvInvocation;
13
+ export { uvInvocation };
@@ -0,0 +1,9 @@
1
+ import type { CodeLanguage, Value } from './types';
2
+ declare const unknown: Value;
3
+ declare const symbol: (name: string) => Value;
4
+ declare const textValue: (value: string) => Value;
5
+ declare const valueString: (value: Value | undefined) => string;
6
+ declare const initialBindings: (language: CodeLanguage) => Map<string, Value>;
7
+ declare const moduleName: (name: string, language: CodeLanguage) => string;
8
+ declare const pythonJoin: (parts: readonly string[]) => string;
9
+ export { initialBindings, moduleName, pythonJoin, symbol, textValue, unknown, valueString };
@@ -37,9 +37,15 @@ interface ReadResponse {
37
37
  };
38
38
  }
39
39
  declare const isBashInput: (x: unknown) => x is BashInput;
40
+ declare const decodeCodeInput: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => import("effect/Option").Option<string | {
41
+ readonly code: string;
42
+ }>;
43
+ declare const decodeExecInput: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => import("effect/Option").Option<{
44
+ readonly cmd: string;
45
+ }>;
40
46
  declare const isEditInput: (x: unknown) => x is EditInput;
41
47
  declare const isWriteInput: (x: unknown) => x is WriteInput;
42
48
  declare const isReadInput: (x: unknown) => x is ReadInput;
43
49
  declare const extractResponseText: (toolName: string, response: unknown) => string;
44
50
  export type { BashInput, BashResponse, EditInput, HookEventType as HookEvent, ReadInput, ReadResponse, WriteInput, };
45
- export { HookEvent as HookEventSchema, extractResponseText, isBashInput, isEditInput, isReadInput, isWriteInput, };
51
+ export { HookEvent as HookEventSchema, extractResponseText, isBashInput, isEditInput, isReadInput, isWriteInput, decodeCodeInput, decodeExecInput, };
@@ -0,0 +1,15 @@
1
+ import { type ShellProgram } from '../lib/bash';
2
+ import type { CodeLanguage } from '../lib/code/types';
3
+ import type { SafePathsConfig } from '../lib/config';
4
+ import { type Decision } from '../lib/decision';
5
+ interface CodePolicy {
6
+ readonly safePaths: SafePathsConfig;
7
+ readonly cwd: string;
8
+ readonly inspectCommand: (command: string) => Decision;
9
+ readonly remoteHeads: ReadonlySet<string>;
10
+ }
11
+ declare const codeDeny: (message: string) => Decision;
12
+ declare const inspectCode: (language: CodeLanguage, source: string, policy: CodePolicy) => Decision;
13
+ declare const embeddedCode: (program: ShellProgram, policy: CodePolicy) => Decision;
14
+ export { codeDeny, embeddedCode, inspectCode };
15
+ export type { CodePolicy };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seanmozeik/tripwire",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Configurable safety hooks for Claude Code, Codex, Cursor, Pi, and Oh My Pi",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -60,16 +60,19 @@
60
60
  "verify": "bun run format:check && bun run lint && bun run typecheck && bun test && bun run build"
61
61
  },
62
62
  "dependencies": {
63
- "unbash": "4.0.10"
63
+ "@lezer/common": "1.5.2",
64
+ "@lezer/javascript": "1.5.4",
65
+ "@lezer/python": "1.1.19",
66
+ "unbash": "4.0.11"
64
67
  },
65
68
  "devDependencies": {
66
69
  "@effect/platform-bun": "4.0.0-rc.112",
67
- "@effect/tsgo": "0.38.0",
70
+ "@effect/tsgo": "0.45.0",
68
71
  "@seanmozeik/de-clank": "0.1.8",
69
- "bun-types": "1.4.0",
72
+ "bun-types": "1.4.2",
70
73
  "effect": "4.0.0-rc.112",
71
- "oxfmt": "0.65.0",
72
- "oxlint": "1.80.0",
74
+ "oxfmt": "0.67.0",
75
+ "oxlint": "1.82.0",
73
76
  "oxlint-tsgolint": "7.0.2001",
74
77
  "typescript": "7.0.2"
75
78
  },
@@ -78,7 +81,7 @@
78
81
  "effect": "4.0.0-rc.112"
79
82
  },
80
83
  "optionalDependencies": {
81
- "@seanmozeik/tripwire-darwin-arm64": "0.8.0"
84
+ "@seanmozeik/tripwire-darwin-arm64": "0.9.0"
82
85
  },
83
86
  "engines": {
84
87
  "bun": ">=1.4"