archbyte 0.2.1 → 0.2.3
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/bin/archbyte.js +30 -7
- package/dist/agents/llm/index.js +1 -1
- package/dist/agents/pipeline/index.js +1 -1
- package/dist/agents/prompt-data.js +4 -4
- package/dist/agents/providers/ollama.js +2 -2
- package/dist/agents/providers/router.js +1 -16
- package/dist/agents/runtime/orchestrator.js +1 -1
- package/dist/agents/runtime/types.d.ts +7 -2
- package/dist/agents/runtime/types.js +9 -7
- package/dist/agents/static/code-sampler.js +1 -4
- package/dist/agents/static/component-detector.js +1 -4
- package/dist/agents/static/event-detector.js +2 -1
- package/dist/agents/static/excluded-dirs.d.ts +3 -0
- package/dist/agents/static/excluded-dirs.js +11 -0
- package/dist/agents/static/file-tree-collector.js +1 -5
- package/dist/agents/tools/claude-code.js +2 -5
- package/dist/agents/tools/local-fs.js +2 -6
- package/dist/cli/analyze.d.ts +2 -1
- package/dist/cli/analyze.js +48 -22
- package/dist/cli/auth.js +2 -5
- package/dist/cli/config.d.ts +1 -0
- package/dist/cli/config.js +84 -42
- package/dist/cli/constants.d.ts +13 -0
- package/dist/cli/constants.js +20 -0
- package/dist/cli/gate.js +3 -3
- package/dist/cli/generate.js +5 -2
- package/dist/cli/license-gate.js +3 -3
- package/dist/cli/run.d.ts +2 -0
- package/dist/cli/run.js +4 -7
- package/dist/cli/serve.js +3 -2
- package/dist/cli/setup.js +116 -69
- package/dist/cli/ui.d.ts +10 -0
- package/dist/cli/ui.js +44 -0
- package/dist/cli/version.d.ts +2 -0
- package/dist/cli/version.js +84 -0
- package/dist/server/src/index.js +40 -0
- package/package.json +1 -1
- package/ui/dist/assets/{index-Bl1r8zrI.css → index-0_XpUUZQ.css} +1 -1
- package/ui/dist/assets/index-BdfGbhpp.js +70 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-CqbB6DOK.js +0 -70
package/bin/archbyte.js
CHANGED
|
@@ -6,6 +6,7 @@ if (major < 18) {
|
|
|
6
6
|
process.exit(1);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
import { createRequire } from 'module';
|
|
9
10
|
import { Command } from 'commander';
|
|
10
11
|
import { handleServe } from '../dist/cli/serve.js';
|
|
11
12
|
import { handleGenerate } from '../dist/cli/generate.js';
|
|
@@ -20,14 +21,19 @@ import { handleConfig } from '../dist/cli/config.js';
|
|
|
20
21
|
import { handleLogin, handleLoginWithToken, handleLogout, handleStatus } from '../dist/cli/auth.js';
|
|
21
22
|
import { handleRun } from '../dist/cli/run.js';
|
|
22
23
|
import { handleSetup } from '../dist/cli/setup.js';
|
|
24
|
+
import { handleVersion, handleUpdate } from '../dist/cli/version.js';
|
|
23
25
|
import { requireLicense } from '../dist/cli/license-gate.js';
|
|
26
|
+
import { DEFAULT_PORT } from '../dist/cli/constants.js';
|
|
27
|
+
|
|
28
|
+
const require = createRequire(import.meta.url);
|
|
29
|
+
const { version: PKG_VERSION } = require('../package.json');
|
|
24
30
|
|
|
25
31
|
const program = new Command();
|
|
26
32
|
|
|
27
33
|
program
|
|
28
34
|
.name('archbyte')
|
|
29
35
|
.description('ArchByte - See what agents build. As they build it.')
|
|
30
|
-
.version(
|
|
36
|
+
.version(PKG_VERSION)
|
|
31
37
|
.addHelpText('after', `
|
|
32
38
|
Quick start:
|
|
33
39
|
$ archbyte login Sign in
|
|
@@ -73,12 +79,14 @@ program
|
|
|
73
79
|
program
|
|
74
80
|
.command('run')
|
|
75
81
|
.description('Analyze, generate, and serve - full pipeline in one shot')
|
|
82
|
+
.option('-d, --dir <path>', 'Project root directory (default: current directory)')
|
|
76
83
|
.option('--static', 'Static-only analysis (no model, free)')
|
|
77
84
|
.option('--skip-llm', 'Alias for --static')
|
|
78
|
-
.option('--provider <name>', 'Model provider: anthropic, openai, google
|
|
85
|
+
.option('--provider <name>', 'Model provider: anthropic, openai, google')
|
|
79
86
|
.option('--api-key <key>', 'Model API key (overrides config)')
|
|
80
|
-
.option('-p, --port <number>',
|
|
87
|
+
.option('-p, --port <number>', `UI server port (default: ${DEFAULT_PORT})`, parseInt)
|
|
81
88
|
.option('-v, --verbose', 'Show detailed output')
|
|
89
|
+
.option('--force', 'Force full re-scan (skip incremental detection)')
|
|
82
90
|
.option('--dry-run', 'Preview without running')
|
|
83
91
|
.action(async (options) => {
|
|
84
92
|
await requireLicense('analyze');
|
|
@@ -88,13 +96,14 @@ program
|
|
|
88
96
|
program
|
|
89
97
|
.command('analyze')
|
|
90
98
|
.description('Run AI-powered architecture analysis (BYOK - uses your model API key)')
|
|
99
|
+
.option('-d, --dir <path>', 'Project root directory (default: current directory)')
|
|
91
100
|
.option('-o, --output <path>', 'Output analysis path (default: .archbyte/analysis.json)')
|
|
92
101
|
.option('-v, --verbose', 'Show detailed output')
|
|
93
|
-
.option('--provider <name>', 'Model provider: anthropic, openai, google
|
|
102
|
+
.option('--provider <name>', 'Model provider: anthropic, openai, google')
|
|
94
103
|
.option('--api-key <key>', 'Model API key (overrides config)')
|
|
95
104
|
.option('--static', 'Static-only analysis (no model, free)')
|
|
96
105
|
.option('--skip-llm', 'Alias for --static')
|
|
97
|
-
.option('--
|
|
106
|
+
.option('--force', 'Force full re-scan (skip incremental detection)')
|
|
98
107
|
.option('--dry-run', 'Preview without running')
|
|
99
108
|
.action(async (options) => {
|
|
100
109
|
await requireLicense('analyze');
|
|
@@ -115,7 +124,7 @@ program
|
|
|
115
124
|
program
|
|
116
125
|
.command('serve')
|
|
117
126
|
.description('Start the visualization UI server')
|
|
118
|
-
.option('-p, --port <number>',
|
|
127
|
+
.option('-p, --port <number>', `Server port (default: ${DEFAULT_PORT})`, parseInt)
|
|
119
128
|
.option('-d, --diagram <path>', 'Path to architecture JSON (default: .archbyte/architecture.json)')
|
|
120
129
|
.action(async (options) => {
|
|
121
130
|
await handleServe(options);
|
|
@@ -207,12 +216,26 @@ program
|
|
|
207
216
|
.command('config')
|
|
208
217
|
.description('Manage ArchByte configuration (provider, API key)')
|
|
209
218
|
.argument('[action]', 'show, set, get, or path')
|
|
210
|
-
.argument('[key]', 'config key (provider, api-key,
|
|
219
|
+
.argument('[key]', 'config key (provider, api-key, model)')
|
|
211
220
|
.argument('[value]', 'config value')
|
|
212
221
|
.action(async (action, key, value) => {
|
|
213
222
|
await handleConfig({ args: [action, key, value].filter(Boolean) });
|
|
214
223
|
});
|
|
215
224
|
|
|
225
|
+
program
|
|
226
|
+
.command('version')
|
|
227
|
+
.description('Show ArchByte version and environment info')
|
|
228
|
+
.action(async () => {
|
|
229
|
+
await handleVersion();
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
program
|
|
233
|
+
.command('update')
|
|
234
|
+
.description('Update ArchByte to the latest version')
|
|
235
|
+
.action(async () => {
|
|
236
|
+
await handleUpdate();
|
|
237
|
+
});
|
|
238
|
+
|
|
216
239
|
// Default: show help
|
|
217
240
|
program
|
|
218
241
|
.action(() => {
|
package/dist/agents/llm/index.js
CHANGED
|
@@ -15,7 +15,7 @@ export async function enhanceWithLLM(analysis, provider, config, projectRoot, on
|
|
|
15
15
|
if (analysis.gaps.length > 0) {
|
|
16
16
|
onProgress?.(`Including ${analysis.gaps.length} gap(s) for LLM resolution`);
|
|
17
17
|
}
|
|
18
|
-
const model = resolveModel(config.provider, "standard", config.modelOverrides);
|
|
18
|
+
const model = resolveModel(config.provider, "standard", config.modelOverrides, config.model);
|
|
19
19
|
onProgress?.(`Calling ${model} for enhancement...`);
|
|
20
20
|
const response = await provider.chat({
|
|
21
21
|
model,
|
|
@@ -100,7 +100,7 @@ const MAX_TOKENS = {
|
|
|
100
100
|
};
|
|
101
101
|
async function runAgent(agent, ctx, provider, config, priorResults, onProgress) {
|
|
102
102
|
const start = Date.now();
|
|
103
|
-
const model = resolveModel(config.provider, agent.modelTier, config.modelOverrides);
|
|
103
|
+
const model = resolveModel(config.provider, agent.modelTier, config.modelOverrides, config.model);
|
|
104
104
|
const { system, user } = agent.buildPrompt(ctx, priorResults);
|
|
105
105
|
onProgress?.(` ${agent.name}: calling ${model}...`);
|
|
106
106
|
const maxTokens = MAX_TOKENS[agent.id] ?? 4096;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Auto-generated by prompts-encode.ts — DO NOT EDIT
|
|
2
2
|
// Run: node agents/prompts-encode.ts
|
|
3
3
|
import { registerPrompt } from "./prompts.js";
|
|
4
|
-
registerPrompt("pipeline/component-identifier", "
|
|
5
|
-
registerPrompt("pipeline/connection-mapper", "GB0WSCMLEUUgHEMNOgkRFzVSEAckDQMEMxdDCTAaHAw1FwAcbFktCjQAQwItG1QMMlIXB2IUFRVhMy8kYhobCy8XABwrFhoWYRAGHDUcEQthEQwFMhYaAC8GEEgrF1QEYQEMDjYOFRckUhARMQ0RCG94aSstFxoAIgYKByxZABwxFxBSSFRURygfEwcwDVZfYRYKGicaAEUiHQcNYhAZFS4AF0cmHAQALxYGBiEAfkhhUAscNglWX2EgJjsWVhM3ETFMIBYtJEUiEw8EMXNZRWMWAhwjGxUWJFBZSCEWGRUuHAYGNlkGACAWEEc1Cx0RJAFDHC1ZFUUlExcJIBgHAEtfQ0onDxELNVBZSCMKDQsiUgYeJxcASiwXEBsjHhFFaQIWCm0KAQdtUhIdJwwRFmh4TkhgHgYVIlBZSCUrJCZhEQIELgp+SGFQFA0gChsGKhcXSnhZIwAjIQwLKRwARSIdDQYnGgAMLhwQYm9ZVgMoHgZKeFkHDSAABgxiHx0JJAEaGzYcGUUgEQANMQp+bwcdEUgnGBcNYREMBiwcFxEoHQ1SSFRUAzMdDlJiChsQMxEGSCEWGRUuHAYGNlk9IWFaDh0xDVQIIAYAAGIYGkUkCgobNhAaAmERDAUyFhoALwZDIQZZER0gERcEO1B+SGEGDFJiDRUXJhcXSCEWGRUuHAYGNlk9IWFaDh0xDVQIIAYAAGIYGkUkCgobNhAaAmERDAUyFhoALwZDIQZZER0gERcEO1B+
|
|
4
|
+
registerPrompt("pipeline/component-identifier", "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");
|
|
5
|
+
registerPrompt("pipeline/connection-mapper", "GB0WSCMLEUUgHEMNOgkRFzVSEAckDQMEMxdDCTAaHAw1FwAcbFktCjQAQwItG1QMMlIXB2IUFRVhMy8kYhobCy8XABwrFhoWYRAGHDUcEQthEQwFMhYaAC8GEEgrF1QEYQEMDjYOFRckUhARMQ0RCG94aSstFxoAIgYKByxZABwxFxBSSFRURygfEwcwDVZfYRYKGicaAEUiHQcNYhAZFS4AF0cmHAQALxYGBiEAfkhhUAscNglWX2EgJjsWVhM3ETFMIBYtJEUiEw8EMXNZRWMWAhwjGxUWJFBZSCEWGRUuHAYGNlkGACAWEEc1Cx0RJAFDHC1ZFUUlExcJIBgHAEtfQ0onDxELNVBZSCMKDQsiUgYeJxcASiwXEBsjHhFFaQIWCm0KAQdtUhIdJwwRFmh4TkhgHgYVIlBZSCUrJCZhEQIELgp+SGFQFA0gChsGKhcXSnhZIwAjIQwLKRwARSIdDQYnGgAMLhwQYm9ZVgMoHgZKeFkHDSAABgxiHx0JJAEaGzYcGUUgEQANMQp+bwcdEUgnGBcNYREMBiwcFxEoHQ1SSFRUAzMdDlJiChsQMxEGSCEWGRUuHAYGNlk9IWFaDh0xDVQIIAYAAGIYGkUkCgobNhAaAmERDAUyFhoALwZDIQZZER0gERcEO1B+SGEGDFJiDRUXJhcXSCEWGRUuHAYGNlk9IWFaDh0xDVQIIAYAAGIYGkUkCgobNhAaAmERDAUyFhoALwZDIQZZER0gERcEO1B+SGEGGhgnQ1QKLxdDByRZAA0kUhcRMhwHRSAQDB4nc1lFJRcQCzAQBBEoHQ1SYhsGDCQUQwwnChcXKAIXAS0XVAonUhcAJ1kGAC0TFwEtFwcNKAJpRWIYBxwvEVlINgsBAGEbBUgjCg0LIhoRBywWARZhWgYeJxcAFm1SEh0nDBEWaHhpKxAwICwCMy9SYjwCADMLQ0okCxsIY1ICBiZZVhEuUEMeIxUBAGE/NjsWWREdIBEXBDtZGQQ1EQtII1kXCiwCDAYnFwBFCDZDDjAWGUU1GgZIMgsbEygWBgxiGhsIMR0NDSwNVAkoARdGYj0bRQ89N0grFwIALwZDCy0UBAovFw0cYjAwFm9SJwdiNzsxYQAGDicLEQsiF0MMIw0VByABBhtiFgZFJAoXDTAXFQlhAQYaNBAXADJSFwAjDVQEMxdDBi0NVAwvUhcAJ1kXCiwCDAYnFwBFLRsQHGxZPQNhCwwdYhgGAGEHDRs3CxFFIBAMHTZZFUUiHQ0GJxoADC4cT0gtFB0RYRsXRkhzNQkyHUMBJhwaESgUGkhoUxIJLgUQQmhZluXVUgYGJlQACmwXDQxiCxEUNBcQHGIJFREpAUMcKgsbECYaQxwqHFQWOAEXDS9DfkhhHAIFJ0NUAy0dFEgsGBkAYVoGRiVXWEVjJxANMFkmACYbEBwwGAAMLhxBQUhUVAEkAQAaKwkADC4cWUg1ERURYRoCGDIcGhZLX0MLIw0RAi4AGlJiFhoAYR0FSGAMBwAzXwkHNwsaADhQT0hgHRURIF8TATIcGAwvF0FEYlsHHDIGBgVgVVRHJRcTBC0AGQAvBkFEYlsRFzMdEUUwHBcKNxcREWBzWUUyBgYYMUNUBDMAAhFiFhJFMgYRASweB0lhFwILKlkxPQAxNyQbWR0LYQYLDWIfGxcsExdIYBobCDEdDQ0sDT0BYZDl+mIaGwgxHQ0NLA09AWNSSw1sHlpJYVAUDSBUEhcuHBcNLB1Uh8fgQwkyEFkWJAAVDTBbXUthNwILKlkHESQCQwU3CgBFIh0NHCMQGkUkCgILNhUNRS4cBkig/+ZFIAARBzVZAww1GkMJYg8VCSgWQwstFAQKLxcNHGIwMEUuHEMNIxocRTIbBw1sWTAKYTwsPGIMBwBhFBENJ1QAADkGQwwnChcXKAIXAS0XB0UgAUMbNhwEFm94aS4uFgNFIhMXDSUWBgwkAVlib1lWEDIXEUUoFgEXLxcaSnhZARYkAE4OIxodCyZSBQQtDgdFLRsIDWIVGwIoHE9IMRATCzQCT0ghEREGKh0WHG5ZBwAgAAAASFRURyUTFwlvCR0VJB4KBidbTkUEJi9EYh0VESBSEBEsGlhFJAQGBjZZBBcuEQYbMRAaAm1SBwk2GFQRMxMNGyQWBgggBgoHLHNZRWMBGhs2HBlHe1ILDSMVAA1hEQsNIRIHSWEREQcsWR4KIwFPSCEYFw0kUhQJMBQdCyZeQwEsDREXLxMPSC8YHQs1Fw0JLBoRb2xSQQwnCRgKOB8GBjZbTkUCO0wrBlVUBzQbDwxiCR0VJB4KBicKWEUzFw8NIwoRRTEADAsnCgcAMnhOSGAcBhcuAE4aJxobEyQAGkp4WQYANQAaSC4WEwwiXkMOIxAYCjcXEURiHREEJVIPDTYNERdhAxYNNxwHSWERChohDB0RYRARDSMSERcyeGk6JwoECi8WQx8rDRxFDjwvMWIYVC8SPS1ILRseACIGWWI5c1RFYxEMBiwcFxEoHQ0bYENUPm9cTTVuc1RFYxQPBzUKVl9hKRhIYBcVCCRQWUhgV1pLY15DSiYcBwYzGxMcKxYaR3tSQUZsV1ZJYVAACTYcEwozC0FSYltaS29QT0hgCgAAMQFBUmIiWktvL0MV");
|
|
6
6
|
registerPrompt("pipeline/flow-detector", "GB0WSCMLEUUgHEMNOgkRFzVSEAckDQMEMxdDCTAaHAw1FwAcbFk1CyAeGhInWQANJFITGi0TEQY1UgAHLA0RHTVSAgYmWR0BJBwXASQATm9LQ01IaFMREyQcFystFxoAIgYKBywKXk97UiYeJxcASCUACh4nF1QGLh8OHSwQFwQ1GwwGYgkVETUXEQYxWVwIJAEQCSUcVBQ0FxYNMVVUFTQQTBs3G1hFNhcBAC0WHxZtUgYeJxcARSQfChw2HAYWaFxpSGJZMgozUgYJIRFORTpSEx0gFR0WKRcRRGIKAQcyEREBIBwGSWERCwksFxEJbVIXDSERGgotHQQRYgR+RWFSTkgyDBYJKAELDTBWBxAjAQAaKxsRF3tSAAcvCRsLJBwXSAs9B0VpGQYKIxtZBiABBkgxFQECMltpSGJZWUUiGgIGLBwYX2EXFQ0sDVsRLgIKC20IAQA0F0MGIxQRb2FSQ0ViDREGKRwMBC0eDV9hBgsNYgoEACIbBQEhWQAAIhoNBy4WExxhBxANJllcAG8VTURiWxETJBwXRScUHRE1FxFKbllWEiQQCwctElZMS3hRRmJTXgQxGzEHNw0RFmtYWUgDKT1FMx0WHCcKWwAvFhMHKxcAFmEWBhwnGgAAJVIFGi0UVAYuFgZIMhgAESQADRtsc1RFYTQMGmIcFQYpSEMTYgkVESleQwUnDRwKJV5DACMXEAkkACUBLhxUGEt4IDoLLT0mAD5ZSA0XGBxhAAYYLQsARSQEBgY2WRcKLxwGCzYQGwsyUgIGJlkGCjQGBhtiDRwENVILCTQcVCYOPCA6By0xRQQkKiwHNzcgYRsNSDYREUUxAAweKx0RAWERDAwnWQcELAIPDTFVVBY1ExcBIVkHBiAcDQ0wWQYAMgcPHDFVVAozUicHIRIRF2EBBho0EBcAMlxDISRZAA0kUhAcIw0dBmEBAAksFxEXYQECETFZVisuUgYeJxcASCUACh4nF1QVIAYXDTAXB0UlFxcNIQ0RAWNeQxonDQEXL1IGBTINDUUkBAYGNjobCy8XABwrFhoWb1InB2I3OzFhGw0eJxcARTETFxwnCxoWYQYLCTZZFRckUg0HNlkREygWBgYhHBBFKBxDHCocVAwvAhYcbHN+NyQBEwcsHVQSKAYLSA03ODxhE0MiETY6RS4QCQ0hDU5vOnhDSGAcAgAvBiAHLBcRBjUbDAYxW05FGlxNRh9VfkVhUAIYKysbEDUXEEp4WS9Lb1w+Yj9zfiwnUg0HYgkVETUXEQYxWRIKNBwHRGILERE0AA1IJxQEEThSAhowGA0Wbw==");
|
|
7
|
-
registerPrompt("pipeline/service-describer", "GB0WSCMLEUUgHEMNOgkRFzVSEAckDQMEMxdDCTAaHAw1FwAcbFk1CyAeGhInWQANJFITGi0TEQY1UgAHLA0RHTVSAgYmWR0BJBwXASQATm9LQ01IaFMEFy4YBgs2PREWIgAKGDYQGwtrWFlIA1kXCSQTEUhwVEdFMhcNHCcXFwBhFgYbIQsdFTUbDAZiFhJFNhoCHGINHAwyUhMaLRMRBjVSBwcnClpvc1xDQmgJBgwsExERDhgaAjQTBA1oU05FFRoGSC8YHQthAhEHJQsVCCwbDQ9iFRULJgcCDydZXABvFU1EYlsgHDEXMAswEAQRY15DShIAAA0uHEFEYlszCmNeQ0oQDAcRY1tNYnFXVE9rFgIcIxsVFiQBSUJ4WTAENRMBCTEcB0U0AQYMYhAaRTUaChtiCQYKKxcAHGxzQEthWEkNOg0RFy8TDzsnCwIMIhcQQmhDVCA5BgYaLBgYRTIXER4rGhEWbjMzITFZFwovARYFJx1UBzhSFwArClQVMx0JDSENWm9LNAwaYh0VESAQAhsnClQELxZDDToNERcvEw87JwsCDCIXEERiCQYKNxsHDXhzWUUoFllIKRwWBCNfAAkxHFQWLQcEYm9ZGgQsF1lIKgwZBC9fEQ0jHRUHLRdDBiMUEW9sUhcRMhxORTUXAAAsFhgKJgtDHDsJEUVpF00PbFVURzEdEBwlCxEWMB5BRGJbBgAlGxBKbllWFjUAChgnW11vbFIHDTEaBgwxBgoHLENUEikTF0grDVMWYQcQDSZZEgozeE5INwoRAQMLWUgjCwYEOFIMDmIaGwgxHQ0NLA1ULAUBQxwqGABFNAEGSDYRHRZhWhYbJ1kfACMTAUUhGAcAYQEPHSUKVAggBgAAKxcTRTUaBkghFhkVLhwGBjZZGgQsFxBBSHM3NwgmKisDNU5FDhwPEWIQGgYtBwcNYh0VESAQAhsnClQELxZDDToNERcvEw9IMRwGEygRBhtiDRwENVILCTQcVCYOPCA6By0xRQQkKiwHNzcgYRsNSDYREUUiHQcNIBgHAHt4TkgSGBcOIBUGRyYcBAAvFgYGIQBUDCwCDBo2ClRNJFwERm5ZVhUmUE9IYAsRASgBQURiWwcRMxsTDWBVVEcBExQbbwoQDm4RDwEnFwBIMkFBQUhUVCAvBAoaLRcZAC8GQx4jCx0EIx4GG2ILEQMkAAYGIRAaAmEGCw0vWVwAbxVNRGI9NTEAMCI7ByYhNw1eQzoHPT02HicxJG5ZJzETOzMtHSoxJhM3NzcJPC1MS19DLC0aHwAzUiAHLwkbFiRSEA0wDx0GJAFDHysNHEUsExcLKhAaAmEbDgklHAdvbFIgBywfHQI0AAIcKxYaRScbDw0xWQYAJxcRDSwaHQsmUhcAJxR+
|
|
8
|
-
registerPrompt("pipeline/validator", "
|
|
7
|
+
registerPrompt("pipeline/service-describer", "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");
|
|
8
|
+
registerPrompt("pipeline/validator", "GB0WSCMLEUUgUhAHJA0DBDMXQwkwGhwMNRcAHDcLEUUzFxUBJw4RF29SNQkuEBAENRdDHCocVAQvEw8RMRAHRTMXEB0uDQdFIBwHSDEMEwIkARdIIRYGFyQRFwEtFwdLS3ggACcaH0UnHRFSSEhaRWtYNBotFxNFIh0OGC0XEQs1UhcRMhwHT2tIQw1sHlpJYRNDOicYFxFhExMYYg0NFSQWQwkxWVYWJAAVASEcVkUyGgwdLh1UByRSQQ4wFhoRJBwHSkhLWkVrWDQNIxJUASQBABorCQAMLhwQQmhDVCYuHxMHLBwaETJSFAE2EVQALAIXEWIWBkU0HAAEJxgGRSUXEAswEAQRKB0NG2Kb9PFhAhEHNBAQAGEQBhw2HAZFLhwGG0hKWkVrWDENJgwaASAcF0ghFhoLJBEXAS0XB09rSEMsNwkYDCITFw1iFgZFNBwNDSEcBxYgABpIIRYaCyQRFwEtFwdFNRoCHGIKHAo0HgdIIBxUFyQfDB4nHX5Rb1JJQhULGwsmUgAHLBcRBjUbDAZiDQ0VJAFJQnhZEUsmXE9IIxdUDCwCDBo2WRcKLxwGCzYQGwthBgsJNlkHDS4HDwxiGxFFYxoXHDJbfm8CICo8Czo1KWExLCYRLSYkCDw3O3hzWUUYHRZILxgNRQ48LzFiCxEDJAAGBiEcVAYuHxMHLBwaEWE7JxtiDRwENVICBDAcFQE4UgYQKwoARSgcQxwqHFQGLh8TBywcGhEyUg8BMQ1UBCMdFQ1sc1lFBR1DJg0tVAwvBAYGNlkaADZSAAcvCRsLJBwXG25ZEAQ1EwEJMRwHSWEdEUgnAQAAMxwCBGIKERc3GwANMVd+SGE2DEgMNiBFIBYHSCEWGgskERcBLRcHRTUdQwstFAQKLxcNHDFZAA0gBkMMLRdTEWEXGwExDVQML1IXACdZGAwyBk1ib1k7Cy0LQwkmHVQGLhwNDSENHQovAUMRLQxUBDMXQwArHhwJOFIABywfHQEkHBdIIxsbEDVSAQkxHBBFLhxDHCocVAYuHxMHLBwaEWECAhwqClhFNRcAACwWGAomGwYbblkVCyVSBhArCgAMLxVDCy0XGgAiBgoHLApab2xSMxonHxEXYQAGBS0PHQsmUgEJJlkXCi8cBgs2EBsLMlIMHicLVAQlFgoGJVkHFSQRFgQjDR0TJFIMBicKWm9sUioOYg0cAGETDQkuAAcMMlIPBy0SB0UzFwIbLRcVBy0XT0gwHAAQMxxDDS8JABxhEQwaMBwXESgdDRtsWTgAMgFDATFZGQozF01iSCsRFjEdDQxiDh0RKVIsJg4gVARhODAnDFkbBysXABx4cw9vYVJBCy0UBAovFw0cFgAEAAIdERonGgAMLhwQSnhZD0VjEQwFMhYaAC8GTgEmW05FYxEMGjAcFxFsBhoYJ1tUGG14Q0hgGhsIMR0NDSwNMAAyEREBMg0dCi8BQVJiAlRHIh0OGC0XEQs1XwoMYENURyMXFxwnC1QBJAEAGisJAAwuHEFIP1V+RWFQAgwmHBAmLhwNDSENHQovAUFSYiIPRWMUEQcvW05FYxsHSm5ZVhEuUFlIYBAQR21SQRw7CRFHHF5pSGJbFwovFAoMJxcXAGNIQ1hsQUFJS1JDSisKBxAkAUFSYiJWASQBABorCQAMLhxDByRZFQs4UhENLxgdCygcBEgrCgcQJAFBNUgEfm8UAQZIJxQEEThSDAooHBcRMl0CGjAYDRZhGwVILBZUBi4AEQ0hDR0KLwFDBiccEAAlXEM8KhxUBi4cBQEmHBoGJFIQCy0LEUVpQk5Za1kGACceBgs2ClQcLgcRSC0PERcgHg9IIRYaAygWBgYhHFQML1IXACdZFQsgHhobKwpUFDQTDwE2AFo=");
|
|
@@ -10,7 +10,7 @@ export class OllamaProvider {
|
|
|
10
10
|
...params.messages.map((m) => this.toOllamaMessage(m)),
|
|
11
11
|
];
|
|
12
12
|
const body = {
|
|
13
|
-
model: params.model
|
|
13
|
+
model: params.model,
|
|
14
14
|
messages,
|
|
15
15
|
stream: false,
|
|
16
16
|
};
|
|
@@ -65,7 +65,7 @@ export class OllamaProvider {
|
|
|
65
65
|
...params.messages.map((m) => this.toOllamaMessage(m)),
|
|
66
66
|
];
|
|
67
67
|
const body = {
|
|
68
|
-
model: params.model
|
|
68
|
+
model: params.model,
|
|
69
69
|
messages,
|
|
70
70
|
stream: true,
|
|
71
71
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { AnthropicProvider } from "./anthropic.js";
|
|
2
2
|
import { OpenAIProvider } from "./openai.js";
|
|
3
3
|
import { GoogleProvider } from "./google.js";
|
|
4
|
-
import { OllamaProvider } from "./ollama.js";
|
|
5
4
|
export function createProvider(config) {
|
|
6
5
|
switch (config.provider) {
|
|
7
6
|
case "anthropic":
|
|
@@ -10,8 +9,6 @@ export function createProvider(config) {
|
|
|
10
9
|
return new OpenAIProvider(config.apiKey);
|
|
11
10
|
case "google":
|
|
12
11
|
return new GoogleProvider(config.apiKey);
|
|
13
|
-
case "ollama":
|
|
14
|
-
return new OllamaProvider(config.ollamaBaseUrl ?? "http://localhost:11434");
|
|
15
12
|
default:
|
|
16
13
|
throw new Error(`Unknown provider: ${config.provider}`);
|
|
17
14
|
}
|
|
@@ -24,11 +21,7 @@ export function detectConfig() {
|
|
|
24
21
|
const explicit = process.env.ARCHBYTE_PROVIDER;
|
|
25
22
|
const apiKey = process.env.ARCHBYTE_API_KEY;
|
|
26
23
|
if (explicit && apiKey) {
|
|
27
|
-
return {
|
|
28
|
-
provider: explicit,
|
|
29
|
-
apiKey,
|
|
30
|
-
ollamaBaseUrl: process.env.OLLAMA_BASE_URL,
|
|
31
|
-
};
|
|
24
|
+
return { provider: explicit, apiKey };
|
|
32
25
|
}
|
|
33
26
|
// Auto-detect from known env vars
|
|
34
27
|
if (process.env.ANTHROPIC_API_KEY) {
|
|
@@ -43,13 +36,5 @@ export function detectConfig() {
|
|
|
43
36
|
apiKey: process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY ?? "",
|
|
44
37
|
};
|
|
45
38
|
}
|
|
46
|
-
// Ollama doesn't need an API key
|
|
47
|
-
if (explicit === "ollama") {
|
|
48
|
-
return {
|
|
49
|
-
provider: "ollama",
|
|
50
|
-
apiKey: "",
|
|
51
|
-
ollamaBaseUrl: process.env.OLLAMA_BASE_URL ?? "http://localhost:11434",
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
39
|
return null;
|
|
55
40
|
}
|
|
@@ -90,7 +90,7 @@ export class Orchestrator {
|
|
|
90
90
|
return false;
|
|
91
91
|
}
|
|
92
92
|
async runAgent(agent, priorResults, onProgress) {
|
|
93
|
-
const model = resolveModel(this.config.provider, agent.modelTier, this.config.modelOverrides);
|
|
93
|
+
const model = resolveModel(this.config.provider, agent.modelTier, this.config.modelOverrides, this.config.model);
|
|
94
94
|
// Create a model-routed provider wrapper
|
|
95
95
|
const routedProvider = {
|
|
96
96
|
name: this.provider.name,
|
|
@@ -98,11 +98,16 @@ export interface License {
|
|
|
98
98
|
isValid: boolean;
|
|
99
99
|
}
|
|
100
100
|
export type ProviderName = "anthropic" | "openai" | "google" | "ollama";
|
|
101
|
+
export interface ProviderProfile {
|
|
102
|
+
apiKey?: string;
|
|
103
|
+
model?: string;
|
|
104
|
+
}
|
|
101
105
|
export interface ArchByteConfig {
|
|
102
106
|
provider: ProviderName;
|
|
103
107
|
apiKey: string;
|
|
108
|
+
model?: string;
|
|
104
109
|
modelOverrides?: Partial<Record<ModelTier, string>>;
|
|
105
|
-
|
|
110
|
+
profiles?: Record<string, ProviderProfile>;
|
|
106
111
|
}
|
|
107
112
|
export interface PipelineResult {
|
|
108
113
|
agents: AgentResult[];
|
|
@@ -114,4 +119,4 @@ export interface PipelineResult {
|
|
|
114
119
|
}>;
|
|
115
120
|
}
|
|
116
121
|
export declare const MODEL_MAP: Record<ProviderName, Record<ModelTier, string>>;
|
|
117
|
-
export declare function resolveModel(provider: ProviderName, tier: ModelTier, overrides?: Partial<Record<ModelTier, string
|
|
122
|
+
export declare function resolveModel(provider: ProviderName, tier: ModelTier, overrides?: Partial<Record<ModelTier, string>>, model?: string): string;
|
|
@@ -7,23 +7,25 @@ export const MODEL_MAP = {
|
|
|
7
7
|
advanced: "claude-opus-4-6",
|
|
8
8
|
},
|
|
9
9
|
openai: {
|
|
10
|
-
fast: "gpt-
|
|
11
|
-
standard: "gpt-
|
|
10
|
+
fast: "gpt-5.2-codex",
|
|
11
|
+
standard: "gpt-5.2",
|
|
12
12
|
advanced: "o3",
|
|
13
13
|
},
|
|
14
14
|
google: {
|
|
15
|
-
fast: "gemini-2.
|
|
15
|
+
fast: "gemini-2.5-flash",
|
|
16
16
|
standard: "gemini-2.5-pro",
|
|
17
17
|
advanced: "gemini-2.5-pro",
|
|
18
18
|
},
|
|
19
19
|
ollama: {
|
|
20
|
-
fast: "
|
|
21
|
-
standard: "
|
|
22
|
-
advanced: "
|
|
20
|
+
fast: "qwen2.5-coder",
|
|
21
|
+
standard: "qwen2.5-coder",
|
|
22
|
+
advanced: "qwen2.5-coder",
|
|
23
23
|
},
|
|
24
24
|
};
|
|
25
|
-
export function resolveModel(provider, tier, overrides) {
|
|
25
|
+
export function resolveModel(provider, tier, overrides, model) {
|
|
26
26
|
if (overrides?.[tier])
|
|
27
27
|
return overrides[tier];
|
|
28
|
+
if (model)
|
|
29
|
+
return model;
|
|
28
30
|
return MODEL_MAP[provider][tier];
|
|
29
31
|
}
|
|
@@ -140,10 +140,7 @@ function extractImportPath(line) {
|
|
|
140
140
|
return cjsMatch[1];
|
|
141
141
|
return null;
|
|
142
142
|
}
|
|
143
|
-
|
|
144
|
-
"node_modules", "dist", "build", ".git", "venv", "__pycache__",
|
|
145
|
-
"target", "coverage", "vendor", ".next", ".nuxt",
|
|
146
|
-
]);
|
|
143
|
+
import { EXCLUDED_DIRS as VENDORED } from "./excluded-dirs.js";
|
|
147
144
|
function isVendored(name) {
|
|
148
145
|
return VENDORED.has(name);
|
|
149
146
|
}
|
|
@@ -69,10 +69,7 @@ const BUILD_CONFIG_FILES = [
|
|
|
69
69
|
"tsconfig.json",
|
|
70
70
|
];
|
|
71
71
|
// Skip these dirs — not components
|
|
72
|
-
|
|
73
|
-
"node_modules", "dist", "build", "target", ".git",
|
|
74
|
-
"coverage", "tmp", ".cache", "venv", "__pycache__",
|
|
75
|
-
]);
|
|
72
|
+
import { EXCLUDED_DIRS as SKIP_DIRS } from "./excluded-dirs.js";
|
|
76
73
|
export async function detectComponents(tk, structure) {
|
|
77
74
|
// Strategy 1: Monorepo workspaces
|
|
78
75
|
if (structure.isMonorepo) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Static Analysis — Event Detector
|
|
2
2
|
// Detects event-driven architecture patterns from deps and code grep
|
|
3
|
+
import { EXCLUDED_DIRS_REGEX } from "./excluded-dirs.js";
|
|
3
4
|
const EDA_DEPS = [
|
|
4
5
|
{ dep: "kafkajs", technology: "Kafka" },
|
|
5
6
|
{ dep: "@confluentinc/kafka-javascript", technology: "Kafka" },
|
|
@@ -50,7 +51,7 @@ export async function detectEvents(tk) {
|
|
|
50
51
|
tk.grepFiles("\\.emit\\(|\\.dispatch\\(|\\.trigger\\("),
|
|
51
52
|
]);
|
|
52
53
|
// Exclude vendored/generated dirs from all results
|
|
53
|
-
const excludeDirs =
|
|
54
|
+
const excludeDirs = EXCLUDED_DIRS_REGEX;
|
|
54
55
|
const filterVendored = (results) => results.filter((r) => !excludeDirs.test("/" + r.file));
|
|
55
56
|
// Filter subscribe results to only EDA-relevant ones (skip generic .on() calls)
|
|
56
57
|
const filteredSubscribe = filterVendored(subscribeResults).filter((r) => /\.(subscribe|consume)\(/.test(r.content));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Shared set of directories to skip during static analysis.
|
|
2
|
+
// Imported by all scanners to avoid duplication.
|
|
3
|
+
export const EXCLUDED_DIRS = new Set([
|
|
4
|
+
"node_modules", "dist", "build", "target", ".git",
|
|
5
|
+
"coverage", "tmp", ".cache", ".turbo", ".nx",
|
|
6
|
+
"venv", ".venv", "env", "__pycache__",
|
|
7
|
+
".next", ".nuxt", ".output",
|
|
8
|
+
"vendor",
|
|
9
|
+
]);
|
|
10
|
+
/** Regex version for filtering grep/file results by path segment */
|
|
11
|
+
export const EXCLUDED_DIRS_REGEX = /\/(node_modules|dist|build|target|\.git|coverage|tmp|\.cache|\.turbo|\.nx|venv|\.venv|env|__pycache__|\.next|\.nuxt|\.output|vendor)\//;
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
// Static Analysis — File Tree Collector
|
|
2
2
|
// Collects depth-limited directory tree for LLM context
|
|
3
|
-
|
|
4
|
-
"node_modules", "dist", "build", ".git", "venv", "__pycache__",
|
|
5
|
-
"target", "coverage", ".next", ".nuxt", ".output", ".cache",
|
|
6
|
-
".turbo", ".nx", "vendor", ".venv", "env",
|
|
7
|
-
]);
|
|
3
|
+
import { EXCLUDED_DIRS as SKIP_DIRS } from "./excluded-dirs.js";
|
|
8
4
|
const MAX_ENTRIES = 2000;
|
|
9
5
|
const MAX_DEPTH = 3;
|
|
10
6
|
export async function collectFileTree(tk) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile, readdir, stat } from "node:fs/promises";
|
|
2
2
|
import { resolve, join } from "node:path";
|
|
3
|
+
import { EXCLUDED_DIRS } from "../static/excluded-dirs.js";
|
|
3
4
|
/**
|
|
4
5
|
* ClaudeCodeBackend — uses the same local FS operations as LocalFSBackend
|
|
5
6
|
* but is designed to be instantiated when running inside Claude Code.
|
|
@@ -101,11 +102,7 @@ export class ClaudeCodeBackend {
|
|
|
101
102
|
}
|
|
102
103
|
for (const entry of entries) {
|
|
103
104
|
if (entry.name.startsWith(".") ||
|
|
104
|
-
entry.name
|
|
105
|
-
entry.name === "dist" ||
|
|
106
|
-
entry.name === "__pycache__" ||
|
|
107
|
-
entry.name === ".git" ||
|
|
108
|
-
entry.name === ".archbyte") {
|
|
105
|
+
EXCLUDED_DIRS.has(entry.name)) {
|
|
109
106
|
continue;
|
|
110
107
|
}
|
|
111
108
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile, readdir, stat } from "node:fs/promises";
|
|
2
2
|
import { resolve, relative, join } from "node:path";
|
|
3
|
+
import { EXCLUDED_DIRS } from "../static/excluded-dirs.js";
|
|
3
4
|
export class LocalFSBackend {
|
|
4
5
|
root;
|
|
5
6
|
constructor(projectRoot) {
|
|
@@ -82,12 +83,7 @@ export class LocalFSBackend {
|
|
|
82
83
|
return;
|
|
83
84
|
}
|
|
84
85
|
for (const entry of entries) {
|
|
85
|
-
|
|
86
|
-
if (entry.name.startsWith(".") ||
|
|
87
|
-
entry.name === "node_modules" ||
|
|
88
|
-
entry.name === "dist" ||
|
|
89
|
-
entry.name === "__pycache__" ||
|
|
90
|
-
entry.name === ".git") {
|
|
86
|
+
if (entry.name.startsWith(".") || EXCLUDED_DIRS.has(entry.name)) {
|
|
91
87
|
continue;
|
|
92
88
|
}
|
|
93
89
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
package/dist/cli/analyze.d.ts
CHANGED
package/dist/cli/analyze.js
CHANGED
|
@@ -6,8 +6,9 @@ import { resolveConfig } from "./config.js";
|
|
|
6
6
|
import { recordUsage } from "./license-gate.js";
|
|
7
7
|
import { staticResultToSpec, writeSpec, writeMetadata, loadSpec, loadMetadata } from "./yaml-io.js";
|
|
8
8
|
import { getChangedFiles, mapFilesToComponents, shouldRunAgents, isGitAvailable } from "./incremental.js";
|
|
9
|
+
import { progressBar } from "./ui.js";
|
|
9
10
|
export async function handleAnalyze(options) {
|
|
10
|
-
const rootDir = process.cwd();
|
|
11
|
+
const rootDir = options.dir ? path.resolve(options.dir) : process.cwd();
|
|
11
12
|
const isStaticOnly = options.static || options.skipLlm;
|
|
12
13
|
console.log();
|
|
13
14
|
console.log(chalk.bold.cyan("ArchByte Analyzer"));
|
|
@@ -40,13 +41,13 @@ export async function handleAnalyze(options) {
|
|
|
40
41
|
// ─── Static-only mode (--static / --skip-llm) ───
|
|
41
42
|
if (isStaticOnly) {
|
|
42
43
|
const startTime = Date.now();
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
const progress = progressBar(3);
|
|
45
|
+
progress.update(0, "Running static analysis...");
|
|
45
46
|
const { runStaticAnalysis } = await import("../agents/static/index.js");
|
|
46
47
|
const result = await runStaticAnalysis(rootDir, (msg) => {
|
|
47
|
-
|
|
48
|
-
console.log(chalk.gray(` [${elapsed}s] ${msg}`));
|
|
48
|
+
progress.update(0, `Static analysis: ${msg}`);
|
|
49
49
|
});
|
|
50
|
+
progress.update(1, "Building analysis...");
|
|
50
51
|
const analysis = buildAnalysisFromStatic(result, rootDir);
|
|
51
52
|
const duration = Date.now() - startTime;
|
|
52
53
|
// Stamp scan metadata on analysis.json (backward compat)
|
|
@@ -59,8 +60,9 @@ export async function handleAnalyze(options) {
|
|
|
59
60
|
const spec = staticResultToSpec(result, rootDir, existingSpec?.rules);
|
|
60
61
|
writeSpec(rootDir, spec);
|
|
61
62
|
writeScanMetadata(rootDir, duration, "static");
|
|
62
|
-
|
|
63
|
+
progress.update(2, "Generating diagram...");
|
|
63
64
|
await autoGenerate(rootDir, options);
|
|
65
|
+
progress.done("Analysis complete");
|
|
64
66
|
printSummary(analysis, duration, "static");
|
|
65
67
|
return;
|
|
66
68
|
}
|
|
@@ -71,7 +73,6 @@ export async function handleAnalyze(options) {
|
|
|
71
73
|
config = {
|
|
72
74
|
provider: options.provider,
|
|
73
75
|
apiKey: options.apiKey ?? config?.apiKey ?? "",
|
|
74
|
-
ollamaBaseUrl: config?.ollamaBaseUrl,
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
78
|
if (options.apiKey && config) {
|
|
@@ -113,16 +114,16 @@ export async function handleAnalyze(options) {
|
|
|
113
114
|
let incrementalContext;
|
|
114
115
|
const priorSpec = loadSpec(rootDir);
|
|
115
116
|
const priorMeta = loadMetadata(rootDir);
|
|
116
|
-
if (priorSpec && !options.
|
|
117
|
+
if (priorSpec && !options.force && isGitAvailable(rootDir) && priorMeta?.lastCommit) {
|
|
117
118
|
const changedFiles = getChangedFiles(rootDir, priorMeta.lastCommit);
|
|
118
119
|
if (changedFiles.length === 0) {
|
|
119
|
-
console.log(chalk.green("No changes detected since last scan. Use --
|
|
120
|
+
console.log(chalk.green("No changes detected since last scan. Use --force to re-scan."));
|
|
120
121
|
console.log();
|
|
121
122
|
return;
|
|
122
123
|
}
|
|
123
124
|
const { affected, unmapped } = mapFilesToComponents(changedFiles, priorSpec);
|
|
124
125
|
if (!shouldRunAgents(affected, unmapped)) {
|
|
125
|
-
console.log(chalk.green("Only config changes detected — no re-scan needed. Use --
|
|
126
|
+
console.log(chalk.green("Only config changes detected — no re-scan needed. Use --force to re-scan."));
|
|
126
127
|
console.log();
|
|
127
128
|
return;
|
|
128
129
|
}
|
|
@@ -140,11 +141,11 @@ export async function handleAnalyze(options) {
|
|
|
140
141
|
console.log();
|
|
141
142
|
}
|
|
142
143
|
// 4. Run static context collection → LLM pipeline
|
|
143
|
-
|
|
144
|
+
const progress = progressBar(7);
|
|
145
|
+
progress.update(0, "Collecting static context...");
|
|
144
146
|
const { runStaticContextCollection } = await import("../agents/static/index.js");
|
|
145
147
|
const ctx = await runStaticContextCollection(rootDir, (msg) => {
|
|
146
|
-
|
|
147
|
-
console.log(chalk.gray(` [${elapsed}s] ${msg}`));
|
|
148
|
+
progress.update(0, `Static context: ${msg}`);
|
|
148
149
|
});
|
|
149
150
|
// Save static context for debugging / re-runs
|
|
150
151
|
const ctxPath = path.join(rootDir, ".archbyte", "static-context.json");
|
|
@@ -152,15 +153,41 @@ export async function handleAnalyze(options) {
|
|
|
152
153
|
fs.mkdirSync(path.dirname(ctxPath), { recursive: true });
|
|
153
154
|
}
|
|
154
155
|
fs.writeFileSync(ctxPath, JSON.stringify(ctx, null, 2), "utf-8");
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
console.log(chalk.bold(`Phase 2: Running model pipeline${incrementalContext ? " (incremental)" : ""} (3 parallel + 2 sequential)...`));
|
|
156
|
+
progress.update(1, "Static context collected");
|
|
157
|
+
progress.update(1, `Running 3 agents in parallel${incrementalContext ? " (incremental)" : ""}...`);
|
|
158
158
|
const { runPipeline } = await import("../agents/pipeline/index.js");
|
|
159
159
|
let result;
|
|
160
|
+
let pipelineStep = 1;
|
|
160
161
|
try {
|
|
161
162
|
result = await runPipeline(ctx, provider, config, (msg) => {
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
// Map pipeline progress messages to bar steps
|
|
164
|
+
if (msg.startsWith("Phase 1:")) {
|
|
165
|
+
pipelineStep = 1;
|
|
166
|
+
progress.update(1, "Running 3 agents in parallel...");
|
|
167
|
+
}
|
|
168
|
+
else if (msg.startsWith("Phase 2:")) {
|
|
169
|
+
pipelineStep = 3;
|
|
170
|
+
}
|
|
171
|
+
else if (msg.includes(": done") && pipelineStep < 3) {
|
|
172
|
+
// A parallel agent finished
|
|
173
|
+
pipelineStep = Math.min(pipelineStep + 0.5, 2);
|
|
174
|
+
progress.update(pipelineStep, `Running agents in parallel... (${msg.trim()})`);
|
|
175
|
+
}
|
|
176
|
+
else if (msg.includes("Connection Mapper") || msg.includes("connection-mapper")) {
|
|
177
|
+
progress.update(3, "Running connection-mapper...");
|
|
178
|
+
}
|
|
179
|
+
else if (msg.includes("Validator") || msg.includes("validator")) {
|
|
180
|
+
progress.update(4, "Running validator...");
|
|
181
|
+
}
|
|
182
|
+
else if (msg.startsWith("Merging")) {
|
|
183
|
+
progress.update(5, "Merging results...");
|
|
184
|
+
}
|
|
185
|
+
else if (msg.startsWith("Token usage")) {
|
|
186
|
+
progress.update(5, msg.trim());
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
progress.update(pipelineStep, msg.trim());
|
|
190
|
+
}
|
|
164
191
|
}, incrementalContext);
|
|
165
192
|
}
|
|
166
193
|
catch (err) {
|
|
@@ -196,8 +223,8 @@ export async function handleAnalyze(options) {
|
|
|
196
223
|
}
|
|
197
224
|
return;
|
|
198
225
|
}
|
|
199
|
-
console.log();
|
|
200
226
|
// 4. Convert to analysis.json format and write
|
|
227
|
+
progress.update(5, "Merging results...");
|
|
201
228
|
const analysis = buildAnalysisFromStatic(result, rootDir);
|
|
202
229
|
const duration = Date.now() - startTime;
|
|
203
230
|
// Stamp scan metadata on analysis.json (backward compat)
|
|
@@ -215,8 +242,9 @@ export async function handleAnalyze(options) {
|
|
|
215
242
|
const spec = staticResultToSpec(result, rootDir, existingSpec?.rules);
|
|
216
243
|
writeSpec(rootDir, spec);
|
|
217
244
|
writeScanMetadata(rootDir, duration, "pipeline", ctx.fileTree.totalFiles, result.tokenUsage);
|
|
218
|
-
|
|
245
|
+
progress.update(6, "Generating diagram...");
|
|
219
246
|
await autoGenerate(rootDir, options);
|
|
247
|
+
progress.done("Analysis complete");
|
|
220
248
|
// Record usage (best-effort, non-blocking)
|
|
221
249
|
recordUsage({
|
|
222
250
|
projectName: path.basename(rootDir),
|
|
@@ -269,8 +297,6 @@ function writeScanMetadata(rootDir, durationMs, mode, filesScanned, tokenUsage)
|
|
|
269
297
|
writeMetadata(rootDir, meta);
|
|
270
298
|
}
|
|
271
299
|
async function autoGenerate(rootDir, options) {
|
|
272
|
-
console.log();
|
|
273
|
-
console.log(chalk.gray("Generating architecture diagram..."));
|
|
274
300
|
const analysisPath = path.join(rootDir, ".archbyte", "analysis.json");
|
|
275
301
|
try {
|
|
276
302
|
const { handleGenerate } = await import("./generate.js");
|
package/dist/cli/auth.js
CHANGED
|
@@ -3,10 +3,7 @@ import * as path from "path";
|
|
|
3
3
|
import * as http from "http";
|
|
4
4
|
import { spawn } from "child_process";
|
|
5
5
|
import chalk from "chalk";
|
|
6
|
-
|
|
7
|
-
const CREDENTIALS_PATH = path.join(CONFIG_DIR, "credentials.json");
|
|
8
|
-
const API_BASE = process.env.ARCHBYTE_API_URL ?? "https://api.heartbyte.io";
|
|
9
|
-
const CLI_CALLBACK_PORT = 19274;
|
|
6
|
+
import { CONFIG_DIR, CREDENTIALS_PATH, API_BASE, CLI_CALLBACK_PORT, OAUTH_TIMEOUT_MS, } from "./constants.js";
|
|
10
7
|
export async function handleLogin(provider) {
|
|
11
8
|
console.log();
|
|
12
9
|
console.log(chalk.bold.cyan("ArchByte Login"));
|
|
@@ -322,7 +319,7 @@ function startOAuthFlow(provider = "github") {
|
|
|
322
319
|
const timeout = setTimeout(() => {
|
|
323
320
|
server.close();
|
|
324
321
|
reject(new Error("Login timed out (60s). Try again or use --token."));
|
|
325
|
-
},
|
|
322
|
+
}, OAUTH_TIMEOUT_MS);
|
|
326
323
|
const server = http.createServer(async (req, res) => {
|
|
327
324
|
const url = new URL(req.url ?? "/", `http://localhost:${CLI_CALLBACK_PORT}`);
|
|
328
325
|
if (url.pathname === "/callback") {
|
package/dist/cli/config.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ interface ConfigOptions {
|
|
|
5
5
|
export declare function handleConfig(options: ConfigOptions): Promise<void>;
|
|
6
6
|
/**
|
|
7
7
|
* Resolve the full ArchByteConfig from config file + env vars.
|
|
8
|
+
* Supports profiles (new) and legacy flat config (backward compat).
|
|
8
9
|
* Env vars override config file.
|
|
9
10
|
*/
|
|
10
11
|
export declare function resolveConfig(): ArchByteConfig | null;
|