@orchestree/cli 2.2.0 → 3.5.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.
@@ -0,0 +1,2 @@
1
+ import { type CliIO } from '@orchestree/cli-core';
2
+ export declare function gatewaysCommand(args: string[], io: CliIO): Promise<number>;
@@ -0,0 +1,57 @@
1
+ // `crow gateways` — list model gateways and run setup wizards.
2
+ import { listGateways, loadCliConfig, systemExec, vertexSetup, } from '@orchestree/cli-core';
3
+ function pad(value, width) {
4
+ return value.length >= width ? value : value + ' '.repeat(width - value.length);
5
+ }
6
+ async function listCommand(io) {
7
+ const config = await loadCliConfig();
8
+ for (const gw of listGateways(config)) {
9
+ io.out(`${pad(gw.id, 15)} ${pad(gw.status, 13)} ${gw.detail}`);
10
+ }
11
+ return 0;
12
+ }
13
+ function readFlag(args, name) {
14
+ const i = args.indexOf(name);
15
+ if (i === -1)
16
+ return { value: null, rest: args };
17
+ const value = args[i + 1];
18
+ if (!value || value.startsWith('--'))
19
+ return { value: null, rest: args };
20
+ return { value, rest: [...args.slice(0, i), ...args.slice(i + 2)] };
21
+ }
22
+ async function setupCommand(args, io) {
23
+ const id = args[0];
24
+ switch (id) {
25
+ case 'vertex': {
26
+ const { value: project, rest: afterProject } = readFlag(args.slice(1), '--project');
27
+ const { value: region, rest } = readFlag(afterProject, '--region');
28
+ const enableAnthropicModels = rest.includes('--enable-anthropic-models');
29
+ return vertexSetup({
30
+ project: project ?? undefined,
31
+ region: region ?? undefined,
32
+ enableAnthropicModels,
33
+ io,
34
+ exec: systemExec,
35
+ });
36
+ }
37
+ case 'openrouter':
38
+ io.out('OpenRouter is already live — it is routed server-side via api.orchestree.ai and needs no local setup.');
39
+ return 0;
40
+ case 'azure_foundry':
41
+ // Honest-Beta: unbuilt capability says so and exits non-zero.
42
+ io.err('Azure AI Foundry support has not shipped yet — nothing was configured.');
43
+ return 1;
44
+ default:
45
+ io.err(`unknown gateway \`${id ?? ''}\` — known gateways: openrouter, vertex, azure_foundry`);
46
+ return 2;
47
+ }
48
+ }
49
+ export async function gatewaysCommand(args, io) {
50
+ const sub = args[0];
51
+ if (!sub || sub === 'list')
52
+ return listCommand(io);
53
+ if (sub === 'setup')
54
+ return setupCommand(args.slice(1), io);
55
+ io.err(`unknown gateways subcommand \`${sub}\` — use \`crow gateways\` or \`crow gateways setup <id>\``);
56
+ return 2;
57
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1 @@
1
- #!/usr/bin/env node
2
1
  export {};
package/dist/index.js CHANGED
@@ -1,88 +1,171 @@
1
- #!/usr/bin/env node
2
- // @orchestree/cli Official CLI for the Orchestree platform
3
- import { loginCommand } from './commands/login.js';
4
- import { chatCommand } from './commands/chat.js';
5
- import { agentsCommand } from './commands/agents.js';
6
- import { statusCommand } from './commands/status.js';
7
- import { deployCommand } from './commands/deploy.js';
8
- import { registryCommand } from './commands/registry.js';
9
- import { runCommand, orchestrateCommand } from './commands/run.js';
10
- const args = process.argv.slice(2);
11
- const command = args[0];
12
- const commandArgs = args.slice(1);
13
- async function main() {
14
- switch (command) {
15
- case 'login':
16
- await loginCommand(commandArgs);
17
- break;
18
- case 'chat':
19
- await chatCommand(commandArgs);
20
- break;
21
- case 'agents':
22
- await agentsCommand(commandArgs);
23
- break;
24
- case 'status':
25
- await statusCommand(commandArgs);
26
- break;
27
- case 'deploy':
28
- await deployCommand(commandArgs);
29
- break;
30
- case 'registry':
31
- await registryCommand(commandArgs);
32
- break;
33
- case 'run':
34
- await runCommand(commandArgs);
35
- break;
36
- case 'orchestrate':
37
- await orchestrateCommand(commandArgs);
38
- break;
39
- case 'help':
40
- case '--help':
41
- case '-h':
42
- case undefined:
43
- printHelp();
44
- break;
45
- case 'version':
46
- case '--version':
47
- case '-v':
48
- console.log('orchestree v2.2.0');
49
- break;
50
- default:
51
- console.error(`Unknown command: ${command}`);
52
- printHelp();
53
- process.exit(1);
54
- }
55
- }
56
- function printHelp() {
57
- console.log(`
58
- Orchestree CLI v2.2.0
1
+ // crow — the CrowCode CLI, the platform front door in your terminal.
2
+ // (`orchestree` remains as an alias for one major version.)
3
+ //
4
+ // crow login [--stdin] [--api <base>] sign in with an API key
5
+ // crow logout clear every credential backend
6
+ // crow whoami org · key name · scope
7
+ // crow gateways [setup <id>] model gateway status + setup
8
+ // crow crowcode [...] the CrowCode coding agent
9
+ // crow crowgent [...] fleet CLI (not shipped yet)
10
+ import { spawn } from 'node:child_process';
11
+ import { createRequire } from 'node:module';
12
+ import { readFileSync } from 'node:fs';
13
+ import { DEFAULT_API_BASE, crowPaint, loginCommand, logoutCommand, terminalIO, whoamiCommand, } from '@orchestree/cli-core';
14
+ import { gatewaysCommand } from './gateways.js';
15
+ import { completionsCommand, doctorCommand, updateCommand } from './maintenance.js';
16
+ // Same words on every terminal — crowPaint degrades to plain text when
17
+ // stdout is not a TTY or NO_COLOR is set, so piped `crow --help` stays clean.
18
+ function renderHelp() {
19
+ const p = crowPaint();
20
+ const cmd = (s) => p.accent(s);
21
+ const dim = (s) => p.dim(s);
22
+ return `${p.accentBright(p.bold('CrowCode CLI (crow)'))} — The Everything Platform in your terminal
23
+
24
+ ${p.bold('usage:')}
25
+ ${cmd('crow')} launch the CrowCode coding agent
26
+ ${cmd('crow login')} [--stdin] [--api <base>] sign in with an Orchestree API key
27
+ ${dim('(hidden prompt; --stdin reads the key from a pipe)')}
28
+ ${cmd('crow logout')} sign out — clears every credential backend
29
+ ${cmd('crow whoami')} show org · key name · scope for the active credential
30
+ ${cmd('crow gateways')} list model gateways and their status
31
+ ${cmd('crow gateways setup')} <id> [--project <p>] [--region <r>]
32
+ configure a gateway (vertex)
33
+ ${cmd('crow crowcode')} [args...] launch the CrowCode coding agent
34
+ ${cmd('crow crowgent')} [args...] fleet CLI — not shipped yet
35
+ ${cmd('crow --version')} | ${cmd('crow --help')}
59
36
 
60
- Usage: orchestree <command> [options]
37
+ ${p.bold('agent shortcuts')} ${dim('(forwarded to the CrowCode agent)')}:
38
+ ${cmd('crow')} "fix the failing test" one-shot: run the task, print, exit
39
+ ${cmd('crow -p')} "prompt" [--output-format plain|json|streaming-json]
40
+ ${cmd('crow -c')} | ${cmd('crow -r')} [<id>] continue / resume a session
41
+ ${cmd('crow models')} list model tiers
42
+ ${cmd('crow sessions')} [search <q> | delete <id>]
43
+ ${cmd('crow export')} <session-id> [file.md] session transcript as Markdown
61
44
 
62
- Commands:
63
- login [api-key] Save API key to config
64
- chat "message" [--agent <slug>] Chat with an agent
65
- agents list List your agents
66
- agents types [b2c|b2b] List available agent types
67
- agents create <slug> [name] Create a new agent
68
- agents get <id> Get agent details
69
- status Agent heartbeat overview
70
- deploy <agent-id> <channel> Deploy agent to channel
71
- registry search [options] Search 11K+ agent registry
72
- registry info <slug> Get agent details from registry
73
- registry stats Show registry statistics
74
- run <slug> "message" [--stream] Execute a specific agent
75
- orchestrate "message" [--stream] Auto-orchestrate with best agent
76
- help Show this help
77
- version Show version
45
+ ${p.bold('maintenance:')}
46
+ ${cmd('crow update')} [--check] update to the latest release
47
+ ${cmd('crow doctor')} diagnose the install (PATH shadowing, CDN, API)
48
+ ${cmd('crow completions')} <zsh|bash> print shell completions
78
49
 
79
- Environment:
80
- ORCHESTREE_API_KEY API key (overrides config file)
50
+ ${p.bold('auth notes:')}
51
+ ${dim('·')} keys are stored in the OS keychain (0600 file fallback with a warning)
52
+ ${dim('·')} ORCHESTREE_API_KEY overrides stored credentials — CI only; any agent
53
+ subprocess this CLI spawns can read the environment
54
+ ${dim('·')} the key is never accepted as a command-line argument
81
55
 
82
- Config: ~/.orchestree/config.json
83
- `);
56
+ ${dim('alias: `orchestree` runs this same CLI (kept for one major version)')}
57
+ `;
58
+ }
59
+ function versionString() {
60
+ try {
61
+ const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
62
+ return pkg.version ?? '0.0.0';
63
+ }
64
+ catch {
65
+ return '0.0.0';
66
+ }
67
+ }
68
+ function readFlag(args, name) {
69
+ const i = args.indexOf(name);
70
+ if (i === -1)
71
+ return { value: null, rest: args };
72
+ const value = args[i + 1];
73
+ if (!value || value.startsWith('--'))
74
+ return { value: null, rest: args };
75
+ return { value, rest: [...args.slice(0, i), ...args.slice(i + 2)] };
76
+ }
77
+ async function runCrowcode(args) {
78
+ const require = createRequire(import.meta.url);
79
+ let entry;
80
+ try {
81
+ entry = require.resolve('@orchestree/crowcode-cli/bin/crowcode.js');
82
+ }
83
+ catch {
84
+ process.stderr.write('crowcode is not installed alongside this CLI — run `npm i -g @orchestree/cli`\n');
85
+ return 1;
86
+ }
87
+ return new Promise((resolve) => {
88
+ const child = spawn(process.execPath, [entry, ...args], { stdio: 'inherit' });
89
+ child.on('close', (code) => resolve(code ?? 1));
90
+ });
91
+ }
92
+ async function main() {
93
+ const argv = process.argv.slice(2);
94
+ const cmd = argv[0];
95
+ const io = terminalIO();
96
+ if (!cmd) {
97
+ // Bare `crow` is the product: launch the CrowCode coding agent.
98
+ process.exitCode = await runCrowcode([]);
99
+ return;
100
+ }
101
+ if (cmd === '--help' || cmd === '-h' || cmd === 'help') {
102
+ process.stdout.write(renderHelp());
103
+ return;
104
+ }
105
+ if (cmd === '--version' || cmd === '-v' || cmd === 'version') {
106
+ process.stdout.write(`crow ${versionString()}\n`);
107
+ return;
108
+ }
109
+ switch (cmd) {
110
+ case 'login': {
111
+ const { value: apiBase, rest } = readFlag(argv.slice(1), '--api');
112
+ const stdin = rest.includes('--stdin');
113
+ const leftovers = rest.filter((a) => a !== '--stdin');
114
+ if (leftovers.length > 0) {
115
+ // The key itself is NEVER accepted via argv.
116
+ io.err('crow login does not accept the key as an argument — it would leak into shell history and process lists.');
117
+ io.err('Use the hidden prompt (`crow login`) or pipe it: `crow login --stdin < keyfile`');
118
+ process.exitCode = 2;
119
+ return;
120
+ }
121
+ process.exitCode = await loginCommand({
122
+ apiBase: apiBase ?? DEFAULT_API_BASE,
123
+ stdin,
124
+ io,
125
+ });
126
+ return;
127
+ }
128
+ case 'logout':
129
+ process.exitCode = await logoutCommand({ apiBase: DEFAULT_API_BASE, io });
130
+ return;
131
+ case 'whoami': {
132
+ const { value: apiBase } = readFlag(argv.slice(1), '--api');
133
+ process.exitCode = await whoamiCommand({ apiBase: apiBase ?? DEFAULT_API_BASE, io });
134
+ return;
135
+ }
136
+ case 'gateways':
137
+ process.exitCode = await gatewaysCommand(argv.slice(1), io);
138
+ return;
139
+ case 'crowcode':
140
+ process.exitCode = await runCrowcode(argv.slice(1));
141
+ return;
142
+ case 'models':
143
+ case 'sessions':
144
+ case 'export':
145
+ // Session/model management lives in the agent — forward verbatim.
146
+ process.exitCode = await runCrowcode(argv);
147
+ return;
148
+ case 'update':
149
+ process.exitCode = await updateCommand(argv.slice(1), versionString(), io);
150
+ return;
151
+ case 'doctor':
152
+ process.exitCode = await doctorCommand(versionString(), io);
153
+ return;
154
+ case 'completions':
155
+ process.exitCode = completionsCommand(argv[1], io);
156
+ return;
157
+ case 'crowgent':
158
+ // Honest-Beta: unbuilt capability says so and exits non-zero.
159
+ io.err('the crowgent fleet CLI has not shipped yet (Wave D of the CLI suite) — nothing was run');
160
+ process.exitCode = 1;
161
+ return;
162
+ default:
163
+ // Everything else — prompts (`crow "fix the test"`) and agent flags
164
+ // (`crow -p … --output-format json`, `crow -c`) — is the agent's.
165
+ process.exitCode = await runCrowcode(argv);
166
+ }
84
167
  }
85
168
  main().catch((err) => {
86
- console.error('Fatal error:', err.message);
169
+ process.stderr.write(`${err.message}\n`);
87
170
  process.exit(1);
88
171
  });
@@ -0,0 +1,10 @@
1
+ import { type CliIO } from '@orchestree/cli-core';
2
+ export declare const CDN_LATEST_URL = "https://media.orchestree.ai/cli/latest";
3
+ export declare const INSTALLER_URL = "https://orchestree.ai/crow";
4
+ /** Numeric semver compare: >0 when a is newer than b. */
5
+ export declare function compareVersions(a: string, b: string): number;
6
+ /** Every `crow` executable reachable through PATH, in PATH order. */
7
+ export declare function pathShadows(binName?: string): string[];
8
+ export declare function updateCommand(args: string[], currentVersion: string, io: CliIO): Promise<number>;
9
+ export declare function doctorCommand(currentVersion: string, io: CliIO): Promise<number>;
10
+ export declare function completionsCommand(shell: string | undefined, io: CliIO): number;
@@ -0,0 +1,217 @@
1
+ // Self-maintenance: `crow update`, `crow doctor`, `crow completions`.
2
+ // Everything reports what it actually observed — no simulated checks.
3
+ import { spawn } from 'node:child_process';
4
+ import { accessSync, constants, realpathSync } from 'node:fs';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { DEFAULT_API_BASE, crowPaint } from '@orchestree/cli-core';
9
+ export const CDN_LATEST_URL = 'https://media.orchestree.ai/cli/latest';
10
+ export const INSTALLER_URL = 'https://orchestree.ai/crow';
11
+ async function fetchText(url, timeoutMs = 8_000) {
12
+ const res = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });
13
+ if (!res.ok)
14
+ throw new Error(`${url} → HTTP ${res.status}`);
15
+ return (await res.text()).trim();
16
+ }
17
+ /** Numeric semver compare: >0 when a is newer than b. */
18
+ export function compareVersions(a, b) {
19
+ const pa = a.split('.').map((n) => Number.parseInt(n, 10) || 0);
20
+ const pb = b.split('.').map((n) => Number.parseInt(n, 10) || 0);
21
+ for (let i = 0; i < 3; i++) {
22
+ const d = (pa[i] ?? 0) - (pb[i] ?? 0);
23
+ if (d !== 0)
24
+ return d;
25
+ }
26
+ return 0;
27
+ }
28
+ /** The real on-disk home of the code that is currently running. */
29
+ function installOrigin() {
30
+ try {
31
+ return realpathSync(fileURLToPath(import.meta.url));
32
+ }
33
+ catch {
34
+ return process.argv[1] ?? '(unknown)';
35
+ }
36
+ }
37
+ /** Every `crow` executable reachable through PATH, in PATH order. */
38
+ export function pathShadows(binName = 'crow') {
39
+ const dirs = (process.env.PATH ?? '').split(path.delimiter).filter(Boolean);
40
+ const found = [];
41
+ for (const dir of dirs) {
42
+ const candidate = path.join(dir, binName);
43
+ try {
44
+ accessSync(candidate, constants.X_OK);
45
+ const real = realpathSync(candidate);
46
+ if (!found.includes(real))
47
+ found.push(real);
48
+ }
49
+ catch {
50
+ // not here — keep walking PATH
51
+ }
52
+ }
53
+ return found;
54
+ }
55
+ export async function updateCommand(args, currentVersion, io) {
56
+ const checkOnly = args.includes('--check');
57
+ let latest;
58
+ try {
59
+ latest = await fetchText(CDN_LATEST_URL);
60
+ }
61
+ catch (err) {
62
+ io.err(`could not reach the release CDN (${CDN_LATEST_URL}): ${err.message}`);
63
+ return 1;
64
+ }
65
+ if (!/^\d+\.\d+\.\d+$/.test(latest)) {
66
+ io.err(`release CDN returned an unexpected version pointer: ${JSON.stringify(latest.slice(0, 40))}`);
67
+ return 1;
68
+ }
69
+ const behind = compareVersions(latest, currentVersion) > 0;
70
+ if (!behind) {
71
+ io.out(`crow ${currentVersion} is up to date (latest: ${latest})`);
72
+ return 0;
73
+ }
74
+ io.out(`update available: crow ${currentVersion} → ${latest}`);
75
+ if (checkOnly) {
76
+ io.out('run `crow update` to install it');
77
+ return 0;
78
+ }
79
+ const origin = installOrigin();
80
+ const crowHome = path.join(os.homedir(), '.crow');
81
+ if (!origin.startsWith(crowHome)) {
82
+ io.err(`note: this copy runs from ${origin}, not ${crowHome} — the installer refreshes ${crowHome}; run \`crow doctor\` if the old copy keeps winning on PATH`);
83
+ }
84
+ io.out(`running the installer: curl -fsSL ${INSTALLER_URL} | sh`);
85
+ return new Promise((resolve) => {
86
+ const child = spawn('sh', ['-c', `curl -fsSL ${INSTALLER_URL} | sh`], { stdio: 'inherit' });
87
+ child.on('close', (code) => resolve(code ?? 1));
88
+ });
89
+ }
90
+ export async function doctorCommand(currentVersion, io) {
91
+ const p = crowPaint();
92
+ const pass = (label, detail) => io.out(` ${p.ok('✓')} ${p.bold(label.padEnd(16))} ${detail}`);
93
+ const warn = (label, detail) => io.out(` ${p.warn('!')} ${p.bold(label.padEnd(16))} ${detail}`);
94
+ const fail = (label, detail) => io.out(` ${p.err('✗')} ${p.bold(label.padEnd(16))} ${detail}`);
95
+ let problems = 0;
96
+ // 1. Node runtime
97
+ const major = Number.parseInt(process.versions.node.split('.')[0], 10);
98
+ if (major >= 18)
99
+ pass('node', `v${process.versions.node} (${process.execPath})`);
100
+ else {
101
+ fail('node', `v${process.versions.node} — crow needs Node >= 18`);
102
+ problems++;
103
+ }
104
+ // 2. Install origin
105
+ const origin = installOrigin();
106
+ const crowHome = path.join(os.homedir(), '.crow');
107
+ if (origin.startsWith(crowHome))
108
+ pass('install', origin);
109
+ else
110
+ warn('install', `${origin} — not the standard ${crowHome} install (npm link or npm -g?)`);
111
+ // 3. PATH shadowing — the exact failure mode behind "old interface" bugs.
112
+ const shadows = pathShadows();
113
+ if (shadows.length === 0) {
114
+ warn('path', '`crow` is not on PATH (running via an absolute path?)');
115
+ }
116
+ else if (shadows.length === 1) {
117
+ pass('path', shadows[0]);
118
+ }
119
+ else {
120
+ fail('path', `${shadows.length} different \`crow\` binaries on PATH — the first one wins:`);
121
+ for (const s of shadows)
122
+ io.out(` ${s === shadows[0] ? p.warn('→') : ' '} ${s}`);
123
+ io.out(` remove stale copies (e.g. \`npm rm -g @orchestree/cli\`) so ${crowHome}/bin wins`);
124
+ problems++;
125
+ }
126
+ // 4. Release CDN + version currency
127
+ try {
128
+ const latest = await fetchText(CDN_LATEST_URL);
129
+ if (compareVersions(latest, currentVersion) > 0) {
130
+ warn('version', `${currentVersion} installed, ${latest} available — run \`crow update\``);
131
+ }
132
+ else {
133
+ pass('version', `${currentVersion} (latest: ${latest})`);
134
+ }
135
+ }
136
+ catch (err) {
137
+ fail('cdn', `${CDN_LATEST_URL} unreachable: ${err.message}`);
138
+ problems++;
139
+ }
140
+ // 5. API reachability — any HTTP answer proves the wire works.
141
+ try {
142
+ const res = await fetch(`${DEFAULT_API_BASE}/health`, {
143
+ signal: AbortSignal.timeout(8_000),
144
+ });
145
+ pass('api', `${DEFAULT_API_BASE} reachable (HTTP ${res.status})`);
146
+ }
147
+ catch (err) {
148
+ fail('api', `${DEFAULT_API_BASE} unreachable: ${err.message}`);
149
+ problems++;
150
+ }
151
+ io.out('');
152
+ io.out(problems === 0 ? p.ok('no problems found') : p.err(`${problems} problem${problems === 1 ? '' : 's'} found`));
153
+ return problems === 0 ? 0 : 1;
154
+ }
155
+ const SUBCOMMANDS = 'login logout whoami gateways crowcode models sessions export update doctor completions help version';
156
+ const ZSH_COMPLETION = `#compdef crow
157
+ # crow zsh completion — generated by \`crow completions zsh\`
158
+ # install: crow completions zsh > "\${fpath[1]}/_crow" && autoload -Uz compinit && compinit
159
+ _crow() {
160
+ local -a subcmds
161
+ subcmds=(
162
+ 'login:sign in with an Orchestree API key'
163
+ 'logout:clear stored credentials'
164
+ 'whoami:show the active credential'
165
+ 'gateways:model gateway status + setup'
166
+ 'crowcode:launch the CrowCode coding agent'
167
+ 'models:list model tiers'
168
+ 'sessions:list, search, or delete sessions'
169
+ 'export:export a session transcript as Markdown'
170
+ 'update:update crow to the latest release'
171
+ 'doctor:diagnose the installation'
172
+ 'completions:print shell completions'
173
+ )
174
+ if (( CURRENT == 2 )); then
175
+ _describe 'crow command' subcmds
176
+ return
177
+ fi
178
+ case "\${words[2]}" in
179
+ sessions) compadd list search delete ;;
180
+ completions) compadd zsh bash ;;
181
+ update) compadd -- --check ;;
182
+ gateways) compadd setup ;;
183
+ esac
184
+ }
185
+ _crow "$@"
186
+ `;
187
+ const BASH_COMPLETION = `# crow bash completion — generated by \`crow completions bash\`
188
+ # install: crow completions bash >> ~/.bashrc (or into bash_completion.d)
189
+ _crow_completions() {
190
+ local cur prev
191
+ cur="\${COMP_WORDS[COMP_CWORD]}"
192
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
193
+ if [ "\$COMP_CWORD" -eq 1 ]; then
194
+ COMPREPLY=( \$(compgen -W "${SUBCOMMANDS}" -- "\$cur") )
195
+ return
196
+ fi
197
+ case "\$prev" in
198
+ sessions) COMPREPLY=( \$(compgen -W "list search delete" -- "\$cur") ) ;;
199
+ completions) COMPREPLY=( \$(compgen -W "zsh bash" -- "\$cur") ) ;;
200
+ update) COMPREPLY=( \$(compgen -W "--check" -- "\$cur") ) ;;
201
+ gateways) COMPREPLY=( \$(compgen -W "setup" -- "\$cur") ) ;;
202
+ esac
203
+ }
204
+ complete -F _crow_completions crow
205
+ `;
206
+ export function completionsCommand(shell, io) {
207
+ if (shell === 'zsh') {
208
+ process.stdout.write(ZSH_COMPLETION);
209
+ return 0;
210
+ }
211
+ if (shell === 'bash') {
212
+ process.stdout.write(BASH_COMPLETION);
213
+ return 0;
214
+ }
215
+ io.err('usage: crow completions <zsh|bash>');
216
+ return 2;
217
+ }
package/package.json CHANGED
@@ -1,57 +1,55 @@
1
1
  {
2
2
  "name": "@orchestree/cli",
3
- "version": "2.2.0",
4
- "description": "Command-line interface for the Orchestree Platform",
3
+ "version": "3.5.0",
4
+ "description": "CrowCode CLI (crow) the Orchestree platform in your terminal: sign in, inspect your identity, manage model gateways, and launch the suite's agents. Installs the `crow` command (`orchestree` remains as an alias).",
5
5
  "type": "module",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
12
- }
6
+ "license": "UNLICENSED",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/multivitaminds/Orchestree.git",
13
+ "directory": "apps/orchestree-cli"
13
14
  },
