@crewx/cli 0.9.0-rc.146 → 0.9.0-rc.147

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 (45) hide show
  1. package/dist/bootstrap/codex-writable-roots.js +1 -113
  2. package/dist/bootstrap/crewx-cli.js +1 -84
  3. package/dist/builtin.js +5 -132
  4. package/dist/commands/agent.js +4 -118
  5. package/dist/commands/cal.js +2 -44
  6. package/dist/commands/db.js +4 -602
  7. package/dist/commands/detached.js +15 -620
  8. package/dist/commands/doctor.js +4 -649
  9. package/dist/commands/emit-trailer.js +2 -33
  10. package/dist/commands/execute.js +15 -294
  11. package/dist/commands/hook/command-marker.js +1 -5
  12. package/dist/commands/hook/install.js +8 -189
  13. package/dist/commands/hook/paths.js +1 -94
  14. package/dist/commands/hook/status.js +1 -86
  15. package/dist/commands/hook/uninstall.js +1 -71
  16. package/dist/commands/hook-dispatch.js +2 -180
  17. package/dist/commands/init.js +31 -437
  18. package/dist/commands/kill.js +1 -11
  19. package/dist/commands/log.js +3 -96
  20. package/dist/commands/parse-agent-message.js +1 -52
  21. package/dist/commands/parse-common-flags.js +3 -212
  22. package/dist/commands/ps.js +2 -117
  23. package/dist/commands/publish.js +7 -283
  24. package/dist/commands/query.js +16 -292
  25. package/dist/commands/registry.js +1 -33
  26. package/dist/commands/resolve-prompt.js +3 -76
  27. package/dist/commands/resolve-recipient.js +3 -47
  28. package/dist/commands/restart.js +18 -172
  29. package/dist/commands/result.js +1 -209
  30. package/dist/commands/shortcut.js +4 -253
  31. package/dist/commands/slack.js +16 -560
  32. package/dist/commands/stop.js +8 -119
  33. package/dist/commands/write-output.js +1 -24
  34. package/dist/index.js +1 -8
  35. package/dist/logging.js +10 -87
  36. package/dist/main.js +6 -289
  37. package/dist/register-builtin-tools.js +1 -9
  38. package/dist/slack/file-download.js +1 -134
  39. package/dist/slack/markdown.js +1 -33
  40. package/dist/utils/env-defaults.js +1 -15
  41. package/dist/utils/inherited-trace.js +1 -65
  42. package/dist/utils/product-package-root.js +1 -39
  43. package/dist/utils/sdk-compat.js +1 -120
  44. package/dist/utils/version.js +1 -28
  45. package/package.json +15 -15
@@ -1,66 +1,4 @@
1
- "use strict";
2
- /**
3
- * crewx init handler.
4
- * Initializes a CrewX project by creating crewx.yaml and supporting dirs.
5
- *
6
- * Usage:
7
- * crewx init Create crewx.yaml in current directory
8
- * crewx init --force Overwrite existing configuration
9
- */
10
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- var desc = Object.getOwnPropertyDescriptor(m, k);
13
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
- desc = { enumerable: true, get: function() { return m[k]; } };
15
- }
16
- Object.defineProperty(o, k2, desc);
17
- }) : (function(o, m, k, k2) {
18
- if (k2 === undefined) k2 = k;
19
- o[k2] = m[k];
20
- }));
21
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
- Object.defineProperty(o, "default", { enumerable: true, value: v });
23
- }) : function(o, v) {
24
- o["default"] = v;
25
- });
26
- var __importStar = (this && this.__importStar) || (function () {
27
- var ownKeys = function(o) {
28
- ownKeys = Object.getOwnPropertyNames || function (o) {
29
- var ar = [];
30
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
- return ar;
32
- };
33
- return ownKeys(o);
34
- };
35
- return function (mod) {
36
- if (mod && mod.__esModule) return mod;
37
- var result = {};
38
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
- __setModuleDefault(result, mod);
40
- return result;
41
- };
42
- })();
43
- var __importDefault = (this && this.__importDefault) || function (mod) {
44
- return (mod && mod.__esModule) ? mod : { "default": mod };
45
- };
46
- Object.defineProperty(exports, "__esModule", { value: true });
47
- exports.buildDefaultAgents = buildDefaultAgents;
48
- exports.parseInitProvider = parseInitProvider;
49
- exports.resolveInitProvider = resolveInitProvider;
50
- exports.handleInit = handleInit;
51
- const fs_1 = require("fs");
52
- const path_1 = require("path");
53
- const path = __importStar(require("path"));
54
- const git = __importStar(require("isomorphic-git"));
55
- const nodeFs = __importStar(require("fs"));
56
- const os_1 = __importDefault(require("os"));
57
- const repository_1 = require("@crewx/sdk/repository");
58
- const sdk_1 = require("@crewx/sdk");
59
- const install_1 = require("./hook/install");
60
- const STATUSLINE_SCRIPT_NAME = 'claude-usage-statusline.js';
61
- const STATUSLINE_SCRIPT_MARKER = 'CrewX claude-usage-statusline';
62
- // Reads Claude Code rate_limits from stdin payload and dumps to ~/.crewx/claude-usage.json
63
- const STATUSLINE_SCRIPT_CONTENT = `// ${STATUSLINE_SCRIPT_MARKER}
1
+ "use strict";var $=exports&&exports.__createBinding||(Object.create?(function(t,e,i,n){if(n===void 0)n=i;var r=Object.getOwnPropertyDescriptor(e,i);if(!r||("get"in r?!e.__esModule:r.writable||r.configurable)){r={enumerable:true,get:function(){return e[i]}}}Object.defineProperty(t,n,r)}):(function(t,e,i,n){if(n===void 0)n=i;t[n]=e[i]}));var j=exports&&exports.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:true,value:e})}):function(t,e){t["default"]=e});var w=exports&&exports.__importStar||(function(){var t=function(e){t=Object.getOwnPropertyNames||function(i){var n=[];for(var r in i)if(Object.prototype.hasOwnProperty.call(i,r))n[n.length]=r;return n};return t(e)};return function(e){if(e&&e.__esModule)return e;var i={};if(e!=null){for(var n=t(e),r=0;r<n.length;r++)if(n[r]!=="default")$(i,e,n[r])}j(i,e);return i}})();var F=exports&&exports.__importDefault||function(t){return t&&t.__esModule?t:{"default":t}};Object.defineProperty(exports,"__esModule",{value:true});exports.buildDefaultAgents=P;exports.parseInitProvider=z;exports.resolveInitProvider=b;exports.handleInit=V;const s=require("fs");const d=require("path");const u=w(require("path"));const _=w(require("isomorphic-git"));const I=w(require("fs"));const E=F(require("os"));const M=require("@crewx/sdk/repository");const f=require("@crewx/sdk");const N=require("./hook/install");const q="claude-usage-statusline.js";const W="CrewX claude-usage-statusline";const Y=`// ${W}
64
2
  // Dumps Claude Code rate_limits (stdin payload) to ~/.crewx/claude-usage.json
