@a5c-ai/babysitter-opencode 0.1.4-staging.fd3ab4c2 → 5.0.1-staging.05ee168a

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 (44) hide show
  1. package/README.md +2 -2
  2. package/bin/cli.cjs +1 -191
  3. package/bin/cli.js +90 -49
  4. package/bin/install-shared.cjs +1 -478
  5. package/bin/install-shared.js +615 -0
  6. package/bin/install.cjs +1 -143
  7. package/bin/install.js +18 -98
  8. package/bin/uninstall.cjs +1 -87
  9. package/bin/uninstall.js +12 -34
  10. package/commands/doctor.md +5 -5
  11. package/commands/help.md +245 -244
  12. package/commands/observe.md +12 -12
  13. package/hooks/babysitter-proxied-session-created.js +24 -0
  14. package/hooks/babysitter-proxied-session-created.sh +11 -0
  15. package/hooks/babysitter-proxied-session-idle.js +24 -0
  16. package/hooks/babysitter-proxied-session-idle.sh +3 -0
  17. package/hooks/babysitter-proxied-shell-env.js +24 -0
  18. package/hooks/babysitter-proxied-shell-env.sh +3 -0
  19. package/hooks/babysitter-proxied-tool-execute-after.js +24 -0
  20. package/hooks/babysitter-proxied-tool-execute-after.sh +3 -0
  21. package/hooks/babysitter-proxied-tool-execute-before.js +24 -0
  22. package/hooks/babysitter-proxied-tool-execute-before.sh +3 -0
  23. package/hooks/hooks.json +18 -18
  24. package/package.json +22 -18
  25. package/plugin.json +6 -4
  26. package/scripts/sync-command-docs.cjs +2 -0
  27. package/scripts/team-install.js +23 -0
  28. package/skills/accomplish-status/SKILL.md +2 -0
  29. package/skills/babysit/SKILL.md +2 -0
  30. package/skills/contrib/SKILL.md +25 -25
  31. package/skills/doctor/SKILL.md +5 -5
  32. package/skills/help/SKILL.md +3 -2
  33. package/skills/observe/SKILL.md +1 -1
  34. package/skills/plugins/SKILL.md +243 -243
  35. package/skills/project-install/SKILL.md +3 -3
  36. package/skills/resume/SKILL.md +1 -1
  37. package/skills/retrospect/SKILL.md +48 -48
  38. package/skills/user-install/SKILL.md +3 -3
  39. package/versions.json +2 -2
  40. package/hooks/session-created.js +0 -181
  41. package/hooks/session-idle.js +0 -123
  42. package/hooks/shell-env.js +0 -87
  43. package/hooks/tool-execute-after.js +0 -106
  44. package/hooks/tool-execute-before.js +0 -108
package/versions.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "sdkVersion": "0.0.188-staging.fd3ab4c2",
3
- "pluginVersion": "0.1.0"
2
+ "sdkVersion": "5.0.1-staging.05ee168a",
3
+ "extensionVersion": "5.0.0"
4
4
  }
