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.
Files changed (41) hide show
  1. package/bin/archbyte.js +30 -7
  2. package/dist/agents/llm/index.js +1 -1
  3. package/dist/agents/pipeline/index.js +1 -1
  4. package/dist/agents/prompt-data.js +4 -4
  5. package/dist/agents/providers/ollama.js +2 -2
  6. package/dist/agents/providers/router.js +1 -16
  7. package/dist/agents/runtime/orchestrator.js +1 -1
  8. package/dist/agents/runtime/types.d.ts +7 -2
  9. package/dist/agents/runtime/types.js +9 -7
  10. package/dist/agents/static/code-sampler.js +1 -4
  11. package/dist/agents/static/component-detector.js +1 -4
  12. package/dist/agents/static/event-detector.js +2 -1
  13. package/dist/agents/static/excluded-dirs.d.ts +3 -0
  14. package/dist/agents/static/excluded-dirs.js +11 -0
  15. package/dist/agents/static/file-tree-collector.js +1 -5
  16. package/dist/agents/tools/claude-code.js +2 -5
  17. package/dist/agents/tools/local-fs.js +2 -6
  18. package/dist/cli/analyze.d.ts +2 -1
  19. package/dist/cli/analyze.js +48 -22
  20. package/dist/cli/auth.js +2 -5
  21. package/dist/cli/config.d.ts +1 -0
  22. package/dist/cli/config.js +84 -42
  23. package/dist/cli/constants.d.ts +13 -0
  24. package/dist/cli/constants.js +20 -0
  25. package/dist/cli/gate.js +3 -3
  26. package/dist/cli/generate.js +5 -2
  27. package/dist/cli/license-gate.js +3 -3
  28. package/dist/cli/run.d.ts +2 -0
  29. package/dist/cli/run.js +4 -7
  30. package/dist/cli/serve.js +3 -2
  31. package/dist/cli/setup.js +116 -69
  32. package/dist/cli/ui.d.ts +10 -0
  33. package/dist/cli/ui.js +44 -0
  34. package/dist/cli/version.d.ts +2 -0
  35. package/dist/cli/version.js +84 -0
  36. package/dist/server/src/index.js +40 -0
  37. package/package.json +1 -1
  38. package/ui/dist/assets/{index-Bl1r8zrI.css → index-0_XpUUZQ.css} +1 -1
  39. package/ui/dist/assets/index-BdfGbhpp.js +70 -0
  40. package/ui/dist/index.html +2 -2
  41. 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('0.2.1')
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, ollama')
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>', 'UI server port (default: 3847)', parseInt)
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, ollama')
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('--full', 'Force full re-scan (skip incremental detection)')
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>', 'Server port (default: 3847)', parseInt)
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, ollama-url)')
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(() => {
@@ -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", "GB0WSCMLEUUgHEMNOgkRFzVSEAckDQMEMxdDCTAaHAw1FwAcbFktCjQAQwItG1QMMlIXB2IQEAAvBgoOO1kREyQAGkgjCxcNKAYGCzYMBgQtHhpIMRATCygUCgsjFwBFIh0OGC0XEQs1UgoGYhhUFi4UFx8jCxFFMQAMAicaAEtLeCJIYBobCDEdDQ0sDVZFKAFDCWIdHRY1Gw0LNlkQADEeDBEjGxgAYQcNATZVVBYkABUBIRxYRSACEwQrGhURKB0NRGIVHQczExERblkbF2EBCg8sEBIMIhMNHGIUGwE0HgZGYjAaBi0HBw14c1lFAxMAAycXEEUyFxEeKxoRFm1SIjgLClhFNh0RAycLB29sUiUaLRcAAC8WQwkyCRgMIhMXAS0XB0VpBQYKblkZCiMbDw1rc1lFDRsBGiMLHQAyXRMJIRIVAiQBQ0ArF1QILhwMGicJGxZoeE5IATU9RTUdDAQxc1lFBRMXCSAYBwAyUksBJFkRHTEeCgsrDRgcYREMBiQQExAzFwdEYhxaAm9SCgZiHRsGKhcRRSEWGRUuAQZBSFRUIDkGBhosGBhFMhcRHisaERZhWgZGJVdUNyQWChtuWSYEIxAKHA8oWEUEHgIbNhAXFiQTEQsqUH5vBx0RSCcYFw1hEQwFMhYaAC8GT0gyCxsTKBYGUkhUVAwlSEMDJxsVB2wRAhsnWQcJNBVDQCdXE0ttUkEJMhBZFiQAFQ0wW1hFYwUGCm8fBgovBgYGJltdb2xSDQkvHE5FKQcOCSxUBgAgFgIKLhxUCyAfBmJvWQAcMRdZSC0XEUUuFENKJAsbCzUXDQxgVVRHIAIKSm5ZVhYkABUBIRxWSWFQFAcwEhEXY15DSi4QFhcgABpKbllWBi0bQURiWxAENRMBCTEcVklhUAQJNhwDBDhQT0hgGhUGKRdBRGJbBRAkBwZKSFRUCSALBhp4WRsLJFIMDmJbBBckAQYGNhgADC4cQURiWxUVMR4KCyMNHQovUE9IYB0VESBQT0hgHAwRJAANCS5bfkhhAgIcKkNUFyQeAhwrDxFFJRsRDSENGxc4UhMJNhFUTSRcBEZuWVYWJAAVDTBbWEVjExMYMVYDACNQSmJvWRAAMhERATINHQovSENZb0tUFiQcFw0sGhFFJRcQCzAQBBEoHQ1ILR9UFTQAEwcxHH5IYQYGCyoXGwkuFQoNMUNUBDMAAhFiFhJFKhcaSDYcFw0vHQ8HJRARFmFaBkYlV1hFGlA3ETIcJwYzGxMcYFVURwQKExonCgdHbVJBOC0KAAIzFzA5DlspTEt4MQ0xCRsLJVIUATYRVCoPPjpII1k+Ng48QwcgExEGNUhDE2JbFwosAgwGJxcAFmNIQzNsV1o4YQ8=");
5
- registerPrompt("pipeline/connection-mapper", "GB0WSCMLEUUgHEMNOgkRFzVSEAckDQMEMxdDCTAaHAw1FwAcbFktCjQAQwItG1QMMlIXB2IUFRVhMy8kYhobCy8XABwrFhoWYRAGHDUcEQthEQwFMhYaAC8GEEgrF1QEYQEMDjYOFRckUhARMQ0RCG94aSstFxoAIgYKByxZABwxFxBSSFRURygfEwcwDVZfYRYKGicaAEUiHQcNYhAZFS4AF0cmHAQALxYGBiEAfkhhUAscNglWX2EgJjsWVhM3ETFMIBYtJEUiEw8EMXNZRWMWAhwjGxUWJFBZSCEWGRUuHAYGNlkGACAWEEc1Cx0RJAFDHC1ZFUUlExcJIBgHAEtfQ0onDxELNVBZSCMKDQsiUgYeJxcASiwXEBsjHhFFaQIWCm0KAQdtUhIdJwwRFmh4TkhgHgYVIlBZSCUrJCZhEQIELgp+SGFQFA0gChsGKhcXSnhZIwAjIQwLKRwARSIdDQYnGgAMLhwQYm9ZVgMoHgZKeFkHDSAABgxiHx0JJAEaGzYcGUUgEQANMQp+bwcdEUgnGBcNYREMBiwcFxEoHQ1SSFRUAzMdDlJiChsQMxEGSCEWGRUuHAYGNlk9IWFaDh0xDVQIIAYAAGIYGkUkCgobNhAaAmERDAUyFhoALwZDIQZZER0gERcEO1B+SGEGDFJiDRUXJhcXSCEWGRUuHAYGNlk9IWFaDh0xDVQIIAYAAGIYGkUkCgobNhAaAmERDAUyFhoALwZDIQZZER0gERcEO1B+SGEGGhgnQ1QKLxdDByRZAA0kUhcRMhwHRSAQDB4nc1lFJRcQCzAQBBEoHQ1SYhsGDCQUQwwnChcXKAIXAS0XVAonUhcAJ1kGAC0TFwEtFwcNKAJpRWIYBxwvEVlINgsBAGEbBUgjCg0LIhoRBywWARZhWgYeJxcAFm1SEh0nDBEWaHhpKS4KG0UoFgYGNhASHGFYSQ4uFgMWa1hDisLtVAAvFk4cLVQRCyVSEQ0zDBEWNVITCTYRB0U1GhEHNx4cRTUaBkgxAAcRJB9ZYm9ZGgQsF1lIJBUbEmEcAgUnWVwAbxVNRGJbIRYkAEM6Jx4dFjUAAhwrFhpHaHhOSCYcBwYzGxMcKxYaX2EFCwk2WRwEMQIGBjFzWUUiExcNJRYGHHtSDAYnWRsDYVAWGycLWQ8uBxEGJwBWSWFQBwk2GFkVKAIGBCsXEUdtUkEbOwoAACxQT0hgHREVLR0aBScXAEdtUkENMAsbF2wABgstDxEXOFBpRWIKAAAxAVlIIwsGBDhSDA5iCgAXKBwEG25ZEQQiGkMtGjg3MQ0rQwEsWQANJFIFBzAUFRFhUAAHLwkbCyQcFyEmWZbj01IABy8JGwskHBchJltUTSRcBEZuWVYSJBBODjAWGhEkHAdIoP/mRSACCkUxHAYTJABBRGJbFRUoXxANMA8RF2GQ5fpiCRsWNRURDTEIGEdoXEMtIxocRTIGBhhiFAEWNVIABywNFQwvUgYQIxoACThSDAYnWZbj01ICGjAWA0U2GxcAYhhUEyAeCgxiGhsIMR0NDSwNVCwFUgwGYhwVBilSEAEmHFpFBR1DJg0tVBAyF0MOMBwRSDUXGxxiHREWIgAKGDYQGwsyUgIbYgoAADEBTWJIPxgKNlIACTYcEwozGwYbeHNZRWMHEA0wVB4KNAANDTtbTkU0AQYabx8VBigcBEgkFRsSMlIPASkcVAkuFQoGblkHDCYcFhhuWRcNJBEIBzcNWEUyFwIaIRF+SGFQBwk2GFkVKAIGBCsXEUd7UiY8DlVUASAGAkgxABoGbVIGHicXAEUxAAwLJwoHDC8VT0gmGAAEYQYRCSwKEgozHwIcKxYab2xSQRs7CgAALFBZSCocFQk1GkMLKhwXDjJeQwswFhpFKx0BG25ZFwQiGgZINRgGCCgcBERiEBoRJAANCS5ZGQQoHBcNLBgaBiR4TkhgHREVLR0aBScXAEd7UiAhbTowSWEQFgEuHVQVKAIGBCsXERZtUhENLhwVFiRSExotGhEWMhcQYm9ZVgAzAAwabwsRBi4EBho7W05FMxcXGjtZGAomGwBEYh8VDC0dFQ0wVVQBJBMHSC4cABEkAEMZNxwBADJeQwsrCxcQKAZDCjAcFQ4kABBiSDA5NQ4gNykMLU5FFAEGSDYREUUEKiIrFlkXCiwCDAYnFwBFCDYQSCQLGwhhBgsNYhobCDEdDQ0sDQdFLRsQHGxZMRMkABpIJAsbCG4GDEgrF1QGLhwNDSENHQovAUMpDD1UADcXERFiGhsIMR0NDSwNVCwFUgoGYh8YCjZSEBwnCQdFLAcQHGILEQMkAAYGIRxUBGEEAgQrHVQGLh8TBywcGhFhOydIJAsbCGEGCw1iFR0WNVICCi0PEUthNgxIDDYgRSgcFQ0sDVQGLh8TBywcGhFhOycbYhYGRTQBBkgkCxEAbAYGEDZZEAAyEREBMg0dCi8BTWJIKxEWMR0NDGIOHREpUiwmDiBUBGE4MCcMWRsHKxcAHHhzD29hUkELLRcaACIGCgcsClZfYSlNRmwkWG9hUkEOLhYDFmNIQzM5WVYLIB8GSnhZVktvXEFEYlsQADIREQEyDR0KL1BZSGBXWktjXkNKIRgAACYdERFgQ1RHb1xNSm5ZVhY1FxMbYENUPm9cTTViBClvPA==");
4
+ registerPrompt("pipeline/component-identifier", "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");
5
+ registerPrompt("pipeline/connection-mapper", "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");
6
6
  registerPrompt("pipeline/flow-detector", "GB0WSCMLEUUgHEMNOgkRFzVSEAckDQMEMxdDCTAaHAw1FwAcbFk1CyAeGhInWQANJFITGi0TEQY1UgAHLA0RHTVSAgYmWR0BJBwXASQATm9LQ01IaFMREyQcFystFxoAIgYKBywKXk97UiYeJxcASCUACh4nF1QGLh8OHSwQFwQ1GwwGYgkVETUXEQYxWVwIJAEQCSUcVBQ0FxYNMVVUFTQQTBs3G1hFNhcBAC0WHxZtUgYeJxcARSQfChw2HAYWaFxpSGJZMgozUgYJIRFORTpSEx0gFR0WKRcRRGIKAQcyEREBIBwGSWERCwksFxEJbVIXDSERGgotHQQRYgR+RWFSTkgyDBYJKAELDTBWBxAjAQAaKxsRF3tSAAcvCRsLJBwXSAs9B0VpGQYKIxtZBiABBkgxFQECMltpSGJZWUUiGgIGLBwYX2EXFQ0sDVsRLgIKC20IAQA0F0MGIxQRb2FSQ0ViDREGKRwMBC0eDV9hBgsNYgoEACIbBQEhWQAAIhoNBy4WExxhBxANJllcAG8VTURiWxETJBwXRScUHRE1FxFKbllWEiQQCwctElZMS3hRRmJTXgQxGzEHNw0RFmtYWUgDKT1FMx0WHCcKWwAvFhMHKxcAFmEWBhwnGgAAJVIFGi0UVAYuFgZIMhgAESQADRtsc1RFYTQMGmIcFQYpSEMTYgkVESleQwUnDRwKJV5DACMXEAkkACUBLhxUGEt4IDoLLT0mAD5ZSA0XGBxhAAYYLQsARSQEBgY2WRcKLxwGCzYQGwsyUgIGJlkGCjQGBhtiDRwENVILCTQcVCYOPCA6By0xRQQkKiwHNzcgYRsNSDYREUUxAAweKx0RAWERDAwnWQcELAIPDTFVVBY1ExcBIVkHBiAcDQ0wWQYAMgcPHDFVVAozUicHIRIRF2EBBho0EBcAMlxDISRZAA0kUhAcIw0dBmEBAAksFxEXYQECETFZVisuUgYeJxcASCUACh4nF1QVIAYXDTAXB0UlFxcNIQ0RAWNeQxonDQEXL1IGBTINDUUkBAYGNjobCy8XABwrFhoWb1InB2I3OzFhGw0eJxcARTETFxwnCxoWYQYLCTZZFRckUg0HNlkREygWBgYhHBBFKBxDHCocVAwvAhYcbHN+NyQBEwcsHVQSKAYLSA03ODxhE0MiETY6RS4QCQ0hDU5vOnhDSGAcAgAvBiAHLBcRBjUbDAYxW05FGlxNRh9VfkVhUAIYKysbEDUXEEp4WS9Lb1w+Yj9zfiwnUg0HYgkVETUXEQYxWRIKNBwHRGILERE0AA1IJxQEEThSAhowGA0Wbw==");
7
- registerPrompt("pipeline/service-describer", "GB0WSCMLEUUgHEMNOgkRFzVSEAckDQMEMxdDCTAaHAw1FwAcbFk1CyAeGhInWQANJFITGi0TEQY1UgAHLA0RHTVSAgYmWR0BJBwXASQATm9LQ01IaFMEFy4YBgs2PREWIgAKGDYQGwtrWFlIA1kXCSQTEUhwVEdFMhcNHCcXFwBhFgYbIQsdFTUbDAZiFhJFNhoCHGINHAwyUhMaLRMRBjVSBwcnClpvc1xDQmgJBgwsExERDhgaAjQTBA1oU05FFRoGSC8YHQthAhEHJQsVCCwbDQ9iFRULJgcCDydZXABvFU1EYlsgHDEXMAswEAQRY15DShIAAA0uHEFEYlszCmNeQ0oQDAcRY1tNYnFXVE9rFgIcIxsVFiQBSUJ4WTAENRMBCTEcB0U0AQYMYhAaRTUaChtiCQYKKxcAHGxzQEthWEkNOg0RFy8TDzsnCwIMIhcQQmhDVCA5BgYaLBgYRTIXER4rGhEWbjMzITFZFwovARYFJx1UBzhSFwArClQVMx0JDSENWm9LNAwaYh0VESAQAhsnClQELxZDDToNERcvEw87JwsCDCIXEERiCQYKNxsHDXhzWUUoFllIKRwWBCNfAAkxHFQWLQcEYm9ZGgQsF1lIKgwZBC9fEQ0jHRUHLRdDBiMUEW9sUhcRMhxORTUXAAAsFhgKJgtDHDsJEUVpF00PbFVURzEdEBwlCxEWMB5BRGJbBgAlGxBKbllWFjUAChgnW11vbFIHDTEaBgwxBgoHLENUEikTF0grDVMWYQcQDSZZEgozeE5INwoRAQMLWUgjCwYEOFIMDmIaGwgxHQ0NLA1ULAUBQxwqGABFNAEGSDYRHRZhWhYbJ1kfACMTAUUhGAcAYQEPHSUKVAggBgAAKxcTRTUaBkghFhkVLhwGBjZZGgQsFxBBSHM3NwgmKisDNU5FDhwPEWIQGgYtBwcNYh0VESAQAhsnClQELxZDDToNERcvEw9IMRwGEygRBhtiDRwENVILCTQcVCYOPCA6By0xRQQkKiwHNzcgYRsNSDYREUUiHQcNIBgHAHt4TkgSGBcOIBUGRyYcBAAvFgYGIQBUDCwCDBo2ClRNJFwERm5ZVhUmUE9IYAsRASgBQURiWwcRMxsTDWBVVEcBExQbbwoQDm4RDwEnFwBIMkFBQUhUVCAvBAoaLRcZAC8GQx4jCx0EIx4GG2ILEQMkAAYGIRAaAmEGCw0vWVwAbxVNRGI9NTEAMCI7ByYhNw1eQzoHPT02HicxJG5ZJzETOzMtHSoxJhM3NzcJPC1MS19DLC0aHwAzUiAHLwkbFiRSEA0wDx0GJAFDHysNHEUsExcLKhAaAmEbDgklHAdvbFIgBywfHQI0AAIcKxYaRScbDw0xWQYAJxcRDSwaHQsmUhcAJxR+SGE2ChonGgBFNAECDydZHQthEQwMJ1kHBCwCDw0xWQQXLgQKDCcdfm8FHUMmDS1UAjQXEBtiFgZFKBwFDTBZBwAzBAoLJwpUESkTF0gvEBMNNVIBDWIMBwAnBw9GYj0bRQ89N0grFxcJNBYGSDEcBhMoEQYbYhMBFjVSAQ0hGAEWJFIXACdZBBcuGAYLNllWBi4HDwxgWQEWJFIXACcUWkUIFEMcKhwGAGEbEEgsFlQGLhwAGicNEUUkBAoMJxcXAG1SBwdiFxsRYRsNCy4MEABhGxdGSHMmADICDAYmWQMMNRpDJww1LUUgUik7DTdUCiMYBgs2WRkENRELASweVBEpGxBIMRocACwTWWI5c1RFYwIRBygcFxEFFxALMBAEESgdDUp4WVZLb1xBREhZVEcxAAoFIwsNKSAcBB0jHhFHe1JBRmxXVklLUkNKJhgABCMTEA0xW05FGlxNRh9VfkVhUAYQNhwGCyAeMA0wDx0GJAFBUmIiWktvL2kV");
8
- registerPrompt("pipeline/validator", "GB0WSCMLEUUgUhAHJA0DBDMXQwkwGhwMNRcAHDcLEUUzFxUBJw4RF29SNQkuEBAENRdDHCocVAQvEw8RMRAHRTMXEB0uDQdFIBwHSDEMEwIkARdIIRYGFyQRFwEtFwdLS3ggACcaH0UnHRFSSEhaRWtYLBoyERULYREMBTIWGgAvBhBCaENUJi4fEwcsHBoRMlIUATYRVB8kAAxIIRYaCyQRFwEtFwdFNRoCHGIKHAo0HgdIIBxUBi4cDQ0hDREBS0BNSGhTIxcuHARIIRYZFS4cBgY2WQAcMRcQQmhDVABvFU1EYhhUNyQTABxiGAQVYQYaGCcdVAQyUkEbJwsCDCIXQUgxERsQLRZDCidZVgMzHQ0cJxcQR0tBTUhoUzkMMgEKBiVZFwovHAYLNhAbCzJYSVJiNhYTKB0WG2ILEQkgBgoHLAocDDEBQwYtDVQGIAIXHTAcEG91XENCaC4RBCpSBw0xGgYMMQYKBywKXk97UiAHLwkbCyQcFxtiDh0RKVIGBTINDUUuAEMdLBoYACAAQwwnChcXKAIXAS0XB0Wj8vdIMgsbEygWBkggHAARJABDBywcB290XENCaD0BFS0bAAk2HFsXJBYWBiYYGhFhEQwFMhYaAC8GEEJoQ1QmLh8TBywcGhEyUhcAIw1UFikdFgQmWRYAYR8GGiUcEG9LIAYbMhYaAWEFChwqWTsrDStDCWIzJyoPUgwKKBwXEXt4GGJiWVYGLh8TBywcGhEVCxMNARYGFyQRFwEtFwdHe1IYSGAaGwgxHQ0NLA1ZDCVQWUhgGhsXMxcAHG8NDRUkUEMVbnNURWMRDAUyFhoALwYnDTEaBgwxBgoHLApWX2EJQ0ohFhkVLhwGBjZUHQFjSENKIBwAESQAQwwnChcXKAIXAS0XVkU8XmlIYlsVASUXBystFxoAIgYKBywKVl9hKRhIYB8GCixQWUhgEBBHbVJBHC1bTkVjGwdKbllWETgCBkp4WVYROAIGSm5ZVgEkAQAaKwkADC4cQVJiWxAAMhFBRGJbFRY4HABKeFkSBC0BBkg/JFhvYVJBGicUGxMkFiAHLBcRBjUbDAYJHA0WY0hDM2AfBgosSFkcLUNOETgCBkofVX5FYVAABywfHQEkHAANYENUVW9KVkRIWVRHKAEQHScKVl9hKUEMJwoXFygCFwEtF1QKJ1ICBjtZBgAsEwoGKxcTRSgBEB0nClY4Sw9pYhcKEUUkHxMcO1kbBysXABwxVhUXMxMaG2IQEkUvHUMLLQsGACIGCgcsClQLJBcHDSZXVDEpF0MLLRcSDCUXDQsnWQcGLgAGSGpJWVRoUhENJBURBjUBQxEtDAZFLgQGGiMVGEUiHQ0OKx0RCyIXQwEsWQANJFICBiMVDRYoAUMZNxgYDDULTQ==");
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 ?? "llama3.3",
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 ?? "llama3.3",
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
- ollamaBaseUrl?: string;
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>>): 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-4o-mini",
11
- standard: "gpt-4o",
10
+ fast: "gpt-5.2-codex",
11
+ standard: "gpt-5.2",
12
12
  advanced: "o3",
13
13
  },
