@fractary/faber-cli 1.5.12 → 1.5.13
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 +273 -20
- package/dist/commands/config.d.ts +9 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +106 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @fractary/faber-cli
|
|
2
2
|
|
|
3
|
-
Command-line interface for FABER development toolkit.
|
|
3
|
+
Command-line interface for FABER development toolkit. Execute and manage FABER workflows, work items, repository operations, specifications, and logs.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -16,35 +16,205 @@ npx @fractary/faber-cli --help
|
|
|
16
16
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
19
|
-
### 1.
|
|
19
|
+
### 1. Install
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
+
npm install -g @fractary/faber-cli
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or use directly with `npx`:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx @fractary/faber-cli --help
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. Authenticate with GitHub
|
|
32
|
+
|
|
33
|
+
**Option A: Automated Setup (Recommended)**
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd your-project
|
|
22
37
|
fractary-faber auth setup
|
|
23
38
|
```
|
|
24
39
|
|
|
25
|
-
|
|
40
|
+
This command will:
|
|
41
|
+
1. Detect your GitHub organization and repository
|
|
42
|
+
2. Show you a URL to create a GitHub App
|
|
43
|
+
3. Guide you through copying the authorization code
|
|
44
|
+
4. Automatically configure FABER CLI
|
|
45
|
+
|
|
46
|
+
All in ~30 seconds!
|
|
47
|
+
|
|
48
|
+
**Option B: Manual Setup**
|
|
49
|
+
|
|
50
|
+
See [GitHub App Setup Guide](../docs/github-app-setup.md) for detailed manual instructions.
|
|
51
|
+
|
|
52
|
+
### 3. Initialize a FABER project
|
|
26
53
|
|
|
27
54
|
```bash
|
|
28
55
|
fractary-faber init
|
|
56
|
+
fractary-faber init --preset minimal
|
|
57
|
+
fractary-faber init --preset enterprise
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Workflow Commands
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Start a FABER workflow
|
|
64
|
+
fractary-faber run --work-id 123
|
|
65
|
+
|
|
66
|
+
# Check workflow status
|
|
67
|
+
fractary-faber status
|
|
68
|
+
fractary-faber status --workflow-id <id>
|
|
69
|
+
|
|
70
|
+
# Pause/resume workflows
|
|
71
|
+
fractary-faber pause <workflow-id>
|
|
72
|
+
fractary-faber resume <workflow-id>
|
|
73
|
+
|
|
74
|
+
# Recover from checkpoint
|
|
75
|
+
fractary-faber recover <workflow-id>
|
|
76
|
+
|
|
77
|
+
# Clean up old workflows
|
|
78
|
+
fractary-faber cleanup --max-age 30
|
|
29
79
|
```
|
|
30
80
|
|
|
31
|
-
###
|
|
81
|
+
### Work Commands
|
|
32
82
|
|
|
33
83
|
```bash
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
84
|
+
# Issue operations
|
|
85
|
+
fractary-faber work issue fetch 123
|
|
86
|
+
fractary-faber work issue create --title "New feature"
|
|
87
|
+
fractary-faber work issue update 123 --title "Updated"
|
|
88
|
+
fractary-faber work issue close 123
|
|
89
|
+
fractary-faber work issue search --query "bug fix"
|
|
90
|
+
|
|
91
|
+
# Comment operations
|
|
92
|
+
fractary-faber work comment create 123 --body "This is a comment"
|
|
93
|
+
fractary-faber work comment list 123
|
|
94
|
+
|
|
95
|
+
# Label operations
|
|
96
|
+
fractary-faber work label add 123 --label "bug,critical"
|
|
97
|
+
fractary-faber work label remove 123 --label "wontfix"
|
|
98
|
+
fractary-faber work label list
|
|
99
|
+
|
|
100
|
+
# Milestone operations
|
|
101
|
+
fractary-faber work milestone create --title "v1.0" --due-on "2025-12-31"
|
|
102
|
+
fractary-faber work milestone list
|
|
103
|
+
fractary-faber work milestone set 123 --milestone "v1.0"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Repository Commands
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Branch operations
|
|
110
|
+
fractary-faber repo branch create "feat/new-feature"
|
|
111
|
+
fractary-faber repo branch list
|
|
112
|
+
fractary-faber repo branch delete feat/old-feature
|
|
113
|
+
|
|
114
|
+
# Commit operations
|
|
115
|
+
fractary-faber repo commit "feat: add new feature"
|
|
116
|
+
|
|
117
|
+
# Pull request operations
|
|
118
|
+
fractary-faber repo pr create "Add new feature" --body "Description"
|
|
119
|
+
fractary-faber repo pr list
|
|
120
|
+
fractary-faber repo pr merge 42
|
|
121
|
+
fractary-faber repo pr review 42
|
|
122
|
+
|
|
123
|
+
# Tag operations
|
|
124
|
+
fractary-faber repo tag create v1.0.0
|
|
125
|
+
fractary-faber repo tag push v1.0.0
|
|
126
|
+
fractary-faber repo tag list
|
|
127
|
+
|
|
128
|
+
# Worktree operations
|
|
129
|
+
fractary-faber repo worktree create feat/new-feature
|
|
130
|
+
fractary-faber repo worktree list
|
|
131
|
+
fractary-faber repo worktree remove feat/new-feature
|
|
37
132
|
```
|
|
38
133
|
|
|
39
|
-
|
|
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
|
+
```
|
|
40
158
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
159
|
+
### Logs Commands
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Capture logs
|
|
163
|
+
fractary-faber logs capture <workflow-id>
|
|
164
|
+
|
|
165
|
+
# Stop capturing logs
|
|
166
|
+
fractary-faber logs stop <session-id>
|
|
167
|
+
|
|
168
|
+
# Write logs
|
|
169
|
+
fractary-faber logs write --message "Log message"
|
|
170
|
+
|
|
171
|
+
# Read logs
|
|
172
|
+
fractary-faber logs read <session-id>
|
|
173
|
+
|
|
174
|
+
# Search logs
|
|
175
|
+
fractary-faber logs search --query "error"
|
|
176
|
+
|
|
177
|
+
# List logs
|
|
178
|
+
fractary-faber logs list
|
|
179
|
+
|
|
180
|
+
# Archive logs
|
|
181
|
+
fractary-faber logs archive --older-than 30
|
|
182
|
+
|
|
183
|
+
# Delete logs
|
|
184
|
+
fractary-faber logs delete <session-id>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Configuration
|
|
188
|
+
|
|
189
|
+
FABER is configured via `.fractary/faber/config.json`:
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"version": "1.0.0",
|
|
194
|
+
"preset": "default",
|
|
195
|
+
"work": {
|
|
196
|
+
"provider": "github"
|
|
197
|
+
},
|
|
198
|
+
"repo": {
|
|
199
|
+
"provider": "github",
|
|
200
|
+
"defaultBranch": "main"
|
|
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
|
+
}
|
|
217
|
+
```
|
|
48
218
|
|
|
49
219
|
## Options
|
|
50
220
|
|
|
@@ -54,13 +224,96 @@ All commands support:
|
|
|
54
224
|
- `--debug` - Enable debug output
|
|
55
225
|
- `--help` - Show command help
|
|
56
226
|
|
|
57
|
-
##
|
|
227
|
+
## Authentication
|
|
228
|
+
|
|
229
|
+
### GitHub App Authentication (Recommended)
|
|
230
|
+
|
|
231
|
+
For enhanced security, audit trails, and enterprise readiness, use GitHub App authentication instead of Personal Access Tokens.
|
|
232
|
+
|
|
233
|
+
**Quick Setup (Automated):**
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
fractary-faber auth setup
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
This command will guide you through creating and configuring a GitHub App in ~30 seconds.
|
|
240
|
+
|
|
241
|
+
**Manual Configuration (`.fractary/settings.json`):**
|
|
242
|
+
```json
|
|
243
|
+
{
|
|
244
|
+
"github": {
|
|
245
|
+
"organization": "your-org",
|
|
246
|
+
"project": "your-repo",
|
|
247
|
+
"app": {
|
|
248
|
+
"id": "123456",
|
|
249
|
+
"installation_id": "12345678",
|
|
250
|
+
"private_key_path": "~/.github/faber-app.pem"
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**For CI/CD (environment variable):**
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"github": {
|
|
260
|
+
"organization": "your-org",
|
|
261
|
+
"project": "your-repo",
|
|
262
|
+
"app": {
|
|
263
|
+
"id": "123456",
|
|
264
|
+
"installation_id": "12345678",
|
|
265
|
+
"private_key_env_var": "GITHUB_APP_PRIVATE_KEY"
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
export GITHUB_APP_PRIVATE_KEY=$(cat ~/.github/faber-app.pem | base64)
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**See detailed setup guide:** [docs/github-app-setup.md](../docs/github-app-setup.md)
|
|
276
|
+
|
|
277
|
+
### Personal Access Token (Legacy)
|
|
278
|
+
|
|
279
|
+
Still supported for backward compatibility:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
export GITHUB_TOKEN=<token>
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Or in `.fractary/settings.json`:
|
|
286
|
+
```json
|
|
287
|
+
{
|
|
288
|
+
"github": {
|
|
289
|
+
"token": "ghp_xxxxxxxxxxxx",
|
|
290
|
+
"organization": "your-org",
|
|
291
|
+
"project": "your-repo"
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Other Providers
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
# Jira
|
|
300
|
+
export JIRA_BASE_URL=<url>
|
|
301
|
+
export JIRA_USERNAME=<username>
|
|
302
|
+
export JIRA_API_TOKEN=<token>
|
|
303
|
+
|
|
304
|
+
# Linear
|
|
305
|
+
export LINEAR_API_KEY=<key>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Architecture
|
|
58
309
|
|
|
59
|
-
|
|
310
|
+
See [SPEC-00026: Distributed Plugin Architecture](../specs/SPEC-00026-distributed-plugin-architecture.md)
|
|
60
311
|
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
312
|
+
The CLI follows SPEC-00026 standards:
|
|
313
|
+
- Package: `@fractary/faber-cli`
|
|
314
|
+
- Binary: `fractary-faber`
|
|
315
|
+
- Located: `/cli` at root of repository
|
|
316
|
+
- Depends on: `@fractary/faber` SDK
|
|
64
317
|
|
|
65
318
|
## License
|
|
66
319
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config command - Read FABER configuration from unified config.yaml
|
|
3
|
+
*
|
|
4
|
+
* This command provides access to configuration values for scripts and tools.
|
|
5
|
+
* It uses the SDK's config loading logic, ensuring consistency across all tools.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
export declare function createConfigCommand(): Command;
|
|
9
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,wBAAgB,mBAAmB,IAAI,OAAO,CAkF7C"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config command - Read FABER configuration from unified config.yaml
|
|
3
|
+
*
|
|
4
|
+
* This command provides access to configuration values for scripts and tools.
|
|
5
|
+
* It uses the SDK's config loading logic, ensuring consistency across all tools.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { loadYamlConfig, configExists, getConfigPath, } from '../lib/yaml-config.js';
|
|
9
|
+
/**
|
|
10
|
+
* Get a nested value from an object using dot notation
|
|
11
|
+
* @param obj The object to search
|
|
12
|
+
* @param path Dot-separated path (e.g., "faber.default_workflow")
|
|
13
|
+
* @returns The value at the path, or undefined if not found
|
|
14
|
+
*/
|
|
15
|
+
function getNestedValue(obj, path) {
|
|
16
|
+
const parts = path.split('.');
|
|
17
|
+
let current = obj;
|
|
18
|
+
for (const part of parts) {
|
|
19
|
+
if (current === null || current === undefined) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
if (typeof current !== 'object') {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
current = current[part];
|
|
26
|
+
}
|
|
27
|
+
return current;
|
|
28
|
+
}
|
|
29
|
+
export function createConfigCommand() {
|
|
30
|
+
const configCmd = new Command('config')
|
|
31
|
+
.description('Manage FABER configuration');
|
|
32
|
+
configCmd
|
|
33
|
+
.command('get')
|
|
34
|
+
.description('Get configuration values')
|
|
35
|
+
.argument('[key]', 'Configuration key path (e.g., faber.default_workflow). Omit for full config.')
|
|
36
|
+
.option('--json', 'Output as JSON (default when no key specified)')
|
|
37
|
+
.option('--raw', 'Output raw value without quotes (for shell scripts)')
|
|
38
|
+
.action(async (key, options) => {
|
|
39
|
+
try {
|
|
40
|
+
// Check if config exists
|
|
41
|
+
if (!configExists()) {
|
|
42
|
+
const configPath = getConfigPath();
|
|
43
|
+
console.error(`Error: Configuration not found at ${configPath}`);
|
|
44
|
+
console.error('Run: fractary-core:init to create configuration');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
// Load configuration using SDK logic
|
|
48
|
+
const config = loadYamlConfig({ warnMissingEnvVars: false });
|
|
49
|
+
if (!config) {
|
|
50
|
+
console.error('Error: Failed to load configuration');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
// If no key specified, output full config
|
|
54
|
+
if (!key) {
|
|
55
|
+
console.log(JSON.stringify(config, null, options.json ? 2 : 0));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Get nested value
|
|
59
|
+
const value = getNestedValue(config, key);
|
|
60
|
+
if (value === undefined) {
|
|
61
|
+
if (options.raw) {
|
|
62
|
+
// Output empty string for undefined (useful for shell scripts)
|
|
63
|
+
console.log('');
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.log('null');
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Output value
|
|
71
|
+
if (options.raw && typeof value === 'string') {
|
|
72
|
+
// Raw output - no quotes, no JSON
|
|
73
|
+
console.log(value);
|
|
74
|
+
}
|
|
75
|
+
else if (typeof value === 'object') {
|
|
76
|
+
// Objects are always JSON
|
|
77
|
+
console.log(JSON.stringify(value, null, options.json ? 2 : 0));
|
|
78
|
+
}
|
|
79
|
+
else if (options.json) {
|
|
80
|
+
// JSON output
|
|
81
|
+
console.log(JSON.stringify(value));
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// Default: string values without quotes, others as JSON
|
|
85
|
+
console.log(typeof value === 'string' ? value : JSON.stringify(value));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
configCmd
|
|
94
|
+
.command('path')
|
|
95
|
+
.description('Show configuration file path')
|
|
96
|
+
.action(() => {
|
|
97
|
+
console.log(getConfigPath());
|
|
98
|
+
});
|
|
99
|
+
configCmd
|
|
100
|
+
.command('exists')
|
|
101
|
+
.description('Check if configuration file exists (exit 0 if yes, 1 if no)')
|
|
102
|
+
.action(() => {
|
|
103
|
+
process.exit(configExists() ? 0 : 1);
|
|
104
|
+
});
|
|
105
|
+
return configCmd;
|
|
106
|
+
}
|
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;AAmBpC;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CA0KxC"}
|
package/dist/index.js
CHANGED
|
@@ -18,11 +18,12 @@ import { createInitCommand } from './commands/init.js';
|
|
|
18
18
|
import { createMigrateCommand } from './commands/migrate.js';
|
|
19
19
|
import { createPlanCommand } from './commands/plan/index.js';
|
|
20
20
|
import { createAuthCommand } from './commands/auth/index.js';
|
|
21
|
+
import { createConfigCommand } from './commands/config.js';
|
|
21
22
|
// Force unbuffered output to prevent buffering issues in terminals
|
|
22
23
|
if (process.stdout.isTTY) {
|
|
23
24
|
process.stdout._handle?.setBlocking?.(true);
|
|
24
25
|
}
|
|
25
|
-
const version = '1.5.
|
|
26
|
+
const version = '1.5.13';
|
|
26
27
|
/**
|
|
27
28
|
* Create and configure the main CLI program
|
|
28
29
|
*/
|
|
@@ -37,6 +38,7 @@ export function createFaberCLI() {
|
|
|
37
38
|
// Workflow commands (top-level)
|
|
38
39
|
program.addCommand(createInitCommand()); // init
|
|
39
40
|
program.addCommand(createMigrateCommand()); // migrate
|
|
41
|
+
program.addCommand(createConfigCommand()); // config get/path/exists
|
|
40
42
|
program.addCommand(createPlanCommand()); // plan
|
|
41
43
|
program.addCommand(createRunCommand()); // workflow-run
|
|
42
44
|
program.addCommand(createStatusCommand()); // run-inspect
|