@fractary/faber-cli 1.5.45 → 1.5.47

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.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,wBAAgB,mBAAmB,IAAI,OAAO,CAkf7C"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,wBAAgB,mBAAmB,IAAI,OAAO,CAqf7C"}
@@ -159,6 +159,9 @@ export function createConfigCommand() {
159
159
  changelog: {
160
160
  path: options.changelogPath,
161
161
  },
162
+ worktree: {
163
+ enabled: false, // FABER does not manage worktrees by default (see SPEC-006)
164
+ },
162
165
  };
163
166
  // Load existing config or create empty
164
167
  let config = loadYamlConfig({ warnMissingEnvVars: false }) || { version: '2.0' };
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,wBAAgB,iBAAiB,IAAI,OAAO,CA0J3C"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/fractary-faber-init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,wBAAgB,iBAAiB,IAAI,OAAO,CA0J3C"}
@@ -24,7 +24,7 @@ export function createPlanCommand() {
24
24
  .option('--work-label <labels>', 'Comma-separated label filters (e.g., "workflow:etl,status:approved")')
25
25
  .option('--workflow <name>', 'Override workflow (default: read from issue "workflow:*" label)')
26
26
  .option('--autonomy <level>', 'Override autonomy level (guarded|autonomous)')
27
- .option('--no-worktree', 'Skip worktree creation')
27
+ .option('--worktree', 'Create a git worktree for this workflow (overrides config)')
28
28
  .option('--no-branch', 'Skip branch creation')
29
29
  .option('--skip-confirm', 'Skip confirmation prompt (use with caution)')
30
30
  .option('--output <format>', 'Output format: text|json|yaml', 'text')
@@ -186,7 +186,7 @@ async function executePlanCommand(options) {
186
186
  const issuesWithWorkflows = await assignWorkflows(issues, availableWorkflows, options, outputFormat);
187
187
  // Step 3: Show confirmation prompt
188
188
  if (!options.skipConfirm) {
189
- const confirmed = await showConfirmationPrompt(issuesWithWorkflows, config, outputFormat);
189
+ const confirmed = await showConfirmationPrompt(issuesWithWorkflows, config, options, outputFormat);
190
190
  if (!confirmed) {
191
191
  if (outputFormat === 'text') {
192
192
  console.log(chalk.yellow('\nāœ– Planning cancelled'));
@@ -306,24 +306,40 @@ async function assignWorkflows(issues, availableWorkflows, options, outputFormat
306
306
  /**
307
307
  * Show confirmation prompt before planning
308
308
  */
309
- async function showConfirmationPrompt(issues, config, outputFormat) {
309
+ async function showConfirmationPrompt(issues, config, options, outputFormat) {
310
310
  if (outputFormat !== 'text') {
311
311
  return true; // Skip in JSON mode
312
312
  }
313
+ const createWorktree = shouldCreateWorktree(options, config);
313
314
  console.log(chalk.cyan('\nšŸ“‹ Will plan workflows for the following issues:\n'));
314
315
  for (const issue of issues) {
315
316
  const { organization, project } = getRepoInfoFromConfig(config);
316
317
  const branch = `feature/${issue.number}`;
317
- const worktree = `~/.claude-worktrees/${organization}-${project}-${issue.number}`;
318
318
  console.log(chalk.bold(`#${issue.number}: ${issue.title}`));
319
319
  console.log(chalk.gray(` Workflow: ${issue.workflow}`));
320
320
  console.log(chalk.gray(` Branch: ${branch}`));
321
- console.log(chalk.gray(` Worktree: ${worktree}`));
321
+ if (createWorktree) {
322
+ const worktree = `~/.claude-worktrees/${organization}-${project}-${issue.number}`;
323
+ console.log(chalk.gray(` Worktree: ${worktree}`));
324
+ }
322
325
  console.log();
323
326
  }
324
327
  const response = await prompt('Proceed? [Y/n]: ');
325
328
  return !response || response.toLowerCase() === 'y' || response.toLowerCase() === 'yes';
326
329
  }
330
+ /**
331
+ * Determine whether to create a worktree based on CLI flag and config
332
+ */
333
+ function shouldCreateWorktree(options, config) {
334
+ // Explicit CLI flag always wins
335
+ if (options.worktree === true)
336
+ return true;
337
+ // Config setting is the default authority
338
+ if (config.worktree?.enabled === true)
339
+ return true;
340
+ // Default: no worktree
341
+ return false;
342
+ }
327
343
  /**
328
344
  * Plan a single issue
329
345
  */
@@ -331,6 +347,7 @@ async function planSingleIssue(issue, config, repoClient, anthropicClient, optio
331
347
  const { organization, project } = getRepoInfoFromConfig(config);
332
348
  const branch = `feature/${issue.number}`;
333
349
  const worktree = `~/.claude-worktrees/${organization}-${project}-${issue.number}`;
350
+ const createWorktree = shouldCreateWorktree(options, config);
334
351
  // Create branch without checking it out (so it won't conflict with worktree creation)
335
352
  if (!options.noBranch) {
336
353
  if (outputFormat === 'text') {
@@ -348,9 +365,9 @@ async function planSingleIssue(issue, config, repoClient, anthropicClient, optio
348
365
  // Branch might already exist, that's ok
349
366
  }
350
367
  }
351
- // Create worktree
352
- let worktreePath = worktree;
353
- if (!options.noWorktree) {
368
+ // Create worktree (only when explicitly opted in via flag or config)
369
+ let worktreePath = createWorktree ? worktree : process.cwd();
370
+ if (createWorktree) {
354
371
  if (outputFormat === 'text') {
355
372
  console.log(chalk.gray(` → Creating worktree: ${worktree}...`));
356
373
  process.stdout.write(''); // Force flush
@@ -393,8 +410,8 @@ async function planSingleIssue(issue, config, repoClient, anthropicClient, optio
393
410
  // Non-fatal: if cleanup fails, workflow-run will handle conflict detection
394
411
  }
395
412
  }
396
- // Check for existing plan in worktree (skip if found, unless --force-new)
397
- if (!options.forceNew && !options.noWorktree) {
413
+ // Check for existing plan (skip if found, unless --force-new)
414
+ if (!options.forceNew) {
398
415
  const runsDir = path.join(worktreePath, '.fractary', 'faber', 'runs');
399
416
  try {
400
417
  const entries = await fs.readdir(runsDir);
@@ -434,8 +451,8 @@ async function planSingleIssue(issue, config, repoClient, anthropicClient, optio
434
451
  plan.autonomy = options.autonomy;
435
452
  }
436
453
  const planId = plan.id;
437
- // Write plan to worktree
438
- if (!options.noWorktree) {
454
+ // Write plan to worktree (or project root when no worktree)
455
+ {
439
456
  // Validate plan ID format (prevent path traversal via malicious plan IDs)
440
457
  validatePlanId(planId);
441
458
  const runDir = getRunDir(planId, worktreePath);
@@ -544,7 +561,7 @@ function generatePlanComment(plan, workflow, worktreePath, planId, issueNumber)
544
561
  comment += `cd ${worktreePath}\n`;
545
562
  comment += `claude\n`;
546
563
  comment += `# Then in Claude Code:\n`;
547
- comment += `/fractary-faber:workflow-run ${issueNumber}\n`;
564
+ comment += `/fractary-faber-workflow-run ${issueNumber}\n`;
548
565
  comment += `\`\`\`\n`;
549
566
  return comment;
550
567
  }
@@ -575,7 +592,7 @@ function outputTextSummary(results) {
575
592
  console.log();
576
593
  console.log(chalk.cyan(' To execute:'));
577
594
  console.log(chalk.gray(` cd ${result.worktree} && claude`));
578
- console.log(chalk.gray(` /fractary-faber:workflow-run ${result.issue.number}`));
595
+ console.log(chalk.gray(` /fractary-faber-workflow-run ${result.issue.number}`));
579
596
  console.log();
580
597
  });
581
598
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/spec/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAc3C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/fractary-faber-spec/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAc3C"}
@@ -40,6 +40,19 @@ export declare function createWorkflowUpdateCommand(): Command;
40
40
  * Create the workflow-inspect command
41
41
  */
42
42
  export declare function createWorkflowInspectCommand(): Command;
43
+ /**
44
+ * Create the workflow-resolve command.
45
+ *
46
+ * Resolves a workflow with full inheritance chain merging via WorkflowResolver.
47
+ * Unlike workflow-inspect (which only looks in project-local registry),
48
+ * workflow-resolve also searches bundled plugin defaults — making it the
49
+ * CLI equivalent of merge-workflows.sh and the correct tool for agents and
50
+ * skills that need a fully-merged workflow definition.
51
+ *
52
+ * Works identically in Claude Code and pi installs: WorkflowResolver uses
53
+ * __dirname to locate bundled workflows without any environment configuration.
54
+ */
55
+ export declare function createWorkflowResolveCommand(): Command;
43
56
  /**
44
57
  * Create the workflow-debug command
45
58
  */
@@ -52,4 +65,8 @@ export declare function createBatchPlanCommand(): Command;
52
65
  * Create the workflow-batch-run command
53
66
  */
54
67
  export declare function createBatchRunCommand(): Command;
68
+ /**
69
+ * Create the workflow-execute command (multi-model CLI-native execution)
70
+ */
71
+ export declare function createWorkflowExecuteCommand(): Command;
55
72
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAsJ1C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAiF7C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAyB7C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAoB5C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CA2B9C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CA8B9C;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAoCrD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CA4BrD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CA0CtD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,OAAO,CAkDpD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAehD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAgB/C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAsJ1C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAiF7C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAyB7C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAoB5C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CA2B9C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CA8B9C;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAoCrD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CA4BrD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CA0CtD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CAkDtD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,OAAO,CAkDpD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAehD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAgB/C;AAgYD;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CAuHtD"}
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { Command } from 'commander';
7
7
  import chalk from 'chalk';
8
- import { FaberWorkflow, StateManager, createWorkflow, updateWorkflow, inspectWorkflow, debugWorkflow, } from '@fractary/faber';
8
+ import { FaberWorkflow, StateManager, createWorkflow, updateWorkflow, inspectWorkflow, debugWorkflow, WorkflowResolver, ExecutorRegistry, WorkflowExecutor, } from '@fractary/faber';
9
9
  import { parsePositiveInteger } from '../../utils/validation.js';
10
10
  /**
11
11
  * Create the workflow-run command
@@ -477,6 +477,67 @@ export function createWorkflowInspectCommand() {
477
477
  }
478
478
  });
479
479
  }
480
+ /**
481
+ * Create the workflow-resolve command.
482
+ *
483
+ * Resolves a workflow with full inheritance chain merging via WorkflowResolver.
484
+ * Unlike workflow-inspect (which only looks in project-local registry),
485
+ * workflow-resolve also searches bundled plugin defaults — making it the
486
+ * CLI equivalent of merge-workflows.sh and the correct tool for agents and
487
+ * skills that need a fully-merged workflow definition.
488
+ *
489
+ * Works identically in Claude Code and pi installs: WorkflowResolver uses
490
+ * __dirname to locate bundled workflows without any environment configuration.
491
+ */
492
+ export function createWorkflowResolveCommand() {
493
+ return new Command('workflow-resolve')
494
+ .description('Resolve a workflow with full inheritance chain merging (includes bundled plugin defaults)')
495
+ .argument('<id>', 'Workflow ID to resolve (e.g. "core", "default", "project:my-workflow")')
496
+ .option('--project-root <path>', 'Project root directory (default: cwd)')
497
+ .option('--json', 'Output as JSON')
498
+ .action(async (id, options) => {
499
+ try {
500
+ const resolver = new WorkflowResolver({
501
+ projectRoot: options.projectRoot,
502
+ });
503
+ const workflow = await resolver.resolveWorkflow(id);
504
+ if (options.json) {
505
+ console.log(JSON.stringify({ status: 'success', workflow }, null, 2));
506
+ }
507
+ else {
508
+ console.log(chalk.bold(`Workflow: ${workflow.id}`));
509
+ if (workflow.description) {
510
+ console.log(` Description: ${workflow.description}`);
511
+ }
512
+ console.log(` Inheritance chain: ${workflow.inheritance_chain.join(' → ')}`);
513
+ if (workflow.skipped_steps?.length) {
514
+ console.log(` Skipped steps: ${workflow.skipped_steps.join(', ')}`);
515
+ }
516
+ console.log();
517
+ for (const [phase, def] of Object.entries(workflow.phases)) {
518
+ const steps = def.steps ?? [];
519
+ const enabled = def.enabled !== false;
520
+ console.log(chalk.cyan(` ${phase}`), enabled ? '' : chalk.gray('(disabled)'), chalk.gray(`${steps.length} steps`));
521
+ }
522
+ }
523
+ }
524
+ catch (error) {
525
+ if (options.json) {
526
+ const msg = error instanceof Error ? error.message : String(error);
527
+ const paths = error.searchedPaths;
528
+ console.error(JSON.stringify({
529
+ status: 'failure',
530
+ message: msg,
531
+ errors: paths ? [`Searched: ${paths.join(', ')}`] : [msg],
532
+ }));
533
+ }
534
+ else {
535
+ console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
536
+ }
537
+ process.exit(1);
538
+ }
539
+ });
540
+ }
480
541
  /**
481
542
  * Create the workflow-debug command
482
543
  */
@@ -708,7 +769,7 @@ async function executeBatchPlanCommand(options) {
708
769
  console.log(chalk.white(` fractary-faber workflow-batch-run --batch ${batchId} --autonomous`));
709
770
  console.log('');
710
771
  console.log(chalk.cyan('Or in Claude Code:'));
711
- console.log(chalk.white(` /fractary-faber:workflow-batch-run --batch ${batchId} --autonomous`));
772
+ console.log(chalk.white(` /fractary-faber-workflow-batch-run --batch ${batchId} --autonomous`));
712
773
  }
713
774
  }
714
775
  async function executeBatchRunCommand(options) {
@@ -872,6 +933,117 @@ async function executeBatchRunCommand(options) {
872
933
  process.exit(1);
873
934
  }
874
935
  }
936
+ /**
937
+ * Create the workflow-execute command (multi-model CLI-native execution)
938
+ */
939
+ export function createWorkflowExecuteCommand() {
940
+ return new Command('workflow-execute')
941
+ .description('Execute a workflow using the multi-model executor framework (CLI-native, no Claude Code required)')
942
+ .argument('<plan-path>', 'Path to plan.json file')
943
+ .option('--model <model>', 'Default model for steps without an explicit executor (default: claude-sonnet-4-6-20250514)')
944
+ .option('--phase <phases>', 'Execute only specified phase(s) — comma-separated')
945
+ .option('--step <step-id>', 'Execute only a specific step')
946
+ .option('--json', 'Output as JSON')
947
+ .action(async (planPath, options) => {
948
+ try {
949
+ const fs = await import('fs/promises');
950
+ const path = await import('path');
951
+ // Load plan
952
+ const resolvedPath = path.resolve(planPath);
953
+ const planContent = await fs.readFile(resolvedPath, 'utf-8');
954
+ const plan = JSON.parse(planContent);
955
+ if (!plan.workflow?.phases) {
956
+ throw new Error('Invalid plan: missing workflow.phases');
957
+ }
958
+ // Create executor registry with defaults
959
+ const registry = ExecutorRegistry.createDefault();
960
+ // Override default model if specified
961
+ const workflowExecutor = plan.workflow.executor || (options.model ? {
962
+ provider: 'claude',
963
+ model: options.model,
964
+ } : undefined);
965
+ // Create workflow executor
966
+ const executor = new WorkflowExecutor(registry);
967
+ // Parse options
968
+ const phasesToRun = options.phase?.split(',').map((p) => p.trim()) ?? null;
969
+ // Extract work ID from plan
970
+ const workId = plan.source?.work_id || plan.items?.[0]?.work_id || 'unknown';
971
+ const issue = plan.items?.[0]?.issue;
972
+ if (!options.json) {
973
+ console.log(chalk.blue.bold('FABER Multi-Model Workflow Execution'));
974
+ console.log(chalk.gray('═'.repeat(50)));
975
+ console.log(chalk.gray(`Plan: ${resolvedPath}`));
976
+ console.log(chalk.gray(`Work ID: ${workId}`));
977
+ console.log(chalk.gray(`Workflow: ${plan.workflow.id}`));
978
+ if (workflowExecutor) {
979
+ console.log(chalk.gray(`Default executor: ${workflowExecutor.provider}${workflowExecutor.model ? ` (${workflowExecutor.model})` : ''}`));
980
+ }
981
+ console.log('');
982
+ }
983
+ // Execute
984
+ const result = await executor.execute({
985
+ phases: plan.workflow.phases,
986
+ executor: workflowExecutor,
987
+ phase_executors: plan.workflow.phase_executors,
988
+ result_handling: plan.workflow.result_handling,
989
+ }, {
990
+ workId,
991
+ issue: issue ? { number: issue.number, title: issue.title, body: '' } : undefined,
992
+ workingDirectory: path.dirname(resolvedPath),
993
+ phasesToRun: phasesToRun || undefined,
994
+ stepToRun: options.step || null,
995
+ onPhaseStart: (phase) => {
996
+ if (!options.json) {
997
+ console.log(chalk.cyan(`\n→ Phase: ${phase.toUpperCase()}`));
998
+ }
999
+ },
1000
+ onStepStart: (phase, step, index, total) => {
1001
+ if (!options.json) {
1002
+ const executor = step.executor;
1003
+ const providerTag = executor
1004
+ ? chalk.magenta(`[${executor.provider}${executor.model ? `:${executor.model}` : ''}]`)
1005
+ : chalk.gray('[default]');
1006
+ console.log(chalk.gray(` [${index + 1}/${total}] ${step.name} ${providerTag}`));
1007
+ }
1008
+ },
1009
+ onStepComplete: (_phase, step, stepResult) => {
1010
+ if (!options.json) {
1011
+ const icon = stepResult.status === 'success' ? chalk.green('āœ“') :
1012
+ stepResult.status === 'warning' ? chalk.yellow('⚠') :
1013
+ chalk.red('āœ—');
1014
+ console.log(` ${icon} ${step.id} (${stepResult.metadata.duration_ms}ms)`);
1015
+ if (stepResult.metadata.tokens_used) {
1016
+ console.log(chalk.gray(` tokens: ${stepResult.metadata.tokens_used.input}→${stepResult.metadata.tokens_used.output}`));
1017
+ }
1018
+ }
1019
+ },
1020
+ onPhaseComplete: (phase, status) => {
1021
+ if (!options.json) {
1022
+ const icon = status === 'completed' ? chalk.green('āœ“') :
1023
+ status === 'skipped' ? chalk.gray('ā­') :
1024
+ chalk.red('āœ—');
1025
+ console.log(` ${icon} Phase ${phase} ${status}`);
1026
+ }
1027
+ },
1028
+ });
1029
+ if (options.json) {
1030
+ console.log(JSON.stringify({ status: 'success', data: result }, null, 2));
1031
+ }
1032
+ else {
1033
+ console.log(chalk.gray('\n' + '═'.repeat(50)));
1034
+ const statusIcon = result.status === 'completed' ? chalk.green('āœ“') : chalk.red('āœ—');
1035
+ console.log(`${statusIcon} Workflow ${result.status} (${result.duration_ms}ms)`);
1036
+ console.log(chalk.gray(` Steps: ${result.steps_completed}/${result.steps_total}`));
1037
+ }
1038
+ if (result.status === 'failed') {
1039
+ process.exit(1);
1040
+ }
1041
+ }
1042
+ catch (error) {
1043
+ handleWorkflowError(error, options);
1044
+ }
1045
+ });
1046
+ }
875
1047
  // Helper functions
876
1048
  function getStateColor(state) {
877
1049
  switch (state) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAwDxC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CA0DxC"}
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import dotenv from 'dotenv';
10
10
  dotenv.config();
11
11
  import { Command } from 'commander';
12
12
  import chalk from 'chalk';
13
- import { createRunCommand, createStatusCommand, createResumeCommand, createPauseCommand, createRecoverCommand, createCleanupCommand, createWorkflowCreateCommand, createWorkflowUpdateCommand, createWorkflowInspectCommand, createWorkflowDebugCommand, createBatchPlanCommand, createBatchRunCommand } from './commands/workflow/index.js';
13
+ import { createRunCommand, createStatusCommand, createResumeCommand, createPauseCommand, createRecoverCommand, createCleanupCommand, createWorkflowCreateCommand, createWorkflowUpdateCommand, createWorkflowInspectCommand, createWorkflowResolveCommand, createWorkflowDebugCommand, createBatchPlanCommand, createBatchRunCommand, createWorkflowExecuteCommand } from './commands/workflow/index.js';
14
14
  import { createSessionLoadCommand, createSessionSaveCommand } from './commands/session.js';
15
15
  import { createWorkCommand } from './commands/work/index.js';
16
16
  import { createRepoCommand } from './commands/repo/index.js';
@@ -51,10 +51,12 @@ export function createFaberCLI() {
51
51
  program.addCommand(createCleanupCommand()); // workflow-cleanup
52
52
  program.addCommand(createWorkflowCreateCommand()); // workflow-create
53
53
  program.addCommand(createWorkflowUpdateCommand()); // workflow-update
54
- program.addCommand(createWorkflowInspectCommand()); // workflow-inspect
54
+ program.addCommand(createWorkflowInspectCommand()); // workflow-inspect (project-local registry)
55
+ program.addCommand(createWorkflowResolveCommand()); // workflow-resolve (full inheritance + bundled defaults)
55
56
  program.addCommand(createWorkflowDebugCommand()); // workflow-debug
56
57
  program.addCommand(createBatchPlanCommand()); // workflow-batch-plan
57
58
  program.addCommand(createBatchRunCommand()); // workflow-batch-run
59
+ program.addCommand(createWorkflowExecuteCommand()); // workflow-execute (multi-model CLI-native)
58
60
  program.addCommand(createSessionLoadCommand()); // session-load
59
61
  program.addCommand(createSessionSaveCommand()); // session-save
60
62
  // Subcommand trees
@@ -34,6 +34,7 @@ export interface GitHubConfig {
34
34
  app?: GitHubAppConfig;
35
35
  }
36
36
  export interface WorktreeConfig {
37
+ enabled?: boolean;
37
38
  location?: string;
38
39
  inherit_from_claude?: boolean;
39
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fractary/faber-cli",
3
- "version": "1.5.45",
3
+ "version": "1.5.47",
4
4
  "description": "FABER CLI - Command-line interface for FABER development toolkit",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -91,7 +91,7 @@
91
91
  "properties": {
92
92
  "id": {
93
93
  "type": "string",
94
- "description": "Workflow identifier (e.g., fractary-faber:default, dataset-create)"
94
+ "description": "Workflow identifier (e.g., fractary-faber-default, dataset-create)"
95
95
  },
96
96
  "resolved_at": {
97
97
  "type": "string",