@@ -1,181 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Babysitter Session Created Hook for OpenCode
4
- *
5
- * Fires when an OpenCode session is created. Ensures the babysitter SDK CLI
6
- * is installed, then delegates to `babysitter hook:run --hook-type session-start`
7
- * to create baseline session state.
8
- *
9
- * OpenCode plugin protocol:
10
- * - Receives event context as JSON via process.argv or stdin
11
- * - Outputs JSON to stdout
12
- * - Exit 0 = success
13
- */
14
-
15
- "use strict";
16
-
17
- const { execSync, execFileSync } = require("child_process");
18
- const { readFileSync, mkdirSync, appendFileSync, existsSync, writeFileSync } = require("fs");
19
- const os = require("os");
20
- const path = require("path");
21
- const crypto = require("crypto");
22
-
23
- const PLUGIN_ROOT = process.env.OPENCODE_PLUGIN_ROOT || path.resolve(__dirname, "..");
24
- const STATE_DIR = process.env.BABYSITTER_STATE_DIR || path.join(process.cwd(), ".a5c");
25
- const LOG_DIR = process.env.BABYSITTER_LOG_DIR || path.join(os.homedir(), ".a5c", "logs");
26
- const LOG_FILE = path.join(LOG_DIR, "babysitter-session-created-hook.log");
27
-
28
- // ---------------------------------------------------------------------------
29
- // Logging
30
- // ---------------------------------------------------------------------------
31
-
32
- function ensureDir(dir) {
33
- try { mkdirSync(dir, { recursive: true }); } catch { /* best-effort */ }
34
- }
35
-
36
- function blog(msg) {
37
- ensureDir(LOG_DIR);
38
- const ts = new Date().toISOString();
39
- try {
40
- appendFileSync(LOG_FILE, `[INFO] ${ts} ${msg}\n`);
41
- } catch { /* best-effort */ }
42
- }
43
-
44
- // ---------------------------------------------------------------------------
45
- // SDK version & install
46
- // ---------------------------------------------------------------------------
47
-
48
- function getSdkVersion() {
49
- try {
50
- const versions = JSON.parse(readFileSync(path.join(PLUGIN_ROOT, "versions.json"), "utf8"));
51
- return versions.sdkVersion || "latest";
52
- } catch {
53
- return "latest";
54
- }
55
- }
56
-
57
- function hasBabysitterCli() {
58
- try {
59
- execSync("babysitter --version", { stdio: "pipe", timeout: 10000 });
60
- return true;
61
- } catch {
62
- return false;
63
- }
64
- }
65
-
66
- function installSdk(version) {
67
- const marker = path.join(PLUGIN_ROOT, ".babysitter-install-attempted");
68
- if (existsSync(marker)) return;
69
-
70
- try {
71
- execSync(`npm i -g "@a5c-ai/babysitter-sdk@${version}" --loglevel=error`, {
72
- stdio: "pipe",
73
- timeout: 120000,
74
- });
75
- blog(`Installed SDK globally (${version})`);
76
- } catch {
77
- // Try user-local prefix
78
- try {
79
- const prefix = path.join(process.env.HOME || process.env.USERPROFILE || "~", ".local");
80
- execSync(`npm i -g "@a5c-ai/babysitter-sdk@${version}" --prefix "${prefix}" --loglevel=error`, {
81
- stdio: "pipe",
82
- timeout: 120000,
83
- });
84
- blog(`Installed SDK to user prefix (${version})`);
85
- } catch {
86
- blog("SDK installation failed");
87
- }
88
- }
89
-
90
- try { writeFileSync(marker, version); } catch { /* best-effort */ }
91
- }
92
-
93
- // ---------------------------------------------------------------------------
94
- // CLI execution helper
95
- // ---------------------------------------------------------------------------
96
-
97
- function runBabysitterHook(hookType, inputJson) {
98
- const sdkVersion = getSdkVersion();
99
- const args = [
100
- "hook:run",
101
- "--hook-type", hookType,
102
- "--harness", "opencode",
103
- "--plugin-root", PLUGIN_ROOT,
104
- "--state-dir", STATE_DIR,
105
- "--json",
106
- ];
107
-
108
- try {
109
- const result = execSync(`babysitter ${args.join(" ")}`, {
110
- input: inputJson,
111
- stdio: ["pipe", "pipe", "pipe"],
112
- timeout: 30000,
113
- env: { ...process.env, BABYSITTER_STATE_DIR: STATE_DIR },
114
- });
115
- return result.toString("utf8").trim();
116
- } catch (err) {
117
- // Fall back to npx
118
- try {
119
- const result = execSync(`npx -y "@a5c-ai/babysitter-sdk@${sdkVersion}" ${args.join(" ")}`, {
120
- input: inputJson,
121
- stdio: ["pipe", "pipe", "pipe"],
122
- timeout: 60000,
123
- env: { ...process.env, BABYSITTER_STATE_DIR: STATE_DIR },
124
- });
125
- return result.toString("utf8").trim();
126
- } catch (npxErr) {
127
- blog(`Hook execution failed: ${npxErr.message}`);
128
- return "{}";
129
- }
130
- }
131
- }
132
-
133
- // ---------------------------------------------------------------------------
134
- // Main
135
- // ---------------------------------------------------------------------------
136
-
137
- function main() {
138
- blog("session-created hook invoked");
139
- blog(`PLUGIN_ROOT=${PLUGIN_ROOT}`);
140
-
141
- // Generate a session ID if OpenCode doesn't provide one
142
- const sessionId = process.env.OPENCODE_SESSION_ID
143
- || process.env.BABYSITTER_SESSION_ID
144
- || crypto.randomUUID();
145
-
146
- // Set env var so downstream hooks can pick it up
147
- process.env.BABYSITTER_SESSION_ID = sessionId;
148
-
149
- const sdkVersion = getSdkVersion();
150
-
151
- // Ensure SDK is installed
152
- if (!hasBabysitterCli()) {
153
- blog("SDK CLI not found, attempting install");
154
- installSdk(sdkVersion);
155
- }
156
-
157
- // Build hook input
158
- const hookInput = JSON.stringify({
159
- session_id: sessionId,
160
- cwd: process.cwd(),
161
- harness: "opencode",
162
- plugin_root: PLUGIN_ROOT,
163
- });
164
-
165
- blog(`Hook input: ${hookInput}`);
166
-
167
- // Delegate to SDK hook handler
168
- const result = runBabysitterHook("session-start", hookInput);
169
-
170
- blog(`Hook result: ${result}`);
171
-
172
- // Output result
173
- try {
174
- const parsed = JSON.parse(result);
175
- process.stdout.write(JSON.stringify(parsed) + "\n");
176
- } catch {
177
- process.stdout.write("{}\n");
178
- }
179
- }
180
-
181
- main();
@@ -1,123 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Babysitter Session Idle Hook for OpenCode
4
- *
5
- * Fires when the OpenCode agent goes idle. Checks if the current babysitter
6
- * run has pending effects that need attention. Since OpenCode does NOT have a
7
- * blocking stop hook, this is fire-and-forget -- it outputs context about
8
- * pending effects so the agent can decide whether to continue iterating.
9
- *
10
- * Delegates to `babysitter hook:run --hook-type stop` (which handles the
11
- * run-state inspection and iteration tracking).
12
- *
13
- * OpenCode plugin protocol:
14
- * - Receives event context as JSON via stdin
15
- * - Outputs JSON to stdout
16
- * - Exit 0 = success
17
- */
18
-
19
- "use strict";
20
-
21
- const { execSync } = require("child_process");
22
- const { readFileSync, mkdirSync, appendFileSync } = require("fs");
23
- const os = require("os");
24
- const path = require("path");
25
-
26
- const PLUGIN_ROOT = process.env.OPENCODE_PLUGIN_ROOT || path.resolve(__dirname, "..");
27
- const STATE_DIR = process.env.BABYSITTER_STATE_DIR || path.join(process.cwd(), ".a5c");
28
- const LOG_DIR = process.env.BABYSITTER_LOG_DIR || path.join(os.homedir(), ".a5c", "logs");
29
- const LOG_FILE = path.join(LOG_DIR, "babysitter-session-idle-hook.log");
30
-
31
- function ensureDir(dir) {
32
- try { mkdirSync(dir, { recursive: true }); } catch { /* best-effort */ }
33
- }
34
-
35
- function blog(msg) {
36
- ensureDir(LOG_DIR);
37
- const ts = new Date().toISOString();
38
- try {
39
- appendFileSync(LOG_FILE, `[INFO] ${ts} ${msg}\n`);
40
- } catch { /* best-effort */ }
41
- }
42
-
43
- function getSdkVersion() {
44
- try {
45
- const versions = JSON.parse(readFileSync(path.join(PLUGIN_ROOT, "versions.json"), "utf8"));
46
- return versions.sdkVersion || "latest";
47
- } catch {
48
- return "latest";
49
- }
50
- }
51
-
52
- function runBabysitterHook(hookType, inputJson) {
53
- const sdkVersion = getSdkVersion();
54
- const args = [
55
- "hook:run",
56
- "--hook-type", hookType,
57
- "--harness", "opencode",
58
- "--plugin-root", PLUGIN_ROOT,
59
- "--state-dir", STATE_DIR,
60
- "--json",
61
- ];
62
-
63
- try {
64
- const result = execSync(`babysitter ${args.join(" ")}`, {
65
- input: inputJson,
66
- stdio: ["pipe", "pipe", "pipe"],
67
- timeout: 30000,
68
- env: { ...process.env, BABYSITTER_STATE_DIR: STATE_DIR },
69
- });
70
- return result.toString("utf8").trim();
71
- } catch {
72
- try {
73
- const result = execSync(`npx -y "@a5c-ai/babysitter-sdk@${sdkVersion}" ${args.join(" ")}`, {
74
- input: inputJson,
75
- stdio: ["pipe", "pipe", "pipe"],
76
- timeout: 60000,
77
- env: { ...process.env, BABYSITTER_STATE_DIR: STATE_DIR },
78
- });
79
- return result.toString("utf8").trim();
80
- } catch (err) {
81
- blog(`Hook execution failed: ${err.message}`);
82
- return "{}";
83
- }
84
- }
85
- }
86
-
87
- function main() {
88
- blog("session-idle hook invoked");
89
-
90
- const sessionId = process.env.BABYSITTER_SESSION_ID
91
- || process.env.OPENCODE_SESSION_ID
92
- || "";
93
-
94
- if (!sessionId) {
95
- blog("No session ID -- nothing to check");
96
- process.stdout.write("{}\n");
97
- return;
98
- }
99
-
100
- const hookInput = JSON.stringify({
101
- session_id: sessionId,
102
- cwd: process.cwd(),
103
- harness: "opencode",
104
- plugin_root: PLUGIN_ROOT,
105
- });
106
-
107
- blog(`Checking run status for session ${sessionId}`);
108
-
109
- // Delegate to the stop hook handler, which inspects run state
110
- // and returns block/allow decisions
111
- const result = runBabysitterHook("stop", hookInput);
112
-
113
- blog(`Hook result: ${result}`);
114
-
115
- try {
116
- const parsed = JSON.parse(result);
117
- process.stdout.write(JSON.stringify(parsed) + "\n");
118
- } catch {
119
- process.stdout.write("{}\n");
120
- }
121
- }
122
-
123
- main();
@@ -1,87 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Babysitter Shell Environment Hook for OpenCode
4
- *
5
- * Fires when OpenCode initializes a shell environment. Injects babysitter
6
- * environment variables (BABYSITTER_SESSION_ID, BABYSITTER_STATE_DIR, etc.)
7
- * so that subprocesses and other hooks can discover the active session.
8
- *
9
- * This is critical for OpenCode because it does NOT natively inject
10
- * distinctive env vars into plugins -- the babysitter plugin must self-inject
11
- * them via this hook.
12
- *
13
- * OpenCode plugin protocol:
14
- * - Outputs env var assignments as JSON: { "env": { "KEY": "VALUE" } }
15
- * - Exit 0 = success
16
- */
17
-
18
- "use strict";
19
-
20
- const { readFileSync, mkdirSync, appendFileSync, existsSync } = require("fs");
21
- const os = require("os");
22
- const path = require("path");
23
- const crypto = require("crypto");
24
-
25
- const PLUGIN_ROOT = process.env.OPENCODE_PLUGIN_ROOT || path.resolve(__dirname, "..");
26
- const STATE_DIR = process.env.BABYSITTER_STATE_DIR || path.join(process.cwd(), ".a5c");
27
- const RUNS_DIR = process.env.BABYSITTER_RUNS_DIR || path.join(STATE_DIR, "runs");
28
- const LOG_DIR = process.env.BABYSITTER_LOG_DIR || path.join(os.homedir(), ".a5c", "logs");
29
- const LOG_FILE = path.join(LOG_DIR, "babysitter-shell-env-hook.log");
30
-
31
- function ensureDir(dir) {
32
- try { mkdirSync(dir, { recursive: true }); } catch { /* best-effort */ }
33
- }
34
-
35
- function blog(msg) {
36
- ensureDir(LOG_DIR);
37
- const ts = new Date().toISOString();
38
- try {
39
- appendFileSync(LOG_FILE, `[INFO] ${ts} ${msg}\n`);
40
- } catch { /* best-effort */ }
41
- }
42
-
43
- function getSdkVersion() {
44
- try {
45
- const versions = JSON.parse(readFileSync(path.join(PLUGIN_ROOT, "versions.json"), "utf8"));
46
- return versions.sdkVersion || "latest";
47
- } catch {
48
- return "latest";
49
- }
50
- }
51
-
52
- function main() {
53
- blog("shell-env hook invoked");
54
-
55
- // Resolve or generate session ID
56
- const sessionId = process.env.BABYSITTER_SESSION_ID
57
- || process.env.OPENCODE_SESSION_ID
58
- || crypto.randomUUID();
59
-
60
- const sdkVersion = getSdkVersion();
61
-
62
- // Build env vars to inject
63
- const env = {
64
- BABYSITTER_SESSION_ID: sessionId,
65
- OPENCODE_SESSION_ID: sessionId,
66
- BABYSITTER_STATE_DIR: STATE_DIR,
67
- BABYSITTER_RUNS_DIR: RUNS_DIR,
68
- OPENCODE_PLUGIN_ROOT: PLUGIN_ROOT,
69
- };
70
-
71
- // Add SDK version for downstream hooks
72
- if (sdkVersion && sdkVersion !== "latest") {
73
- env.BABYSITTER_SDK_VERSION = sdkVersion;
74
- }
75
-
76
- // Add global state dir if defined
77
- const globalStateDir = process.env.BABYSITTER_GLOBAL_STATE_DIR;
78
- if (globalStateDir) {
79
- env.BABYSITTER_GLOBAL_STATE_DIR = globalStateDir;
80
- }
81
-
82
- blog(`Injecting env: ${JSON.stringify(env)}`);
83
-
84
- process.stdout.write(JSON.stringify({ env }) + "\n");
85
- }
86
-
87
- main();
@@ -1,106 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Babysitter Tool Execute After Hook for OpenCode
4
- *
5
- * Fires after a tool execution in OpenCode. Delegates to
6
- * `babysitter hook:run --hook-type post-tool-use` for post-tool-use awareness.
7
- *
8
- * This hook can be used to:
9
- * - Log tool execution results for babysitter run observability
10
- * - Trigger babysitter effects based on tool outputs
11
- * - Update session state after tool executions
12
- *
13
- * OpenCode plugin protocol:
14
- * - Receives tool result context as JSON via stdin
15
- * - Outputs JSON to stdout
16
- * - Exit 0 = success
17
- */
18
-
19
- "use strict";
20
-
21
- const { execSync } = require("child_process");
22
- const { readFileSync, mkdirSync, appendFileSync } = require("fs");
23
- const os = require("os");
24
- const path = require("path");
25
-
26
- const PLUGIN_ROOT = process.env.OPENCODE_PLUGIN_ROOT || path.resolve(__dirname, "..");
27
- const STATE_DIR = process.env.BABYSITTER_STATE_DIR || path.join(process.cwd(), ".a5c");
28
- const LOG_DIR = process.env.BABYSITTER_LOG_DIR || path.join(os.homedir(), ".a5c", "logs");
29
- const LOG_FILE = path.join(LOG_DIR, "babysitter-tool-after-hook.log");
30
-
31
- function ensureDir(dir) {
32
- try { mkdirSync(dir, { recursive: true }); } catch { /* best-effort */ }
33
- }
34
-
35
- function blog(msg) {
36
- ensureDir(LOG_DIR);
37
- const ts = new Date().toISOString();
38
- try {
39
- appendFileSync(LOG_FILE, `[INFO] ${ts} ${msg}\n`);
40
- } catch { /* best-effort */ }
41
- }
42
-
43
- function getSdkVersion() {
44
- try {
45
- const versions = JSON.parse(readFileSync(path.join(PLUGIN_ROOT, "versions.json"), "utf8"));
46
- return versions.sdkVersion || "latest";
47
- } catch {
48
- return "latest";
49
- }
50
- }
51
-
52
- function main() {
53
- const sessionId = process.env.BABYSITTER_SESSION_ID
54
- || process.env.OPENCODE_SESSION_ID
55
- || "";
56
-
57
- if (!sessionId) {
58
- process.stdout.write("{}\n");
59
- return;
60
- }
61
-
62
- // Read stdin for tool result context
63
- let inputData = "";
64
- try {
65
- inputData = require("fs").readFileSync(0, "utf8");
66
- } catch {
67
- // No stdin available
68
- }
69
-
70
- blog(`tool-execute-after: session=${sessionId}`);
71
-
72
- const hookInput = JSON.stringify({
73
- session_id: sessionId,
74
- cwd: process.cwd(),
75
- harness: "opencode",
76
- plugin_root: PLUGIN_ROOT,
77
- tool_result: inputData ? JSON.parse(inputData) : {},
78
- });
79
-
80
- const sdkVersion = getSdkVersion();
81
- const args = [
82
- "hook:run",
83
- "--hook-type", "post-tool-use",
84
- "--harness", "opencode",
85
- "--plugin-root", PLUGIN_ROOT,
86
- "--state-dir", STATE_DIR,
87
- "--json",
88
- ];
89
-
90
- try {
91
- const result = execSync(`babysitter ${args.join(" ")}`, {
92
- input: hookInput,
93
- stdio: ["pipe", "pipe", "pipe"],
94
- timeout: 10000,
95
- env: { ...process.env, BABYSITTER_STATE_DIR: STATE_DIR },
96
- });
97
- const output = result.toString("utf8").trim();
98
- blog(`Hook result: ${output}`);
99
- process.stdout.write((output || "{}") + "\n");
100
- } catch {
101
- blog("Post-tool-use hook failed -- non-blocking");
102
- process.stdout.write("{}\n");
103
- }
104
- }
105
-
106
- main();
@@ -1,108 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Babysitter Tool Execute Before Hook for OpenCode
4
- *
5
- * Fires before a tool execution in OpenCode. Delegates to
6
- * `babysitter hook:run --hook-type pre-tool-use` for pre-tool-use awareness.
7
- *
8
- * This hook can be used to:
9
- * - Log tool invocations for babysitter run observability
10
- * - Block certain tool calls during specific orchestration phases
11
- * - Inject babysitter context into tool arguments
12
- *
13
- * OpenCode plugin protocol:
14
- * - Receives tool context as JSON via stdin
15
- * - Outputs JSON to stdout (empty = allow, { block: true } = block)
16
- * - Exit 0 = success
17
- */
18
-
19
- "use strict";
20
-
21
- const { execSync } = require("child_process");
22
- const { readFileSync, mkdirSync, appendFileSync } = require("fs");
23
- const os = require("os");
24
- const path = require("path");
25
-
26
- const PLUGIN_ROOT = process.env.OPENCODE_PLUGIN_ROOT || path.resolve(__dirname, "..");
27
- const STATE_DIR = process.env.BABYSITTER_STATE_DIR || path.join(process.cwd(), ".a5c");
28
- const LOG_DIR = process.env.BABYSITTER_LOG_DIR || path.join(os.homedir(), ".a5c", "logs");
29
- const LOG_FILE = path.join(LOG_DIR, "babysitter-tool-before-hook.log");
30
-
31
- function ensureDir(dir) {
32
- try { mkdirSync(dir, { recursive: true }); } catch { /* best-effort */ }
33
- }
34
-
35
- function blog(msg) {
36
- ensureDir(LOG_DIR);
37
- const ts = new Date().toISOString();
38
- try {
39
- appendFileSync(LOG_FILE, `[INFO] ${ts} ${msg}\n`);
40
- } catch { /* best-effort */ }
41
- }
42
-
43
- function getSdkVersion() {
44
- try {
45
- const versions = JSON.parse(readFileSync(path.join(PLUGIN_ROOT, "versions.json"), "utf8"));
46
- return versions.sdkVersion || "latest";
47
- } catch {
48
- return "latest";
49
- }
50
- }
51
-
52
- function main() {
53
- const sessionId = process.env.BABYSITTER_SESSION_ID
54
- || process.env.OPENCODE_SESSION_ID
55
- || "";
56
-
57
- if (!sessionId) {
58
- // No session -- pass through without intervention
59
- process.stdout.write("{}\n");
60
- return;
61
- }
62
-
63
- // Read stdin for tool context
64
- let inputData = "";
65
- try {
66
- inputData = require("fs").readFileSync(0, "utf8");
67
- } catch {
68
- // No stdin available
69
- }
70
-
71
- blog(`tool-execute-before: session=${sessionId}`);
72
-
73
- const hookInput = JSON.stringify({
74
- session_id: sessionId,
75
- cwd: process.cwd(),
76
- harness: "opencode",
77
- plugin_root: PLUGIN_ROOT,
78
- tool_context: inputData ? JSON.parse(inputData) : {},
79
- });
80
-
81
- const sdkVersion = getSdkVersion();
82
- const args = [
83
- "hook:run",
84
- "--hook-type", "pre-tool-use",
85
- "--harness", "opencode",
86
- "--plugin-root", PLUGIN_ROOT,
87
- "--state-dir", STATE_DIR,
88
- "--json",
89
- ];
90
-
91
- try {
92
- const result = execSync(`babysitter ${args.join(" ")}`, {
93
- input: hookInput,
94
- stdio: ["pipe", "pipe", "pipe"],
95
- timeout: 10000,
96
- env: { ...process.env, BABYSITTER_STATE_DIR: STATE_DIR },
97
- });
98
- const output = result.toString("utf8").trim();
99
- blog(`Hook result: ${output}`);
100
- process.stdout.write((output || "{}") + "\n");
101
- } catch {
102
- // On failure, allow the tool execution to proceed
103
- blog("Pre-tool-use hook failed -- allowing execution");
104
- process.stdout.write("{}\n");
105
- }
106
- }
107
-
108
- main();