@covibes/zeroshot 5.3.0 → 5.4.1
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/LICENSE +1 -1
- package/README.md +8 -385
- package/cli/index.js +108 -4615
- package/package.json +16 -125
- package/CHANGELOG.md +0 -537
- package/cli/commands/providers.js +0 -150
- package/cli/lib/first-run.js +0 -211
- package/cli/lib/update-checker.js +0 -281
- package/cli/message-formatter-utils.js +0 -75
- package/cli/message-formatters-normal.js +0 -253
- package/cli/message-formatters-watch.js +0 -181
- package/cluster-templates/base-templates/debug-workflow.json +0 -375
- package/cluster-templates/base-templates/full-workflow.json +0 -697
- package/cluster-templates/base-templates/single-worker.json +0 -63
- package/cluster-templates/base-templates/worker-validator.json +0 -152
- package/cluster-templates/conductor-bootstrap.json +0 -124
- package/docker/zeroshot-cluster/Dockerfile +0 -152
- package/docker/zeroshot-cluster/pre-baked-deps.json +0 -28
- package/lib/completion.js +0 -174
- package/lib/docker-config.js +0 -212
- package/lib/id-detector.js +0 -53
- package/lib/provider-detection.js +0 -59
- package/lib/provider-names.js +0 -56
- package/lib/settings.js +0 -405
- package/lib/stream-json-parser.js +0 -10
- package/scripts/fix-node-pty-permissions.js +0 -75
- package/scripts/record-demo.sh +0 -279
- package/scripts/test-install.sh +0 -40
- package/scripts/validate-templates.js +0 -100
- package/src/agent/agent-config.js +0 -193
- package/src/agent/agent-context-builder.js +0 -335
- package/src/agent/agent-hook-executor.js +0 -402
- package/src/agent/agent-lifecycle.js +0 -683
- package/src/agent/agent-stuck-detector.js +0 -256
- package/src/agent/agent-task-executor.js +0 -1431
- package/src/agent/agent-trigger-evaluator.js +0 -67
- package/src/agent/output-extraction.js +0 -200
- package/src/agent/output-reformatter.js +0 -175
- package/src/agent/schema-utils.js +0 -111
- package/src/agent-wrapper.js +0 -570
- package/src/agents/git-pusher-agent.json +0 -20
- package/src/attach/attach-client.js +0 -438
- package/src/attach/attach-server.js +0 -543
- package/src/attach/index.js +0 -35
- package/src/attach/protocol.js +0 -220
- package/src/attach/ring-buffer.js +0 -121
- package/src/attach/socket-discovery.js +0 -267
- package/src/claude-task-runner.js +0 -523
- package/src/config-router.js +0 -80
- package/src/config-validator.js +0 -1660
- package/src/copy-worker.js +0 -43
- package/src/github.js +0 -139
- package/src/isolation-manager.js +0 -1381
- package/src/ledger.js +0 -614
- package/src/logic-engine.js +0 -223
- package/src/message-bus-bridge.js +0 -139
- package/src/message-bus.js +0 -249
- package/src/name-generator.js +0 -232
- package/src/orchestrator.js +0 -2519
- package/src/preflight.js +0 -485
- package/src/process-metrics.js +0 -566
- package/src/providers/anthropic/cli-builder.js +0 -45
- package/src/providers/anthropic/index.js +0 -134
- package/src/providers/anthropic/models.js +0 -23
- package/src/providers/anthropic/output-parser.js +0 -159
- package/src/providers/base-provider.js +0 -181
- package/src/providers/capabilities.js +0 -51
- package/src/providers/google/cli-builder.js +0 -55
- package/src/providers/google/index.js +0 -116
- package/src/providers/google/models.js +0 -24
- package/src/providers/google/output-parser.js +0 -92
- package/src/providers/index.js +0 -75
- package/src/providers/openai/cli-builder.js +0 -122
- package/src/providers/openai/index.js +0 -135
- package/src/providers/openai/models.js +0 -21
- package/src/providers/openai/output-parser.js +0 -129
- package/src/schemas/sub-cluster.js +0 -156
- package/src/status-footer.js +0 -980
- package/src/sub-cluster-wrapper.js +0 -560
- package/src/task-runner.js +0 -30
- package/src/template-resolver.js +0 -369
- package/src/tui/CHANGES.txt +0 -133
- package/src/tui/LAYOUT.md +0 -261
- package/src/tui/README.txt +0 -192
- package/src/tui/TWO-LEVEL-NAVIGATION.md +0 -186
- package/src/tui/data-poller.js +0 -325
- package/src/tui/demo.js +0 -208
- package/src/tui/formatters.js +0 -128
- package/src/tui/index.js +0 -193
- package/src/tui/keybindings.js +0 -383
- package/src/tui/layout.js +0 -334
- package/src/tui/renderer.js +0 -194
- package/task-lib/attachable-watcher.js +0 -272
- package/task-lib/claude-recovery.js +0 -119
- package/task-lib/commands/clean.js +0 -50
- package/task-lib/commands/get-log-path.js +0 -23
- package/task-lib/commands/kill.js +0 -32
- package/task-lib/commands/list.js +0 -105
- package/task-lib/commands/logs.js +0 -411
- package/task-lib/commands/resume.js +0 -42
- package/task-lib/commands/run.js +0 -57
- package/task-lib/commands/schedule.js +0 -105
- package/task-lib/commands/scheduler-cmd.js +0 -96
- package/task-lib/commands/schedules.js +0 -98
- package/task-lib/commands/status.js +0 -44
- package/task-lib/commands/unschedule.js +0 -16
- package/task-lib/completion.js +0 -9
- package/task-lib/config.js +0 -10
- package/task-lib/name-generator.js +0 -230
- package/task-lib/package.json +0 -3
- package/task-lib/runner.js +0 -144
- package/task-lib/scheduler.js +0 -252
- package/task-lib/store.js +0 -230
- package/task-lib/tui/formatters.js +0 -166
- package/task-lib/tui/index.js +0 -197
- package/task-lib/tui/layout.js +0 -111
- package/task-lib/tui/renderer.js +0 -119
- package/task-lib/tui.js +0 -384
- package/task-lib/watcher.js +0 -188
package/lib/settings.js
DELETED
|
@@ -1,405 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Settings management for zeroshot
|
|
3
|
-
* Persistent user preferences stored in ~/.zeroshot/settings.json
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const fs = require('fs');
|
|
7
|
-
const path = require('path');
|
|
8
|
-
const os = require('os');
|
|
9
|
-
const { validateMountConfig, validateEnvPassthrough } = require('./docker-config');
|
|
10
|
-
const {
|
|
11
|
-
VALID_PROVIDERS,
|
|
12
|
-
normalizeProviderName,
|
|
13
|
-
normalizeProviderSettings,
|
|
14
|
-
} = require('./provider-names');
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Get settings file path (dynamically reads env var for testing)
|
|
18
|
-
* Using a getter ensures tests can override the path at runtime
|
|
19
|
-
* @returns {string}
|
|
20
|
-
*/
|
|
21
|
-
function getSettingsFile() {
|
|
22
|
-
return (
|
|
23
|
-
process.env.ZEROSHOT_SETTINGS_FILE || path.join(os.homedir(), '.zeroshot', 'settings.json')
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Model hierarchy for cost ceiling validation
|
|
29
|
-
* Higher number = more expensive/capable model
|
|
30
|
-
*/
|
|
31
|
-
const MODEL_HIERARCHY = {
|
|
32
|
-
opus: 3,
|
|
33
|
-
sonnet: 2,
|
|
34
|
-
haiku: 1,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const VALID_MODELS = Object.keys(MODEL_HIERARCHY);
|
|
38
|
-
const LEVEL_RANKS = { level1: 1, level2: 2, level3: 3 };
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Validate a requested model against the maxModel ceiling and minModel floor
|
|
42
|
-
* @param {string} requestedModel - Model the agent wants to use
|
|
43
|
-
* @param {string} maxModel - Maximum allowed model (cost ceiling)
|
|
44
|
-
* @param {string|null} minModel - Minimum required model (cost floor)
|
|
45
|
-
* @returns {string} The validated model
|
|
46
|
-
* @throws {Error} If requested model exceeds ceiling or falls below floor
|
|
47
|
-
*/
|
|
48
|
-
function validateModelAgainstMax(requestedModel, maxModel, minModel = null) {
|
|
49
|
-
if (!requestedModel) return maxModel; // Default to ceiling if unspecified
|
|
50
|
-
|
|
51
|
-
if (!VALID_MODELS.includes(requestedModel)) {
|
|
52
|
-
throw new Error(`Invalid model "${requestedModel}". Valid: ${VALID_MODELS.join(', ')}`);
|
|
53
|
-
}
|
|
54
|
-
if (!VALID_MODELS.includes(maxModel)) {
|
|
55
|
-
throw new Error(`Invalid maxModel "${maxModel}". Valid: ${VALID_MODELS.join(', ')}`);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (MODEL_HIERARCHY[requestedModel] > MODEL_HIERARCHY[maxModel]) {
|
|
59
|
-
throw new Error(
|
|
60
|
-
`Agent requests "${requestedModel}" but maxModel is "${maxModel}". ` +
|
|
61
|
-
`Either lower agent's model or raise maxModel.`
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (minModel) {
|
|
66
|
-
if (!VALID_MODELS.includes(minModel)) {
|
|
67
|
-
throw new Error(`Invalid minModel "${minModel}". Valid: ${VALID_MODELS.join(', ')}`);
|
|
68
|
-
}
|
|
69
|
-
if (MODEL_HIERARCHY[minModel] > MODEL_HIERARCHY[maxModel]) {
|
|
70
|
-
throw new Error(`minModel "${minModel}" cannot be higher than maxModel "${maxModel}".`);
|
|
71
|
-
}
|
|
72
|
-
if (MODEL_HIERARCHY[requestedModel] < MODEL_HIERARCHY[minModel]) {
|
|
73
|
-
throw new Error(
|
|
74
|
-
`Agent requests "${requestedModel}" but minModel is "${minModel}". ` +
|
|
75
|
-
`Either raise agent's model or lower minModel.`
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return requestedModel;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Default settings
|
|
84
|
-
const DEFAULT_SETTINGS = {
|
|
85
|
-
maxModel: 'opus', // Cost ceiling - agents cannot use models above this
|
|
86
|
-
minModel: null, // Cost floor - agents cannot use models below this (null = no minimum)
|
|
87
|
-
defaultProvider: 'claude',
|
|
88
|
-
providerSettings: {
|
|
89
|
-
claude: {
|
|
90
|
-
maxLevel: 'level3',
|
|
91
|
-
minLevel: 'level1',
|
|
92
|
-
defaultLevel: 'level2',
|
|
93
|
-
levelOverrides: {},
|
|
94
|
-
},
|
|
95
|
-
codex: {
|
|
96
|
-
maxLevel: 'level3',
|
|
97
|
-
minLevel: 'level1',
|
|
98
|
-
defaultLevel: 'level2',
|
|
99
|
-
levelOverrides: {},
|
|
100
|
-
},
|
|
101
|
-
gemini: {
|
|
102
|
-
maxLevel: 'level3',
|
|
103
|
-
minLevel: 'level1',
|
|
104
|
-
defaultLevel: 'level2',
|
|
105
|
-
levelOverrides: {},
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
defaultConfig: 'conductor-bootstrap',
|
|
109
|
-
defaultDocker: false,
|
|
110
|
-
strictSchema: true, // true = reliable json output (default), false = live streaming (may crash - see bold-meadow-11)
|
|
111
|
-
logLevel: 'normal',
|
|
112
|
-
// Auto-update settings
|
|
113
|
-
autoCheckUpdates: true, // Check npm registry for newer versions
|
|
114
|
-
lastUpdateCheckAt: null, // Unix timestamp of last check (null = never checked)
|
|
115
|
-
lastSeenVersion: null, // Don't re-prompt for same version
|
|
116
|
-
// Claude command - customize how to invoke Claude CLI (default: 'claude')
|
|
117
|
-
// Example: 'ccr code' for claude-code-router integration
|
|
118
|
-
claudeCommand: 'claude',
|
|
119
|
-
// Docker isolation mounts - preset names or {host, container, readonly?} objects
|
|
120
|
-
// Valid presets: gh, git, ssh, aws, azure, kube, terraform, gcloud, claude, codex, gemini
|
|
121
|
-
dockerMounts: ['gh', 'git', 'ssh'],
|
|
122
|
-
// Extra env vars to pass to Docker container (in addition to preset-implied ones)
|
|
123
|
-
// Supports: VAR (if set), VAR_* (pattern), VAR=value (forced), VAR= (empty)
|
|
124
|
-
dockerEnvPassthrough: [],
|
|
125
|
-
// Container home directory - where $HOME resolves in container paths
|
|
126
|
-
// Default: /home/node (matches zeroshot-cluster-base image)
|
|
127
|
-
dockerContainerHome: '/home/node',
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
function mapLegacyModelToLevel(model) {
|
|
131
|
-
switch (model) {
|
|
132
|
-
case 'haiku':
|
|
133
|
-
return 'level1';
|
|
134
|
-
case 'sonnet':
|
|
135
|
-
return 'level2';
|
|
136
|
-
case 'opus':
|
|
137
|
-
return 'level3';
|
|
138
|
-
default:
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function mergeProviderSettings(current, overrides) {
|
|
144
|
-
const merged = { ...current };
|
|
145
|
-
for (const provider of VALID_PROVIDERS) {
|
|
146
|
-
merged[provider] = {
|
|
147
|
-
...current[provider],
|
|
148
|
-
...(overrides?.[provider] || {}),
|
|
149
|
-
};
|
|
150
|
-
if (!merged[provider].levelOverrides) {
|
|
151
|
-
merged[provider].levelOverrides = {};
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return merged;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function applyLegacyModelBounds(settings) {
|
|
158
|
-
if (!settings.providerSettings) return settings;
|
|
159
|
-
const claude = settings.providerSettings.claude || {};
|
|
160
|
-
const legacyMaxLevel = mapLegacyModelToLevel(settings.maxModel);
|
|
161
|
-
const legacyMinLevel = mapLegacyModelToLevel(settings.minModel);
|
|
162
|
-
|
|
163
|
-
if (legacyMaxLevel) {
|
|
164
|
-
claude.maxLevel = legacyMaxLevel;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (legacyMinLevel) {
|
|
168
|
-
claude.minLevel = legacyMinLevel;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const minRank = LEVEL_RANKS[claude.minLevel] || LEVEL_RANKS.level1;
|
|
172
|
-
const maxRank = LEVEL_RANKS[claude.maxLevel] || LEVEL_RANKS.level3;
|
|
173
|
-
const defaultRank = LEVEL_RANKS[claude.defaultLevel] || LEVEL_RANKS.level2;
|
|
174
|
-
|
|
175
|
-
if (minRank > maxRank) {
|
|
176
|
-
claude.minLevel = 'level1';
|
|
177
|
-
claude.maxLevel = 'level3';
|
|
178
|
-
} else if (defaultRank < minRank) {
|
|
179
|
-
claude.defaultLevel = claude.minLevel;
|
|
180
|
-
} else if (defaultRank > maxRank) {
|
|
181
|
-
claude.defaultLevel = claude.maxLevel;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
settings.providerSettings.claude = claude;
|
|
185
|
-
return settings;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function normalizeLoadedSettings(parsed) {
|
|
189
|
-
const normalized = { ...parsed };
|
|
190
|
-
if (parsed.defaultProvider) {
|
|
191
|
-
normalized.defaultProvider = normalizeProviderName(parsed.defaultProvider);
|
|
192
|
-
}
|
|
193
|
-
if (parsed.providerSettings) {
|
|
194
|
-
normalized.providerSettings = normalizeProviderSettings(parsed.providerSettings);
|
|
195
|
-
}
|
|
196
|
-
return normalized;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Load settings from disk, merging with defaults
|
|
201
|
-
*/
|
|
202
|
-
function loadSettings() {
|
|
203
|
-
const settingsFile = getSettingsFile();
|
|
204
|
-
if (!fs.existsSync(settingsFile)) {
|
|
205
|
-
return { ...DEFAULT_SETTINGS };
|
|
206
|
-
}
|
|
207
|
-
try {
|
|
208
|
-
const data = fs.readFileSync(settingsFile, 'utf8');
|
|
209
|
-
const parsed = normalizeLoadedSettings(JSON.parse(data));
|
|
210
|
-
const merged = { ...DEFAULT_SETTINGS, ...parsed };
|
|
211
|
-
merged.defaultProvider =
|
|
212
|
-
normalizeProviderName(merged.defaultProvider) || DEFAULT_SETTINGS.defaultProvider;
|
|
213
|
-
merged.providerSettings = mergeProviderSettings(
|
|
214
|
-
DEFAULT_SETTINGS.providerSettings,
|
|
215
|
-
parsed.providerSettings
|
|
216
|
-
);
|
|
217
|
-
return applyLegacyModelBounds(merged);
|
|
218
|
-
} catch {
|
|
219
|
-
console.error('Warning: Could not load settings, using defaults');
|
|
220
|
-
return { ...DEFAULT_SETTINGS };
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Save settings to disk
|
|
226
|
-
*/
|
|
227
|
-
function saveSettings(settings) {
|
|
228
|
-
const settingsFile = getSettingsFile();
|
|
229
|
-
const dir = path.dirname(settingsFile);
|
|
230
|
-
if (!fs.existsSync(dir)) {
|
|
231
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
232
|
-
}
|
|
233
|
-
fs.writeFileSync(settingsFile, JSON.stringify(settings, null, 2), 'utf8');
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Validate a setting value
|
|
238
|
-
* @returns {string|null} Error message if invalid, null if valid
|
|
239
|
-
*/
|
|
240
|
-
function validateSetting(key, value) {
|
|
241
|
-
if (!(key in DEFAULT_SETTINGS)) {
|
|
242
|
-
return `Unknown setting: ${key}`;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (key === 'maxModel' && !VALID_MODELS.includes(value)) {
|
|
246
|
-
return `Invalid model: ${value}. Valid models: ${VALID_MODELS.join(', ')}`;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (key === 'minModel' && value !== null && !VALID_MODELS.includes(value)) {
|
|
250
|
-
return `Invalid model: ${value}. Valid models: ${VALID_MODELS.join(', ')}, null`;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
if (key === 'logLevel' && !['quiet', 'normal', 'verbose'].includes(value)) {
|
|
254
|
-
return `Invalid log level: ${value}. Valid levels: quiet, normal, verbose`;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (key === 'claudeCommand') {
|
|
258
|
-
if (typeof value !== 'string') {
|
|
259
|
-
return 'claudeCommand must be a string';
|
|
260
|
-
}
|
|
261
|
-
if (value.trim().length === 0) {
|
|
262
|
-
return 'claudeCommand cannot be empty';
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (key === 'defaultProvider') {
|
|
267
|
-
const normalized = normalizeProviderName(value);
|
|
268
|
-
if (!VALID_PROVIDERS.includes(normalized)) {
|
|
269
|
-
return `Invalid provider: ${value}. Valid providers: ${VALID_PROVIDERS.join(', ')}`;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (key === 'providerSettings') {
|
|
274
|
-
const normalizedSettings = normalizeProviderSettings(value);
|
|
275
|
-
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
276
|
-
return 'providerSettings must be an object';
|
|
277
|
-
}
|
|
278
|
-
for (const [provider, settings] of Object.entries(normalizedSettings || {})) {
|
|
279
|
-
if (!VALID_PROVIDERS.includes(provider)) {
|
|
280
|
-
return `Unknown provider in providerSettings: ${provider}`;
|
|
281
|
-
}
|
|
282
|
-
if (typeof settings !== 'object' || settings === null) {
|
|
283
|
-
return `providerSettings.${provider} must be an object`;
|
|
284
|
-
}
|
|
285
|
-
if (settings.maxLevel && !LEVEL_RANKS[settings.maxLevel]) {
|
|
286
|
-
return `Invalid maxLevel for ${provider}: ${settings.maxLevel}`;
|
|
287
|
-
}
|
|
288
|
-
if (settings.minLevel && !LEVEL_RANKS[settings.minLevel]) {
|
|
289
|
-
return `Invalid minLevel for ${provider}: ${settings.minLevel}`;
|
|
290
|
-
}
|
|
291
|
-
if (settings.defaultLevel && !LEVEL_RANKS[settings.defaultLevel]) {
|
|
292
|
-
return `Invalid defaultLevel for ${provider}: ${settings.defaultLevel}`;
|
|
293
|
-
}
|
|
294
|
-
if (
|
|
295
|
-
settings.levelOverrides &&
|
|
296
|
-
(typeof settings.levelOverrides !== 'object' || Array.isArray(settings.levelOverrides))
|
|
297
|
-
) {
|
|
298
|
-
return `levelOverrides for ${provider} must be an object`;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (key === 'dockerMounts') {
|
|
304
|
-
return validateMountConfig(value);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (key === 'dockerEnvPassthrough') {
|
|
308
|
-
return validateEnvPassthrough(value);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
return null;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Coerce value to correct type based on default value type
|
|
316
|
-
*/
|
|
317
|
-
function coerceValue(key, value) {
|
|
318
|
-
const defaultValue = DEFAULT_SETTINGS[key];
|
|
319
|
-
|
|
320
|
-
// Handle null values for minModel
|
|
321
|
-
if (key === 'minModel' && (value === 'null' || value === null)) {
|
|
322
|
-
return null;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
if (typeof defaultValue === 'boolean') {
|
|
326
|
-
return value === 'true' || value === '1' || value === 'yes' || value === true;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if (typeof defaultValue === 'number') {
|
|
330
|
-
const parsed = parseInt(value);
|
|
331
|
-
if (isNaN(parsed)) {
|
|
332
|
-
throw new Error(`Invalid number: ${value}`);
|
|
333
|
-
}
|
|
334
|
-
return parsed;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Handle array settings (dockerMounts, dockerEnvPassthrough)
|
|
338
|
-
if (Array.isArray(defaultValue)) {
|
|
339
|
-
if (typeof value === 'string') {
|
|
340
|
-
try {
|
|
341
|
-
const parsed = JSON.parse(value);
|
|
342
|
-
if (!Array.isArray(parsed)) {
|
|
343
|
-
throw new Error(`${key} must be an array`);
|
|
344
|
-
}
|
|
345
|
-
return parsed;
|
|
346
|
-
} catch (e) {
|
|
347
|
-
if (e instanceof SyntaxError) {
|
|
348
|
-
throw new Error(`Invalid JSON for ${key}: ${value}`);
|
|
349
|
-
}
|
|
350
|
-
throw e;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
return value;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
if (key === 'providerSettings') {
|
|
357
|
-
if (typeof value === 'string') {
|
|
358
|
-
try {
|
|
359
|
-
return normalizeProviderSettings(JSON.parse(value));
|
|
360
|
-
} catch {
|
|
361
|
-
throw new Error(`Invalid JSON for providerSettings: ${value}`);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
return normalizeProviderSettings(value);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
if (key === 'defaultProvider') {
|
|
368
|
-
return normalizeProviderName(value);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
return value;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Get parsed Claude command from settings/env
|
|
376
|
-
* Supports space-separated commands like 'ccr code'
|
|
377
|
-
* @returns {{ command: string, args: string[] }}
|
|
378
|
-
*/
|
|
379
|
-
function getClaudeCommand() {
|
|
380
|
-
const settings = loadSettings();
|
|
381
|
-
const raw = process.env.ZEROSHOT_CLAUDE_COMMAND || settings.claudeCommand || 'claude';
|
|
382
|
-
const parts = raw.trim().split(/\s+/);
|
|
383
|
-
return {
|
|
384
|
-
command: parts[0],
|
|
385
|
-
args: parts.slice(1),
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
module.exports = {
|
|
390
|
-
loadSettings,
|
|
391
|
-
saveSettings,
|
|
392
|
-
validateSetting,
|
|
393
|
-
coerceValue,
|
|
394
|
-
DEFAULT_SETTINGS,
|
|
395
|
-
getSettingsFile,
|
|
396
|
-
getClaudeCommand,
|
|
397
|
-
// Model validation exports
|
|
398
|
-
MODEL_HIERARCHY,
|
|
399
|
-
VALID_MODELS,
|
|
400
|
-
validateModelAgainstMax,
|
|
401
|
-
// Backward compatibility: SETTINGS_FILE as getter (reads env var dynamically)
|
|
402
|
-
get SETTINGS_FILE() {
|
|
403
|
-
return getSettingsFile();
|
|
404
|
-
},
|
|
405
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compatibility wrapper for Claude stream-json parsing.
|
|
3
|
-
* Prefer provider-specific parsers in src/providers.
|
|
4
|
-
*/
|
|
5
|
-
const { parseEvent, parseChunk } = require('../src/providers/anthropic/output-parser');
|
|
6
|
-
|
|
7
|
-
module.exports = {
|
|
8
|
-
parseEvent,
|
|
9
|
-
parseChunk,
|
|
10
|
-
};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Fix node-pty spawn-helper permissions.
|
|
4
|
-
*
|
|
5
|
-
* node-pty prebuilds ship with spawn-helper lacking execute permission (mode 644).
|
|
6
|
-
* This causes "posix_spawnp failed" errors on macOS/Linux.
|
|
7
|
-
*
|
|
8
|
-
* Upstream bug: https://github.com/microsoft/node-pty/issues/XXX
|
|
9
|
-
* (File issue if not already reported)
|
|
10
|
-
*
|
|
11
|
-
* This script runs as postinstall to fix it automatically.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const fs = require('fs');
|
|
15
|
-
const path = require('path');
|
|
16
|
-
|
|
17
|
-
// Skip on Windows - chmod doesn't apply
|
|
18
|
-
if (process.platform === 'win32') {
|
|
19
|
-
process.exit(0);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const prebuildsDir = path.join(__dirname, '..', 'node_modules', 'node-pty', 'prebuilds');
|
|
23
|
-
|
|
24
|
-
if (!fs.existsSync(prebuildsDir)) {
|
|
25
|
-
// node-pty not installed yet or using compiled version
|
|
26
|
-
process.exit(0);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
let fixed = 0;
|
|
30
|
-
let errors = 0;
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
const platforms = fs.readdirSync(prebuildsDir).filter(f => {
|
|
34
|
-
try {
|
|
35
|
-
return fs.statSync(path.join(prebuildsDir, f)).isDirectory();
|
|
36
|
-
} catch {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
for (const platform of platforms) {
|
|
42
|
-
// Only fix Unix platforms (darwin, linux)
|
|
43
|
-
if (!platform.startsWith('darwin') && !platform.startsWith('linux')) {
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const helper = path.join(prebuildsDir, platform, 'spawn-helper');
|
|
48
|
-
try {
|
|
49
|
-
if (!fs.existsSync(helper)) continue;
|
|
50
|
-
|
|
51
|
-
const stat = fs.statSync(helper);
|
|
52
|
-
// Check if not executable (missing user execute bit)
|
|
53
|
-
if (!(stat.mode & 0o100)) {
|
|
54
|
-
fs.chmodSync(helper, 0o755);
|
|
55
|
-
fixed++;
|
|
56
|
-
}
|
|
57
|
-
} catch (err) {
|
|
58
|
-
// Log but don't fail install - permission fix is best-effort
|
|
59
|
-
console.warn(`[postinstall] Warning: Could not fix ${helper}: ${err.message}`);
|
|
60
|
-
errors++;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
} catch (err) {
|
|
64
|
-
// Don't fail install on unexpected errors
|
|
65
|
-
console.warn(`[postinstall] Warning: node-pty permission fix failed: ${err.message}`);
|
|
66
|
-
process.exit(0);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (fixed > 0) {
|
|
70
|
-
console.log(`[postinstall] Fixed node-pty spawn-helper permissions (${fixed} platform(s))`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (errors > 0) {
|
|
74
|
-
console.warn(`[postinstall] ${errors} platform(s) could not be fixed - may need manual chmod`);
|
|
75
|
-
}
|