@xaccefy/pi-casefile 0.1.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.
@@ -0,0 +1,86 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { extname } from "node:path";
4
+
5
+ export type PocRun = {
6
+ path: string;
7
+ exitCode: number;
8
+ output: string;
9
+ ranAt: string;
10
+ sandbox: boolean;
11
+ };
12
+
13
+ /**
14
+ * Run a PoC script. Supports docker sandbox (default) or local execution.
15
+ *
16
+ * Python (.py), JavaScript (.js/.mjs/.cjs), and shell (.sh) scripts are supported.
17
+ * Unsupported extensions are rejected with a clear error.
18
+ */
19
+ export function runPoc(pocPath: string, useSandbox = true): PocRun {
20
+ if (!existsSync(pocPath)) {
21
+ throw new Error(`PoC not found on disk: ${pocPath}`);
22
+ }
23
+
24
+ const ext = extname(pocPath).toLowerCase();
25
+ const isPython = ext === ".py";
26
+ const isJavaScript = ext === ".js" || ext === ".mjs" || ext === ".cjs";
27
+
28
+ if (!isPython && !isJavaScript && ext !== ".sh") {
29
+ throw new Error(
30
+ `Unsupported PoC extension "${ext}". Supported: .py (Python), .js/.mjs/.cjs (Node), .sh (shell)`,
31
+ );
32
+ }
33
+
34
+ const ranAt = new Date().toISOString();
35
+
36
+ // Resolve the runner command and container image for the file type
37
+ const runner = isPython ? "python3" : isJavaScript ? "node" : "sh";
38
+ const image = isPython ? "python:3.12-slim" : isJavaScript ? "node:22-slim" : "alpine";
39
+
40
+ if (useSandbox) {
41
+ const containerPath = `/workspace/poc${ext}`;
42
+
43
+ const args = [
44
+ "run",
45
+ "--rm",
46
+ "--network",
47
+ "none",
48
+ "-v",
49
+ `${pocPath}:${containerPath}:ro`,
50
+ image,
51
+ runner,
52
+ containerPath,
53
+ ];
54
+
55
+ const result = spawnSync("docker", args, {
56
+ encoding: "utf8",
57
+ timeout: 30000,
58
+ maxBuffer: 8 * 1024 * 1024,
59
+ });
60
+
61
+ const output = (result.stdout ?? "") + (result.stderr ?? "");
62
+ return {
63
+ path: pocPath,
64
+ exitCode: result.status ?? (result.signal ? 1 : 0),
65
+ output: output.slice(0, 4000),
66
+ ranAt,
67
+ sandbox: true,
68
+ };
69
+ }
70
+
71
+ // Local execution
72
+ const result = spawnSync(runner, [pocPath], {
73
+ encoding: "utf8",
74
+ timeout: 30000,
75
+ maxBuffer: 8 * 1024 * 1024,
76
+ });
77
+
78
+ const output = (result.stdout ?? "") + (result.stderr ?? "");
79
+ return {
80
+ path: pocPath,
81
+ exitCode: result.status ?? (result.signal ? 1 : 0),
82
+ output: output.slice(0, 4000),
83
+ ranAt,
84
+ sandbox: false,
85
+ };
86
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * SQLite compatibility shim — transparently uses Node's built-in `node:sqlite`
3
+ * (DatabaseSync) when available, falling back to Bun's `bun:sqlite` (Database).
4
+ *
5
+ * This file is intentionally duplicated in pi-codeintel because pi-casefile is
6
+ * published as a standalone npm package and cannot share an internal module
7
+ * with sibling workspace packages. Keep the two copies in sync.
8
+ */
9
+
10
+ /** A prepared SQL statement (subset of the API used by XPI). */
11
+ export interface StatementSync {
12
+ run(...params: unknown[]): { changes: number | bigint; lastInsertRowid: number | bigint };
13
+ get(...params: unknown[]): any;
14
+ all(...params: unknown[]): any[];
15
+ }
16
+
17
+ /** A synchronous SQLite database connection (subset of the API used by XPI). */
18
+ export interface DatabaseSync {
19
+ exec(sql: string): void;
20
+ prepare(sql: string): StatementSync;
21
+ close?(): void;
22
+ }
23
+
24
+ /** Constructor loaded at module init — instance type is the `DatabaseSync` interface above. */
25
+ export let DatabaseSync: new (path: string) => DatabaseSync;
26
+
27
+ try {
28
+ const mod = await import("node:sqlite");
29
+ DatabaseSync = mod.DatabaseSync;
30
+ } catch {
31
+ const mod = await import("bun:sqlite");
32
+ DatabaseSync = mod.Database;
33
+ }