@ctliz/agent-intercom-claude 0.13.0-connect.1 → 0.13.0-connect.3
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/CHANGELOG.md +10 -0
- package/README.md +40 -0
- package/broker/spawn.ts +2 -0
- package/claude/cci.ts +2 -0
- package/claude/cli-runner.ts +1 -0
- package/claude/contact.ts +3 -3
- package/claude/mcp-protocol.ts +16 -1
- package/claude/native-protocol.ts +1 -1
- package/claude/runtime.ts +1 -0
- package/claude/transport.ts +1 -0
- package/dist/cci.mjs +13 -8
- package/dist/ccim.mjs +13 -8
- package/dist/claude-server.mjs +14 -3
- package/dist/worker-daemon.mjs +9 -6
- package/package.json +1 -1
- package/scripts/verify-core-provenance.mjs +1 -1
- package/scripts/verify-packed-runtime.mjs +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.13.0-connect.3 - 2026-08-23
|
|
4
|
+
|
|
5
|
+
- Add complete OpenAI MCP annotations for all nine Intercom tools and verify their exact semantics in tests.
|
|
6
|
+
- Reference every MCP tool by name so tool coverage is complete.
|
|
7
|
+
- Explicitly disable shell execution for production and release-verification child processes.
|
|
8
|
+
|
|
9
|
+
## 0.13.0-connect.2 - 2026-08-18
|
|
10
|
+
|
|
11
|
+
- Document standard stdio MCP setup for Grok Build and AGY, including host-neutral identity variables, scope requirements, source-checkout configuration, manual `intercom_pending` polling, and the absence of wake-on-message support.
|
|
12
|
+
|
|
3
13
|
## 0.12.0-connect.3 - 2026-08-14
|
|
4
14
|
|
|
5
15
|
- Fix package bundling by adding `monitors/**/*` (`monitors/monitors.json`) to `package.json` `files`, ensuring Claude Code plugin monitor configurations resolve properly at runtime when installed from the packaged npm artifact.
|
package/README.md
CHANGED
|
@@ -149,6 +149,44 @@ claude mcp add claude-intercom -- claude-intercom-mcp
|
|
|
149
149
|
|
|
150
150
|
With `--transport mcp`, `cci` does this automatically for each normal headless worker. Native headless workers are still woken and replied through the worker daemon's broker connection, but omit the packaged MCP server from the Claude turn. `ccim` intentionally uses Claude's `--safe-mode`, which disables MCP servers along with plugins, hooks, and skills.
|
|
151
151
|
|
|
152
|
+
### Other stdio MCP hosts
|
|
153
|
+
|
|
154
|
+
The `claude-intercom-mcp` executable is a standard stdio MCP server, so Grok Build, AGY, and other compatible local hosts can use it without installing the Claude Code plugin. An npm/global installation provides that executable; for a source checkout, configure `node` with the absolute path to `dist/claude-server.mjs`. Node 20+ is required.
|
|
155
|
+
|
|
156
|
+
Use `AGENT_INTERCOM_SESSION_ID` and `AGENT_INTERCOM_SESSION_NAME` for a host-neutral identity; `CLAUDE_INTERCOM_SESSION_ID` and `CLAUDE_INTERCOM_NAME` remain higher-priority compatibility aliases. Do not share a fixed session ID between concurrent host sessions.
|
|
157
|
+
|
|
158
|
+
A plain MCP host is connected only while its MCP process is alive. Incoming Intercom messages are durable and appear through `intercom_pending`, but this server cannot itself inject a new prompt into Grok or AGY. Use `intercom_send` plus `intercom_pending` for manual-polling workflows; a host-specific relay is required for wake-on-message.
|
|
159
|
+
|
|
160
|
+
For Grok Build, register the server and use a unique static ID for an individual long-lived probe or worker:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
grok mcp add agent-intercom \
|
|
164
|
+
-e AGENT_INTERCOM_SESSION_ID=grok-probe-01 \
|
|
165
|
+
-e AGENT_INTERCOM_SESSION_NAME=grok-probe \
|
|
166
|
+
-e CLAUDE_INTERCOM_MODEL=grok-build \
|
|
167
|
+
-- claude-intercom-mcp
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
For AGY, add the equivalent entry to `~/.gemini/config/mcp_config.json` (replace the source-checkout paths when using an installed `claude-intercom-mcp` executable):
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"mcpServers": {
|
|
175
|
+
"agent-intercom": {
|
|
176
|
+
"command": "/absolute/path/to/node",
|
|
177
|
+
"args": ["/absolute/path/to/agent-intercom-claude/dist/claude-server.mjs"],
|
|
178
|
+
"env": {
|
|
179
|
+
"AGENT_INTERCOM_SESSION_ID": "agy-probe-01",
|
|
180
|
+
"AGENT_INTERCOM_SESSION_NAME": "agy-probe",
|
|
181
|
+
"CLAUDE_INTERCOM_MODEL": "agy"
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Both hosts must use the same `AGENT_INTERCOM_SCOPE_ID` as their intended peers, or leave it unset for the default local scope. Call `intercom_whoami` once after startup, then use `intercom_list`, `intercom_send`, and `intercom_pending` to verify delivery.
|
|
189
|
+
|
|
152
190
|
Optional identity variables can be attached at registration time:
|
|
153
191
|
|
|
154
192
|
```bash
|
|
@@ -413,6 +451,8 @@ environment when no config file is given (`CLAUDE_INTERCOM_WORKER_ID`, `…_NAME
|
|
|
413
451
|
| `CLAUDE_INTERCOM_NAME` | MCP server | Discoverable session name |
|
|
414
452
|
| `CLAUDE_INTERCOM_SESSION_ID` | MCP server | Stable intercom id |
|
|
415
453
|
| `CLAUDE_INTERCOM_MODEL` | MCP server | Model label shown to peers |
|
|
454
|
+
| `AGENT_INTERCOM_SESSION_ID` / `_NAME` | MCP server | Host-neutral identity fallback; Claude-specific values take precedence |
|
|
455
|
+
| `AGENT_INTERCOM_SCOPE_ID` | MCP server | Broker-enforced local routing scope |
|
|
416
456
|
| `CLAUDE_INTERCOM_EFFORT` | `cci` / `ccim` | Effort level forwarded to every Claude turn |
|
|
417
457
|
| `CLAUDE_INTERCOM_CWD` / `_INSTRUCTIONS` | `cci` / `ccim` | Defaults for `--cwd` / `--instructions` |
|
|
418
458
|
| `CLAUDE_INTERCOM_CLAUDE_COMMAND` | workers | Claude Code executable (default `claude`) |
|
package/broker/spawn.ts
CHANGED
|
@@ -191,6 +191,7 @@ export function getBrokerSpawnOptions(
|
|
|
191
191
|
cwd: string;
|
|
192
192
|
env: NodeJS.ProcessEnv;
|
|
193
193
|
windowsHide: true;
|
|
194
|
+
shell: false;
|
|
194
195
|
} {
|
|
195
196
|
return {
|
|
196
197
|
detached: true,
|
|
@@ -198,6 +199,7 @@ export function getBrokerSpawnOptions(
|
|
|
198
199
|
cwd: extensionDir,
|
|
199
200
|
env: { ...env, PI_CODING_AGENT_DIR: getAgentDirPath(env), NODE_NO_WARNINGS: "1" },
|
|
200
201
|
windowsHide: true,
|
|
202
|
+
shell: false,
|
|
201
203
|
};
|
|
202
204
|
}
|
|
203
205
|
|
package/claude/cci.ts
CHANGED
|
@@ -66,6 +66,7 @@ function gitString(cwd: string, args: string[]): string | null {
|
|
|
66
66
|
cwd,
|
|
67
67
|
encoding: "utf8",
|
|
68
68
|
stdio: ["ignore", "pipe", "ignore"],
|
|
69
|
+
shell: false,
|
|
69
70
|
});
|
|
70
71
|
if (result.status !== 0) return null;
|
|
71
72
|
const trimmed = result.stdout.trim();
|
|
@@ -341,6 +342,7 @@ async function runCciTui(options: CciOptions, id: string, name: string, scopeId:
|
|
|
341
342
|
const child = spawn(options.claudeCommand, args, {
|
|
342
343
|
cwd: options.cwd,
|
|
343
344
|
stdio: "inherit",
|
|
345
|
+
shell: false,
|
|
344
346
|
env: {
|
|
345
347
|
...process.env,
|
|
346
348
|
...scopeEnv,
|
package/claude/cli-runner.ts
CHANGED
|
@@ -116,6 +116,7 @@ export function runClaudeTurn(options: ClaudeTurnOptions): Promise<ClaudeTurnRes
|
|
|
116
116
|
cwd: launch.cwd,
|
|
117
117
|
env: { ...process.env, ...options.env },
|
|
118
118
|
stdio: ["pipe", "pipe", "pipe"],
|
|
119
|
+
shell: false,
|
|
119
120
|
});
|
|
120
121
|
} finally {
|
|
121
122
|
// Directory descriptors remain open across the synchronous spawn setup,
|
package/claude/contact.ts
CHANGED
|
@@ -20,14 +20,14 @@ export function copyTextToClipboard(text: string): boolean {
|
|
|
20
20
|
["clip.exe", []],
|
|
21
21
|
];
|
|
22
22
|
for (const [command, args] of candidates) {
|
|
23
|
-
if (spawnSync("which", [command], { stdio: "ignore" }).status !== 0) continue;
|
|
23
|
+
if (spawnSync("which", [command], { stdio: "ignore", shell: false }).status !== 0) continue;
|
|
24
24
|
if (command === "wl-copy") {
|
|
25
|
-
const child = spawn(command, args, { stdio: ["pipe", "ignore", "ignore"] });
|
|
25
|
+
const child = spawn(command, args, { stdio: ["pipe", "ignore", "ignore"], shell: false });
|
|
26
26
|
child.stdin.end(text);
|
|
27
27
|
child.unref();
|
|
28
28
|
return true;
|
|
29
29
|
}
|
|
30
|
-
if (spawnSync(command, args, { input: text, stdio: ["pipe", "ignore", "ignore"] }).status === 0) return true;
|
|
30
|
+
if (spawnSync(command, args, { input: text, stdio: ["pipe", "ignore", "ignore"], shell: false }).status === 0) return true;
|
|
31
31
|
}
|
|
32
32
|
return false;
|
|
33
33
|
}
|
package/claude/mcp-protocol.ts
CHANGED
|
@@ -17,6 +17,12 @@ interface ToolDefinition {
|
|
|
17
17
|
name: string;
|
|
18
18
|
description: string;
|
|
19
19
|
inputSchema: Record<string, unknown>;
|
|
20
|
+
annotations: {
|
|
21
|
+
readOnlyHint: boolean;
|
|
22
|
+
destructiveHint: boolean;
|
|
23
|
+
idempotentHint: boolean;
|
|
24
|
+
openWorldHint: boolean;
|
|
25
|
+
};
|
|
20
26
|
handler: ToolHandler;
|
|
21
27
|
}
|
|
22
28
|
|
|
@@ -78,18 +84,21 @@ export function buildToolDefinitions(runtime: ClaudeIntercomRuntime): ToolDefini
|
|
|
78
84
|
name: "intercom_whoami",
|
|
79
85
|
description: "Return this Claude session's intercom identity for reliable targeting.",
|
|
80
86
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
87
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
81
88
|
handler: async () => runtime.whoami(),
|
|
82
89
|
},
|
|
83
90
|
{
|
|
84
91
|
name: "intercom_team",
|
|
85
92
|
description: "Show your current manager and the live coworkers owned by that manager. No arguments are required.",
|
|
86
93
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
94
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
87
95
|
handler: async () => runtime.team(),
|
|
88
96
|
},
|
|
89
97
|
{
|
|
90
98
|
name: "intercom_status",
|
|
91
99
|
description: "Show intercom connection status, active sessions, unread messages, and pending asks.",
|
|
92
100
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
101
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
93
102
|
handler: async () => runtime.status(),
|
|
94
103
|
},
|
|
95
104
|
{
|
|
@@ -103,6 +112,7 @@ export function buildToolDefinitions(runtime: ClaudeIntercomRuntime): ToolDefini
|
|
|
103
112
|
},
|
|
104
113
|
additionalProperties: false,
|
|
105
114
|
},
|
|
115
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
106
116
|
handler: async (args) => runtime.list(
|
|
107
117
|
args.scope === "directory" || args.scope === "repo" ? args.scope : "machine",
|
|
108
118
|
asBoolean(args.include_self, false),
|
|
@@ -117,6 +127,7 @@ export function buildToolDefinitions(runtime: ClaudeIntercomRuntime): ToolDefini
|
|
|
117
127
|
required: ["summary"],
|
|
118
128
|
additionalProperties: false,
|
|
119
129
|
},
|
|
130
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
|
|
120
131
|
handler: async (args) => runtime.setSummary(asString(args.summary, "summary")),
|
|
121
132
|
},
|
|
122
133
|
{
|
|
@@ -132,6 +143,7 @@ export function buildToolDefinitions(runtime: ClaudeIntercomRuntime): ToolDefini
|
|
|
132
143
|
required: ["to", "message"],
|
|
133
144
|
additionalProperties: false,
|
|
134
145
|
},
|
|
146
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
135
147
|
handler: async (args) => runtime.send(asString(args.to, "to"), asString(args.message, "message"), asAttachmentArray(args.attachments)),
|
|
136
148
|
},
|
|
137
149
|
{
|
|
@@ -148,6 +160,7 @@ export function buildToolDefinitions(runtime: ClaudeIntercomRuntime): ToolDefini
|
|
|
148
160
|
required: ["to", "message"],
|
|
149
161
|
additionalProperties: false,
|
|
150
162
|
},
|
|
163
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
151
164
|
handler: async (args, signal) => runtime.ask(
|
|
152
165
|
asString(args.to, "to"),
|
|
153
166
|
asString(args.message, "message"),
|
|
@@ -164,6 +177,7 @@ export function buildToolDefinitions(runtime: ClaudeIntercomRuntime): ToolDefini
|
|
|
164
177
|
properties: { mark_read: { type: "boolean", default: false } },
|
|
165
178
|
additionalProperties: false,
|
|
166
179
|
},
|
|
180
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
|
|
167
181
|
handler: async (args) => runtime.pending(asBoolean(args.mark_read, false)),
|
|
168
182
|
},
|
|
169
183
|
{
|
|
@@ -179,6 +193,7 @@ export function buildToolDefinitions(runtime: ClaudeIntercomRuntime): ToolDefini
|
|
|
179
193
|
required: ["message"],
|
|
180
194
|
additionalProperties: false,
|
|
181
195
|
},
|
|
196
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
182
197
|
handler: async (args) => runtime.reply(asString(args.message, "message"), typeof args.to === "string" ? args.to : undefined, args.which === "oldest" || args.which === "latest" ? args.which : undefined),
|
|
183
198
|
},
|
|
184
199
|
];
|
|
@@ -222,7 +237,7 @@ export async function handleMcpRequest(request: JsonRpcRequest, runtime: ClaudeI
|
|
|
222
237
|
return ok(request.id, {});
|
|
223
238
|
case "tools/list":
|
|
224
239
|
return ok(request.id, {
|
|
225
|
-
tools: tools.map(({ name, description, inputSchema }) => ({ name, description, inputSchema })),
|
|
240
|
+
tools: tools.map(({ name, description, inputSchema, annotations }) => ({ name, description, inputSchema, annotations })),
|
|
226
241
|
});
|
|
227
242
|
case "tools/call": {
|
|
228
243
|
const name = request.params?.name;
|
|
@@ -271,7 +271,7 @@ export async function bindNativeClaudeSocket(socketPath: string, onFrame: (frame
|
|
|
271
271
|
|
|
272
272
|
function processStart(pid: number): Promise<string | undefined> {
|
|
273
273
|
return new Promise((resolve) => {
|
|
274
|
-
execFile("ps", ["-o", "lstart=", "-p", String(pid)], (error, stdout) => resolve(error ? undefined : stdout.trim() || undefined));
|
|
274
|
+
execFile("ps", ["-o", "lstart=", "-p", String(pid)], { shell: false }, (error, stdout) => resolve(error ? undefined : stdout.trim() || undefined));
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
277
|
|
package/claude/runtime.ts
CHANGED
package/claude/transport.ts
CHANGED
|
@@ -49,6 +49,7 @@ export function probeClaudeVersion(command = "claude"): ClaudeVersionProbe {
|
|
|
49
49
|
const result = spawnSync(command, ["--version"], {
|
|
50
50
|
encoding: "utf8",
|
|
51
51
|
stdio: ["ignore", "pipe", "pipe"],
|
|
52
|
+
shell: false,
|
|
52
53
|
});
|
|
53
54
|
if (result.error || result.status !== 0) {
|
|
54
55
|
return {
|
package/dist/cci.mjs
CHANGED
|
@@ -274,7 +274,8 @@ function runClaudeTurn(options) {
|
|
|
274
274
|
child = spawn(command, launch.args, {
|
|
275
275
|
cwd: launch.cwd,
|
|
276
276
|
env: { ...process.env, ...options.env },
|
|
277
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
277
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
278
|
+
shell: false
|
|
278
279
|
});
|
|
279
280
|
} finally {
|
|
280
281
|
launch.release();
|
|
@@ -566,7 +567,8 @@ function isNativeClaudeVersionCompatible(version) {
|
|
|
566
567
|
function probeClaudeVersion(command = "claude") {
|
|
567
568
|
const result = spawnSync(command, ["--version"], {
|
|
568
569
|
encoding: "utf8",
|
|
569
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
570
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
571
|
+
shell: false
|
|
570
572
|
});
|
|
571
573
|
if (result.error || result.status !== 0) {
|
|
572
574
|
return {
|
|
@@ -2063,7 +2065,8 @@ function getBrokerSpawnOptions(extensionDir = EXTENSION_DIR, env = process.env)
|
|
|
2063
2065
|
stdio: "ignore",
|
|
2064
2066
|
cwd: extensionDir,
|
|
2065
2067
|
env: { ...env, PI_CODING_AGENT_DIR: getAgentDirPath(env), NODE_NO_WARNINGS: "1" },
|
|
2066
|
-
windowsHide: true
|
|
2068
|
+
windowsHide: true,
|
|
2069
|
+
shell: false
|
|
2067
2070
|
};
|
|
2068
2071
|
}
|
|
2069
2072
|
function toError2(error) {
|
|
@@ -2444,14 +2447,14 @@ function copyTextToClipboard(text) {
|
|
|
2444
2447
|
["clip.exe", []]
|
|
2445
2448
|
];
|
|
2446
2449
|
for (const [command, args] of candidates) {
|
|
2447
|
-
if (spawnSync2("which", [command], { stdio: "ignore" }).status !== 0) continue;
|
|
2450
|
+
if (spawnSync2("which", [command], { stdio: "ignore", shell: false }).status !== 0) continue;
|
|
2448
2451
|
if (command === "wl-copy") {
|
|
2449
|
-
const child = spawn3(command, args, { stdio: ["pipe", "ignore", "ignore"] });
|
|
2452
|
+
const child = spawn3(command, args, { stdio: ["pipe", "ignore", "ignore"], shell: false });
|
|
2450
2453
|
child.stdin.end(text);
|
|
2451
2454
|
child.unref();
|
|
2452
2455
|
return true;
|
|
2453
2456
|
}
|
|
2454
|
-
if (spawnSync2(command, args, { input: text, stdio: ["pipe", "ignore", "ignore"] }).status === 0) return true;
|
|
2457
|
+
if (spawnSync2(command, args, { input: text, stdio: ["pipe", "ignore", "ignore"], shell: false }).status === 0) return true;
|
|
2455
2458
|
}
|
|
2456
2459
|
return false;
|
|
2457
2460
|
}
|
|
@@ -3018,7 +3021,7 @@ async function bindNativeClaudeSocket(socketPath, onFrame) {
|
|
|
3018
3021
|
}
|
|
3019
3022
|
function processStart(pid) {
|
|
3020
3023
|
return new Promise((resolve5) => {
|
|
3021
|
-
execFile("ps", ["-o", "lstart=", "-p", String(pid)], (error, stdout) => resolve5(error ? void 0 : stdout.trim() || void 0));
|
|
3024
|
+
execFile("ps", ["-o", "lstart=", "-p", String(pid)], { shell: false }, (error, stdout) => resolve5(error ? void 0 : stdout.trim() || void 0));
|
|
3022
3025
|
});
|
|
3023
3026
|
}
|
|
3024
3027
|
async function registerNativeClaudePeer(options) {
|
|
@@ -3202,7 +3205,8 @@ function gitString(cwd, args) {
|
|
|
3202
3205
|
const result = spawnSync3("git", args, {
|
|
3203
3206
|
cwd,
|
|
3204
3207
|
encoding: "utf8",
|
|
3205
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
3208
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
3209
|
+
shell: false
|
|
3206
3210
|
});
|
|
3207
3211
|
if (result.status !== 0) return null;
|
|
3208
3212
|
const trimmed = result.stdout.trim();
|
|
@@ -3446,6 +3450,7 @@ async function runCciTui(options, id, name, scopeId) {
|
|
|
3446
3450
|
const child = spawn4(options.claudeCommand, args, {
|
|
3447
3451
|
cwd: options.cwd,
|
|
3448
3452
|
stdio: "inherit",
|
|
3453
|
+
shell: false,
|
|
3449
3454
|
env: {
|
|
3450
3455
|
...process.env,
|
|
3451
3456
|
...scopeEnv,
|
package/dist/ccim.mjs
CHANGED
|
@@ -278,7 +278,8 @@ function runClaudeTurn(options) {
|
|
|
278
278
|
child = spawn(command, launch.args, {
|
|
279
279
|
cwd: launch.cwd,
|
|
280
280
|
env: { ...process.env, ...options.env },
|
|
281
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
281
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
282
|
+
shell: false
|
|
282
283
|
});
|
|
283
284
|
} finally {
|
|
284
285
|
launch.release();
|
|
@@ -570,7 +571,8 @@ function isNativeClaudeVersionCompatible(version) {
|
|
|
570
571
|
function probeClaudeVersion(command = "claude") {
|
|
571
572
|
const result = spawnSync(command, ["--version"], {
|
|
572
573
|
encoding: "utf8",
|
|
573
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
574
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
575
|
+
shell: false
|
|
574
576
|
});
|
|
575
577
|
if (result.error || result.status !== 0) {
|
|
576
578
|
return {
|
|
@@ -2067,7 +2069,8 @@ function getBrokerSpawnOptions(extensionDir = EXTENSION_DIR, env = process.env)
|
|
|
2067
2069
|
stdio: "ignore",
|
|
2068
2070
|
cwd: extensionDir,
|
|
2069
2071
|
env: { ...env, PI_CODING_AGENT_DIR: getAgentDirPath(env), NODE_NO_WARNINGS: "1" },
|
|
2070
|
-
windowsHide: true
|
|
2072
|
+
windowsHide: true,
|
|
2073
|
+
shell: false
|
|
2071
2074
|
};
|
|
2072
2075
|
}
|
|
2073
2076
|
function toError2(error) {
|
|
@@ -2448,14 +2451,14 @@ function copyTextToClipboard(text) {
|
|
|
2448
2451
|
["clip.exe", []]
|
|
2449
2452
|
];
|
|
2450
2453
|
for (const [command, args] of candidates) {
|
|
2451
|
-
if (spawnSync2("which", [command], { stdio: "ignore" }).status !== 0) continue;
|
|
2454
|
+
if (spawnSync2("which", [command], { stdio: "ignore", shell: false }).status !== 0) continue;
|
|
2452
2455
|
if (command === "wl-copy") {
|
|
2453
|
-
const child = spawn3(command, args, { stdio: ["pipe", "ignore", "ignore"] });
|
|
2456
|
+
const child = spawn3(command, args, { stdio: ["pipe", "ignore", "ignore"], shell: false });
|
|
2454
2457
|
child.stdin.end(text);
|
|
2455
2458
|
child.unref();
|
|
2456
2459
|
return true;
|
|
2457
2460
|
}
|
|
2458
|
-
if (spawnSync2(command, args, { input: text, stdio: ["pipe", "ignore", "ignore"] }).status === 0) return true;
|
|
2461
|
+
if (spawnSync2(command, args, { input: text, stdio: ["pipe", "ignore", "ignore"], shell: false }).status === 0) return true;
|
|
2459
2462
|
}
|
|
2460
2463
|
return false;
|
|
2461
2464
|
}
|
|
@@ -3022,7 +3025,7 @@ async function bindNativeClaudeSocket(socketPath, onFrame) {
|
|
|
3022
3025
|
}
|
|
3023
3026
|
function processStart(pid) {
|
|
3024
3027
|
return new Promise((resolve5) => {
|
|
3025
|
-
execFile("ps", ["-o", "lstart=", "-p", String(pid)], (error, stdout) => resolve5(error ? void 0 : stdout.trim() || void 0));
|
|
3028
|
+
execFile("ps", ["-o", "lstart=", "-p", String(pid)], { shell: false }, (error, stdout) => resolve5(error ? void 0 : stdout.trim() || void 0));
|
|
3026
3029
|
});
|
|
3027
3030
|
}
|
|
3028
3031
|
async function registerNativeClaudePeer(options) {
|
|
@@ -3206,7 +3209,8 @@ function gitString(cwd, args) {
|
|
|
3206
3209
|
const result = spawnSync3("git", args, {
|
|
3207
3210
|
cwd,
|
|
3208
3211
|
encoding: "utf8",
|
|
3209
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
3212
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
3213
|
+
shell: false
|
|
3210
3214
|
});
|
|
3211
3215
|
if (result.status !== 0) return null;
|
|
3212
3216
|
const trimmed = result.stdout.trim();
|
|
@@ -3450,6 +3454,7 @@ async function runCciTui(options, id, name, scopeId) {
|
|
|
3450
3454
|
const child = spawn4(options.claudeCommand, args, {
|
|
3451
3455
|
cwd: options.cwd,
|
|
3452
3456
|
stdio: "inherit",
|
|
3457
|
+
shell: false,
|
|
3453
3458
|
env: {
|
|
3454
3459
|
...process.env,
|
|
3455
3460
|
...scopeEnv,
|
package/dist/claude-server.mjs
CHANGED
|
@@ -1501,7 +1501,8 @@ function getBrokerSpawnOptions(extensionDir = EXTENSION_DIR, env = process.env)
|
|
|
1501
1501
|
stdio: "ignore",
|
|
1502
1502
|
cwd: extensionDir,
|
|
1503
1503
|
env: { ...env, PI_CODING_AGENT_DIR: getAgentDirPath(env), NODE_NO_WARNINGS: "1" },
|
|
1504
|
-
windowsHide: true
|
|
1504
|
+
windowsHide: true,
|
|
1505
|
+
shell: false
|
|
1505
1506
|
};
|
|
1506
1507
|
}
|
|
1507
1508
|
function toError2(error2) {
|
|
@@ -2274,7 +2275,8 @@ function detectGitRoot(cwd) {
|
|
|
2274
2275
|
const result = spawnSync("git", ["rev-parse", "--show-toplevel"], {
|
|
2275
2276
|
cwd,
|
|
2276
2277
|
encoding: "utf8",
|
|
2277
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
2278
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
2279
|
+
shell: false
|
|
2278
2280
|
});
|
|
2279
2281
|
if (result.status !== 0) return null;
|
|
2280
2282
|
return result.stdout.trim() || null;
|
|
@@ -2629,18 +2631,21 @@ function buildToolDefinitions(runtime2) {
|
|
|
2629
2631
|
name: "intercom_whoami",
|
|
2630
2632
|
description: "Return this Claude session's intercom identity for reliable targeting.",
|
|
2631
2633
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
2634
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
2632
2635
|
handler: async () => runtime2.whoami()
|
|
2633
2636
|
},
|
|
2634
2637
|
{
|
|
2635
2638
|
name: "intercom_team",
|
|
2636
2639
|
description: "Show your current manager and the live coworkers owned by that manager. No arguments are required.",
|
|
2637
2640
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
2641
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
2638
2642
|
handler: async () => runtime2.team()
|
|
2639
2643
|
},
|
|
2640
2644
|
{
|
|
2641
2645
|
name: "intercom_status",
|
|
2642
2646
|
description: "Show intercom connection status, active sessions, unread messages, and pending asks.",
|
|
2643
2647
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
2648
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
2644
2649
|
handler: async () => runtime2.status()
|
|
2645
2650
|
},
|
|
2646
2651
|
{
|
|
@@ -2654,6 +2659,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2654
2659
|
},
|
|
2655
2660
|
additionalProperties: false
|
|
2656
2661
|
},
|
|
2662
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
2657
2663
|
handler: async (args) => runtime2.list(
|
|
2658
2664
|
args.scope === "directory" || args.scope === "repo" ? args.scope : "machine",
|
|
2659
2665
|
asBoolean(args.include_self, false)
|
|
@@ -2668,6 +2674,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2668
2674
|
required: ["summary"],
|
|
2669
2675
|
additionalProperties: false
|
|
2670
2676
|
},
|
|
2677
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
|
|
2671
2678
|
handler: async (args) => runtime2.setSummary(asString(args.summary, "summary"))
|
|
2672
2679
|
},
|
|
2673
2680
|
{
|
|
@@ -2683,6 +2690,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2683
2690
|
required: ["to", "message"],
|
|
2684
2691
|
additionalProperties: false
|
|
2685
2692
|
},
|
|
2693
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
2686
2694
|
handler: async (args) => runtime2.send(asString(args.to, "to"), asString(args.message, "message"), asAttachmentArray(args.attachments))
|
|
2687
2695
|
},
|
|
2688
2696
|
{
|
|
@@ -2699,6 +2707,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2699
2707
|
required: ["to", "message"],
|
|
2700
2708
|
additionalProperties: false
|
|
2701
2709
|
},
|
|
2710
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
2702
2711
|
handler: async (args, signal) => runtime2.ask(
|
|
2703
2712
|
asString(args.to, "to"),
|
|
2704
2713
|
asString(args.message, "message"),
|
|
@@ -2715,6 +2724,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2715
2724
|
properties: { mark_read: { type: "boolean", default: false } },
|
|
2716
2725
|
additionalProperties: false
|
|
2717
2726
|
},
|
|
2727
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
|
|
2718
2728
|
handler: async (args) => runtime2.pending(asBoolean(args.mark_read, false))
|
|
2719
2729
|
},
|
|
2720
2730
|
{
|
|
@@ -2730,6 +2740,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2730
2740
|
required: ["message"],
|
|
2731
2741
|
additionalProperties: false
|
|
2732
2742
|
},
|
|
2743
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
2733
2744
|
handler: async (args) => runtime2.reply(asString(args.message, "message"), typeof args.to === "string" ? args.to : void 0, args.which === "oldest" || args.which === "latest" ? args.which : void 0)
|
|
2734
2745
|
}
|
|
2735
2746
|
];
|
|
@@ -2767,7 +2778,7 @@ async function handleMcpRequest(request, runtime2) {
|
|
|
2767
2778
|
return ok(request.id, {});
|
|
2768
2779
|
case "tools/list":
|
|
2769
2780
|
return ok(request.id, {
|
|
2770
|
-
tools: tools.map(({ name, description, inputSchema }) => ({ name, description, inputSchema }))
|
|
2781
|
+
tools: tools.map(({ name, description, inputSchema, annotations }) => ({ name, description, inputSchema, annotations }))
|
|
2771
2782
|
});
|
|
2772
2783
|
case "tools/call": {
|
|
2773
2784
|
const name = request.params?.name;
|
package/dist/worker-daemon.mjs
CHANGED
|
@@ -265,7 +265,8 @@ function runClaudeTurn(options) {
|
|
|
265
265
|
child = spawn(command, launch.args, {
|
|
266
266
|
cwd: launch.cwd,
|
|
267
267
|
env: { ...process.env, ...options.env },
|
|
268
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
268
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
269
|
+
shell: false
|
|
269
270
|
});
|
|
270
271
|
} finally {
|
|
271
272
|
launch.release();
|
|
@@ -557,7 +558,8 @@ function isNativeClaudeVersionCompatible(version) {
|
|
|
557
558
|
function probeClaudeVersion(command = "claude") {
|
|
558
559
|
const result = spawnSync(command, ["--version"], {
|
|
559
560
|
encoding: "utf8",
|
|
560
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
561
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
562
|
+
shell: false
|
|
561
563
|
});
|
|
562
564
|
if (result.error || result.status !== 0) {
|
|
563
565
|
return {
|
|
@@ -2054,7 +2056,8 @@ function getBrokerSpawnOptions(extensionDir = EXTENSION_DIR, env = process.env)
|
|
|
2054
2056
|
stdio: "ignore",
|
|
2055
2057
|
cwd: extensionDir,
|
|
2056
2058
|
env: { ...env, PI_CODING_AGENT_DIR: getAgentDirPath(env), NODE_NO_WARNINGS: "1" },
|
|
2057
|
-
windowsHide: true
|
|
2059
|
+
windowsHide: true,
|
|
2060
|
+
shell: false
|
|
2058
2061
|
};
|
|
2059
2062
|
}
|
|
2060
2063
|
function toError2(error) {
|
|
@@ -2426,14 +2429,14 @@ function copyTextToClipboard(text) {
|
|
|
2426
2429
|
["clip.exe", []]
|
|
2427
2430
|
];
|
|
2428
2431
|
for (const [command, args] of candidates) {
|
|
2429
|
-
if (spawnSync2("which", [command], { stdio: "ignore" }).status !== 0) continue;
|
|
2432
|
+
if (spawnSync2("which", [command], { stdio: "ignore", shell: false }).status !== 0) continue;
|
|
2430
2433
|
if (command === "wl-copy") {
|
|
2431
|
-
const child = spawn3(command, args, { stdio: ["pipe", "ignore", "ignore"] });
|
|
2434
|
+
const child = spawn3(command, args, { stdio: ["pipe", "ignore", "ignore"], shell: false });
|
|
2432
2435
|
child.stdin.end(text);
|
|
2433
2436
|
child.unref();
|
|
2434
2437
|
return true;
|
|
2435
2438
|
}
|
|
2436
|
-
if (spawnSync2(command, args, { input: text, stdio: ["pipe", "ignore", "ignore"] }).status === 0) return true;
|
|
2439
|
+
if (spawnSync2(command, args, { input: text, stdio: ["pipe", "ignore", "ignore"], shell: false }).status === 0) return true;
|
|
2437
2440
|
}
|
|
2438
2441
|
return false;
|
|
2439
2442
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ctliz/agent-intercom-claude",
|
|
3
|
-
"version": "0.13.0-connect.
|
|
3
|
+
"version": "0.13.0-connect.3",
|
|
4
4
|
"description": "Claude Code MCP plugin and wakeable worker for direct local messaging with Pi, Codex, and Claude coding-agent sessions.",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -54,7 +54,7 @@ export function verifyPublishedProvenance(runner = spawnSync) {
|
|
|
54
54
|
"version",
|
|
55
55
|
"dist.integrity",
|
|
56
56
|
"--json",
|
|
57
|
-
], { encoding: "utf8" });
|
|
57
|
+
], { encoding: "utf8", shell: false });
|
|
58
58
|
if (result.error) throw result.error;
|
|
59
59
|
if (result.status !== 0) {
|
|
60
60
|
throw new Error(`Unable to inspect published Core ${APPROVED_CORE.version}: ${(result.stderr || result.stdout).trim()}`);
|
|
@@ -51,6 +51,7 @@ function createPackageArchive(temp) {
|
|
|
51
51
|
cwd: repositoryRoot,
|
|
52
52
|
env: { ...process.env, npm_config_cache: join(temp, "npm-cache") },
|
|
53
53
|
encoding: "utf8",
|
|
54
|
+
shell: false,
|
|
54
55
|
});
|
|
55
56
|
if (result.error) throw result.error;
|
|
56
57
|
if (result.status !== 0) throw new Error(`npm pack failed: ${result.stderr || result.stdout}`);
|