@parall/claude-agent 1.16.0 → 1.17.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/dist/dispatch.d.ts.map +1 -1
- package/dist/dispatch.js +5 -75
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +15 -14
- package/package.json +4 -4
- package/src/dispatch.ts +5 -68
- package/src/workspace.ts +15 -14
package/dist/dispatch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,YAAY,EACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,KAAK,wBAAwB,GAAG,IAAI,CAClC,iBAAiB,EACf,gBAAgB,GAChB,cAAc,GACd,oBAAoB,GACpB,WAAW,GACX,YAAY,GACZ,iBAAiB,GACjB,OAAO,GACP,gBAAgB,GAChB,cAAc,CACjB,GAAG;IACF,cAAc,EAAE,oBAAoB,CAAC;CACtC,CAAC;
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,YAAY,EACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,KAAK,wBAAwB,GAAG,IAAI,CAClC,iBAAiB,EACf,gBAAgB,GAChB,cAAc,GACd,oBAAoB,GACpB,WAAW,GACX,YAAY,GACZ,iBAAiB,GACjB,OAAO,GACP,gBAAgB,GAChB,cAAc,CACjB,GAAG;IACF,cAAc,EAAE,oBAAoB,CAAC;CACtC,CAAC;AAEF,qBAAa,iBAAkB,YAAW,eAAe;IAC3C,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,wBAAwB;IAEpD,QAAQ,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC;IAwFjG,WAAW,CAAC,EAAE,UAAU,EAAE,EAAE,QAAQ;IAIpC,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe;IAIrC,OAAO,CAAC,SAAS;CAkClB"}
|
package/dist/dispatch.js
CHANGED
|
@@ -1,60 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
3
|
import { parseClaudeStreamJson } from "./output-parser.js";
|
|
4
|
-
function extractBashCommand(input) {
|
|
5
|
-
if (!input || typeof input !== "object")
|
|
6
|
-
return undefined;
|
|
7
|
-
const command = input.command;
|
|
8
|
-
return typeof command === "string" && command.trim() ? command.trim() : undefined;
|
|
9
|
-
}
|
|
10
|
-
// Returns the non-flag tokens that follow a Parall CLI invocation in `command`,
|
|
11
|
-
// or null if the command isn't a Parall CLI call. Handles all the documented
|
|
12
|
-
// forms — bare `parall`, `npx [--yes|-y] @parall/cli[@version]`,
|
|
13
|
-
// `pnpm (exec|dlx) parall` — and skips `npx` flags so that `npx --yes`
|
|
14
|
-
// matches as well as `npx -y`. Tokenization avoids the regex false-match
|
|
15
|
-
// where `messages send --no-reply` looked like the receiver-side `no-reply`.
|
|
16
|
-
function parseParallCliInvocation(command) {
|
|
17
|
-
const tokens = command.replace(/\s+/g, " ").trim().split(" ");
|
|
18
|
-
let i = 0;
|
|
19
|
-
if (tokens[i] === "parall") {
|
|
20
|
-
i++;
|
|
21
|
-
}
|
|
22
|
-
else if (tokens[i] === "npx") {
|
|
23
|
-
i++;
|
|
24
|
-
while (i < tokens.length && tokens[i].startsWith("-"))
|
|
25
|
-
i++;
|
|
26
|
-
if (i >= tokens.length || !/^@parall\/cli(?:@.+)?$/.test(tokens[i]))
|
|
27
|
-
return null;
|
|
28
|
-
i++;
|
|
29
|
-
}
|
|
30
|
-
else if (tokens[i] === "pnpm") {
|
|
31
|
-
i++;
|
|
32
|
-
if (i < tokens.length && (tokens[i] === "exec" || tokens[i] === "dlx"))
|
|
33
|
-
i++;
|
|
34
|
-
if (i >= tokens.length || tokens[i] !== "parall")
|
|
35
|
-
return null;
|
|
36
|
-
i++;
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
return tokens.slice(i).filter((t) => !t.startsWith("-"));
|
|
42
|
-
}
|
|
43
|
-
function isParallSendCommand(command) {
|
|
44
|
-
if (!command)
|
|
45
|
-
return false;
|
|
46
|
-
const sub = parseParallCliInvocation(command);
|
|
47
|
-
if (!sub || sub.length === 0)
|
|
48
|
-
return false;
|
|
49
|
-
// `dm <user>` or `messages send <chat>`
|
|
50
|
-
return sub[0] === "dm" || (sub[0] === "messages" && sub[1] === "send");
|
|
51
|
-
}
|
|
52
|
-
function isParallNoReplyCommand(command) {
|
|
53
|
-
if (!command)
|
|
54
|
-
return false;
|
|
55
|
-
const sub = parseParallCliInvocation(command);
|
|
56
|
-
return sub?.[0] === "no-reply";
|
|
57
|
-
}
|
|
58
4
|
export class ClaudeCodeAdapter {
|
|
59
5
|
opts;
|
|
60
6
|
constructor(opts) {
|
|
@@ -93,11 +39,6 @@ export class ClaudeCodeAdapter {
|
|
|
93
39
|
});
|
|
94
40
|
const groupKey = randomUUID();
|
|
95
41
|
let sawError = false;
|
|
96
|
-
let suppressProjectedText = false;
|
|
97
|
-
// Sticky for the whole dispatch: set when the agent explicitly calls
|
|
98
|
-
// `parall no-reply` to silence the turn. All subsequent text events are
|
|
99
|
-
// emitted with project=false so the bridge never leaks a chat message.
|
|
100
|
-
let noReplyCalled = false;
|
|
101
42
|
let completed = false;
|
|
102
43
|
try {
|
|
103
44
|
for await (const event of parseClaudeStreamJson(proc.stdout)) {
|
|
@@ -105,30 +46,19 @@ export class ClaudeCodeAdapter {
|
|
|
105
46
|
this.opts.sessionManager.recordSessionId(sessionKey, event.sessionId);
|
|
106
47
|
continue;
|
|
107
48
|
}
|
|
108
|
-
if (event.type === "tool_call") {
|
|
109
|
-
const cmd = extractBashCommand(event.input);
|
|
110
|
-
if (isParallNoReplyCommand(cmd)) {
|
|
111
|
-
noReplyCalled = true;
|
|
112
|
-
}
|
|
113
|
-
else if (isParallSendCommand(cmd)) {
|
|
114
|
-
suppressProjectedText = true;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
49
|
if (event.type === "error") {
|
|
118
50
|
sawError = true;
|
|
119
51
|
yield event;
|
|
120
52
|
continue;
|
|
121
53
|
}
|
|
122
54
|
if (event.type === "text") {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
: event.project;
|
|
128
|
-
suppressProjectedText = false;
|
|
55
|
+
// Runtime output contract (symmetric with OpenClaw channel): Claude's
|
|
56
|
+
// plain text is never projected as a chat message. To reply, the agent
|
|
57
|
+
// must explicitly run `parall messages send` / `dm` via Bash. Text
|
|
58
|
+
// events are still recorded as suppressed session steps for audit.
|
|
129
59
|
yield {
|
|
130
60
|
...event,
|
|
131
|
-
project,
|
|
61
|
+
project: false,
|
|
132
62
|
groupKey,
|
|
133
63
|
};
|
|
134
64
|
continue;
|
package/dist/workspace.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAkCA,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,GAAG,CAAC,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,QA0BtC"}
|
package/dist/workspace.js
CHANGED
|
@@ -2,32 +2,33 @@ import * as fs from "node:fs";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
const CLAUDE_MD = `# CLAUDE.md
|
|
4
4
|
|
|
5
|
-
You are an agent in Parall IM. You participate in chats, handle tasks, and
|
|
5
|
+
You are an agent in Parall IM. You participate in chats, handle tasks, and interact exclusively through the Parall CLI.
|
|
6
6
|
|
|
7
7
|
## Message Model
|
|
8
8
|
|
|
9
9
|
Incoming events are rendered as structured \`[Event: ...]\` blocks.
|
|
10
|
-
|
|
10
|
+
Each event includes \`[Chat: ... (prll://cht_xxx)]\` — use that chat ID (or full URI) when replying.
|
|
11
|
+
|
|
12
|
+
**Your plain-text output is not delivered to anyone** — it is recorded as suppressed thinking in your session steps and discarded from the chat.
|
|
13
|
+
To say something in a chat, you **must** invoke the Parall CLI via the Bash tool. To stay silent, simply do not invoke it.
|
|
11
14
|
|
|
12
15
|
## Parall CLI
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
All outbound interactions go through \`@parall/cli\`. Credentials are pre-injected as environment variables — no setup needed.
|
|
15
18
|
|
|
16
|
-
- \`npx --yes @parall/cli@latest messages send
|
|
17
|
-
- \`npx --yes @parall/cli@latest
|
|
18
|
-
- \`npx --yes @parall/cli@latest
|
|
19
|
-
- \`npx --yes @parall/cli@latest no-reply [--reason "..."]\` —
|
|
19
|
+
- \`npx --yes @parall/cli@latest messages send prll://cht_xxx --text "..."\` — reply into the triggering chat
|
|
20
|
+
- \`npx --yes @parall/cli@latest dm prll://usr_xxx --text "..." [--no-reply]\` — direct message another user
|
|
21
|
+
- \`npx --yes @parall/cli@latest tasks update prll://tsk_xxx --status in_progress\` — task state
|
|
22
|
+
- \`npx --yes @parall/cli@latest no-reply [--reason "..."]\` — explicitly declare this turn silent (audit signal; not required for silence, just clarifies intent)
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
\`PRLL_API_URL\`, \`PRLL_API_KEY\`, \`PRLL_ORG_ID\`, \`PRLL_SESSION_ID\`, \`PRLL_CHAT_ID\`, \`PRLL_TRIGGER_MESSAGE_ID\`, \`PRLL_STEP_ID_FILE\`.
|
|
24
|
+
Available env: \`PRLL_API_URL\`, \`PRLL_API_KEY\`, \`PRLL_ORG_ID\`, \`PRLL_SESSION_ID\`, \`PRLL_CHAT_ID\`, \`PRLL_TRIGGER_MESSAGE_ID\`, \`PRLL_STEP_ID_FILE\`.
|
|
23
25
|
|
|
24
26
|
## Guardrails
|
|
25
27
|
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- Keep replies concise and task-focused.
|
|
28
|
+
- A dispatch may coalesce multiple events. Decide per event whether to reply via \`messages send\` / \`dm\` — events you do not act on simply receive no reply.
|
|
29
|
+
- If an event carries \`[Hint: no_reply]\`, do not send anything for that event. \`no-reply\` is optional and only useful as an explicit intent marker.
|
|
30
|
+
- Never try to "speak" by typing sentences like "No response needed" / "Noted" / "OK" — they are discarded, so they accomplish nothing except polluting your session log.
|
|
31
|
+
- Keep CLI replies concise and task-focused.
|
|
31
32
|
`;
|
|
32
33
|
export function ensureClaudeWorkspace(workspaceDir, log) {
|
|
33
34
|
fs.mkdirSync(workspaceDir, { recursive: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/claude-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "Claude Code bridge runtime for self-hosted Parall agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"src"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@parall/
|
|
29
|
-
"@parall/
|
|
30
|
-
"@parall/
|
|
28
|
+
"@parall/sdk": "1.17.0",
|
|
29
|
+
"@parall/agent-core": "1.17.0",
|
|
30
|
+
"@parall/cli": "1.17.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^22.0.0",
|
package/src/dispatch.ts
CHANGED
|
@@ -26,53 +26,6 @@ type ClaudeCodeAdapterOptions = Pick<
|
|
|
26
26
|
sessionManager: ClaudeSessionManager;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
function extractBashCommand(input: unknown): string | undefined {
|
|
30
|
-
if (!input || typeof input !== "object") return undefined;
|
|
31
|
-
const command = (input as { command?: unknown }).command;
|
|
32
|
-
return typeof command === "string" && command.trim() ? command.trim() : undefined;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Returns the non-flag tokens that follow a Parall CLI invocation in `command`,
|
|
36
|
-
// or null if the command isn't a Parall CLI call. Handles all the documented
|
|
37
|
-
// forms — bare `parall`, `npx [--yes|-y] @parall/cli[@version]`,
|
|
38
|
-
// `pnpm (exec|dlx) parall` — and skips `npx` flags so that `npx --yes`
|
|
39
|
-
// matches as well as `npx -y`. Tokenization avoids the regex false-match
|
|
40
|
-
// where `messages send --no-reply` looked like the receiver-side `no-reply`.
|
|
41
|
-
function parseParallCliInvocation(command: string): string[] | null {
|
|
42
|
-
const tokens = command.replace(/\s+/g, " ").trim().split(" ");
|
|
43
|
-
let i = 0;
|
|
44
|
-
if (tokens[i] === "parall") {
|
|
45
|
-
i++;
|
|
46
|
-
} else if (tokens[i] === "npx") {
|
|
47
|
-
i++;
|
|
48
|
-
while (i < tokens.length && tokens[i].startsWith("-")) i++;
|
|
49
|
-
if (i >= tokens.length || !/^@parall\/cli(?:@.+)?$/.test(tokens[i])) return null;
|
|
50
|
-
i++;
|
|
51
|
-
} else if (tokens[i] === "pnpm") {
|
|
52
|
-
i++;
|
|
53
|
-
if (i < tokens.length && (tokens[i] === "exec" || tokens[i] === "dlx")) i++;
|
|
54
|
-
if (i >= tokens.length || tokens[i] !== "parall") return null;
|
|
55
|
-
i++;
|
|
56
|
-
} else {
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
return tokens.slice(i).filter((t) => !t.startsWith("-"));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function isParallSendCommand(command: string | undefined): boolean {
|
|
63
|
-
if (!command) return false;
|
|
64
|
-
const sub = parseParallCliInvocation(command);
|
|
65
|
-
if (!sub || sub.length === 0) return false;
|
|
66
|
-
// `dm <user>` or `messages send <chat>`
|
|
67
|
-
return sub[0] === "dm" || (sub[0] === "messages" && sub[1] === "send");
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function isParallNoReplyCommand(command: string | undefined): boolean {
|
|
71
|
-
if (!command) return false;
|
|
72
|
-
const sub = parseParallCliInvocation(command);
|
|
73
|
-
return sub?.[0] === "no-reply";
|
|
74
|
-
}
|
|
75
|
-
|
|
76
29
|
export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
77
30
|
constructor(private readonly opts: ClaudeCodeAdapterOptions) {}
|
|
78
31
|
|
|
@@ -115,11 +68,6 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
115
68
|
|
|
116
69
|
const groupKey = randomUUID();
|
|
117
70
|
let sawError = false;
|
|
118
|
-
let suppressProjectedText = false;
|
|
119
|
-
// Sticky for the whole dispatch: set when the agent explicitly calls
|
|
120
|
-
// `parall no-reply` to silence the turn. All subsequent text events are
|
|
121
|
-
// emitted with project=false so the bridge never leaks a chat message.
|
|
122
|
-
let noReplyCalled = false;
|
|
123
71
|
let completed = false;
|
|
124
72
|
|
|
125
73
|
try {
|
|
@@ -129,15 +77,6 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
129
77
|
continue;
|
|
130
78
|
}
|
|
131
79
|
|
|
132
|
-
if (event.type === "tool_call") {
|
|
133
|
-
const cmd = extractBashCommand(event.input);
|
|
134
|
-
if (isParallNoReplyCommand(cmd)) {
|
|
135
|
-
noReplyCalled = true;
|
|
136
|
-
} else if (isParallSendCommand(cmd)) {
|
|
137
|
-
suppressProjectedText = true;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
80
|
if (event.type === "error") {
|
|
142
81
|
sawError = true;
|
|
143
82
|
yield event;
|
|
@@ -145,15 +84,13 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
145
84
|
}
|
|
146
85
|
|
|
147
86
|
if (event.type === "text") {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
: event.project;
|
|
153
|
-
suppressProjectedText = false;
|
|
87
|
+
// Runtime output contract (symmetric with OpenClaw channel): Claude's
|
|
88
|
+
// plain text is never projected as a chat message. To reply, the agent
|
|
89
|
+
// must explicitly run `parall messages send` / `dm` via Bash. Text
|
|
90
|
+
// events are still recorded as suppressed session steps for audit.
|
|
154
91
|
yield {
|
|
155
92
|
...event,
|
|
156
|
-
project,
|
|
93
|
+
project: false,
|
|
157
94
|
groupKey,
|
|
158
95
|
};
|
|
159
96
|
continue;
|
package/src/workspace.ts
CHANGED
|
@@ -3,32 +3,33 @@ import * as path from "node:path";
|
|
|
3
3
|
|
|
4
4
|
const CLAUDE_MD = `# CLAUDE.md
|
|
5
5
|
|
|
6
|
-
You are an agent in Parall IM. You participate in chats, handle tasks, and
|
|
6
|
+
You are an agent in Parall IM. You participate in chats, handle tasks, and interact exclusively through the Parall CLI.
|
|
7
7
|
|
|
8
8
|
## Message Model
|
|
9
9
|
|
|
10
10
|
Incoming events are rendered as structured \`[Event: ...]\` blocks.
|
|
11
|
-
|
|
11
|
+
Each event includes \`[Chat: ... (prll://cht_xxx)]\` — use that chat ID (or full URI) when replying.
|
|
12
|
+
|
|
13
|
+
**Your plain-text output is not delivered to anyone** — it is recorded as suppressed thinking in your session steps and discarded from the chat.
|
|
14
|
+
To say something in a chat, you **must** invoke the Parall CLI via the Bash tool. To stay silent, simply do not invoke it.
|
|
12
15
|
|
|
13
16
|
## Parall CLI
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
All outbound interactions go through \`@parall/cli\`. Credentials are pre-injected as environment variables — no setup needed.
|
|
16
19
|
|
|
17
|
-
- \`npx --yes @parall/cli@latest messages send
|
|
18
|
-
- \`npx --yes @parall/cli@latest
|
|
19
|
-
- \`npx --yes @parall/cli@latest
|
|
20
|
-
- \`npx --yes @parall/cli@latest no-reply [--reason "..."]\` —
|
|
20
|
+
- \`npx --yes @parall/cli@latest messages send prll://cht_xxx --text "..."\` — reply into the triggering chat
|
|
21
|
+
- \`npx --yes @parall/cli@latest dm prll://usr_xxx --text "..." [--no-reply]\` — direct message another user
|
|
22
|
+
- \`npx --yes @parall/cli@latest tasks update prll://tsk_xxx --status in_progress\` — task state
|
|
23
|
+
- \`npx --yes @parall/cli@latest no-reply [--reason "..."]\` — explicitly declare this turn silent (audit signal; not required for silence, just clarifies intent)
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
\`PRLL_API_URL\`, \`PRLL_API_KEY\`, \`PRLL_ORG_ID\`, \`PRLL_SESSION_ID\`, \`PRLL_CHAT_ID\`, \`PRLL_TRIGGER_MESSAGE_ID\`, \`PRLL_STEP_ID_FILE\`.
|
|
25
|
+
Available env: \`PRLL_API_URL\`, \`PRLL_API_KEY\`, \`PRLL_ORG_ID\`, \`PRLL_SESSION_ID\`, \`PRLL_CHAT_ID\`, \`PRLL_TRIGGER_MESSAGE_ID\`, \`PRLL_STEP_ID_FILE\`.
|
|
24
26
|
|
|
25
27
|
## Guardrails
|
|
26
28
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
- Keep replies concise and task-focused.
|
|
29
|
+
- A dispatch may coalesce multiple events. Decide per event whether to reply via \`messages send\` / \`dm\` — events you do not act on simply receive no reply.
|
|
30
|
+
- If an event carries \`[Hint: no_reply]\`, do not send anything for that event. \`no-reply\` is optional and only useful as an explicit intent marker.
|
|
31
|
+
- Never try to "speak" by typing sentences like "No response needed" / "Noted" / "OK" — they are discarded, so they accomplish nothing except polluting your session log.
|
|
32
|
+
- Keep CLI replies concise and task-focused.
|
|
32
33
|
`;
|
|
33
34
|
|
|
34
35
|
export function ensureClaudeWorkspace(
|