14
14
  google: {
15
- fast: "gemini-2.0-flash",
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: "llama3.2",
21
- standard: "llama3.3",
22
- advanced: "llama3.3",
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
- const VENDORED = new Set([
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
- const SKIP_DIRS = new Set([
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 = /\/(node_modules|venv|\.venv|__pycache__|dist|build|\.git|vendor|target)\//;
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,3 @@
1
+ export declare const EXCLUDED_DIRS: Set<string>;
2
+ /** Regex version for filtering grep/file results by path segment */
3
+ export declare const EXCLUDED_DIRS_REGEX: RegExp;
@@ -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
- const SKIP_DIRS = new Set([
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 === "node_modules" ||
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
- // Skip hidden dirs, node_modules, dist, .git
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;
@@ -7,7 +7,8 @@ interface AnalyzeOptions {
7
7
  static?: boolean;
8
8
  skipLlm?: boolean;
9
9
  dryRun?: boolean;
10
- full?: boolean;
10
+ force?: boolean;
11
+ dir?: string;
11
12
  }
12
13
  export declare function handleAnalyze(options: AnalyzeOptions): Promise<void>;
13
14
  /**
@@ -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
- console.log(chalk.bold("Running static analysis (no model)..."));
44
- console.log();
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
- const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
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
- console.log(chalk.green(`Saved spec to: .archbyte/archbyte.yaml`));
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.full && isGitAvailable(rootDir) && priorMeta?.lastCommit) {
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 --full to force re-scan."));
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 --full to force."));
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
- console.log(chalk.bold("Phase 1: Collecting static context..."));
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
- const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
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
- console.log(chalk.gray(` Saved static context to: .archbyte/static-context.json`));
156
- console.log();
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
- const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
163
- console.log(chalk.gray(` [${elapsed}s] ${msg}`));
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
- console.log(chalk.green(`Saved spec to: .archbyte/archbyte.yaml`));
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
- const CONFIG_DIR = path.join(process.env.HOME ?? process.env.USERPROFILE ?? ".", ".archbyte");
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
- }, 60000);
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") {
@@ -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;