archbyte 0.2.2 → 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 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.2')
36
+ .version(PKG_VERSION)
31
37
  .addHelpText('after', `
32
38
  Quick start:
33
39
  $ archbyte login Sign in
@@ -73,11 +79,12 @@ 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')
82
89
  .option('--force', 'Force full re-scan (skip incremental detection)')
83
90
  .option('--dry-run', 'Preview without running')
@@ -89,9 +96,10 @@ program
89
96
  program
90
97
  .command('analyze')
91
98
  .description('Run AI-powered architecture analysis (BYOK - uses your model API key)')
99
+ .option('-d, --dir <path>', 'Project root directory (default: current directory)')
92
100
  .option('-o, --output <path>', 'Output analysis path (default: .archbyte/analysis.json)')
93
101
  .option('-v, --verbose', 'Show detailed output')
94
- .option('--provider <name>', 'Model provider: anthropic, openai, google, ollama')
102
+ .option('--provider <name>', 'Model provider: anthropic, openai, google')
95
103
  .option('--api-key <key>', 'Model API key (overrides config)')
96
104
  .option('--static', 'Static-only analysis (no model, free)')
97
105
  .option('--skip-llm', 'Alias for --static')
@@ -116,7 +124,7 @@ program
116
124
  program
117
125
  .command('serve')
118
126
  .description('Start the visualization UI server')
119
- .option('-p, --port <number>', 'Server port (default: 3847)', parseInt)
127
+ .option('-p, --port <number>', `Server port (default: ${DEFAULT_PORT})`, parseInt)
120
128
  .option('-d, --diagram <path>', 'Path to architecture JSON (default: .archbyte/architecture.json)')
121
129
  .action(async (options) => {
122
130
  await handleServe(options);
@@ -208,12 +216,26 @@ program
208
216
  .command('config')
209
217
  .description('Manage ArchByte configuration (provider, API key)')
210
218
  .argument('[action]', 'show, set, get, or path')
211
- .argument('[key]', 'config key (provider, api-key, ollama-url)')
219
+ .argument('[key]', 'config key (provider, api-key, model)')
212
220
  .argument('[value]', 'config value')
213
221
  .action(async (action, key, value) => {
214
222
  await handleConfig({ args: [action, key, value].filter(Boolean) });
215
223
  });
216
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
+
217
239
  // Default: show help
218
240
  program
219
241
  .action(() => {
@@ -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", "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");
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+SGE2ChonGgBFNAECDydZHQthEQwMJ1kHBCwCDw0xWQQXLgQKDCcdfm8FHUMmDS1UAjQXEBtiFgZFKBwFDTBZBwAzBAoLJwpUESkTF0gvEBMNNVIBDWIMBwAnBw9GYj0bRQ89N0grFxcJNBYGSDEcBhMoEQYbYhMBFjVSAQ0hGAEWJFIXACdZBBcuGAYLNllWBi4HDwxgWQEWJFIXACcUWkUIFEMcKhwGAGEbEEgsFlQGLhwAGicNEUUkBAoMJxcXAG1SBwdiFxsRYRsNCy4MEABhGxdGSHMmADICDAYmWQMMNRpDJww1LUUgUik7DTdUCiMYBgs2WRkENRELASweVBEpGxBIMRocACwTWWI5c1RFYwIRBygcFxEFFxALMBAEESgdDUp4WVZLb1xBREhZVEcxAAoFIwsNKSAcBB0jHhFHe1JBRmxXVklLUkNKJhgABCMTEA0xW05FGlxNRh9VfkVhUAYQNhwGCyAeMA0wDx0GJAFBUmIiWktvL2kV");
8
- registerPrompt("pipeline/validator", "GB0WSCMLEUUgUhAHJA0DBDMXQwkwGhwMNRcAHDcLEUUzFxUBJw4RF29SNQkuEBAENRdDHCocVAQvEw8RMRAHRTMXEB0uDQdFIBwHSDEMEwIkARdIIRYGFyQRFwEtFwdLS3ggACcaH0UnHRFSSEhaRWtYLBoyERULYREMBTIWGgAvBhBCaENUJi4fEwcsHBoRMlIUATYRVB8kAAxIIRYaCyQRFwEtFwdFNRoCHGIKHAo0HgdIIBxUBi4cDQ0hDREBS0BNSGhTIxcuHARIIRYZFS4cBgY2WQAcMRcQQmhDVABvFU1EYhhUNyQTABxiGAQVYQYaGCcdVAQyUkEbJwsCDCIXQUgxERsQLRZDCidZVgMzHQ0cJxcQR0tBTUhoUzkMMgEKBiVZFwovHAYLNhAbCzJYSVJiNhYTKB0WG2ILEQkgBgoHLAocDDEBQwYtDVQGIAIXHTAcEG91XENCaC4RBCpSBw0xGgYMMQYKBywKXk97UiAHLwkbCyQcFxtiDh0RKVIGBTINDUUuAEMdLBoYACAAQwwnChcXKAIXAS0XB0Wj8vdIMgsbEygWBkggHAARJABDBywcB290XENCaD0BFS0bAAk2HFsXJBYWBiYYGhFhEQwFMhYaAC8GEEJoQ1QmLh8TBywcGhEyUhcAIw1UFikdFgQmWRYAYR8GGiUcEG9LIAYbMhYaAWEFChwqWTsrDStDCWIzJyoPUgwKKBwXEXt4GGJiWVYGLh8TBywcGhEVCxMNARYGFyQRFwEtFwdHe1IYSGAaGwgxHQ0NLA1ZDCVQWUhgGhsXMxcAHG8NDRUkUEMVbnNURWMRDAUyFhoALwYnDTEaBgwxBgoHLApWX2EJQ0ohFhkVLhwGBjZUHQFjSENKIBwAESQAQwwnChcXKAIXAS0XVkU8XmlIYlsVASUXBystFxoAIgYKBywKVl9hKRhIYB8GCixQWUhgEBBHbVJBHC1bTkVjGwdKbllWETgCBkp4WVYROAIGSm5ZVgEkAQAaKwkADC4cQVJiWxAAMhFBRGJbFRY4HABKeFkSBC0BBkg/JFhvYVJBGicUGxMkFiAHLBcRBjUbDAYJHA0WY0hDM2AfBgosSFkcLUNOETgCBkofVX5FYVAABywfHQEkHAANYENUVW9KVkRIWVRHKAEQHScKVl9hKUEMJwoXFygCFwEtF1QKJ1ICBjtZBgAsEwoGKxcTRSgBEB0nClY4Sw9pYhcKEUUkHxMcO1kbBysXABwxVhUXMxMaG2IQEkUvHUMLLQsGACIGCgcsClQLJBcHDSZXVDEpF0MLLRcSDCUXDQsnWQcGLgAGSGpJWVRoUhENJBURBjUBQxEtDAZFLgQGGiMVGEUiHQ0OKx0RCyIXQwEsWQANJFICBiMVDRYoAUMZNxgYDDULTQ==");
7
+ registerPrompt("pipeline/service-describer", "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");
8
+ registerPrompt("pipeline/validator", "GB0WSCMLEUUgUhAHJA0DBDMXQwkwGhwMNRcAHDcLEUUzFxUBJw4RF29SNQkuEBAENRdDHCocVAQvEw8RMRAHRTMXEB0uDQdFIBwHSDEMEwIkARdIIRYGFyQRFwEtFwdLS3ggACcaH0UnHRFSSEhaRWtYNBotFxNFIh0OGC0XEQs1UhcRMhwHT2tIQw1sHlpJYRNDOicYFxFhExMYYg0NFSQWQwkxWVYWJAAVASEcVkUyGgwdLh1UByRSQQ4wFhoRJBwHSkhLWkVrWDQNIxJUASQBABorCQAMLhwQQmhDVCYuHxMHLBwaETJSFAE2EVQALAIXEWIWBkU0HAAEJxgGRSUXEAswEAQRKB0NG2Kb9PFhAhEHNBAQAGEQBhw2HAZFLhwGG0hKWkVrWDENJgwaASAcF0ghFhoLJBEXAS0XB09rSEMsNwkYDCITFw1iFgZFNBwNDSEcBxYgABpIIRYaCyQRFwEtFwdFNRoCHGIKHAo0HgdIIBxUFyQfDB4nHX5Rb1JJQhULGwsmUgAHLBcRBjUbDAZiDQ0VJAFJQnhZEUsmXE9IIxdUDCwCDBo2WRcKLxwGCzYQGwthBgsJNlkHDS4HDwxiGxFFYxoXHDJbfm8CICo8Czo1KWExLCYRLSYkCDw3O3hzWUUYHRZILxgNRQ48LzFiCxEDJAAGBiEcVAYuHxMHLBwaEWE7JxtiDRwENVICBDAcFQE4UgYQKwoARSgcQxwqHFQGLh8TBywcGhEyUg8BMQ1UBCMdFQ1sc1lFBR1DJg0tVAwvBAYGNlkaADZSAAcvCRsLJBwXG25ZEAQ1EwEJMRwHSWEdEUgnAQAAMxwCBGIKERc3GwANMVd+SGE2DEgMNiBFIBYHSCEWGgskERcBLRcHRTUdQwstFAQKLxcNHDFZAA0gBkMMLRdTEWEXGwExDVQML1IXACdZGAwyBk1ib1k7Cy0LQwkmHVQGLhwNDSENHQovAUMRLQxUBDMXQwArHhwJOFIABywfHQEkHBdIIxsbEDVSAQkxHBBFLhxDHCocVAYuHxMHLBwaEWECAhwqClhFNRcAACwWGAomGwYbblkVCyVSBhArCgAMLxVDCy0XGgAiBgoHLApab2xSMxonHxEXYQAGBS0PHQsmUgEJJlkXCi8cBgs2EBsLMlIMHicLVAQlFgoGJVkHFSQRFgQjDR0TJFIMBicKWm9sUioOYg0cAGETDQkuAAcMMlIPBy0SB0UzFwIbLRcVBy0XT0gwHAAQMxxDDS8JABxhEQwaMBwXESgdDRtsWTgAMgFDATFZGQozF01iSCsRFjEdDQxiDh0RKVIsJg4gVARhODAnDFkbBysXABx4cw9vYVJBCy0UBAovFw0cFgAEAAIdERonGgAMLhwQSnhZD0VjEQwFMhYaAC8GTgEmW05FYxEMGjAcFxFsBhoYJ1tUGG14Q0hgGhsIMR0NDSwNMAAyEREBMg0dCi8BQVJiAlRHIh0OGC0XEQs1XwoMYENURyMXFxwnC1QBJAEAGisJAAwuHEFIP1V+RWFQAgwmHBAmLhwNDSENHQovAUFSYiIPRWMUEQcvW05FYxsHSm5ZVhEuUFlIYBAQR21SQRw7CRFHHF5pSGJbFwovFAoMJxcXAGNIQ1hsQUFJS1JDSisKBxAkAUFSYiJWASQBABorCQAMLhxDByRZFQs4UhENLxgdCygcBEgrCgcQJAFBNUgEfm8UAQZIJxQEEThSDAooHBcRMl0CGjAYDRZhGwVILBZUBi4AEQ0hDR0KLwFDBiccEAAlXEM8KhxUBi4cBQEmHBoGJFIQCy0LEUVpQk5Za1kGACceBgs2ClQcLgcRSC0PERcgHg9IIRYaAygWBgYhHFQML1IXACdZFQsgHhobKwpUFDQTDwE2AFo=");
@@ -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
  }
@@ -98,12 +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;
104
108
  model?: string;
105
109
  modelOverrides?: Partial<Record<ModelTier, string>>;
106
- ollamaBaseUrl?: string;
110
+ profiles?: Record<string, ProviderProfile>;
107
111
  }
108
112
  export interface PipelineResult {
109
113
  agents: AgentResult[];
@@ -7,12 +7,12 @@ 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
  },
@@ -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;
@@ -8,6 +8,7 @@ interface AnalyzeOptions {
8
8
  skipLlm?: boolean;
9
9
  dryRun?: boolean;
10
10
  force?: boolean;
11
+ dir?: string;
11
12
  }
12
13
  export declare function handleAnalyze(options: AnalyzeOptions): Promise<void>;
13
14
  /**
@@ -8,7 +8,7 @@ import { staticResultToSpec, writeSpec, writeMetadata, loadSpec, loadMetadata }
8
8
  import { getChangedFiles, mapFilesToComponents, shouldRunAgents, isGitAvailable } from "./incremental.js";
9
9
  import { progressBar } from "./ui.js";
10
10
  export async function handleAnalyze(options) {
11
- const rootDir = process.cwd();
11
+ const rootDir = options.dir ? path.resolve(options.dir) : process.cwd();
12
12
  const isStaticOnly = options.static || options.skipLlm;
13
13
  console.log();
14
14
  console.log(chalk.bold.cyan("ArchByte Analyzer"));
@@ -73,7 +73,6 @@ export async function handleAnalyze(options) {
73
73
  config = {
74
74
  provider: options.provider,
75
75
  apiKey: options.apiKey ?? config?.apiKey ?? "",
76
- ollamaBaseUrl: config?.ollamaBaseUrl,
77
76
  };
78
77
  }
79
78
  if (options.apiKey && config) {
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;
@@ -1,9 +1,7 @@
1
1
  import * as fs from "fs";
2
- import * as path from "path";
3
2
  import chalk from "chalk";
4
- const CONFIG_DIR = path.join(process.env.HOME ?? process.env.USERPROFILE ?? ".", ".archbyte");
5
- const CONFIG_PATH = path.join(CONFIG_DIR, "config.json");
6
- const VALID_PROVIDERS = ["anthropic", "openai", "google", "ollama"];
3
+ import { CONFIG_DIR, CONFIG_PATH } from "./constants.js";
4
+ const VALID_PROVIDERS = ["anthropic", "openai", "google"];
7
5
  export async function handleConfig(options) {
8
6
  const [action, key, value] = options.args;
9
7
  if (!action || action === "show") {
@@ -13,7 +11,7 @@ export async function handleConfig(options) {
13
11
  if (action === "set") {
14
12
  if (!key || !value) {
15
13
  console.error(chalk.red("Usage: archbyte config set <key> <value>"));
16
- console.error(chalk.gray(" Keys: provider, api-key, ollama-url"));
14
+ console.error(chalk.gray(" Keys: provider, api-key, model"));
17
15
  process.exit(1);
18
16
  }
19
17
  setConfig(key, value);
@@ -57,75 +55,105 @@ function saveConfig(config) {
57
55
  }
58
56
  function showConfig() {
59
57
  const config = loadConfig();
58
+ const profiles = (config.profiles ?? {});
60
59
  console.log();
61
60
  console.log(chalk.bold.cyan("ArchByte Configuration"));
62
61
  console.log(chalk.gray(`Config file: ${CONFIG_PATH}`));
63
62
  console.log();
64
- if (!config.provider && !config.apiKey) {
65
- console.log(chalk.yellow("No configuration found. Set up with:"));
66
- console.log(chalk.gray(" archbyte config set provider anthropic"));
67
- console.log(chalk.gray(" archbyte config set api-key sk-ant-..."));
68
- console.log();
69
- console.log(chalk.gray("Or use environment variables:"));
70
- console.log(chalk.gray(" export ARCHBYTE_PROVIDER=anthropic"));
71
- console.log(chalk.gray(" export ARCHBYTE_API_KEY=sk-ant-..."));
63
+ const configured = Object.keys(profiles).filter((p) => profiles[p]?.apiKey);
64
+ if (!config.provider && !configured.length && !config.apiKey) {
65
+ console.log(chalk.yellow("No configuration found. Run:"));
66
+ console.log(chalk.gray(" archbyte init"));
72
67
  return;
73
68
  }
74
69
  console.log(` ${chalk.bold("provider")}: ${config.provider ?? chalk.gray("not set")}`);
75
- console.log(` ${chalk.bold("api-key")}: ${config.apiKey ? maskKey(config.apiKey) : chalk.gray("not set")}`);
76
- if (config.model) {
77
- console.log(` ${chalk.bold("model")}: ${config.model}`);
70
+ // Show profiles
71
+ if (configured.length > 0) {
72
+ console.log();
73
+ for (const name of configured) {
74
+ const p = profiles[name];
75
+ const active = name === config.provider ? chalk.green(" (active)") : "";
76
+ console.log(` ${chalk.bold(name)}${active}`);
77
+ console.log(` api-key: ${p.apiKey ? maskKey(p.apiKey) : chalk.gray("not set")}`);
78
+ if (p.model)
79
+ console.log(` model: ${p.model}`);
80
+ }
78
81
  }
79
- if (config.ollamaBaseUrl) {
80
- console.log(` ${chalk.bold("ollama-url")}: ${config.ollamaBaseUrl}`);
82
+ else if (config.apiKey) {
83
+ // Legacy flat config
84
+ console.log(` ${chalk.bold("api-key")}: ${maskKey(config.apiKey)}`);
85
+ if (config.model) {
86
+ console.log(` ${chalk.bold("model")}: ${config.model}`);
87
+ }
81
88
  }
82
89
  console.log();
83
90
  }
84
91
  function setConfig(key, value) {
85
92
  const config = loadConfig();
93
+ if (!config.profiles)
94
+ config.profiles = {};
95
+ const profiles = config.profiles;
86
96
  switch (key) {
87
97
  case "provider": {
88
98
  if (!VALID_PROVIDERS.includes(value)) {
89
99
  console.error(chalk.red(`Invalid provider: ${value}. Must be: ${VALID_PROVIDERS.join(", ")}`));
90
100
  process.exit(1);
91
101
  }
92
- const oldProvider = config.provider;
93
102
  config.provider = value;
94
- // Clear model override when switching providers model names are provider-specific
95
- if (oldProvider && oldProvider !== value && config.model) {
96
- delete config.model;
97
- console.log(chalk.yellow(`Cleared model override (was for ${oldProvider})`));
103
+ // Check if this provider has a stored profile
104
+ if (profiles[value]?.apiKey) {
105
+ console.log(chalk.green(`Switched to ${value} (credentials on file)`));
106
+ }
107
+ else {
108
+ console.log(chalk.yellow(`Switched to ${value} — run archbyte init to configure API key`));
98
109
  }
99
110
  break;
100
111
  }
101
112
  case "api-key":
102
113
  case "apiKey":
103
- case "key":
104
- config.apiKey = value;
114
+ case "key": {
115
+ const activeProvider = config.provider;
116
+ if (!activeProvider) {
117
+ console.error(chalk.red("Set a provider first: archbyte config set provider <name>"));
118
+ process.exit(1);
119
+ }
120
+ if (!profiles[activeProvider])
121
+ profiles[activeProvider] = {};
122
+ profiles[activeProvider].apiKey = value;
105
123
  break;
106
- case "model":
124
+ }
125
+ case "model": {
126
+ const activeProvider2 = config.provider;
127
+ if (!activeProvider2) {
128
+ console.error(chalk.red("Set a provider first: archbyte config set provider <name>"));
129
+ process.exit(1);
130
+ }
131
+ if (!profiles[activeProvider2])
132
+ profiles[activeProvider2] = {};
107
133
  if (value === "" || value === "default") {
108
- delete config.model;
134
+ delete profiles[activeProvider2].model;
109
135
  saveConfig(config);
110
136
  console.log(chalk.green("Cleared model override (will use provider defaults)"));
111
137
  return;
112
138
  }
113
- config.model = value;
114
- break;
115
- case "ollama-url":
116
- case "ollamaUrl":
117
- config.ollamaBaseUrl = value;
139
+ profiles[activeProvider2].model = value;
118
140
  break;
141
+ }
119
142
  default:
120
143
  console.error(chalk.red(`Unknown config key: ${key}`));
121
- console.error(chalk.gray(" Valid keys: provider, api-key, model, ollama-url"));
144
+ console.error(chalk.gray(" Valid keys: provider, api-key, model"));
122
145
  process.exit(1);
123
146
  }
124
147
  saveConfig(config);
125
- console.log(chalk.green(`Set ${key} = ${key.includes("key") ? maskKey(value) : value}`));
148
+ if (key !== "provider") {
149
+ console.log(chalk.green(`Set ${key} = ${key.includes("key") ? maskKey(value) : value}`));
150
+ }
126
151
  }
127
152
  function getConfig(key) {
128
153
  const config = loadConfig();
154
+ const profiles = (config.profiles ?? {});
155
+ const active = config.provider;
156
+ const profile = active ? profiles[active] : undefined;
129
157
  switch (key) {
130
158
  case "provider":
131
159
  console.log(config.provider ?? "");
@@ -133,14 +161,10 @@ function getConfig(key) {
133
161
  case "api-key":
134
162
  case "apiKey":
135
163
  case "key":
136
- console.log(config.apiKey ?? "");
164
+ console.log(profile?.apiKey ?? config.apiKey ?? "");
137
165
  break;
138
166
  case "model":
139
- console.log(config.model ?? "");
140
- break;
141
- case "ollama-url":
142
- case "ollamaUrl":
143
- console.log(config.ollamaBaseUrl ?? "");
167
+ console.log(profile?.model ?? config.model ?? "");
144
168
  break;
145
169
  default:
146
170
  console.error(chalk.red(`Unknown config key: ${key}`));
@@ -154,12 +178,21 @@ function maskKey(key) {
154
178
  }
155
179
  /**
156
180
  * Resolve the full ArchByteConfig from config file + env vars.
181
+ * Supports profiles (new) and legacy flat config (backward compat).
157
182
  * Env vars override config file.
158
183
  */
159
184
  export function resolveConfig() {
160
185
  const config = loadConfig();
161
186
  const provider = process.env.ARCHBYTE_PROVIDER ?? config.provider;
162
- const apiKey = process.env.ARCHBYTE_API_KEY ?? config.apiKey;
187
+ // Reject unknown providers (e.g. legacy "ollama")
188
+ if (provider && !VALID_PROVIDERS.includes(provider)) {
189
+ return null;
190
+ }
191
+ // Resolve API key + model from profiles first, then legacy flat keys
192
+ const profiles = (config.profiles ?? {});
193
+ const profile = provider ? profiles[provider] : undefined;
194
+ const apiKey = process.env.ARCHBYTE_API_KEY ?? profile?.apiKey ?? config.apiKey;
195
+ const model = process.env.ARCHBYTE_MODEL ?? profile?.model ?? config.model;
163
196
  // Auto-detect from known env vars if nothing explicit
164
197
  if (!provider && !apiKey) {
165
198
  if (process.env.ANTHROPIC_API_KEY) {
@@ -176,25 +209,11 @@ export function resolveConfig() {
176
209
  }
177
210
  return null;
178
211
  }
179
- if (!provider)
180
- return null;
181
- // Ollama doesn't need an API key
182
- if (provider === "ollama") {
183
- return {
184
- provider: "ollama",
185
- apiKey: "",
186
- model: process.env.ARCHBYTE_MODEL ?? config.model,
187
- ollamaBaseUrl: process.env.OLLAMA_BASE_URL ??
188
- config.ollamaBaseUrl ??
189
- "http://localhost:11434",
190
- };
191
- }
192
- if (!apiKey)
212
+ if (!provider || !apiKey)
193
213
  return null;
194
214
  return {
195
215
  provider,
196
216
  apiKey,
197
- model: process.env.ARCHBYTE_MODEL ?? config.model,
198
- ollamaBaseUrl: config.ollamaBaseUrl,
217
+ model: model,
199
218
  };
200
219
  }
@@ -0,0 +1,13 @@
1
+ export declare const API_BASE: string;
2
+ export declare const SITE_URL = "https://archbyte.heartbyte.io";
3
+ export declare const DEFAULT_PORT = 3847;
4
+ export declare const CLI_CALLBACK_PORT = 19274;
5
+ export declare const CONFIG_DIR: string;
6
+ export declare const CONFIG_PATH: string;
7
+ export declare const CREDENTIALS_PATH: string;
8
+ /** Project-local .archbyte directory name */
9
+ export declare const PROJECT_DIR = ".archbyte";
10
+ /** Timeout for non-critical network checks (license, version, gate) */
11
+ export declare const NETWORK_TIMEOUT_MS = 5000;
12
+ /** Timeout for OAuth callback server */
13
+ export declare const OAUTH_TIMEOUT_MS = 60000;