@fractary/faber-cli 1.4.4 → 1.5.0
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/dist/commands/auth/index.d.ts.map +1 -1
- package/dist/commands/auth/index.js +42 -52
- package/dist/commands/init.d.ts +4 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +120 -149
- package/dist/commands/migrate.d.ts +9 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +213 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -7
- package/dist/lib/anthropic-client.d.ts +2 -2
- package/dist/lib/anthropic-client.d.ts.map +1 -1
- package/dist/lib/config.d.ts +9 -4
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +41 -32
- package/dist/lib/repo-client.d.ts +3 -3
- package/dist/lib/repo-client.d.ts.map +1 -1
- package/dist/lib/sdk-config-adapter.d.ts +9 -9
- package/dist/lib/sdk-config-adapter.d.ts.map +1 -1
- package/dist/lib/yaml-config.d.ts +108 -0
- package/dist/lib/yaml-config.d.ts.map +1 -0
- package/dist/lib/yaml-config.js +343 -0
- package/dist/types/config.d.ts +58 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +1 -0
- package/package.json +4 -2
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migrate command - Convert .fractary/settings.json to .fractary/config.yaml
|
|
3
|
+
*
|
|
4
|
+
* Migrates old FABER configuration to the unified config format.
|
|
5
|
+
* After migration, settings.json is backed up and all FABER commands use config.yaml.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import fs from 'fs/promises';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import * as yaml from 'js-yaml';
|
|
12
|
+
import { loadYamlConfig, writeYamlConfig, findProjectRoot, configExists, oldSettingsExists, getOldSettingsPath, getConfigPath } from '../lib/yaml-config.js';
|
|
13
|
+
export function createMigrateCommand() {
|
|
14
|
+
return new Command('migrate')
|
|
15
|
+
.description('Migrate from .fractary/settings.json to .fractary/config.yaml')
|
|
16
|
+
.option('--dry-run', 'Show what would be migrated without making changes')
|
|
17
|
+
.option('--no-backup', 'Do not create backup of old settings.json')
|
|
18
|
+
.option('--json', 'Output as JSON')
|
|
19
|
+
.action(async (options) => {
|
|
20
|
+
try {
|
|
21
|
+
const projectRoot = findProjectRoot();
|
|
22
|
+
const settingsPath = getOldSettingsPath(projectRoot);
|
|
23
|
+
const configPath = getConfigPath(projectRoot);
|
|
24
|
+
// Step 1: Check if settings.json exists
|
|
25
|
+
if (!oldSettingsExists(projectRoot)) {
|
|
26
|
+
if (options.json) {
|
|
27
|
+
console.log(JSON.stringify({
|
|
28
|
+
status: 'error',
|
|
29
|
+
error: {
|
|
30
|
+
message: 'No .fractary/settings.json found to migrate',
|
|
31
|
+
recommendation: 'If starting fresh, run: fractary-core:init'
|
|
32
|
+
}
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.error(chalk.red('Error: No .fractary/settings.json found to migrate'));
|
|
37
|
+
console.log();
|
|
38
|
+
console.log('If you\'re starting fresh, run:');
|
|
39
|
+
console.log(chalk.cyan(' fractary-core:init'));
|
|
40
|
+
console.log();
|
|
41
|
+
}
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
// Step 2: Load old settings
|
|
45
|
+
let oldSettings;
|
|
46
|
+
try {
|
|
47
|
+
const content = await fs.readFile(settingsPath, 'utf-8');
|
|
48
|
+
oldSettings = JSON.parse(content);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
52
|
+
if (options.json) {
|
|
53
|
+
console.log(JSON.stringify({
|
|
54
|
+
status: 'error',
|
|
55
|
+
error: { message: `Failed to parse settings.json: ${message}` }
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
console.error(chalk.red(`Error: Failed to parse settings.json: ${message}`));
|
|
60
|
+
}
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
// Step 3: Load existing config.yaml (if exists)
|
|
64
|
+
let config;
|
|
65
|
+
const configExistsAlready = configExists(projectRoot);
|
|
66
|
+
if (configExistsAlready) {
|
|
67
|
+
config = loadYamlConfig({ projectRoot }) || { version: '2.0' };
|
|
68
|
+
if (!options.json) {
|
|
69
|
+
console.log(chalk.yellow('Note: Existing config.yaml found - will merge settings'));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
config = { version: '2.0' };
|
|
74
|
+
}
|
|
75
|
+
// Step 4: Build migrated config
|
|
76
|
+
// Map old structure to new unified structure
|
|
77
|
+
if (oldSettings.anthropic) {
|
|
78
|
+
config.anthropic = {
|
|
79
|
+
...config.anthropic,
|
|
80
|
+
...oldSettings.anthropic
|
|
81
|
+
};
|
|
82
|
+
// Convert hardcoded API key to env var reference if present
|
|
83
|
+
if (config.anthropic?.api_key && !config.anthropic.api_key.startsWith('${')) {
|
|
84
|
+
if (!options.json) {
|
|
85
|
+
console.log(chalk.yellow('⚠️ Found hardcoded Anthropic API key'));
|
|
86
|
+
console.log(' Recommendation: Set ANTHROPIC_API_KEY environment variable');
|
|
87
|
+
console.log(' and use ${ANTHROPIC_API_KEY} in config.yaml');
|
|
88
|
+
console.log();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (oldSettings.github) {
|
|
93
|
+
config.github = {
|
|
94
|
+
...config.github,
|
|
95
|
+
...oldSettings.github
|
|
96
|
+
};
|
|
97
|
+
// Warn about hardcoded tokens
|
|
98
|
+
if (config.github?.token && !config.github.token.startsWith('${')) {
|
|
99
|
+
if (!options.json) {
|
|
100
|
+
console.log(chalk.yellow('⚠️ Found hardcoded GitHub token'));
|
|
101
|
+
console.log(' Recommendation: Set GITHUB_TOKEN environment variable');
|
|
102
|
+
console.log(' and use ${GITHUB_TOKEN} in config.yaml');
|
|
103
|
+
console.log();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Move FABER-specific settings to faber section
|
|
108
|
+
if (oldSettings.worktree || oldSettings.workflow || oldSettings.backlog_management) {
|
|
109
|
+
// Validate and convert backlog_management.default_order_by
|
|
110
|
+
let backlogManagement;
|
|
111
|
+
if (oldSettings.backlog_management) {
|
|
112
|
+
const validOrderBy = ['priority', 'created', 'updated', 'none'];
|
|
113
|
+
const orderBy = oldSettings.backlog_management.default_order_by;
|
|
114
|
+
backlogManagement = {
|
|
115
|
+
...oldSettings.backlog_management,
|
|
116
|
+
default_order_by: orderBy && validOrderBy.includes(orderBy)
|
|
117
|
+
? orderBy
|
|
118
|
+
: undefined
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
config.faber = {
|
|
122
|
+
...config.faber,
|
|
123
|
+
...(oldSettings.worktree && { worktree: oldSettings.worktree }),
|
|
124
|
+
...(oldSettings.workflow && { workflow: oldSettings.workflow }),
|
|
125
|
+
...(backlogManagement && { backlog_management: backlogManagement })
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
// Step 5: Handle dry-run
|
|
129
|
+
if (options.dryRun) {
|
|
130
|
+
const yamlContent = yaml.dump(config, {
|
|
131
|
+
indent: 2,
|
|
132
|
+
lineWidth: 100,
|
|
133
|
+
noRefs: true,
|
|
134
|
+
sortKeys: false,
|
|
135
|
+
});
|
|
136
|
+
if (options.json) {
|
|
137
|
+
console.log(JSON.stringify({
|
|
138
|
+
status: 'dry-run',
|
|
139
|
+
wouldWrite: configPath,
|
|
140
|
+
wouldBackup: options.backup !== false ? `${settingsPath}.backup` : null,
|
|
141
|
+
config: config
|
|
142
|
+
}, null, 2));
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
console.log(chalk.cyan('Dry run - would write to config.yaml:'));
|
|
146
|
+
console.log();
|
|
147
|
+
console.log(yamlContent);
|
|
148
|
+
console.log();
|
|
149
|
+
if (options.backup !== false) {
|
|
150
|
+
console.log(chalk.gray(`Would backup: ${settingsPath} → ${settingsPath}.backup`));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
// Step 6: Write new config
|
|
156
|
+
writeYamlConfig(config, projectRoot);
|
|
157
|
+
// Step 7: Backup old settings
|
|
158
|
+
if (options.backup !== false) {
|
|
159
|
+
const backupPath = `${settingsPath}.backup`;
|
|
160
|
+
await fs.rename(settingsPath, backupPath);
|
|
161
|
+
if (options.json) {
|
|
162
|
+
console.log(JSON.stringify({
|
|
163
|
+
status: 'success',
|
|
164
|
+
configPath,
|
|
165
|
+
backupPath,
|
|
166
|
+
message: 'Successfully migrated to config.yaml'
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.log(chalk.green('✓ Successfully migrated to .fractary/config.yaml'));
|
|
171
|
+
console.log(chalk.green(`✓ Backup created at ${path.relative(projectRoot, backupPath)}`));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
// Delete old settings without backup
|
|
176
|
+
await fs.unlink(settingsPath);
|
|
177
|
+
if (options.json) {
|
|
178
|
+
console.log(JSON.stringify({
|
|
179
|
+
status: 'success',
|
|
180
|
+
configPath,
|
|
181
|
+
message: 'Successfully migrated to config.yaml (no backup)'
|
|
182
|
+
}));
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
console.log(chalk.green('✓ Successfully migrated to .fractary/config.yaml'));
|
|
186
|
+
console.log(chalk.yellow('⚠️ Old settings.json deleted (no backup)'));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (!options.json) {
|
|
190
|
+
console.log();
|
|
191
|
+
console.log('Next steps:');
|
|
192
|
+
console.log(' 1. Review .fractary/config.yaml');
|
|
193
|
+
console.log(' 2. Replace any hardcoded secrets with environment variable references');
|
|
194
|
+
console.log(' Example: api_key: ${ANTHROPIC_API_KEY}');
|
|
195
|
+
console.log(' 3. Consider running ' + chalk.cyan('fractary-core:init') + ' to set up other plugins');
|
|
196
|
+
console.log();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
201
|
+
if (options.json) {
|
|
202
|
+
console.error(JSON.stringify({
|
|
203
|
+
status: 'error',
|
|
204
|
+
error: { message }
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
console.error(chalk.red('Error:'), message);
|
|
209
|
+
}
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
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;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CA4IxC"}
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { createRepoCommand } from './commands/repo/index.js';
|
|
|
13
13
|
import { createSpecCommand } from './commands/spec/index.js';
|
|
14
14
|
import { createLogsCommand } from './commands/logs/index.js';
|
|
15
15
|
import { createInitCommand } from './commands/init.js';
|
|
16
|
+
import { createMigrateCommand } from './commands/migrate.js';
|
|
16
17
|
import { createPlanCommand } from './commands/plan/index.js';
|
|
17
18
|
import { createAuthCommand } from './commands/auth/index.js';
|
|
18
19
|
// Force unbuffered output to prevent buffering issues in terminals
|
|
@@ -32,9 +33,10 @@ export function createFaberCLI() {
|
|
|
32
33
|
.enablePositionalOptions();
|
|
33
34
|
// Global options
|
|
34
35
|
program.option('--debug', 'Enable debug output');
|
|
35
|
-
// Workflow commands (top-level)
|
|
36
|
-
program.addCommand(createInitCommand()); //
|
|
37
|
-
program.addCommand(
|
|
36
|
+
// Workflow commands (top-level)
|
|
37
|
+
program.addCommand(createInitCommand()); // init
|
|
38
|
+
program.addCommand(createMigrateCommand()); // migrate
|
|
39
|
+
program.addCommand(createPlanCommand()); // plan
|
|
38
40
|
program.addCommand(createRunCommand()); // workflow-run
|
|
39
41
|
program.addCommand(createStatusCommand()); // workflow-status
|
|
40
42
|
program.addCommand(createResumeCommand()); // workflow-resume
|
|
@@ -46,13 +48,12 @@ export function createFaberCLI() {
|
|
|
46
48
|
console.warn(chalk.yellow(`\n⚠️ DEPRECATED: "${oldName}" → use "${newName}"\n`));
|
|
47
49
|
};
|
|
48
50
|
program
|
|
49
|
-
.command('init')
|
|
50
|
-
.description('(DEPRECATED: Use
|
|
51
|
-
.option('--preset <name>', 'Use a preset configuration', 'default')
|
|
51
|
+
.command('workflow-init')
|
|
52
|
+
.description('(DEPRECATED: Use init)')
|
|
52
53
|
.option('--force', 'Overwrite existing configuration')
|
|
53
54
|
.option('--json', 'Output as JSON')
|
|
54
55
|
.action((options) => {
|
|
55
|
-
showDeprecationWarning('init', '
|
|
56
|
+
showDeprecationWarning('workflow-init', 'init');
|
|
56
57
|
const initCmd = createInitCommand();
|
|
57
58
|
initCmd.parse(['', '', ...Object.entries(options).flatMap(([k, v]) => typeof v === 'boolean' && v ? [`--${k}`] : typeof v === 'string' ? [`--${k}`, v] : [])], { from: 'user' });
|
|
58
59
|
});
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates workflow plans via Claude API
|
|
5
5
|
*/
|
|
6
|
-
import type {
|
|
6
|
+
import type { LoadedFaberConfig } from '../types/config.js';
|
|
7
7
|
interface GeneratePlanInput {
|
|
8
8
|
workflow: string;
|
|
9
9
|
issueTitle: string;
|
|
@@ -35,7 +35,7 @@ export declare class AnthropicClient {
|
|
|
35
35
|
private git;
|
|
36
36
|
private ajv;
|
|
37
37
|
private planSchema;
|
|
38
|
-
constructor(config:
|
|
38
|
+
constructor(config: LoadedFaberConfig);
|
|
39
39
|
/**
|
|
40
40
|
* Load plan JSON schema for validation
|
|
41
41
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-client.d.ts","sourceRoot":"","sources":["../../src/lib/anthropic-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"anthropic-client.d.ts","sourceRoot":"","sources":["../../src/lib/anthropic-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAK5D,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,YAAY;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE;QACL,MAAM,EAAE,MAAM,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,UAAU,CAAM;gBAEZ,MAAM,EAAE,iBAAiB;IAerC;;OAEG;YACW,cAAc;IAiB5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;OAEG;IACG,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IA6DnE;;OAEG;YACW,kBAAkB;IAchC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAqD/B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAgB/B;;OAEG;YACW,eAAe;CAqB9B"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Configuration Manager
|
|
3
3
|
*
|
|
4
|
-
* Loads FABER CLI configuration
|
|
4
|
+
* Loads FABER CLI configuration from unified .fractary/config.yaml
|
|
5
|
+
* and respects Claude Code settings
|
|
5
6
|
*/
|
|
6
|
-
import type { FaberConfig } from '../types/config.js';
|
|
7
|
+
import type { FaberConfig, AnthropicConfig, GitHubConfig } from '../types/config.js';
|
|
7
8
|
/**
|
|
8
9
|
* Configuration Manager
|
|
9
10
|
*/
|
|
@@ -11,9 +12,13 @@ export declare class ConfigManager {
|
|
|
11
12
|
private config;
|
|
12
13
|
private constructor();
|
|
13
14
|
/**
|
|
14
|
-
* Load configuration
|
|
15
|
+
* Load configuration from unified .fractary/config.yaml
|
|
16
|
+
* Returns a FaberConfig structure with all necessary settings
|
|
15
17
|
*/
|
|
16
|
-
static load(): Promise<FaberConfig
|
|
18
|
+
static load(): Promise<FaberConfig & {
|
|
19
|
+
anthropic?: AnthropicConfig;
|
|
20
|
+
github?: GitHubConfig;
|
|
21
|
+
}>;
|
|
17
22
|
/**
|
|
18
23
|
* Find config file by searching upwards from current directory
|
|
19
24
|
* Similar to how git finds .git directory
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAiB,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGpG;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAc;IAE5B,OAAO;IAIP;;;OAGG;WACU,IAAI,IAAI,OAAO,CAAC,WAAW,GAAG;QAAE,SAAS,CAAC,EAAE,eAAe,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,CAAA;KAAE,CAAC;IAiGlG;;;OAGG;mBACkB,cAAc;IAwBnC;;OAEG;mBACkB,8BAA8B;IAoBnD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAyBnC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,WAAW,GAAG,GAAG;CAGjC"}
|
package/dist/lib/config.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Configuration Manager
|
|
3
3
|
*
|
|
4
|
-
* Loads FABER CLI configuration
|
|
4
|
+
* Loads FABER CLI configuration from unified .fractary/config.yaml
|
|
5
|
+
* and respects Claude Code settings
|
|
5
6
|
*/
|
|
6
7
|
import fs from 'fs/promises';
|
|
7
8
|
import path from 'path';
|
|
8
9
|
import os from 'os';
|
|
10
|
+
import { loadYamlConfig, oldSettingsExists, getOldSettingsPath } from './yaml-config.js';
|
|
9
11
|
/**
|
|
10
12
|
* Configuration Manager
|
|
11
13
|
*/
|
|
@@ -14,41 +16,48 @@ export class ConfigManager {
|
|
|
14
16
|
this.config = config;
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
|
-
* Load configuration
|
|
19
|
+
* Load configuration from unified .fractary/config.yaml
|
|
20
|
+
* Returns a FaberConfig structure with all necessary settings
|
|
18
21
|
*/
|
|
19
22
|
static async load() {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
28
|
-
// Load from FABER config file - search upwards from current directory
|
|
29
|
-
try {
|
|
30
|
-
const faberConfigPath = await ConfigManager.findConfigFile('.fractary', 'settings.json');
|
|
31
|
-
if (faberConfigPath) {
|
|
32
|
-
const faberConfigContent = await fs.readFile(faberConfigPath, 'utf-8');
|
|
33
|
-
const faberConfig = JSON.parse(faberConfigContent);
|
|
34
|
-
// Merge with config
|
|
35
|
-
if (faberConfig.anthropic) {
|
|
36
|
-
config.anthropic = { ...config.anthropic, ...faberConfig.anthropic };
|
|
37
|
-
}
|
|
38
|
-
if (faberConfig.github) {
|
|
39
|
-
config.github = { ...config.github, ...faberConfig.github };
|
|
40
|
-
}
|
|
41
|
-
if (faberConfig.worktree) {
|
|
42
|
-
config.worktree = { ...config.worktree, ...faberConfig.worktree };
|
|
43
|
-
}
|
|
44
|
-
if (faberConfig.workflow) {
|
|
45
|
-
config.workflow = { ...config.workflow, ...faberConfig.workflow };
|
|
46
|
-
}
|
|
47
|
-
}
|
|
23
|
+
// Check if old settings.json exists and show error
|
|
24
|
+
if (oldSettingsExists()) {
|
|
25
|
+
const oldPath = getOldSettingsPath();
|
|
26
|
+
throw new Error(`Found old configuration at ${oldPath}\n\n` +
|
|
27
|
+
`This version requires .fractary/config.yaml format.\n` +
|
|
28
|
+
`Run: fractary-faber migrate\n\n` +
|
|
29
|
+
`This will convert your settings to the new unified config format.`);
|
|
48
30
|
}
|
|
49
|
-
|
|
50
|
-
|
|
31
|
+
// Load unified config from YAML
|
|
32
|
+
const unifiedConfig = loadYamlConfig({ warnMissingEnvVars: true });
|
|
33
|
+
if (!unifiedConfig) {
|
|
34
|
+
throw new Error('No .fractary/config.yaml found.\n' +
|
|
35
|
+
'Run `fractary-core:init` first to initialize shared configuration.');
|
|
51
36
|
}
|
|
37
|
+
// Extract anthropic config (from top level)
|
|
38
|
+
let anthropic = {
|
|
39
|
+
api_key: process.env.ANTHROPIC_API_KEY || unifiedConfig.anthropic?.api_key,
|
|
40
|
+
model: unifiedConfig.anthropic?.model,
|
|
41
|
+
max_tokens: unifiedConfig.anthropic?.max_tokens,
|
|
42
|
+
};
|
|
43
|
+
// Extract github config (from top level)
|
|
44
|
+
let github = {
|
|
45
|
+
token: process.env.GITHUB_TOKEN || unifiedConfig.github?.token,
|
|
46
|
+
organization: unifiedConfig.github?.organization,
|
|
47
|
+
project: unifiedConfig.github?.project,
|
|
48
|
+
repo: unifiedConfig.github?.repo,
|
|
49
|
+
app: unifiedConfig.github?.app,
|
|
50
|
+
};
|
|
51
|
+
// Extract FABER-specific config
|
|
52
|
+
const faberConfig = unifiedConfig.faber || {};
|
|
53
|
+
// Build the result config (keeping anthropic and github for backward compatibility)
|
|
54
|
+
const config = {
|
|
55
|
+
anthropic,
|
|
56
|
+
github,
|
|
57
|
+
worktree: faberConfig.worktree,
|
|
58
|
+
workflow: faberConfig.workflow,
|
|
59
|
+
backlog_management: faberConfig.backlog_management,
|
|
60
|
+
};
|
|
52
61
|
// Read Claude Code configuration for worktree location
|
|
53
62
|
if (!config.worktree?.location || config.worktree?.inherit_from_claude !== false) {
|
|
54
63
|
const claudeWorktreeLocation = await ConfigManager.readClaudeCodeWorktreeLocation();
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Supports both PAT and GitHub App authentication methods.
|
|
6
6
|
*/
|
|
7
7
|
import { WorkManager, RepoManager } from '@fractary/core';
|
|
8
|
-
import type {
|
|
8
|
+
import type { LoadedFaberConfig } from '../types/config.js';
|
|
9
9
|
interface Issue {
|
|
10
10
|
id: string;
|
|
11
11
|
number: number;
|
|
@@ -51,7 +51,7 @@ export declare class RepoClient {
|
|
|
51
51
|
* @param config - FABER CLI configuration
|
|
52
52
|
* @returns Promise resolving to RepoClient instance
|
|
53
53
|
*/
|
|
54
|
-
static create(config:
|
|
54
|
+
static create(config: LoadedFaberConfig): Promise<RepoClient>;
|
|
55
55
|
/**
|
|
56
56
|
* Create a RepoClient instance
|
|
57
57
|
*
|
|
@@ -59,7 +59,7 @@ export declare class RepoClient {
|
|
|
59
59
|
* @param workManager - Optional pre-initialized WorkManager (for async factory)
|
|
60
60
|
* @param repoManager - Optional pre-initialized RepoManager (for async factory)
|
|
61
61
|
*/
|
|
62
|
-
constructor(config:
|
|
62
|
+
constructor(config: LoadedFaberConfig, workManager?: WorkManager, repoManager?: RepoManager);
|
|
63
63
|
/**
|
|
64
64
|
* Fetch specific issues by ID
|
|
65
65
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo-client.d.ts","sourceRoot":"","sources":["../../src/lib/repo-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAS1D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"repo-client.d.ts","sourceRoot":"","sources":["../../src/lib/repo-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAS1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAS;IAExB;;;;;;;;OAQG;WACU,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAmBnE;;;;;;OAMG;gBACS,MAAM,EAAE,iBAAiB,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,WAAW;IA0C3F;;;;OAIG;IACG,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAclD;;;;OAIG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAetD;;;;OAIG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrD;;;;OAIG;IACG,cAAc,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IA+BzF;;;;OAIG;IACG,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CA0B9D"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Converts FABER CLI configuration to @fractary/core SDK configuration format
|
|
5
5
|
* Supports both PAT and GitHub App authentication methods.
|
|
6
6
|
*/
|
|
7
|
-
import type {
|
|
7
|
+
import type { LoadedFaberConfig } from '../types/config.js';
|
|
8
8
|
import type { WorkConfig, RepoConfig } from '@fractary/core';
|
|
9
9
|
import { TokenProvider } from './github-app-auth.js';
|
|
10
10
|
/**
|
|
@@ -14,7 +14,7 @@ import { TokenProvider } from './github-app-auth.js';
|
|
|
14
14
|
* @param faberConfig - FABER CLI configuration
|
|
15
15
|
* @returns Promise resolving to the current token
|
|
16
16
|
*/
|
|
17
|
-
export declare function getToken(faberConfig:
|
|
17
|
+
export declare function getToken(faberConfig: LoadedFaberConfig): Promise<string>;
|
|
18
18
|
/**
|
|
19
19
|
* Get the token provider for dynamic token refresh
|
|
20
20
|
* Useful for long-running operations that need fresh tokens
|
|
@@ -22,21 +22,21 @@ export declare function getToken(faberConfig: FaberConfig): Promise<string>;
|
|
|
22
22
|
* @param faberConfig - FABER CLI configuration
|
|
23
23
|
* @returns TokenProvider instance
|
|
24
24
|
*/
|
|
25
|
-
export declare function getTokenProviderInstance(faberConfig:
|
|
25
|
+
export declare function getTokenProviderInstance(faberConfig: LoadedFaberConfig): TokenProvider;
|
|
26
26
|
/**
|
|
27
27
|
* Validate GitHub authentication configuration
|
|
28
28
|
*
|
|
29
29
|
* @param faberConfig - FABER CLI configuration
|
|
30
30
|
* @throws Error if configuration is invalid
|
|
31
31
|
*/
|
|
32
|
-
export declare function validateGitHubAuth(faberConfig:
|
|
32
|
+
export declare function validateGitHubAuth(faberConfig: LoadedFaberConfig): Promise<void>;
|
|
33
33
|
/**
|
|
34
34
|
* Check if GitHub App authentication is configured
|
|
35
35
|
*
|
|
36
36
|
* @param faberConfig - FABER CLI configuration
|
|
37
37
|
* @returns true if GitHub App is configured
|
|
38
38
|
*/
|
|
39
|
-
export declare function isGitHubAppConfigured(faberConfig:
|
|
39
|
+
export declare function isGitHubAppConfigured(faberConfig: LoadedFaberConfig): boolean;
|
|
40
40
|
/**
|
|
41
41
|
* Create WorkConfig for WorkManager from FaberConfig
|
|
42
42
|
*
|
|
@@ -44,7 +44,7 @@ export declare function isGitHubAppConfigured(faberConfig: FaberConfig): boolean
|
|
|
44
44
|
* @returns WorkConfig for @fractary/core WorkManager
|
|
45
45
|
* @throws Error if required fields are missing
|
|
46
46
|
*/
|
|
47
|
-
export declare function createWorkConfig(faberConfig:
|
|
47
|
+
export declare function createWorkConfig(faberConfig: LoadedFaberConfig): WorkConfig;
|
|
48
48
|
/**
|
|
49
49
|
* Create WorkConfig for WorkManager from FaberConfig (async version)
|
|
50
50
|
*
|
|
@@ -54,7 +54,7 @@ export declare function createWorkConfig(faberConfig: FaberConfig): WorkConfig;
|
|
|
54
54
|
* @returns Promise resolving to WorkConfig for @fractary/core WorkManager
|
|
55
55
|
* @throws Error if required fields are missing
|
|
56
56
|
*/
|
|
57
|
-
export declare function createWorkConfigAsync(faberConfig:
|
|
57
|
+
export declare function createWorkConfigAsync(faberConfig: LoadedFaberConfig): Promise<WorkConfig>;
|
|
58
58
|
/**
|
|
59
59
|
* Create RepoConfig for RepoManager from FaberConfig
|
|
60
60
|
*
|
|
@@ -62,7 +62,7 @@ export declare function createWorkConfigAsync(faberConfig: FaberConfig): Promise
|
|
|
62
62
|
* @returns RepoConfig for @fractary/core RepoManager
|
|
63
63
|
* @throws Error if required fields are missing
|
|
64
64
|
*/
|
|
65
|
-
export declare function createRepoConfig(faberConfig:
|
|
65
|
+
export declare function createRepoConfig(faberConfig: LoadedFaberConfig): RepoConfig;
|
|
66
66
|
/**
|
|
67
67
|
* Create RepoConfig for RepoManager from FaberConfig (async version)
|
|
68
68
|
*
|
|
@@ -72,5 +72,5 @@ export declare function createRepoConfig(faberConfig: FaberConfig): RepoConfig;
|
|
|
72
72
|
* @returns Promise resolving to RepoConfig for @fractary/core RepoManager
|
|
73
73
|
* @throws Error if required fields are missing
|
|
74
74
|
*/
|
|
75
|
-
export declare function createRepoConfigAsync(faberConfig:
|
|
75
|
+
export declare function createRepoConfigAsync(faberConfig: LoadedFaberConfig): Promise<RepoConfig>;
|
|
76
76
|
//# sourceMappingURL=sdk-config-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-config-adapter.d.ts","sourceRoot":"","sources":["../../src/lib/sdk-config-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"sdk-config-adapter.d.ts","sourceRoot":"","sources":["../../src/lib/sdk-config-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAmB,MAAM,oBAAoB,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAEL,aAAa,EAGd,MAAM,sBAAsB,CAAC;AA2D9B;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAG9E;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,iBAAiB,GAAG,aAAa,CAEtF;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBtF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAG7E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,iBAAiB,GAAG,UAAU,CAmC3E;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAkB/F;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,iBAAiB,GAAG,UAAU,CAyB3E;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAY/F"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified YAML Configuration Loader for FABER CLI
|
|
3
|
+
*
|
|
4
|
+
* Loads and parses `.fractary/config.yaml` with environment variable substitution.
|
|
5
|
+
* Provides access to shared configuration for FABER and fractary-core plugins.
|
|
6
|
+
*/
|
|
7
|
+
export type { AnthropicConfig, GitHubAppConfig, GitHubConfig, WorktreeConfig, WorkflowConfig, BacklogManagementConfig, FaberConfig, UnifiedConfig, ConfigLoadOptions, } from '../types/config.js';
|
|
8
|
+
import type { UnifiedConfig, ConfigLoadOptions } from '../types/config.js';
|
|
9
|
+
/**
|
|
10
|
+
* Load and parse `.fractary/config.yaml` with environment variable substitution
|
|
11
|
+
*
|
|
12
|
+
* @param options Configuration loading options
|
|
13
|
+
* @returns Parsed configuration object or null if not found
|
|
14
|
+
* @throws Error if config is invalid or throwIfMissing is true and file doesn't exist
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const config = loadYamlConfig();
|
|
19
|
+
* if (config?.github) {
|
|
20
|
+
* console.log('GitHub config:', config.github);
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadYamlConfig(options?: ConfigLoadOptions): UnifiedConfig | null;
|
|
25
|
+
/**
|
|
26
|
+
* Write unified configuration to `.fractary/config.yaml`
|
|
27
|
+
*
|
|
28
|
+
* @param config Configuration object to write
|
|
29
|
+
* @param projectRoot Project root directory (auto-detected if not provided)
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* writeYamlConfig({
|
|
34
|
+
* version: '2.0',
|
|
35
|
+
* github: {
|
|
36
|
+
* organization: 'myorg',
|
|
37
|
+
* project: 'myrepo'
|
|
38
|
+
* }
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function writeYamlConfig(config: UnifiedConfig, projectRoot?: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* Substitute ${ENV_VAR} placeholders with actual environment variables
|
|
45
|
+
*
|
|
46
|
+
* Supports:
|
|
47
|
+
* - ${VAR_NAME} - Replace with env var value
|
|
48
|
+
* - ${VAR_NAME:-default} - Replace with env var value or default if not set
|
|
49
|
+
*
|
|
50
|
+
* Security: Default values are limited to 1000 characters to prevent abuse.
|
|
51
|
+
* Variable names must match pattern: [A-Z_][A-Z0-9_]*
|
|
52
|
+
*
|
|
53
|
+
* @param content Content with environment variable placeholders
|
|
54
|
+
* @param warnMissing Whether to warn about missing environment variables
|
|
55
|
+
* @returns Content with substituted values
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const content = 'token: ${GITHUB_TOKEN}';
|
|
60
|
+
* const result = substituteEnvVars(content);
|
|
61
|
+
* // result: 'token: ghp_xxxxx'
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function substituteEnvVars(content: string, warnMissing?: boolean): string;
|
|
65
|
+
/**
|
|
66
|
+
* Find project root by looking for .fractary directory or .git
|
|
67
|
+
*
|
|
68
|
+
* Walks up the directory tree from startDir until it finds:
|
|
69
|
+
* - A directory containing `.fractary/`
|
|
70
|
+
* - A directory containing `.git/`
|
|
71
|
+
* - The filesystem root
|
|
72
|
+
*
|
|
73
|
+
* Security: Normalizes paths and prevents traversal outside filesystem boundaries.
|
|
74
|
+
* Maximum of 100 directory levels to prevent infinite loops.
|
|
75
|
+
*
|
|
76
|
+
* @param startDir Directory to start searching from (default: current working directory)
|
|
77
|
+
* @returns Project root directory (normalized absolute path)
|
|
78
|
+
*/
|
|
79
|
+
export declare function findProjectRoot(startDir?: string): string;
|
|
80
|
+
/**
|
|
81
|
+
* Check if a valid configuration file exists
|
|
82
|
+
*
|
|
83
|
+
* @param projectRoot Project root directory (auto-detected if not provided)
|
|
84
|
+
* @returns true if config exists at .fractary/config.yaml
|
|
85
|
+
*/
|
|
86
|
+
export declare function configExists(projectRoot?: string): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Get the configuration file path
|
|
89
|
+
*
|
|
90
|
+
* @param projectRoot Project root directory (auto-detected if not provided)
|
|
91
|
+
* @returns Full path to configuration file
|
|
92
|
+
*/
|
|
93
|
+
export declare function getConfigPath(projectRoot?: string): string;
|
|
94
|
+
/**
|
|
95
|
+
* Check if old settings.json exists (for migration)
|
|
96
|
+
*
|
|
97
|
+
* @param projectRoot Project root directory (auto-detected if not provided)
|
|
98
|
+
* @returns true if old settings.json exists
|
|
99
|
+
*/
|
|
100
|
+
export declare function oldSettingsExists(projectRoot?: string): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Get the old settings.json file path
|
|
103
|
+
*
|
|
104
|
+
* @param projectRoot Project root directory (auto-detected if not provided)
|
|
105
|
+
* @returns Full path to old settings.json file
|
|
106
|
+
*/
|
|
107
|
+
export declare function getOldSettingsPath(projectRoot?: string): string;
|
|
108
|
+
//# sourceMappingURL=yaml-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml-config.d.ts","sourceRoot":"","sources":["../../src/lib/yaml-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,YAAY,EACV,eAAe,EACf,eAAe,EACf,YAAY,EACZ,cAAc,EACd,cAAc,EACd,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AA8F3E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,iBAAsB,GAAG,aAAa,GAAG,IAAI,CAoDpF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAkBN;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,UAAO,GAAG,MAAM,CAgD7E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAoDxE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAI1D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAI/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAG/D"}
|