@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.
- package/LICENSE +21 -0
- package/README.md +492 -0
- package/dist/cli/index.d.ts +15 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +308 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +32 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +234 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/templates.d.ts +27 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +266 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/engine/action-registry.d.ts +49 -0
- package/dist/engine/action-registry.d.ts.map +1 -0
- package/dist/engine/action-registry.js +95 -0
- package/dist/engine/action-registry.js.map +1 -0
- package/dist/engine/gate.d.ts +57 -0
- package/dist/engine/gate.d.ts.map +1 -0
- package/dist/engine/gate.js +145 -0
- package/dist/engine/gate.js.map +1 -0
- package/dist/engine/runtime.d.ts +98 -0
- package/dist/engine/runtime.d.ts.map +1 -0
- package/dist/engine/runtime.js +138 -0
- package/dist/engine/runtime.js.map +1 -0
- package/dist/engine/session.d.ts +74 -0
- package/dist/engine/session.d.ts.map +1 -0
- package/dist/engine/session.js +343 -0
- package/dist/engine/session.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/ledger/ledger.d.ts +58 -0
- package/dist/ledger/ledger.d.ts.map +1 -0
- package/dist/ledger/ledger.js +188 -0
- package/dist/ledger/ledger.js.map +1 -0
- package/dist/ledger/query.d.ts +29 -0
- package/dist/ledger/query.d.ts.map +1 -0
- package/dist/ledger/query.js +61 -0
- package/dist/ledger/query.js.map +1 -0
- package/dist/ledger/types.d.ts +27 -0
- package/dist/ledger/types.d.ts.map +1 -0
- package/dist/ledger/types.js +5 -0
- package/dist/ledger/types.js.map +1 -0
- package/dist/policy/evaluator.d.ts +21 -0
- package/dist/policy/evaluator.d.ts.map +1 -0
- package/dist/policy/evaluator.js +383 -0
- package/dist/policy/evaluator.js.map +1 -0
- package/dist/policy/loader.d.ts +27 -0
- package/dist/policy/loader.d.ts.map +1 -0
- package/dist/policy/loader.js +69 -0
- package/dist/policy/loader.js.map +1 -0
- package/dist/policy/schema.d.ts +168 -0
- package/dist/policy/schema.d.ts.map +1 -0
- package/dist/policy/schema.js +107 -0
- package/dist/policy/schema.js.map +1 -0
- package/dist/proxy/mcp-proxy.d.ts +43 -0
- package/dist/proxy/mcp-proxy.d.ts.map +1 -0
- package/dist/proxy/mcp-proxy.js +240 -0
- package/dist/proxy/mcp-proxy.js.map +1 -0
- package/dist/proxy/mcp-types.d.ts +79 -0
- package/dist/proxy/mcp-types.d.ts.map +1 -0
- package/dist/proxy/mcp-types.js +28 -0
- package/dist/proxy/mcp-types.js.map +1 -0
- package/dist/proxy/shell-proxy.d.ts +52 -0
- package/dist/proxy/shell-proxy.d.ts.map +1 -0
- package/dist/proxy/shell-proxy.js +92 -0
- package/dist/proxy/shell-proxy.js.map +1 -0
- package/dist/rollback/manager.d.ts +62 -0
- package/dist/rollback/manager.d.ts.map +1 -0
- package/dist/rollback/manager.js +151 -0
- package/dist/rollback/manager.js.map +1 -0
- package/dist/server/server.d.ts +24 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +200 -0
- package/dist/server/server.js.map +1 -0
- package/dist/tools/base.d.ts +58 -0
- package/dist/tools/base.d.ts.map +1 -0
- package/dist/tools/base.js +48 -0
- package/dist/tools/base.js.map +1 -0
- package/dist/tools/command-run.d.ts +30 -0
- package/dist/tools/command-run.d.ts.map +1 -0
- package/dist/tools/command-run.js +87 -0
- package/dist/tools/command-run.js.map +1 -0
- package/dist/tools/file-read.d.ts +34 -0
- package/dist/tools/file-read.d.ts.map +1 -0
- package/dist/tools/file-read.js +67 -0
- package/dist/tools/file-read.js.map +1 -0
- package/dist/tools/file-write.d.ts +39 -0
- package/dist/tools/file-write.d.ts.map +1 -0
- package/dist/tools/file-write.js +158 -0
- package/dist/tools/file-write.js.map +1 -0
- package/dist/tools/git.d.ts +48 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +193 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/http-request.d.ts +48 -0
- package/dist/tools/http-request.d.ts.map +1 -0
- package/dist/tools/http-request.js +91 -0
- package/dist/tools/http-request.js.map +1 -0
- package/dist/types.d.ts +257 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/examples/coding-agent.policy.yaml +80 -0
- package/examples/devops-deploy.policy.yaml +107 -0
- package/examples/mcp-proxy.config.yaml +34 -0
- package/examples/simple-session.ts +161 -0
- package/examples/video-upscaler.policy.yaml +86 -0
- package/package.json +92 -0
- package/schemas/generate.ts +18 -0
- package/schemas/policy.schema.json +7 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-types.d.ts","sourceRoot":"","sources":["../../src/proxy/mcp-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,SAAS,EAAE,OAAO,GAAG,KAAK,CAAC;IAC3B,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,sEAAsE;IACtE,SAAS,EAAE,OAAO,GAAG,KAAK,CAAC;IAC3B,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAMD,eAAO,MAAM,sBAAsB;;;;;;;;;;iBAOjC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;iBAQ/B,CAAC;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Proxy configuration types.
|
|
3
|
+
*
|
|
4
|
+
* Defines the configuration for the MCP proxy server, including
|
|
5
|
+
* backend MCP server connections and transport settings.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Zod schemas for config file validation
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
export const MCPBackendConfigSchema = z.object({
|
|
12
|
+
name: z.string().min(1),
|
|
13
|
+
transport: z.enum(['stdio', 'sse']),
|
|
14
|
+
command: z.string().optional(),
|
|
15
|
+
args: z.array(z.string()).optional(),
|
|
16
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
17
|
+
url: z.string().url().optional(),
|
|
18
|
+
});
|
|
19
|
+
export const MCPProxyConfigSchema = z.object({
|
|
20
|
+
policy: z.string().min(1),
|
|
21
|
+
ledger_dir: z.string().default('.det-acp/ledgers'),
|
|
22
|
+
backends: z.array(MCPBackendConfigSchema).min(1),
|
|
23
|
+
transport: z.enum(['stdio', 'sse']).default('stdio'),
|
|
24
|
+
port: z.number().int().positive().optional(),
|
|
25
|
+
host: z.string().optional(),
|
|
26
|
+
session_metadata: z.record(z.string(), z.unknown()).optional(),
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=mcp-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-types.js","sourceRoot":"","sources":["../../src/proxy/mcp-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAsCxB,8EAA8E;AAC9E,yCAAyC;AACzC,8EAA8E;AAE9E,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACpC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAChD,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC;IAClD,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IACpD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC5C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC/D,CAAC,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell Proxy — validates shell commands against policy before execution.
|
|
3
|
+
*
|
|
4
|
+
* Wraps command execution with policy enforcement:
|
|
5
|
+
* 1. Parse the command to extract the binary name
|
|
6
|
+
* 2. Evaluate against the session policy
|
|
7
|
+
* 3. If allowed, execute and record result
|
|
8
|
+
* 4. If denied, return the denial reasons without executing
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* - Programmatic: `new ShellProxy(gateway, sessionId).exec('ls -la')`
|
|
12
|
+
* - CLI: `det-acp exec <policy> -- <command>`
|
|
13
|
+
*/
|
|
14
|
+
import type { AgentGateway } from '../engine/runtime.js';
|
|
15
|
+
export interface ShellResult {
|
|
16
|
+
/** Whether the action was allowed by policy */
|
|
17
|
+
allowed: boolean;
|
|
18
|
+
/** Exit code of the command (if executed) */
|
|
19
|
+
exitCode?: number;
|
|
20
|
+
/** Standard output (if executed) */
|
|
21
|
+
stdout?: string;
|
|
22
|
+
/** Standard error (if executed) */
|
|
23
|
+
stderr?: string;
|
|
24
|
+
/** Denial info (if denied) */
|
|
25
|
+
denied?: {
|
|
26
|
+
reasons: string[];
|
|
27
|
+
};
|
|
28
|
+
/** The action ID assigned by the gateway */
|
|
29
|
+
actionId?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ShellExecOptions {
|
|
32
|
+
/** Working directory */
|
|
33
|
+
cwd?: string;
|
|
34
|
+
/** Timeout in milliseconds */
|
|
35
|
+
timeout?: number;
|
|
36
|
+
/** Environment variables */
|
|
37
|
+
env?: Record<string, string>;
|
|
38
|
+
}
|
|
39
|
+
export declare class ShellProxy {
|
|
40
|
+
private gateway;
|
|
41
|
+
private sessionId;
|
|
42
|
+
constructor(gateway: AgentGateway, sessionId: string);
|
|
43
|
+
/**
|
|
44
|
+
* Evaluate and optionally execute a shell command.
|
|
45
|
+
*/
|
|
46
|
+
exec(command: string, opts?: ShellExecOptions): Promise<ShellResult>;
|
|
47
|
+
/**
|
|
48
|
+
* Get the session ID this proxy is associated with.
|
|
49
|
+
*/
|
|
50
|
+
getSessionId(): string;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=shell-proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-proxy.d.ts","sourceRoot":"","sources":["../../src/proxy/shell-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM;IAKpD;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;IAmE1E;;OAEG;IACH,YAAY,IAAI,MAAM;CAGvB"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell Proxy — validates shell commands against policy before execution.
|
|
3
|
+
*
|
|
4
|
+
* Wraps command execution with policy enforcement:
|
|
5
|
+
* 1. Parse the command to extract the binary name
|
|
6
|
+
* 2. Evaluate against the session policy
|
|
7
|
+
* 3. If allowed, execute and record result
|
|
8
|
+
* 4. If denied, return the denial reasons without executing
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* - Programmatic: `new ShellProxy(gateway, sessionId).exec('ls -la')`
|
|
12
|
+
* - CLI: `det-acp exec <policy> -- <command>`
|
|
13
|
+
*/
|
|
14
|
+
import { execSync } from 'node:child_process';
|
|
15
|
+
export class ShellProxy {
|
|
16
|
+
gateway;
|
|
17
|
+
sessionId;
|
|
18
|
+
constructor(gateway, sessionId) {
|
|
19
|
+
this.gateway = gateway;
|
|
20
|
+
this.sessionId = sessionId;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Evaluate and optionally execute a shell command.
|
|
24
|
+
*/
|
|
25
|
+
async exec(command, opts) {
|
|
26
|
+
// Evaluate the command against the session policy
|
|
27
|
+
const evaluation = await this.gateway.evaluate(this.sessionId, {
|
|
28
|
+
tool: 'command:run',
|
|
29
|
+
input: { command },
|
|
30
|
+
});
|
|
31
|
+
if (evaluation.decision === 'deny') {
|
|
32
|
+
return {
|
|
33
|
+
allowed: false,
|
|
34
|
+
denied: { reasons: evaluation.reasons },
|
|
35
|
+
actionId: evaluation.actionId,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (evaluation.decision === 'gate') {
|
|
39
|
+
return {
|
|
40
|
+
allowed: false,
|
|
41
|
+
denied: { reasons: [`Requires approval: ${evaluation.reasons.join('; ')}`] },
|
|
42
|
+
actionId: evaluation.actionId,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// Allowed — execute the command
|
|
46
|
+
const execOpts = {
|
|
47
|
+
cwd: opts?.cwd,
|
|
48
|
+
timeout: opts?.timeout ?? 30_000,
|
|
49
|
+
env: opts?.env ? { ...process.env, ...opts.env } : undefined,
|
|
50
|
+
encoding: 'utf-8',
|
|
51
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
52
|
+
};
|
|
53
|
+
let stdout = '';
|
|
54
|
+
let stderr = '';
|
|
55
|
+
let exitCode = 0;
|
|
56
|
+
try {
|
|
57
|
+
const result = execSync(command, execOpts);
|
|
58
|
+
stdout = typeof result === 'string' ? result : result?.toString() ?? '';
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const execErr = err;
|
|
62
|
+
exitCode = execErr.status ?? 1;
|
|
63
|
+
stdout = execErr.stdout?.toString() ?? '';
|
|
64
|
+
stderr = execErr.stderr?.toString() ?? execErr.message ?? '';
|
|
65
|
+
}
|
|
66
|
+
// Record the result
|
|
67
|
+
await this.gateway.recordResult(this.sessionId, evaluation.actionId, {
|
|
68
|
+
success: exitCode === 0,
|
|
69
|
+
output: stdout,
|
|
70
|
+
error: exitCode !== 0 ? (stderr || `Exit code: ${exitCode}`) : undefined,
|
|
71
|
+
durationMs: 0, // execSync is blocking, timing would need wrapping
|
|
72
|
+
artifacts: [
|
|
73
|
+
{ type: 'exit_code', value: String(exitCode), description: 'Process exit code' },
|
|
74
|
+
{ type: 'log', value: stdout.slice(0, 10000), description: 'stdout (truncated)' },
|
|
75
|
+
],
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
allowed: true,
|
|
79
|
+
exitCode,
|
|
80
|
+
stdout,
|
|
81
|
+
stderr,
|
|
82
|
+
actionId: evaluation.actionId,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get the session ID this proxy is associated with.
|
|
87
|
+
*/
|
|
88
|
+
getSessionId() {
|
|
89
|
+
return this.sessionId;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=shell-proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-proxy.js","sourceRoot":"","sources":["../../src/proxy/shell-proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rollback Manager — generates compensation plans for session actions.
|
|
3
|
+
*
|
|
4
|
+
* In the gateway model, the control plane does not execute actions directly,
|
|
5
|
+
* so it cannot directly rollback. Instead, it provides:
|
|
6
|
+
* - A compensation plan listing actions that should be undone
|
|
7
|
+
* - Integration with the ShellProxy or MCP proxy to execute compensating actions
|
|
8
|
+
*
|
|
9
|
+
* All rollback actions are recorded in the evidence ledger.
|
|
10
|
+
*/
|
|
11
|
+
import type { ActionRegistry } from '../engine/action-registry.js';
|
|
12
|
+
import type { EvidenceLedger } from '../ledger/ledger.js';
|
|
13
|
+
import type { ExecutionContext, SessionAction, RollbackResult } from '../types.js';
|
|
14
|
+
export interface CompensationStep {
|
|
15
|
+
actionId: string;
|
|
16
|
+
actionIndex: number;
|
|
17
|
+
tool: string;
|
|
18
|
+
input: Record<string, unknown>;
|
|
19
|
+
/** Whether this action was successfully executed (and thus may need rollback) */
|
|
20
|
+
wasExecuted: boolean;
|
|
21
|
+
/** Whether the tool adapter supports rollback */
|
|
22
|
+
canRollback: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface CompensationPlan {
|
|
25
|
+
sessionId: string;
|
|
26
|
+
/** Steps in reverse order (last executed = first to compensate) */
|
|
27
|
+
steps: CompensationStep[];
|
|
28
|
+
}
|
|
29
|
+
export interface RollbackReport {
|
|
30
|
+
totalSteps: number;
|
|
31
|
+
succeeded: number;
|
|
32
|
+
failed: number;
|
|
33
|
+
skipped: number;
|
|
34
|
+
results: Array<{
|
|
35
|
+
actionId: string;
|
|
36
|
+
actionIndex: number;
|
|
37
|
+
tool: string;
|
|
38
|
+
result: RollbackResult;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
export declare class RollbackManager {
|
|
42
|
+
private registry;
|
|
43
|
+
private ledger;
|
|
44
|
+
constructor(registry: ActionRegistry, ledger: EvidenceLedger);
|
|
45
|
+
/**
|
|
46
|
+
* Build a compensation plan from session actions.
|
|
47
|
+
* Returns steps in reverse order (last executed = first to compensate).
|
|
48
|
+
*/
|
|
49
|
+
buildCompensationPlan(sessionId: string, actions: SessionAction[]): CompensationPlan;
|
|
50
|
+
/**
|
|
51
|
+
* Execute a compensation plan using registered tool adapters.
|
|
52
|
+
* Only works for tools that have adapters with rollback support.
|
|
53
|
+
* Continues even if individual rollbacks fail (best-effort).
|
|
54
|
+
*/
|
|
55
|
+
execute(plan: CompensationPlan, ctx: ExecutionContext): Promise<RollbackReport>;
|
|
56
|
+
/**
|
|
57
|
+
* Get a compensation plan without executing it.
|
|
58
|
+
* Useful for the gateway model where the caller handles execution.
|
|
59
|
+
*/
|
|
60
|
+
getCompensationPlan(sessionId: string, actions: SessionAction[]): CompensationPlan;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/rollback/manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,cAAc,EACf,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,iFAAiF;IACjF,WAAW,EAAE,OAAO,CAAC;IACrB,iDAAiD;IACjD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,cAAc,CAAC;KACxB,CAAC,CAAC;CACJ;AAED,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;gBADN,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,cAAc;IAGhC;;;OAGG;IACH,qBAAqB,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EAAE,GACvB,gBAAgB;IAqBnB;;;;OAIG;IACG,OAAO,CACX,IAAI,EAAE,gBAAgB,EACtB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,cAAc,CAAC;IA0G1B;;;OAGG;IACH,mBAAmB,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EAAE,GACvB,gBAAgB;CAGpB"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rollback Manager — generates compensation plans for session actions.
|
|
3
|
+
*
|
|
4
|
+
* In the gateway model, the control plane does not execute actions directly,
|
|
5
|
+
* so it cannot directly rollback. Instead, it provides:
|
|
6
|
+
* - A compensation plan listing actions that should be undone
|
|
7
|
+
* - Integration with the ShellProxy or MCP proxy to execute compensating actions
|
|
8
|
+
*
|
|
9
|
+
* All rollback actions are recorded in the evidence ledger.
|
|
10
|
+
*/
|
|
11
|
+
export class RollbackManager {
|
|
12
|
+
registry;
|
|
13
|
+
ledger;
|
|
14
|
+
constructor(registry, ledger) {
|
|
15
|
+
this.registry = registry;
|
|
16
|
+
this.ledger = ledger;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build a compensation plan from session actions.
|
|
20
|
+
* Returns steps in reverse order (last executed = first to compensate).
|
|
21
|
+
*/
|
|
22
|
+
buildCompensationPlan(sessionId, actions) {
|
|
23
|
+
const steps = [];
|
|
24
|
+
for (let i = actions.length - 1; i >= 0; i--) {
|
|
25
|
+
const action = actions[i];
|
|
26
|
+
const wasExecuted = action.result?.success === true;
|
|
27
|
+
const adapter = this.registry.get(action.request.tool);
|
|
28
|
+
steps.push({
|
|
29
|
+
actionId: action.id,
|
|
30
|
+
actionIndex: action.index,
|
|
31
|
+
tool: action.request.tool,
|
|
32
|
+
input: action.request.input,
|
|
33
|
+
wasExecuted,
|
|
34
|
+
canRollback: adapter != null,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return { sessionId, steps };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Execute a compensation plan using registered tool adapters.
|
|
41
|
+
* Only works for tools that have adapters with rollback support.
|
|
42
|
+
* Continues even if individual rollbacks fail (best-effort).
|
|
43
|
+
*/
|
|
44
|
+
async execute(plan, ctx) {
|
|
45
|
+
const results = [];
|
|
46
|
+
let succeeded = 0;
|
|
47
|
+
let failed = 0;
|
|
48
|
+
let skipped = 0;
|
|
49
|
+
for (const step of plan.steps) {
|
|
50
|
+
// Skip steps that were not successfully executed
|
|
51
|
+
if (!step.wasExecuted) {
|
|
52
|
+
skipped++;
|
|
53
|
+
results.push({
|
|
54
|
+
actionId: step.actionId,
|
|
55
|
+
actionIndex: step.actionIndex,
|
|
56
|
+
tool: step.tool,
|
|
57
|
+
result: {
|
|
58
|
+
tool: step.tool,
|
|
59
|
+
success: true,
|
|
60
|
+
description: 'Skipped — action was not successfully executed',
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const adapter = this.registry.get(step.tool);
|
|
66
|
+
if (!adapter) {
|
|
67
|
+
failed++;
|
|
68
|
+
const result = {
|
|
69
|
+
tool: step.tool,
|
|
70
|
+
success: false,
|
|
71
|
+
description: `Cannot rollback — tool adapter "${step.tool}" not found`,
|
|
72
|
+
error: 'Tool adapter not registered',
|
|
73
|
+
};
|
|
74
|
+
results.push({
|
|
75
|
+
actionId: step.actionId,
|
|
76
|
+
actionIndex: step.actionIndex,
|
|
77
|
+
tool: step.tool,
|
|
78
|
+
result,
|
|
79
|
+
});
|
|
80
|
+
await this.ledger.append(ctx.sessionId, 'action:rollback', {
|
|
81
|
+
actionId: step.actionId,
|
|
82
|
+
actionIndex: step.actionIndex,
|
|
83
|
+
tool: step.tool,
|
|
84
|
+
success: false,
|
|
85
|
+
error: result.error,
|
|
86
|
+
});
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
const result = await adapter.rollback(step.input, ctx);
|
|
91
|
+
results.push({
|
|
92
|
+
actionId: step.actionId,
|
|
93
|
+
actionIndex: step.actionIndex,
|
|
94
|
+
tool: step.tool,
|
|
95
|
+
result,
|
|
96
|
+
});
|
|
97
|
+
if (result.success) {
|
|
98
|
+
succeeded++;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
failed++;
|
|
102
|
+
}
|
|
103
|
+
await this.ledger.append(ctx.sessionId, 'action:rollback', {
|
|
104
|
+
actionId: step.actionId,
|
|
105
|
+
actionIndex: step.actionIndex,
|
|
106
|
+
tool: step.tool,
|
|
107
|
+
success: result.success,
|
|
108
|
+
description: result.description,
|
|
109
|
+
error: result.error,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
failed++;
|
|
114
|
+
const result = {
|
|
115
|
+
tool: step.tool,
|
|
116
|
+
success: false,
|
|
117
|
+
description: 'Rollback threw an exception',
|
|
118
|
+
error: err.message,
|
|
119
|
+
};
|
|
120
|
+
results.push({
|
|
121
|
+
actionId: step.actionId,
|
|
122
|
+
actionIndex: step.actionIndex,
|
|
123
|
+
tool: step.tool,
|
|
124
|
+
result,
|
|
125
|
+
});
|
|
126
|
+
await this.ledger.append(ctx.sessionId, 'action:rollback', {
|
|
127
|
+
actionId: step.actionId,
|
|
128
|
+
actionIndex: step.actionIndex,
|
|
129
|
+
tool: step.tool,
|
|
130
|
+
success: false,
|
|
131
|
+
error: err.message,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
totalSteps: plan.steps.length,
|
|
137
|
+
succeeded,
|
|
138
|
+
failed,
|
|
139
|
+
skipped,
|
|
140
|
+
results,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get a compensation plan without executing it.
|
|
145
|
+
* Useful for the gateway model where the caller handles execution.
|
|
146
|
+
*/
|
|
147
|
+
getCompensationPlan(sessionId, actions) {
|
|
148
|
+
return this.buildCompensationPlan(sessionId, actions);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/rollback/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Session Server — language-agnostic interface to the Deterministic Agent Control Protocol.
|
|
3
|
+
*
|
|
4
|
+
* Provides REST endpoints for:
|
|
5
|
+
* - Session creation, evaluation, result recording
|
|
6
|
+
* - Gate approval/rejection
|
|
7
|
+
* - Session termination and reporting
|
|
8
|
+
* - Ledger queries and integrity verification
|
|
9
|
+
* - Policy validation
|
|
10
|
+
* - Health checks
|
|
11
|
+
*/
|
|
12
|
+
import type { FastifyInstance } from 'fastify';
|
|
13
|
+
import { type GatewayConfig } from '../engine/runtime.js';
|
|
14
|
+
export interface ServerConfig {
|
|
15
|
+
host?: string;
|
|
16
|
+
port?: number;
|
|
17
|
+
gatewayConfig: GatewayConfig;
|
|
18
|
+
}
|
|
19
|
+
export declare function createServer(config: ServerConfig): Promise<FastifyInstance>;
|
|
20
|
+
/**
|
|
21
|
+
* Start the session server.
|
|
22
|
+
*/
|
|
23
|
+
export declare function startServer(config: ServerConfig): Promise<FastifyInstance>;
|
|
24
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAUxE,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CA0OjF;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAQhF"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Session Server — language-agnostic interface to the Deterministic Agent Control Protocol.
|
|
3
|
+
*
|
|
4
|
+
* Provides REST endpoints for:
|
|
5
|
+
* - Session creation, evaluation, result recording
|
|
6
|
+
* - Gate approval/rejection
|
|
7
|
+
* - Session termination and reporting
|
|
8
|
+
* - Ledger queries and integrity verification
|
|
9
|
+
* - Policy validation
|
|
10
|
+
* - Health checks
|
|
11
|
+
*/
|
|
12
|
+
import Fastify from 'fastify';
|
|
13
|
+
import { AgentGateway } from '../engine/runtime.js';
|
|
14
|
+
import { parsePolicyYaml, PolicyValidationError } from '../policy/loader.js';
|
|
15
|
+
import { EvidenceLedger } from '../ledger/ledger.js';
|
|
16
|
+
import { queryLedger, summarizeSessionLedger } from '../ledger/query.js';
|
|
17
|
+
export async function createServer(config) {
|
|
18
|
+
const app = Fastify({ logger: true });
|
|
19
|
+
// Initialize gateway
|
|
20
|
+
const gateway = await AgentGateway.create(config.gatewayConfig);
|
|
21
|
+
// --- Health ---
|
|
22
|
+
app.get('/health', async () => {
|
|
23
|
+
return {
|
|
24
|
+
status: 'ok',
|
|
25
|
+
timestamp: new Date().toISOString(),
|
|
26
|
+
tools: gateway.getRegistry().listTools(),
|
|
27
|
+
activeSessions: gateway.listSessions().filter((s) => s.state === 'active').length,
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
// --- Policy Validation ---
|
|
31
|
+
app.post('/validate', async (request, reply) => {
|
|
32
|
+
try {
|
|
33
|
+
const policy = parsePolicyYaml(request.body.yaml);
|
|
34
|
+
return { valid: true, policy };
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (err instanceof PolicyValidationError) {
|
|
38
|
+
reply.status(400);
|
|
39
|
+
return { valid: false, errors: err.issues };
|
|
40
|
+
}
|
|
41
|
+
reply.status(500);
|
|
42
|
+
return { valid: false, errors: [{ path: '', message: err.message }] };
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// --- Session Creation ---
|
|
46
|
+
app.post('/sessions', async (request, reply) => {
|
|
47
|
+
try {
|
|
48
|
+
const { policy, metadata } = request.body;
|
|
49
|
+
const session = await gateway.createSession(policy, metadata);
|
|
50
|
+
reply.status(201);
|
|
51
|
+
return { sessionId: session.id, state: session.state, session };
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
reply.status(400);
|
|
55
|
+
return { error: err.message };
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
// --- List Sessions ---
|
|
59
|
+
app.get('/sessions', async () => {
|
|
60
|
+
const sessions = gateway.listSessions();
|
|
61
|
+
return {
|
|
62
|
+
sessions: sessions.map((s) => ({
|
|
63
|
+
id: s.id,
|
|
64
|
+
state: s.state,
|
|
65
|
+
actionsCount: s.actions.length,
|
|
66
|
+
createdAt: s.createdAt,
|
|
67
|
+
updatedAt: s.updatedAt,
|
|
68
|
+
})),
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
// --- Get Session ---
|
|
72
|
+
app.get('/sessions/:id', async (request, reply) => {
|
|
73
|
+
const session = gateway.getSession(request.params.id);
|
|
74
|
+
if (!session) {
|
|
75
|
+
reply.status(404);
|
|
76
|
+
return { error: 'Session not found' };
|
|
77
|
+
}
|
|
78
|
+
return { session };
|
|
79
|
+
});
|
|
80
|
+
// --- Evaluate Action ---
|
|
81
|
+
app.post('/sessions/:id/evaluate', async (request, reply) => {
|
|
82
|
+
try {
|
|
83
|
+
const result = await gateway.evaluate(request.params.id, request.body.action);
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
reply.status(400);
|
|
88
|
+
return { error: err.message };
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
// --- Record Result ---
|
|
92
|
+
app.post('/sessions/:id/record', async (request, reply) => {
|
|
93
|
+
try {
|
|
94
|
+
await gateway.recordResult(request.params.id, request.body.actionId, request.body.result);
|
|
95
|
+
return { success: true };
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
reply.status(400);
|
|
99
|
+
return { error: err.message };
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// --- Approve Gate ---
|
|
103
|
+
app.post('/sessions/:id/approve', async (request, reply) => {
|
|
104
|
+
try {
|
|
105
|
+
await gateway.resolveGate(request.params.id, request.body.actionId, 'approved', request.body.respondedBy, request.body.reason);
|
|
106
|
+
return { approved: true };
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
reply.status(400);
|
|
110
|
+
return { error: err.message };
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
// --- Reject Gate ---
|
|
114
|
+
app.post('/sessions/:id/reject', async (request, reply) => {
|
|
115
|
+
try {
|
|
116
|
+
await gateway.resolveGate(request.params.id, request.body.actionId, 'rejected', request.body.respondedBy, request.body.reason);
|
|
117
|
+
return { rejected: true };
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
reply.status(400);
|
|
121
|
+
return { error: err.message };
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
// --- Terminate Session ---
|
|
125
|
+
app.post('/sessions/:id/terminate', async (request, reply) => {
|
|
126
|
+
try {
|
|
127
|
+
const report = await gateway.terminateSession(request.params.id, request.body?.reason);
|
|
128
|
+
return { report };
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
reply.status(400);
|
|
132
|
+
return { error: err.message };
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
// --- Session Report ---
|
|
136
|
+
app.get('/sessions/:id/report', async (request, reply) => {
|
|
137
|
+
try {
|
|
138
|
+
const report = gateway.getSessionReport(request.params.id);
|
|
139
|
+
return { report };
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
reply.status(400);
|
|
143
|
+
return { error: err.message };
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
// --- Session Ledger ---
|
|
147
|
+
app.get('/sessions/:id/ledger', async (request, reply) => {
|
|
148
|
+
const ledger = gateway.getSessionLedger(request.params.id);
|
|
149
|
+
if (!ledger) {
|
|
150
|
+
reply.status(404);
|
|
151
|
+
return { error: 'Session not found or ledger not available' };
|
|
152
|
+
}
|
|
153
|
+
const entries = ledger.readAll();
|
|
154
|
+
const filtered = queryLedger(entries, {
|
|
155
|
+
sessionId: request.params.id,
|
|
156
|
+
types: request.query.types?.split(','),
|
|
157
|
+
limit: request.query.limit ? parseInt(request.query.limit) : undefined,
|
|
158
|
+
offset: request.query.offset ? parseInt(request.query.offset) : undefined,
|
|
159
|
+
});
|
|
160
|
+
return {
|
|
161
|
+
entries: filtered,
|
|
162
|
+
total: entries.length,
|
|
163
|
+
returned: filtered.length,
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
// --- Session Ledger Summary ---
|
|
167
|
+
app.get('/sessions/:id/ledger/summary', async (request, reply) => {
|
|
168
|
+
const ledger = gateway.getSessionLedger(request.params.id);
|
|
169
|
+
if (!ledger) {
|
|
170
|
+
reply.status(404);
|
|
171
|
+
return { error: 'Session not found or ledger not available' };
|
|
172
|
+
}
|
|
173
|
+
const entries = ledger.readAll();
|
|
174
|
+
const summary = summarizeSessionLedger(entries, request.params.id);
|
|
175
|
+
return { summary };
|
|
176
|
+
});
|
|
177
|
+
// --- Ledger Integrity Check ---
|
|
178
|
+
app.get('/sessions/:id/ledger/verify', async (request, reply) => {
|
|
179
|
+
const ledger = gateway.getSessionLedger(request.params.id);
|
|
180
|
+
if (!ledger) {
|
|
181
|
+
reply.status(404);
|
|
182
|
+
return { error: 'Session not found or ledger not available' };
|
|
183
|
+
}
|
|
184
|
+
const result = EvidenceLedger.verifyIntegrity(ledger.getFilePath());
|
|
185
|
+
return { integrity: result };
|
|
186
|
+
});
|
|
187
|
+
return app;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Start the session server.
|
|
191
|
+
*/
|
|
192
|
+
export async function startServer(config) {
|
|
193
|
+
const app = await createServer(config);
|
|
194
|
+
const host = config.host ?? '127.0.0.1';
|
|
195
|
+
const port = config.port ?? 3100;
|
|
196
|
+
await app.listen({ host, port });
|
|
197
|
+
console.log(`Deterministic Agent Control Protocol gateway running at http://${host}:${port}`);
|
|
198
|
+
return app;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
|