wireal-run 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,11 @@
1
+ const { read, write } = require("./record.cjs");
2
+
3
+ read((payload) => {
4
+ write(
5
+ process.argv[2] ||
6
+ (typeof payload.hook_event_name === "string"
7
+ ? payload.hook_event_name
8
+ : "hook"),
9
+ payload,
10
+ );
11
+ });
@@ -0,0 +1,98 @@
1
+ const { isAbsolute, resolve, sep } = require("node:path");
2
+
3
+ const pathKeys = new Set([
4
+ "file_path",
5
+ "path",
6
+ "notebook_path",
7
+ "directory",
8
+ "cwd",
9
+ "target_file",
10
+ "output_path",
11
+ ]);
12
+
13
+ function inside(worktree, value) {
14
+ const root = resolve(worktree);
15
+ const full = isAbsolute(value) ? resolve(value) : resolve(root, value);
16
+ return full === root || full.startsWith(root + sep);
17
+ }
18
+
19
+ function named(input, found) {
20
+ if (Array.isArray(input)) {
21
+ for (const item of input) named(item, found);
22
+ return found;
23
+ }
24
+ if (!input || typeof input !== "object") return found;
25
+ for (const [key, value] of Object.entries(input)) {
26
+ if (typeof value === "string") {
27
+ if (pathKeys.has(key)) found.push(value);
28
+ if (key === "command")
29
+ for (const path of absolutes(value)) found.push(path);
30
+ continue;
31
+ }
32
+ named(value, found);
33
+ }
34
+ return found;
35
+ }
36
+
37
+ function absolutes(command) {
38
+ const found = [];
39
+ for (const match of command.matchAll(/(^|[\s'"=(])(~?\/[^\s'";|&)]*)/g)) {
40
+ const value = match[2];
41
+ if (value && value !== "/" && !value.startsWith("~")) found.push(value);
42
+ }
43
+ return found;
44
+ }
45
+
46
+ function decide(payload, worktree) {
47
+ if (!worktree) return { allow: true, reason: "no worktree configured" };
48
+ const paths = named(payload && payload.tool_input, []);
49
+ const outside = paths.filter((value) => !inside(worktree, value));
50
+ if (outside.length === 0)
51
+ return {
52
+ allow: true,
53
+ reason: paths.length
54
+ ? `paths stay inside ${worktree}`
55
+ : "the tool names no path",
56
+ };
57
+ return {
58
+ allow: false,
59
+ reason: `outside the worktree: ${outside.join(", ")}`,
60
+ };
61
+ }
62
+
63
+ function answer(event, verdict) {
64
+ if (event === "PreToolUse")
65
+ return {
66
+ hookSpecificOutput: {
67
+ hookEventName: "PreToolUse",
68
+ permissionDecision: verdict.allow ? "allow" : "deny",
69
+ permissionDecisionReason: verdict.reason,
70
+ },
71
+ };
72
+ return {
73
+ hookSpecificOutput: {
74
+ hookEventName: "PermissionRequest",
75
+ decision: verdict.allow
76
+ ? { behavior: "allow" }
77
+ : { behavior: "deny", message: verdict.reason },
78
+ },
79
+ };
80
+ }
81
+
82
+ module.exports = { decide, answer, inside, named };
83
+
84
+ if (require.main === module) {
85
+ const { read, write } = require("./record.cjs");
86
+ read((payload) => {
87
+ const event =
88
+ typeof payload.hook_event_name === "string"
89
+ ? payload.hook_event_name
90
+ : "PermissionRequest";
91
+ write(event, payload);
92
+ process.stdout.write(
93
+ JSON.stringify(
94
+ answer(event, decide(payload, process.env.WIREAL_AGENT_WORKTREE)),
95
+ ),
96
+ );
97
+ });
98
+ }
@@ -0,0 +1,34 @@
1
+ const { appendFileSync } = require("node:fs");
2
+
3
+ function read(then) {
4
+ let body = "";
5
+ process.stdin.setEncoding("utf8");
6
+ process.stdin.on("data", (chunk) => {
7
+ body += chunk;
8
+ });
9
+ process.stdin.on("end", () => {
10
+ let payload = {};
11
+ try {
12
+ const parsed = JSON.parse(body);
13
+ if (parsed && typeof parsed === "object") payload = parsed;
14
+ } catch {
15
+ payload = {};
16
+ }
17
+ then(payload);
18
+ });
19
+ }
20
+
21
+ function write(kind, payload) {
22
+ const file = process.env.WIREAL_AGENT_EVENTS;
23
+ if (!file) return;
24
+ try {
25
+ appendFileSync(
26
+ file,
27
+ JSON.stringify({ at: new Date().toISOString(), kind, payload }) + "\n",
28
+ );
29
+ } catch {
30
+ return;
31
+ }
32
+ }
33
+
34
+ module.exports = { read, write };
@@ -0,0 +1,6 @@
1
+ const { read, write } = require("./record.cjs");
2
+
3
+ read((payload) => {
4
+ write("statusline", payload);
5
+ process.stdout.write("\n");
6
+ });
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "wireal-run",
3
+ "version": "0.1.0",
4
+ "description": "Run Claude Code and Codex agents on your machine against a Wireal workspace.",
5
+ "license": "SEE LICENSE IN LICENSE",
6
+ "homepage": "https://wireal.co/docs",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/berkepak/wireal.git"
10
+ },
11
+ "type": "module",
12
+ "bin": {
13
+ "wireal-run": "bin/wireal-run.mjs"
14
+ },
15
+ "files": [
16
+ "bin",
17
+ "hooks",
18
+ "README.md"
19
+ ],
20
+ "engines": {
21
+ "node": ">=22"
22
+ },
23
+ "dependencies": {
24
+ "@modelcontextprotocol/server": "^2.0.0",
25
+ "@xterm/headless": "^6.0.0",
26
+ "node-pty": "1.2.0-beta.15",
27
+ "zod": "^4.5.4"
28
+ }
29
+ }