opencode-dux 1.0.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.
- package/LICENSE +21 -0
- package/README.md +452 -0
- package/dist/agents/descriptions.d.ts +6 -0
- package/dist/agents/designer.d.ts +2 -0
- package/dist/agents/explorer.d.ts +2 -0
- package/dist/agents/fixer.d.ts +2 -0
- package/dist/agents/index.d.ts +22 -0
- package/dist/agents/interpreter.d.ts +2 -0
- package/dist/agents/librarian.d.ts +2 -0
- package/dist/agents/oracle.d.ts +2 -0
- package/dist/agents/orchestrator.d.ts +27 -0
- package/dist/agents/overrides.d.ts +18 -0
- package/dist/agents/prompt-blocks.d.ts +97 -0
- package/dist/agents/steward.d.ts +3 -0
- package/dist/cli/config-io.d.ts +24 -0
- package/dist/cli/config-manager.d.ts +4 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +1006 -0
- package/dist/cli/install.d.ts +2 -0
- package/dist/cli/mcps.d.ts +13 -0
- package/dist/cli/model-key-normalization.d.ts +1 -0
- package/dist/cli/paths.d.ts +35 -0
- package/dist/cli/providers.d.ts +137 -0
- package/dist/cli/skills.d.ts +22 -0
- package/dist/cli/system.d.ts +5 -0
- package/dist/cli/types.d.ts +38 -0
- package/dist/config/constants.d.ts +12 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/loader.d.ts +40 -0
- package/dist/config/runtime-preset.d.ts +12 -0
- package/dist/config/schema.d.ts +281 -0
- package/dist/config/utils.d.ts +10 -0
- package/dist/discovery/local/types.d.ts +79 -0
- package/dist/discovery/local.d.ts +73 -0
- package/dist/discovery/mcp-servers.d.ts +88 -0
- package/dist/discovery/skills.d.ts +94 -0
- package/dist/hooks/apply-patch/codec.d.ts +7 -0
- package/dist/hooks/apply-patch/errors.d.ts +25 -0
- package/dist/hooks/apply-patch/execution-context.d.ts +27 -0
- package/dist/hooks/apply-patch/index.d.ts +15 -0
- package/dist/hooks/apply-patch/matching.d.ts +26 -0
- package/dist/hooks/apply-patch/operations.d.ts +3 -0
- package/dist/hooks/apply-patch/patch.d.ts +2 -0
- package/dist/hooks/apply-patch/prepared-changes.d.ts +17 -0
- package/dist/hooks/apply-patch/resolution.d.ts +19 -0
- package/dist/hooks/apply-patch/rewrite.d.ts +7 -0
- package/dist/hooks/apply-patch/test-helpers.d.ts +6 -0
- package/dist/hooks/apply-patch/types.d.ts +80 -0
- package/dist/hooks/auto-update-checker/cache.d.ts +11 -0
- package/dist/hooks/auto-update-checker/checker.d.ts +32 -0
- package/dist/hooks/auto-update-checker/constants.d.ts +11 -0
- package/dist/hooks/auto-update-checker/index.d.ts +18 -0
- package/dist/hooks/auto-update-checker/types.d.ts +22 -0
- package/dist/hooks/chat-headers.d.ts +16 -0
- package/dist/hooks/context-pressure-reminder/index.d.ts +33 -0
- package/dist/hooks/delegate-task-retry/guidance.d.ts +2 -0
- package/dist/hooks/delegate-task-retry/hook.d.ts +8 -0
- package/dist/hooks/delegate-task-retry/index.d.ts +4 -0
- package/dist/hooks/delegate-task-retry/patterns.d.ts +11 -0
- package/dist/hooks/filter-available-skills/index.d.ts +32 -0
- package/dist/hooks/foreground-fallback/index.d.ts +72 -0
- package/dist/hooks/image-hook.d.ts +5 -0
- package/dist/hooks/index.d.ts +14 -0
- package/dist/hooks/json-error-recovery/hook.d.ts +18 -0
- package/dist/hooks/json-error-recovery/index.d.ts +1 -0
- package/dist/hooks/phase-reminder/index.d.ts +26 -0
- package/dist/hooks/post-file-tool-nudge/index.d.ts +19 -0
- package/dist/hooks/task-session-manager/index.d.ts +52 -0
- package/dist/hooks/todo-continuation/index.d.ts +53 -0
- package/dist/hooks/todo-continuation/todo-hygiene.d.ts +35 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +31782 -0
- package/dist/mcp/context7.d.ts +6 -0
- package/dist/mcp/grep-app.d.ts +6 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/types.d.ts +12 -0
- package/dist/mcp/websearch.d.ts +9 -0
- package/dist/skills/registry.d.ts +29 -0
- package/dist/subscriptions/accounts-store.d.ts +57 -0
- package/dist/subscriptions/index.d.ts +13 -0
- package/dist/subscriptions/neuralwatt-scraper.d.ts +14 -0
- package/dist/subscriptions/opencode-go-scraper.d.ts +27 -0
- package/dist/subscriptions/types.d.ts +115 -0
- package/dist/subscriptions/usage-service.d.ts +74 -0
- package/dist/tools/ast-grep/cli.d.ts +15 -0
- package/dist/tools/ast-grep/constants.d.ts +25 -0
- package/dist/tools/ast-grep/downloader.d.ts +5 -0
- package/dist/tools/ast-grep/index.d.ts +10 -0
- package/dist/tools/ast-grep/tools.d.ts +3 -0
- package/dist/tools/ast-grep/types.d.ts +30 -0
- package/dist/tools/ast-grep/utils.d.ts +4 -0
- package/dist/tools/delegate.d.ts +14 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/preset-manager.d.ts +27 -0
- package/dist/tools/smartfetch/binary.d.ts +3 -0
- package/dist/tools/smartfetch/cache.d.ts +6 -0
- package/dist/tools/smartfetch/constants.d.ts +12 -0
- package/dist/tools/smartfetch/index.d.ts +3 -0
- package/dist/tools/smartfetch/network.d.ts +38 -0
- package/dist/tools/smartfetch/secondary-model.d.ts +28 -0
- package/dist/tools/smartfetch/tool.d.ts +3 -0
- package/dist/tools/smartfetch/types.d.ts +122 -0
- package/dist/tools/smartfetch/utils.d.ts +18 -0
- package/dist/tui-state.d.ts +168 -0
- package/dist/tui.d.ts +37 -0
- package/dist/tui.js +1896 -0
- package/dist/utils/agent-variant.d.ts +63 -0
- package/dist/utils/compat.d.ts +30 -0
- package/dist/utils/env.d.ts +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/internal-initiator.d.ts +6 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/polling.d.ts +21 -0
- package/dist/utils/session-manager.d.ts +55 -0
- package/dist/utils/session.d.ts +90 -0
- package/dist/utils/subagent-depth.d.ts +35 -0
- package/dist/utils/system-collapse.d.ts +6 -0
- package/dist/utils/task.d.ts +4 -0
- package/dist/utils/zip-extractor.d.ts +1 -0
- package/index.ts +1 -0
- package/opencode-dux.schema.json +634 -0
- package/package.json +103 -0
- package/src/agents/descriptions.ts +55 -0
- package/src/agents/designer.test.ts +86 -0
- package/src/agents/designer.ts +154 -0
- package/src/agents/display-name.test.ts +186 -0
- package/src/agents/explorer.test.ts +79 -0
- package/src/agents/explorer.ts +144 -0
- package/src/agents/fixer.test.ts +79 -0
- package/src/agents/fixer.ts +145 -0
- package/src/agents/index.test.ts +472 -0
- package/src/agents/index.ts +248 -0
- package/src/agents/interpreter.ts +136 -0
- package/src/agents/librarian.test.ts +80 -0
- package/src/agents/librarian.ts +145 -0
- package/src/agents/oracle.test.ts +89 -0
- package/src/agents/oracle.ts +184 -0
- package/src/agents/orchestrator.test.ts +116 -0
- package/src/agents/orchestrator.ts +574 -0
- package/src/agents/overrides.ts +95 -0
- package/src/agents/prompt-blocks.test.ts +114 -0
- package/src/agents/prompt-blocks.ts +640 -0
- package/src/agents/steward.ts +146 -0
- package/src/cli/config-io.test.ts +536 -0
- package/src/cli/config-io.ts +473 -0
- package/src/cli/config-manager.test.ts +141 -0
- package/src/cli/config-manager.ts +4 -0
- package/src/cli/index.ts +88 -0
- package/src/cli/install.ts +282 -0
- package/src/cli/mcps.test.ts +62 -0
- package/src/cli/mcps.ts +39 -0
- package/src/cli/model-key-normalization.test.ts +21 -0
- package/src/cli/model-key-normalization.ts +60 -0
- package/src/cli/paths.test.ts +167 -0
- package/src/cli/paths.ts +144 -0
- package/src/cli/providers.test.ts +118 -0
- package/src/cli/providers.ts +141 -0
- package/src/cli/skills.test.ts +111 -0
- package/src/cli/skills.ts +103 -0
- package/src/cli/system.test.ts +91 -0
- package/src/cli/system.ts +180 -0
- package/src/cli/types.ts +43 -0
- package/src/config/constants.ts +58 -0
- package/src/config/index.ts +4 -0
- package/src/config/loader.test.ts +1194 -0
- package/src/config/loader.ts +269 -0
- package/src/config/model-resolution.test.ts +176 -0
- package/src/config/runtime-preset.test.ts +61 -0
- package/src/config/runtime-preset.ts +37 -0
- package/src/config/schema.ts +248 -0
- package/src/config/utils.test.ts +41 -0
- package/src/config/utils.ts +23 -0
- package/src/discovery/local/types.ts +85 -0
- package/src/discovery/local.ts +322 -0
- package/src/discovery/mcp-servers.ts +804 -0
- package/src/discovery/skills.ts +959 -0
- package/src/hooks/apply-patch/codec.test.ts +184 -0
- package/src/hooks/apply-patch/codec.ts +352 -0
- package/src/hooks/apply-patch/errors.ts +117 -0
- package/src/hooks/apply-patch/execution-context.ts +432 -0
- package/src/hooks/apply-patch/hook.test.ts +768 -0
- package/src/hooks/apply-patch/index.ts +126 -0
- package/src/hooks/apply-patch/matching.test.ts +215 -0
- package/src/hooks/apply-patch/matching.ts +586 -0
- package/src/hooks/apply-patch/operations.test.ts +1535 -0
- package/src/hooks/apply-patch/operations.ts +3 -0
- package/src/hooks/apply-patch/patch.ts +9 -0
- package/src/hooks/apply-patch/prepared-changes.ts +400 -0
- package/src/hooks/apply-patch/resolution.test.ts +420 -0
- package/src/hooks/apply-patch/resolution.ts +437 -0
- package/src/hooks/apply-patch/rewrite.ts +496 -0
- package/src/hooks/apply-patch/test-helpers.ts +52 -0
- package/src/hooks/apply-patch/types.ts +111 -0
- package/src/hooks/auto-update-checker/cache.test.ts +179 -0
- package/src/hooks/auto-update-checker/cache.ts +188 -0
- package/src/hooks/auto-update-checker/checker.test.ts +159 -0
- package/src/hooks/auto-update-checker/checker.ts +308 -0
- package/src/hooks/auto-update-checker/constants.ts +33 -0
- package/src/hooks/auto-update-checker/index.test.ts +282 -0
- package/src/hooks/auto-update-checker/index.ts +225 -0
- package/src/hooks/auto-update-checker/types.ts +26 -0
- package/src/hooks/chat-headers.test.ts +236 -0
- package/src/hooks/chat-headers.ts +97 -0
- package/src/hooks/context-pressure-reminder/index.test.ts +179 -0
- package/src/hooks/context-pressure-reminder/index.ts +137 -0
- package/src/hooks/delegate-task-retry/guidance.ts +41 -0
- package/src/hooks/delegate-task-retry/hook.ts +23 -0
- package/src/hooks/delegate-task-retry/index.test.ts +38 -0
- package/src/hooks/delegate-task-retry/index.ts +7 -0
- package/src/hooks/delegate-task-retry/patterns.ts +79 -0
- package/src/hooks/filter-available-skills/index.test.ts +297 -0
- package/src/hooks/filter-available-skills/index.ts +160 -0
- package/src/hooks/foreground-fallback/index.test.ts +624 -0
- package/src/hooks/foreground-fallback/index.ts +374 -0
- package/src/hooks/image-hook.ts +6 -0
- package/src/hooks/index.ts +17 -0
- package/src/hooks/json-error-recovery/hook.ts +73 -0
- package/src/hooks/json-error-recovery/index.test.ts +111 -0
- package/src/hooks/json-error-recovery/index.ts +6 -0
- package/src/hooks/phase-reminder/index.test.ts +74 -0
- package/src/hooks/phase-reminder/index.ts +85 -0
- package/src/hooks/post-file-tool-nudge/index.test.ts +94 -0
- package/src/hooks/post-file-tool-nudge/index.ts +63 -0
- package/src/hooks/task-session-manager/index.test.ts +833 -0
- package/src/hooks/task-session-manager/index.ts +434 -0
- package/src/hooks/todo-continuation/index.test.ts +3026 -0
- package/src/hooks/todo-continuation/index.ts +878 -0
- package/src/hooks/todo-continuation/todo-hygiene.test.ts +204 -0
- package/src/hooks/todo-continuation/todo-hygiene.ts +207 -0
- package/src/index.ts +1672 -0
- package/src/mcp/context7.ts +14 -0
- package/src/mcp/grep-app.ts +11 -0
- package/src/mcp/index.test.ts +96 -0
- package/src/mcp/index.ts +66 -0
- package/src/mcp/types.ts +16 -0
- package/src/mcp/websearch.ts +47 -0
- package/src/skills/codemap/README.md +60 -0
- package/src/skills/codemap/SKILL.md +174 -0
- package/src/skills/codemap/scripts/codemap.mjs +483 -0
- package/src/skills/codemap/scripts/codemap.test.ts +129 -0
- package/src/skills/registry.ts +218 -0
- package/src/skills/simplify/README.md +19 -0
- package/src/skills/simplify/SKILL.md +138 -0
- package/src/subscriptions/accounts-store.test.ts +236 -0
- package/src/subscriptions/accounts-store.ts +184 -0
- package/src/subscriptions/index.ts +30 -0
- package/src/subscriptions/neuralwatt-scraper.ts +108 -0
- package/src/subscriptions/opencode-go-scraper.ts +301 -0
- package/src/subscriptions/types.ts +145 -0
- package/src/subscriptions/usage-service.test.ts +202 -0
- package/src/subscriptions/usage-service.ts +651 -0
- package/src/tools/ast-grep/cli.ts +257 -0
- package/src/tools/ast-grep/constants.ts +214 -0
- package/src/tools/ast-grep/downloader.ts +131 -0
- package/src/tools/ast-grep/index.ts +24 -0
- package/src/tools/ast-grep/tools.ts +117 -0
- package/src/tools/ast-grep/types.ts +51 -0
- package/src/tools/ast-grep/utils.ts +126 -0
- package/src/tools/delegate-handoff.test.ts +18 -0
- package/src/tools/delegate.ts +508 -0
- package/src/tools/index.ts +8 -0
- package/src/tools/preset-manager.test.ts +795 -0
- package/src/tools/preset-manager.ts +332 -0
- package/src/tools/smartfetch/binary.ts +58 -0
- package/src/tools/smartfetch/cache.test.ts +34 -0
- package/src/tools/smartfetch/cache.ts +112 -0
- package/src/tools/smartfetch/constants.ts +29 -0
- package/src/tools/smartfetch/index.ts +8 -0
- package/src/tools/smartfetch/network.test.ts +178 -0
- package/src/tools/smartfetch/network.ts +614 -0
- package/src/tools/smartfetch/secondary-model.test.ts +85 -0
- package/src/tools/smartfetch/secondary-model.ts +276 -0
- package/src/tools/smartfetch/tool.test.ts +60 -0
- package/src/tools/smartfetch/tool.ts +832 -0
- package/src/tools/smartfetch/types.ts +135 -0
- package/src/tools/smartfetch/utils.test.ts +24 -0
- package/src/tools/smartfetch/utils.ts +456 -0
- package/src/tui-state.test.ts +867 -0
- package/src/tui-state.ts +1255 -0
- package/src/tui.test.ts +336 -0
- package/src/tui.ts +1539 -0
- package/src/utils/agent-variant.test.ts +244 -0
- package/src/utils/agent-variant.ts +187 -0
- package/src/utils/compat.ts +91 -0
- package/src/utils/env.ts +12 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/internal-initiator.ts +28 -0
- package/src/utils/logger.test.ts +220 -0
- package/src/utils/logger.ts +136 -0
- package/src/utils/polling.test.ts +191 -0
- package/src/utils/polling.ts +67 -0
- package/src/utils/session-manager.test.ts +173 -0
- package/src/utils/session-manager.ts +356 -0
- package/src/utils/session.test.ts +110 -0
- package/src/utils/session.ts +389 -0
- package/src/utils/subagent-depth.test.ts +170 -0
- package/src/utils/subagent-depth.ts +75 -0
- package/src/utils/system-collapse.test.ts +86 -0
- package/src/utils/system-collapse.ts +24 -0
- package/src/utils/task.test.ts +24 -0
- package/src/utils/task.ts +20 -0
- package/src/utils/zip-extractor.ts +102 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/// <reference types="bun-types" />
|
|
2
|
+
|
|
3
|
+
import { describe, expect, mock, test } from 'bun:test';
|
|
4
|
+
import {
|
|
5
|
+
chmodSync,
|
|
6
|
+
mkdirSync,
|
|
7
|
+
mkdtempSync,
|
|
8
|
+
rmSync,
|
|
9
|
+
writeFileSync,
|
|
10
|
+
} from 'node:fs';
|
|
11
|
+
import { tmpdir } from 'node:os';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import {
|
|
14
|
+
fetchLatestVersion,
|
|
15
|
+
getOpenCodeVersion,
|
|
16
|
+
isOpenCodeInstalled,
|
|
17
|
+
} from './system';
|
|
18
|
+
|
|
19
|
+
describe('system', () => {
|
|
20
|
+
test('isOpenCodeInstalled detects opencode in ~/.opencode/bin', async () => {
|
|
21
|
+
const dir = mkdtempSync(join(tmpdir(), 'opencode-system-test-'));
|
|
22
|
+
const originalPath = process.env.PATH;
|
|
23
|
+
const originalHome = process.env.HOME;
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const opencodePath = join(dir, '.opencode', 'bin', 'opencode');
|
|
27
|
+
mkdirSync(join(dir, '.opencode', 'bin'), { recursive: true });
|
|
28
|
+
writeFileSync(opencodePath, '#!/bin/sh\necho 1.2.3\n');
|
|
29
|
+
chmodSync(opencodePath, 0o755);
|
|
30
|
+
process.env.HOME = dir;
|
|
31
|
+
process.env.PATH = '/usr/bin:/bin:/usr/sbin:/sbin';
|
|
32
|
+
|
|
33
|
+
const system = await import(`./system?test=home-detect-${Date.now()}`);
|
|
34
|
+
expect(await system.isOpenCodeInstalled()).toBe(true);
|
|
35
|
+
} finally {
|
|
36
|
+
process.env.PATH = originalPath;
|
|
37
|
+
process.env.HOME = originalHome;
|
|
38
|
+
rmSync(dir, { recursive: true, force: true });
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('isOpenCodeInstalled returns boolean', async () => {
|
|
43
|
+
// We don't necessarily want to depend on the host system
|
|
44
|
+
// but for a basic test we can just check it returns a boolean
|
|
45
|
+
const result = await isOpenCodeInstalled();
|
|
46
|
+
expect(typeof result).toBe('boolean');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('fetchLatestVersion returns version string or null', async () => {
|
|
50
|
+
// Mock global fetch
|
|
51
|
+
const originalFetch = globalThis.fetch;
|
|
52
|
+
globalThis.fetch = mock(async () => {
|
|
53
|
+
return {
|
|
54
|
+
ok: true,
|
|
55
|
+
json: async () => ({ version: '1.2.3' }),
|
|
56
|
+
};
|
|
57
|
+
}) as any;
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const version = await fetchLatestVersion('any-package');
|
|
61
|
+
expect(version).toBe('1.2.3');
|
|
62
|
+
} finally {
|
|
63
|
+
globalThis.fetch = originalFetch;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('fetchLatestVersion returns null on error', async () => {
|
|
68
|
+
const originalFetch = globalThis.fetch;
|
|
69
|
+
try {
|
|
70
|
+
globalThis.fetch = mock(async () => {
|
|
71
|
+
return {
|
|
72
|
+
ok: false,
|
|
73
|
+
};
|
|
74
|
+
}) as any;
|
|
75
|
+
|
|
76
|
+
const version = await fetchLatestVersion('any-package');
|
|
77
|
+
expect(version).toBeNull();
|
|
78
|
+
} finally {
|
|
79
|
+
globalThis.fetch = originalFetch;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('getOpenCodeVersion returns string or null', async () => {
|
|
84
|
+
const version = await getOpenCodeVersion();
|
|
85
|
+
if (version !== null) {
|
|
86
|
+
expect(typeof version).toBe('string');
|
|
87
|
+
} else {
|
|
88
|
+
expect(version).toBeNull();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { statSync } from 'node:fs';
|
|
3
|
+
import { crossSpawn } from '../utils/compat';
|
|
4
|
+
|
|
5
|
+
let cachedOpenCodePath: string | null = null;
|
|
6
|
+
|
|
7
|
+
function resolvePathCommand(command: string): string | null {
|
|
8
|
+
try {
|
|
9
|
+
const resolver = process.platform === 'win32' ? 'where' : 'which';
|
|
10
|
+
const result = spawnSync(resolver, [command], {
|
|
11
|
+
encoding: 'utf-8',
|
|
12
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
if (result.status !== 0) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const resolved = result.stdout
|
|
20
|
+
.split(/\r?\n/)
|
|
21
|
+
.map((line) => line.trim())
|
|
22
|
+
.find(Boolean);
|
|
23
|
+
|
|
24
|
+
return resolved ?? null;
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function canExecute(command: string, args: string[]): boolean {
|
|
31
|
+
try {
|
|
32
|
+
const result = spawnSync(command, args, {
|
|
33
|
+
stdio: 'ignore',
|
|
34
|
+
});
|
|
35
|
+
return result.status === 0;
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getOpenCodePaths(): string[] {
|
|
42
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
43
|
+
|
|
44
|
+
return [
|
|
45
|
+
// PATH (try this first)
|
|
46
|
+
'opencode',
|
|
47
|
+
// User local installations (Linux & macOS)
|
|
48
|
+
`${home}/.local/bin/opencode`,
|
|
49
|
+
`${home}/.opencode/bin/opencode`,
|
|
50
|
+
`${home}/bin/opencode`,
|
|
51
|
+
// System-wide installations
|
|
52
|
+
'/usr/local/bin/opencode',
|
|
53
|
+
'/opt/opencode/bin/opencode',
|
|
54
|
+
'/usr/bin/opencode',
|
|
55
|
+
'/bin/opencode',
|
|
56
|
+
// macOS specific
|
|
57
|
+
'/Applications/OpenCode.app/Contents/MacOS/opencode',
|
|
58
|
+
`${home}/Applications/OpenCode.app/Contents/MacOS/opencode`,
|
|
59
|
+
// Homebrew (macOS & Linux)
|
|
60
|
+
'/opt/homebrew/bin/opencode',
|
|
61
|
+
'/home/linuxbrew/.linuxbrew/bin/opencode',
|
|
62
|
+
`${home}/homebrew/bin/opencode`,
|
|
63
|
+
// macOS user Library
|
|
64
|
+
`${home}/Library/Application Support/opencode/bin/opencode`,
|
|
65
|
+
// Snap (Linux)
|
|
66
|
+
'/snap/bin/opencode',
|
|
67
|
+
'/var/snap/opencode/current/bin/opencode',
|
|
68
|
+
// Flatpak (Linux)
|
|
69
|
+
'/var/lib/flatpak/exports/bin/ai.opencode.OpenCode',
|
|
70
|
+
`${home}/.local/share/flatpak/exports/bin/ai.opencode.OpenCode`,
|
|
71
|
+
// Nix (Linux/macOS)
|
|
72
|
+
'/nix/store/opencode/bin/opencode',
|
|
73
|
+
`${home}/.nix-profile/bin/opencode`,
|
|
74
|
+
'/run/current-system/sw/bin/opencode',
|
|
75
|
+
// Cargo (Rust toolchain)
|
|
76
|
+
`${home}/.cargo/bin/opencode`,
|
|
77
|
+
// npm/npx global
|
|
78
|
+
`${home}/.npm-global/bin/opencode`,
|
|
79
|
+
'/usr/local/lib/node_modules/opencode/bin/opencode',
|
|
80
|
+
// Yarn global
|
|
81
|
+
`${home}/.yarn/bin/opencode`,
|
|
82
|
+
// PNPM
|
|
83
|
+
`${home}/.pnpm-global/bin/opencode`,
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function resolveOpenCodePath(): string {
|
|
88
|
+
if (cachedOpenCodePath) {
|
|
89
|
+
return cachedOpenCodePath;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const pathOpenCodePath = resolvePathCommand('opencode');
|
|
93
|
+
if (pathOpenCodePath) {
|
|
94
|
+
cachedOpenCodePath = pathOpenCodePath;
|
|
95
|
+
return pathOpenCodePath;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const paths = getOpenCodePaths();
|
|
99
|
+
|
|
100
|
+
for (const opencodePath of paths) {
|
|
101
|
+
if (opencodePath === 'opencode') continue;
|
|
102
|
+
try {
|
|
103
|
+
const stat = statSync(opencodePath);
|
|
104
|
+
if (stat.isFile()) {
|
|
105
|
+
cachedOpenCodePath = opencodePath;
|
|
106
|
+
return opencodePath;
|
|
107
|
+
}
|
|
108
|
+
} catch {
|
|
109
|
+
// Try next path
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Fallback to 'opencode' and hope it's in PATH
|
|
114
|
+
return 'opencode';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function isOpenCodeInstalled(): Promise<boolean> {
|
|
118
|
+
const pathOpenCodePath = resolvePathCommand('opencode');
|
|
119
|
+
|
|
120
|
+
if (pathOpenCodePath && canExecute(pathOpenCodePath, ['--version'])) {
|
|
121
|
+
cachedOpenCodePath = pathOpenCodePath;
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const paths = getOpenCodePaths();
|
|
126
|
+
|
|
127
|
+
for (const opencodePath of paths) {
|
|
128
|
+
if (opencodePath === 'opencode') continue;
|
|
129
|
+
try {
|
|
130
|
+
const proc = crossSpawn([opencodePath, '--version'], {
|
|
131
|
+
stdout: 'pipe',
|
|
132
|
+
stderr: 'pipe',
|
|
133
|
+
});
|
|
134
|
+
await proc.exited;
|
|
135
|
+
if (proc.exitCode === 0) {
|
|
136
|
+
cachedOpenCodePath = opencodePath;
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
} catch {
|
|
140
|
+
// Try next path
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export async function getOpenCodeVersion(): Promise<string | null> {
|
|
147
|
+
const opencodePath = resolveOpenCodePath();
|
|
148
|
+
try {
|
|
149
|
+
const proc = crossSpawn([opencodePath, '--version'], {
|
|
150
|
+
stdout: 'pipe',
|
|
151
|
+
stderr: 'pipe',
|
|
152
|
+
});
|
|
153
|
+
const outputPromise = proc.stdout();
|
|
154
|
+
await proc.exited;
|
|
155
|
+
if (proc.exitCode === 0) {
|
|
156
|
+
return (await outputPromise).trim();
|
|
157
|
+
}
|
|
158
|
+
} catch {
|
|
159
|
+
// Failed
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function getOpenCodePath(): string | null {
|
|
165
|
+
const path = resolveOpenCodePath();
|
|
166
|
+
return path === 'opencode' ? null : path;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export async function fetchLatestVersion(
|
|
170
|
+
packageName: string,
|
|
171
|
+
): Promise<string | null> {
|
|
172
|
+
try {
|
|
173
|
+
const res = await fetch(`https://registry.npmjs.org/${packageName}/latest`);
|
|
174
|
+
if (!res.ok) return null;
|
|
175
|
+
const data = (await res.json()) as { version: string };
|
|
176
|
+
return data.version;
|
|
177
|
+
} catch {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
package/src/cli/types.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type BooleanArg = 'yes' | 'no';
|
|
2
|
+
|
|
3
|
+
export interface InstallArgs {
|
|
4
|
+
tui: boolean;
|
|
5
|
+
skills?: BooleanArg;
|
|
6
|
+
preset?: string;
|
|
7
|
+
dryRun?: boolean;
|
|
8
|
+
reset?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface OpenCodeConfig {
|
|
12
|
+
plugin?: unknown[];
|
|
13
|
+
provider?: Record<string, unknown>;
|
|
14
|
+
agent?: Record<string, unknown>;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface InstallConfig {
|
|
19
|
+
installSkills: boolean;
|
|
20
|
+
installCustomSkills: boolean;
|
|
21
|
+
preset?: string;
|
|
22
|
+
promptForStar?: boolean;
|
|
23
|
+
dryRun?: boolean;
|
|
24
|
+
reset: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ConfigMergeResult {
|
|
28
|
+
success: boolean;
|
|
29
|
+
configPath: string;
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface DetectedConfig {
|
|
34
|
+
isInstalled: boolean;
|
|
35
|
+
hasKimi: boolean;
|
|
36
|
+
hasOpenAI: boolean;
|
|
37
|
+
hasAnthropic?: boolean;
|
|
38
|
+
hasCopilot?: boolean;
|
|
39
|
+
hasZaiPlan?: boolean;
|
|
40
|
+
hasAntigravity: boolean;
|
|
41
|
+
hasChutes?: boolean;
|
|
42
|
+
hasOpencodeZen: boolean;
|
|
43
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Agent names
|
|
2
|
+
export const AGENT_ALIASES: Record<string, string> = {
|
|
3
|
+
explore: 'explorer',
|
|
4
|
+
'frontend-ui-ux-engineer': 'designer',
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const SUBAGENT_NAMES = [
|
|
8
|
+
'explorer',
|
|
9
|
+
'librarian',
|
|
10
|
+
'oracle',
|
|
11
|
+
'designer',
|
|
12
|
+
'fixer',
|
|
13
|
+
'steward',
|
|
14
|
+
'interpreter',
|
|
15
|
+
] as const;
|
|
16
|
+
|
|
17
|
+
export const ORCHESTRATOR_NAME = 'orchestrator' as const;
|
|
18
|
+
|
|
19
|
+
export const ALL_AGENT_NAMES = [ORCHESTRATOR_NAME, ...SUBAGENT_NAMES] as const;
|
|
20
|
+
|
|
21
|
+
// Agent name type (for use in DEFAULT_MODELS)
|
|
22
|
+
export type AgentName = (typeof ALL_AGENT_NAMES)[number];
|
|
23
|
+
|
|
24
|
+
// Default models for each agent
|
|
25
|
+
// Hybrid NeuralWatt + OpenCode-Go strategy:
|
|
26
|
+
// - Orchestrator on NeuralWatt GLM-5.1 (energy-efficient, strong routing)
|
|
27
|
+
// - Explorer on NeuralWatt Qwen3.5-397B-Fast (cheap MoE, tool-calling, no reasoning overhead)
|
|
28
|
+
// - Oracle, Librarian, Designer, Fixer on OpenCode-Go (proven reliability)
|
|
29
|
+
export const DEFAULT_MODELS: Record<AgentName, string | undefined> = {
|
|
30
|
+
orchestrator: 'neuralwatt/zai-org/GLM-5.1-FP8',
|
|
31
|
+
oracle: 'opencode-go/deepseek-v4-flash',
|
|
32
|
+
librarian: 'opencode-go/deepseek-v4-flash',
|
|
33
|
+
explorer: 'neuralwatt/qwen3.5-397b-fast',
|
|
34
|
+
designer: 'opencode-go/mimo-v2.5-pro',
|
|
35
|
+
fixer: 'opencode-go/deepseek-v4-flash',
|
|
36
|
+
steward: 'opencode-go/deepseek-v4-flash',
|
|
37
|
+
interpreter: 'opencode-go/mimo-v2.5-pro',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Polling configuration
|
|
41
|
+
export const POLL_INTERVAL_MS = 500;
|
|
42
|
+
|
|
43
|
+
// Timeouts
|
|
44
|
+
export const MAX_POLL_TIME_MS = 5 * 60 * 1000; // 5 minutes
|
|
45
|
+
|
|
46
|
+
// Subagent depth limits
|
|
47
|
+
export const DEFAULT_MAX_SUBAGENT_DEPTH = 10;
|
|
48
|
+
|
|
49
|
+
// Workflow reminders
|
|
50
|
+
export const PHASE_REMINDER_TEXT = `!IMPORTANT! Follow <first_gate> order in system prompt; delegate_subagent in the same turn you name the agent. !END!`;
|
|
51
|
+
|
|
52
|
+
// Polling stability
|
|
53
|
+
export const STABLE_POLLS_THRESHOLD = 3;
|
|
54
|
+
|
|
55
|
+
// SDK discovery timeout for local MCP/skill scans (milliseconds).
|
|
56
|
+
// Prevents plugin init from hanging when the SDK is not ready.
|
|
57
|
+
// Adjustable via config override at build/runtime.
|
|
58
|
+
export const SDK_DISCOVERY_TIMEOUT_MS = 10_000; // 10 seconds
|