@the-open-engine/zeroshot 5.4.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/CHANGELOG.md +539 -0
- package/LICENSE +21 -0
- package/README.md +508 -0
- package/cli/commands/inspect-render.js +135 -0
- package/cli/commands/inspect.js +294 -0
- package/cli/commands/providers.js +149 -0
- package/cli/index.js +5431 -0
- package/cli/lib/first-run.js +211 -0
- package/cli/lib/update-checker.js +281 -0
- package/cli/message-formatter-utils.js +75 -0
- package/cli/message-formatters-normal.js +275 -0
- package/cli/message-formatters-watch.js +185 -0
- package/cluster-templates/base-templates/debug-workflow.json +422 -0
- package/cluster-templates/base-templates/full-workflow.json +727 -0
- package/cluster-templates/base-templates/heavy-validation.json +272 -0
- package/cluster-templates/base-templates/quick-validation.json +285 -0
- package/cluster-templates/base-templates/single-worker.json +71 -0
- package/cluster-templates/base-templates/worker-validator.json +230 -0
- package/cluster-templates/conductor-bootstrap.json +130 -0
- package/docker/zeroshot-cluster/Dockerfile +153 -0
- package/docker/zeroshot-cluster/pre-baked-deps.json +28 -0
- package/lib/agent-cli-provider/adapters/claude-parser.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/claude-parser.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/claude-parser.js +122 -0
- package/lib/agent-cli-provider/adapters/claude-parser.js.map +1 -0
- package/lib/agent-cli-provider/adapters/claude-recovery.d.ts +15 -0
- package/lib/agent-cli-provider/adapters/claude-recovery.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/claude-recovery.js +165 -0
- package/lib/agent-cli-provider/adapters/claude-recovery.js.map +1 -0
- package/lib/agent-cli-provider/adapters/claude.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/claude.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/claude.js +181 -0
- package/lib/agent-cli-provider/adapters/claude.js.map +1 -0
- package/lib/agent-cli-provider/adapters/codex-parser.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/codex-parser.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/codex-parser.js +192 -0
- package/lib/agent-cli-provider/adapters/codex-parser.js.map +1 -0
- package/lib/agent-cli-provider/adapters/codex.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/codex.js +151 -0
- package/lib/agent-cli-provider/adapters/codex.js.map +1 -0
- package/lib/agent-cli-provider/adapters/common.d.ts +28 -0
- package/lib/agent-cli-provider/adapters/common.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/common.js +71 -0
- package/lib/agent-cli-provider/adapters/common.js.map +1 -0
- package/lib/agent-cli-provider/adapters/gemini.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/gemini.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/gemini.js +176 -0
- package/lib/agent-cli-provider/adapters/gemini.js.map +1 -0
- package/lib/agent-cli-provider/adapters/index.d.ts +9 -0
- package/lib/agent-cli-provider/adapters/index.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/index.js +95 -0
- package/lib/agent-cli-provider/adapters/index.js.map +1 -0
- package/lib/agent-cli-provider/adapters/opencode.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/opencode.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/opencode.js +228 -0
- package/lib/agent-cli-provider/adapters/opencode.js.map +1 -0
- package/lib/agent-cli-provider/contract-actions.d.ts +5 -0
- package/lib/agent-cli-provider/contract-actions.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-actions.js +140 -0
- package/lib/agent-cli-provider/contract-actions.js.map +1 -0
- package/lib/agent-cli-provider/contract-env.d.ts +11 -0
- package/lib/agent-cli-provider/contract-env.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-env.js +113 -0
- package/lib/agent-cli-provider/contract-env.js.map +1 -0
- package/lib/agent-cli-provider/contract-envelope.d.ts +49 -0
- package/lib/agent-cli-provider/contract-envelope.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-envelope.js +52 -0
- package/lib/agent-cli-provider/contract-envelope.js.map +1 -0
- package/lib/agent-cli-provider/contract-errors.d.ts +22 -0
- package/lib/agent-cli-provider/contract-errors.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-errors.js +71 -0
- package/lib/agent-cli-provider/contract-errors.js.map +1 -0
- package/lib/agent-cli-provider/contract-fallback.d.ts +7 -0
- package/lib/agent-cli-provider/contract-fallback.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-fallback.js +102 -0
- package/lib/agent-cli-provider/contract-fallback.js.map +1 -0
- package/lib/agent-cli-provider/contract-invoke.d.ts +5 -0
- package/lib/agent-cli-provider/contract-invoke.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-invoke.js +89 -0
- package/lib/agent-cli-provider/contract-invoke.js.map +1 -0
- package/lib/agent-cli-provider/contract-options.d.ts +3 -0
- package/lib/agent-cli-provider/contract-options.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-options.js +140 -0
- package/lib/agent-cli-provider/contract-options.js.map +1 -0
- package/lib/agent-cli-provider/contract-parse.d.ts +15 -0
- package/lib/agent-cli-provider/contract-parse.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-parse.js +81 -0
- package/lib/agent-cli-provider/contract-parse.js.map +1 -0
- package/lib/agent-cli-provider/contract-support.d.ts +18 -0
- package/lib/agent-cli-provider/contract-support.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-support.js +154 -0
- package/lib/agent-cli-provider/contract-support.js.map +1 -0
- package/lib/agent-cli-provider/contract.d.ts +13 -0
- package/lib/agent-cli-provider/contract.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract.js +30 -0
- package/lib/agent-cli-provider/contract.js.map +1 -0
- package/lib/agent-cli-provider/env-safety.d.ts +11 -0
- package/lib/agent-cli-provider/env-safety.d.ts.map +1 -0
- package/lib/agent-cli-provider/env-safety.js +83 -0
- package/lib/agent-cli-provider/env-safety.js.map +1 -0
- package/lib/agent-cli-provider/errors.d.ts +5 -0
- package/lib/agent-cli-provider/errors.d.ts.map +1 -0
- package/lib/agent-cli-provider/errors.js +115 -0
- package/lib/agent-cli-provider/errors.js.map +1 -0
- package/lib/agent-cli-provider/executable.d.ts +3 -0
- package/lib/agent-cli-provider/executable.d.ts.map +1 -0
- package/lib/agent-cli-provider/executable.js +24 -0
- package/lib/agent-cli-provider/executable.js.map +1 -0
- package/lib/agent-cli-provider/index.d.ts +8 -0
- package/lib/agent-cli-provider/index.d.ts.map +1 -0
- package/lib/agent-cli-provider/index.js +31 -0
- package/lib/agent-cli-provider/index.js.map +1 -0
- package/lib/agent-cli-provider/invoke-evidence.d.ts +4 -0
- package/lib/agent-cli-provider/invoke-evidence.d.ts.map +1 -0
- package/lib/agent-cli-provider/invoke-evidence.js +17 -0
- package/lib/agent-cli-provider/invoke-evidence.js.map +1 -0
- package/lib/agent-cli-provider/json.d.ts +16 -0
- package/lib/agent-cli-provider/json.d.ts.map +1 -0
- package/lib/agent-cli-provider/json.js +110 -0
- package/lib/agent-cli-provider/json.js.map +1 -0
- package/lib/agent-cli-provider/log-prefix.d.ts +2 -0
- package/lib/agent-cli-provider/log-prefix.d.ts.map +1 -0
- package/lib/agent-cli-provider/log-prefix.js +22 -0
- package/lib/agent-cli-provider/log-prefix.js.map +1 -0
- package/lib/agent-cli-provider/process-runner.d.ts +17 -0
- package/lib/agent-cli-provider/process-runner.d.ts.map +1 -0
- package/lib/agent-cli-provider/process-runner.js +89 -0
- package/lib/agent-cli-provider/process-runner.js.map +1 -0
- package/lib/agent-cli-provider/redaction.d.ts +9 -0
- package/lib/agent-cli-provider/redaction.d.ts.map +1 -0
- package/lib/agent-cli-provider/redaction.js +227 -0
- package/lib/agent-cli-provider/redaction.js.map +1 -0
- package/lib/agent-cli-provider/schema.d.ts +5 -0
- package/lib/agent-cli-provider/schema.d.ts.map +1 -0
- package/lib/agent-cli-provider/schema.js +136 -0
- package/lib/agent-cli-provider/schema.js.map +1 -0
- package/lib/agent-cli-provider/single-agent-runtime.d.ts +15 -0
- package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -0
- package/lib/agent-cli-provider/single-agent-runtime.js +228 -0
- package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -0
- package/lib/agent-cli-provider/types.d.ts +194 -0
- package/lib/agent-cli-provider/types.d.ts.map +1 -0
- package/lib/agent-cli-provider/types.js +12 -0
- package/lib/agent-cli-provider/types.js.map +1 -0
- package/lib/completion.js +174 -0
- package/lib/detached-startup.js +220 -0
- package/lib/docker-config.js +220 -0
- package/lib/git-remote-utils.js +165 -0
- package/lib/id-detector.js +55 -0
- package/lib/provider-defaults.js +62 -0
- package/lib/provider-detection.js +59 -0
- package/lib/provider-names.js +57 -0
- package/lib/repo-settings.js +69 -0
- package/lib/settings/claude-auth.js +78 -0
- package/lib/settings.js +542 -0
- package/lib/start-cluster.js +321 -0
- package/lib/stream-json-parser.js +67 -0
- package/package.json +162 -0
- package/scripts/fix-node-pty-permissions.js +75 -0
- package/scripts/record-demo.sh +279 -0
- package/scripts/setup-merge-queue.sh +170 -0
- package/scripts/test-install.sh +40 -0
- package/scripts/validate-templates.js +107 -0
- package/src/agent/agent-config.js +266 -0
- package/src/agent/agent-context-builder.js +189 -0
- package/src/agent/agent-context-sections.js +338 -0
- package/src/agent/agent-context-sources.js +147 -0
- package/src/agent/agent-hook-executor.js +721 -0
- package/src/agent/agent-input-injector.js +141 -0
- package/src/agent/agent-lifecycle.js +982 -0
- package/src/agent/agent-quality-gate-schema.js +93 -0
- package/src/agent/agent-quality-gates-context.js +51 -0
- package/src/agent/agent-stuck-detector.js +256 -0
- package/src/agent/agent-task-executor.js +2028 -0
- package/src/agent/agent-trigger-evaluator.js +67 -0
- package/src/agent/context-metrics.js +160 -0
- package/src/agent/context-pack-builder.js +367 -0
- package/src/agent/context-replay-policy.js +51 -0
- package/src/agent/guidance-queue.js +77 -0
- package/src/agent/output-extraction.js +367 -0
- package/src/agent/output-reformatter.js +175 -0
- package/src/agent/pr-verification.js +653 -0
- package/src/agent/rate-limit-backoff.js +82 -0
- package/src/agent/schema-utils.js +146 -0
- package/src/agent/validation-platform.js +35 -0
- package/src/agent-cli-provider/adapters/claude-parser.ts +133 -0
- package/src/agent-cli-provider/adapters/claude-recovery.ts +203 -0
- package/src/agent-cli-provider/adapters/claude.ts +247 -0
- package/src/agent-cli-provider/adapters/codex-parser.ts +211 -0
- package/src/agent-cli-provider/adapters/codex.ts +217 -0
- package/src/agent-cli-provider/adapters/common.ts +124 -0
- package/src/agent-cli-provider/adapters/gemini.ts +243 -0
- package/src/agent-cli-provider/adapters/index.ts +126 -0
- package/src/agent-cli-provider/adapters/opencode.ts +286 -0
- package/src/agent-cli-provider/contract-actions.ts +150 -0
- package/src/agent-cli-provider/contract-env.ts +111 -0
- package/src/agent-cli-provider/contract-envelope.ts +110 -0
- package/src/agent-cli-provider/contract-errors.ts +66 -0
- package/src/agent-cli-provider/contract-fallback.ts +121 -0
- package/src/agent-cli-provider/contract-invoke.ts +104 -0
- package/src/agent-cli-provider/contract-options.ts +173 -0
- package/src/agent-cli-provider/contract-parse.ts +94 -0
- package/src/agent-cli-provider/contract-support.ts +167 -0
- package/src/agent-cli-provider/contract.ts +56 -0
- package/src/agent-cli-provider/env-safety.ts +82 -0
- package/src/agent-cli-provider/errors.ts +122 -0
- package/src/agent-cli-provider/executable.ts +24 -0
- package/src/agent-cli-provider/index.ts +83 -0
- package/src/agent-cli-provider/invoke-evidence.ts +18 -0
- package/src/agent-cli-provider/json.ts +114 -0
- package/src/agent-cli-provider/log-prefix.ts +20 -0
- package/src/agent-cli-provider/process-runner.ts +145 -0
- package/src/agent-cli-provider/redaction.ts +282 -0
- package/src/agent-cli-provider/schema.ts +115 -0
- package/src/agent-cli-provider/single-agent-runtime.ts +311 -0
- package/src/agent-cli-provider/types.ts +237 -0
- package/src/agent-wrapper.js +615 -0
- package/src/agents/git-pusher-template.js +705 -0
- package/src/attach/attach-client.js +438 -0
- package/src/attach/attach-server.js +543 -0
- package/src/attach/index.js +37 -0
- package/src/attach/protocol.js +220 -0
- package/src/attach/ring-buffer.js +121 -0
- package/src/attach/send-input.js +88 -0
- package/src/attach/socket-discovery.js +267 -0
- package/src/claude-task-runner.js +661 -0
- package/src/config-router.js +89 -0
- package/src/config-validator.js +2202 -0
- package/src/copy-worker.js +43 -0
- package/src/guidance-topics.js +10 -0
- package/src/input-helpers.js +65 -0
- package/src/isolation-manager.js +1734 -0
- package/src/issue-providers/README.md +305 -0
- package/src/issue-providers/azure-devops-provider.js +307 -0
- package/src/issue-providers/base-provider.js +232 -0
- package/src/issue-providers/github-provider.js +210 -0
- package/src/issue-providers/gitlab-provider.js +262 -0
- package/src/issue-providers/index.js +196 -0
- package/src/issue-providers/jira-provider.js +260 -0
- package/src/ledger.js +692 -0
- package/src/lib/gc.js +232 -0
- package/src/lib/safe-exec.js +88 -0
- package/src/logic-engine.js +201 -0
- package/src/message-buffer.js +81 -0
- package/src/message-bus-bridge.js +144 -0
- package/src/message-bus.js +256 -0
- package/src/name-generator.js +232 -0
- package/src/orchestrator.js +3924 -0
- package/src/preflight.js +712 -0
- package/src/process-metrics.js +608 -0
- package/src/providers/anthropic/index.js +3 -0
- package/src/providers/base-provider.js +355 -0
- package/src/providers/capabilities.js +60 -0
- package/src/providers/google/index.js +3 -0
- package/src/providers/index.js +293 -0
- package/src/providers/openai/index.js +3 -0
- package/src/providers/opencode/index.js +3 -0
- package/src/quality-gates.js +143 -0
- package/src/schemas/sub-cluster.js +208 -0
- package/src/state-snapshot.js +398 -0
- package/src/state-snapshotter.js +142 -0
- package/src/status-footer.js +1026 -0
- package/src/sub-cluster-wrapper.js +693 -0
- package/src/task-runner.js +30 -0
- package/src/template-resolver.js +425 -0
- package/src/template-validation/index.js +338 -0
- package/src/template-validation/simulate-consensus-gates.js +324 -0
- package/src/template-validation/simulate-random-topology.js +541 -0
- package/src/template-validation/simulate-two-stage-validation.js +270 -0
- package/src/worktree-claude-config.js +135 -0
- package/src/worktree-tooling-env.js +150 -0
- package/task-lib/attachable-watcher.js +381 -0
- package/task-lib/commands/clean.js +50 -0
- package/task-lib/commands/episodes.js +105 -0
- package/task-lib/commands/get-log-path.js +23 -0
- package/task-lib/commands/kill.js +32 -0
- package/task-lib/commands/list.js +105 -0
- package/task-lib/commands/logs.js +439 -0
- package/task-lib/commands/resume.js +42 -0
- package/task-lib/commands/run.js +57 -0
- package/task-lib/commands/schedule.js +105 -0
- package/task-lib/commands/scheduler-cmd.js +96 -0
- package/task-lib/commands/schedules.js +148 -0
- package/task-lib/commands/status.js +44 -0
- package/task-lib/commands/unschedule.js +16 -0
- package/task-lib/completion.js +9 -0
- package/task-lib/config.js +11 -0
- package/task-lib/name-generator.js +230 -0
- package/task-lib/package.json +3 -0
- package/task-lib/provider-helper-runtime.js +29 -0
- package/task-lib/runner.js +190 -0
- package/task-lib/scheduler.js +252 -0
- package/task-lib/store.js +529 -0
- package/task-lib/watcher.js +305 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-Run Setup Wizard
|
|
3
|
+
*
|
|
4
|
+
* Interactive setup on first use:
|
|
5
|
+
* - Welcome banner
|
|
6
|
+
* - Max model ceiling selection (sonnet/opus/haiku)
|
|
7
|
+
* - Auto-update preference
|
|
8
|
+
* - Marks setup as complete
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const readline = require('readline');
|
|
12
|
+
const { loadSettings, saveSettings } = require('../../lib/settings');
|
|
13
|
+
const { detectProviders } = require('../../src/providers');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Print welcome banner
|
|
17
|
+
*/
|
|
18
|
+
function printWelcome() {
|
|
19
|
+
console.log(`
|
|
20
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
21
|
+
ā ā
|
|
22
|
+
ā Welcome to Zeroshot! ā
|
|
23
|
+
ā Multi-agent orchestration engine ā
|
|
24
|
+
ā ā
|
|
25
|
+
ā Let's configure a few settings to get started. ā
|
|
26
|
+
ā ā
|
|
27
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
28
|
+
`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Create readline interface
|
|
33
|
+
* @returns {readline.Interface}
|
|
34
|
+
*/
|
|
35
|
+
function createReadline() {
|
|
36
|
+
return readline.createInterface({
|
|
37
|
+
input: process.stdin,
|
|
38
|
+
output: process.stdout,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Prompt for provider selection
|
|
44
|
+
* @param {readline.Interface} rl
|
|
45
|
+
* @param {object} detected
|
|
46
|
+
* @returns {Promise<string>}
|
|
47
|
+
*/
|
|
48
|
+
function promptProvider(rl, detected) {
|
|
49
|
+
console.log('\nWhich AI provider would you like to use by default?\n');
|
|
50
|
+
|
|
51
|
+
const available = Object.entries(detected).filter(([_, status]) => status.available);
|
|
52
|
+
|
|
53
|
+
if (available.length === 0) {
|
|
54
|
+
console.log('No AI CLI tools detected. Please install one of:');
|
|
55
|
+
console.log(' - Claude Code: npm install -g @anthropic-ai/claude-code');
|
|
56
|
+
console.log(' - Codex CLI: npm install -g @openai/codex');
|
|
57
|
+
console.log(' - Gemini CLI: npm install -g @google/gemini-cli');
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
available.forEach(([name], i) => {
|
|
62
|
+
console.log(` ${i + 1}) ${name} (installed)`);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return new Promise((resolve) => {
|
|
66
|
+
rl.question('\nChoice [1]: ', (answer) => {
|
|
67
|
+
const idx = parseInt(answer) - 1 || 0;
|
|
68
|
+
resolve(available[idx]?.[0] || available[0][0]);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Prompt for model selection
|
|
75
|
+
* @param {readline.Interface} rl
|
|
76
|
+
* @returns {Promise<string>}
|
|
77
|
+
*/
|
|
78
|
+
function promptModel(rl) {
|
|
79
|
+
return new Promise((resolve) => {
|
|
80
|
+
console.log('What is the maximum Claude model agents can use? (cost ceiling)\n');
|
|
81
|
+
console.log(' 1) sonnet - Agents can use sonnet or haiku (recommended)');
|
|
82
|
+
console.log(' 2) opus - Agents can use opus, sonnet, or haiku');
|
|
83
|
+
console.log(' 3) haiku - Agents can only use haiku (lowest cost)\n');
|
|
84
|
+
|
|
85
|
+
rl.question('Enter 1, 2, or 3 [2]: ', (answer) => {
|
|
86
|
+
const choice = answer.trim() || '2';
|
|
87
|
+
switch (choice) {
|
|
88
|
+
case '2':
|
|
89
|
+
resolve('opus');
|
|
90
|
+
break;
|
|
91
|
+
case '3':
|
|
92
|
+
resolve('haiku');
|
|
93
|
+
break;
|
|
94
|
+
default:
|
|
95
|
+
resolve('sonnet');
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Prompt for auto-update preference
|
|
103
|
+
* @param {readline.Interface} rl
|
|
104
|
+
* @returns {Promise<boolean>}
|
|
105
|
+
*/
|
|
106
|
+
function promptAutoUpdate(rl) {
|
|
107
|
+
return new Promise((resolve) => {
|
|
108
|
+
console.log('\nWould you like zeroshot to check for updates automatically?');
|
|
109
|
+
console.log('(Checks npm registry every 24 hours)\n');
|
|
110
|
+
|
|
111
|
+
rl.question('Enable auto-update checks? [Y/n]: ', (answer) => {
|
|
112
|
+
const normalized = answer.trim().toLowerCase();
|
|
113
|
+
// Default to yes if empty or starts with 'y'
|
|
114
|
+
resolve(normalized === '' || normalized === 'y' || normalized === 'yes');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Print completion message
|
|
121
|
+
* @param {object} settings - Saved settings
|
|
122
|
+
*/
|
|
123
|
+
function printComplete(settings) {
|
|
124
|
+
console.log(`
|
|
125
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
126
|
+
ā Setup complete! ā
|
|
127
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
128
|
+
|
|
129
|
+
Your settings:
|
|
130
|
+
⢠Provider: ${settings.defaultProvider}
|
|
131
|
+
⢠Max model: ${settings.maxModel} (Claude ceiling)
|
|
132
|
+
⢠Auto-updates: ${settings.autoCheckUpdates ? 'enabled' : 'disabled'}
|
|
133
|
+
|
|
134
|
+
Change anytime with: zeroshot settings set <key> <value>
|
|
135
|
+
|
|
136
|
+
Get started:
|
|
137
|
+
zeroshot run "Fix the bug in auth.js"
|
|
138
|
+
zeroshot run 123 (GitHub issue number)
|
|
139
|
+
zeroshot --help
|
|
140
|
+
|
|
141
|
+
`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Check if first-run setup is needed
|
|
146
|
+
* @param {object} settings - Current settings
|
|
147
|
+
* @returns {boolean}
|
|
148
|
+
*/
|
|
149
|
+
function detectFirstRun(settings) {
|
|
150
|
+
return !settings.firstRunComplete;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Main entry point - run first-time setup if needed
|
|
155
|
+
* @param {object} options
|
|
156
|
+
* @param {boolean} options.quiet - Skip interactive prompts
|
|
157
|
+
* @returns {Promise<boolean>} True if setup was run
|
|
158
|
+
*/
|
|
159
|
+
async function checkFirstRun(options = {}) {
|
|
160
|
+
const settings = loadSettings();
|
|
161
|
+
|
|
162
|
+
// Already completed setup
|
|
163
|
+
if (!detectFirstRun(settings)) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Quiet mode - use defaults, mark complete
|
|
168
|
+
if (options.quiet) {
|
|
169
|
+
settings.firstRunComplete = true;
|
|
170
|
+
saveSettings(settings);
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Interactive setup
|
|
175
|
+
printWelcome();
|
|
176
|
+
|
|
177
|
+
const rl = createReadline();
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
const detected = await detectProviders();
|
|
181
|
+
const provider = await promptProvider(rl, detected);
|
|
182
|
+
settings.defaultProvider = provider;
|
|
183
|
+
|
|
184
|
+
// Model ceiling selection
|
|
185
|
+
const model = await promptModel(rl);
|
|
186
|
+
settings.maxModel = model;
|
|
187
|
+
|
|
188
|
+
// Auto-update preference
|
|
189
|
+
const autoUpdate = await promptAutoUpdate(rl);
|
|
190
|
+
settings.autoCheckUpdates = autoUpdate;
|
|
191
|
+
|
|
192
|
+
// Mark complete
|
|
193
|
+
settings.firstRunComplete = true;
|
|
194
|
+
saveSettings(settings);
|
|
195
|
+
|
|
196
|
+
// Print completion
|
|
197
|
+
printComplete(settings);
|
|
198
|
+
|
|
199
|
+
return true;
|
|
200
|
+
} finally {
|
|
201
|
+
rl.close();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
module.exports = {
|
|
206
|
+
checkFirstRun,
|
|
207
|
+
// Exported for testing
|
|
208
|
+
detectFirstRun,
|
|
209
|
+
printWelcome,
|
|
210
|
+
printComplete,
|
|
211
|
+
};
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update Checker - Checks npm registry for newer versions
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - 24-hour check interval (avoids registry spam)
|
|
6
|
+
* - 5-second timeout (non-blocking if offline)
|
|
7
|
+
* - Interactive prompt for manual update
|
|
8
|
+
* - Respects quiet mode (no prompts in CI/scripts)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const https = require('https');
|
|
12
|
+
const { spawn } = require('child_process');
|
|
13
|
+
const readline = require('readline');
|
|
14
|
+
const { loadSettings, saveSettings } = require('../../lib/settings');
|
|
15
|
+
|
|
16
|
+
// 24 hours in milliseconds
|
|
17
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
18
|
+
|
|
19
|
+
// Timeout for npm registry fetch (5 seconds)
|
|
20
|
+
const FETCH_TIMEOUT_MS = 5000;
|
|
21
|
+
|
|
22
|
+
// npm registry URL
|
|
23
|
+
const REGISTRY_URL = 'https://registry.npmjs.org/@the-open-engine/zeroshot/latest';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get current package version
|
|
27
|
+
* @returns {string}
|
|
28
|
+
*/
|
|
29
|
+
function getCurrentVersion() {
|
|
30
|
+
const pkg = require('../../package.json');
|
|
31
|
+
return pkg.version;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Compare semver versions
|
|
36
|
+
* @param {string} current - Current version (e.g., "1.5.0")
|
|
37
|
+
* @param {string} latest - Latest version (e.g., "1.6.0")
|
|
38
|
+
* @returns {boolean} True if latest > current
|
|
39
|
+
*/
|
|
40
|
+
function isNewerVersion(current, latest) {
|
|
41
|
+
const currentParts = current.split('.').map(Number);
|
|
42
|
+
const latestParts = latest.split('.').map(Number);
|
|
43
|
+
|
|
44
|
+
for (let i = 0; i < 3; i++) {
|
|
45
|
+
const c = currentParts[i] || 0;
|
|
46
|
+
const l = latestParts[i] || 0;
|
|
47
|
+
if (l > c) return true;
|
|
48
|
+
if (l < c) return false;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Fetch latest version from npm registry
|
|
55
|
+
* @returns {Promise<string|null>} Latest version or null on failure
|
|
56
|
+
*/
|
|
57
|
+
function fetchLatestVersion() {
|
|
58
|
+
return new Promise((resolve) => {
|
|
59
|
+
const req = https.get(REGISTRY_URL, { timeout: FETCH_TIMEOUT_MS }, (res) => {
|
|
60
|
+
if (res.statusCode !== 200) {
|
|
61
|
+
resolve(null);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let data = '';
|
|
66
|
+
res.on('data', (chunk) => {
|
|
67
|
+
data += chunk;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
res.on('end', () => {
|
|
71
|
+
try {
|
|
72
|
+
const json = JSON.parse(data);
|
|
73
|
+
resolve(json.version || null);
|
|
74
|
+
} catch {
|
|
75
|
+
resolve(null);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
req.on('error', () => {
|
|
81
|
+
resolve(null);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
req.on('timeout', () => {
|
|
85
|
+
req.destroy();
|
|
86
|
+
resolve(null);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Additional safety timeout
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
req.destroy();
|
|
92
|
+
resolve(null);
|
|
93
|
+
}, FETCH_TIMEOUT_MS + 1000);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Prompt user for update confirmation
|
|
99
|
+
* @param {string} currentVersion
|
|
100
|
+
* @param {string} latestVersion
|
|
101
|
+
* @returns {Promise<boolean>} True if user wants to update
|
|
102
|
+
*/
|
|
103
|
+
function promptForUpdate(currentVersion, latestVersion) {
|
|
104
|
+
return new Promise((resolve) => {
|
|
105
|
+
const rl = readline.createInterface({
|
|
106
|
+
input: process.stdin,
|
|
107
|
+
output: process.stdout,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
console.log(`\nš¦ Update available: ${currentVersion} ā ${latestVersion}`);
|
|
111
|
+
rl.question(' Install now? [y/N] ', (answer) => {
|
|
112
|
+
rl.close();
|
|
113
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Check if we have write permission to npm global directory
|
|
120
|
+
* @returns {boolean} True if we can write to npm global prefix
|
|
121
|
+
*/
|
|
122
|
+
function canWriteToNpmGlobal() {
|
|
123
|
+
const { execSync } = require('child_process');
|
|
124
|
+
const fs = require('fs');
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
// Get npm global prefix (e.g., /usr/lib or /home/user/.nvm/versions/node/...)
|
|
128
|
+
const prefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
|
|
129
|
+
const globalModulesDir = require('path').join(prefix, 'lib', 'node_modules');
|
|
130
|
+
|
|
131
|
+
// Check if directory exists and is writable
|
|
132
|
+
fs.accessSync(globalModulesDir, fs.constants.W_OK);
|
|
133
|
+
return true;
|
|
134
|
+
} catch {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Run npm install to update the package
|
|
141
|
+
* @returns {Promise<boolean>} True if update succeeded
|
|
142
|
+
*/
|
|
143
|
+
function runUpdate() {
|
|
144
|
+
return new Promise((resolve) => {
|
|
145
|
+
// Check permissions BEFORE attempting update
|
|
146
|
+
if (!canWriteToNpmGlobal()) {
|
|
147
|
+
console.log('\nā ļø Cannot auto-update: no write permission to npm global directory.');
|
|
148
|
+
console.log(' Run manually with sudo:');
|
|
149
|
+
console.log(' sudo npm install -g @the-open-engine/zeroshot@latest\n');
|
|
150
|
+
resolve(false);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log('\nš„ Installing update...');
|
|
155
|
+
|
|
156
|
+
const proc = spawn('npm', ['install', '-g', '@the-open-engine/zeroshot@latest'], {
|
|
157
|
+
stdio: 'inherit',
|
|
158
|
+
shell: true,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
proc.on('close', (code) => {
|
|
162
|
+
if (code === 0) {
|
|
163
|
+
console.log('ā
Update installed successfully!');
|
|
164
|
+
console.log(' Restart zeroshot to use the new version.\n');
|
|
165
|
+
resolve(true);
|
|
166
|
+
} else {
|
|
167
|
+
console.log('ā Update failed. Try manually:');
|
|
168
|
+
console.log(' sudo npm install -g @the-open-engine/zeroshot@latest\n');
|
|
169
|
+
resolve(false);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
proc.on('error', () => {
|
|
174
|
+
console.log('ā Update failed. Try manually:');
|
|
175
|
+
console.log(' sudo npm install -g @the-open-engine/zeroshot@latest\n');
|
|
176
|
+
resolve(false);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Check if update check should run
|
|
183
|
+
* @param {object} settings - Current settings
|
|
184
|
+
* @returns {boolean}
|
|
185
|
+
*/
|
|
186
|
+
function shouldCheckForUpdates(settings) {
|
|
187
|
+
// Disabled by user
|
|
188
|
+
if (!settings.autoCheckUpdates) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Never checked before
|
|
193
|
+
if (!settings.lastUpdateCheckAt) {
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Check if 24 hours have passed
|
|
198
|
+
const elapsed = Date.now() - settings.lastUpdateCheckAt;
|
|
199
|
+
return elapsed >= CHECK_INTERVAL_MS;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Main entry point - check for updates
|
|
204
|
+
* @param {object} options
|
|
205
|
+
* @param {boolean} options.quiet - Skip interactive prompts
|
|
206
|
+
* @returns {Promise<void>}
|
|
207
|
+
*/
|
|
208
|
+
async function checkForUpdates(options = {}) {
|
|
209
|
+
const settings = loadSettings();
|
|
210
|
+
|
|
211
|
+
// Skip check if not due
|
|
212
|
+
if (!shouldCheckForUpdates(settings)) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const currentVersion = getCurrentVersion();
|
|
217
|
+
const latestVersion = await fetchLatestVersion();
|
|
218
|
+
|
|
219
|
+
// Update last check timestamp regardless of result
|
|
220
|
+
settings.lastUpdateCheckAt = Date.now();
|
|
221
|
+
saveSettings(settings);
|
|
222
|
+
|
|
223
|
+
// Network failure - silently skip
|
|
224
|
+
if (!latestVersion) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// No update available
|
|
229
|
+
if (!isNewerVersion(currentVersion, latestVersion)) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Already notified about this version
|
|
234
|
+
if (settings.lastSeenVersion === latestVersion) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Update lastSeenVersion so we don't nag about the same version
|
|
239
|
+
settings.lastSeenVersion = latestVersion;
|
|
240
|
+
saveSettings(settings);
|
|
241
|
+
|
|
242
|
+
// Check write permissions upfront
|
|
243
|
+
const hasWriteAccess = canWriteToNpmGlobal();
|
|
244
|
+
|
|
245
|
+
// Quiet mode - just inform, no prompt
|
|
246
|
+
if (options.quiet) {
|
|
247
|
+
console.log(`š¦ Update available: ${currentVersion} ā ${latestVersion}`);
|
|
248
|
+
if (hasWriteAccess) {
|
|
249
|
+
console.log(' Run: npm install -g @the-open-engine/zeroshot@latest\n');
|
|
250
|
+
} else {
|
|
251
|
+
console.log(' Run: sudo npm install -g @the-open-engine/zeroshot@latest\n');
|
|
252
|
+
}
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// No write permission - inform user but don't offer interactive prompt
|
|
257
|
+
// (they'd say yes then get an error, which is frustrating UX)
|
|
258
|
+
if (!hasWriteAccess) {
|
|
259
|
+
console.log(`\nš¦ Update available: ${currentVersion} ā ${latestVersion}`);
|
|
260
|
+
console.log(' Run: sudo npm install -g @the-open-engine/zeroshot@latest\n');
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Interactive mode - prompt for update (only if we have write access)
|
|
265
|
+
const wantsUpdate = await promptForUpdate(currentVersion, latestVersion);
|
|
266
|
+
if (wantsUpdate) {
|
|
267
|
+
await runUpdate();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
module.exports = {
|
|
272
|
+
checkForUpdates,
|
|
273
|
+
// Exported for testing and CLI update command
|
|
274
|
+
getCurrentVersion,
|
|
275
|
+
isNewerVersion,
|
|
276
|
+
fetchLatestVersion,
|
|
277
|
+
runUpdate,
|
|
278
|
+
shouldCheckForUpdates,
|
|
279
|
+
canWriteToNpmGlobal,
|
|
280
|
+
CHECK_INTERVAL_MS,
|
|
281
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message formatting utilities for CLI output
|
|
3
|
+
* Extracted from index.js to reduce complexity
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Get color for sender based on consistent hashing
|
|
10
|
+
* @param {string} sender - Sender name
|
|
11
|
+
* @returns {Function} Chalk color function
|
|
12
|
+
*/
|
|
13
|
+
function getColorForSender(sender) {
|
|
14
|
+
const colors = [chalk.cyan, chalk.magenta, chalk.yellow, chalk.green, chalk.blue];
|
|
15
|
+
let hash = 0;
|
|
16
|
+
for (let i = 0; i < sender.length; i++) {
|
|
17
|
+
hash = (hash << 5) - hash + sender.charCodeAt(i);
|
|
18
|
+
hash = hash & hash;
|
|
19
|
+
}
|
|
20
|
+
return colors[Math.abs(hash) % colors.length];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Build message prefix with timestamp, sender, and optional cluster ID
|
|
25
|
+
* @param {Object} msg - Message object
|
|
26
|
+
* @param {boolean} showClusterId - Whether to show cluster ID
|
|
27
|
+
* @param {boolean} isActive - Whether cluster is active
|
|
28
|
+
* @returns {string} Formatted prefix
|
|
29
|
+
*/
|
|
30
|
+
function buildMessagePrefix(msg, showClusterId, isActive) {
|
|
31
|
+
const color = isActive ? getColorForSender(msg.sender) : chalk.dim;
|
|
32
|
+
|
|
33
|
+
let senderLabel = msg.sender;
|
|
34
|
+
if (showClusterId && msg.cluster_id) {
|
|
35
|
+
senderLabel = `${msg.cluster_id}/${msg.sender}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const modelSuffix = msg.sender_model ? chalk.dim(` [${msg.sender_model}]`) : '';
|
|
39
|
+
return color(`${senderLabel.padEnd(showClusterId ? 25 : 15)} |`) + modelSuffix;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Build cluster prefix for watch mode
|
|
44
|
+
* @param {string} clusterId - Cluster ID
|
|
45
|
+
* @param {boolean} isActive - Whether cluster is active
|
|
46
|
+
* @returns {string} Formatted prefix
|
|
47
|
+
*/
|
|
48
|
+
function buildClusterPrefix(clusterId, isActive) {
|
|
49
|
+
return isActive
|
|
50
|
+
? chalk.white(`${clusterId.padEnd(20)} |`)
|
|
51
|
+
: chalk.dim(`${clusterId.padEnd(20)} |`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Parse and normalize data fields (handles string JSON)
|
|
56
|
+
* @param {string|Array} data - Data to parse
|
|
57
|
+
* @returns {Array} Parsed array
|
|
58
|
+
*/
|
|
59
|
+
function parseDataField(data) {
|
|
60
|
+
if (typeof data === 'string') {
|
|
61
|
+
try {
|
|
62
|
+
return JSON.parse(data);
|
|
63
|
+
} catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return Array.isArray(data) ? data : [];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = {
|
|
71
|
+
getColorForSender,
|
|
72
|
+
buildMessagePrefix,
|
|
73
|
+
buildClusterPrefix,
|
|
74
|
+
parseDataField,
|
|
75
|
+
};
|