@fractary/faber-cli 1.5.21 → 1.5.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -98
- package/dist/commands/config.d.ts +12 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +118 -74
- package/dist/commands/workflow/index.d.ts +2 -2
- package/dist/commands/workflow/index.d.ts.map +1 -1
- package/dist/commands/workflow/index.js +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @fractary/faber-cli
|
|
2
2
|
|
|
3
|
-
Command-line interface for FABER development toolkit. Execute and manage FABER workflows, work items, repository operations,
|
|
3
|
+
Command-line interface for FABER development toolkit. Execute and manage FABER workflows, work items, repository operations, and logs.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -52,30 +52,51 @@ See [GitHub App Setup Guide](../docs/github-app-setup.md) for detailed manual in
|
|
|
52
52
|
### 3. Initialize a FABER project
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
|
-
fractary-faber
|
|
56
|
-
fractary-faber init
|
|
57
|
-
fractary-faber init --
|
|
55
|
+
fractary-faber configure
|
|
56
|
+
fractary-faber config init
|
|
57
|
+
fractary-faber config init --autonomy guarded
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
### Workflow Commands
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
+
# Plan a workflow (creates plan, branch, worktree)
|
|
64
|
+
fractary-faber workflow-plan --work-id 123
|
|
65
|
+
|
|
63
66
|
# Start a FABER workflow
|
|
64
|
-
fractary-faber run --work-id 123
|
|
67
|
+
fractary-faber workflow-run --work-id 123
|
|
65
68
|
|
|
66
69
|
# Check workflow status
|
|
67
|
-
fractary-faber
|
|
68
|
-
fractary-faber
|
|
70
|
+
fractary-faber run-inspect
|
|
71
|
+
fractary-faber run-inspect --work-id 123
|
|
69
72
|
|
|
70
73
|
# Pause/resume workflows
|
|
71
|
-
fractary-faber pause <workflow-id>
|
|
72
|
-
fractary-faber resume <workflow-id>
|
|
74
|
+
fractary-faber workflow-pause <workflow-id>
|
|
75
|
+
fractary-faber workflow-resume <workflow-id>
|
|
73
76
|
|
|
74
77
|
# Recover from checkpoint
|
|
75
|
-
fractary-faber recover <workflow-id>
|
|
78
|
+
fractary-faber workflow-recover <workflow-id>
|
|
76
79
|
|
|
77
80
|
# Clean up old workflows
|
|
78
|
-
fractary-faber cleanup --max-age 30
|
|
81
|
+
fractary-faber workflow-cleanup --max-age 30
|
|
82
|
+
|
|
83
|
+
# Create/update workflow definitions
|
|
84
|
+
fractary-faber workflow-create
|
|
85
|
+
fractary-faber workflow-update
|
|
86
|
+
|
|
87
|
+
# Inspect and debug workflows
|
|
88
|
+
fractary-faber workflow-inspect
|
|
89
|
+
fractary-faber workflow-debugger
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Session Commands
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Save current session state
|
|
96
|
+
fractary-faber session-save
|
|
97
|
+
|
|
98
|
+
# Load a previous session
|
|
99
|
+
fractary-faber session-load --work-id 123
|
|
79
100
|
```
|
|
80
101
|
|
|
81
102
|
### Work Commands
|
|
@@ -131,31 +152,6 @@ fractary-faber repo worktree list
|
|
|
131
152
|
fractary-faber repo worktree remove feat/new-feature
|
|
132
153
|
```
|
|
133
154
|
|
|
134
|
-
### Specification Commands
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
# Create specifications
|
|
138
|
-
fractary-faber spec create "My Specification"
|
|
139
|
-
|
|
140
|
-
# Get specification
|
|
141
|
-
fractary-faber spec get <id>
|
|
142
|
-
|
|
143
|
-
# List specifications
|
|
144
|
-
fractary-faber spec list
|
|
145
|
-
|
|
146
|
-
# Update specification
|
|
147
|
-
fractary-faber spec update <id> --title "Updated"
|
|
148
|
-
|
|
149
|
-
# Validate specification
|
|
150
|
-
fractary-faber spec validate <id>
|
|
151
|
-
|
|
152
|
-
# Refine specification
|
|
153
|
-
fractary-faber spec refine <id>
|
|
154
|
-
|
|
155
|
-
# Delete specification
|
|
156
|
-
fractary-faber spec delete <id>
|
|
157
|
-
```
|
|
158
|
-
|
|
159
155
|
### Logs Commands
|
|
160
156
|
|
|
161
157
|
```bash
|
|
@@ -184,36 +180,57 @@ fractary-faber logs archive --older-than 30
|
|
|
184
180
|
fractary-faber logs delete <session-id>
|
|
185
181
|
```
|
|
186
182
|
|
|
183
|
+
### Configuration Commands
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# Get configuration values
|
|
187
|
+
fractary-faber config get
|
|
188
|
+
fractary-faber config get faber.workflows.autonomy
|
|
189
|
+
|
|
190
|
+
# Show config file path
|
|
191
|
+
fractary-faber config path
|
|
192
|
+
|
|
193
|
+
# Check if config exists
|
|
194
|
+
fractary-faber config exists
|
|
195
|
+
|
|
196
|
+
# Initialize config with defaults
|
|
197
|
+
fractary-faber config init --autonomy guarded
|
|
198
|
+
|
|
199
|
+
# Set a value
|
|
200
|
+
fractary-faber config set faber.workflows.autonomy autonomous
|
|
201
|
+
|
|
202
|
+
# Validate configuration
|
|
203
|
+
fractary-faber config validate
|
|
204
|
+
|
|
205
|
+
# Migrate legacy config format
|
|
206
|
+
fractary-faber config migrate
|
|
207
|
+
fractary-faber config migrate --dry-run
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Run Management Commands
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Manage run directories and paths
|
|
214
|
+
fractary-faber runs dir
|
|
215
|
+
fractary-faber runs plan-path <plan-id>
|
|
216
|
+
fractary-faber runs state-path <plan-id>
|
|
217
|
+
```
|
|
218
|
+
|
|
187
219
|
## Configuration
|
|
188
220
|
|
|
189
|
-
FABER is configured via `.fractary/
|
|
190
|
-
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
"spec": {
|
|
203
|
-
"directory": ".fractary/faber/specs"
|
|
204
|
-
},
|
|
205
|
-
"logs": {
|
|
206
|
-
"directory": ".fractary/faber/logs"
|
|
207
|
-
},
|
|
208
|
-
"workflow": {
|
|
209
|
-
"defaultAutonomy": "guarded",
|
|
210
|
-
"phases": ["frame", "architect", "build", "evaluate", "release"],
|
|
211
|
-
"checkpoints": true
|
|
212
|
-
},
|
|
213
|
-
"state": {
|
|
214
|
-
"directory": ".fractary/faber/state"
|
|
215
|
-
}
|
|
216
|
-
}
|
|
221
|
+
FABER is configured via `.fractary/config.yaml`:
|
|
222
|
+
|
|
223
|
+
```yaml
|
|
224
|
+
faber:
|
|
225
|
+
workflows:
|
|
226
|
+
path: .fractary/faber/workflows
|
|
227
|
+
default: default
|
|
228
|
+
autonomy: guarded
|
|
229
|
+
runs:
|
|
230
|
+
path: .fractary/faber/runs
|
|
231
|
+
worktree:
|
|
232
|
+
location: ~/.claude-worktrees
|
|
233
|
+
inherit_from_claude: true
|
|
217
234
|
```
|
|
218
235
|
|
|
219
236
|
## Options
|
|
@@ -238,34 +255,26 @@ fractary-faber auth setup
|
|
|
238
255
|
|
|
239
256
|
This command will guide you through creating and configuring a GitHub App in ~30 seconds.
|
|
240
257
|
|
|
241
|
-
**Manual Configuration (`.fractary/
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
"
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
"private_key_path": "~/.github/faber-app.pem"
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
258
|
+
**Manual Configuration (`.fractary/config.yaml`):**
|
|
259
|
+
```yaml
|
|
260
|
+
github:
|
|
261
|
+
organization: your-org
|
|
262
|
+
project: your-repo
|
|
263
|
+
app:
|
|
264
|
+
id: "123456"
|
|
265
|
+
installation_id: "12345678"
|
|
266
|
+
private_key_path: ~/.github/faber-app.pem
|
|
254
267
|
```
|
|
255
268
|
|
|
256
269
|
**For CI/CD (environment variable):**
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
"
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
"private_key_env_var": "GITHUB_APP_PRIVATE_KEY"
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
270
|
+
```yaml
|
|
271
|
+
github:
|
|
272
|
+
organization: your-org
|
|
273
|
+
project: your-repo
|
|
274
|
+
app:
|
|
275
|
+
id: "123456"
|
|
276
|
+
installation_id: "12345678"
|
|
277
|
+
private_key_env_var: GITHUB_APP_PRIVATE_KEY
|
|
269
278
|
```
|
|
270
279
|
|
|
271
280
|
```bash
|
|
@@ -282,15 +291,12 @@ Still supported for backward compatibility:
|
|
|
282
291
|
export GITHUB_TOKEN=<token>
|
|
283
292
|
```
|
|
284
293
|
|
|
285
|
-
Or in `.fractary/
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
"project": "your-repo"
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
+
Or in `.fractary/config.yaml`:
|
|
295
|
+
```yaml
|
|
296
|
+
github:
|
|
297
|
+
token: ghp_xxxxxxxxxxxx
|
|
298
|
+
organization: your-org
|
|
299
|
+
project: your-repo
|
|
294
300
|
```
|
|
295
301
|
|
|
296
302
|
### Other Providers
|
|
@@ -2,7 +2,18 @@
|
|
|
2
2
|
* Config command - Manage FABER configuration
|
|
3
3
|
*
|
|
4
4
|
* Provides commands for reading, writing, and migrating FABER configuration.
|
|
5
|
-
* Uses the SDK's ConfigInitializer
|
|
5
|
+
* Uses the SDK's ConfigInitializer, ConfigValidator, and ConfigUpdater for
|
|
6
|
+
* all operations to ensure consistency.
|
|
7
|
+
*
|
|
8
|
+
* Subcommands:
|
|
9
|
+
* config init - Initialize FABER configuration (used by config-init command)
|
|
10
|
+
* config update - Update configuration fields with backup (used by config-updater agent)
|
|
11
|
+
* config validate - Validate configuration (used by config-validator agent)
|
|
12
|
+
* config get - Get configuration values
|
|
13
|
+
* config set - Set a single configuration value
|
|
14
|
+
* config migrate - Migrate legacy configuration
|
|
15
|
+
* config path - Show configuration file path
|
|
16
|
+
* config exists - Check if configuration file exists
|
|
6
17
|
*/
|
|
7
18
|
import { Command } from 'commander';
|
|
8
19
|
export declare function createConfigCommand(): Command;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA
|
|
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,CA6e7C"}
|
package/dist/commands/config.js
CHANGED
|
@@ -2,13 +2,25 @@
|
|
|
2
2
|
* Config command - Manage FABER configuration
|
|
3
3
|
*
|
|
4
4
|
* Provides commands for reading, writing, and migrating FABER configuration.
|
|
5
|
-
* Uses the SDK's ConfigInitializer
|
|
5
|
+
* Uses the SDK's ConfigInitializer, ConfigValidator, and ConfigUpdater for
|
|
6
|
+
* all operations to ensure consistency.
|
|
7
|
+
*
|
|
8
|
+
* Subcommands:
|
|
9
|
+
* config init - Initialize FABER configuration (used by config-init command)
|
|
10
|
+
* config update - Update configuration fields with backup (used by config-updater agent)
|
|
11
|
+
* config validate - Validate configuration (used by config-validator agent)
|
|
12
|
+
* config get - Get configuration values
|
|
13
|
+
* config set - Set a single configuration value
|
|
14
|
+
* config migrate - Migrate legacy configuration
|
|
15
|
+
* config path - Show configuration file path
|
|
16
|
+
* config exists - Check if configuration file exists
|
|
6
17
|
*/
|
|
7
18
|
import { Command } from 'commander';
|
|
8
19
|
import * as fs from 'fs';
|
|
9
20
|
import * as path from 'path';
|
|
10
21
|
import * as yaml from 'js-yaml';
|
|
11
22
|
import { loadYamlConfig, configExists, getConfigPath, writeYamlConfig, findProjectRoot, } from '../lib/yaml-config.js';
|
|
23
|
+
import { ConfigValidator, ConfigUpdater } from '@fractary/faber';
|
|
12
24
|
/**
|
|
13
25
|
* Get a nested value from an object using dot notation
|
|
14
26
|
* @param obj The object to search
|
|
@@ -341,95 +353,41 @@ ${yaml.dump(manifest, { indent: 2, lineWidth: 100 })}`;
|
|
|
341
353
|
}
|
|
342
354
|
});
|
|
343
355
|
// =========================================================================
|
|
344
|
-
// Config Validate Command
|
|
356
|
+
// Config Validate Command (delegates to SDK ConfigValidator)
|
|
345
357
|
// =========================================================================
|
|
346
358
|
configCmd
|
|
347
359
|
.command('validate')
|
|
348
360
|
.description('Validate FABER configuration')
|
|
349
|
-
.
|
|
361
|
+
.option('--json', 'Output validation results as JSON')
|
|
362
|
+
.action(async (options) => {
|
|
350
363
|
try {
|
|
351
364
|
const projectRoot = findProjectRoot();
|
|
352
|
-
const
|
|
353
|
-
if (
|
|
354
|
-
console.
|
|
355
|
-
|
|
356
|
-
process.exit(1);
|
|
365
|
+
const result = ConfigValidator.validateFromDisk(projectRoot);
|
|
366
|
+
if (options.json) {
|
|
367
|
+
console.log(JSON.stringify(result, null, 2));
|
|
368
|
+
process.exit(result.valid ? 0 : 1);
|
|
357
369
|
}
|
|
358
|
-
|
|
359
|
-
const
|
|
360
|
-
if (!config) {
|
|
361
|
-
console.error('Failed to load configuration');
|
|
362
|
-
process.exit(1);
|
|
363
|
-
}
|
|
364
|
-
const faber = config.faber;
|
|
365
|
-
const errors = [];
|
|
366
|
-
const warnings = [];
|
|
367
|
-
// Check for faber section
|
|
368
|
-
if (!faber) {
|
|
369
|
-
errors.push('Missing faber section');
|
|
370
|
-
}
|
|
371
|
-
else {
|
|
372
|
-
// Check for required fields
|
|
373
|
-
const workflows = faber['workflows'];
|
|
374
|
-
const runs = faber['runs'];
|
|
375
|
-
// Legacy format warnings
|
|
376
|
-
if (Array.isArray(faber['workflows'])) {
|
|
377
|
-
warnings.push('Using deprecated workflows array format');
|
|
378
|
-
}
|
|
379
|
-
if (faber['workflow']?.['config_path']) {
|
|
380
|
-
warnings.push('Using deprecated workflow.config_path');
|
|
381
|
-
}
|
|
382
|
-
if (faber['repository']) {
|
|
383
|
-
warnings.push('Using deprecated repository section');
|
|
384
|
-
}
|
|
385
|
-
if (faber['logging']) {
|
|
386
|
-
warnings.push('Using deprecated logging section');
|
|
387
|
-
}
|
|
388
|
-
if (faber['state']) {
|
|
389
|
-
warnings.push('Using deprecated state section');
|
|
390
|
-
}
|
|
391
|
-
// Validate new format fields
|
|
392
|
-
if (workflows && typeof workflows === 'object' && !Array.isArray(workflows)) {
|
|
393
|
-
const autonomy = workflows['autonomy'];
|
|
394
|
-
if (autonomy && !['dry-run', 'assisted', 'guarded', 'autonomous'].includes(autonomy)) {
|
|
395
|
-
errors.push(`Invalid autonomy level: ${autonomy}`);
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
// Check if directories exist
|
|
399
|
-
const workflowsPath = workflows?.['path'] || '.fractary/faber/workflows';
|
|
400
|
-
const runsPath = runs?.['path'] || '.fractary/faber/runs';
|
|
401
|
-
const workflowsDir = path.isAbsolute(workflowsPath)
|
|
402
|
-
? workflowsPath
|
|
403
|
-
: path.join(projectRoot, workflowsPath);
|
|
404
|
-
const runsDir = path.isAbsolute(runsPath) ? runsPath : path.join(projectRoot, runsPath);
|
|
405
|
-
if (!fs.existsSync(workflowsDir)) {
|
|
406
|
-
warnings.push(`Workflows directory does not exist: ${workflowsDir}`);
|
|
407
|
-
}
|
|
408
|
-
if (!fs.existsSync(runsDir)) {
|
|
409
|
-
warnings.push(`Runs directory does not exist: ${runsDir}`);
|
|
410
|
-
}
|
|
411
|
-
// Check for workflow manifest
|
|
412
|
-
const manifestPath = path.join(workflowsDir, 'workflows.yaml');
|
|
413
|
-
if (fs.existsSync(workflowsDir) && !fs.existsSync(manifestPath)) {
|
|
414
|
-
warnings.push('Workflow manifest not found: workflows.yaml');
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
// Output results
|
|
370
|
+
const errors = result.findings.filter((f) => f.severity === 'error');
|
|
371
|
+
const warnings = result.findings.filter((f) => f.severity === 'warning');
|
|
418
372
|
if (errors.length === 0 && warnings.length === 0) {
|
|
419
373
|
console.log('Configuration is valid.');
|
|
420
374
|
return;
|
|
421
375
|
}
|
|
422
376
|
if (errors.length > 0) {
|
|
423
377
|
console.error('Errors:');
|
|
424
|
-
errors.forEach((e) =>
|
|
378
|
+
errors.forEach((e) => {
|
|
379
|
+
console.error(` - ${e.message}`);
|
|
380
|
+
if (e.suggestion)
|
|
381
|
+
console.error(` ${e.suggestion}`);
|
|
382
|
+
});
|
|
425
383
|
}
|
|
426
384
|
if (warnings.length > 0) {
|
|
427
385
|
console.warn('Warnings:');
|
|
428
|
-
warnings.forEach((w) =>
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
}
|
|
386
|
+
warnings.forEach((w) => {
|
|
387
|
+
console.warn(` - ${w.message}`);
|
|
388
|
+
if (w.suggestion)
|
|
389
|
+
console.warn(` ${w.suggestion}`);
|
|
390
|
+
});
|
|
433
391
|
}
|
|
434
392
|
if (errors.length > 0) {
|
|
435
393
|
process.exit(1);
|
|
@@ -440,6 +398,92 @@ ${yaml.dump(manifest, { indent: 2, lineWidth: 100 })}`;
|
|
|
440
398
|
process.exit(1);
|
|
441
399
|
}
|
|
442
400
|
});
|
|
401
|
+
// =========================================================================
|
|
402
|
+
// Config Update Command (delegates to SDK ConfigUpdater)
|
|
403
|
+
// =========================================================================
|
|
404
|
+
configCmd
|
|
405
|
+
.command('update')
|
|
406
|
+
.description('Update FABER configuration fields with backup and validation')
|
|
407
|
+
.argument('<changes...>', 'Key=value pairs to update (e.g., faber.workflows.autonomy=autonomous)')
|
|
408
|
+
.option('--dry-run', 'Preview changes without applying')
|
|
409
|
+
.option('--json', 'Output results as JSON')
|
|
410
|
+
.action(async (changeArgs, options) => {
|
|
411
|
+
try {
|
|
412
|
+
const projectRoot = findProjectRoot();
|
|
413
|
+
if (!configExists(projectRoot)) {
|
|
414
|
+
console.error('Configuration not found. Run: fractary-faber config init');
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
417
|
+
// Parse key=value pairs into ConfigChange objects
|
|
418
|
+
const changes = changeArgs.map((arg) => {
|
|
419
|
+
const eqIdx = arg.indexOf('=');
|
|
420
|
+
if (eqIdx === -1) {
|
|
421
|
+
console.error(`Invalid change format: ${arg}`);
|
|
422
|
+
console.error('Expected format: key=value (e.g., faber.workflows.autonomy=autonomous)');
|
|
423
|
+
process.exit(1);
|
|
424
|
+
}
|
|
425
|
+
const key = arg.substring(0, eqIdx);
|
|
426
|
+
const rawValue = arg.substring(eqIdx + 1);
|
|
427
|
+
// Strip leading "faber." prefix — ConfigUpdater operates within the faber section
|
|
428
|
+
const faberKey = key.startsWith('faber.') ? key.substring(6) : key;
|
|
429
|
+
// Parse value types
|
|
430
|
+
let value = rawValue;
|
|
431
|
+
if (rawValue === 'true')
|
|
432
|
+
value = true;
|
|
433
|
+
else if (rawValue === 'false')
|
|
434
|
+
value = false;
|
|
435
|
+
else if (/^-?\d+$/.test(rawValue))
|
|
436
|
+
value = parseInt(rawValue, 10);
|
|
437
|
+
else if (/^-?\d+\.\d+$/.test(rawValue))
|
|
438
|
+
value = parseFloat(rawValue);
|
|
439
|
+
return { key: faberKey, value };
|
|
440
|
+
});
|
|
441
|
+
// Preview mode
|
|
442
|
+
if (options.dryRun) {
|
|
443
|
+
const previews = ConfigUpdater.previewChanges(changes, projectRoot);
|
|
444
|
+
if (options.json) {
|
|
445
|
+
console.log(JSON.stringify({ mode: 'preview', changes: previews }, null, 2));
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
console.log('Proposed changes:');
|
|
449
|
+
console.log('');
|
|
450
|
+
for (const p of previews) {
|
|
451
|
+
console.log(` faber.${p.key}:`);
|
|
452
|
+
console.log(` Current: ${JSON.stringify(p.currentValue) ?? '(not set)'}`);
|
|
453
|
+
console.log(` Proposed: ${JSON.stringify(p.proposedValue)}`);
|
|
454
|
+
console.log('');
|
|
455
|
+
}
|
|
456
|
+
console.log('Dry run — no changes applied.');
|
|
457
|
+
}
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
// Apply changes
|
|
461
|
+
const result = ConfigUpdater.applyChanges(changes, projectRoot);
|
|
462
|
+
if (options.json) {
|
|
463
|
+
console.log(JSON.stringify(result, null, 2));
|
|
464
|
+
process.exit(result.success ? 0 : 1);
|
|
465
|
+
}
|
|
466
|
+
if (!result.success) {
|
|
467
|
+
console.error(`Update failed: ${result.error}`);
|
|
468
|
+
if (result.backupPath) {
|
|
469
|
+
console.error(`Backup preserved at: ${result.backupPath}`);
|
|
470
|
+
}
|
|
471
|
+
process.exit(1);
|
|
472
|
+
}
|
|
473
|
+
console.log('Configuration updated successfully.');
|
|
474
|
+
if (result.backupPath) {
|
|
475
|
+
console.log(`Backup: ${result.backupPath}`);
|
|
476
|
+
}
|
|
477
|
+
console.log('');
|
|
478
|
+
for (const change of result.changes) {
|
|
479
|
+
console.log(` faber.${change.key}: ${JSON.stringify(change.currentValue)} -> ${JSON.stringify(change.proposedValue)}`);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
catch (error) {
|
|
483
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
484
|
+
process.exit(1);
|
|
485
|
+
}
|
|
486
|
+
});
|
|
443
487
|
return configCmd;
|
|
444
488
|
}
|
|
445
489
|
/**
|
|
@@ -41,7 +41,7 @@ export declare function createWorkflowUpdateCommand(): Command;
|
|
|
41
41
|
*/
|
|
42
42
|
export declare function createWorkflowInspectCommand(): Command;
|
|
43
43
|
/**
|
|
44
|
-
* Create the workflow-
|
|
44
|
+
* Create the workflow-debug command
|
|
45
45
|
*/
|
|
46
|
-
export declare function
|
|
46
|
+
export declare function createWorkflowDebugCommand(): Command;
|
|
47
47
|
//# 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,CAkD1C;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,
|
|
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,CAkD1C;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"}
|
|
@@ -386,10 +386,10 @@ export function createWorkflowInspectCommand() {
|
|
|
386
386
|
});
|
|
387
387
|
}
|
|
388
388
|
/**
|
|
389
|
-
* Create the workflow-
|
|
389
|
+
* Create the workflow-debug command
|
|
390
390
|
*/
|
|
391
|
-
export function
|
|
392
|
-
return new Command('workflow-
|
|
391
|
+
export function createWorkflowDebugCommand() {
|
|
392
|
+
return new Command('workflow-debug')
|
|
393
393
|
.description('Debug a workflow run')
|
|
394
394
|
.option('--run-id <id>', 'Run ID to debug')
|
|
395
395
|
.option('--json', 'Output as JSON')
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAqDxC"}
|
package/dist/index.js
CHANGED
|
@@ -10,12 +10,11 @@ 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,
|
|
13
|
+
import { createRunCommand, createStatusCommand, createResumeCommand, createPauseCommand, createRecoverCommand, createCleanupCommand, createWorkflowCreateCommand, createWorkflowUpdateCommand, createWorkflowInspectCommand, createWorkflowDebugCommand } 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';
|
|
17
17
|
import { createLogsCommand } from './commands/logs/index.js';
|
|
18
|
-
import { createInitCommand } from './commands/init.js';
|
|
19
18
|
import { createMigrateCommand } from './commands/migrate.js';
|
|
20
19
|
import { createPlanCommand } from './commands/plan/index.js';
|
|
21
20
|
import { createAuthCommand } from './commands/auth/index.js';
|
|
@@ -25,7 +24,7 @@ import { createRunsCommand } from './commands/runs.js';
|
|
|
25
24
|
if (process.stdout.isTTY) {
|
|
26
25
|
process.stdout._handle?.setBlocking?.(true);
|
|
27
26
|
}
|
|
28
|
-
const version = '1.5.
|
|
27
|
+
const version = '1.5.22';
|
|
29
28
|
/**
|
|
30
29
|
* Create and configure the main CLI program
|
|
31
30
|
*/
|
|
@@ -37,10 +36,10 @@ export function createFaberCLI() {
|
|
|
37
36
|
.enablePositionalOptions();
|
|
38
37
|
// Global options
|
|
39
38
|
program.option('--debug', 'Enable debug output');
|
|
39
|
+
// Configuration commands
|
|
40
|
+
program.addCommand(createConfigCommand()); // config init/update/validate/get/set/migrate/path/exists
|
|
41
|
+
program.addCommand(createMigrateCommand()); // migrate (legacy top-level alias)
|
|
40
42
|
// Workflow commands (top-level)
|
|
41
|
-
program.addCommand(createInitCommand()); // configure
|
|
42
|
-
program.addCommand(createMigrateCommand()); // migrate
|
|
43
|
-
program.addCommand(createConfigCommand()); // config get/path/exists
|
|
44
43
|
program.addCommand(createRunsCommand()); // runs dir/plan-path/state-path
|
|
45
44
|
program.addCommand(createPlanCommand()); // workflow-plan
|
|
46
45
|
program.addCommand(createRunCommand()); // workflow-run
|
|
@@ -52,7 +51,7 @@ export function createFaberCLI() {
|
|
|
52
51
|
program.addCommand(createWorkflowCreateCommand()); // workflow-create
|
|
53
52
|
program.addCommand(createWorkflowUpdateCommand()); // workflow-update
|
|
54
53
|
program.addCommand(createWorkflowInspectCommand()); // workflow-inspect
|
|
55
|
-
program.addCommand(
|
|
54
|
+
program.addCommand(createWorkflowDebugCommand()); // workflow-debug
|
|
56
55
|
program.addCommand(createSessionLoadCommand()); // session-load
|
|
57
56
|
program.addCommand(createSessionSaveCommand()); // session-save
|
|
58
57
|
// Subcommand trees
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fractary/faber-cli",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.23",
|
|
4
4
|
"description": "FABER CLI - Command-line interface for FABER development toolkit",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@fractary/core": "^0.5.0",
|
|
41
|
-
"@fractary/faber": "^2.4.
|
|
41
|
+
"@fractary/faber": "^2.4.14",
|
|
42
42
|
"ajv": "^8.12.0",
|
|
43
43
|
"chalk": "^5.0.0",
|
|
44
44
|
"commander": "^12.0.0",
|