claude-tempo 0.20.1 → 0.21.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/cli/commands.js +8 -4
- package/dist/cli/config-command.js +3 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +5 -0
- package/dist/spawn.d.ts +14 -3
- package/dist/spawn.js +27 -6
- package/package.json +1 -1
package/dist/cli/commands.js
CHANGED
|
@@ -178,6 +178,8 @@ async function start(opts) {
|
|
|
178
178
|
temporalEnvVars[config_1.ENV.TEMPORAL_TLS_CERT_PATH] = config.temporalTlsCertPath;
|
|
179
179
|
if (config.temporalTlsKeyPath)
|
|
180
180
|
temporalEnvVars[config_1.ENV.TEMPORAL_TLS_KEY_PATH] = config.temporalTlsKeyPath;
|
|
181
|
+
if (config.claudeBin)
|
|
182
|
+
temporalEnvVars[config_1.ENV.CLAUDE_BIN] = config.claudeBin;
|
|
181
183
|
if (opts.agent === 'copilot') {
|
|
182
184
|
const { pid } = (0, spawn_1.spawnCopilotBridge)({
|
|
183
185
|
name: opts.name || `copilot-${Date.now()}`,
|
|
@@ -212,7 +214,7 @@ async function start(opts) {
|
|
|
212
214
|
[config_1.ENV.CONDUCTOR]: opts.conductor ? 'true' : '',
|
|
213
215
|
[config_1.ENV.PLAYER_NAME]: sessionName || '',
|
|
214
216
|
};
|
|
215
|
-
const { pid } = (0, spawn_1.spawnInTerminal)(claudeArgs, workDir, envVars);
|
|
217
|
+
const { pid } = (0, spawn_1.spawnInTerminal)(claudeArgs, workDir, envVars, { claudeBin: config.claudeBin });
|
|
216
218
|
out.success(`Launched ${role} session${sessionName ? ` "${sessionName}"` : ''} (pid ${pid ?? 'unknown'})`);
|
|
217
219
|
}
|
|
218
220
|
out.log(` Ensemble: ${opts.ensemble}`);
|
|
@@ -841,7 +843,7 @@ async function up(opts) {
|
|
|
841
843
|
if (resolvedConductorType || conductorTypeName) {
|
|
842
844
|
conductorEnvVars[config_1.ENV.PLAYER_TYPE] = resolvedConductorType?.name || conductorTypeName || '';
|
|
843
845
|
}
|
|
844
|
-
({ pid } = (0, spawn_1.spawnInTerminal)(claudeArgs, process.cwd(), conductorEnvVars));
|
|
846
|
+
({ pid } = (0, spawn_1.spawnInTerminal)(claudeArgs, process.cwd(), conductorEnvVars, { claudeBin: config.claudeBin }));
|
|
845
847
|
}
|
|
846
848
|
out.success(`Conductor launched (pid ${pid ?? 'unknown'})`);
|
|
847
849
|
// Step 6: If lineup provided, recruit players and create schedules
|
|
@@ -946,7 +948,7 @@ async function up(opts) {
|
|
|
946
948
|
if (resolvedPlayerType) {
|
|
947
949
|
playerEnvVars[config_1.ENV.PLAYER_TYPE] = resolvedPlayerType.name;
|
|
948
950
|
}
|
|
949
|
-
(0, spawn_1.spawnInTerminal)(claudeArgs, playerWorkDir, playerEnvVars);
|
|
951
|
+
(0, spawn_1.spawnInTerminal)(claudeArgs, playerWorkDir, playerEnvVars, { claudeBin: config.claudeBin });
|
|
950
952
|
}
|
|
951
953
|
out.log(` ${out.green('ok')} ${out.bold(player.name)} in ${playerWorkDir}`);
|
|
952
954
|
}
|
|
@@ -1765,7 +1767,9 @@ async function encore(opts) {
|
|
|
1765
1767
|
envVars[config_1.ENV.TEMPORAL_TLS_CERT_PATH] = config.temporalTlsCertPath;
|
|
1766
1768
|
if (config.temporalTlsKeyPath)
|
|
1767
1769
|
envVars[config_1.ENV.TEMPORAL_TLS_KEY_PATH] = config.temporalTlsKeyPath;
|
|
1768
|
-
|
|
1770
|
+
if (config.claudeBin)
|
|
1771
|
+
envVars[config_1.ENV.CLAUDE_BIN] = config.claudeBin;
|
|
1772
|
+
const { pid } = (0, spawn_1.spawnInTerminal)(spawnArgs, targetMeta.workDir, envVars, { claudeBin: config.claudeBin });
|
|
1769
1773
|
out.success(`Encore! "${opts.name}" revived (pid ${pid})`);
|
|
1770
1774
|
await connection.close();
|
|
1771
1775
|
}
|
|
@@ -173,6 +173,8 @@ function configSet(key, value) {
|
|
|
173
173
|
'temporal-tls-key-path': 'temporalTlsKeyPath',
|
|
174
174
|
defaultAgent: 'defaultAgent',
|
|
175
175
|
'default-agent': 'defaultAgent',
|
|
176
|
+
claudeBin: 'claudeBin',
|
|
177
|
+
'claude-bin': 'claudeBin',
|
|
176
178
|
};
|
|
177
179
|
const configKey = keyMap[key];
|
|
178
180
|
if (!configKey) {
|
|
@@ -200,6 +202,7 @@ function configShow() {
|
|
|
200
202
|
{ key: 'temporalTlsCertPath', configKey: 'temporalTlsCertPath' },
|
|
201
203
|
{ key: 'temporalTlsKeyPath', configKey: 'temporalTlsKeyPath' },
|
|
202
204
|
{ key: 'defaultAgent', configKey: 'defaultAgent' },
|
|
205
|
+
{ key: 'claudeBin', configKey: 'claudeBin' },
|
|
203
206
|
];
|
|
204
207
|
out.log(` Config file: ${out.dim(config_1.CONFIG_FILE_PATH)}`);
|
|
205
208
|
console.log();
|
package/dist/config.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export declare const ENV: {
|
|
|
15
15
|
readonly TEMPORAL_TLS_KEY_PATH: "TEMPORAL_TLS_KEY_PATH";
|
|
16
16
|
readonly DEFAULT_AGENT: "CLAUDE_TEMPO_DEFAULT_AGENT";
|
|
17
17
|
readonly PLAYER_TYPE: "CLAUDE_TEMPO_PLAYER_TYPE";
|
|
18
|
+
readonly CLAUDE_BIN: "CLAUDE_TEMPO_CLAUDE_BIN";
|
|
18
19
|
};
|
|
19
20
|
export interface Config {
|
|
20
21
|
temporalAddress: string;
|
|
@@ -23,6 +24,7 @@ export interface Config {
|
|
|
23
24
|
temporalTlsCertPath?: string;
|
|
24
25
|
temporalTlsKeyPath?: string;
|
|
25
26
|
defaultAgent: AgentType;
|
|
27
|
+
claudeBin?: string;
|
|
26
28
|
taskQueue: string;
|
|
27
29
|
ensemble: string;
|
|
28
30
|
}
|
|
@@ -34,6 +36,7 @@ export interface PersistedConfig {
|
|
|
34
36
|
temporalTlsCertPath?: string;
|
|
35
37
|
temporalTlsKeyPath?: string;
|
|
36
38
|
defaultAgent?: AgentType;
|
|
39
|
+
claudeBin?: string;
|
|
37
40
|
}
|
|
38
41
|
export declare const CLAUDE_TEMPO_HOME: string;
|
|
39
42
|
export declare const CONFIG_FILE_PATH: string;
|
package/dist/config.js
CHANGED
|
@@ -36,6 +36,7 @@ exports.ENV = {
|
|
|
36
36
|
TEMPORAL_TLS_KEY_PATH: 'TEMPORAL_TLS_KEY_PATH',
|
|
37
37
|
DEFAULT_AGENT: 'CLAUDE_TEMPO_DEFAULT_AGENT',
|
|
38
38
|
PLAYER_TYPE: 'CLAUDE_TEMPO_PLAYER_TYPE',
|
|
39
|
+
CLAUDE_BIN: 'CLAUDE_TEMPO_CLAUDE_BIN',
|
|
39
40
|
};
|
|
40
41
|
exports.CLAUDE_TEMPO_HOME = (0, path_1.join)((0, os_1.homedir)(), '.claude-tempo');
|
|
41
42
|
exports.CONFIG_FILE_PATH = (0, path_1.join)(exports.CLAUDE_TEMPO_HOME, 'config.json');
|
|
@@ -192,6 +193,7 @@ function getConfig(overrides = {}) {
|
|
|
192
193
|
defaultAgent: validAgent(overrides.defaultAgent
|
|
193
194
|
|| process.env[exports.ENV.DEFAULT_AGENT]
|
|
194
195
|
|| configFile.defaultAgent),
|
|
196
|
+
claudeBin: process.env[exports.ENV.CLAUDE_BIN] || configFile.claudeBin || undefined,
|
|
195
197
|
taskQueue: process.env[exports.ENV.TASK_QUEUE] ?? 'claude-tempo',
|
|
196
198
|
ensemble: process.env[exports.ENV.ENSEMBLE] ?? 'default',
|
|
197
199
|
};
|
|
@@ -227,6 +229,7 @@ function getConfigWithSources(overrides = {}) {
|
|
|
227
229
|
const tlsCert = resolveWithSource('temporalTlsCertPath', overrides.temporalTlsCertPath, exports.ENV.TEMPORAL_TLS_CERT_PATH, configFile.temporalTlsCertPath, temporalCli.temporalTlsCertPath);
|
|
228
230
|
const tlsKey = resolveWithSource('temporalTlsKeyPath', overrides.temporalTlsKeyPath, exports.ENV.TEMPORAL_TLS_KEY_PATH, configFile.temporalTlsKeyPath, temporalCli.temporalTlsKeyPath);
|
|
229
231
|
const defaultAgent = resolveWithSource('defaultAgent', overrides.defaultAgent, exports.ENV.DEFAULT_AGENT, configFile.defaultAgent, undefined, 'claude');
|
|
232
|
+
const claudeBin = resolveWithSource('claudeBin', undefined, exports.ENV.CLAUDE_BIN, configFile.claudeBin, undefined);
|
|
230
233
|
return {
|
|
231
234
|
config: {
|
|
232
235
|
temporalAddress: address.value,
|
|
@@ -235,6 +238,7 @@ function getConfigWithSources(overrides = {}) {
|
|
|
235
238
|
temporalTlsCertPath: tlsCert.value,
|
|
236
239
|
temporalTlsKeyPath: tlsKey.value,
|
|
237
240
|
defaultAgent: validAgent(defaultAgent.value),
|
|
241
|
+
claudeBin: claudeBin.value,
|
|
238
242
|
taskQueue: process.env[exports.ENV.TASK_QUEUE] ?? 'claude-tempo',
|
|
239
243
|
ensemble: process.env[exports.ENV.ENSEMBLE] ?? 'default',
|
|
240
244
|
},
|
|
@@ -245,6 +249,7 @@ function getConfigWithSources(overrides = {}) {
|
|
|
245
249
|
temporalTlsCertPath: tlsCert.source,
|
|
246
250
|
temporalTlsKeyPath: tlsKey.source,
|
|
247
251
|
defaultAgent: defaultAgent.source,
|
|
252
|
+
claudeBin: claudeBin.source,
|
|
248
253
|
},
|
|
249
254
|
};
|
|
250
255
|
}
|
package/dist/spawn.d.ts
CHANGED
|
@@ -10,8 +10,17 @@ export declare function resolveIconPath(): string;
|
|
|
10
10
|
export declare function ensureWindowsTerminalProfile(): boolean;
|
|
11
11
|
/** POSIX shell-safe single-quoting (works in bash, zsh, and fish) */
|
|
12
12
|
export declare function shellQuote(s: string): string;
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the path to the `claude` binary.
|
|
15
|
+
*
|
|
16
|
+
* Resolution order:
|
|
17
|
+
* 1. `configBin` parameter (from Config.claudeBin — env var or config file)
|
|
18
|
+
* 2. `CLAUDE_TEMPO_CLAUDE_BIN` env var (checked directly for spawned processes that
|
|
19
|
+
* may not have full config resolution, e.g., activities)
|
|
20
|
+
* 3. `which claude` / `where claude` lookup
|
|
21
|
+
* 4. Bare `claude` fallback
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveClaudePath(configBin?: string): string;
|
|
15
24
|
/**
|
|
16
25
|
* Detect the macOS terminal the user is actually running in.
|
|
17
26
|
*
|
|
@@ -38,7 +47,9 @@ export declare function buildClaudeCommand(claudeBin: string, claudeArgs: string
|
|
|
38
47
|
* - Windows: shell:true with env vars
|
|
39
48
|
* - Linux: terminal emulator with -e flag
|
|
40
49
|
*/
|
|
41
|
-
export declare function spawnInTerminal(claudeArgs: string[], workDir: string, envVars: Record<string, string
|
|
50
|
+
export declare function spawnInTerminal(claudeArgs: string[], workDir: string, envVars: Record<string, string>, options?: {
|
|
51
|
+
claudeBin?: string;
|
|
52
|
+
}): {
|
|
42
53
|
pid: number | undefined;
|
|
43
54
|
};
|
|
44
55
|
export interface CopilotBridgeOpts {
|
package/dist/spawn.js
CHANGED
|
@@ -130,8 +130,25 @@ function ensureWindowsTerminalProfile() {
|
|
|
130
130
|
function shellQuote(s) {
|
|
131
131
|
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
132
132
|
}
|
|
133
|
-
/**
|
|
134
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Resolve the path to the `claude` binary.
|
|
135
|
+
*
|
|
136
|
+
* Resolution order:
|
|
137
|
+
* 1. `configBin` parameter (from Config.claudeBin — env var or config file)
|
|
138
|
+
* 2. `CLAUDE_TEMPO_CLAUDE_BIN` env var (checked directly for spawned processes that
|
|
139
|
+
* may not have full config resolution, e.g., activities)
|
|
140
|
+
* 3. `which claude` / `where claude` lookup
|
|
141
|
+
* 4. Bare `claude` fallback
|
|
142
|
+
*/
|
|
143
|
+
function resolveClaudePath(configBin) {
|
|
144
|
+
// Priority 1: explicit config value
|
|
145
|
+
if (configBin)
|
|
146
|
+
return configBin;
|
|
147
|
+
// Priority 2: env var (may be set by parent process)
|
|
148
|
+
const envBin = process.env.CLAUDE_TEMPO_CLAUDE_BIN;
|
|
149
|
+
if (envBin)
|
|
150
|
+
return envBin;
|
|
151
|
+
// Priority 3: which/where lookup
|
|
135
152
|
const cmd = process.platform === 'win32' ? 'where' : 'which';
|
|
136
153
|
try {
|
|
137
154
|
return (0, child_process_1.execFileSync)(cmd, ['claude'], { encoding: 'utf8' }).trim().split('\n')[0];
|
|
@@ -205,8 +222,10 @@ function buildClaudeCommand(claudeBin, claudeArgs, envVars) {
|
|
|
205
222
|
const envInline = Object.entries(envVars)
|
|
206
223
|
.map(([k, v]) => `${k}=${shellQuote(v)}`)
|
|
207
224
|
.join(' ');
|
|
225
|
+
// Quote the binary path if it contains spaces (e.g., "C:\Program Files\...")
|
|
226
|
+
const quotedBin = claudeBin.includes(' ') ? shellQuote(claudeBin) : claudeBin;
|
|
208
227
|
const args = claudeArgs.map(a => shellQuote(a)).join(' ');
|
|
209
|
-
return envInline ? `${envInline} ${
|
|
228
|
+
return envInline ? `${envInline} ${quotedBin} ${args}` : `${quotedBin} ${args}`;
|
|
210
229
|
}
|
|
211
230
|
/**
|
|
212
231
|
* Spawn a Claude Code session in a visible terminal window.
|
|
@@ -218,8 +237,8 @@ function buildClaudeCommand(claudeBin, claudeArgs, envVars) {
|
|
|
218
237
|
* - Windows: shell:true with env vars
|
|
219
238
|
* - Linux: terminal emulator with -e flag
|
|
220
239
|
*/
|
|
221
|
-
function spawnInTerminal(claudeArgs, workDir, envVars) {
|
|
222
|
-
const claudeBin = resolveClaudePath();
|
|
240
|
+
function spawnInTerminal(claudeArgs, workDir, envVars, options) {
|
|
241
|
+
const claudeBin = resolveClaudePath(options?.claudeBin);
|
|
223
242
|
const claudeInvocation = buildClaudeCommand(claudeBin, claudeArgs, envVars);
|
|
224
243
|
if (process.platform === 'darwin') {
|
|
225
244
|
const detected = detectMacTerminal();
|
|
@@ -308,7 +327,9 @@ function spawnInTerminal(claudeArgs, workDir, envVars) {
|
|
|
308
327
|
const setCmds = Object.entries(envVars)
|
|
309
328
|
.map(([k, v]) => `set "${k}=${cmdEscape(v)}"`)
|
|
310
329
|
.join(' && ');
|
|
311
|
-
|
|
330
|
+
// Quote the binary path if it contains spaces (e.g., "C:\Program Files\...")
|
|
331
|
+
const quotedWinBin = claudeBin.includes(' ') ? `"${cmdEscape(claudeBin)}"` : cmdEscape(claudeBin);
|
|
332
|
+
const claudeCmd = `${quotedWinBin} ${claudeArgs.map(a => `"${cmdEscape(a)}"`).join(' ')}`;
|
|
312
333
|
const innerCmd = setCmds
|
|
313
334
|
? `${setCmds} && ${claudeCmd}`
|
|
314
335
|
: claudeCmd;
|