@crewx/cli 0.9.0-rc.18 → 0.9.0-rc.180

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.
Files changed (80) hide show
  1. package/dist/bootstrap/codex-writable-roots.d.ts +20 -1
  2. package/dist/bootstrap/codex-writable-roots.js +1 -88
  3. package/dist/bootstrap/crewx-cli.js +1 -63
  4. package/dist/bootstrap/rate-limit-snapshot.d.ts +15 -0
  5. package/dist/bootstrap/rate-limit-snapshot.js +1 -0
  6. package/dist/builtin.d.ts +1 -1
  7. package/dist/builtin.js +5 -127
  8. package/dist/commands/agent.d.ts +1 -0
  9. package/dist/commands/agent.js +3 -246
  10. package/dist/commands/ai-account.d.ts +4 -0
  11. package/dist/commands/ai-account.js +27 -0
  12. package/dist/commands/cal.d.ts +15 -0
  13. package/dist/commands/cal.js +2 -0
  14. package/dist/commands/command-help.d.ts +26 -0
  15. package/dist/commands/command-help.js +52 -0
  16. package/dist/commands/db.d.ts +3 -0
  17. package/dist/commands/db.js +59 -125
  18. package/dist/commands/detached.d.ts +102 -0
  19. package/dist/commands/detached.js +15 -0
  20. package/dist/commands/doctor.d.ts +77 -0
  21. package/dist/commands/doctor.js +4 -196
  22. package/dist/commands/emit-trailer.d.ts +25 -0
  23. package/dist/commands/emit-trailer.js +2 -0
  24. package/dist/commands/execute.d.ts +8 -4
  25. package/dist/commands/execute.js +15 -146
  26. package/dist/commands/hook/command-marker.d.ts +2 -0
  27. package/dist/commands/hook/command-marker.js +1 -0
  28. package/dist/commands/hook/install.d.ts +0 -1
  29. package/dist/commands/hook/install.js +8 -175
  30. package/dist/commands/hook/paths.js +1 -94
  31. package/dist/commands/hook/status.js +1 -86
  32. package/dist/commands/hook/uninstall.js +1 -71
  33. package/dist/commands/hook-dispatch.js +2 -180
  34. package/dist/commands/init.d.ts +34 -0
  35. package/dist/commands/init.js +38 -371
  36. package/dist/commands/kill.d.ts +2 -8
  37. package/dist/commands/kill.js +1 -52
  38. package/dist/commands/log.js +3 -95
  39. package/dist/commands/parse-agent-message.js +1 -52
  40. package/dist/commands/parse-common-flags.d.ts +5 -1
  41. package/dist/commands/parse-common-flags.js +3 -181
  42. package/dist/commands/ps.d.ts +2 -2
  43. package/dist/commands/ps.js +2 -107
  44. package/dist/commands/publish.d.ts +1 -0
  45. package/dist/commands/publish.js +27 -0
  46. package/dist/commands/query.d.ts +7 -2
  47. package/dist/commands/query.js +16 -146
  48. package/dist/commands/registry.js +1 -31
  49. package/dist/commands/resolve-prompt.js +3 -54
  50. package/dist/commands/resolve-recipient.d.ts +14 -0
  51. package/dist/commands/resolve-recipient.js +3 -0
  52. package/dist/commands/restart.d.ts +3 -1
  53. package/dist/commands/restart.js +18 -162
  54. package/dist/commands/result.d.ts +8 -3
  55. package/dist/commands/result.js +1 -70
  56. package/dist/commands/shortcut.d.ts +1 -0
  57. package/dist/commands/shortcut.js +18 -0
  58. package/dist/commands/slack.js +16 -559
  59. package/dist/commands/stop.d.ts +8 -0
  60. package/dist/commands/stop.js +8 -0
  61. package/dist/commands/write-output.js +1 -24
  62. package/dist/index.d.ts +1 -1
  63. package/dist/index.js +1 -5
  64. package/dist/logging.d.ts +1 -1
  65. package/dist/logging.js +10 -86
  66. package/dist/main.d.ts +3 -2
  67. package/dist/main.js +49 -253
  68. package/dist/register-builtin-tools.js +1 -9
  69. package/dist/slack/file-download.js +1 -134
  70. package/dist/slack/markdown.js +1 -33
  71. package/dist/utils/env-defaults.d.ts +2 -5
  72. package/dist/utils/env-defaults.js +1 -10
  73. package/dist/utils/inherited-trace.d.ts +24 -0
  74. package/dist/utils/inherited-trace.js +1 -25
  75. package/dist/utils/product-package-root.d.ts +6 -0
  76. package/dist/utils/product-package-root.js +1 -0
  77. package/dist/utils/sdk-compat.d.ts +24 -0
  78. package/dist/utils/sdk-compat.js +1 -0
  79. package/dist/utils/version.js +1 -28
  80. package/package.json +16 -12
