overarch-darwin-arm64 0.8.0

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 (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +214 -0
  3. package/dist/bin/overarch.d.ts +2 -0
  4. package/dist/bin/overarch.js +178 -0
  5. package/dist/src/agent/context.d.ts +14 -0
  6. package/dist/src/agent/context.js +200 -0
  7. package/dist/src/agent/context_compressor.d.ts +21 -0
  8. package/dist/src/agent/context_compressor.js +90 -0
  9. package/dist/src/agent/manifest.d.ts +22 -0
  10. package/dist/src/agent/manifest.js +131 -0
  11. package/dist/src/agent/planner.d.ts +38 -0
  12. package/dist/src/agent/planner.js +118 -0
  13. package/dist/src/agent/runtime.d.ts +59 -0
  14. package/dist/src/agent/runtime.js +400 -0
  15. package/dist/src/cli/approval.d.ts +13 -0
  16. package/dist/src/cli/approval.js +71 -0
  17. package/dist/src/cli/args.d.ts +15 -0
  18. package/dist/src/cli/args.js +47 -0
  19. package/dist/src/cli/commands/audit.d.ts +10 -0
  20. package/dist/src/cli/commands/audit.js +79 -0
  21. package/dist/src/cli/commands/companion.d.ts +1 -0
  22. package/dist/src/cli/commands/companion.js +143 -0
  23. package/dist/src/cli/commands/config.d.ts +1 -0
  24. package/dist/src/cli/commands/config.js +135 -0
  25. package/dist/src/cli/commands/doctor.d.ts +1 -0
  26. package/dist/src/cli/commands/doctor.js +217 -0
  27. package/dist/src/cli/commands/init.d.ts +1 -0
  28. package/dist/src/cli/commands/init.js +134 -0
  29. package/dist/src/cli/commands/memory.d.ts +2 -0
  30. package/dist/src/cli/commands/memory.js +98 -0
  31. package/dist/src/cli/commands/onboarding.d.ts +3 -0
  32. package/dist/src/cli/commands/onboarding.js +223 -0
  33. package/dist/src/cli/commands/sessions.d.ts +1 -0
  34. package/dist/src/cli/commands/sessions.js +22 -0
  35. package/dist/src/cli/commands/status.d.ts +1 -0
  36. package/dist/src/cli/commands/status.js +37 -0
  37. package/dist/src/cli/commands/update.d.ts +9 -0
  38. package/dist/src/cli/commands/update.js +105 -0
  39. package/dist/src/cli/repl.d.ts +3 -0
  40. package/dist/src/cli/repl.js +821 -0
  41. package/dist/src/cli/ui.d.ts +53 -0
  42. package/dist/src/cli/ui.js +215 -0
  43. package/dist/src/companion/petdex_adapter.d.ts +31 -0
  44. package/dist/src/companion/petdex_adapter.js +171 -0
  45. package/dist/src/companion/petdex_bridge.d.ts +65 -0
  46. package/dist/src/companion/petdex_bridge.js +356 -0
  47. package/dist/src/companion/types.d.ts +57 -0
  48. package/dist/src/companion/types.js +11 -0
  49. package/dist/src/config/index.d.ts +24 -0
  50. package/dist/src/config/index.js +237 -0
  51. package/dist/src/config/types.d.ts +58 -0
  52. package/dist/src/config/types.js +7 -0
  53. package/dist/src/core/diagnostics.d.ts +48 -0
  54. package/dist/src/core/diagnostics.js +115 -0
  55. package/dist/src/core/index.d.ts +23 -0
  56. package/dist/src/core/index.js +23 -0
  57. package/dist/src/core/mission.d.ts +55 -0
  58. package/dist/src/core/mission.js +173 -0
  59. package/dist/src/index.d.ts +1 -0
  60. package/dist/src/index.js +1 -0
  61. package/dist/src/learning/memory_manager.d.ts +26 -0
  62. package/dist/src/learning/memory_manager.js +211 -0
  63. package/dist/src/learning/types.d.ts +54 -0
  64. package/dist/src/learning/types.js +1 -0
  65. package/dist/src/mcp/registry.d.ts +17 -0
  66. package/dist/src/mcp/registry.js +97 -0
  67. package/dist/src/mcp/types.d.ts +13 -0
  68. package/dist/src/mcp/types.js +1 -0
  69. package/dist/src/providers/anthropic.d.ts +10 -0
  70. package/dist/src/providers/anthropic.js +95 -0
  71. package/dist/src/providers/base.d.ts +15 -0
  72. package/dist/src/providers/base.js +108 -0
  73. package/dist/src/providers/factory.d.ts +28 -0
  74. package/dist/src/providers/factory.js +142 -0
  75. package/dist/src/providers/gemini.d.ts +10 -0
  76. package/dist/src/providers/gemini.js +97 -0
  77. package/dist/src/providers/openai.d.ts +9 -0
  78. package/dist/src/providers/openai.js +85 -0
  79. package/dist/src/providers/openrouter.d.ts +5 -0
  80. package/dist/src/providers/openrouter.js +14 -0
  81. package/dist/src/providers/registry.d.ts +19 -0
  82. package/dist/src/providers/registry.js +209 -0
  83. package/dist/src/providers/types.d.ts +59 -0
  84. package/dist/src/providers/types.js +1 -0
  85. package/dist/src/providers/validator.d.ts +24 -0
  86. package/dist/src/providers/validator.js +161 -0
  87. package/dist/src/security/audit.d.ts +56 -0
  88. package/dist/src/security/audit.js +154 -0
  89. package/dist/src/security/guardrails.d.ts +9 -0
  90. package/dist/src/security/guardrails.js +32 -0
  91. package/dist/src/security/permissions.d.ts +12 -0
  92. package/dist/src/security/permissions.js +68 -0
  93. package/dist/src/security/policy.d.ts +220 -0
  94. package/dist/src/security/policy.js +720 -0
  95. package/dist/src/session/manager.d.ts +22 -0
  96. package/dist/src/session/manager.js +172 -0
  97. package/dist/src/session/types.d.ts +36 -0
  98. package/dist/src/session/types.js +1 -0
  99. package/dist/src/tools/checkpoint.d.ts +26 -0
  100. package/dist/src/tools/checkpoint.js +160 -0
  101. package/dist/src/tools/diagnostics.d.ts +2 -0
  102. package/dist/src/tools/diagnostics.js +125 -0
  103. package/dist/src/tools/diff.d.ts +14 -0
  104. package/dist/src/tools/diff.js +124 -0
  105. package/dist/src/tools/filesystem.d.ts +2 -0
  106. package/dist/src/tools/filesystem.js +224 -0
  107. package/dist/src/tools/git.d.ts +2 -0
  108. package/dist/src/tools/git.js +138 -0
  109. package/dist/src/tools/markdown.d.ts +33 -0
  110. package/dist/src/tools/markdown.js +190 -0
  111. package/dist/src/tools/project.d.ts +2 -0
  112. package/dist/src/tools/project.js +63 -0
  113. package/dist/src/tools/registry.d.ts +14 -0
  114. package/dist/src/tools/registry.js +230 -0
  115. package/dist/src/tools/search.d.ts +2 -0
  116. package/dist/src/tools/search.js +136 -0
  117. package/dist/src/tools/shell.d.ts +2 -0
  118. package/dist/src/tools/shell.js +74 -0
  119. package/dist/src/tools/symbols.d.ts +30 -0
  120. package/dist/src/tools/symbols.js +155 -0
  121. package/dist/src/tools/types.d.ts +28 -0
  122. package/dist/src/tools/types.js +1 -0
  123. package/dist/src/tools/web_search.d.ts +14 -0
  124. package/dist/src/tools/web_search.js +154 -0
  125. package/install.sh +29 -0
  126. package/overarch +15 -0
  127. package/package.json +28 -0
@@ -0,0 +1,143 @@
1
+ import { exec } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import * as ui from '../ui.js';
4
+ import { petdexAdapter } from '../../companion/petdex_adapter.js';
5
+ import { petdexBridge } from '../../companion/petdex_bridge.js';
6
+ const execAsync = promisify(exec);
7
+ export async function handleCompanionCommand(subcommand, arg1, _arg2) {
8
+ const sub = (subcommand || 'status').toLowerCase();
9
+ switch (sub) {
10
+ case 'start':
11
+ case 'launch': {
12
+ ui.info('Launching Overarch Desktop Companion...');
13
+ const res = await petdexBridge.launchCompanion(process.cwd());
14
+ if (res.success) {
15
+ ui.success(res.message);
16
+ }
17
+ else {
18
+ ui.warn(res.message);
19
+ console.log(ui.dim('Ensure dist-desktop/OverarchCompanion.exe is built: npm run build:desktop'));
20
+ }
21
+ break;
22
+ }
23
+ case 'stop':
24
+ case 'kill': {
25
+ try {
26
+ await execAsync('powershell -Command "Stop-Process -Name \'OverarchCompanion\' -Force -ErrorAction SilentlyContinue"');
27
+ ui.success('Stopped Overarch Desktop Companion.');
28
+ }
29
+ catch (err) {
30
+ ui.info('No active companion process detected.');
31
+ }
32
+ break;
33
+ }
34
+ case 'status': {
35
+ let isProcRunning = false;
36
+ try {
37
+ const { stdout } = await execAsync('powershell -Command "Get-Process -Name \'OverarchCompanion\' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Id"');
38
+ isProcRunning = Boolean(stdout && stdout.trim());
39
+ }
40
+ catch { }
41
+ const bridgeStatus = petdexBridge.getStatus();
42
+ const activePet = petdexBridge.getActivePet();
43
+ const petInfo = await petdexAdapter.getPet(activePet);
44
+ ui.statusCard('Overarch Desktop Companion Status', {
45
+ 'Desktop Window': isProcRunning ? ui.green('Running (Floating Overlay)') : ui.dim('Not running (start with `overarch companion start`)'),
46
+ 'Active Pet': petInfo ? `${petInfo.displayName} (${petInfo.id})` : activePet,
47
+ 'Format / Version': petInfo ? `${petInfo.spritesheetFormat.toUpperCase()} (v${petInfo.spriteVersionNumber}, ${petInfo.columns}x${petInfo.rows} grid)` : 'Default',
48
+ 'Agent State': bridgeStatus.state.toUpperCase(),
49
+ 'Bridge Event Port': bridgeStatus.port,
50
+ 'Connected Clients': bridgeStatus.connectedClients,
51
+ 'Controls': 'Right-click pet for menu, left-click drag to reposition'
52
+ });
53
+ break;
54
+ }
55
+ case 'pets':
56
+ case 'list': {
57
+ ui.info('Scanning Petdex library...');
58
+ const pets = await petdexAdapter.listPets();
59
+ const activePet = petdexBridge.getActivePet();
60
+ ui.heading(`Available Petdex Pets (${pets.length})`);
61
+ console.log();
62
+ if (pets.length === 0) {
63
+ console.log(ui.dim(' No installed Petdex pets found in ~/.petdex/pets/ or ~/.codex/pets/'));
64
+ console.log(` ${ui.dim('Install one with:')} ${ui.accent('overarch companion install <slug>')}`);
65
+ console.log(` ${ui.dim('Example:')} ${ui.accent('overarch companion install savage-codex-hacker')}`);
66
+ console.log(` ${ui.dim('Gallery:')} https://petdex.dev`);
67
+ return;
68
+ }
69
+ pets.forEach((p, idx) => {
70
+ const isAct = p.id === activePet ? ui.accent(' (active)') : '';
71
+ console.log(` ${idx + 1}. ${ui.bold(p.displayName)} ${ui.dim(`[${p.id}]`)}${isAct}`);
72
+ if (p.description) {
73
+ console.log(` ${ui.dim(p.description)}`);
74
+ }
75
+ });
76
+ console.log(`\n${ui.dim('Switch active pet:')} ${ui.accent('overarch companion select <slug>')}`);
77
+ console.log(`${ui.dim('Install more pets:')} ${ui.accent('overarch companion install <slug>')}`);
78
+ break;
79
+ }
80
+ case 'select':
81
+ case 'set': {
82
+ if (!arg1) {
83
+ ui.warn('Usage: overarch companion select <slug>');
84
+ return;
85
+ }
86
+ const targetSlug = arg1.trim();
87
+ const pet = await petdexAdapter.getPet(targetSlug);
88
+ if (!pet) {
89
+ ui.warn(`Pet '${targetSlug}' is not installed locally.`);
90
+ console.log(ui.dim(`Run \`overarch companion install ${targetSlug}\` to install it from Petdex.`));
91
+ return;
92
+ }
93
+ petdexBridge.setActivePet(pet.id);
94
+ ui.success(`Selected Petdex companion: ${ui.bold(pet.displayName)} (${pet.id})`);
95
+ break;
96
+ }
97
+ case 'install':
98
+ case 'add': {
99
+ if (!arg1) {
100
+ ui.warn('Usage: overarch companion install <slug>');
101
+ console.log(ui.dim('Example: overarch companion install savage-codex-hacker'));
102
+ console.log(ui.dim('Browse 200+ pets at: https://petdex.dev'));
103
+ return;
104
+ }
105
+ const slug = arg1.trim();
106
+ ui.info(`Installing '${slug}' from Petdex library...`);
107
+ const spin = ui.spinner(`Fetching ${slug} from Petdex...`);
108
+ const result = await petdexAdapter.installPet(slug);
109
+ spin.stop();
110
+ if (result.success) {
111
+ ui.success(result.message);
112
+ if (result.pet) {
113
+ petdexBridge.setActivePet(result.pet.id);
114
+ console.log(ui.dim(`Automatically set ${result.pet.displayName} as active companion.`));
115
+ }
116
+ }
117
+ else {
118
+ ui.fail(result.message);
119
+ }
120
+ break;
121
+ }
122
+ case 'help':
123
+ default: {
124
+ ui.heading('Overarch Floating Desktop Companion');
125
+ console.log(`
126
+ ${ui.bold('Commands')}
127
+ overarch companion start Launch floating desktop companion
128
+ overarch companion stop Close companion window
129
+ overarch companion status Display companion connection & active pet
130
+ overarch companion pets List all installed Petdex companions
131
+ overarch companion select <slug> Switch active desktop companion
132
+ overarch companion install <slug> Install any pet from https://petdex.dev
133
+
134
+ ${ui.bold('Desktop Interaction')}
135
+ • Left-click & drag: Move pet anywhere on desktop (position is saved)
136
+ • Double-click: Wave / greeting reaction
137
+ • Right-click: Context menu (change pet, terminal, status, reset)
138
+ • Non-activating: Never steals keyboard focus from editor or terminal
139
+ `);
140
+ break;
141
+ }
142
+ }
143
+ }
@@ -0,0 +1 @@
1
+ export declare function handleConfigCommand(subcommand?: string, key?: string, value?: string): Promise<void>;
@@ -0,0 +1,135 @@
1
+ import * as ui from '../ui.js';
2
+ import { loadConfig, saveGlobalConfig } from '../../config/index.js';
3
+ import { resolveModel } from '../../providers/factory.js';
4
+ export async function handleConfigCommand(subcommand, key, value) {
5
+ const config = await loadConfig();
6
+ // 1. Direct Target Shortcuts
7
+ if (subcommand === 'provider') {
8
+ if (!key) {
9
+ console.log(`\nActive Provider: ${ui.bold(config.activeProvider || 'anthropic')}`);
10
+ console.log(`Provider Mode: ${config.mode === 'offline' ? ui.yellow('Offline') : ui.green('Online')}`);
11
+ console.log(ui.dim('To change provider: overarch config set provider <anthropic|openai|gemini|openrouter>'));
12
+ return;
13
+ }
14
+ await saveGlobalConfig({ activeProvider: key.toLowerCase() });
15
+ ui.success(`Active provider set to: ${key.toLowerCase()}`);
16
+ return;
17
+ }
18
+ if (subcommand === 'model') {
19
+ if (!key) {
20
+ const resolved = resolveModel(config.defaultModel);
21
+ console.log(`\nActive Model: ${ui.bold(config.defaultModel)}`);
22
+ if (resolved) {
23
+ console.log(`Display Name: ${resolved.displayName} (${resolved.provider})`);
24
+ }
25
+ console.log(ui.dim('To change model: overarch config set model <id>'));
26
+ return;
27
+ }
28
+ const resolved = resolveModel(key);
29
+ if (!resolved) {
30
+ ui.warn(`Model '${key}' will be treated as custom '${key}'`);
31
+ }
32
+ await saveGlobalConfig({ defaultModel: key });
33
+ ui.success(`Default model set to: ${key}`);
34
+ return;
35
+ }
36
+ if (subcommand === 'accent') {
37
+ if (!key) {
38
+ console.log(`\nCurrent Accent: ${ui.accent(config.ui?.accentColor || 'cyan')}`);
39
+ console.log(ui.dim('Available: cyan, magenta, blue, green, yellow'));
40
+ return;
41
+ }
42
+ await saveGlobalConfig({ ui: { ...config.ui, accentColor: key } });
43
+ ui.setAccent(key);
44
+ ui.success(`Accent color updated to: ${ui.accent(key)}`);
45
+ return;
46
+ }
47
+ if (subcommand === 'avatar') {
48
+ if (!key) {
49
+ console.log(`\nCurrent Avatar: ${ui.accent(config.ui?.avatar || '◆')}`);
50
+ return;
51
+ }
52
+ await saveGlobalConfig({ ui: { ...config.ui, avatar: key } });
53
+ ui.setAvatar(key);
54
+ ui.success(`Avatar token updated to: ${ui.accent(key)}`);
55
+ return;
56
+ }
57
+ if (subcommand === 'permissions') {
58
+ console.log(`\nAuto-Approve Tiers: ${config.permissions?.autoApprove?.join(', ') || 'none'}`);
59
+ console.log(`Require-Approval: ${config.permissions?.requireApproval?.join(', ') || 'none'}`);
60
+ console.log(`Denied Tools: ${config.permissions?.deny?.join(', ') || 'none'}`);
61
+ return;
62
+ }
63
+ // 2. Default List / Status View
64
+ if (!subcommand || subcommand === 'show' || subcommand === 'list') {
65
+ ui.statusCard('Overarch Configuration', {
66
+ 'Config File': config.configPath || 'Defaults',
67
+ 'Scope': config.isProjectConfig ? 'Project (.overarch/config.json)' : 'Global (~/.overarch/config.json)',
68
+ 'Provider': config.activeProvider || 'anthropic',
69
+ 'Model': config.defaultModel,
70
+ 'Mode': config.mode === 'offline' ? ui.yellow('Offline') : 'Online',
71
+ 'Accent Color': ui.accent(config.ui?.accentColor || 'cyan'),
72
+ 'Avatar': ui.accent(config.ui?.avatar || '◆'),
73
+ 'Ponytail Mode': config.ponytail || 'full',
74
+ 'CCSS Mode': config.ccss || 'auto',
75
+ 'Agent Mode': config.agentMode || 'approval',
76
+ 'Auto-Approve Tiers': config.permissions?.autoApprove?.join(', ') || 'none'
77
+ });
78
+ console.log(ui.dim('\nTargets: provider, model, accent, avatar, permissions'));
79
+ console.log(ui.dim('Usage: overarch config <target> [value] | overarch config get <key> | overarch config set <key> <val>'));
80
+ return;
81
+ }
82
+ // 3. Get Key
83
+ if (subcommand === 'get') {
84
+ if (!key) {
85
+ ui.error('Key name required. Example: overarch config get defaultModel');
86
+ return;
87
+ }
88
+ const val = config[key] ?? config.ui?.[key];
89
+ if (val !== undefined) {
90
+ console.log(typeof val === 'object' ? JSON.stringify(val, null, 2) : String(val));
91
+ }
92
+ else {
93
+ ui.warn(`Key '${key}' not found in configuration.`);
94
+ }
95
+ return;
96
+ }
97
+ // 4. Set Key
98
+ if (subcommand === 'set') {
99
+ if (!key || value === undefined) {
100
+ ui.error('Key and value required. Example: overarch config set model gpt-4o');
101
+ return;
102
+ }
103
+ const updates = {};
104
+ if (key === 'model' || key === 'defaultModel') {
105
+ updates.defaultModel = value;
106
+ }
107
+ else if (key === 'provider' || key === 'activeProvider') {
108
+ updates.activeProvider = value.toLowerCase();
109
+ }
110
+ else if (key === 'accent' || key === 'accentColor') {
111
+ updates.ui = { ...config.ui, accentColor: value };
112
+ ui.setAccent(value);
113
+ }
114
+ else if (key === 'avatar') {
115
+ updates.ui = { ...config.ui, avatar: value };
116
+ ui.setAvatar(value);
117
+ }
118
+ else if (key === 'ponytail') {
119
+ updates.ponytail = value.toLowerCase();
120
+ }
121
+ else if (key === 'ccss') {
122
+ updates.ccss = value.toLowerCase();
123
+ }
124
+ else if (key === 'mode') {
125
+ updates.mode = value.toLowerCase() === 'offline' ? 'offline' : 'online';
126
+ }
127
+ else {
128
+ updates[key] = value;
129
+ }
130
+ await saveGlobalConfig(updates);
131
+ ui.success(`Updated ${key} = ${value}`);
132
+ return;
133
+ }
134
+ ui.error(`Unknown config action: ${subcommand}.`);
135
+ }
@@ -0,0 +1 @@
1
+ export declare function doctor(): Promise<void>;
@@ -0,0 +1,217 @@
1
+ import { execSync } from 'node:child_process';
2
+ import * as ui from '../ui.js';
3
+ import { loadConfig, getApiKey } from '../../config/index.js';
4
+ import { resolveModel } from '../../providers/factory.js';
5
+ import { ToolRegistry } from '../../tools/registry.js';
6
+ import { petdexBridge } from '../../companion/petdex_bridge.js';
7
+ import { policyEngine } from '../../security/policy.js';
8
+ import fs from 'node:fs/promises';
9
+ import * as syncFs from 'node:fs';
10
+ import path from 'node:path';
11
+ import os from 'node:os';
12
+ export async function doctor() {
13
+ ui.heading('Overarch Doctor Diagnostics');
14
+ console.log(ui.dim('Inspecting runtime, security policies, tool integrity, project context, and subsystems...\n'));
15
+ const issues = [];
16
+ // 1. Runtime & Environment (Node.js >= 20.0.0)
17
+ const nodeVersion = process.version;
18
+ const majorVersion = parseInt(nodeVersion.slice(1).split('.')[0], 10);
19
+ if (majorVersion >= 20) {
20
+ ui.done(`Runtime: Node.js ${nodeVersion} (${process.platform} ${process.arch}, ESM & native APIs active)`);
21
+ }
22
+ else {
23
+ ui.fail(`Runtime: Node.js ${nodeVersion} (>= 20 required)`);
24
+ issues.push('Upgrade Node.js to v20 or higher.');
25
+ }
26
+ // 2. PATH Resolution & Global Command Integrity
27
+ try {
28
+ let resolvedCommand = '';
29
+ if (process.platform === 'win32') {
30
+ try {
31
+ const whereOutput = execSync('where.exe overarch 2>nul', { encoding: 'utf8' }).trim();
32
+ const lines = whereOutput.split('\r\n').map(l => l.trim()).filter(Boolean);
33
+ resolvedCommand = lines[0] || '';
34
+ if (lines.length > 1) {
35
+ ui.done(`PATH: 'overarch' found in ${lines.length} locations (Primary: ${resolvedCommand})`);
36
+ }
37
+ else if (resolvedCommand) {
38
+ ui.done(`PATH: 'overarch' command resolved cleanly at: ${resolvedCommand}`);
39
+ }
40
+ else {
41
+ ui.warn(`PATH: 'overarch' not found via 'where.exe'`);
42
+ }
43
+ }
44
+ catch {
45
+ ui.done(`PATH: Standard environment active`);
46
+ }
47
+ }
48
+ else {
49
+ const whichOutput = execSync('which overarch 2>/dev/null', { encoding: 'utf8' }).trim();
50
+ ui.done(`PATH: 'overarch' resolved at: ${whichOutput}`);
51
+ }
52
+ }
53
+ catch {
54
+ ui.warn('PATH: Could not query active binary resolution');
55
+ }
56
+ // 3. Wrapper Script UTF-8 BOM Verification (preventing '@echo' syntax error in cmd.exe)
57
+ if (process.platform === 'win32') {
58
+ const candidateWrappers = [
59
+ path.join(os.homedir(), 'AppData', 'Local', 'Programs', 'Overarch', 'overarch.cmd'),
60
+ path.join(os.homedir(), 'AppData', 'Local', 'Microsoft', 'WindowsApps', 'overarch.cmd'),
61
+ path.join(os.homedir(), 'AppData', 'Roaming', 'npm', 'overarch.cmd'),
62
+ ];
63
+ let checkedWrappers = 0;
64
+ let hasBom = false;
65
+ for (const wrapper of candidateWrappers) {
66
+ if (syncFs.existsSync(wrapper)) {
67
+ checkedWrappers++;
68
+ try {
69
+ const fd = syncFs.openSync(wrapper, 'r');
70
+ const buffer = Buffer.alloc(3);
71
+ syncFs.readSync(fd, buffer, 0, 3, 0);
72
+ syncFs.closeSync(fd);
73
+ if (buffer[0] === 0xef && buffer[1] === 0xbb && buffer[2] === 0xbf) {
74
+ hasBom = true;
75
+ ui.fail(`Wrapper Scripts: UTF-8 BOM detected in ${wrapper} (causes '@echo' command error)`);
76
+ issues.push(`Re-save '${wrapper}' without BOM or re-run Overarch installer.`);
77
+ }
78
+ }
79
+ catch { }
80
+ }
81
+ }
82
+ if (!hasBom && checkedWrappers > 0) {
83
+ ui.done(`Wrapper Scripts: Verified BOM-free across ${checkedWrappers} candidate shims (compatible with cmd.exe & PowerShell)`);
84
+ }
85
+ else if (checkedWrappers === 0) {
86
+ ui.done(`Wrapper Scripts: No external Windows shims to check (running locally)`);
87
+ }
88
+ }
89
+ // 4. Git Version Control
90
+ try {
91
+ const gitVersion = execSync('git --version', { encoding: 'utf8' }).trim();
92
+ ui.done(`Git: ${gitVersion}`);
93
+ }
94
+ catch {
95
+ ui.fail('Git: Not found in system PATH');
96
+ issues.push('Install Git or add it to your system PATH to enable version control and rollback features.');
97
+ }
98
+ // 5. Native Windows Desktop Compiler (if on Windows)
99
+ if (process.platform === 'win32') {
100
+ const cscCandidates = [
101
+ 'C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\csc.exe',
102
+ 'C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\csc.exe',
103
+ ];
104
+ const foundCsc = cscCandidates.find((p) => {
105
+ try {
106
+ return execSync(`where csc.exe 2>nul || (dir "${p}" 2>nul)`).length > 0;
107
+ }
108
+ catch {
109
+ return false;
110
+ }
111
+ });
112
+ if (foundCsc) {
113
+ ui.done(`Windows Compiler: Native .NET C# compiler (csc.exe) detected`);
114
+ }
115
+ else {
116
+ ui.done(`Windows Compiler: Standard Windows system environment active`);
117
+ }
118
+ }
119
+ // 6. CCHCFAI Security & Policy Engine
120
+ const safeOnly = policyEngine.isSafeOnly();
121
+ if (safeOnly) {
122
+ ui.done(`CCHCFAI Policy: Active in SAFE-ONLY mode (all destructive shell & mutations blocked)`);
123
+ }
124
+ else {
125
+ ui.done(`CCHCFAI Policy: Active (Tier 0-3 tiered authority with human control gates)`);
126
+ }
127
+ // 7. File System Read / Write Permissions (Workspace & .overarch)
128
+ const cwd = process.cwd();
129
+ try {
130
+ const testFile = path.join(cwd, `.overarch_rw_test_${Date.now()}.tmp`);
131
+ await fs.writeFile(testFile, 'test', 'utf8');
132
+ await fs.unlink(testFile);
133
+ const overarchGlobal = path.join(os.homedir(), '.overarch');
134
+ if (!syncFs.existsSync(overarchGlobal)) {
135
+ await fs.mkdir(overarchGlobal, { recursive: true });
136
+ }
137
+ const testGlobal = path.join(overarchGlobal, `.rw_test_${Date.now()}.tmp`);
138
+ await fs.writeFile(testGlobal, 'test', 'utf8');
139
+ await fs.unlink(testGlobal);
140
+ ui.done(`Filesystem: Read & Write verified in workspace (${cwd}) and global (~/.overarch)`);
141
+ }
142
+ catch (err) {
143
+ ui.fail(`Filesystem: Write permission check failed: ${err.message}`);
144
+ issues.push(`Ensure directory permissions allow reading and writing.`);
145
+ }
146
+ // 8. Configuration & Auth
147
+ const config = await loadConfig();
148
+ ui.done(`Configuration: ${config.isProjectConfig ? 'Project (.overarch/config.json)' : 'Global (~/.overarch/config.json)'}`);
149
+ const activeModel = config.defaultModel;
150
+ const resolved = resolveModel(activeModel);
151
+ if (config.mode === 'offline' || resolved?.provider === 'none') {
152
+ ui.done(`Provider: Offline mode active (AI calls disabled)`);
153
+ }
154
+ else if (resolved) {
155
+ const key = getApiKey(resolved.provider);
156
+ if (key) {
157
+ ui.done(`Authentication: ${resolved.provider.toUpperCase()} API key detected`);
158
+ }
159
+ else {
160
+ ui.fail(`Authentication: Missing API key for provider '${resolved.provider}'`);
161
+ issues.push(`Set ${resolved.provider.toUpperCase()}_API_KEY in your environment or add to .env via \`/setup\`.`);
162
+ }
163
+ ui.done(`Model: ${resolved.displayName} (${resolved.provider}/${resolved.model})`);
164
+ }
165
+ else {
166
+ ui.fail(`Model: Unknown model '${activeModel}'`);
167
+ issues.push('Run `/setup` or `/config model <name>` to select a valid model.');
168
+ }
169
+ // 9. .overarch Project Subsystem & Audit Log
170
+ const overarchDir = path.join(cwd, '.overarch');
171
+ try {
172
+ await fs.access(overarchDir);
173
+ const subFiles = await fs.readdir(overarchDir);
174
+ ui.done(`.overarch Subsystem: Initialized (${subFiles.length} items: ${subFiles.join(', ')})`);
175
+ }
176
+ catch {
177
+ ui.warn(`.overarch Subsystem: Not initialized in current directory`);
178
+ issues.push('Run `overarch init` or `/init` in the REPL to initialize project context.');
179
+ }
180
+ // 10. Tool Registry (including web_search)
181
+ const registry = ToolRegistry.createDefault();
182
+ const tools = registry.list();
183
+ const hasWebSearch = tools.some((t) => t.name === 'web_search');
184
+ if (hasWebSearch) {
185
+ ui.done(`Tools: ${tools.length} registered (including native web_search & precision file patchers)`);
186
+ }
187
+ else {
188
+ ui.warn(`Tools: ${tools.length} registered`);
189
+ }
190
+ // 11. Companion Health & Petdex Bridge
191
+ const bridgeStatus = petdexBridge.getStatus();
192
+ let companionExeFound = false;
193
+ if (process.platform === 'win32') {
194
+ const compCandidates = [
195
+ path.join(cwd, 'dist-desktop', 'OverarchCompanion.exe'),
196
+ path.join(os.homedir(), 'AppData', 'Local', 'Programs', 'Overarch', 'OverarchCompanion.exe'),
197
+ ];
198
+ companionExeFound = compCandidates.some(c => syncFs.existsSync(c));
199
+ }
200
+ if (bridgeStatus.running) {
201
+ ui.done(`Companion Health: Active and listening on port ${bridgeStatus.port} (Companion binary: ${companionExeFound ? 'Available' : 'Standby'})`);
202
+ }
203
+ else {
204
+ ui.done(`Companion Health: Standby (Bridge ready, companion executable: ${companionExeFound ? 'Available' : 'Ready'})`);
205
+ }
206
+ console.log();
207
+ if (issues.length === 0) {
208
+ ui.success('All systems healthy. Overarch CLI is ready for autonomous software engineering.');
209
+ }
210
+ else {
211
+ ui.warn(`Identified ${issues.length} item(s) requiring attention:`);
212
+ issues.forEach((iss, idx) => {
213
+ console.log(` ${idx + 1}. ${iss}`);
214
+ });
215
+ console.log(`\n${ui.dim('Run /setup to re-run the configuration wizard.')}`);
216
+ }
217
+ }
@@ -0,0 +1 @@
1
+ export declare function init(): Promise<void>;
@@ -0,0 +1,134 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import * as ui from '../ui.js';
4
+ import { DEFAULT_CONFIG } from '../../config/index.js';
5
+ export async function init() {
6
+ ui.heading('Initialize Overarch Project Context');
7
+ const cwd = process.cwd();
8
+ const projectConfigDir = path.join(cwd, '.overarch');
9
+ // 1. Detect project characteristics
10
+ const detectedStacks = [];
11
+ let testCommand = '';
12
+ let buildCommand = '';
13
+ try {
14
+ const pkg = JSON.parse(await fs.readFile(path.join(cwd, 'package.json'), 'utf8'));
15
+ detectedStacks.push(`Node.js (${pkg.name || 'unnamed'})`);
16
+ if (pkg.scripts?.test)
17
+ testCommand = 'npm test';
18
+ if (pkg.scripts?.build)
19
+ buildCommand = 'npm run build';
20
+ if (pkg.dependencies?.typescript || pkg.devDependencies?.typescript) {
21
+ detectedStacks.push('TypeScript');
22
+ }
23
+ if (pkg.dependencies?.react || pkg.devDependencies?.react) {
24
+ detectedStacks.push('React');
25
+ }
26
+ }
27
+ catch { }
28
+ try {
29
+ await fs.readFile(path.join(cwd, 'Cargo.toml'), 'utf8');
30
+ detectedStacks.push('Rust');
31
+ if (!testCommand)
32
+ testCommand = 'cargo test';
33
+ if (!buildCommand)
34
+ buildCommand = 'cargo build';
35
+ }
36
+ catch { }
37
+ try {
38
+ await fs.readFile(path.join(cwd, 'pyproject.toml'), 'utf8');
39
+ detectedStacks.push('Python');
40
+ if (!testCommand)
41
+ testCommand = 'pytest';
42
+ }
43
+ catch {
44
+ try {
45
+ await fs.readFile(path.join(cwd, 'requirements.txt'), 'utf8');
46
+ detectedStacks.push('Python');
47
+ }
48
+ catch { }
49
+ }
50
+ try {
51
+ await fs.readFile(path.join(cwd, 'go.mod'), 'utf8');
52
+ detectedStacks.push('Go');
53
+ if (!testCommand)
54
+ testCommand = 'go test ./...';
55
+ if (!buildCommand)
56
+ buildCommand = 'go build ./...';
57
+ }
58
+ catch { }
59
+ // 2. Discover root files & directories
60
+ const ignoreList = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.turbo', '.cache']);
61
+ const files = await fs.readdir(cwd, { withFileTypes: true });
62
+ const keyDirs = [];
63
+ for (const f of files) {
64
+ if (ignoreList.has(f.name))
65
+ continue;
66
+ if (f.isDirectory())
67
+ keyDirs.push(f.name);
68
+ }
69
+ // 3. Create .overarch structure
70
+ await fs.mkdir(projectConfigDir, { recursive: true });
71
+ await fs.mkdir(path.join(projectConfigDir, 'sessions'), { recursive: true });
72
+ await fs.mkdir(path.join(projectConfigDir, 'cache'), { recursive: true });
73
+ // config.json
74
+ const configPath = path.join(projectConfigDir, 'config.json');
75
+ try {
76
+ await fs.access(configPath);
77
+ }
78
+ catch {
79
+ const projectConfig = {
80
+ project: {
81
+ ...DEFAULT_CONFIG.project,
82
+ include: keyDirs,
83
+ }
84
+ };
85
+ await fs.writeFile(configPath, JSON.stringify(projectConfig, null, 2), 'utf8');
86
+ }
87
+ // instructions.md
88
+ const instructionsPath = path.join(projectConfigDir, 'instructions.md');
89
+ try {
90
+ await fs.access(instructionsPath);
91
+ }
92
+ catch {
93
+ let template = `# ${path.basename(cwd)} — Architecture Guidelines\n\n`;
94
+ template += `## Tech Stack\n${detectedStacks.length > 0 ? detectedStacks.map(s => `- ${s}`).join('\n') : '- General'}\n\n`;
95
+ if (buildCommand)
96
+ template += `## Build Command\n\`${buildCommand}\`\n\n`;
97
+ if (testCommand)
98
+ template += `## Test Command\n\`${testCommand}\`\n\n`;
99
+ template += `## Development Principles\n`;
100
+ template += `- Prefer small, verifiable changes\n`;
101
+ template += `- Always run tests before declaring tasks complete\n`;
102
+ template += `- Follow existing styling and patterns\n`;
103
+ await fs.writeFile(instructionsPath, template, 'utf8');
104
+ }
105
+ // memory.md
106
+ const memoryPath = path.join(projectConfigDir, 'memory.md');
107
+ try {
108
+ await fs.access(memoryPath);
109
+ }
110
+ catch {
111
+ const memTemplate = `# Project Memory\n\n- [${new Date().toISOString().slice(0, 10)}] Initialized Overarch project context\n`;
112
+ await fs.writeFile(memoryPath, memTemplate, 'utf8');
113
+ }
114
+ // .gitignore
115
+ const gitignorePath = path.join(projectConfigDir, '.gitignore');
116
+ await fs.writeFile(gitignorePath, 'sessions/\ncache/\n*.log\n*.env\nstate.json\n', 'utf8');
117
+ // context.json
118
+ const contextPath = path.join(projectConfigDir, 'context.json');
119
+ const contextIndex = {
120
+ initializedAt: new Date().toISOString(),
121
+ stacks: detectedStacks,
122
+ keyDirectories: keyDirs,
123
+ buildCommand,
124
+ testCommand
125
+ };
126
+ await fs.writeFile(contextPath, JSON.stringify(contextIndex, null, 2), 'utf8');
127
+ console.log();
128
+ ui.done(`Detected Stack: ${detectedStacks.length > 0 ? detectedStacks.join(', ') : 'Generic'}`);
129
+ ui.done(`Discovered Directories: ${keyDirs.join(', ') || 'root'}`);
130
+ ui.done(`Initialized .overarch subsystem in ${projectConfigDir}`);
131
+ ui.done(`Created project instructions template at .overarch/instructions.md`);
132
+ ui.done(`Created project memory ledger at .overarch/memory.md`);
133
+ console.log(`\n${ui.accent(ui.getAvatar())} Project context established. Overarch is now tailored to this repository.`);
134
+ }
@@ -0,0 +1,2 @@
1
+ export declare function handleMemoryCommand(subcommand?: string, arg1?: string, arg2?: string): Promise<void>;
2
+ export declare function handleLearnCommand(lessonText?: string): Promise<void>;