14
- "files": [
15
- "dist",
16
- "README.md",
17
- "LICENSE",
18
- "bin"
19
- ],
20
15
  "keywords": [
16
+ "crow",
17
+ "crowcode",
21
18
  "orchestree",
22
19
  "cli",
23
20
  "command-line",
24
21
  "devtools"
25
22
  ],
26
- "author": "Orchestree <hello@orchestree.ai>",
27
- "license": "MIT",
28
- "homepage": "https://orchestree.ai/developer/cli",
29
- "repository": {
30
- "type": "git",
31
- "url": "https://github.com/orchestree/orchestree.git",
32
- "directory": "packages/cli"
33
- },
34
- "bugs": {
35
- "url": "https://github.com/orchestree/orchestree/issues"
36
- },
37
- "scripts": {
38
- "build": "tsc --outDir dist",
39
- "dev": "tsc --outDir dist --watch",
40
- "start": "node bin/orchestree.js",
41
- "test": "echo \"Tests passed\" && exit 0",
42
- "clean": "rm -rf dist",
43
- "prepublishOnly": "npm run build"
23
+ "bin": {
24
+ "crow": "./bin/crow.js",
25
+ "orchestree": "./bin/orchestree.js"
44
26
  },
27
+ "files": [
28
+ "bin",
29
+ "dist",
30
+ "CHANGELOG.md"
31
+ ],
45
32
  "engines": {
46
- "node": ">=18.0.0"
33
+ "node": ">=20"
47
34
  },
48
- "publishConfig": {
49
- "access": "public"
35
+ "scripts": {
36
+ "dev": "tsx src/index.ts",
37
+ "start": "node dist/index.js",
38
+ "build": "tsc -p tsconfig.json",
39
+ "test": "vitest",
40
+ "test:run": "vitest run",
41
+ "typecheck": "tsc -p tsconfig.json --noEmit",
42
+ "lint": "echo 'No lint configured for orchestree-cli yet'"
50
43
  },
51
44
  "dependencies": {
52
- "@orchestree/sdk": "^1.5.0"
45
+ "@orchestree/cli-core": "0.2.0",
46
+ "@orchestree/crowcode-cli": "0.5.0"
53
47
  },
54
- "bin": {
55
- "orchestree": "./bin/orchestree.js"
48
+ "devDependencies": {
49
+ "@orchestree/typescript-config": "0.0.0",
50
+ "@types/node": "^24.10.1",
51
+ "tsx": "^4.20.0",
52
+ "typescript": "~5.9.3",
53
+ "vitest": "^4.0.18"
56
54
  }
57
- }
55
+ }
@@ -1 +0,0 @@
1
- export declare function agentsCommand(args: string[]): Promise<void>;