4runr-os 2.1.14 → 2.1.18

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 (103) hide show
  1. package/dist/config.d.ts +43 -0
  2. package/dist/config.d.ts.map +1 -0
  3. package/dist/config.js +91 -0
  4. package/dist/config.js.map +1 -0
  5. package/dist/index.js +239 -142
  6. package/dist/index.js.map +1 -1
  7. package/dist/version-check.d.ts +30 -0
  8. package/dist/version-check.d.ts.map +1 -0
  9. package/dist/version-check.js +168 -0
  10. package/dist/version-check.js.map +1 -0
  11. package/package.json +5 -2
  12. package/dist/tui_mk1/core/eventBus.d.ts +0 -28
  13. package/dist/tui_mk1/core/eventBus.d.ts.map +0 -1
  14. package/dist/tui_mk1/core/eventBus.js +0 -52
  15. package/dist/tui_mk1/core/eventBus.js.map +0 -1
  16. package/dist/tui_mk1/core/feedStore.d.ts +0 -31
  17. package/dist/tui_mk1/core/feedStore.d.ts.map +0 -1
  18. package/dist/tui_mk1/core/feedStore.js +0 -51
  19. package/dist/tui_mk1/core/feedStore.js.map +0 -1
  20. package/dist/tui_mk1/kernel.d.ts +0 -32
  21. package/dist/tui_mk1/kernel.d.ts.map +0 -1
  22. package/dist/tui_mk1/kernel.js +0 -220
  23. package/dist/tui_mk1/kernel.js.map +0 -1
  24. package/dist/tui_mk1/layout/layoutEngine.d.ts +0 -47
  25. package/dist/tui_mk1/layout/layoutEngine.d.ts.map +0 -1
  26. package/dist/tui_mk1/layout/layoutEngine.js +0 -551
  27. package/dist/tui_mk1/layout/layoutEngine.js.map +0 -1
  28. package/dist/tui_mk1/log.d.ts +0 -23
  29. package/dist/tui_mk1/log.d.ts.map +0 -1
  30. package/dist/tui_mk1/log.js +0 -125
  31. package/dist/tui_mk1/log.js.map +0 -1
  32. package/dist/tui_mk1/logger.d.ts +0 -11
  33. package/dist/tui_mk1/logger.d.ts.map +0 -1
  34. package/dist/tui_mk1/logger.js +0 -96
  35. package/dist/tui_mk1/logger.js.map +0 -1
  36. package/dist/tui_mk1/mk1App.d.ts +0 -47
  37. package/dist/tui_mk1/mk1App.d.ts.map +0 -1
  38. package/dist/tui_mk1/mk1App.js +0 -492
  39. package/dist/tui_mk1/mk1App.js.map +0 -1
  40. package/dist/tui_mk1/resizeController.d.ts +0 -39
  41. package/dist/tui_mk1/resizeController.d.ts.map +0 -1
  42. package/dist/tui_mk1/resizeController.js +0 -122
  43. package/dist/tui_mk1/resizeController.js.map +0 -1
  44. package/dist/tui_mk1/stdoutGuard.d.ts +0 -15
  45. package/dist/tui_mk1/stdoutGuard.d.ts.map +0 -1
  46. package/dist/tui_mk1/stdoutGuard.js +0 -73
  47. package/dist/tui_mk1/stdoutGuard.js.map +0 -1
  48. package/dist/tui_mk1/terminalRestore.d.ts +0 -22
  49. package/dist/tui_mk1/terminalRestore.d.ts.map +0 -1
  50. package/dist/tui_mk1/terminalRestore.js +0 -96
  51. package/dist/tui_mk1/terminalRestore.js.map +0 -1
  52. package/dist/tui_mk1/ui/debugGutter.d.ts +0 -7
  53. package/dist/tui_mk1/ui/debugGutter.d.ts.map +0 -1
  54. package/dist/tui_mk1/ui/debugGutter.js +0 -60
  55. package/dist/tui_mk1/ui/debugGutter.js.map +0 -1
  56. package/dist/tui_mk1/ui/offenderScanner.d.ts +0 -31
  57. package/dist/tui_mk1/ui/offenderScanner.d.ts.map +0 -1
  58. package/dist/tui_mk1/ui/offenderScanner.js +0 -80
  59. package/dist/tui_mk1/ui/offenderScanner.js.map +0 -1
  60. package/dist/tui_mk1/ui/safe.d.ts +0 -9
  61. package/dist/tui_mk1/ui/safe.d.ts.map +0 -1
  62. package/dist/tui_mk1/ui/safe.js +0 -29
  63. package/dist/tui_mk1/ui/safe.js.map +0 -1
  64. package/dist/tui_mk1/ui/safeText.d.ts +0 -22
  65. package/dist/tui_mk1/ui/safeText.d.ts.map +0 -1
  66. package/dist/tui_mk1/ui/safeText.js +0 -50
  67. package/dist/tui_mk1/ui/safeText.js.map +0 -1
  68. package/dist/tui_mk1/ui/uiBuilder.d.ts +0 -44
  69. package/dist/tui_mk1/ui/uiBuilder.d.ts.map +0 -1
  70. package/dist/tui_mk1/ui/uiBuilder.js +0 -467
  71. package/dist/tui_mk1/ui/uiBuilder.js.map +0 -1
  72. package/dist/tui_mk1/viewport/safeViewport.d.ts +0 -28
  73. package/dist/tui_mk1/viewport/safeViewport.d.ts.map +0 -1
  74. package/dist/tui_mk1/viewport/safeViewport.js +0 -71
  75. package/dist/tui_mk1/viewport/safeViewport.js.map +0 -1
  76. package/dist/tui_mk2/debug/overlay.d.ts +0 -14
  77. package/dist/tui_mk2/debug/overlay.d.ts.map +0 -1
  78. package/dist/tui_mk2/debug/overlay.js +0 -38
  79. package/dist/tui_mk2/debug/overlay.js.map +0 -1
  80. package/dist/tui_mk2/kernel.d.ts +0 -28
  81. package/dist/tui_mk2/kernel.d.ts.map +0 -1
  82. package/dist/tui_mk2/kernel.js +0 -138
  83. package/dist/tui_mk2/kernel.js.map +0 -1
  84. package/dist/tui_mk2/layout/applyLayout.d.ts +0 -18
  85. package/dist/tui_mk2/layout/applyLayout.d.ts.map +0 -1
  86. package/dist/tui_mk2/layout/applyLayout.js +0 -66
  87. package/dist/tui_mk2/layout/applyLayout.js.map +0 -1
  88. package/dist/tui_mk2/layout/computeLayout.d.ts +0 -71
  89. package/dist/tui_mk2/layout/computeLayout.d.ts.map +0 -1
  90. package/dist/tui_mk2/layout/computeLayout.js +0 -255
  91. package/dist/tui_mk2/layout/computeLayout.js.map +0 -1
  92. package/dist/tui_mk2/layout/invariants.d.ts +0 -21
  93. package/dist/tui_mk2/layout/invariants.d.ts.map +0 -1
  94. package/dist/tui_mk2/layout/invariants.js +0 -34
  95. package/dist/tui_mk2/layout/invariants.js.map +0 -1
  96. package/dist/tui_mk2/layout/layoutEngine.d.ts +0 -70
  97. package/dist/tui_mk2/layout/layoutEngine.d.ts.map +0 -1
  98. package/dist/tui_mk2/layout/layoutEngine.js +0 -297
  99. package/dist/tui_mk2/layout/layoutEngine.js.map +0 -1
  100. package/dist/tui_mk2/mk2App.d.ts +0 -51
  101. package/dist/tui_mk2/mk2App.d.ts.map +0 -1
  102. package/dist/tui_mk2/mk2App.js +0 -297
  103. package/dist/tui_mk2/mk2App.js.map +0 -1
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Configuration management for 4runr-os
3
+ * Stores settings in ~/.4runr/config.json
4
+ */
5
+ interface Config {
6
+ autoUpdate?: boolean;
7
+ updateCheck?: boolean;
8
+ [key: string]: any;
9
+ }
10
+ /**
11
+ * Load config from file
12
+ */
13
+ export declare function loadConfig(): Config;
14
+ /**
15
+ * Save config to file
16
+ */
17
+ export declare function saveConfig(config: Config): void;
18
+ /**
19
+ * Get a config value
20
+ */
21
+ export declare function getConfig(key: string): any;
22
+ /**
23
+ * Set a config value
24
+ */
25
+ export declare function setConfig(key: string, value: any): void;
26
+ /**
27
+ * Check if auto-update is enabled
28
+ */
29
+ export declare function isAutoUpdateEnabled(): boolean;
30
+ /**
31
+ * Check if update check is enabled
32
+ */
33
+ export declare function isUpdateCheckEnabled(): boolean;
34
+ /**
35
+ * Set auto-update enabled/disabled
36
+ */
37
+ export declare function setAutoUpdate(enabled: boolean): void;
38
+ /**
39
+ * Set update check enabled/disabled
40
+ */
41
+ export declare function setUpdateCheck(enabled: boolean): void;
42
+ export {};
43
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,UAAU,MAAM;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAgBD;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAcnC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAS/C;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAG1C;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAIvD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAErD"}
package/dist/config.js ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Configuration management for 4runr-os
3
+ * Stores settings in ~/.4runr/config.json
4
+ */
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+ import * as os from 'os';
8
+ const CONFIG_DIR = path.join(os.homedir(), '.4runr');
9
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
10
+ const DEFAULT_CONFIG = {
11
+ autoUpdate: true,
12
+ updateCheck: true,
13
+ };
14
+ /**
15
+ * Ensure config directory exists
16
+ */
17
+ function ensureConfigDir() {
18
+ if (!fs.existsSync(CONFIG_DIR)) {
19
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
20
+ }
21
+ }
22
+ /**
23
+ * Load config from file
24
+ */
25
+ export function loadConfig() {
26
+ ensureConfigDir();
27
+ if (!fs.existsSync(CONFIG_FILE)) {
28
+ return { ...DEFAULT_CONFIG };
29
+ }
30
+ try {
31
+ const content = fs.readFileSync(CONFIG_FILE, 'utf-8');
32
+ const config = JSON.parse(content);
33
+ return { ...DEFAULT_CONFIG, ...config };
34
+ }
35
+ catch {
36
+ return { ...DEFAULT_CONFIG };
37
+ }
38
+ }
39
+ /**
40
+ * Save config to file
41
+ */
42
+ export function saveConfig(config) {
43
+ ensureConfigDir();
44
+ try {
45
+ const merged = { ...DEFAULT_CONFIG, ...loadConfig(), ...config };
46
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), 'utf-8');
47
+ }
48
+ catch (error) {
49
+ throw new Error(`Failed to save config: ${error}`);
50
+ }
51
+ }
52
+ /**
53
+ * Get a config value
54
+ */
55
+ export function getConfig(key) {
56
+ const config = loadConfig();
57
+ return config[key];
58
+ }
59
+ /**
60
+ * Set a config value
61
+ */
62
+ export function setConfig(key, value) {
63
+ const config = loadConfig();
64
+ config[key] = value;
65
+ saveConfig(config);
66
+ }
67
+ /**
68
+ * Check if auto-update is enabled
69
+ */
70
+ export function isAutoUpdateEnabled() {
71
+ return getConfig('autoUpdate') !== false;
72
+ }
73
+ /**
74
+ * Check if update check is enabled
75
+ */
76
+ export function isUpdateCheckEnabled() {
77
+ return getConfig('updateCheck') !== false;
78
+ }
79
+ /**
80
+ * Set auto-update enabled/disabled
81
+ */
82
+ export function setAutoUpdate(enabled) {
83
+ setConfig('autoUpdate', enabled);
84
+ }
85
+ /**
86
+ * Set update check enabled/disabled
87
+ */
88
+ export function setUpdateCheck(enabled) {
89
+ setConfig('updateCheck', enabled);
90
+ }
91
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACrD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAQzD,MAAM,cAAc,GAAW;IAC7B,UAAU,EAAE,IAAI;IAChB,WAAW,EAAE,IAAI;CAClB,CAAC;AAEF;;GAEG;AACH,SAAS,eAAe;IACtB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,eAAe,EAAE,CAAC;IAElB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,eAAe,EAAE,CAAC;IAElB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,UAAU,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC;QACjE,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,KAAU;IAC/C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACpB,UAAU,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,SAAS,CAAC,YAAY,CAAC,KAAK,KAAK,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,SAAS,CAAC,aAAa,CAAC,KAAK,KAAK,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AACpC,CAAC"}
package/dist/index.js CHANGED
@@ -7,6 +7,9 @@ import * as readline from 'readline';
7
7
  import * as fs from 'fs';
