@adecore/agents 0.48.3 → 0.48.4

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.
@@ -3,6 +3,7 @@ import { errorText } from '../error-text.js';
3
3
  import { claudeArgs, claudeEnv, promptPrefix } from '../providers/claude.js';
4
4
  import { ChatChild, MAX_LINE_LENGTH, readStreamLines } from './chat-process.js';
5
5
  import { ClaudeProtocol } from './claude-protocol.js';
6
+ import { claudeSystemPromptArgs } from './claude-system-prompt.js';
6
7
  import { buildUserMessage } from './input.js';
7
8
  // Claude may echo a steer only once a slow tool returns, so a running turn sets no deadline; after the turn ended, a message
8
9
  // it still holds opens the next turn at once or never arrives.
@@ -57,7 +58,12 @@ export class ClaudeBackend {
57
58
  })
58
59
  ];
59
60
  if (this.launch.instructions !== null) {
60
- args.push('--append-system-prompt', this.launch.instructions);
61
+ try {
62
+ args.push(...claudeSystemPromptArgs(this.launch.instructions));
63
+ }
64
+ catch (error) {
65
+ return Promise.reject(error instanceof Error ? error : new Error(errorText(error)));
66
+ }
61
67
  }
62
68
  this.stdinClosed = false;
63
69
  const child = new ChatChild({
@@ -0,0 +1 @@
1
+ export declare function claudeSystemPromptArgs(instructions: string, platform?: NodeJS.Platform, folder?: string): string[];
@@ -0,0 +1,18 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { writeFileSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ /*
6
+ * The flags that hand Claude its system prompt. npm installs the CLI as a batch file on Windows, and
7
+ * a line through cmd.exe holds no line break and stops near 8 KB, so there the prompt goes in a file.
8
+ * The name follows the content, so chats with the same prompt share one file and no chat removes it from under another.
9
+ */
10
+ export function claudeSystemPromptArgs(instructions, platform = process.platform, folder = tmpdir()) {
11
+ if (platform !== 'win32') {
12
+ return ['--append-system-prompt', instructions];
13
+ }
14
+ const digest = createHash('sha256').update(instructions).digest('hex').slice(0, 32);
15
+ const path = join(folder, `adecore-claude-prompt-${digest}.md`);
16
+ writeFileSync(path, instructions, { mode: 0o600 });
17
+ return ['--append-system-prompt-file', path];
18
+ }
@@ -3,7 +3,7 @@
3
3
  * compaction, edits, subagents, interrupts and crashes through the real frame shapes.
4
4
  */
5
5
  import { spawn } from 'node:child_process';
6
- import { writeFileSync } from 'node:fs';
6
+ import { readFileSync, writeFileSync } from 'node:fs';
7
7
  import { resolve } from 'node:path';
8
8
  export function fakeClaude(io) {
9
9
  const args = io.argv;
@@ -938,7 +938,8 @@ export function fakeClaude(io) {
938
938
  }
939
939
  if (text === 'system?') {
940
940
  const at = args.indexOf('--append-system-prompt');
941
- assistantText(at >= 0 ? args[at + 1] : 'none');
941
+ const fileAt = args.indexOf('--append-system-prompt-file');
942
+ assistantText(at >= 0 ? args[at + 1] : fileAt >= 0 ? readFileSync(args[fileAt + 1], 'utf8') : 'none');
942
943
  result();
943
944
  return;
944
945
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/agents",
3
- "version": "0.48.3",
3
+ "version": "0.48.4",
4
4
  "description": "Node-compatible agent chat hosts, providers, accounts, usage and durable task coordination.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -93,8 +93,8 @@
93
93
  "test": "bun --conditions=source test"
94
94
  },
95
95
  "dependencies": {
96
- "@adecore/agent-contracts": "0.48.3",
97
- "@adecore/intelligent-ui": "0.48.3",
96
+ "@adecore/agent-contracts": "0.48.4",
97
+ "@adecore/intelligent-ui": "0.48.4",
98
98
  "zod": "^4.6.7"
99
99
  },
100
100
  "devDependencies": {
@@ -4,6 +4,7 @@ import { claudeArgs, claudeEnv, promptPrefix } from '../providers/claude.ts';
4
4
  import type { ApprovalDecision, BackendHost, BackendLaunch, ChatBackend, TurnInput } from './backend.ts';
5
5
  import { ChatChild, MAX_LINE_LENGTH, readStreamLines } from './chat-process.ts';
6
6
  import { ClaudeProtocol } from './claude-protocol.ts';
7
+ import { claudeSystemPromptArgs } from './claude-system-prompt.ts';
7
8
  import { buildUserMessage } from './input.ts';
8
9
 
9
10
  // Claude may echo a steer only once a slow tool returns, so a running turn sets no deadline; after the turn ended, a message
@@ -72,7 +73,11 @@ export class ClaudeBackend implements ChatBackend {
72
73
  ];
73
74
 
74
75
  if (this.launch.instructions !== null) {
75
- args.push('--append-system-prompt', this.launch.instructions);
76
+ try {
77
+ args.push(...claudeSystemPromptArgs(this.launch.instructions));
78
+ } catch (error) {
79
+ return Promise.reject(error instanceof Error ? error : new Error(errorText(error)));
80
+ }
76
81
  }
77
82
 
78
83
  this.stdinClosed = false;
@@ -0,0 +1,22 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { writeFileSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+
6
+ /*
7
+ * The flags that hand Claude its system prompt. npm installs the CLI as a batch file on Windows, and
8
+ * a line through cmd.exe holds no line break and stops near 8 KB, so there the prompt goes in a file.
9
+ * The name follows the content, so chats with the same prompt share one file and no chat removes it from under another.
10
+ */
11
+ export function claudeSystemPromptArgs(instructions: string, platform: NodeJS.Platform = process.platform, folder: string = tmpdir()): string[] {
12
+ if (platform !== 'win32') {
13
+ return ['--append-system-prompt', instructions];
14
+ }
15
+
16
+ const digest = createHash('sha256').update(instructions).digest('hex').slice(0, 32);
17
+ const path = join(folder, `adecore-claude-prompt-${digest}.md`);
18
+
19
+ writeFileSync(path, instructions, { mode: 0o600 });
20
+
21
+ return ['--append-system-prompt-file', path];
22
+ }
@@ -3,7 +3,7 @@
3
3
  * compaction, edits, subagents, interrupts and crashes through the real frame shapes.
4
4
  */
5
5
  import { spawn } from 'node:child_process';
6
- import { writeFileSync } from 'node:fs';
6
+ import { readFileSync, writeFileSync } from 'node:fs';
7
7
  import { resolve } from 'node:path';
8
8
  import type { FakeCli, FakeIo, FakeProgram } from './fake-cli.ts';
9
9
 
@@ -1113,7 +1113,8 @@ export function fakeClaude(io: FakeIo): FakeProgram {
1113
1113
 
1114
1114
  if (text === 'system?') {
1115
1115
  const at = args.indexOf('--append-system-prompt');
1116
- assistantText(at >= 0 ? args[at + 1]! : 'none');
1116
+ const fileAt = args.indexOf('--append-system-prompt-file');
1117
+ assistantText(at >= 0 ? args[at + 1]! : fileAt >= 0 ? readFileSync(args[fileAt + 1]!, 'utf8') : 'none');
1117
1118
  result();
1118
1119
 
1119
1120
  return;