@det-acp/core 0.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.
Files changed (114) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +492 -0
  3. package/dist/cli/index.d.ts +15 -0
  4. package/dist/cli/index.d.ts.map +1 -0
  5. package/dist/cli/index.js +308 -0
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/cli/init.d.ts +32 -0
  8. package/dist/cli/init.d.ts.map +1 -0
  9. package/dist/cli/init.js +234 -0
  10. package/dist/cli/init.js.map +1 -0
  11. package/dist/cli/templates.d.ts +27 -0
  12. package/dist/cli/templates.d.ts.map +1 -0
  13. package/dist/cli/templates.js +266 -0
  14. package/dist/cli/templates.js.map +1 -0
  15. package/dist/engine/action-registry.d.ts +49 -0
  16. package/dist/engine/action-registry.d.ts.map +1 -0
  17. package/dist/engine/action-registry.js +95 -0
  18. package/dist/engine/action-registry.js.map +1 -0
  19. package/dist/engine/gate.d.ts +57 -0
  20. package/dist/engine/gate.d.ts.map +1 -0
  21. package/dist/engine/gate.js +145 -0
  22. package/dist/engine/gate.js.map +1 -0
  23. package/dist/engine/runtime.d.ts +98 -0
  24. package/dist/engine/runtime.d.ts.map +1 -0
  25. package/dist/engine/runtime.js +138 -0
  26. package/dist/engine/runtime.js.map +1 -0
  27. package/dist/engine/session.d.ts +74 -0
  28. package/dist/engine/session.d.ts.map +1 -0
  29. package/dist/engine/session.js +343 -0
  30. package/dist/engine/session.js.map +1 -0
  31. package/dist/index.d.ts +48 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +56 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/ledger/ledger.d.ts +58 -0
  36. package/dist/ledger/ledger.d.ts.map +1 -0
  37. package/dist/ledger/ledger.js +188 -0
  38. package/dist/ledger/ledger.js.map +1 -0
  39. package/dist/ledger/query.d.ts +29 -0
  40. package/dist/ledger/query.d.ts.map +1 -0
  41. package/dist/ledger/query.js +61 -0
  42. package/dist/ledger/query.js.map +1 -0
  43. package/dist/ledger/types.d.ts +27 -0
  44. package/dist/ledger/types.d.ts.map +1 -0
  45. package/dist/ledger/types.js +5 -0
  46. package/dist/ledger/types.js.map +1 -0
  47. package/dist/policy/evaluator.d.ts +21 -0
  48. package/dist/policy/evaluator.d.ts.map +1 -0
  49. package/dist/policy/evaluator.js +383 -0
  50. package/dist/policy/evaluator.js.map +1 -0
  51. package/dist/policy/loader.d.ts +27 -0
  52. package/dist/policy/loader.d.ts.map +1 -0
  53. package/dist/policy/loader.js +69 -0
  54. package/dist/policy/loader.js.map +1 -0
  55. package/dist/policy/schema.d.ts +168 -0
  56. package/dist/policy/schema.d.ts.map +1 -0
  57. package/dist/policy/schema.js +107 -0
  58. package/dist/policy/schema.js.map +1 -0
  59. package/dist/proxy/mcp-proxy.d.ts +43 -0
  60. package/dist/proxy/mcp-proxy.d.ts.map +1 -0
  61. package/dist/proxy/mcp-proxy.js +240 -0
  62. package/dist/proxy/mcp-proxy.js.map +1 -0
  63. package/dist/proxy/mcp-types.d.ts +79 -0
  64. package/dist/proxy/mcp-types.d.ts.map +1 -0
  65. package/dist/proxy/mcp-types.js +28 -0
  66. package/dist/proxy/mcp-types.js.map +1 -0
  67. package/dist/proxy/shell-proxy.d.ts +52 -0
  68. package/dist/proxy/shell-proxy.d.ts.map +1 -0
  69. package/dist/proxy/shell-proxy.js +92 -0
  70. package/dist/proxy/shell-proxy.js.map +1 -0
  71. package/dist/rollback/manager.d.ts +62 -0
  72. package/dist/rollback/manager.d.ts.map +1 -0
  73. package/dist/rollback/manager.js +151 -0
  74. package/dist/rollback/manager.js.map +1 -0
  75. package/dist/server/server.d.ts +24 -0
  76. package/dist/server/server.d.ts.map +1 -0
  77. package/dist/server/server.js +200 -0
  78. package/dist/server/server.js.map +1 -0
  79. package/dist/tools/base.d.ts +58 -0
  80. package/dist/tools/base.d.ts.map +1 -0
  81. package/dist/tools/base.js +48 -0
  82. package/dist/tools/base.js.map +1 -0
  83. package/dist/tools/command-run.d.ts +30 -0
  84. package/dist/tools/command-run.d.ts.map +1 -0
  85. package/dist/tools/command-run.js +87 -0
  86. package/dist/tools/command-run.js.map +1 -0
  87. package/dist/tools/file-read.d.ts +34 -0
  88. package/dist/tools/file-read.d.ts.map +1 -0
  89. package/dist/tools/file-read.js +67 -0
  90. package/dist/tools/file-read.js.map +1 -0
  91. package/dist/tools/file-write.d.ts +39 -0
  92. package/dist/tools/file-write.d.ts.map +1 -0
  93. package/dist/tools/file-write.js +158 -0
  94. package/dist/tools/file-write.js.map +1 -0
  95. package/dist/tools/git.d.ts +48 -0
  96. package/dist/tools/git.d.ts.map +1 -0
  97. package/dist/tools/git.js +193 -0
  98. package/dist/tools/git.js.map +1 -0
  99. package/dist/tools/http-request.d.ts +48 -0
  100. package/dist/tools/http-request.d.ts.map +1 -0
  101. package/dist/tools/http-request.js +91 -0
  102. package/dist/tools/http-request.js.map +1 -0
  103. package/dist/types.d.ts +257 -0
  104. package/dist/types.d.ts.map +1 -0
  105. package/dist/types.js +8 -0
  106. package/dist/types.js.map +1 -0
  107. package/examples/coding-agent.policy.yaml +80 -0
  108. package/examples/devops-deploy.policy.yaml +107 -0
  109. package/examples/mcp-proxy.config.yaml +34 -0
  110. package/examples/simple-session.ts +161 -0
  111. package/examples/video-upscaler.policy.yaml +86 -0
  112. package/package.json +92 -0
  113. package/schemas/generate.ts +18 -0
  114. package/schemas/policy.schema.json +7 -0
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Tool Adapter Base — the contract that every tool must implement.
3
+ *
4
+ * The runtime NEVER calls execute() directly. It always goes through:
5
+ * validate → dryRun → (gate check) → execute → verify
6
+ *
7
+ * Each step is recorded in the evidence ledger.
8
+ */
9
+ import { z } from 'zod';
10
+ import type { DryRunResult, ExecutionContext, ExecutionResult, Policy, RollbackResult, ValidationResult } from '../types.js';
11
+ export declare abstract class ToolAdapter {
12
+ /** Unique tool identifier, e.g. "file:read" */
13
+ abstract readonly name: string;
14
+ /** Human-readable description */
15
+ abstract readonly description: string;
16
+ /** Zod schema for validating tool-specific input */
17
+ abstract readonly inputSchema: z.ZodType;
18
+ /**
19
+ * Validate the input against the schema and the policy.
20
+ * Returns allow/deny/gate verdict.
21
+ */
22
+ abstract validate(input: unknown, policy: Policy): ValidationResult;
23
+ /**
24
+ * Preview what the tool would do without making any changes.
25
+ * Must be side-effect-free.
26
+ */
27
+ abstract dryRun(input: Record<string, unknown>, ctx: ExecutionContext): Promise<DryRunResult>;
28
+ /**
29
+ * Execute the action for real.
30
+ * Must capture artifacts (diffs, checksums, logs) as evidence.
31
+ * Must store rollback data in ctx.rollbackData if the action is reversible.
32
+ */
33
+ abstract execute(input: Record<string, unknown>, ctx: ExecutionContext): Promise<ExecutionResult>;
34
+ /**
35
+ * Undo the action. Called during rollback if the action was executed.
36
+ * Should use ctx.rollbackData stored during execute().
37
+ */
38
+ abstract rollback(input: Record<string, unknown>, ctx: ExecutionContext): Promise<RollbackResult>;
39
+ /**
40
+ * Generate a deterministic idempotency key for this action + input.
41
+ * Used to detect duplicate calls.
42
+ */
43
+ idempotencyKey(input: Record<string, unknown>): string;
44
+ /**
45
+ * Parse and validate the raw input against this tool's schema.
46
+ * Returns the parsed input or throws.
47
+ */
48
+ parseInput(raw: unknown): Record<string, unknown>;
49
+ /**
50
+ * Helper to create a successful execution result.
51
+ */
52
+ protected success(output: unknown, durationMs: number, artifacts?: ExecutionResult['artifacts']): ExecutionResult;
53
+ /**
54
+ * Helper to create a failed execution result.
55
+ */
56
+ protected failure(error: string, durationMs: number): ExecutionResult;
57
+ }
58
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/tools/base.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAEV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,MAAM,EACN,cAAc,EACd,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,8BAAsB,WAAW;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAE/B,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAEtC,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC;IAEzC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAEnE;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAE7F;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAEjG;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;IAEjG;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAItD;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIjD;;OAEG;IACH,SAAS,CAAC,OAAO,CACf,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,eAAe,CAAC,WAAW,CAAM,GAC3C,eAAe;IAUlB;;OAEG;IACH,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe;CAQtE"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Tool Adapter Base — the contract that every tool must implement.
3
+ *
4
+ * The runtime NEVER calls execute() directly. It always goes through:
5
+ * validate → dryRun → (gate check) → execute → verify
6
+ *
7
+ * Each step is recorded in the evidence ledger.
8
+ */
9
+ export class ToolAdapter {
10
+ /**
11
+ * Generate a deterministic idempotency key for this action + input.
12
+ * Used to detect duplicate calls.
13
+ */
14
+ idempotencyKey(input) {
15
+ return `${this.name}:${JSON.stringify(input, Object.keys(input).sort())}`;
16
+ }
17
+ /**
18
+ * Parse and validate the raw input against this tool's schema.
19
+ * Returns the parsed input or throws.
20
+ */
21
+ parseInput(raw) {
22
+ return this.inputSchema.parse(raw);
23
+ }
24
+ /**
25
+ * Helper to create a successful execution result.
26
+ */
27
+ success(output, durationMs, artifacts = []) {
28
+ return {
29
+ tool: this.name,
30
+ success: true,
31
+ output,
32
+ artifacts,
33
+ durationMs,
34
+ };
35
+ }
36
+ /**
37
+ * Helper to create a failed execution result.
38
+ */
39
+ failure(error, durationMs) {
40
+ return {
41
+ tool: this.name,
42
+ success: false,
43
+ error,
44
+ durationMs,
45
+ };
46
+ }
47
+ }
48
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/tools/base.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,MAAM,OAAgB,WAAW;IAmC/B;;;OAGG;IACH,cAAc,CAAC,KAA8B;QAC3C,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;IAC5E,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,GAAY;QACrB,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;IAChE,CAAC;IAED;;OAEG;IACO,OAAO,CACf,MAAe,EACf,UAAkB,EAClB,YAA0C,EAAE;QAE5C,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI;YACb,MAAM;YACN,SAAS;YACT,UAAU;SACX,CAAC;IACJ,CAAC;IAED;;OAEG;IACO,OAAO,CAAC,KAAa,EAAE,UAAkB;QACjD,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,KAAK;YACd,KAAK;YACL,UAAU;SACX,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * command:run — Allow-listed command execution tool adapter.
3
+ *
4
+ * Runs shell commands with strict binary allow-listing, timeout, and output capture.
5
+ */
6
+ import { z } from 'zod';
7
+ import { ToolAdapter } from './base.js';
8
+ import type { DryRunResult, ExecutionContext, ExecutionResult, Policy, RollbackResult, ValidationResult } from '../types.js';
9
+ export declare const CommandRunInputSchema: z.ZodObject<{
10
+ command: z.ZodString;
11
+ cwd: z.ZodOptional<z.ZodString>;
12
+ timeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
13
+ env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
14
+ }, z.core.$strip>;
15
+ export type CommandRunInput = z.infer<typeof CommandRunInputSchema>;
16
+ export declare class CommandRunAdapter extends ToolAdapter {
17
+ readonly name = "command:run";
18
+ readonly description = "Run a shell command from the allow-listed binaries";
19
+ readonly inputSchema: z.ZodObject<{
20
+ command: z.ZodString;
21
+ cwd: z.ZodOptional<z.ZodString>;
22
+ timeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
23
+ env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
24
+ }, z.core.$strip>;
25
+ validate(input: unknown, policy: Policy): ValidationResult;
26
+ dryRun(input: Record<string, unknown>, _ctx: ExecutionContext): Promise<DryRunResult>;
27
+ execute(input: Record<string, unknown>, ctx: ExecutionContext): Promise<ExecutionResult>;
28
+ rollback(_input: Record<string, unknown>, _ctx: ExecutionContext): Promise<RollbackResult>;
29
+ }
30
+ //# sourceMappingURL=command-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-run.d.ts","sourceRoot":"","sources":["../../src/tools/command-run.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,MAAM,EACN,cAAc,EACd,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,qBAAqB;;;;;iBAKhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,WAAW,wDAAwD;IAC5E,QAAQ,CAAC,WAAW;;;;;sBAAyB;IAE7C,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAkBpD,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAYrF,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAwCxF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;CAUjG"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * command:run — Allow-listed command execution tool adapter.
3
+ *
4
+ * Runs shell commands with strict binary allow-listing, timeout, and output capture.
5
+ */
6
+ import { execSync } from 'node:child_process';
7
+ import { z } from 'zod';
8
+ import { ToolAdapter } from './base.js';
9
+ import { evaluateAction } from '../policy/evaluator.js';
10
+ export const CommandRunInputSchema = z.object({
11
+ command: z.string().min(1, 'Command is required'),
12
+ cwd: z.string().optional(),
13
+ timeout: z.number().positive().optional().default(30000),
14
+ env: z.record(z.string(), z.string()).optional(),
15
+ });
16
+ export class CommandRunAdapter extends ToolAdapter {
17
+ name = 'command:run';
18
+ description = 'Run a shell command from the allow-listed binaries';
19
+ inputSchema = CommandRunInputSchema;
20
+ validate(input, policy) {
21
+ const parsed = CommandRunInputSchema.safeParse(input);
22
+ if (!parsed.success) {
23
+ return {
24
+ verdict: 'deny',
25
+ tool: this.name,
26
+ reasons: parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`),
27
+ };
28
+ }
29
+ // The evaluator checks the binary against the scope.binaries allow-list
30
+ // We pass input.command as input.binary for the evaluator's scope check
31
+ return evaluateAction({ tool: this.name, input: { ...parsed.data, binary: parsed.data.command } }, policy);
32
+ }
33
+ async dryRun(input, _ctx) {
34
+ const { command, cwd, timeout } = input;
35
+ const binary = command.split(/\s+/)[0];
36
+ return {
37
+ tool: this.name,
38
+ wouldDo: `Run command: "${command}" (binary: ${binary}, timeout: ${timeout}ms)`,
39
+ estimatedChanges: [],
40
+ warnings: cwd ? [] : ['No working directory specified, using process cwd'],
41
+ };
42
+ }
43
+ async execute(input, ctx) {
44
+ const start = Date.now();
45
+ const { command, cwd, timeout, env } = input;
46
+ try {
47
+ const stdout = execSync(command, {
48
+ cwd: cwd ?? process.cwd(),
49
+ timeout,
50
+ env: env ? { ...process.env, ...env } : process.env,
51
+ encoding: 'utf-8',
52
+ maxBuffer: 10 * 1024 * 1024, // 10MB
53
+ stdio: ['pipe', 'pipe', 'pipe'],
54
+ });
55
+ return this.success({ stdout: stdout.toString(), command }, Date.now() - start, [
56
+ { type: 'exit_code', value: '0', description: `Command: ${command}` },
57
+ { type: 'log', value: stdout.toString().slice(0, 4096), description: 'stdout (truncated)' },
58
+ ]);
59
+ }
60
+ catch (err) {
61
+ const execErr = err;
62
+ const exitCode = execErr.status ?? 1;
63
+ const stderr = execErr.stderr ?? execErr.message;
64
+ return {
65
+ tool: this.name,
66
+ success: false,
67
+ output: { stdout: execErr.stdout ?? '', stderr, exitCode },
68
+ error: `Command failed with exit code ${exitCode}: ${stderr}`,
69
+ artifacts: [
70
+ { type: 'exit_code', value: String(exitCode), description: `Command: ${command}` },
71
+ ],
72
+ durationMs: Date.now() - start,
73
+ };
74
+ }
75
+ }
76
+ async rollback(_input, _ctx) {
77
+ // Command execution is generally not reversible.
78
+ // Specific rollback logic would need to be defined at a higher level
79
+ // (e.g., compensation actions in the job definition).
80
+ return {
81
+ tool: this.name,
82
+ success: false,
83
+ description: 'Command execution cannot be automatically rolled back. Define compensation actions at the job level.',
84
+ };
85
+ }
86
+ }
87
+ //# sourceMappingURL=command-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-run.js","sourceRoot":"","sources":["../../src/tools/command-run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * file:read — Scoped file read tool adapter.
3
+ *
4
+ * Reads file contents, enforcing path scope from the policy.
5
+ */
6
+ import { z } from 'zod';
7
+ import { ToolAdapter } from './base.js';
8
+ import type { DryRunResult, ExecutionContext, ExecutionResult, Policy, RollbackResult, ValidationResult } from '../types.js';
9
+ export declare const FileReadInputSchema: z.ZodObject<{
10
+ path: z.ZodString;
11
+ encoding: z.ZodDefault<z.ZodEnum<{
12
+ "utf-8": "utf-8";
13
+ base64: "base64";
14
+ hex: "hex";
15
+ }>>;
16
+ }, z.core.$strip>;
17
+ export type FileReadInput = z.infer<typeof FileReadInputSchema>;
18
+ export declare class FileReadAdapter extends ToolAdapter {
19
+ readonly name = "file:read";
20
+ readonly description = "Read the contents of a file within allowed path scopes";
21
+ readonly inputSchema: z.ZodObject<{
22
+ path: z.ZodString;
23
+ encoding: z.ZodDefault<z.ZodEnum<{
24
+ "utf-8": "utf-8";
25
+ base64: "base64";
26
+ hex: "hex";
27
+ }>>;
28
+ }, z.core.$strip>;
29
+ validate(input: unknown, policy: Policy): ValidationResult;
30
+ dryRun(input: Record<string, unknown>, _ctx: ExecutionContext): Promise<DryRunResult>;
31
+ execute(input: Record<string, unknown>, _ctx: ExecutionContext): Promise<ExecutionResult>;
32
+ rollback(_input: Record<string, unknown>, _ctx: ExecutionContext): Promise<RollbackResult>;
33
+ }
34
+ //# sourceMappingURL=file-read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-read.d.ts","sourceRoot":"","sources":["../../src/tools/file-read.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,MAAM,EACN,cAAc,EACd,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,mBAAmB;;;;;;;iBAG9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,4DAA4D;IAChF,QAAQ,CAAC,WAAW;;;;;;;sBAAuB;IAE3C,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAiBpD,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAarF,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAqBzF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;CAQjG"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * file:read — Scoped file read tool adapter.
3
+ *
4
+ * Reads file contents, enforcing path scope from the policy.
5
+ */
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+ import crypto from 'node:crypto';
9
+ import { z } from 'zod';
10
+ import { ToolAdapter } from './base.js';
11
+ import { evaluateAction } from '../policy/evaluator.js';
12
+ export const FileReadInputSchema = z.object({
13
+ path: z.string().min(1, 'File path is required'),
14
+ encoding: z.enum(['utf-8', 'base64', 'hex']).default('utf-8'),
15
+ });
16
+ export class FileReadAdapter extends ToolAdapter {
17
+ name = 'file:read';
18
+ description = 'Read the contents of a file within allowed path scopes';
19
+ inputSchema = FileReadInputSchema;
20
+ validate(input, policy) {
21
+ // Schema validation
22
+ const parsed = FileReadInputSchema.safeParse(input);
23
+ if (!parsed.success) {
24
+ return {
25
+ verdict: 'deny',
26
+ tool: this.name,
27
+ reasons: parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`),
28
+ };
29
+ }
30
+ return evaluateAction({ tool: this.name, input: parsed.data }, policy);
31
+ }
32
+ async dryRun(input, _ctx) {
33
+ const { path: filePath } = input;
34
+ const absPath = path.resolve(filePath);
35
+ const exists = fs.existsSync(absPath);
36
+ return {
37
+ tool: this.name,
38
+ wouldDo: `Read file: ${absPath}`,
39
+ estimatedChanges: [],
40
+ warnings: exists ? [] : [`File does not exist: ${absPath}`],
41
+ };
42
+ }
43
+ async execute(input, _ctx) {
44
+ const start = Date.now();
45
+ const { path: filePath, encoding } = input;
46
+ const absPath = path.resolve(filePath);
47
+ try {
48
+ const content = fs.readFileSync(absPath, encoding);
49
+ const checksum = crypto.createHash('sha256').update(content).digest('hex');
50
+ return this.success({ content, size: Buffer.byteLength(content), path: absPath }, Date.now() - start, [
51
+ { type: 'checksum', value: `sha256:${checksum}`, description: `Checksum of ${absPath}` },
52
+ ]);
53
+ }
54
+ catch (err) {
55
+ return this.failure(err.message, Date.now() - start);
56
+ }
57
+ }
58
+ async rollback(_input, _ctx) {
59
+ // file:read is side-effect-free — nothing to rollback
60
+ return {
61
+ tool: this.name,
62
+ success: true,
63
+ description: 'No rollback needed for read-only operation',
64
+ };
65
+ }
66
+ }
67
+ //# sourceMappingURL=file-read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-read.js","sourceRoot":"","sources":["../../src/tools/file-read.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAUxD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,uBAAuB,CAAC;IAChD,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;CAC9D,CAAC,CAAC;AAIH,MAAM,OAAO,eAAgB,SAAQ,WAAW;IACrC,IAAI,GAAG,WAAW,CAAC;IACnB,WAAW,GAAG,wDAAwD,CAAC;IACvE,WAAW,GAAG,mBAAmB,CAAC;IAE3C,QAAQ,CAAC,KAAc,EAAE,MAAc;QACrC,oBAAoB;QACpB,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE,MAAM;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aAC7E,CAAC;QACJ,CAAC;QAED,OAAO,cAAc,CACnB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,EACvC,MAAM,CACP,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAA8B,EAAE,IAAsB;QACjE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,KAAsB,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAEtC,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,cAAc,OAAO,EAAE;YAChC,gBAAgB,EAAE,EAAE;YACpB,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,wBAAwB,OAAO,EAAE,CAAC;SAC5D,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,KAA8B,EAAE,IAAsB;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAsB,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,QAA0B,CAAC,CAAC;YACrE,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAE3E,OAAO,IAAI,CAAC,OAAO,CACjB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAC5D,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAClB;gBACE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,QAAQ,EAAE,EAAE,WAAW,EAAE,eAAe,OAAO,EAAE,EAAE;aACzF,CACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,OAAO,CAAE,GAAa,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAA+B,EAAE,IAAsB;QACpE,sDAAsD;QACtD,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,4CAA4C;SAC1D,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * file:write — Scoped file write tool adapter.
3
+ *
4
+ * Writes file contents, enforcing path scope from the policy.
5
+ * Creates a backup before writing for rollback support.
6
+ */
7
+ import { z } from 'zod';
8
+ import { ToolAdapter } from './base.js';
9
+ import type { DryRunResult, ExecutionContext, ExecutionResult, Policy, RollbackResult, ValidationResult } from '../types.js';
10
+ export declare const FileWriteInputSchema: z.ZodObject<{
11
+ path: z.ZodString;
12
+ content: z.ZodString;
13
+ encoding: z.ZodDefault<z.ZodEnum<{
14
+ "utf-8": "utf-8";
15
+ base64: "base64";
16
+ hex: "hex";
17
+ }>>;
18
+ createDirs: z.ZodDefault<z.ZodBoolean>;
19
+ }, z.core.$strip>;
20
+ export type FileWriteInput = z.infer<typeof FileWriteInputSchema>;
21
+ export declare class FileWriteAdapter extends ToolAdapter {
22
+ readonly name = "file:write";
23
+ readonly description = "Write contents to a file within allowed path scopes";
24
+ readonly inputSchema: z.ZodObject<{
25
+ path: z.ZodString;
26
+ content: z.ZodString;
27
+ encoding: z.ZodDefault<z.ZodEnum<{
28
+ "utf-8": "utf-8";
29
+ base64: "base64";
30
+ hex: "hex";
31
+ }>>;
32
+ createDirs: z.ZodDefault<z.ZodBoolean>;
33
+ }, z.core.$strip>;
34
+ validate(input: unknown, policy: Policy): ValidationResult;
35
+ dryRun(input: Record<string, unknown>, _ctx: ExecutionContext): Promise<DryRunResult>;
36
+ execute(input: Record<string, unknown>, ctx: ExecutionContext): Promise<ExecutionResult>;
37
+ rollback(input: Record<string, unknown>, ctx: ExecutionContext): Promise<RollbackResult>;
38
+ }
39
+ //# sourceMappingURL=file-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-write.d.ts","sourceRoot":"","sources":["../../src/tools/file-write.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAEf,MAAM,EACN,cAAc,EACd,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,oBAAoB;;;;;;;;;iBAK/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,WAAW,yDAAyD;IAC7E,QAAQ,CAAC,WAAW;;;;;;;;;sBAAwB;IAE5C,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAgBpD,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAuBrF,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAkExF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;CAsD/F"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * file:write — Scoped file write tool adapter.
3
+ *
4
+ * Writes file contents, enforcing path scope from the policy.
5
+ * Creates a backup before writing for rollback support.
6
+ */
7
+ import fs from 'node:fs';
8
+ import path from 'node:path';
9
+ import crypto from 'node:crypto';
10
+ import { z } from 'zod';
11
+ import { ToolAdapter } from './base.js';
12
+ import { evaluateAction } from '../policy/evaluator.js';
13
+ export const FileWriteInputSchema = z.object({
14
+ path: z.string().min(1, 'File path is required'),
15
+ content: z.string(),
16
+ encoding: z.enum(['utf-8', 'base64', 'hex']).default('utf-8'),
17
+ createDirs: z.boolean().default(false),
18
+ });
19
+ export class FileWriteAdapter extends ToolAdapter {
20
+ name = 'file:write';
21
+ description = 'Write contents to a file within allowed path scopes';
22
+ inputSchema = FileWriteInputSchema;
23
+ validate(input, policy) {
24
+ const parsed = FileWriteInputSchema.safeParse(input);
25
+ if (!parsed.success) {
26
+ return {
27
+ verdict: 'deny',
28
+ tool: this.name,
29
+ reasons: parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`),
30
+ };
31
+ }
32
+ return evaluateAction({ tool: this.name, input: parsed.data }, policy);
33
+ }
34
+ async dryRun(input, _ctx) {
35
+ const { path: filePath, content } = input;
36
+ const absPath = path.resolve(filePath);
37
+ const exists = fs.existsSync(absPath);
38
+ const warnings = [];
39
+ if (!exists) {
40
+ const dir = path.dirname(absPath);
41
+ if (!fs.existsSync(dir)) {
42
+ warnings.push(`Parent directory does not exist: ${dir}`);
43
+ }
44
+ }
45
+ return {
46
+ tool: this.name,
47
+ wouldDo: exists
48
+ ? `Overwrite file: ${absPath} (${Buffer.byteLength(content)} bytes)`
49
+ : `Create new file: ${absPath} (${Buffer.byteLength(content)} bytes)`,
50
+ estimatedChanges: [absPath],
51
+ warnings,
52
+ };
53
+ }
54
+ async execute(input, ctx) {
55
+ const start = Date.now();
56
+ const { path: filePath, content, encoding, createDirs } = input;
57
+ const absPath = path.resolve(filePath);
58
+ const artifacts = [];
59
+ try {
60
+ // Backup existing file for rollback
61
+ let previousContent = null;
62
+ const existed = fs.existsSync(absPath);
63
+ if (existed) {
64
+ previousContent = fs.readFileSync(absPath, 'utf-8');
65
+ const prevChecksum = crypto.createHash('sha256').update(previousContent).digest('hex');
66
+ artifacts.push({
67
+ type: 'checksum',
68
+ value: `sha256:${prevChecksum}`,
69
+ description: `Previous checksum of ${absPath}`,
70
+ });
71
+ }
72
+ // Store rollback data
73
+ const rollbackKey = `file:write:${absPath}`;
74
+ ctx.rollbackData[rollbackKey] = {
75
+ existed,
76
+ previousContent,
77
+ path: absPath,
78
+ };
79
+ // Create directories if needed
80
+ if (createDirs) {
81
+ fs.mkdirSync(path.dirname(absPath), { recursive: true });
82
+ }
83
+ // Write the file
84
+ fs.writeFileSync(absPath, content, encoding);
85
+ // Produce evidence
86
+ const newChecksum = crypto.createHash('sha256').update(content).digest('hex');
87
+ artifacts.push({
88
+ type: 'checksum',
89
+ value: `sha256:${newChecksum}`,
90
+ description: `New checksum of ${absPath}`,
91
+ });
92
+ if (previousContent !== null) {
93
+ artifacts.push({
94
+ type: 'diff',
95
+ value: `--- ${absPath}\n+++ ${absPath}\n@@ modified @@\n-${previousContent.length} bytes\n+${content.length} bytes`,
96
+ description: 'Size diff',
97
+ });
98
+ }
99
+ // Update budget
100
+ ctx.budget.filesChanged++;
101
+ ctx.budget.totalOutputBytes += Buffer.byteLength(content);
102
+ return this.success({ path: absPath, bytesWritten: Buffer.byteLength(content), created: !existed }, Date.now() - start, artifacts);
103
+ }
104
+ catch (err) {
105
+ return this.failure(err.message, Date.now() - start);
106
+ }
107
+ }
108
+ async rollback(input, ctx) {
109
+ const { path: filePath } = input;
110
+ const absPath = path.resolve(filePath);
111
+ const rollbackKey = `file:write:${absPath}`;
112
+ const rollbackData = ctx.rollbackData[rollbackKey];
113
+ if (!rollbackData) {
114
+ return {
115
+ tool: this.name,
116
+ success: false,
117
+ description: 'No rollback data available',
118
+ error: 'Rollback data not found — execute() may not have been called',
119
+ };
120
+ }
121
+ try {
122
+ if (rollbackData.existed && rollbackData.previousContent !== null) {
123
+ // Restore previous content
124
+ fs.writeFileSync(rollbackData.path, rollbackData.previousContent, 'utf-8');
125
+ return {
126
+ tool: this.name,
127
+ success: true,
128
+ description: `Restored previous content of ${rollbackData.path}`,
129
+ };
130
+ }
131
+ else if (!rollbackData.existed) {
132
+ // File was newly created — delete it
133
+ if (fs.existsSync(rollbackData.path)) {
134
+ fs.unlinkSync(rollbackData.path);
135
+ }
136
+ return {
137
+ tool: this.name,
138
+ success: true,
139
+ description: `Deleted newly created file ${rollbackData.path}`,
140
+ };
141
+ }
142
+ return {
143
+ tool: this.name,
144
+ success: true,
145
+ description: 'No rollback action needed',
146
+ };
147
+ }
148
+ catch (err) {
149
+ return {
150
+ tool: this.name,
151
+ success: false,
152
+ description: `Failed to rollback file write to ${rollbackData.path}`,
153
+ error: err.message,
154
+ };
155
+ }
156
+ }
157
+ }
158
+ //# sourceMappingURL=file-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-write.js","sourceRoot":"","sources":["../../src/tools/file-write.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAWxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,uBAAuB,CAAC;IAChD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAC7D,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CACvC,CAAC,CAAC;AAIH,MAAM,OAAO,gBAAiB,SAAQ,WAAW;IACtC,IAAI,GAAG,YAAY,CAAC;IACpB,WAAW,GAAG,qDAAqD,CAAC;IACpE,WAAW,GAAG,oBAAoB,CAAC;IAE5C,QAAQ,CAAC,KAAc,EAAE,MAAc;QACrC,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE,MAAM;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aAC7E,CAAC;QACJ,CAAC;QAED,OAAO,cAAc,CACnB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,EACvC,MAAM,CACP,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAA8B,EAAE,IAAsB;QACjE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAuB,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,QAAQ,CAAC,IAAI,CAAC,oCAAoC,GAAG,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,MAAM;gBACb,CAAC,CAAC,mBAAmB,OAAO,KAAK,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS;gBACpE,CAAC,CAAC,oBAAoB,OAAO,KAAK,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS;YACvE,gBAAgB,EAAE,CAAC,OAAO,CAAC;YAC3B,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,KAA8B,EAAE,GAAqB;QACjE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,KAAuB,CAAC;QAClF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,SAAS,GAAwB,EAAE,CAAC;QAE1C,IAAI,CAAC;YACH,oCAAoC;YACpC,IAAI,eAAe,GAAkB,IAAI,CAAC;YAC1C,MAAM,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,OAAO,EAAE,CAAC;gBACZ,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACpD,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvF,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,UAAU;oBAChB,KAAK,EAAE,UAAU,YAAY,EAAE;oBAC/B,WAAW,EAAE,wBAAwB,OAAO,EAAE;iBAC/C,CAAC,CAAC;YACL,CAAC;YAED,sBAAsB;YACtB,MAAM,WAAW,GAAG,cAAc,OAAO,EAAE,CAAC;YAC5C,GAAG,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG;gBAC9B,OAAO;gBACP,eAAe;gBACf,IAAI,EAAE,OAAO;aACd,CAAC;YAEF,+BAA+B;YAC/B,IAAI,UAAU,EAAE,CAAC;gBACf,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,CAAC;YAED,iBAAiB;YACjB,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAA0B,CAAC,CAAC;YAE/D,mBAAmB;YACnB,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9E,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,UAAU,WAAW,EAAE;gBAC9B,WAAW,EAAE,mBAAmB,OAAO,EAAE;aAC1C,CAAC,CAAC;YAEH,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;gBAC7B,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,MAAM;oBACZ,KAAK,EAAE,OAAO,OAAO,SAAS,OAAO,sBAAsB,eAAe,CAAC,MAAM,YAAY,OAAO,CAAC,MAAM,QAAQ;oBACnH,WAAW,EAAE,WAAW;iBACzB,CAAC,CAAC;YACL,CAAC;YAED,gBAAgB;YAChB,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YAC1B,GAAG,CAAC,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAE1D,OAAO,IAAI,CAAC,OAAO,CACjB,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,EAC9E,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAClB,SAAS,CACV,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,OAAO,CAAE,GAAa,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAA8B,EAAE,GAAqB;QAClE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,KAAuB,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,WAAW,GAAG,cAAc,OAAO,EAAE,CAAC;QAC5C,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC,WAAW,CAIpC,CAAC;QAEd,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,4BAA4B;gBACzC,KAAK,EAAE,8DAA8D;aACtE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,IAAI,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;gBAClE,2BAA2B;gBAC3B,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;gBAC3E,OAAO;oBACL,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,OAAO,EAAE,IAAI;oBACb,WAAW,EAAE,gCAAgC,YAAY,CAAC,IAAI,EAAE;iBACjE,CAAC;YACJ,CAAC;iBAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;gBACjC,qCAAqC;gBACrC,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;gBACnC,CAAC;gBACD,OAAO;oBACL,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,OAAO,EAAE,IAAI;oBACb,WAAW,EAAE,8BAA8B,YAAY,CAAC,IAAI,EAAE;iBAC/D,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,2BAA2B;aACzC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,oCAAoC,YAAY,CAAC,IAAI,EAAE;gBACpE,KAAK,EAAG,GAAa,CAAC,OAAO;aAC9B,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * git:diff and git:apply — Scoped git tool adapters.
3
+ *
4
+ * git:diff — produces a diff of changes in a repo (read-only).
5
+ * git:apply — applies a patch to a repo (with rollback via git stash).
6
+ */
7
+ import { z } from 'zod';
8
+ import { ToolAdapter } from './base.js';
9
+ import type { DryRunResult, ExecutionContext, ExecutionResult, Policy, RollbackResult, ValidationResult } from '../types.js';
10
+ export declare const GitDiffInputSchema: z.ZodObject<{
11
+ repo: z.ZodString;
12
+ ref: z.ZodDefault<z.ZodString>;
13
+ paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
14
+ }, z.core.$strip>;
15
+ export type GitDiffInput = z.infer<typeof GitDiffInputSchema>;
16
+ export declare class GitDiffAdapter extends ToolAdapter {
17
+ readonly name = "git:diff";
18
+ readonly description = "Get git diff output for a repository";
19
+ readonly inputSchema: z.ZodObject<{
20
+ repo: z.ZodString;
21
+ ref: z.ZodDefault<z.ZodString>;
22
+ paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
23
+ }, z.core.$strip>;
24
+ validate(input: unknown, policy: Policy): ValidationResult;
25
+ dryRun(input: Record<string, unknown>, _ctx: ExecutionContext): Promise<DryRunResult>;
26
+ execute(input: Record<string, unknown>, _ctx: ExecutionContext): Promise<ExecutionResult>;
27
+ rollback(_input: Record<string, unknown>, _ctx: ExecutionContext): Promise<RollbackResult>;
28
+ }
29
+ export declare const GitApplyInputSchema: z.ZodObject<{
30
+ repo: z.ZodString;
31
+ patch: z.ZodString;
32
+ check: z.ZodDefault<z.ZodBoolean>;
33
+ }, z.core.$strip>;
34
+ export type GitApplyInput = z.infer<typeof GitApplyInputSchema>;
35
+ export declare class GitApplyAdapter extends ToolAdapter {
36
+ readonly name = "git:apply";
37
+ readonly description = "Apply a git patch to a repository";
38
+ readonly inputSchema: z.ZodObject<{
39
+ repo: z.ZodString;
40
+ patch: z.ZodString;
41
+ check: z.ZodDefault<z.ZodBoolean>;
42
+ }, z.core.$strip>;
43
+ validate(input: unknown, policy: Policy): ValidationResult;
44
+ dryRun(input: Record<string, unknown>, _ctx: ExecutionContext): Promise<DryRunResult>;
45
+ execute(input: Record<string, unknown>, ctx: ExecutionContext): Promise<ExecutionResult>;
46
+ rollback(input: Record<string, unknown>, ctx: ExecutionContext): Promise<RollbackResult>;
47
+ }
48
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/tools/git.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,MAAM,EACN,cAAc,EACd,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAMrB,eAAO,MAAM,kBAAkB;;;;iBAI7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,qBAAa,cAAe,SAAQ,WAAW;IAC7C,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,WAAW,0CAA0C;IAC9D,QAAQ,CAAC,WAAW;;;;sBAAsB;IAE1C,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAgBpD,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAUrF,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IA+BzF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;CAOjG;AAMD,eAAO,MAAM,mBAAmB;;;;iBAI9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,uCAAuC;IAC3D,QAAQ,CAAC,WAAW;;;;sBAAuB;IAE3C,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAgBpD,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAyBrF,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAwCxF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;CA+C/F"}