8
8
  import * as path from 'path';
9
9
  import * as os from 'os';
10
+ import { spawn } from 'child_process';
11
+ import { fileURLToPath } from 'url';
12
+ import { dirname } from 'path';
10
13
  import { GatewayClient } from './gateway-client.js';
11
14
  import { executeLocalModel, verifyLocalModelServer } from './local-model-executor.js';
12
15
  import { checkOllamaInstallation, installOllama, startOllamaServer, downloadModel, verifyLocalExecution } from './local-setup.js';
@@ -512,84 +515,119 @@ const commands = {
512
515
  }
513
516
  },
514
517
  config: {
515
- description: 'Configure AI provider (OpenAI/Anthropic)',
516
- usage: 'config',
518
+ description: 'Configure settings and AI provider',
519
+ usage: 'config [auto-update|provider] [enable|disable]',
517
520
  handler: async (args, rl) => {
518
- console.log(`\n${bright}AI Provider Configuration${reset}\n`);
519
- // Choose provider
520
- console.log(`${gray}Available providers:${reset}`);
521
- console.log(` 1. OpenAI (GPT-4, GPT-3.5)`);
522
- console.log(` 2. Anthropic (Claude)`);
523
- const providerChoice = await prompt(rl, `\n${cyan}Select provider (1 or 2):${reset} `);
524
- if (providerChoice !== '1' && providerChoice !== '2') {
525
- console.log(`${red}Invalid choice${reset}\n`);
526
- return;
527
- }
528
- const provider = providerChoice === '1' ? 'openai' : 'anthropic';
529
- aiConfig.provider = provider;
530
- // Get API key
531
- const apiKey = await prompt(rl, `${cyan}Enter your ${provider.toUpperCase()} API key:${reset} `);
532
- if (!apiKey) {
533
- console.log(`${red}API key required${reset}\n`);
521
+ // Handle settings subcommands
522
+ if (args[0] === 'auto-update') {
523
+ const { setAutoUpdate, isAutoUpdateEnabled } = await import('./config.js');
524
+ const action = args[1];
525
+ if (action === 'enable') {
526
+ setAutoUpdate(true);
527
+ console.log(`${green}✓${reset} Auto-update enabled\n`);
528
+ }
529
+ else if (action === 'disable') {
530
+ setAutoUpdate(false);
531
+ console.log(`${green}✓${reset} Auto-update disabled\n`);
532
+ }
533
+ else if (action === 'status' || !action) {
534
+ const enabled = isAutoUpdateEnabled();
535
+ const statusText = enabled ? `${green}Enabled${reset}` : `${yellow}Disabled${reset}`;
536
+ console.log(`\n${bright}Auto-Update:${reset} ${statusText}\n`);
537
+ console.log(`${gray}Usage:${reset}`);
538
+ console.log(` ${cyan}config auto-update enable${reset} - Enable automatic updates`);
539
+ console.log(` ${cyan}config auto-update disable${reset} - Disable automatic updates\n`);
540
+ }
541
+ else {
542
+ console.log(`${red}Invalid action: ${action}${reset}\n`);
543
+ console.log(`${gray}Usage: config auto-update [enable|disable|status]${reset}\n`);
544
+ }
534
545
  return;
535
546
  }
536
- aiConfig.apiKey = apiKey;
537
- // Store credentials on server
538
- console.log(`\n${gray}Storing credentials securely...${reset}`);
539
- try {
540
- const response = await fetch(`${gatewayUrl}/api/ai-providers/credentials`, {
541
- method: 'POST',
542
- headers: { 'Content-Type': 'application/json' },
543
- body: JSON.stringify({ provider, apiKey })
544
- });
545
- if (response.ok) {
546
- console.log(`${green}✓${reset} Credentials stored securely (AES-256-GCM encrypted)\n`);
547
- // Choose model
548
- console.log(`${gray}Available models for ${provider}:${reset}`);
549
- if (provider === 'openai') {
550
- console.log(` 1. gpt-4 (Most capable)`);
551
- console.log(` 2. gpt-4-turbo (Faster, cheaper)`);
552
- console.log(` 3. gpt-3.5-turbo (Fast, economical)`);
553
- }
554
- else {
555
- console.log(` 1. claude-3-opus-20240229 (Most capable)`);
556
- console.log(` 2. claude-3-sonnet-20240229 (Balanced)`);
557
- console.log(` 3. claude-3-haiku-20240307 (Fast, economical)`);
558
- }
559
- const modelChoice = await prompt(rl, `\n${cyan}Select model (1-3):${reset} `);
560
- const models = provider === 'openai'
561
- ? ['gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo']
562
- : ['claude-3-opus-20240229', 'claude-3-sonnet-20240229', 'claude-3-haiku-20240307'];
563
- const modelIndex = parseInt(modelChoice) - 1;
564
- if (modelIndex >= 0 && modelIndex < 3) {
565
- aiConfig.model = models[modelIndex];
566
- console.log(`${green}✓${reset} Model set to: ${bright}${aiConfig.model}${reset}\n`);
567
- // Test connection
568
- console.log(`${gray}Testing connection...${reset}`);
569
- const testResponse = await fetch(`${gatewayUrl}/api/ai-providers/test`, {
570
- method: 'POST',
571
- headers: { 'Content-Type': 'application/json' },
572
- body: JSON.stringify({ provider, model: aiConfig.model })
573
- });
574
- if (testResponse.ok) {
575
- console.log(`${green}✓${reset} Connection successful! You're ready to build agents.\n`);
547
+ // Original AI provider configuration
548
+ if (args[0] === 'provider' || (!args[0] || args[0] === '')) {
549
+ console.log(`\n${bright}AI Provider Configuration${reset}\n`);
550
+ // Choose provider
551
+ console.log(`${gray}Available providers:${reset}`);
552
+ console.log(` 1. OpenAI (GPT-4, GPT-3.5)`);
553
+ console.log(` 2. Anthropic (Claude)`);
554
+ const providerChoice = await prompt(rl, `\n${cyan}Select provider (1 or 2):${reset} `);
555
+ if (providerChoice !== '1' && providerChoice !== '2') {
556
+ console.log(`${red}Invalid choice${reset}\n`);
557
+ return;
558
+ }
559
+ const provider = providerChoice === '1' ? 'openai' : 'anthropic';
560
+ aiConfig.provider = provider;
561
+ // Get API key
562
+ const apiKey = await prompt(rl, `${cyan}Enter your ${provider.toUpperCase()} API key:${reset} `);
563
+ if (!apiKey) {
564
+ console.log(`${red}API key required${reset}\n`);
565
+ return;
566
+ }
567
+ aiConfig.apiKey = apiKey;
568
+ // Store credentials on server
569
+ console.log(`\n${gray}Storing credentials securely...${reset}`);
570
+ try {
571
+ const response = await fetch(`${gatewayUrl}/api/ai-providers/credentials`, {
572
+ method: 'POST',
573
+ headers: { 'Content-Type': 'application/json' },
574
+ body: JSON.stringify({ provider, apiKey })
575
+ });
576
+ if (response.ok) {
577
+ console.log(`${green}✓${reset} Credentials stored securely (AES-256-GCM encrypted)\n`);
578
+ // Choose model
579
+ console.log(`${gray}Available models for ${provider}:${reset}`);
580
+ if (provider === 'openai') {
581
+ console.log(` 1. gpt-4 (Most capable)`);
582
+ console.log(` 2. gpt-4-turbo (Faster, cheaper)`);
583
+ console.log(` 3. gpt-3.5-turbo (Fast, economical)`);
576
584
  }
577
585
  else {
578
- const error = await testResponse.json();
579
- console.log(`${yellow}⚠${reset} Warning: ${error?.message || 'Unknown error'}\n`);
586
+ console.log(` 1. claude-3-opus-20240229 (Most capable)`);
587
+ console.log(` 2. claude-3-sonnet-20240229 (Balanced)`);
588
+ console.log(` 3. claude-3-haiku-20240307 (Fast, economical)`);
589
+ }
590
+ const modelChoice = await prompt(rl, `\n${cyan}Select model (1-3):${reset} `);
591
+ const models = provider === 'openai'
592
+ ? ['gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo']
593
+ : ['claude-3-opus-20240229', 'claude-3-sonnet-20240229', 'claude-3-haiku-20240307'];
594
+ const modelIndex = parseInt(modelChoice) - 1;
595
+ if (modelIndex >= 0 && modelIndex < 3) {
596
+ aiConfig.model = models[modelIndex];
597
+ console.log(`${green}✓${reset} Model set to: ${bright}${aiConfig.model}${reset}\n`);
598
+ // Test connection
599
+ console.log(`${gray}Testing connection...${reset}`);
600
+ const testResponse = await fetch(`${gatewayUrl}/api/ai-providers/test`, {
601
+ method: 'POST',
602
+ headers: { 'Content-Type': 'application/json' },
603
+ body: JSON.stringify({ provider, model: aiConfig.model })
604
+ });
605
+ if (testResponse.ok) {
606
+ console.log(`${green}✓${reset} Connection successful! You're ready to build agents.\n`);
607
+ }
608
+ else {
609
+ const error = await testResponse.json();
610
+ console.log(`${yellow}⚠${reset} Warning: ${error?.message || 'Unknown error'}\n`);
611
+ }
612
+ }
613
+ else {
614
+ console.log(`${red}Invalid model choice${reset}\n`);
580
615
  }
581
616
  }
582
617
  else {
583
- console.log(`${red}Invalid model choice${reset}\n`);
618
+ const error = await response.json();
619
+ console.log(`${red}✗${reset} Failed to store credentials: ${error?.message || 'Unknown error'}\n`);
584
620
  }
585
621
  }
586
- else {
587
- const error = await response.json();
588
- console.log(`${red}✗${reset} Failed to store credentials: ${error?.message || 'Unknown error'}\n`);
622
+ catch (error) {
623
+ console.log(`${red}✗${reset} Error: ${error?.message || 'Unknown error'}\n`);
589
624
  }
590
625
  }
591
- catch (error) {
592
- console.log(`${red}✗${reset} Error: ${error?.message || 'Unknown error'}\n`);
626
+ else {
627
+ console.log(`\n${bright}Configuration${reset}\n`);
628
+ console.log(`${gray}Available settings:${reset}`);
629
+ console.log(` ${cyan}config auto-update${reset} - Manage automatic updates`);
630
+ console.log(` ${cyan}config provider${reset} - Configure AI provider\n`);
593
631
  }
594
632
  }
595
633
  },
@@ -2377,65 +2415,49 @@ process.on('SIGTERM', () => {
2377
2415
  stopAllAnimations();
2378
2416
  process.exit(0);
2379
2417
  });
2380
- // Start the OS
2381
- async function main() {
2382
- // Phase 1: Check for NO_TUI mode
2383
- const noTui = process.env.NO_TUI === '1';
2384
- if (noTui) {
2385
- // NO_TUI mode: text-based hub
2386
- const { buildUiState } = await import('./state/uiStateBuilder.js');
2387
- // Load custom agents on startup
2388
- loadCustomAgents();
2389
- // Build UI state
2390
- syncStateToStore();
2391
- const state = getState();
2392
- updateAppState({
2393
- customAgents: customAgents,
2394
- runHistory: runHistory,
2395
- });
2396
- // Old TUI code removed - use 4runr-ui package instead
2397
- console.log('\n⚠️ Old TUI has been removed.');
2398
- console.log(' Use the new 4runr-ui package instead:');
2399
- console.log(' npm install -g 4runr-ui');
2400
- console.log(' 4r\n');
2401
- process.exit(0);
2402
- }
2403
- else {
2404
- // TUI mode: Use V3 Terminal UI
2418
+ // main() function removed - all routing now at top level
2419
+ // FIXED: Unified routing - MK3 (Rust TUI) is default, MK1/MK2 require explicit opt-in
2420
+ // Priority: TUI_MK1=1 > TUI_MK2=1 > NO_TUI > default to MK3
2421
+ if (process.env.TUI_MK1 === '1') {
2422
+ // MK1 TUI mode - explicit opt-in via TUI_MK1=1
2423
+ process.stderr.write('[DEBUG] Starting MK1 TUI (explicit opt-in)...\n');
2424
+ (async () => {
2405
2425
  try {
2406
- // Load custom agents on startup
2407
- loadCustomAgents();
2408
- // Sync state
2409
- syncStateToStore();
2410
- const state = getState();
2411
- updateAppState({
2412
- customAgents: customAgents,
2413
- runHistory: runHistory,
2414
- });
2415
- // Old TUI code removed - use 4runr-ui package instead
2416
- console.log('\n⚠️ Old TUI (V3/V4/V5) has been removed.');
2417
- console.log(' Use the new 4runr-ui package instead:');
2418
- console.log(' npm install -g 4runr-ui');
2419
- console.log(' 4r\n');
2420
- console.log(' Or run from source:');
2421
- console.log(' cd packages/4runr-ui && node dist/index.js\n');
2422
- process.exit(0);
2426
+ // @ts-ignore - Dynamic import, file exists at runtime
2427
+ const { startMK1 } = await import('./tui_mk1/mk1App.js');
2428
+ await startMK1();
2429
+ }
2430
+ catch (error) {
2431
+ const errorMsg = error.message || String(error);
2432
+ process.stderr.write(`\n[ERROR] Failed to start MK1 TUI: ${errorMsg}\n`);
2433
+ process.exit(1);
2434
+ }
2435
+ })();
2436
+ }
2437
+ else if (process.env.TUI_MK2 === '1') {
2438
+ // MK2 TUI mode - explicit opt-in via TUI_MK2=1
2439
+ process.stderr.write('[DEBUG] Starting MK2 TUI (explicit opt-in)...\n');
2440
+ (async () => {
2441
+ try {
2442
+ process.stderr.write('[DEBUG] Importing mk2App.js...\n');
2443
+ // @ts-ignore - Dynamic import, file exists at runtime
2444
+ const { startMK2 } = await import('./tui_mk2/mk2App.js');
2445
+ process.stderr.write('[DEBUG] Calling startMK2()...\n');
2446
+ await startMK2();
2447
+ process.stderr.write('[DEBUG] MK2 started successfully\n');
2423
2448
  }
2424
2449
  catch (error) {
2425
- // Only show errors if TUI failed to initialize
2426
2450
  const errorMsg = error.message || String(error);
2427
2451
  const errorStack = error.stack || '';
2428
- // Write to stderr before TUI log gate might interfere
2429
- process.stderr.write(`\nFailed to initialize TUI: ${errorMsg}\n${errorStack}\n\n`);
2430
- process.stderr.write(`To exit if screen is black: Press Ctrl+C or type 'q'\n`);
2452
+ process.stderr.write(`\n[ERROR] Failed to start MK2 TUI: ${errorMsg}\n${errorStack}\n`);
2431
2453
  process.exit(1);
2432
2454
  }
2433
- }
2455
+ })();
2434
2456
  }
2435
- // Handle CLI arguments for NO_TUI mode
2436
- const cliArgs = process.argv.slice(2);
2437
- if (process.env.NO_TUI === '1' || cliArgs.includes('--no-tui')) {
2457
+ else if (process.env.NO_TUI === '1' || process.argv.slice(2).includes('--no-tui')) {
2458
+ // NO_TUI mode: handle CLI commands
2438
2459
  // NO_TUI mode: handle CLI commands
2460
+ const cliArgs = process.argv.slice(2);
2439
2461
  (async () => {
2440
2462
  loadCustomAgents();
2441
2463
  syncStateToStore();
@@ -2478,39 +2500,114 @@ if (process.env.NO_TUI === '1' || cliArgs.includes('--no-tui')) {
2478
2500
  process.exit(0);
2479
2501
  })();
2480
2502
  }
2481
- else if (process.env.TUI_MK === '2' || (process.argv[1]?.includes('4r') && process.env.TUI_MK !== '1')) {
2482
- // MK2 TUI mode - clean rebuild (Phase 1: Frame Lock)
2483
- // Default to MK2 when TUI_MK=2 is set, or when script path includes '4r' (Windows/Linux compatible)
2503
+ else {
2504
+ // MK3 TUI mode - DEFAULT (for 4r, 4runr, 4runr-os)
2505
+ // Launch Rust mk3-tui binary
2484
2506
  (async () => {
2485
- try {
2486
- const { startMK2 } = await import('./tui_mk2/mk2App.js');
2487
- await startMK2();
2507
+ // Check for updates and auto-update if needed
2508
+ const { checkAndUpdate } = await import('./version-check.js');
2509
+ const { isAutoUpdateEnabled, isUpdateCheckEnabled } = await import('./config.js');
2510
+ // Check config file for auto-update setting (env vars override config)
2511
+ const autoUpdateEnabled = process.env.NO_AUTO_UPDATE !== '1' && isAutoUpdateEnabled();
2512
+ const updateCheckEnabled = process.env.NO_UPDATE_CHECK !== '1' && isUpdateCheckEnabled();
2513
+ // Check for updates first - if update happens, process will exit
2514
+ if (updateCheckEnabled) {
2515
+ await checkAndUpdate('4runr-os', autoUpdateEnabled);
2488
2516
  }
2489
- catch (error) {
2490
- const errorMsg = error.message || String(error);
2491
- process.stderr.write(`\nFailed to start MK2 TUI: ${errorMsg}\n`);
2492
- process.exit(1);
2517
+ // Get __dirname equivalent for ES modules
2518
+ const __filename = fileURLToPath(import.meta.url);
2519
+ const __dirname = dirname(__filename);
2520
+ // Try to find mk3-tui binary in multiple locations
2521
+ const binaryName = process.platform === 'win32' ? 'mk3-tui.exe' : 'mk3-tui';
2522
+ const possiblePaths = [
2523
+ // From npm package 4runr-os-mk3 (global install) - binary is in PATH as 'mk3-tui'
2524
+ binaryName,
2525
+ // From npm package 4runr-os-mk3 (local node_modules via dependency)
2526
+ path.join(__dirname, '..', 'node_modules', '4runr-os-mk3', 'target', 'release', binaryName),
2527
+ // From local build in monorepo (development)
2528
+ path.join(__dirname, '..', '..', '..', 'apps', 'mk3-tui', 'target', 'release', binaryName),
2529
+ // From npm package 4runr-os-mk3 (local node_modules at root)
2530
+ path.join(__dirname, '..', '..', '..', 'node_modules', '4runr-os-mk3', 'target', 'release', binaryName),
2531
+ ];
2532
+ let binaryPath = null;
2533
+ for (const testPath of possiblePaths) {
2534
+ if (testPath.includes('node_modules') || testPath.includes('apps')) {
2535
+ // Absolute path - check if exists
2536
+ if (fs.existsSync(testPath)) {
2537
+ binaryPath = testPath;
2538
+ break;
2539
+ }
2540
+ }
2541
+ else {
2542
+ // Try to find in PATH
2543
+ try {
2544
+ const { execSync } = await import('child_process');
2545
+ execSync(`which ${testPath}`, { stdio: 'ignore' });
2546
+ binaryPath = testPath;
2547
+ break;
2548
+ }
2549
+ catch {
2550
+ // Not in PATH, continue
2551
+ }
2552
+ }
2493
2553
  }
2494
- })();
2495
- }
2496
- else if (process.env.TUI_MK1 === '1' || process.argv[1]?.includes('4runr') || process.argv[1]?.includes('4runr-os')) {
2497
- // MK1 TUI mode - new bulletproof implementation
2498
- // Default to MK1 when running as global binary (4runr, 4runr-os) or explicitly TUI_MK1=1
2499
- (async () => {
2500
- try {
2501
- const { startMK1 } = await import('./tui_mk1/mk1App.js');
2502
- await startMK1();
2554
+ if (!binaryPath) {
2555
+ process.stderr.write('\n[ERROR] mk3-tui binary not found.\n');
2556
+ process.stderr.write('The 4runr-os package requires 4runr-os-mk3.\n');
2557
+ process.stderr.write('Installing automatically...\n\n');
2558
+ try {
2559
+ // Try to install 4runr-os-mk3 automatically
2560
+ const { execSync } = await import('child_process');
2561
+ execSync('npm install -g 4runr-os-mk3', { stdio: 'inherit' });
2562
+ // Retry finding binary after install
2563
+ const retryPaths = [
2564
+ binaryName,
2565
+ path.join(__dirname, '..', 'node_modules', '4runr-os-mk3', 'target', 'release', binaryName),
2566
+ ];
2567
+ for (const testPath of retryPaths) {
2568
+ if (testPath === binaryName) {
2569
+ try {
2570
+ execSync(`which ${testPath}`, { stdio: 'ignore' });
2571
+ binaryPath = testPath;
2572
+ break;
2573
+ }
2574
+ catch {
2575
+ continue;
2576
+ }
2577
+ }
2578
+ else if (fs.existsSync(testPath)) {
2579
+ binaryPath = testPath;
2580
+ break;
2581
+ }
2582
+ }
2583
+ if (!binaryPath) {
2584
+ process.stderr.write('\n[ERROR] Installation completed but binary still not found.\n');
2585
+ process.stderr.write('Please run: npm install -g 4runr-os-mk3\n');
2586
+ process.stderr.write('Then try again: 4r\n\n');
2587
+ process.exit(1);
2588
+ }
2589
+ }
2590
+ catch (installError) {
2591
+ process.stderr.write('\n[ERROR] Auto-install failed. Please install manually:\n');
2592
+ process.stderr.write(' npm install -g 4runr-os-mk3\n');
2593
+ process.stderr.write('Then run: 4r\n\n');
2594
+ process.exit(1);
2595
+ }
2503
2596
  }
2504
- catch (error) {
2505
- const errorMsg = error.message || String(error);
2506
- process.stderr.write(`\nFailed to start MK1 TUI: ${errorMsg}\n`);
2597
+ // Spawn mk3-tui binary with all arguments
2598
+ const child = spawn(binaryPath, process.argv.slice(2), {
2599
+ stdio: 'inherit',
2600
+ cwd: process.cwd(),
2601
+ });
2602
+ child.on('error', (err) => {
2603
+ process.stderr.write(`\n[ERROR] Failed to start mk3-tui: ${err.message}\n`);
2507
2604
  process.exit(1);
2508
- }
2605
+ });
2606
+ child.on('exit', (code) => {
2607
+ process.exit(code || 0);
2608
+ });
2509
2609
  })();
2510
2610
  }
2511
- else {
2512
- main();
2513
- }
2514
2611
  /**
2515
2612
  * Print posture drilldown (NO_TUI)
2516
2613
  */