archbyte 0.3.5 → 0.4.1
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 +42 -0
- package/bin/archbyte.js +26 -25
- package/dist/agents/pipeline/merger.d.ts +2 -2
- package/dist/agents/pipeline/merger.js +165 -35
- package/dist/agents/pipeline/types.d.ts +29 -1
- package/dist/agents/pipeline/types.js +0 -1
- package/dist/agents/providers/claude-sdk.d.ts +7 -0
- package/dist/agents/providers/claude-sdk.js +83 -0
- package/dist/agents/providers/router.d.ts +5 -0
- package/dist/agents/providers/router.js +23 -1
- package/dist/agents/runtime/types.d.ts +6 -2
- package/dist/agents/runtime/types.js +6 -1
- package/dist/agents/static/component-detector.js +35 -3
- package/dist/agents/static/connection-mapper.d.ts +1 -1
- package/dist/agents/static/connection-mapper.js +74 -1
- package/dist/agents/static/index.js +5 -2
- package/dist/agents/static/types.d.ts +26 -0
- package/dist/cli/analyze.js +65 -18
- package/dist/cli/arch-diff.d.ts +38 -0
- package/dist/cli/arch-diff.js +61 -0
- package/dist/cli/auth.d.ts +8 -2
- package/dist/cli/auth.js +241 -31
- package/dist/cli/config.js +31 -5
- package/dist/cli/export.js +64 -2
- package/dist/cli/patrol.d.ts +5 -3
- package/dist/cli/patrol.js +417 -65
- package/dist/cli/setup.js +76 -8
- package/dist/cli/shared.d.ts +11 -0
- package/dist/cli/shared.js +61 -0
- package/dist/cli/ui.d.ts +9 -0
- package/dist/cli/ui.js +59 -5
- package/dist/cli/validate.d.ts +0 -1
- package/dist/cli/validate.js +0 -16
- package/dist/server/src/index.js +593 -19
- package/package.json +4 -1
- package/templates/archbyte.yaml +8 -0
- package/ui/dist/assets/index-DDCNauh7.css +1 -0
- package/ui/dist/assets/index-DO4t5Xu1.js +72 -0
- package/ui/dist/index.html +2 -2
- package/dist/cli/mcp-server.d.ts +0 -1
- package/dist/cli/mcp-server.js +0 -443
- package/dist/cli/mcp.d.ts +0 -1
- package/dist/cli/mcp.js +0 -98
- package/ui/dist/assets/index-0_XpUUZQ.css +0 -1
- package/ui/dist/assets/index-BTo0zV5E.js +0 -70
package/dist/cli/setup.js
CHANGED
|
@@ -15,6 +15,12 @@ const PROVIDERS = [
|
|
|
15
15
|
{ name: "google", label: "Google", hint: "Gemini 2.5 Pro / Flash" },
|
|
16
16
|
];
|
|
17
17
|
const PROVIDER_MODELS = {
|
|
18
|
+
"claude-sdk": [
|
|
19
|
+
{ id: "", label: "Default (recommended)", hint: "Sonnet for all agents" },
|
|
20
|
+
{ id: "opus", label: "Claude Opus 4.6", hint: "Most capable" },
|
|
21
|
+
{ id: "sonnet", label: "Claude Sonnet 4.5", hint: "Fast, great quality" },
|
|
22
|
+
{ id: "haiku", label: "Claude Haiku 4.5", hint: "Fastest, cheapest" },
|
|
23
|
+
],
|
|
18
24
|
anthropic: [
|
|
19
25
|
{ id: "", label: "Default (recommended)", hint: "Opus for all agents" },
|
|
20
26
|
{ id: "claude-opus-4-6", label: "Claude Opus 4.6", hint: "Most capable" },
|
|
@@ -205,16 +211,10 @@ export async function handleSetup() {
|
|
|
205
211
|
console.log();
|
|
206
212
|
console.log(chalk.bold.cyan("ArchByte Setup"));
|
|
207
213
|
console.log(chalk.gray("Configure your model provider and API key.\n"));
|
|
208
|
-
// Detect AI coding tools
|
|
214
|
+
// Detect AI coding tools
|
|
209
215
|
const hasClaude = isInPath("claude");
|
|
210
216
|
const codexDir = path.join(CONFIG_DIR, "../.codex");
|
|
211
217
|
const hasCodex = fs.existsSync(codexDir);
|
|
212
|
-
if (hasClaude || hasCodex) {
|
|
213
|
-
const tools = [hasClaude && "Claude Code", hasCodex && "Codex CLI"].filter(Boolean).join(" and ");
|
|
214
|
-
console.log(chalk.cyan(` Detected ${tools} on this machine.`));
|
|
215
|
-
console.log(chalk.white(` After setup, run `) + chalk.bold.cyan(`archbyte mcp install`) + chalk.white(` to use ArchByte from your AI tool.`));
|
|
216
|
-
console.log();
|
|
217
|
-
}
|
|
218
218
|
const config = loadConfig();
|
|
219
219
|
const profiles = getProfiles(config);
|
|
220
220
|
// Migrate legacy flat config → profiles
|
|
@@ -247,6 +247,75 @@ export async function handleSetup() {
|
|
|
247
247
|
}
|
|
248
248
|
console.log();
|
|
249
249
|
}
|
|
250
|
+
// Detect AI coding tools and offer zero-config options
|
|
251
|
+
if (hasClaude || hasCodex) {
|
|
252
|
+
const tools = [hasClaude && "Claude Code", hasCodex && "Codex CLI"].filter(Boolean).join(" and ");
|
|
253
|
+
console.log(chalk.cyan(` Detected ${tools} on this machine.\n`));
|
|
254
|
+
// Build options based on what's detected
|
|
255
|
+
const toolOptions = [];
|
|
256
|
+
if (hasClaude) {
|
|
257
|
+
toolOptions.push({
|
|
258
|
+
label: `Claude Code (SDK) ${chalk.gray("zero config — uses your Claude Code subscription")}`,
|
|
259
|
+
value: "claude-sdk",
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
if (hasCodex) {
|
|
263
|
+
toolOptions.push({
|
|
264
|
+
label: `Codex CLI ${chalk.gray("zero config — uses your Codex subscription")}`,
|
|
265
|
+
value: "codex",
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
toolOptions.push({
|
|
269
|
+
label: `Bring your own API key ${chalk.gray("Anthropic, OpenAI, or Google")}`,
|
|
270
|
+
value: "byok",
|
|
271
|
+
});
|
|
272
|
+
const toolIdx = await select("How do you want to run ArchByte?", toolOptions.map((o) => o.label));
|
|
273
|
+
const choice = toolOptions[toolIdx].value;
|
|
274
|
+
if (choice === "claude-sdk") {
|
|
275
|
+
config.provider = "claude-sdk";
|
|
276
|
+
// Model selection
|
|
277
|
+
const models = PROVIDER_MODELS["claude-sdk"];
|
|
278
|
+
const modelIdx = await select("\n Choose a model:", models.map((m) => `${m.label} ${chalk.gray(m.hint)}`));
|
|
279
|
+
const chosenModel = models[modelIdx];
|
|
280
|
+
if (chosenModel.id) {
|
|
281
|
+
config.model = chosenModel.id;
|
|
282
|
+
console.log(chalk.green(` ✓ Model: ${chosenModel.label}`));
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
delete config.model;
|
|
286
|
+
console.log(chalk.green(` ✓ Model: Sonnet (default)`));
|
|
287
|
+
}
|
|
288
|
+
config.profiles = profiles;
|
|
289
|
+
delete config.apiKey;
|
|
290
|
+
saveConfig(config);
|
|
291
|
+
const dim = chalk.gray;
|
|
292
|
+
const sep = dim(" ───");
|
|
293
|
+
console.log();
|
|
294
|
+
console.log(chalk.bold.green(" ✓ Setup complete — using Claude Code (SDK)"));
|
|
295
|
+
console.log();
|
|
296
|
+
console.log(sep);
|
|
297
|
+
console.log();
|
|
298
|
+
console.log(dim(" No API key needed. ArchByte uses your Claude Code subscription."));
|
|
299
|
+
console.log(dim(" All model calls go through Claude Code on this machine."));
|
|
300
|
+
console.log();
|
|
301
|
+
console.log(sep);
|
|
302
|
+
console.log();
|
|
303
|
+
console.log(" " + chalk.bold("Next steps"));
|
|
304
|
+
console.log();
|
|
305
|
+
console.log(" " + chalk.cyan("archbyte run") + " Analyze your codebase");
|
|
306
|
+
console.log(" " + chalk.cyan("archbyte status") + " Check account and usage");
|
|
307
|
+
console.log(" " + chalk.cyan("archbyte --help") + " See all commands");
|
|
308
|
+
console.log();
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (choice === "codex") {
|
|
312
|
+
// TODO: Add Codex SDK provider when available
|
|
313
|
+
console.log(chalk.yellow("\n Codex SDK provider coming soon. Setting up with API key for now.\n"));
|
|
314
|
+
}
|
|
315
|
+
// User chose BYOK — continue to normal provider selection below
|
|
316
|
+
if (choice === "byok")
|
|
317
|
+
console.log();
|
|
318
|
+
}
|
|
250
319
|
// Step 1: Choose provider
|
|
251
320
|
const idx = await select("Choose your model provider:", PROVIDERS.map((p) => {
|
|
252
321
|
const active = config.provider === p.name ? chalk.green(" (active)") : "";
|
|
@@ -523,7 +592,6 @@ export async function handleSetup() {
|
|
|
523
592
|
console.log();
|
|
524
593
|
console.log(" " + chalk.cyan("archbyte run") + " Analyze your codebase");
|
|
525
594
|
if (hasClaude || hasCodex) {
|
|
526
|
-
console.log(" " + chalk.cyan("archbyte mcp install") + " Use from your AI tool");
|
|
527
595
|
}
|
|
528
596
|
console.log(" " + chalk.cyan("archbyte status") + " Check account and usage");
|
|
529
597
|
console.log(" " + chalk.cyan("archbyte --help") + " See all commands");
|
package/dist/cli/shared.d.ts
CHANGED
|
@@ -64,5 +64,16 @@ export declare function parseRulesFromYaml(content: string): RuleConfig;
|
|
|
64
64
|
* level: error
|
|
65
65
|
*/
|
|
66
66
|
export declare function parseCustomRulesFromYaml(content: string): CustomRule[];
|
|
67
|
+
/**
|
|
68
|
+
* Parse the patrol.ignore list from archbyte.yaml.
|
|
69
|
+
* Returns user-defined glob patterns for watch mode to ignore.
|
|
70
|
+
*
|
|
71
|
+
* patrol:
|
|
72
|
+
* ignore:
|
|
73
|
+
* - "docs/"
|
|
74
|
+
* - "*.md"
|
|
75
|
+
* - "build/"
|
|
76
|
+
*/
|
|
77
|
+
export declare function loadPatrolIgnore(configPath?: string): string[];
|
|
67
78
|
export declare function getRuleLevel(config: RuleConfig, rule: keyof RuleConfig, defaultLevel: RuleLevel): RuleLevel;
|
|
68
79
|
export declare function getThreshold(config: RuleConfig, rule: "max-connections", defaultVal: number): number;
|
package/dist/cli/shared.js
CHANGED
|
@@ -259,6 +259,67 @@ export function parseCustomRulesFromYaml(content) {
|
|
|
259
259
|
flushItem();
|
|
260
260
|
return rules;
|
|
261
261
|
}
|
|
262
|
+
/**
|
|
263
|
+
* Parse the patrol.ignore list from archbyte.yaml.
|
|
264
|
+
* Returns user-defined glob patterns for watch mode to ignore.
|
|
265
|
+
*
|
|
266
|
+
* patrol:
|
|
267
|
+
* ignore:
|
|
268
|
+
* - "docs/"
|
|
269
|
+
* - "*.md"
|
|
270
|
+
* - "build/"
|
|
271
|
+
*/
|
|
272
|
+
export function loadPatrolIgnore(configPath) {
|
|
273
|
+
const rootDir = process.cwd();
|
|
274
|
+
const yamlPath = configPath
|
|
275
|
+
? path.resolve(rootDir, configPath)
|
|
276
|
+
: path.join(rootDir, ".archbyte", "archbyte.yaml");
|
|
277
|
+
if (!fs.existsSync(yamlPath))
|
|
278
|
+
return [];
|
|
279
|
+
try {
|
|
280
|
+
const lines = fs.readFileSync(yamlPath, "utf-8").split("\n");
|
|
281
|
+
const patterns = [];
|
|
282
|
+
let inPatrol = false;
|
|
283
|
+
let inIgnore = false;
|
|
284
|
+
for (const line of lines) {
|
|
285
|
+
const trimmed = line.trimEnd();
|
|
286
|
+
if (/^patrol:\s*$/.test(trimmed)) {
|
|
287
|
+
inPatrol = true;
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
// Another top-level section ends patrol
|
|
291
|
+
if (inPatrol && /^\S/.test(trimmed) && !trimmed.startsWith("#")) {
|
|
292
|
+
inPatrol = false;
|
|
293
|
+
inIgnore = false;
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
if (!inPatrol)
|
|
297
|
+
continue;
|
|
298
|
+
if (trimmed === "" || trimmed.trim().startsWith("#"))
|
|
299
|
+
continue;
|
|
300
|
+
if (/^ {2}ignore:\s*$/.test(trimmed)) {
|
|
301
|
+
inIgnore = true;
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
// Another patrol sub-key ends ignore
|
|
305
|
+
if (inIgnore && /^ {2}\S/.test(trimmed) && !/^ {2}ignore:/.test(trimmed)) {
|
|
306
|
+
inIgnore = false;
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
if (!inIgnore)
|
|
310
|
+
continue;
|
|
311
|
+
// List item: " - pattern"
|
|
312
|
+
const itemMatch = trimmed.match(/^ {4}-\s+"?([^"]+)"?\s*$/);
|
|
313
|
+
if (itemMatch) {
|
|
314
|
+
patterns.push(itemMatch[1].trim());
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return patterns;
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
return [];
|
|
321
|
+
}
|
|
322
|
+
}
|
|
262
323
|
export function getRuleLevel(config, rule, defaultLevel) {
|
|
263
324
|
const entry = config[rule];
|
|
264
325
|
if (!entry)
|
package/dist/cli/ui.d.ts
CHANGED
|
@@ -30,4 +30,13 @@ export declare function progressBar(totalSteps: number): ProgressBar;
|
|
|
30
30
|
* (arrow keys, etc.) to prevent accidental confirmation.
|
|
31
31
|
*/
|
|
32
32
|
export declare function confirm(prompt: string): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Text input prompt. Returns the entered string.
|
|
35
|
+
* Non-TTY fallback: returns empty string.
|
|
36
|
+
*
|
|
37
|
+
* @param mask - If true, replaces each character with * (for passwords).
|
|
38
|
+
*/
|
|
39
|
+
export declare function textInput(prompt: string, opts?: {
|
|
40
|
+
mask?: boolean;
|
|
41
|
+
}): Promise<string>;
|
|
33
42
|
export {};
|
package/dist/cli/ui.js
CHANGED
|
@@ -111,13 +111,12 @@ export function select(prompt, options) {
|
|
|
111
111
|
cleanup();
|
|
112
112
|
resolve(selected);
|
|
113
113
|
}
|
|
114
|
-
else if (data === "\x03") {
|
|
115
|
-
// Ctrl+C
|
|
114
|
+
else if (data === "\x03" || data === "q") {
|
|
115
|
+
// Ctrl+C or q — clean exit
|
|
116
116
|
cleanup();
|
|
117
117
|
process.stdout.write("\n");
|
|
118
118
|
process.exit(0);
|
|
119
119
|
}
|
|
120
|
-
// All other keys (including q, arrows, etc.) are ignored
|
|
121
120
|
};
|
|
122
121
|
function cleanup() {
|
|
123
122
|
stdin.removeListener("data", onData);
|
|
@@ -202,8 +201,8 @@ export function confirm(prompt) {
|
|
|
202
201
|
process.stdout.write("n\n");
|
|
203
202
|
resolve(false);
|
|
204
203
|
}
|
|
205
|
-
else if (data === "\x03") {
|
|
206
|
-
// Ctrl+C
|
|
204
|
+
else if (data === "\x03" || data === "q") {
|
|
205
|
+
// Ctrl+C or q — clean exit
|
|
207
206
|
process.stdout.write("\n");
|
|
208
207
|
process.exit(0);
|
|
209
208
|
}
|
|
@@ -216,3 +215,58 @@ export function confirm(prompt) {
|
|
|
216
215
|
stdin.on("data", onData);
|
|
217
216
|
});
|
|
218
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Text input prompt. Returns the entered string.
|
|
220
|
+
* Non-TTY fallback: returns empty string.
|
|
221
|
+
*
|
|
222
|
+
* @param mask - If true, replaces each character with * (for passwords).
|
|
223
|
+
*/
|
|
224
|
+
export function textInput(prompt, opts) {
|
|
225
|
+
if (!process.stdout.isTTY) {
|
|
226
|
+
console.log(` ${prompt}: `);
|
|
227
|
+
return Promise.resolve("");
|
|
228
|
+
}
|
|
229
|
+
return new Promise((resolve) => {
|
|
230
|
+
process.stdout.write(` ${prompt}: `);
|
|
231
|
+
const stdin = process.stdin;
|
|
232
|
+
const wasRaw = stdin.isRaw;
|
|
233
|
+
stdin.setRawMode(true);
|
|
234
|
+
stdin.resume();
|
|
235
|
+
stdin.setEncoding("utf8");
|
|
236
|
+
let value = "";
|
|
237
|
+
const onData = (data) => {
|
|
238
|
+
if (data === "\r" || data === "\n") {
|
|
239
|
+
// Enter — submit
|
|
240
|
+
stdin.removeListener("data", onData);
|
|
241
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
242
|
+
stdin.pause();
|
|
243
|
+
process.stdout.write("\n");
|
|
244
|
+
resolve(value);
|
|
245
|
+
}
|
|
246
|
+
else if (data === "\x03") {
|
|
247
|
+
// Ctrl+C
|
|
248
|
+
stdin.removeListener("data", onData);
|
|
249
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
250
|
+
stdin.pause();
|
|
251
|
+
process.stdout.write("\n");
|
|
252
|
+
process.exit(0);
|
|
253
|
+
}
|
|
254
|
+
else if (data === "\x7f" || data === "\b") {
|
|
255
|
+
// Backspace
|
|
256
|
+
if (value.length > 0) {
|
|
257
|
+
value = value.slice(0, -1);
|
|
258
|
+
process.stdout.write("\b \b");
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else if (data.startsWith("\x1b")) {
|
|
262
|
+
// Ignore escape sequences
|
|
263
|
+
}
|
|
264
|
+
else if (data >= " ") {
|
|
265
|
+
// Printable character
|
|
266
|
+
value += data;
|
|
267
|
+
process.stdout.write(opts?.mask ? "*" : data);
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
stdin.on("data", onData);
|
|
271
|
+
});
|
|
272
|
+
}
|
package/dist/cli/validate.d.ts
CHANGED
package/dist/cli/validate.js
CHANGED
|
@@ -202,22 +202,6 @@ export async function handleValidate(options) {
|
|
|
202
202
|
}
|
|
203
203
|
// Human-readable output
|
|
204
204
|
printValidationReport(result);
|
|
205
|
-
// Watch mode: re-validate on file changes
|
|
206
|
-
if (options.watch) {
|
|
207
|
-
const chokidar = await import("chokidar");
|
|
208
|
-
const diagramPath = resolveArchitecturePath(options);
|
|
209
|
-
console.log(chalk.gray(` Watching ${diagramPath} for changes...`));
|
|
210
|
-
console.log(chalk.gray(" Press Ctrl+C to stop."));
|
|
211
|
-
const watcher = chokidar.watch(diagramPath, { ignoreInitial: true });
|
|
212
|
-
watcher.on("change", () => {
|
|
213
|
-
console.clear();
|
|
214
|
-
const watchResult = runValidation(options);
|
|
215
|
-
printValidationReport(watchResult);
|
|
216
|
-
console.log(chalk.gray(` Watching ${diagramPath} for changes...`));
|
|
217
|
-
console.log(chalk.gray(" Press Ctrl+C to stop."));
|
|
218
|
-
});
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
205
|
if (result.errors > 0) {
|
|
222
206
|
process.exit(1);
|
|
223
207
|
}
|