@@ -1,196 +1,4 @@
1
- "use strict";
2
- /**
3
- * crewx doctor handler.
4
- * Performs system diagnosis: checks config, CLI tools, and environment.
5
- *
6
- * Usage:
7
- * crewx doctor Run full diagnosis
8
- * crewx doctor --config <path> Use specific config file
9
- */
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.handleDoctor = handleDoctor;
12
- const fs_1 = require("fs");
13
- const path_1 = require("path");
14
- const child_process_1 = require("child_process");
15
- const sdk_1 = require("@crewx/sdk");
16
- const parse_common_flags_1 = require("./parse-common-flags");
17
- function statusIcon(status) {
18
- switch (status) {
19
- case 'success': return 'āœ…';
20
- case 'warning': return 'āš ļø ';
21
- case 'error': return 'āŒ';
22
- }
23
- }
24
- /**
25
- * Check if a CLI command is available on PATH.
26
- */
27
- function isCommandAvailable(cmd) {
28
- try {
29
- (0, child_process_1.execSync)(`which ${cmd}`, { stdio: 'ignore' });
30
- return true;
31
- }
32
- catch {
33
- return false;
34
- }
35
- }
36
- /**
37
- * Check crewx.yaml configuration file.
38
- */
39
- function checkConfig(configPath) {
40
- if (!(0, fs_1.existsSync)(configPath)) {
41
- return {
42
- name: 'Configuration File',
43
- status: 'error',
44
- message: `Configuration file not found: ${configPath}`,
45
- details: "Run 'crewx init' to create a default configuration file.",
46
- };
47
- }
48
- try {
49
- const raw = (0, sdk_1.loadYamlFile)(configPath);
50
- const config = raw;
51
- if (!config?.agents || !Array.isArray(config.agents)) {
52
- return {
53
- name: 'Configuration File',
54
- status: 'error',
55
- message: 'Invalid configuration format',
56
- details: 'Configuration file exists but has invalid structure.',
57
- };
58
- }
59
- if (config.agents.length === 0) {
60
- return {
61
- name: 'Configuration File',
62
- status: 'warning',
63
- message: 'No agents configured',
64
- details: 'Add agent definitions to your crewx.yaml.',
65
- };
66
- }
67
- return {
68
- name: 'Configuration File',
69
- status: 'success',
70
- message: `Found ${config.agents.length} agent(s) in ${configPath}`,
71
- };
72
- }
73
- catch (err) {
74
- return {
75
- name: 'Configuration File',
76
- status: 'error',
77
- message: 'Failed to parse configuration',
78
- details: `Error: ${err instanceof Error ? err.message : String(err)}`,
79
- };
80
- }
81
- }
82
- /**
83
- * Check .crewx/logs directory.
84
- */
85
- function checkLogsDir() {
86
- const logsDir = (0, path_1.join)(process.cwd(), '.crewx', 'logs');
87
- if (!(0, fs_1.existsSync)(logsDir)) {
88
- return {
89
- name: 'Logs Directory',
90
- status: 'warning',
91
- message: 'Logs directory not found',
92
- details: `Will be created automatically at ${logsDir}`,
93
- };
94
- }
95
- return {
96
- name: 'Logs Directory',
97
- status: 'success',
98
- message: `Logs directory exists: ${logsDir}`,
99
- };
100
- }
101
- /**
102
- * Check CLI provider availability.
103
- * Providers are checked in PROVIDER_ORDER: codex → claude → opencode → antigravity → copilot.
104
- */
105
- function checkCliProviders() {
106
- // Map each provider (in PROVIDER_ORDER) to its CLI command and install hint.
107
- const providerInfo = {
108
- codex: { cmd: 'codex', install: 'npm install -g @openai/codex' },
109
- claude: { cmd: 'claude', install: 'npm install -g @anthropic-ai/claude-code' },
110
- opencode: { cmd: 'opencode', install: 'npm install -g opencode' },
111
- antigravity: { cmd: 'antigravity', install: 'npm install -g antigravity' },
112
- copilot: { cmd: 'gh', install: 'brew install gh # or visit cli.github.com' },
113
- };
114
- return sdk_1.PROVIDER_ORDER.map(provider => {
115
- const info = providerInfo[provider];
116
- const displayName = provider === 'copilot' ? 'copilot (gh)' : provider;
117
- const available = isCommandAvailable(info.cmd);
118
- return {
119
- name: `${displayName.toUpperCase()} CLI`,
120
- status: available ? 'success' : 'warning',
121
- message: available ? 'Installed and available' : 'Not installed or not on PATH',
122
- details: available ? undefined : `Install: ${info.install}`,
123
- };
124
- });
125
- }
126
- /**
127
- * Check CREWX_CLI env var.
128
- */
129
- function checkEnvVars() {
130
- const crewxCli = process.env.CREWX_CLI;
131
- if (crewxCli) {
132
- return {
133
- name: 'CREWX_CLI',
134
- status: 'success',
135
- message: `Set to: ${crewxCli}`,
136
- };
137
- }
138
- return {
139
- name: 'CREWX_CLI',
140
- status: 'warning',
141
- message: 'Not set — defaulting to "npx crewx"',
142
- details: 'This is auto-set at CLI startup; no action needed.',
143
- };
144
- }
145
- /**
146
- * Assess overall health.
147
- */
148
- function assessHealth(diagnostics) {
149
- const errors = diagnostics.filter(d => d.status === 'error').length;
150
- const warnings = diagnostics.filter(d => d.status === 'warning').length;
151
- const successes = diagnostics.filter(d => d.status === 'success').length;
152
- if (errors > 0) {
153
- return { status: 'error', message: `System has ${errors} error(s) that need attention` };
154
- }
155
- if (warnings > 0) {
156
- return { status: 'warning', message: `System is functional with ${warnings} warning(s)` };
157
- }
158
- return { status: 'success', message: `System is healthy — all ${successes} checks passed` };
159
- }
160
- /**
161
- * Handle `crewx doctor` command.
162
- */
163
- async function handleDoctor(args) {
164
- const { config } = (0, parse_common_flags_1.parseCommonFlags)(args);
165
- const configPath = config ?? process.env.CREWX_CONFIG ?? (0, path_1.join)(process.cwd(), 'crewx.yaml');
166
- console.log('🩺 Starting CrewX system diagnosis...\n');
167
- const diagnostics = [
168
- checkConfig(configPath),
169
- checkLogsDir(),
170
- checkEnvVars(),
171
- ...checkCliProviders(),
172
- ];
173
- // Print diagnostics
174
- diagnostics.forEach(d => {
175
- const icon = statusIcon(d.status);
176
- console.log(`${icon} ${d.name}: ${d.message}`);
177
- if (d.details) {
178
- console.log(` ${d.details}`);
179
- }
180
- });
181
- const health = assessHealth(diagnostics);
182
- const healthIcon = statusIcon(health.status);
183
- console.log('');
184
- console.log('─'.repeat(60));
185
- console.log(`${healthIcon} Overall: ${health.message}`);
186
- if (health.status === 'success') {
187
- console.log('\nNext steps:');
188
- console.log(' crewx query "@claude hello"');
189
- }
190
- else {
191
- console.log('\nAddress the issues above, then run `crewx doctor` again.');
192
- }
193
- if (health.status === 'error') {
194
- process.exit(1);
195
- }
196
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.CLI_PROVIDER_INFO=void 0;exports.formatBytes=$;exports.inspectNpxCache=y;exports.inspectHookCommands=R;exports.inspectCrewxExecutable=E;exports.inspectCrewxShims=x;exports.checkCliProviders=S;exports.handleDoctor=ee;const w=require("node:child_process");const u=require("node:fs");const F=require("node:os");const c=require("node:path");const d=require("@crewx/sdk");const N=require("./parse-common-flags");const I=require("./hook/command-marker");exports.CLI_PROVIDER_INFO={codex:{cmd:"codex",install:"npm install -g @openai/codex"},claude:{cmd:"claude",install:"npm install -g @anthropic-ai/claude-code"},grok:{cmd:"grok",install:"curl -fsSL https://x.ai/cli/install.sh | bash"},opencode:{cmd:"opencode",install:"npm install -g opencode"},antigravity:{cmd:"antigravity",install:"npm install -g antigravity"},copilot:{cmd:"gh",install:"brew install gh # or visit cli.github.com"}};function v(e){switch(e){case"success":return"\u2705";case"warning":return"\u26A0\uFE0F ";case"error":return"\u274C"}}function P(e){try{(0,w.execSync)(`which ${e}`,{stdio:"ignore"});return true}catch{return false}}function $(e){if(!Number.isFinite(e)||e<=0)return"0 B";const t=["B","KB","MB","GB","TB"];let n=e;let s=0;while(n>=1024&&s<t.length-1){n/=1024;s+=1}const o=s===0||n>=10?Math.round(n):n.toFixed(1);return`${o} ${t[s]}`}function p(e){try{const t=(0,u.lstatSync)(e);if(!t.isDirectory())return t.size;return(0,u.readdirSync)(e,{withFileTypes:true}).reduce((n,s)=>{return n+p((0,c.join)(e,s.name))},0)}catch{return 0}}function b(e){try{return(0,u.readdirSync)(e,{withFileTypes:true}).filter(t=>t.isDirectory()).map(t=>(0,c.join)(e,t.name)).sort()}catch{return[]}}function _(e){try{const t=JSON.parse((0,u.readFileSync)(e,"utf8"));if(typeof t!=="object"||t===null||Array.isArray(t))return void 0;return t}catch{return void 0}}function O(e=process.env){const t=e.NPM_CONFIG_CACHE??e.npm_config_cache;const n=t?.trim()||(0,c.join)((0,F.homedir)(),".npm");const s=(0,c.resolve)(n);return(0,c.basename)(s)==="_npx"?s:(0,c.join)(s,"_npx")}const L=["dependencies","devDependencies","optionalDependencies","peerDependencies"];function T(e){const t=_((0,c.join)(e,"package.json"));if(!t)return[];const n=[];for(const s of L){const o=t[s];if(typeof o!=="object"||o===null||Array.isArray(o))continue;for(const[i,r]of Object.entries(o)){if(typeof r!=="string"||!r.startsWith("file:"))continue;const a=(0,c.resolve)(e,r.slice("file:".length));if(!(0,u.existsSync)(a)){n.push(`${s}.${i}=${r} (missing ${a})`)}}}return n}function k(e,t,n){const s=e.get(t);if(s){s.details.push(...n);return s}const o={directory:t,sizeBytes:p(t),details:[...n]};e.set(t,o);return o}function y(e=O()){const t=(0,c.resolve)(e);const n=[];const s=[];const o=new Map;for(const i of b(t)){const r=(0,c.join)(i,"package-lock.json");try{const l=(0,u.statSync)(r);if(l.isFile()&&l.size===0){const h=k(o,i,[`0-byte lockfile: ${r}`]);n.push(h)}}catch{}const a=T(i);if(a.length>0){const l=k(o,i,a);s.push(l)}}return{cacheRoot:t,zeroByteLockfileDirectories:n,staleFileCacheDirectories:s,cleanableDirectories:[...o.values()]}}function C(e){if(typeof e!=="object"||e===null||Array.isArray(e))return void 0;return e}function X(e){const t=C(e.hooks)??e;const n=t.PreToolUse;if(!Array.isArray(n))return[];const s=[];for(const o of n){const i=C(o);const r=i?.hooks;if(!Array.isArray(r))continue;for(const a of r){const l=C(a)?.command;if(typeof l==="string"&&I.CREWX_HOOK_COMMAND_RE.test(l)){s.push(l)}}}return s}function B(e){const t=e.trim();if(!t)return"";if(t.startsWith("'")||t.startsWith('"')){const n=t[0];const s=t.indexOf(n,1);return s===-1?t.slice(1):t.slice(1,s)}return t.split(/\s+/,1)[0]}function H(e){return(0,c.isAbsolute)(e)||/^[A-Za-z]:[\\/]/.test(e)||e.startsWith("\\\\")}function q(e){const t=B(e);if(/^(?:npx|pnpm|yarn)$/i.test(t))return"launcher";if(!H(t))return"non-absolute";return void 0}function R(e){const t=[{provider:"claude",settingsPath:(0,c.join)((0,c.resolve)(e),".claude","settings.json")},{provider:"codex",settingsPath:(0,c.join)((0,c.resolve)(e),".codex","hooks.json")}];const n=[];const s=[];for(const o of t){if(!(0,u.existsSync)(o.settingsPath))continue;n.push(o.settingsPath);const i=_(o.settingsPath);if(!i)continue;for(const r of X(i)){const a=q(r);if(a){s.push({provider:o.provider,settingsPath:o.settingsPath,command:r,reason:a})}}}return{inspectedFiles:n,issues:s}}function W(e,t="global_first"){try{const n=(0,d.loadYamlFile)(e);const s=n.settings?.bin_resolution;return s==="local_first"||s==="global_first"?s:t}catch{return t}}function z(e,t,n){if(n!=="win32")return[];try{(0,d.primeWindowsConsoleCodePage)();const s=(0,w.execFileSync)("where.exe",["crewx"],{cwd:e,env:t,encoding:null,stdio:["ignore","pipe","ignore"]});return(0,d.decodeConsoleBuffer)(s,{platform:n}).split(/\r?\n/).map(o=>o.trim()).filter(o=>o.length>0)}catch{return[]}}function E(e={}){const t=e.platform??process.platform;const n=(0,c.resolve)(e.cwd??process.cwd());const s=e.env??process.env;const o=e.configPath??(0,c.join)(n,"crewx.yaml");const i=e.resolution??(0,d.resolveCrewxExecutable)({env:s,cwd:n,platform:t});const r=e.pathCandidates?[...e.pathCandidates]:z(n,s,t);const a=i.ok?Object.keys(i.requiredEnv??{}).filter(l=>l==="ELECTRON_RUN_AS_NODE"):[];return{platform:t,pathCandidates:r,...i.ok?{stage:i.stage,argv:[...i.argv],adoptedPath:i.argv[0]}:{resolutionError:i.reason},electron:a.includes("ELECTRON_RUN_AS_NODE"),requiredEnvKeys:a,binResolution:e.binResolution??W(o)}}function M(e){const t=[`platform: ${e.platform}`,`stage: ${e.stage??"(unresolved)"}`,`argv: ${e.argv?(0,d.formatCrewxExecutableArgv)(e.argv):"(unresolved)"}`,`adopted path: ${e.adoptedPath??"(none)"}`,`Electron runtime: ${e.electron?"yes":"no"}`,`required environment keys: ${e.requiredEnvKeys.length>0?e.requiredEnvKeys.join(", "):"(none)"}`,`bin_resolution setting: ${e.binResolution}`,...e.platform==="win32"?[`where.exe crewx candidates: ${e.pathCandidates.length>0?e.pathCandidates.join(", "):"(none)"}`]:[]];if(e.resolutionError){return{name:"CrewX Executable",status:"warning",message:"Could not resolve the CrewX executable",details:`${t.join("\n")}
2
+ Resolution failed; no environment values were printed.`}}return{name:"CrewX Executable",status:"success",message:"SDK child executable contract is available",details:t.join("\n")}}function x(e=(0,d.getCrewxHome)(),t=(()=>{const n=(0,d.resolveCrewxExecutable)();return n.ok?(0,d.crewxCliShimFingerprint)(n):void 0})()){const n=(0,c.join)((0,c.resolve)(e),"bin-shim");const s=[];if(t){for(const o of b(n)){const i=o.slice(n.length+1);if(i===t)continue;s.push({fingerprint:i,directory:o,sizeBytes:p(o),details:[`not current fingerprint (${t})`]})}}return{shimRoot:n,currentFingerprint:t,staleDirectories:s}}function K(e){const t=e.zeroByteLockfileDirectories.length;const n=e.staleFileCacheDirectories.length;const s=e.cleanableDirectories.length;if(t===0&&n===0){return{name:"npx Cache",status:"success",message:`No stale entries found in ${e.cacheRoot}`}}const o=[];if(t>0){o.push(`0-byte package-lock.json: ${e.zeroByteLockfileDirectories.map(i=>i.directory).join(", ")}`)}if(n>0){o.push(`stale file: cache: ${e.staleFileCacheDirectories.map(i=>i.directory).join(", ")}`)}o.push("Run `crewx doctor --clean-npx-cache` to remove these cache directories explicitly.");return{name:"npx Cache",status:"warning",message:`Found ${s} problematic npx cache director${s===1?"y":"ies"}`,details:o.join("\n")}}function U(e){if(e.issues.length===0){return{name:"CrewX Hooks",status:"success",message:e.inspectedFiles.length>0?"Installed CrewX hook commands use absolute entrypoints":"No installed CrewX hooks found"}}const t=e.issues.map(n=>`${n.settingsPath}: ${n.command} (${n.reason})`).join("\n");return{name:"CrewX Hooks",status:"warning",message:`Found ${e.issues.length} hook command(s) that need an absolute CrewX entrypoint`,details:`${t}
3
+ Run \`crewx hook install\` to refresh the hook after reviewing the change.`}}function V(e){if(!e.currentFingerprint){return{name:"CrewX PATH Shims",status:"warning",message:"Could not resolve the current CrewX executable; skipped orphan shim cleanup",details:`Shim root: ${e.shimRoot}`}}if(e.staleDirectories.length===0){return{name:"CrewX PATH Shims",status:"success",message:"No orphaned CrewX PATH shims found"}}return{name:"CrewX PATH Shims",status:"warning",message:`Found ${e.staleDirectories.length} orphaned CrewX PATH shim director${e.staleDirectories.length===1?"y":"ies"}`,details:`${e.staleDirectories.map(t=>t.directory).join(", ")}
4
+ Run \`crewx doctor --clean-npx-cache\` to remove stale shims explicitly.`}}function D(e,t){const n=(0,c.resolve)(t);let s=0;const o=[];for(const i of e){const r=(0,c.resolve)(i.directory);if((0,c.dirname)(r)!==n){o.push(`${r} (unexpected parent)`);continue}try{(0,u.rmSync)(r,{recursive:true,force:true});if(!(0,u.existsSync)(r))s+=1;else o.push(r)}catch{o.push(r)}}return{removed:s,failed:o}}function G(e,t){const n=e.cleanableDirectories;const s=t.staleDirectories;const o=[...n,...s];const i=o.reduce((h,g)=>h+g.sizeBytes,0);console.log(`\u26A0\uFE0F --clean-npx-cache: before cleanup, ${n.length} npx cache director${n.length===1?"y":"ies"} and ${s.length} orphan shim director${s.length===1?"y":"ies"} (${$(i)}).`);const r=D(n,e.cacheRoot);const a=D(s,t.shimRoot);const l=[...r.failed,...a.failed];console.log(` Removed ${r.removed+a.removed} director${r.removed+a.removed===1?"y":"ies"}.`);if(l.length>0){console.log(` Could not remove: ${l.join(", ")}`)}}function J(e){if(!(0,u.existsSync)(e)){return{name:"Configuration File",status:"error",message:`Configuration file not found: ${e}`,details:"Run 'crewx init' to create a default configuration file."}}try{const t=(0,d.loadYamlFile)(e);const n=t;if(!n?.agents||!Array.isArray(n.agents)){return{name:"Configuration File",status:"error",message:"Invalid configuration format",details:"Configuration file exists but has invalid structure."}}if(n.agents.length===0){return{name:"Configuration File",status:"warning",message:"No agents configured",details:"Add agent definitions to your crewx.yaml."}}return{name:"Configuration File",status:"success",message:`Found ${n.agents.length} agent(s) in ${e}`}}catch(t){return{name:"Configuration File",status:"error",message:"Failed to parse configuration",details:`Error: ${t instanceof Error?t.message:String(t)}`}}}function Y(){const e=(0,c.join)(process.cwd(),".crewx","logs");if(!(0,u.existsSync)(e)){return{name:"Logs Directory",status:"warning",message:"Logs directory not found",details:`Will be created automatically at ${e}`}}return{name:"Logs Directory",status:"success",message:`Logs directory exists: ${e}`}}function S(){return d.PROVIDER_ORDER.map(e=>{const t=exports.CLI_PROVIDER_INFO[e];if(!t){return{name:`${e.toUpperCase()} CLI`,status:"error",message:"Diagnostic metadata is missing",details:`Add ${e} to CLI_PROVIDER_INFO.`}}const n=e==="copilot"?"copilot (gh)":e;const s=P(t.cmd);return{name:`${n.toUpperCase()} CLI`,status:s?"success":"warning",message:s?"Installed and available":"Not installed or not on PATH",details:s?void 0:`Install: ${t.install}`}})}function Z(){const e=process.env.CREWX_CLI;if(e){return{name:"CREWX_CLI",status:"success",message:`Set to: ${e}`}}return{name:"CREWX_CLI",status:"warning",message:'Not set \u2014 defaulting to "crewx"',details:"This is auto-set at CLI startup; no action needed."}}function Q(e){const t=e.filter(o=>o.status==="error").length;const n=e.filter(o=>o.status==="warning").length;const s=e.filter(o=>o.status==="success").length;if(t>0){return{status:"error",message:`System has ${t} error(s) that need attention`}}if(n>0){return{status:"warning",message:`System is functional with ${n} warning(s)`}}return{status:"success",message:`System is healthy \u2014 all ${s} checks passed`}}async function ee(e){const t=e.includes("--clean-npx-cache");const n=e.filter(f=>f!=="--clean-npx-cache");const{config:s}=(0,N.parseCommonFlags)(n);const o=s??process.env.CREWX_CONFIG??(0,c.join)(process.cwd(),"crewx.yaml");console.log("\u{1FA7A} Starting CrewX system diagnosis...\n");let i=y();let r=x();const a=(0,c.dirname)((0,c.resolve)(o));const l=R(a);const h=E({configPath:o,cwd:process.cwd()});if(t){G(i,r);i=y();r=x()}const g=[J(o),Y(),Z(),M(h),...S(),K(i),U(l),V(r)];g.forEach(f=>{const A=v(f.status);console.log(`${A} ${f.name}: ${f.message}`);if(f.details){console.log(` ${f.details}`)}});const m=Q(g);const j=v(m.status);console.log("");console.log("\u2500".repeat(60));console.log(`${j} Overall: ${m.message}`);if(m.status==="success"){console.log("\nNext steps:");console.log(' crewx q --to crewx "hello"')}else{console.log("\nAddress the issues above, then run `crewx doctor` again.")}if(m.status==="error"){process.exit(1)}}
@@ -0,0 +1,25 @@
1
+ import type { TraceContext } from '@crewx/sdk';
2
+ /** Mutable per-process guard shared by a handler and main()'s error boundary. */
3
+ export interface DelegationEmitState {
4
+ emitted: boolean;
5
+ }
6
+ /** The result fields needed to produce a delegation control line. */
7
+ export interface DelegationEmitOptions {
8
+ command?: string;
9
+ trace?: TraceContext;
10
+ taskId?: string;
11
+ agentId?: string;
12
+ isError: boolean;
13
+ state?: DelegationEmitState;
14
+ }
15
+ export declare function createDelegationEmitState(): DelegationEmitState;
16
+ /**
17
+ * Return true only for an inherited child invocation of q/query/x/execute.
18
+ * Root CLI calls and unrelated built-in commands must remain byte-compatible.
19
+ */
20
+ export declare function shouldEmitDelegationResult(command: string | undefined, trace?: TraceContext | undefined): boolean;
21
+ /**
22
+ * Write one machine-readable result line to stdout when this is a delegated call.
23
+ * The shared SDK formatter owns the wire syntax and validation rules.
24
+ */
25
+ export declare function emitDelegationResult(options: DelegationEmitOptions): boolean;
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.createDelegationEmitState=m;exports.shouldEmitDelegationResult=n;exports.emitDelegationResult=f;const l=require("@crewx/sdk");const c=require("../utils/inherited-trace");const d=new Set(["q","query","x","execute"]);function m(){return{emitted:false}}function n(e,t=(0,c.readInheritedTrace)()){return d.has(e??"")&&Boolean(t?.parentTaskId)}function f(e){const{command:t,trace:i,state:r,taskId:a,agentId:o,isError:s}=e;if(r?.emitted||!n(t,i))return false;const u=(0,l.formatDelegationResult)({taskId:a,agentId:o,isError:s});if(r)r.emitted=true;process.stdout.write(`${u}
2
+ `);return true}
@@ -3,25 +3,29 @@
3
3
  * Parses args, loads config via Crewx SDK, and executes the task.
4
4
  *
5
5
  * Flags:
6
+ * --to <agent> Explicit recipient (the positional @agent form is shorthand)
6
7
  * --thread <name> Conversation thread name
7
8
  * --provider <cli/xxx> Provider override
9
+ * --model <name> Model override (e.g. claude-sonnet-5)
8
10
  * --metadata <json> Extra metadata JSON (double-quoted object). Propagated to events/hooks/tracing.
9
- * e.g. --metadata='{"workflow_id":"wf-1"}'
10
11
  * --verbose Debug output mode (default: raw agent response only)
11
12
  * --config/-c <path> Config file path override
12
13
  * --output-format <fmt> Output format (json|text|stream-json)
13
14
  * --effort <level> Model effort (high|medium|low)
14
- * -f/--prompt-file <path> Read task body from file (bypasses cmd.exe argv truncation)
15
+ * -f/--prompt-file <path> Read task body from file
16
+ * --detach/--async Persist a receipt and launch a detached runner
17
+ * --wait Force synchronous execution
15
18
  *
16
19
  * Stdin support:
17
20
  * Pipe or redirect content into crewx x to supply the task body via stdin.
18
- * e.g. cat task.md | crewx x "@agent label"
19
21
  * Stdin is ignored when running in an interactive TTY.
20
22
  */
23
+ import { type DelegationEmitState } from './emit-trailer';
24
+ export { runDetachedMiddle } from './detached';
21
25
  /**
22
26
  * Handle `crewx execute <agentRef> <message>` command.
23
27
  *
24
28
  * Default output: raw agent response only (stdout).
25
29
  * --verbose: debug info written to stderr, response to stdout.
26
30
  */
27
- export declare function handleExecute(args: string[]): Promise<void>;
31
+ export declare function handleExecute(args: string[], command?: string, emitState?: DelegationEmitState): Promise<void>;
@@ -1,146 +1,15 @@
1
- "use strict";
2
- /**
3
- * crewx execute handler.
4
- * Parses args, loads config via Crewx SDK, and executes the task.
5
- *
6
- * Flags:
7
- * --thread <name> Conversation thread name
8
- * --provider <cli/xxx> Provider override
9
- * --metadata <json> Extra metadata JSON (double-quoted object). Propagated to events/hooks/tracing.
10
- * e.g. --metadata='{"workflow_id":"wf-1"}'
11
- * --verbose Debug output mode (default: raw agent response only)
12
- * --config/-c <path> Config file path override
13
- * --output-format <fmt> Output format (json|text|stream-json)
14
- * --effort <level> Model effort (high|medium|low)
15
- * -f/--prompt-file <path> Read task body from file (bypasses cmd.exe argv truncation)
16
- *
17
- * Stdin support:
18
- * Pipe or redirect content into crewx x to supply the task body via stdin.
19
- * e.g. cat task.md | crewx x "@agent label"
20
- * Stdin is ignored when running in an interactive TTY.
21
- */
22
- Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.handleExecute = handleExecute;
24
- const sdk_1 = require("@crewx/sdk");
25
- const parse_agent_message_1 = require("./parse-agent-message");
26
- const parse_common_flags_1 = require("./parse-common-flags");
27
- const resolve_prompt_1 = require("./resolve-prompt");
28
- const crewx_cli_1 = require("../bootstrap/crewx-cli");
29
- const inherited_trace_1 = require("../utils/inherited-trace");
30
- const write_output_1 = require("./write-output");
31
- /**
32
- * Handle `crewx execute <agentRef> <message>` command.
33
- *
34
- * Default output: raw agent response only (stdout).
35
- * --verbose: debug info written to stderr, response to stdout.
36
- */
37
- async function handleExecute(args) {
38
- const { thread, provider, metadata, verbose, config, outputFormat, effort, promptFile, overdrive, vars, out, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
39
- const { agentRef: parsedAgentRef, message } = (0, parse_agent_message_1.parseAgentMessage)(rest);
40
- // No @mention → default to @crewx agent (matches cli-bak behaviour)
41
- const agentRef = parsedAgentRef || '@crewx';
42
- // Resolve final prompt: argv | stdin pipe | --prompt-file (or combination)
43
- const finalMessage = await (0, resolve_prompt_1.resolvePrompt)(message, promptFile);
44
- if (!finalMessage) {
45
- console.error('Usage: crewx execute [@agent] <task> [options]');
46
- console.error(' crewx x [@agent] <task> [options]');
47
- console.error('');
48
- console.error(' @agent is optional. Defaults to @crewx when omitted.');
49
- console.error(' Task body can also be supplied via stdin pipe or --prompt-file.');
50
- console.error('');
51
- console.error('Examples:');
52
- console.error(' crewx x "@agent do something"');
53
- console.error(' cat task.md | crewx x "@agent label"');
54
- console.error(' crewx x "@agent label" --prompt-file=task.md');
55
- console.error('');
56
- console.error('Options:');
57
- console.error(' --thread <name> Conversation thread name');
58
- console.error(' --provider <cli/xxx> Provider override');
59
- console.error(' --metadata <json> Extra metadata (JSON object, double-quoted).');
60
- console.error(' Propagated to events/hooks/tracing.');
61
- console.error(' Invalid JSON aborts with exit code 2.');
62
- console.error(' e.g. --metadata=\'{"workflow_id":"wf-1"}\'');
63
- console.error(' --verbose Debug output mode');
64
- console.error(' --config/-c <path> Config file path');
65
- console.error(' --output-format <fmt> Output format (json|text|stream-json)');
66
- console.error(' --out/-o <path> Save result to file (stdout suppressed)');
67
- console.error(' --effort <level> Model effort (high|medium|low)');
68
- console.error(' -f/--prompt-file <path> Read task body from file');
69
- console.error(' --var key=value Template variable (repeatable)');
70
- console.error(' --overdrive Activate overdrive (boost) profile for this request');
71
- process.exit(1);
72
- }
73
- const configPath = config ?? process.env.CREWX_CONFIG ?? 'crewx.yaml';
74
- // Only show exec audit span JSON in verbose mode
75
- (0, sdk_1.setAuditVerbose)(verbose);
76
- const crewx = await (0, crewx_cli_1.createCliCrewx)(configPath);
77
- // file:// remote agent delegation is handled transparently inside Crewx.query/execute.
78
- if (verbose) {
79
- process.stderr.write(`šŸ“‹ Task: ${finalMessage}\n`);
80
- process.stderr.write(`šŸ¤– Agent: ${agentRef}\n`);
81
- if (thread)
82
- process.stderr.write(`šŸ”— Thread: ${thread}\n`);
83
- if (provider)
84
- process.stderr.write(`šŸ”Œ Provider: ${provider}\n`);
85
- if (outputFormat)
86
- process.stderr.write(`šŸ“„ Output-format: ${outputFormat}\n`);
87
- if (effort)
88
- process.stderr.write(`⚔ Effort: ${effort}\n`);
89
- if (overdrive)
90
- process.stderr.write(`šŸš€ Overdrive: ON\n`);
91
- process.stderr.write('─'.repeat(60) + '\n');
92
- }
93
- let parsedMetadata = {};
94
- try {
95
- parsedMetadata = (0, parse_common_flags_1.parseMetadata)(metadata);
96
- }
97
- catch (err) {
98
- const msg = err instanceof Error ? err.message : String(err);
99
- process.stderr.write(`Error: ${msg}\n`);
100
- process.exit(2);
101
- }
102
- let exitCode = 0;
103
- try {
104
- const result = await crewx.execute(agentRef, finalMessage, {
105
- provider,
106
- effort: effort || undefined,
107
- overdrive: overdrive || undefined,
108
- threadId: thread,
109
- metadata: Object.keys(parsedMetadata).length > 0 ? parsedMetadata : undefined,
110
- vars: Object.keys(vars).length > 0 ? vars : undefined,
111
- trace: (0, inherited_trace_1.readInheritedTrace)(),
112
- });
113
- if (!result.ok) {
114
- const errMsg = result.error?.message ?? 'Execute failed';
115
- console.error(errMsg);
116
- (0, write_output_1.appendError)(out, errMsg);
117
- exitCode = 1;
118
- }
119
- else {
120
- if (verbose) {
121
- process.stderr.write(`\nšŸ“Š Results from ${agentRef}:\n`);
122
- process.stderr.write('═'.repeat(60) + '\n');
123
- process.stderr.write('🟢 Status: Success\n');
124
- process.stderr.write(`šŸ¤– Provider: ${result.meta.provider}\n`);
125
- process.stderr.write(`ā±ļø Duration: ${result.meta.durationMs}ms\n`);
126
- process.stderr.write('\nšŸ“„ Response:\n');
127
- process.stderr.write('─'.repeat(40) + '\n');
128
- }
129
- (0, write_output_1.writeResult)(out, result.data);
130
- if (verbose) {
131
- process.stderr.write('\nāœ… Execute completed successfully\n');
132
- }
133
- }
134
- }
135
- catch (err) {
136
- const errMsg = err instanceof Error ? err.message : String(err);
137
- console.error(`Error: ${errMsg}`);
138
- (0, write_output_1.appendError)(out, `Error: ${errMsg}`);
139
- exitCode = 1;
140
- }
141
- finally {
142
- await crewx.close();
143
- }
144
- if (exitCode !== 0)
145
- process.exit(exitCode);
146
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.runDetachedMiddle=void 0;exports.handleExecute=Y;const F=require("@crewx/sdk");const V=require("@crewx/sdk/repository");const z=require("./parse-agent-message");const j=require("./parse-common-flags");const K=require("./resolve-recipient");const L=require("./resolve-prompt");const Q=require("../bootstrap/crewx-cli");const v=require("../utils/inherited-trace");const D=require("./write-output");const i=require("./detached");const s=require("./emit-trailer");var S=require("./detached");Object.defineProperty(exports,"runDetachedMiddle",{enumerable:true,get:function(){return S.runDetachedMiddle}});async function Y(u,r="execute",a=(0,s.createDelegationEmitState)()){const I=(0,i.readDetachedMiddleHop)(u);if(I){await(0,i.runDetachedMiddle)(r,I);return}const p=(0,i.extractReceiptFlags)(u);const m=(0,i.resolveReceiptMode)({detach:p.detach,wait:p.wait,detachedRunner:(0,v.isDetachedRunner)(),agentContext:Boolean(process.env["CREWX_AGENT_ID"])});if(m.receipt){await(0,i.runDetached)(r,p.rest,m.reason,u);return}let b;try{b=(0,j.parseCommonFlags)(p.rest)}catch(e){(0,s.emitDelegationResult)({command:r,isError:true,state:a});throw e}const{thread:x,provider:k,model:E,metadata:N,verbose:f,config:H,outputFormat:A,effort:R,promptFile:B,overdrive:M,vars:T,out:_,rest:G,to:W}=b;const n=(0,v.readInheritedTrace)();let $;let q;let c;try{({agentRef:$,message:q}=(0,z.parseAgentMessage)(G));c=await(0,L.resolvePrompt)(q,B)}catch(e){(0,s.emitDelegationResult)({command:r,trace:n,isError:true,state:a});throw e}let g;try{({agentRef:g}=(0,K.resolveRecipient)({positionalRef:$,toFlag:W,agentContext:Boolean(process.env["CREWX_AGENT_ID"]),bodyForHint:c,command:r,invocationArgs:u}))}catch(e){const t=e instanceof Error?e.message:String(e);process.stderr.write(`Error: ${t}
2
+ `);(0,s.emitDelegationResult)({command:r,trace:n,isError:true,state:a});process.exit(2);return}if(!c){console.error("Usage: crewx execute --to <agent> <task> [options]");console.error(" crewx x --to <agent> <task> [options]");console.error(' Human-terminal shorthand: crewx x "@agent <task>"');console.error("");console.error(" Agent calls require --to or a positional @agent recipient.");console.error(" Human terminal and cron calls default to @crewx when omitted.");console.error(" Task body can also be supplied via stdin pipe or --prompt-file.");console.error("");console.error("Examples:");console.error(' crewx x --to agent "do something"');console.error(" crewx x --to agent -f task.md");console.error(" Prompt files contain only the body; set the recipient separately with --to.");console.error("");console.error("Options:");console.error(" --to <agent> Explicit agent recipient");console.error(" --thread <name> Conversation thread name");console.error(" --provider <cli/xxx> Provider override");console.error(" --model <name> Model override (e.g. claude-sonnet-5)");console.error(" --metadata <json> Extra metadata (JSON object, double-quoted).");console.error(" Propagated to events/hooks/tracing.");console.error(" Invalid JSON aborts with exit code 2.");console.error(` e.g. --metadata='{"workflow_id":"wf-1"}'`);console.error(" --verbose Debug output mode");console.error(" --config/-c <path> Config file path");console.error(" --output-format <fmt> Output format (json|text|stream-json)");console.error(" --out/-o <path> Save result to file (stdout suppressed)");console.error(" --effort <level> Model effort (high|medium|low)");console.error(" -f/--prompt-file <path> Read body only from file; set recipient separately with --to");console.error(" --var key=value Template variable (repeatable)");console.error(" --overdrive Activate overdrive (boost) profile for this request");(0,s.emitDelegationResult)({command:r,trace:n,isError:true,state:a});process.exit(1);return}const X=H??process.env.CREWX_CONFIG??"crewx.yaml";(0,F.setAuditVerbose)(f);let y;try{y=await(0,Q.createCliCrewx)(X)}catch(e){(0,s.emitDelegationResult)({command:r,trace:n,isError:true,state:a});throw e}if(f){process.stderr.write(`mode=sync reason=${m.reason}
3
+ `);process.stderr.write(`\u{1F4CB} Task: ${c}
4
+ `);process.stderr.write(`\u{1F916} Agent: ${g}
5
+ `);if(x)process.stderr.write(`\u{1F517} Thread: ${x}
6
+ `);if(k)process.stderr.write(`\u{1F50C} Provider: ${k}
7
+ `);if(E)process.stderr.write(`\u{1F9E0} Model: ${E}
8
+ `);if(A)process.stderr.write(`\u{1F4C4} Output-format: ${A}
9
+ `);if(R)process.stderr.write(`\u26A1 Effort: ${R}
10
+ `);if(M)process.stderr.write("\u{1F680} Overdrive: ON\n");process.stderr.write("\u2500".repeat(60)+"\n")}let h={};try{h=(0,j.parseMetadata)(N)}catch(e){const t=e instanceof Error?e.message:String(e);process.stderr.write(`Error: ${t}
11
+ `);(0,s.emitDelegationResult)({command:r,trace:n,isError:true,state:a});process.exit(2);return}const J=(0,i.resolveCliTaskActor)(h);const U=(0,v.isDetachedRunner)();const C=(0,v.readRunnerAssignment)();let w;let O;let P;if(C!==void 0){const e=new V.TaskRepository;const t=(0,i.adoptAssignedTask)(e,C,U);if(t.kind==="failed"){(0,s.emitDelegationResult)({command:r,trace:n,isError:true,state:a});process.exit(1);return}if(t.kind==="adopted"){w=t.taskId;O=(0,i.readAssignedTaskActor)(e,t.taskId);P=(0,i.readAssignedTaskProviderAccountId)(e,t.taskId)}}let d;if(w===void 0){d=(0,F.admitDurableTask)(`direct-cli:${r}`);if(!d.ok){(0,i.reportAdmissionBlocked)(d);(0,s.emitDelegationResult)({command:r,trace:n,isError:true,state:a});process.exit(1);return}}let l=0;let o;try{try{o=await y.execute(g,c,{provider:k,model:E,effort:R||void 0,overdrive:M||void 0,threadId:x,taskId:w,actor:w===void 0?J:O,metadata:Object.keys(h).length>0?h:void 0,vars:Object.keys(T).length>0?T:void 0,trace:n,providerAccountId:P});if(!o.ok){const e=o.error?.message??"Execute failed";console.error(e);(0,D.appendError)(_,e);l=1}else{if(f){process.stderr.write(`
12
+ \u{1F4CA} Results from ${g}:
13
+ `);process.stderr.write("\u2550".repeat(60)+"\n");process.stderr.write("\u{1F7E2} Status: Success\n");process.stderr.write(`\u{1F916} Provider: ${o.meta.provider}
14
+ `);process.stderr.write(`\u23F1\uFE0F Duration: ${o.meta.durationMs}ms
15
+ `);process.stderr.write("\n\u{1F4C4} Response:\n");process.stderr.write("\u2500".repeat(40)+"\n")}(0,D.writeResult)(_,o.data);if(f)process.stderr.write("\n\u2705 Execute completed successfully\n")}}catch(e){const t=e instanceof Error?e.message:String(e);console.error(`Error: ${t}`);(0,D.appendError)(_,`Error: ${t}`);l=1}finally{try{await y.close()}catch(e){(0,s.emitDelegationResult)({command:r,trace:n,taskId:o?.meta.taskId,agentId:o?.meta.agentId,isError:true,state:a});throw e}}}finally{if(d?.ok)d.release()}(0,s.emitDelegationResult)({command:r,trace:n,taskId:o?.meta.taskId,agentId:o?.meta.agentId,isError:l!==0||o?.ok===false,state:a});if(l!==0)process.exit(l)}
@@ -0,0 +1,2 @@
1
+ /** Match only commands that invoke CrewX's hook-dispatch subcommand. */
2
+ export declare const CREWX_HOOK_COMMAND_RE: RegExp;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.CREWX_HOOK_COMMAND_RE=void 0;exports.CREWX_HOOK_COMMAND_RE=/crewx(?:\.js|\.cmd|\.exe)?['"]?\s+hook-dispatch\b/i;
@@ -10,7 +10,6 @@
10
10
  * - Never traverses parent directories — project root determined by crewx.yaml
11
11
  */
12
12
  import { type HookProvider } from './paths';
13
- export declare const CREWX_HOOK_COMMAND_MARKER = "crewx hook-dispatch";
14
13
  export declare function resolveCrewxBinary(): string;
15
14
  export interface HookInstallOpts {
16
15
  projectRoot: string;