65
3
  const fs = require('fs');
66
4
  const os = require('os');
@@ -82,13 +20,10 @@ process.stdin.on('end', () => {
82
20
  }
83
21
  } catch (_) {}
84
22
  });
85
- `;
86
- const INIT_AUTHOR = { name: 'CrewX', email: 'crewx@local' };
87
- const CREWX_MARKER = '# CrewX runtime';
88
- const CREWX_GITIGNORE = `# CrewX runtime
23
+ `;const G={name:"CrewX",email:"crewx@local"};const K="# CrewX runtime";const L=`# CrewX runtime
89
24
  .crewx/
90
25
 
91
- # Secrets (workspace .env — see docs/manual)
26
+ # Secrets (workspace .env \u2014 see docs/manual)
92
27
  .env
93
28
  .env.*
94
29
  !.env.example
@@ -105,73 +40,15 @@ skills/*/logs/
105
40
  skills/*/.crewx/
106
41
 
107
42
  # OS
108
- .DS_Store`.trim();
109
- /** Build the three default agents using the selected CLI provider profile. */
110
- function buildDefaultAgents(provider) {
111
- const profile = (0, sdk_1.getDefaultAgentProfile)(provider);
112
- if (!profile) {
113
- throw new Error(`DEFAULT_AGENT_PROFILE_NOT_FOUND: ${provider}`);
114
- }
115
- return [
116
- {
117
- id: 'planner',
118
- name: 'Planner',
119
- role: 'Product/Architecture Planner',
120
- team: 'core',
121
- provider,
122
- working_directory: './',
123
- description: 'Owns requirements analysis, design, and work breakdown',
124
- options: {
125
- query: profile.planner.query,
126
- execute: profile.planner.execute,
127
- },
128
- inline: {
129
- model: profile.planner.model,
130
- prompt: `You are a planner. Break down user goals into concrete,\ntestable steps. Challenge assumptions. Never write code directly.`,
131
- },
132
- },
133
- {
134
- id: 'developer',
135
- name: 'Developer',
136
- role: 'Implementation Engineer',
137
- team: 'core',
138
- provider,
139
- working_directory: './',
140
- description: 'Implements code changes and tests',
141
- options: {
142
- query: profile.worker.query,
143
- execute: profile.worker.execute,
144
- },
145
- inline: {
146
- model: profile.worker.model,
147
- prompt: `Implement what the planner specifies. Prefer editing\nexisting files. Run tests before reporting done.`,
148
- },
149
- },
150
- {
151
- id: 'reviewer',
152
- name: 'Reviewer',
153
- role: 'Code Reviewer',
154
- team: 'core',
155
- provider,
156
- working_directory: './',
157
- description: 'Reviews code quality, security, and readability',
158
- options: {
159
- query: profile.worker.query,
160
- execute: profile.worker.execute,
161
- },
162
- inline: {
163
- model: profile.worker.model,
164
- prompt: `Review diffs for correctness, security, readability.\nCite file:line. Be blunt, not polite.`,
165
- },
166
- },
167
- ];
168
- }
169
- const GOAL_TEMPLATE = `---
43
+ .DS_Store`.trim();function P(t){const e=(0,f.getDefaultAgentProfile)(t);if(!e){throw new Error(`DEFAULT_AGENT_PROFILE_NOT_FOUND: ${t}`)}return[{id:"planner",name:"Planner",role:"Product/Architecture Planner",team:"core",provider:t,working_directory:"./",description:"Owns requirements analysis, design, and work breakdown",options:{query:e.planner.query,execute:e.planner.execute},inline:{model:e.planner.model,prompt:`You are a planner. Break down user goals into concrete,
44
+ testable steps. Challenge assumptions. Never write code directly.`}},{id:"developer",name:"Developer",role:"Implementation Engineer",team:"core",provider:t,working_directory:"./",description:"Implements code changes and tests",options:{query:e.worker.query,execute:e.worker.execute},inline:{model:e.worker.model,prompt:`Implement what the planner specifies. Prefer editing
45
+ existing files. Run tests before reporting done.`}},{id:"reviewer",name:"Reviewer",role:"Code Reviewer",team:"core",provider:t,working_directory:"./",description:"Reviews code quality, security, and readability",options:{query:e.worker.query,execute:e.worker.execute},inline:{model:e.worker.model,prompt:`Review diffs for correctness, security, readability.
46
+ Cite file:line. Be blunt, not polite.`}}]}const B=`---
170
47
  type: goal
171
- description: CrewX Goal — OKR
48
+ description: CrewX Goal \u2014 OKR
172
49
  notation:
173
- weight: "(w:N) — KR weight, default 1 if omitted"
174
- auto: "N% auto — L1 progress auto-calculated as weighted average of children"
50
+ weight: "(w:N) \u2014 KR weight, default 1 if omitted"
51
+ auto: "N% auto \u2014 L1 progress auto-calculated as weighted average of children"
175
52
  ---
176
53
 
177
54
  # Goal Title
@@ -192,8 +69,7 @@ Describe the goal...
192
69
  ## Notes
193
70
 
194
71
  ## Reflection
195
- `;
196
- const DAILY_TEMPLATE = `# YYYY-MM-DD (Day)
72
+ `;const X=`# YYYY-MM-DD (Day)
197
73
 
198
74
  ## Top 3
199
75
  1.
@@ -207,8 +83,7 @@ const DAILY_TEMPLATE = `# YYYY-MM-DD (Day)
207
83
  ## Notes
208
84
 
209
85
  ## Reflection
210
- `;
211
- const WI_TEMPLATE = `---
86
+ `;const U=`---
212
87
  wi_id: WI-{YYYYMMDD}-{SEQ}
213
88
  title: ""
214
89
  date: ""
@@ -248,7 +123,7 @@ consumers:
248
123
  # store: useThreadDetailStore
249
124
  # component: MessageBubble
250
125
 
251
- # Estimated scope (atomicity: ≤ $0.30, 1-3 files)
126
+ # Estimated scope (atomicity: \u2264 $0.30, 1-3 files)
252
127
  estimated_files: 0
253
128
  estimated_cost: "$0.00"
254
129
  ---
@@ -318,7 +193,7 @@ npx doc section {design_doc} "{spec_id}"
318
193
  | Level | Condition |
319
194
  |-------|-----------|
320
195
  | \`low\` | Single file, no API change, existing tests sufficient |
321
- | \`medium\` | 2-3 files, API change with ≤ 1 consumer |
196
+ | \`medium\` | 2-3 files, API change with \u2264 1 consumer |
322
197
  | \`high\` | API change + 2+ consumers, or store refactoring |
323
198
  | \`critical\` | DB schema change, or core SDK interface change |
324
199
 
@@ -362,318 +237,37 @@ N tests passed
362
237
  ### Commit
363
238
  - hash: <commit hash>
364
239
  - branch: <worktree branch>
365
- (empty = completion report invalid — worktree tasks only)
240
+ (empty = completion report invalid \u2014 worktree tasks only)
366
241
 
367
242
  ### Remaining items
368
243
  None / (list if any)
369
244
  \`\`\`
370
- `;
371
- function indentBlock(text, spaces) {
372
- const prefix = ' '.repeat(spaces);
373
- return text
374
- .split('\n')
375
- .map((line) => `${prefix}${line}`)
376
- .join('\n');
377
- }
378
- function generateDefaultYaml(agents) {
379
- const agentBlocks = agents
380
- .map((a) => ` - id: "${a.id}"
381
- name: "${a.name}"
382
- role: "${a.role}"
383
- team: "${a.team}"
384
- provider: "${a.provider}"
385
- working_directory: "${a.working_directory}"
386
- description: "${a.description}"
245
+ `;function H(t,e){const i=" ".repeat(e);return t.split("\n").map(n=>`${i}${n}`).join("\n")}function J(t){const e=t.map(i=>` - id: "${i.id}"
246
+ name: "${i.name}"
247
+ role: "${i.role}"
248
+ team: "${i.team}"
249
+ provider: "${i.provider}"
250
+ working_directory: "${i.working_directory}"
251
+ description: "${i.description}"
387
252
  options:
388
253
  query:
389
- mode: "${a.options.query.mode}"
390
- effort: "${a.options.query.effort}"
254
+ mode: "${i.options.query.mode}"
255
+ effort: "${i.options.query.effort}"
391
256
  execute:
392
- mode: "${a.options.execute.mode}"
393
- effort: "${a.options.execute.effort}"
257
+ mode: "${i.options.execute.mode}"
258
+ effort: "${i.options.execute.effort}"
394
259
  inline:
395
- model: "${a.inline.model}"
260
+ model: "${i.inline.model}"
396
261
  prompt: |
397
- ${indentBlock(a.inline.prompt, 8)}`)
398
- .join('\n\n');
399
- return `# CrewX Agents Configuration
262
+ ${H(i.inline.prompt,8)}`).join("\n\n");return`# CrewX Agents Configuration
400
263
  # Generated by 'crewx init'
401
264
 
402
265
  agents:
403
- ${agentBlocks}
266
+ ${e}
404
267
 
405
268
  # Usage examples:
406
269
  # crewx q --to planner "analyze this codebase"
407
270
  # crewx x --to developer "implement the feature described above"
408
271
  # crewx agent ls
409
- `;
410
- }
411
- function isInitProvider(value) {
412
- return value === 'cli/claude' || value === 'cli/codex';
413
- }
414
- function invalidProviderError(value) {
415
- if (value === undefined || value.length === 0) {
416
- return new Error('Missing --provider value. Expected: cli/claude | cli/codex');
417
- }
418
- return new Error(`Invalid --provider value: "${value}". Expected: cli/claude | cli/codex`);
419
- }
420
- /** Parse the provider option accepted by `crewx init`. */
421
- function parseInitProvider(args) {
422
- for (let index = 0; index < args.length; index += 1) {
423
- const arg = args[index];
424
- if (arg === '--provider') {
425
- const value = args[index + 1];
426
- if (value === undefined || value.startsWith('--'))
427
- throw invalidProviderError(undefined);
428
- if (!isInitProvider(value))
429
- throw invalidProviderError(value);
430
- return value;
431
- }
432
- if (arg?.startsWith('--provider=')) {
433
- const value = arg.slice('--provider='.length);
434
- if (!isInitProvider(value))
435
- throw invalidProviderError(value);
436
- return value;
437
- }
438
- }
439
- return undefined;
440
- }
441
- /** Resolve an explicit provider or detect Claude, then Codex, using PATH only. */
442
- function resolveInitProvider(provider, deps = {}) {
443
- if (provider !== undefined)
444
- return provider;
445
- if ((0, sdk_1.isProviderAvailable)('cli/claude', deps))
446
- return 'cli/claude';
447
- if ((0, sdk_1.isProviderAvailable)('cli/codex', deps))
448
- return 'cli/codex';
449
- return 'cli/claude';
450
- }
451
- /**
452
- * Programmatic init — creates crewx.yaml, support dirs, and optionally installs hooks.
453
- * Throws on unrecoverable errors (PATH_NOT_FOUND, YAML_CREATE_FAILED).
454
- * Partial failures (hook install, mkdir, workspace registration) are collected in InitResult.errors.
455
- * Workspace registration is always attempted (even when yaml already exists) so that CLI and
456
- * server paths both produce a row in ~/.crewx/crewx.db.
457
- */
458
- async function handleInit(opts) {
459
- const { path: target, skipHook = false, force = false, provider: requestedProvider } = opts;
460
- const provider = resolveInitProvider(requestedProvider);
461
- const errors = [];
462
- let yamlCreated = false;
463
- let hookInstalled = false;
464
- let skippedReason;
465
- if (!(0, fs_1.existsSync)(target)) {
466
- throw new Error(`PATH_NOT_FOUND: ${target}`);
467
- }
468
- const yamlPath = (0, path_1.join)(target, 'crewx.yaml');
469
- const ymlPath = (0, path_1.join)(target, 'crewx.yml');
470
- if ((0, fs_1.existsSync)(yamlPath) || (0, fs_1.existsSync)(ymlPath)) {
471
- if (!force) {
472
- // yaml already exists: skip creation but still register workspace below
473
- skippedReason = 'yaml-exists';
474
- }
475
- }
476
- if (!skippedReason) {
477
- try {
478
- const content = generateDefaultYaml(buildDefaultAgents(provider));
479
- (0, fs_1.writeFileSync)(yamlPath, content, 'utf-8');
480
- yamlCreated = true;
481
- }
482
- catch (e) {
483
- throw new Error(`YAML_CREATE_FAILED: ${e.message}`);
484
- }
485
- if (!skipHook) {
486
- try {
487
- await (0, install_1.handleHookInstall)({ projectRoot: target, yes: true });
488
- hookInstalled = true;
489
- }
490
- catch (e) {
491
- errors.push(`HOOK_INSTALL_FAILED: ${e.message}`);
492
- }
493
- }
494
- }
495
- // Always create docs dirs and templates, regardless of whether yaml was skipped
496
- for (const dir of ['.crewx/logs', '.claude/commands', 'docs/goal', 'docs/daily', 'docs/wi', 'workflows']) {
497
- try {
498
- (0, fs_1.mkdirSync)((0, path_1.join)(target, dir), { recursive: true });
499
- }
500
- catch (e) {
501
- errors.push(`MKDIR_FAILED:${dir}:${e.message}`);
502
- }
503
- }
504
- const docTemplates = [
505
- { dir: 'docs/goal', file: 'GOAL-TEMPLATE.md', content: GOAL_TEMPLATE },
506
- { dir: 'docs/daily', file: 'DAILY-TEMPLATE.md', content: DAILY_TEMPLATE },
507
- { dir: 'docs/wi', file: 'WI-TEMPLATE.md', content: WI_TEMPLATE },
508
- ];
509
- for (const t of docTemplates) {
510
- const fullPath = (0, path_1.join)(target, t.dir, t.file);
511
- if (force || !(0, fs_1.existsSync)(fullPath)) {
512
- const action = (0, fs_1.existsSync)(fullPath) ? 'updated' : 'created';
513
- (0, fs_1.writeFileSync)(fullPath, t.content, 'utf-8');
514
- console.log(`✅ ${t.dir}/ ${action} (${t.file})`);
515
- }
516
- }
517
- try {
518
- const workflowTemplatesDir = (0, sdk_1.resolveWorkflowTemplatesPath)();
519
- for (const filename of [sdk_1.WI_DEFAULT_FLOW_FILENAME, sdk_1.WI_PLAN_FLOW_FILENAME]) {
520
- const sourcePath = (0, path_1.join)(workflowTemplatesDir, filename);
521
- const targetPath = (0, path_1.join)(target, 'workflows', filename);
522
- if (force || !(0, fs_1.existsSync)(targetPath)) {
523
- const action = (0, fs_1.existsSync)(targetPath) ? 'updated' : 'created';
524
- (0, fs_1.copyFileSync)(sourcePath, targetPath);
525
- console.log(`✅ workflows/ ${action} (${filename})`);
526
- }
527
- }
528
- }
529
- catch (e) {
530
- errors.push(`WORKFLOW_TEMPLATE_FAILED:${e.message}`);
531
- }
532
- // Always register workspace in ~/.crewx/crewx.db (best-effort, idempotent)
533
- let workspaceId;
534
- let slug;
535
- try {
536
- const ws = new repository_1.WorkspaceRepository().registerWorkspace(target);
537
- workspaceId = ws.id;
538
- slug = ws.slug;
539
- }
540
- catch (e) {
541
- errors.push(`WORKSPACE_REGISTER_FAILED: ${e.message}`);
542
- }
543
- const gitignorePath = (0, path_1.join)(target, '.gitignore');
544
- if (!(0, fs_1.existsSync)(gitignorePath)) {
545
- (0, fs_1.writeFileSync)(gitignorePath, CREWX_GITIGNORE + '\n', 'utf-8');
546
- console.log('✅ .gitignore updated with CrewX entries');
547
- }
548
- else {
549
- const existing = (0, fs_1.readFileSync)(gitignorePath, 'utf-8');
550
- if (!existing.includes(CREWX_MARKER)) {
551
- const separator = existing.endsWith('\n') ? '\n' : '\n\n';
552
- (0, fs_1.appendFileSync)(gitignorePath, separator + CREWX_GITIGNORE + '\n', 'utf-8');
553
- console.log('✅ .gitignore updated with CrewX entries');
554
- }
555
- else {
556
- console.log('ℹ .gitignore already contains CrewX entries');
557
- }
558
- }
559
- // Git auto-initialization
560
- await initGitRepo(target, errors);
561
- // Idempotent statusLine merge into ~/.claude/settings.json
562
- const statusLineResult = ensureClaudeStatusLine();
563
- return { yamlCreated, hookInstalled, errors, provider, skippedReason, workspaceId, slug, ...statusLineResult };
564
- }
565
- function ensureClaudeStatusLine() {
566
- const home = os_1.default.homedir();
567
- const crewxDir = path.join(home, '.crewx');
568
- const scriptPath = path.join(crewxDir, STATUSLINE_SCRIPT_NAME);
569
- const settingsPath = path.join(home, '.claude', 'settings.json');
570
- // Always write/update the dump script itself (idempotent: same content)
571
- try {
572
- (0, fs_1.mkdirSync)(crewxDir, { recursive: true });
573
- (0, fs_1.writeFileSync)(scriptPath, STATUSLINE_SCRIPT_CONTENT, 'utf-8');
574
- }
575
- catch (_) {
576
- return { statusLineConfigured: false, statusLineSkipped: false };
577
- }
578
- const statusLineValue = `node ${scriptPath}`;
579
- let settings = {};
580
- if ((0, fs_1.existsSync)(settingsPath)) {
581
- try {
582
- settings = JSON.parse((0, fs_1.readFileSync)(settingsPath, 'utf-8'));
583
- }
584
- catch (_) {
585
- settings = {};
586
- }
587
- }
588
- if (typeof settings.statusLine === 'string' && settings.statusLine !== '') {
589
- // Already our script — no-op
590
- if (settings.statusLine === statusLineValue) {
591
- console.log('ℹ statusLine already configured (CrewX claude-usage dump)');
592
- return { statusLineConfigured: false, statusLineSkipped: false };
593
- }
594
- // Existing user statusLine — skip, do not overwrite
595
- console.log('ℹ statusLine already set in ~/.claude/settings.json — skipping Claude usage dump setup.\n' +
596
- ' To enable manually, set "statusLine" to: ' +
597
- statusLineValue);
598
- return { statusLineConfigured: false, statusLineSkipped: true };
599
- }
600
- // No existing statusLine — inject ours
601
- try {
602
- settings.statusLine = statusLineValue;
603
- const claudeDir = path.join(home, '.claude');
604
- (0, fs_1.mkdirSync)(claudeDir, { recursive: true });
605
- (0, fs_1.writeFileSync)(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
606
- console.log('✅ statusLine configured for Claude usage dump (~/.claude/settings.json)');
607
- return { statusLineConfigured: true, statusLineSkipped: false };
608
- }
609
- catch (_) {
610
- return { statusLineConfigured: false, statusLineSkipped: false };
611
- }
612
- }
613
- async function initGitRepo(target, errors) {
614
- // Danger path guards — skip git steps but keep init successful
615
- const home = os_1.default.homedir();
616
- if (target === home) {
617
- console.log('ℹ git init skipped: target is home directory');
618
- return;
619
- }
620
- // Check filesystem root
621
- const parsedPath = path.parse(target);
622
- if (parsedPath.root === target || target === '/') {
623
- console.log('ℹ git init skipped: target is filesystem root');
624
- return;
625
- }
626
- // Check if ancestor has .git (target is inside existing git repo)
627
- let checkDir = path.dirname(target);
628
- while (checkDir !== path.parse(checkDir).root) {
629
- if ((0, fs_1.existsSync)((0, path_1.join)(checkDir, '.git'))) {
630
- console.log(`ℹ git init skipped: already inside a git repo (${checkDir})`);
631
- return;
632
- }
633
- const parent = path.dirname(checkDir);
634
- if (parent === checkDir)
635
- break;
636
- checkDir = parent;
637
- }
638
- // Skip if .git already exists in target
639
- if ((0, fs_1.existsSync)((0, path_1.join)(target, '.git'))) {
640
- console.log('ℹ git init skipped: .git already exists');
641
- return;
642
- }
643
- // Initialize git repo
644
- try {
645
- await git.init({ fs: nodeFs, dir: target, defaultBranch: 'main' });
646
- console.log('✅ git repository initialized (main branch)');
647
- }
648
- catch (e) {
649
- errors.push(`GIT_INIT_FAILED: ${e.message}`);
650
- return;
651
- }
652
- // Ensure node_modules/ in .gitignore
653
- const gitignorePath = (0, path_1.join)(target, '.gitignore');
654
- if ((0, fs_1.existsSync)(gitignorePath)) {
655
- const content = (0, fs_1.readFileSync)(gitignorePath, 'utf-8');
656
- if (!content.includes('node_modules/')) {
657
- const separator = content.endsWith('\n') ? '' : '\n';
658
- (0, fs_1.appendFileSync)(gitignorePath, `${separator}node_modules/\n`, 'utf-8');
659
- }
660
- }
661
- else {
662
- (0, fs_1.writeFileSync)(gitignorePath, 'node_modules/\n', 'utf-8');
663
- }
664
- // Initial commit
665
- try {
666
- // Stage all files
667
- await git.add({ fs: nodeFs, dir: target, filepath: '.' });
668
- await git.commit({
669
- fs: nodeFs,
670
- dir: target,
671
- message: 'chore: crewx init',
672
- author: INIT_AUTHOR,
673
- });
674
- console.log('✅ initial commit created (chore: crewx init)');
675
- }
676
- catch (e) {
677
- errors.push(`GIT_COMMIT_FAILED: ${e.message}`);
678
- }
679
- }
272
+ `}function T(t){return t==="cli/claude"||t==="cli/codex"}function S(t){if(t===void 0||t.length===0){return new Error("Missing --provider value. Expected: cli/claude | cli/codex")}return new Error(`Invalid --provider value: "${t}". Expected: cli/claude | cli/codex`)}function z(t){for(let e=0;e<t.length;e+=1){const i=t[e];if(i==="--provider"){const n=t[e+1];if(n===void 0||n.startsWith("--"))throw S(void 0);if(!T(n))throw S(n);return n}if(i?.startsWith("--provider=")){const n=i.slice("--provider=".length);if(!T(n))throw S(n);return n}}return void 0}function b(t,e={}){if(t!==void 0)return t;if((0,f.isProviderAvailable)("cli/claude",e))return"cli/claude";if((0,f.isProviderAvailable)("cli/codex",e))return"cli/codex";return"cli/claude"}async function V(t){const{path:e,skipHook:i=false,force:n=false,provider:r}=t;const c=b(r);const a=[];let p=false;let k=false;let g;if(!(0,s.existsSync)(e)){throw new Error(`PATH_NOT_FOUND: ${e}`)}const v=(0,d.join)(e,"crewx.yaml");const x=(0,d.join)(e,"crewx.yml");if((0,s.existsSync)(v)||(0,s.existsSync)(x)){if(!n){g="yaml-exists"}}if(!g){try{const o=J(P(c));(0,s.writeFileSync)(v,o,"utf-8");p=true}catch(o){throw new Error(`YAML_CREATE_FAILED: ${o.message}`)}if(!i){try{await(0,N.handleHookInstall)({projectRoot:e,yes:true});k=true}catch(o){a.push(`HOOK_INSTALL_FAILED: ${o.message}`)}}}for(const o of[".crewx/logs",".claude/commands","docs/goal","docs/daily","docs/wi","workflows"]){try{(0,s.mkdirSync)((0,d.join)(e,o),{recursive:true})}catch(l){a.push(`MKDIR_FAILED:${o}:${l.message}`)}}const C=[{dir:"docs/goal",file:"GOAL-TEMPLATE.md",content:B},{dir:"docs/daily",file:"DAILY-TEMPLATE.md",content:X},{dir:"docs/wi",file:"WI-TEMPLATE.md",content:U}];for(const o of C){const l=(0,d.join)(e,o.dir,o.file);if(n||!(0,s.existsSync)(l)){const h=(0,s.existsSync)(l)?"updated":"created";(0,s.writeFileSync)(l,o.content,"utf-8");console.log(`\u2705 ${o.dir}/ ${h} (${o.file})`)}}try{const o=(0,f.resolveWorkflowTemplatesPath)();for(const l of[f.WI_DEFAULT_FLOW_FILENAME,f.WI_PLAN_FLOW_FILENAME]){const h=(0,d.join)(o,l);const y=(0,d.join)(e,"workflows",l);if(n||!(0,s.existsSync)(y)){const R=(0,s.existsSync)(y)?"updated":"created";(0,s.copyFileSync)(h,y);console.log(`\u2705 workflows/ ${R} (${l})`)}}}catch(o){a.push(`WORKFLOW_TEMPLATE_FAILED:${o.message}`)}let A;let D;try{const o=new M.WorkspaceRepository().registerWorkspace(e);A=o.id;D=o.slug}catch(o){a.push(`WORKSPACE_REGISTER_FAILED: ${o.message}`)}const m=(0,d.join)(e,".gitignore");if(!(0,s.existsSync)(m)){(0,s.writeFileSync)(m,L+"\n","utf-8");console.log("\u2705 .gitignore updated with CrewX entries")}else{const o=(0,s.readFileSync)(m,"utf-8");if(!o.includes(K)){const l=o.endsWith("\n")?"\n":"\n\n";(0,s.appendFileSync)(m,l+L+"\n","utf-8");console.log("\u2705 .gitignore updated with CrewX entries")}else{console.log("\u2139 .gitignore already contains CrewX entries")}}await Z(e,a);const O=Q();return{yamlCreated:p,hookInstalled:k,errors:a,provider:c,skippedReason:g,workspaceId:A,slug:D,...O}}function Q(){const t=E.default.homedir();const e=u.join(t,".crewx");const i=u.join(e,q);const n=u.join(t,".claude","settings.json");try{(0,s.mkdirSync)(e,{recursive:true});(0,s.writeFileSync)(i,Y,"utf-8")}catch(a){return{statusLineConfigured:false,statusLineSkipped:false}}const r=`node ${i}`;let c={};if((0,s.existsSync)(n)){try{c=JSON.parse((0,s.readFileSync)(n,"utf-8"))}catch(a){c={}}}if(typeof c.statusLine==="string"&&c.statusLine!==""){if(c.statusLine===r){console.log("\u2139 statusLine already configured (CrewX claude-usage dump)");return{statusLineConfigured:false,statusLineSkipped:false}}console.log('\u2139 statusLine already set in ~/.claude/settings.json \u2014 skipping Claude usage dump setup.\n To enable manually, set "statusLine" to: '+r);return{statusLineConfigured:false,statusLineSkipped:true}}try{c.statusLine=r;const a=u.join(t,".claude");(0,s.mkdirSync)(a,{recursive:true});(0,s.writeFileSync)(n,JSON.stringify(c,null,2)+"\n","utf-8");console.log("\u2705 statusLine configured for Claude usage dump (~/.claude/settings.json)");return{statusLineConfigured:true,statusLineSkipped:false}}catch(a){return{statusLineConfigured:false,statusLineSkipped:false}}}async function Z(t,e){const i=E.default.homedir();if(t===i){console.log("\u2139 git init skipped: target is home directory");return}const n=u.parse(t);if(n.root===t||t==="/"){console.log("\u2139 git init skipped: target is filesystem root");return}let r=u.dirname(t);while(r!==u.parse(r).root){if((0,s.existsSync)((0,d.join)(r,".git"))){console.log(`\u2139 git init skipped: already inside a git repo (${r})`);return}const a=u.dirname(r);if(a===r)break;r=a}if((0,s.existsSync)((0,d.join)(t,".git"))){console.log("\u2139 git init skipped: .git already exists");return}try{await _.init({fs:I,dir:t,defaultBranch:"main"});console.log("\u2705 git repository initialized (main branch)")}catch(a){e.push(`GIT_INIT_FAILED: ${a.message}`);return}const c=(0,d.join)(t,".gitignore");if((0,s.existsSync)(c)){const a=(0,s.readFileSync)(c,"utf-8");if(!a.includes("node_modules/")){const p=a.endsWith("\n")?"":"\n";(0,s.appendFileSync)(c,`${p}node_modules/
273
+ `,"utf-8")}}else{(0,s.writeFileSync)(c,"node_modules/\n","utf-8")}try{await _.add({fs:I,dir:t,filepath:"."});await _.commit({fs:I,dir:t,message:"chore: crewx init",author:G});console.log("\u2705 initial commit created (chore: crewx init)")}catch(a){e.push(`GIT_COMMIT_FAILED: ${a.message}`)}}
@@ -1,11 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleStop = void 0;
4
- exports.handleKill = handleKill;
5
- /** Compatibility entry point for `crewx kill`; the implementation lives in stop.ts. */
6
- var stop_1 = require("./stop");
7
- Object.defineProperty(exports, "handleStop", { enumerable: true, get: function () { return stop_1.handleStop; } });
8
- const stop_2 = require("./stop");
9
- async function handleKill(args) {
10
- return (0, stop_2.handleStop)(args, 'kill');
11
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.handleStop=void 0;exports.handleKill=r;var t=require("./stop");Object.defineProperty(exports,"handleStop",{enumerable:true,get:function(){return t.handleStop}});const n=require("./stop");async function r(e){return(0,n.handleStop)(e,"kill")}
@@ -1,96 +1,3 @@
1
- "use strict";
2
- /**
3
- * crewx log handler.
4
- * Lists task execution logs or shows a specific task log.
5
- *
6
- * Usage:
7
- * crewx log List all tasks (newest first)
8
- * crewx log ls Same as above
9
- * crewx log <task_id> Show specific task details
10
- */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.handleLog = handleLog;
13
- const sdk_1 = require("@crewx/sdk");
14
- const repository_1 = require("@crewx/sdk/repository");
15
- function statusIcon(status) {
16
- switch (status) {
17
- case 'running': return '⏳';
18
- case 'success': return '✅';
19
- case 'failed': return '❌';
20
- default: return '❓';
21
- }
22
- }
23
- async function handleLog(args) {
24
- const action = args[0];
25
- const isTaskId = action && (action.startsWith('tsk_') || action.startsWith('task_'));
26
- const isListCommand = !action || action === 'ls' || action === 'list';
27
- const repo = new repository_1.TaskRepository();
28
- if (isTaskId) {
29
- const task = repo.getTask(action);
30
- if (!task) {
31
- console.error(`Task not found: ${action}`);
32
- process.exit(1);
33
- return;
34
- }
35
- console.log(`\nTask Log\n${'='.repeat(60)}`);
36
- console.log(`Task ID: ${task.id}`);
37
- console.log(`Status: ${statusIcon(task.status)} ${task.status}`);
38
- console.log(`Agent: ${task.agent_id ?? '—'}`);
39
- console.log(`Mode: ${task.mode ?? '—'}`);
40
- console.log(`Started: ${(0, sdk_1.formatDisplayTimestamp)(new Date(task.started_at))}`);
41
- if (task.completed_at) {
42
- const duration = new Date(task.completed_at).getTime() - new Date(task.started_at).getTime();
43
- console.log(`Completed: ${(0, sdk_1.formatDisplayTimestamp)(new Date(task.completed_at))} (${duration}ms)`);
44
- }
45
- console.log('='.repeat(60));
46
- console.log('');
47
- if (task.status === 'success' && task.result) {
48
- console.log('Result:');
49
- console.log(task.result);
50
- }
51
- else if (task.status === 'failed' && task.error) {
52
- console.log(`Error: ${task.error}`);
53
- }
54
- else if (task.status === 'running') {
55
- console.log('(task is still running)');
56
- }
57
- return;
58
- }
59
- if (isListCommand) {
60
- const allTasks = repo.getAllTasks();
61
- console.log('\nAvailable Task Logs');
62
- console.log('='.repeat(60));
63
- const total = allTasks.length;
64
- const completed = allTasks.filter((t) => t.status === 'success').length;
65
- const failed = allTasks.filter((t) => t.status === 'failed').length;
66
- const running = allTasks.filter((t) => t.status === 'running').length;
67
- console.log(`Total: ${total} | ✅ Completed: ${completed} | ❌ Failed: ${failed} | ⏳ Running: ${running}`);
68
- console.log('='.repeat(60));
69
- console.log('');
70
- if (allTasks.length === 0) {
71
- console.log('No task logs found.');
72
- console.log('Tip: Run `crewx query` or `crewx execute` to create tasks.');
73
- return;
74
- }
75
- allTasks.forEach((task, idx) => {
76
- const icon = statusIcon(task.status);
77
- const duration = task.completed_at
78
- ? `${new Date(task.completed_at).getTime() - new Date(task.started_at).getTime()}ms`
79
- : 'running...';
80
- console.log(`${idx + 1}. ${icon} ${task.id}`);
81
- console.log(` Agent: ${task.agent_id ?? '—'} Mode: ${task.mode ?? '—'}`);
82
- console.log(` Started: ${(0, sdk_1.formatDisplayTimestamp)(new Date(task.started_at))}`);
83
- console.log(` Duration: ${duration}`);
84
- console.log('');
85
- });
86
- console.log('Tip: Use "crewx log <task_id>" to view detailed log');
87
- return;
88
- }
89
- console.error(`Unknown log action: ${action}`);
90
- console.error('');
91
- console.error('Usage:');
92
- console.error(' crewx log List all logs (default)');
93
- console.error(' crewx log ls List all logs');
94
- console.error(' crewx log <task_id> View specific log');
95
- process.exit(1);
96
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.handleLog=T;const n=require("@crewx/sdk");const $=require("@crewx/sdk/repository");function a(s){switch(s){case"running":return"\u23F3";case"success":return"\u2705";case"failed":return"\u274C";default:return"\u2753"}}async function T(s){const t=s[0];const c=t&&(t.startsWith("tsk_")||t.startsWith("task_"));const i=!t||t==="ls"||t==="list";const r=new $.TaskRepository;if(c){const e=r.getTask(t);if(!e){console.error(`Task not found: ${t}`);process.exit(1);return}console.log(`
2
+ Task Log
3
+ ${"=".repeat(60)}`);console.log(`Task ID: ${e.id}`);console.log(`Status: ${a(e.status)} ${e.status}`);console.log(`Agent: ${e.agent_id??"\u2014"}`);console.log(`Mode: ${e.mode??"\u2014"}`);console.log(`Started: ${(0,n.formatDisplayTimestamp)(new Date(e.started_at))}`);if(e.completed_at){const l=new Date(e.completed_at).getTime()-new Date(e.started_at).getTime();console.log(`Completed: ${(0,n.formatDisplayTimestamp)(new Date(e.completed_at))} (${l}ms)`)}console.log("=".repeat(60));console.log("");if(e.status==="success"&&e.result){console.log("Result:");console.log(e.result)}else if(e.status==="failed"&&e.error){console.log(`Error: ${e.error}`)}else if(e.status==="running"){console.log("(task is still running)")}return}if(i){const e=r.getAllTasks();console.log("\nAvailable Task Logs");console.log("=".repeat(60));const l=e.length;const g=e.filter(o=>o.status==="success").length;const u=e.filter(o=>o.status==="failed").length;const d=e.filter(o=>o.status==="running").length;console.log(`Total: ${l} | \u2705 Completed: ${g} | \u274C Failed: ${u} | \u23F3 Running: ${d}`);console.log("=".repeat(60));console.log("");if(e.length===0){console.log("No task logs found.");console.log("Tip: Run `crewx query` or `crewx execute` to create tasks.");return}e.forEach((o,f)=>{const m=a(o.status);const p=o.completed_at?`${new Date(o.completed_at).getTime()-new Date(o.started_at).getTime()}ms`:"running...";console.log(`${f+1}. ${m} ${o.id}`);console.log(` Agent: ${o.agent_id??"\u2014"} Mode: ${o.mode??"\u2014"}`);console.log(` Started: ${(0,n.formatDisplayTimestamp)(new Date(o.started_at))}`);console.log(` Duration: ${p}`);console.log("")});console.log('Tip: Use "crewx log <task_id>" to view detailed log');return}console.error(`Unknown log action: ${t}`);console.error("");console.error("Usage:");console.error(" crewx log List all logs (default)");console.error(" crewx log ls List all logs");console.error(" crewx log <task_id> View specific log");process.exit(1)}