open-multi-agent-kit 0.95.0 → 0.95.2
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/CHANGELOG.md +33 -0
- package/README.md +1 -1
- package/dist/approvals/approval-receipt-store.d.ts +18 -0
- package/dist/approvals/approval-receipt-store.d.ts.map +1 -0
- package/dist/approvals/approval-receipt-store.js +169 -0
- package/dist/approvals/approval-receipt-store.js.map +1 -0
- package/dist/approvals/approval-receipt.d.ts +43 -0
- package/dist/approvals/approval-receipt.d.ts.map +1 -0
- package/dist/approvals/approval-receipt.js +208 -0
- package/dist/approvals/approval-receipt.js.map +1 -0
- package/dist/approvals/approval-verifier.d.ts +17 -0
- package/dist/approvals/approval-verifier.d.ts.map +1 -0
- package/dist/approvals/approval-verifier.js +23 -0
- package/dist/approvals/approval-verifier.js.map +1 -0
- package/dist/approvals/plannotator-approval-bridge.d.ts +58 -0
- package/dist/approvals/plannotator-approval-bridge.d.ts.map +1 -0
- package/dist/approvals/plannotator-approval-bridge.js +169 -0
- package/dist/approvals/plannotator-approval-bridge.js.map +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/commands/package-doctor-cli.d.ts +13 -0
- package/dist/commands/package-doctor-cli.d.ts.map +1 -0
- package/dist/commands/package-doctor-cli.js +80 -0
- package/dist/commands/package-doctor-cli.js.map +1 -0
- package/dist/commands/router-feedback-cli.d.ts +11 -0
- package/dist/commands/router-feedback-cli.d.ts.map +1 -0
- package/dist/commands/router-feedback-cli.js +99 -0
- package/dist/commands/router-feedback-cli.js.map +1 -0
- package/dist/commands/stats-cli.d.ts +20 -0
- package/dist/commands/stats-cli.d.ts.map +1 -0
- package/dist/commands/stats-cli.js +99 -0
- package/dist/commands/stats-cli.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +4 -1
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +97 -29
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +583 -199
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +8 -2
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/transaction.d.ts +9 -0
- package/dist/core/compaction/transaction.d.ts.map +1 -1
- package/dist/core/compaction/transaction.js +17 -2
- package/dist/core/compaction/transaction.js.map +1 -1
- package/dist/core/context-budget-governor-v2.d.ts +1 -1
- package/dist/core/context-budget-governor-v2.d.ts.map +1 -1
- package/dist/core/context-budget-governor-v2.js +1 -1
- package/dist/core/context-budget-governor-v2.js.map +1 -1
- package/dist/core/context-budget-system-prompt.d.ts.map +1 -1
- package/dist/core/context-budget-system-prompt.js +18 -2
- package/dist/core/context-budget-system-prompt.js.map +1 -1
- package/dist/core/context-budget-v2-cache-disk.d.ts +109 -0
- package/dist/core/context-budget-v2-cache-disk.d.ts.map +1 -0
- package/dist/core/context-budget-v2-cache-disk.js +343 -0
- package/dist/core/context-budget-v2-cache-disk.js.map +1 -0
- package/dist/core/context-budget-v2-cache-keys.d.ts +22 -0
- package/dist/core/context-budget-v2-cache-keys.d.ts.map +1 -1
- package/dist/core/context-budget-v2-cache-keys.js +4 -4
- package/dist/core/context-budget-v2-cache-keys.js.map +1 -1
- package/dist/core/context-budget-v2-cache.d.ts +1 -0
- package/dist/core/context-budget-v2-cache.d.ts.map +1 -1
- package/dist/core/context-budget-v2-cache.js +1 -0
- package/dist/core/context-budget-v2-cache.js.map +1 -1
- package/dist/core/context-budget-v2-plan-cache-keys.d.ts.map +1 -1
- package/dist/core/context-budget-v2-plan-cache-keys.js +39 -5
- package/dist/core/context-budget-v2-plan-cache-keys.js.map +1 -1
- package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planner.js +17 -14
- package/dist/core/context-budget-v2-planner.js.map +1 -1
- package/dist/core/context-budget-v2-types.d.ts +1 -0
- package/dist/core/context-budget-v2-types.d.ts.map +1 -1
- package/dist/core/context-budget-v2-types.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +45 -22
- package/dist/core/extensions/loader.js.bak-sharedjiti-20260812-111246 +553 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +4 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/headroom.d.ts.map +1 -1
- package/dist/core/headroom.js +7 -2
- package/dist/core/headroom.js.map +1 -1
- package/dist/core/mcp/client.d.ts +105 -0
- package/dist/core/mcp/client.d.ts.map +1 -0
- package/dist/core/mcp/client.js +198 -0
- package/dist/core/mcp/client.js.map +1 -0
- package/dist/core/mcp/config.d.ts +23 -0
- package/dist/core/mcp/config.d.ts.map +1 -0
- package/dist/core/mcp/config.js +89 -0
- package/dist/core/mcp/config.js.map +1 -0
- package/dist/core/mcp/index.d.ts +15 -0
- package/dist/core/mcp/index.d.ts.map +1 -0
- package/dist/core/mcp/index.js +15 -0
- package/dist/core/mcp/index.js.map +1 -0
- package/dist/core/mcp/manager.d.ts +84 -0
- package/dist/core/mcp/manager.d.ts.map +1 -0
- package/dist/core/mcp/manager.js +173 -0
- package/dist/core/mcp/manager.js.map +1 -0
- package/dist/core/mcp/protocol.d.ts +59 -0
- package/dist/core/mcp/protocol.d.ts.map +1 -0
- package/dist/core/mcp/protocol.js +103 -0
- package/dist/core/mcp/protocol.js.map +1 -0
- package/dist/core/mcp/stdio-transport.d.ts +63 -0
- package/dist/core/mcp/stdio-transport.d.ts.map +1 -0
- package/dist/core/mcp/stdio-transport.js +132 -0
- package/dist/core/mcp/stdio-transport.js.map +1 -0
- package/dist/core/mcp/tools.d.ts +47 -0
- package/dist/core/mcp/tools.d.ts.map +1 -0
- package/dist/core/mcp/tools.js +102 -0
- package/dist/core/mcp/tools.js.map +1 -0
- package/dist/core/package-archive.d.ts +3 -0
- package/dist/core/package-archive.d.ts.map +1 -0
- package/dist/core/package-archive.js +161 -0
- package/dist/core/package-archive.js.map +1 -0
- package/dist/core/package-doctor-source-scan.d.ts +13 -0
- package/dist/core/package-doctor-source-scan.d.ts.map +1 -0
- package/dist/core/package-doctor-source-scan.js +124 -0
- package/dist/core/package-doctor-source-scan.js.map +1 -0
- package/dist/core/package-doctor.d.ts +41 -0
- package/dist/core/package-doctor.d.ts.map +1 -0
- package/dist/core/package-doctor.js +145 -0
- package/dist/core/package-doctor.js.map +1 -0
- package/dist/core/package-manager.d.ts +10 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +175 -42
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/package-manifest.d.ts +26 -0
- package/dist/core/package-manifest.d.ts.map +1 -0
- package/dist/core/package-manifest.js +85 -0
- package/dist/core/package-manifest.js.map +1 -0
- package/dist/core/pi-compat.d.ts +5 -0
- package/dist/core/pi-compat.d.ts.map +1 -0
- package/dist/core/pi-compat.js +18 -0
- package/dist/core/pi-compat.js.map +1 -0
- package/dist/core/reasoning-router-bias.d.ts +10 -14
- package/dist/core/reasoning-router-bias.d.ts.map +1 -1
- package/dist/core/reasoning-router-bias.js +22 -15
- package/dist/core/reasoning-router-bias.js.map +1 -1
- package/dist/core/reasoning-router-v4.d.ts +9 -1
- package/dist/core/reasoning-router-v4.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4.js +20 -5
- package/dist/core/reasoning-router-v4.js.map +1 -1
- package/dist/core/redaction.d.ts +2 -5
- package/dist/core/redaction.d.ts.map +1 -1
- package/dist/core/redaction.js +14 -1
- package/dist/core/redaction.js.map +1 -1
- package/dist/core/repository-learning-scope.d.ts +10 -0
- package/dist/core/repository-learning-scope.d.ts.map +1 -0
- package/dist/core/repository-learning-scope.js +42 -0
- package/dist/core/repository-learning-scope.js.map +1 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +16 -1
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/router-feedback-collector.d.ts +2 -1
- package/dist/core/router-feedback-collector.d.ts.map +1 -1
- package/dist/core/router-feedback-collector.js +2 -2
- package/dist/core/router-feedback-collector.js.map +1 -1
- package/dist/core/runtime-provenance.d.ts +54 -0
- package/dist/core/runtime-provenance.d.ts.map +1 -0
- package/dist/core/runtime-provenance.js +115 -0
- package/dist/core/runtime-provenance.js.map +1 -0
- package/dist/core/sandbox/backend.d.ts.map +1 -1
- package/dist/core/sandbox/backend.js +39 -21
- package/dist/core/sandbox/backend.js.map +1 -1
- package/dist/core/sandbox/default-policy.d.ts +4 -5
- package/dist/core/sandbox/default-policy.d.ts.map +1 -1
- package/dist/core/sandbox/default-policy.js +9 -11
- package/dist/core/sandbox/default-policy.js.map +1 -1
- package/dist/core/session-bash-runtime.d.ts +4 -4
- package/dist/core/session-bash-runtime.d.ts.map +1 -1
- package/dist/core/session-bash-runtime.js +6 -5
- package/dist/core/session-bash-runtime.js.map +1 -1
- package/dist/core/session-compaction-service.d.ts.map +1 -1
- package/dist/core/session-compaction-service.js +7 -7
- package/dist/core/session-compaction-service.js.map +1 -1
- package/dist/core/session-manager.d.ts +4 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +47 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +7 -4
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +11 -3
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts +9 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +10 -4
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +2 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +15 -0
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/turn-metrics.d.ts +135 -0
- package/dist/core/turn-metrics.d.ts.map +1 -0
- package/dist/core/turn-metrics.js +261 -0
- package/dist/core/turn-metrics.js.map +1 -0
- package/dist/core/verified-bash-runtime.d.ts.map +1 -1
- package/dist/core/verified-bash-runtime.js +10 -4
- package/dist/core/verified-bash-runtime.js.map +1 -1
- package/dist/guardrails/replay-ledger-lock-owner.d.ts +7 -0
- package/dist/guardrails/replay-ledger-lock-owner.d.ts.map +1 -1
- package/dist/guardrails/replay-ledger-lock-owner.js +39 -0
- package/dist/guardrails/replay-ledger-lock-owner.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +18 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/control-panel-layout.d.ts.map +1 -1
- package/dist/modes/interactive/components/control-panel-layout.js +2 -2
- package/dist/modes/interactive/components/control-panel-layout.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +3 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +40 -12
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +10 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/status-sidebar.d.ts +14 -2
- package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-sidebar.js +106 -19
- package/dist/modes/interactive/components/status-sidebar.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +10 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +104 -17
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +1 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +1 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/docs/compaction.md +25 -3
- package/docs/containerization.md +14 -2
- package/docs/docs.json +8 -0
- package/docs/environment-variables.md +1 -1
- package/docs/extensions.md +75 -16
- package/docs/mcp.md +97 -0
- package/docs/metrics.md +87 -0
- package/docs/packages.md +25 -4
- package/docs/providers.md +1 -1
- package/docs/sdk.md +25 -4
- package/docs/settings.md +8 -7
- package/docs/usage.md +13 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/plannotator-approval-bridge.ts +83 -0
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/README.md +21 -11
- package/examples/extensions/subagent/adaptive-agent-runtime.ts +9 -3
- package/examples/extensions/subagent/agents/planner.md +1 -3
- package/examples/extensions/subagent/agents/reviewer.md +1 -3
- package/examples/extensions/subagent/agents/scout.md +1 -3
- package/examples/extensions/subagent/agents/worker.md +0 -1
- package/examples/extensions/subagent/agents.test.ts +9 -0
- package/examples/extensions/subagent/agents.ts +11 -4
- package/examples/extensions/subagent/deadline-budget.test.ts +32 -0
- package/examples/extensions/subagent/deadline-budget.ts +25 -1
- package/examples/extensions/subagent/fixtures/fake-omk-json.mjs +10 -0
- package/examples/extensions/subagent/index.ts +234 -55
- package/examples/extensions/subagent/subagent-execution-policy.test.ts +27 -0
- package/examples/extensions/subagent/subagent-extension-smoke.test.ts +167 -2
- package/examples/extensions/subagent/workflow-graph.test.ts +80 -0
- package/examples/extensions/subagent/workflow-graph.ts +89 -0
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +253 -439
- package/package.json +8 -8
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension loader - loads TypeScript extension modules using jiti.
|
|
3
|
+
*
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
import { createRequire } from "node:module";
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { createJiti } from "jiti/static";
|
|
10
|
+
import * as _bundledOmkAgentCore from "omk-agent-core";
|
|
11
|
+
import * as _bundledOmkAgentCoreNode from "omk-agent-core/node";
|
|
12
|
+
import * as _bundledOmkAi from "omk-ai";
|
|
13
|
+
import * as _bundledOmkAiOauth from "omk-ai/oauth";
|
|
14
|
+
import * as _bundledOmkTui from "omk-tui";
|
|
15
|
+
// Static imports of packages that extensions may use.
|
|
16
|
+
// These MUST be static so Bun bundles them into the compiled binary.
|
|
17
|
+
// The virtualModules option then makes them available to extensions.
|
|
18
|
+
import * as _bundledTypebox from "typebox";
|
|
19
|
+
import * as _bundledTypeboxCompile from "typebox/compile";
|
|
20
|
+
import * as _bundledTypeboxValue from "typebox/value";
|
|
21
|
+
import { CONFIG_DIR_NAME, getAgentDir, isBunBinary } from "../../config.js";
|
|
22
|
+
// NOTE: This import works because loader.ts exports are NOT re-exported from index.ts,
|
|
23
|
+
// avoiding a circular dependency. Extensions can import from open-multi-agent-kit.
|
|
24
|
+
import * as _bundledOmkCodingAgent from "../../index.js";
|
|
25
|
+
import { resolvePath } from "../../utils/paths.js";
|
|
26
|
+
import { createEventBus } from "../event-bus.js";
|
|
27
|
+
import { execCommand } from "../exec.js";
|
|
28
|
+
import { readPackageManifest } from "../package-manifest.js";
|
|
29
|
+
import { LEGACY_PI_RUNTIME_ALIASES } from "../pi-compat.js";
|
|
30
|
+
import { createSyntheticSourceInfo } from "../source-info.js";
|
|
31
|
+
const LEGACY_PI_VIRTUAL_TARGETS = {
|
|
32
|
+
"coding-agent": _bundledOmkCodingAgent,
|
|
33
|
+
"agent-core": _bundledOmkAgentCore,
|
|
34
|
+
"agent-core-node": _bundledOmkAgentCoreNode,
|
|
35
|
+
ai: _bundledOmkAi,
|
|
36
|
+
"ai-oauth": _bundledOmkAiOauth,
|
|
37
|
+
tui: _bundledOmkTui,
|
|
38
|
+
};
|
|
39
|
+
/** Modules available to extensions via virtualModules (for compiled Bun binary) */
|
|
40
|
+
const VIRTUAL_MODULES = {
|
|
41
|
+
...Object.fromEntries(Object.entries(LEGACY_PI_RUNTIME_ALIASES).map(([specifier, target]) => [
|
|
42
|
+
specifier,
|
|
43
|
+
LEGACY_PI_VIRTUAL_TARGETS[target],
|
|
44
|
+
])),
|
|
45
|
+
typebox: _bundledTypebox,
|
|
46
|
+
"typebox/compile": _bundledTypeboxCompile,
|
|
47
|
+
"typebox/value": _bundledTypeboxValue,
|
|
48
|
+
"@sinclair/typebox": _bundledTypebox,
|
|
49
|
+
"@sinclair/typebox/compile": _bundledTypeboxCompile,
|
|
50
|
+
"@sinclair/typebox/value": _bundledTypeboxValue,
|
|
51
|
+
"omk-agent-core": _bundledOmkAgentCore,
|
|
52
|
+
"omk-agent-core/node": _bundledOmkAgentCoreNode,
|
|
53
|
+
"omk-tui": _bundledOmkTui,
|
|
54
|
+
"omk-ai": _bundledOmkAi,
|
|
55
|
+
"omk-ai/oauth": _bundledOmkAiOauth,
|
|
56
|
+
"open-multi-agent-kit": _bundledOmkCodingAgent,
|
|
57
|
+
};
|
|
58
|
+
const require = createRequire(import.meta.url);
|
|
59
|
+
let _aliases = null;
|
|
60
|
+
function findPackageJsonPath(specifier, startDir, resolvePackageJson = require.resolve, existsSync = fs.existsSync) {
|
|
61
|
+
try {
|
|
62
|
+
return resolvePackageJson(`${specifier}/package.json`);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
let current = startDir;
|
|
66
|
+
while (true) {
|
|
67
|
+
const candidate = path.join(current, "node_modules", ...specifier.split("/"), "package.json");
|
|
68
|
+
if (existsSync(candidate)) {
|
|
69
|
+
return candidate;
|
|
70
|
+
}
|
|
71
|
+
const parent = path.dirname(current);
|
|
72
|
+
if (parent === current) {
|
|
73
|
+
throw new Error(`Unable to resolve package.json for ${specifier}. Install ${specifier} or run OMK from a workspace containing its built package.`);
|
|
74
|
+
}
|
|
75
|
+
current = parent;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function resolveWorkspaceOrPackageFile(workspaceRelativePath, specifier, packageRelativePath, packagesRoot, resolvePackageJson, existsSync, startDir) {
|
|
80
|
+
const workspacePath = path.join(packagesRoot, workspaceRelativePath);
|
|
81
|
+
if (existsSync(workspacePath)) {
|
|
82
|
+
return workspacePath;
|
|
83
|
+
}
|
|
84
|
+
const packageJsonPath = findPackageJsonPath(specifier, startDir, resolvePackageJson, existsSync);
|
|
85
|
+
return path.join(path.dirname(packageJsonPath), packageRelativePath);
|
|
86
|
+
}
|
|
87
|
+
/** Internal test seam for omk-agent-core/node resolution branches. */
|
|
88
|
+
export function resolveOmkAgentCoreNodeEntryForTests(options) {
|
|
89
|
+
return resolveWorkspaceOrPackageFile("agent/dist/node.js", "omk-agent-core", "dist/node.js", options.packagesRoot, options.resolvePackageJson, options.existsSync, options.startDir);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get aliases for jiti (used in Node.js/development mode).
|
|
93
|
+
* In Bun binary mode, virtualModules is used instead.
|
|
94
|
+
*/
|
|
95
|
+
function getAliases() {
|
|
96
|
+
if (_aliases)
|
|
97
|
+
return _aliases;
|
|
98
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
99
|
+
const packageIndex = path.resolve(__dirname, "../..", "index.js");
|
|
100
|
+
const typeboxEntry = require.resolve("typebox");
|
|
101
|
+
const typeboxCompileEntry = require.resolve("typebox/compile");
|
|
102
|
+
const typeboxValueEntry = require.resolve("typebox/value");
|
|
103
|
+
const packagesRoot = path.resolve(__dirname, "../../../../");
|
|
104
|
+
const omkCodingAgentEntry = packageIndex;
|
|
105
|
+
const omkAgentCoreEntry = resolveWorkspaceOrPackageFile("agent/dist/index.js", "omk-agent-core", "dist/index.js", packagesRoot, require.resolve, fs.existsSync, __dirname);
|
|
106
|
+
const omkAgentCoreNodeEntry = resolveWorkspaceOrPackageFile("agent/dist/node.js", "omk-agent-core", "dist/node.js", packagesRoot, require.resolve, fs.existsSync, __dirname);
|
|
107
|
+
const omkTuiEntry = resolveWorkspaceOrPackageFile("tui/dist/index.js", "omk-tui", "dist/index.js", packagesRoot, require.resolve, fs.existsSync, __dirname);
|
|
108
|
+
const omkAiEntry = resolveWorkspaceOrPackageFile("ai/dist/index.js", "omk-ai", "dist/index.js", packagesRoot, require.resolve, fs.existsSync, __dirname);
|
|
109
|
+
const omkAiOauthEntry = resolveWorkspaceOrPackageFile("ai/dist/oauth.js", "omk-ai", "dist/oauth.js", packagesRoot, require.resolve, fs.existsSync, __dirname);
|
|
110
|
+
const legacyPiAliasTargets = {
|
|
111
|
+
"coding-agent": omkCodingAgentEntry,
|
|
112
|
+
"agent-core": omkAgentCoreEntry,
|
|
113
|
+
"agent-core-node": omkAgentCoreNodeEntry,
|
|
114
|
+
ai: omkAiEntry,
|
|
115
|
+
"ai-oauth": omkAiOauthEntry,
|
|
116
|
+
tui: omkTuiEntry,
|
|
117
|
+
};
|
|
118
|
+
_aliases = {
|
|
119
|
+
...Object.fromEntries(Object.entries(LEGACY_PI_RUNTIME_ALIASES).map(([specifier, target]) => [
|
|
120
|
+
specifier,
|
|
121
|
+
legacyPiAliasTargets[target],
|
|
122
|
+
])),
|
|
123
|
+
"open-multi-agent-kit": omkCodingAgentEntry,
|
|
124
|
+
"omk-agent-core": omkAgentCoreEntry,
|
|
125
|
+
"omk-agent-core/node": omkAgentCoreNodeEntry,
|
|
126
|
+
"omk-tui": omkTuiEntry,
|
|
127
|
+
"omk-ai": omkAiEntry,
|
|
128
|
+
"omk-ai/oauth": omkAiOauthEntry,
|
|
129
|
+
typebox: typeboxEntry,
|
|
130
|
+
"typebox/compile": typeboxCompileEntry,
|
|
131
|
+
"typebox/value": typeboxValueEntry,
|
|
132
|
+
"@sinclair/typebox": typeboxEntry,
|
|
133
|
+
"@sinclair/typebox/compile": typeboxCompileEntry,
|
|
134
|
+
"@sinclair/typebox/value": typeboxValueEntry,
|
|
135
|
+
};
|
|
136
|
+
return _aliases;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Create a runtime with throwing stubs for action methods.
|
|
140
|
+
* Runner.bindCore() replaces these with real implementations.
|
|
141
|
+
*/
|
|
142
|
+
export function createExtensionRuntime() {
|
|
143
|
+
const notInitialized = () => {
|
|
144
|
+
throw new Error("Extension runtime not initialized. Action methods cannot be called during extension loading.");
|
|
145
|
+
};
|
|
146
|
+
const state = {};
|
|
147
|
+
const assertActive = () => {
|
|
148
|
+
if (state.staleMessage) {
|
|
149
|
+
throw new Error(state.staleMessage);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
const runtime = {
|
|
153
|
+
sendMessage: notInitialized,
|
|
154
|
+
sendUserMessage: notInitialized,
|
|
155
|
+
appendEntry: notInitialized,
|
|
156
|
+
setSessionName: notInitialized,
|
|
157
|
+
getSessionName: notInitialized,
|
|
158
|
+
setLabel: notInitialized,
|
|
159
|
+
getActiveTools: notInitialized,
|
|
160
|
+
getAllTools: notInitialized,
|
|
161
|
+
setActiveTools: notInitialized,
|
|
162
|
+
// registerTool() is valid during extension load; refresh is only needed post-bind.
|
|
163
|
+
refreshTools: () => { },
|
|
164
|
+
getCommands: notInitialized,
|
|
165
|
+
setModel: () => Promise.reject(new Error("Extension runtime not initialized")),
|
|
166
|
+
getThinkingLevel: notInitialized,
|
|
167
|
+
setThinkingLevel: notInitialized,
|
|
168
|
+
// Optional; replaced by bindCore when the session provides a handler.
|
|
169
|
+
callMcpTool: undefined,
|
|
170
|
+
flagValues: new Map(),
|
|
171
|
+
pendingProviderRegistrations: [],
|
|
172
|
+
assertActive,
|
|
173
|
+
invalidate: (message) => {
|
|
174
|
+
state.staleMessage ??=
|
|
175
|
+
message ??
|
|
176
|
+
"This extension ctx is stale after session replacement or reload. Do not use a captured extension API or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().";
|
|
177
|
+
},
|
|
178
|
+
// Pre-bind: queue registrations so bindCore() can flush them once the
|
|
179
|
+
// model registry is available. bindCore() replaces both with direct calls.
|
|
180
|
+
registerProvider: (name, config, extensionPath = "<unknown>") => {
|
|
181
|
+
runtime.pendingProviderRegistrations.push({ name, config, extensionPath });
|
|
182
|
+
},
|
|
183
|
+
unregisterProvider: (name) => {
|
|
184
|
+
runtime.pendingProviderRegistrations = runtime.pendingProviderRegistrations.filter((r) => r.name !== name);
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
return runtime;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Create the ExtensionAPI for an extension.
|
|
191
|
+
* Registration methods write to the extension object.
|
|
192
|
+
* Action methods delegate to the shared runtime.
|
|
193
|
+
*/
|
|
194
|
+
function createExtensionAPI(extension, runtime, cwd, eventBus) {
|
|
195
|
+
const api = {
|
|
196
|
+
// Registration methods - write to extension
|
|
197
|
+
on(event, handler) {
|
|
198
|
+
runtime.assertActive();
|
|
199
|
+
const list = extension.handlers.get(event) ?? [];
|
|
200
|
+
list.push(handler);
|
|
201
|
+
extension.handlers.set(event, list);
|
|
202
|
+
},
|
|
203
|
+
registerTool(tool) {
|
|
204
|
+
runtime.assertActive();
|
|
205
|
+
extension.tools.set(tool.name, {
|
|
206
|
+
definition: tool,
|
|
207
|
+
sourceInfo: extension.sourceInfo,
|
|
208
|
+
});
|
|
209
|
+
runtime.refreshTools();
|
|
210
|
+
},
|
|
211
|
+
registerCommand(name, options) {
|
|
212
|
+
runtime.assertActive();
|
|
213
|
+
extension.commands.set(name, {
|
|
214
|
+
name,
|
|
215
|
+
sourceInfo: extension.sourceInfo,
|
|
216
|
+
...options,
|
|
217
|
+
});
|
|
218
|
+
},
|
|
219
|
+
registerShortcut(shortcut, options) {
|
|
220
|
+
runtime.assertActive();
|
|
221
|
+
extension.shortcuts.set(shortcut, { shortcut, extensionPath: extension.path, ...options });
|
|
222
|
+
},
|
|
223
|
+
registerFlag(name, options) {
|
|
224
|
+
runtime.assertActive();
|
|
225
|
+
extension.flags.set(name, { name, extensionPath: extension.path, ...options });
|
|
226
|
+
if (options.default !== undefined && !runtime.flagValues.has(name)) {
|
|
227
|
+
runtime.flagValues.set(name, options.default);
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
registerMessageRenderer(customType, renderer) {
|
|
231
|
+
runtime.assertActive();
|
|
232
|
+
extension.messageRenderers.set(customType, renderer);
|
|
233
|
+
},
|
|
234
|
+
// Flag access - checks extension registered it, reads from runtime
|
|
235
|
+
getFlag(name) {
|
|
236
|
+
runtime.assertActive();
|
|
237
|
+
if (!extension.flags.has(name))
|
|
238
|
+
return undefined;
|
|
239
|
+
return runtime.flagValues.get(name);
|
|
240
|
+
},
|
|
241
|
+
// Action methods - delegate to shared runtime
|
|
242
|
+
sendMessage(message, options) {
|
|
243
|
+
runtime.assertActive();
|
|
244
|
+
runtime.sendMessage(message, options);
|
|
245
|
+
},
|
|
246
|
+
sendUserMessage(content, options) {
|
|
247
|
+
runtime.assertActive();
|
|
248
|
+
runtime.sendUserMessage(content, options);
|
|
249
|
+
},
|
|
250
|
+
appendEntry(customType, data) {
|
|
251
|
+
runtime.assertActive();
|
|
252
|
+
runtime.appendEntry(customType, data);
|
|
253
|
+
},
|
|
254
|
+
setSessionName(name) {
|
|
255
|
+
runtime.assertActive();
|
|
256
|
+
runtime.setSessionName(name);
|
|
257
|
+
},
|
|
258
|
+
getSessionName() {
|
|
259
|
+
runtime.assertActive();
|
|
260
|
+
return runtime.getSessionName();
|
|
261
|
+
},
|
|
262
|
+
setLabel(entryId, label) {
|
|
263
|
+
runtime.assertActive();
|
|
264
|
+
runtime.setLabel(entryId, label);
|
|
265
|
+
},
|
|
266
|
+
exec(command, args, options) {
|
|
267
|
+
runtime.assertActive();
|
|
268
|
+
return execCommand(command, args, options?.cwd ?? cwd, options);
|
|
269
|
+
},
|
|
270
|
+
// Always expose the method so load-time factories can capture it (typeof === "function").
|
|
271
|
+
// The bound handler is resolved at call time after bindCore; until then callers get a clear error.
|
|
272
|
+
async callMcpTool(server, name, args) {
|
|
273
|
+
runtime.assertActive();
|
|
274
|
+
const handler = runtime.callMcpTool;
|
|
275
|
+
if (typeof handler !== "function") {
|
|
276
|
+
throw new Error("Extension callMcpTool is not bound. The session must provide a callMcpTool handler via bindCore.");
|
|
277
|
+
}
|
|
278
|
+
return handler(server, name, args);
|
|
279
|
+
},
|
|
280
|
+
isMcpToolBound() {
|
|
281
|
+
runtime.assertActive();
|
|
282
|
+
return typeof runtime.callMcpTool === "function";
|
|
283
|
+
},
|
|
284
|
+
getActiveTools() {
|
|
285
|
+
runtime.assertActive();
|
|
286
|
+
return runtime.getActiveTools();
|
|
287
|
+
},
|
|
288
|
+
getAllTools() {
|
|
289
|
+
runtime.assertActive();
|
|
290
|
+
return runtime.getAllTools();
|
|
291
|
+
},
|
|
292
|
+
setActiveTools(toolNames) {
|
|
293
|
+
runtime.assertActive();
|
|
294
|
+
runtime.setActiveTools(toolNames);
|
|
295
|
+
},
|
|
296
|
+
getCommands() {
|
|
297
|
+
runtime.assertActive();
|
|
298
|
+
return runtime.getCommands();
|
|
299
|
+
},
|
|
300
|
+
setModel(model) {
|
|
301
|
+
runtime.assertActive();
|
|
302
|
+
return runtime.setModel(model);
|
|
303
|
+
},
|
|
304
|
+
getThinkingLevel() {
|
|
305
|
+
runtime.assertActive();
|
|
306
|
+
return runtime.getThinkingLevel();
|
|
307
|
+
},
|
|
308
|
+
setThinkingLevel(level) {
|
|
309
|
+
runtime.assertActive();
|
|
310
|
+
runtime.setThinkingLevel(level);
|
|
311
|
+
},
|
|
312
|
+
registerProvider(name, config) {
|
|
313
|
+
runtime.assertActive();
|
|
314
|
+
runtime.registerProvider(name, config, extension.path);
|
|
315
|
+
},
|
|
316
|
+
unregisterProvider(name) {
|
|
317
|
+
runtime.assertActive();
|
|
318
|
+
runtime.unregisterProvider(name, extension.path);
|
|
319
|
+
},
|
|
320
|
+
// Track extension event subscriptions so they can be
|
|
321
|
+
// unsubscribed on reload instead of stacking duplicate listeners
|
|
322
|
+
// on the shared event bus.
|
|
323
|
+
events: {
|
|
324
|
+
emit: (channel, data) => {
|
|
325
|
+
eventBus.emit(channel, data);
|
|
326
|
+
},
|
|
327
|
+
on: (channel, handler) => {
|
|
328
|
+
const unsubscribe = eventBus.on(channel, handler);
|
|
329
|
+
extension.eventBusSubscriptions?.push(unsubscribe);
|
|
330
|
+
return unsubscribe;
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
};
|
|
334
|
+
return api;
|
|
335
|
+
}
|
|
336
|
+
async function loadExtensionModule(extensionPath, binaryMode = isBunBinary) {
|
|
337
|
+
const jiti = createJiti(import.meta.url, {
|
|
338
|
+
moduleCache: false,
|
|
339
|
+
// In Bun binary: use virtualModules for bundled packages (no filesystem resolution)
|
|
340
|
+
// Also disable tryNative so jiti handles ALL imports (not just the entry point)
|
|
341
|
+
// In Node.js/dev: use aliases to resolve to node_modules paths
|
|
342
|
+
...(binaryMode ? { virtualModules: VIRTUAL_MODULES, tryNative: false } : { alias: getAliases() }),
|
|
343
|
+
});
|
|
344
|
+
const module = await jiti.import(extensionPath, { default: true });
|
|
345
|
+
const factory = module;
|
|
346
|
+
return typeof factory !== "function" ? undefined : factory;
|
|
347
|
+
}
|
|
348
|
+
/** Internal test seam for loading extensions through Bun binary virtual modules. */
|
|
349
|
+
export async function loadExtensionModuleWithVirtualModulesForTests(extensionPath) {
|
|
350
|
+
return loadExtensionModule(extensionPath, true);
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Create an Extension object with empty collections.
|
|
354
|
+
*/
|
|
355
|
+
function createExtension(extensionPath, resolvedPath) {
|
|
356
|
+
const source = extensionPath.startsWith("<") && extensionPath.endsWith(">")
|
|
357
|
+
? extensionPath.slice(1, -1).split(":")[0] || "temporary"
|
|
358
|
+
: "local";
|
|
359
|
+
const baseDir = extensionPath.startsWith("<") ? undefined : path.dirname(resolvedPath);
|
|
360
|
+
return {
|
|
361
|
+
path: extensionPath,
|
|
362
|
+
resolvedPath,
|
|
363
|
+
sourceInfo: createSyntheticSourceInfo(extensionPath, { source, baseDir }),
|
|
364
|
+
handlers: new Map(),
|
|
365
|
+
tools: new Map(),
|
|
366
|
+
messageRenderers: new Map(),
|
|
367
|
+
commands: new Map(),
|
|
368
|
+
flags: new Map(),
|
|
369
|
+
shortcuts: new Map(),
|
|
370
|
+
eventBusSubscriptions: [],
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
async function loadExtension(extensionPath, cwd, eventBus, runtime) {
|
|
374
|
+
const resolvedPath = resolvePath(extensionPath, cwd, { normalizeUnicodeSpaces: true });
|
|
375
|
+
try {
|
|
376
|
+
const factory = await loadExtensionModule(resolvedPath);
|
|
377
|
+
if (!factory) {
|
|
378
|
+
return { extension: null, error: `Extension does not export a valid factory function: ${extensionPath}` };
|
|
379
|
+
}
|
|
380
|
+
const extension = createExtension(extensionPath, resolvedPath);
|
|
381
|
+
const api = createExtensionAPI(extension, runtime, cwd, eventBus);
|
|
382
|
+
await factory(api);
|
|
383
|
+
return { extension, error: null };
|
|
384
|
+
}
|
|
385
|
+
catch (err) {
|
|
386
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
387
|
+
return { extension: null, error: `Failed to load extension: ${message}` };
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Create an Extension from an inline factory function.
|
|
392
|
+
*/
|
|
393
|
+
export async function loadExtensionFromFactory(factory, cwd, eventBus, runtime, extensionPath = "<inline>") {
|
|
394
|
+
const extension = createExtension(extensionPath, extensionPath);
|
|
395
|
+
const resolvedCwd = resolvePath(cwd);
|
|
396
|
+
const api = createExtensionAPI(extension, runtime, resolvedCwd, eventBus);
|
|
397
|
+
await factory(api);
|
|
398
|
+
return extension;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Load extensions from paths.
|
|
402
|
+
*/
|
|
403
|
+
export async function loadExtensions(paths, cwd, eventBus) {
|
|
404
|
+
const extensions = [];
|
|
405
|
+
const errors = [];
|
|
406
|
+
const resolvedCwd = resolvePath(cwd);
|
|
407
|
+
const resolvedEventBus = eventBus ?? createEventBus();
|
|
408
|
+
const runtime = createExtensionRuntime();
|
|
409
|
+
for (const extPath of paths) {
|
|
410
|
+
const { extension, error } = await loadExtension(extPath, resolvedCwd, resolvedEventBus, runtime);
|
|
411
|
+
if (error) {
|
|
412
|
+
errors.push({ path: extPath, error });
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
if (extension) {
|
|
416
|
+
extensions.push(extension);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
extensions,
|
|
421
|
+
errors,
|
|
422
|
+
runtime,
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
function isExtensionFile(name) {
|
|
426
|
+
return name.endsWith(".ts") || name.endsWith(".js");
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Resolve extension entry points from a directory.
|
|
430
|
+
*
|
|
431
|
+
* Checks for:
|
|
432
|
+
* 1. package.json with "omk.extensions" or "pi.extensions" (omk wins)
|
|
433
|
+
* 2. index.ts or index.js -> returns the index file
|
|
434
|
+
*
|
|
435
|
+
* Returns resolved paths or null if no entry points found.
|
|
436
|
+
*/
|
|
437
|
+
function resolveExtensionEntries(dir) {
|
|
438
|
+
const packageJsonPath = path.join(dir, "package.json");
|
|
439
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
440
|
+
const resolvedManifest = readPackageManifest(packageJsonPath);
|
|
441
|
+
if (resolvedManifest && (resolvedManifest.key !== null || resolvedManifest.diagnostics.length > 0)) {
|
|
442
|
+
const entries = [];
|
|
443
|
+
for (const extPath of resolvedManifest.manifest?.extensions ?? []) {
|
|
444
|
+
const candidate = path.resolve(dir, extPath);
|
|
445
|
+
if (!fs.existsSync(candidate))
|
|
446
|
+
continue;
|
|
447
|
+
if (fs.statSync(candidate).isDirectory()) {
|
|
448
|
+
for (const indexName of ["index.ts", "index.js", "index.mjs", "index.cjs"]) {
|
|
449
|
+
const indexPath = path.join(candidate, indexName);
|
|
450
|
+
if (fs.existsSync(indexPath)) {
|
|
451
|
+
entries.push(indexPath);
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
entries.push(candidate);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return entries;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
// Check for index.ts or index.js
|
|
464
|
+
const indexTs = path.join(dir, "index.ts");
|
|
465
|
+
const indexJs = path.join(dir, "index.js");
|
|
466
|
+
if (fs.existsSync(indexTs)) {
|
|
467
|
+
return [indexTs];
|
|
468
|
+
}
|
|
469
|
+
if (fs.existsSync(indexJs)) {
|
|
470
|
+
return [indexJs];
|
|
471
|
+
}
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Discover extensions in a directory.
|
|
476
|
+
*
|
|
477
|
+
* Discovery rules:
|
|
478
|
+
* 1. Direct files: `extensions/*.ts` or `*.js` → load
|
|
479
|
+
* 2. Subdirectory with index: `extensions/* /index.ts` or `index.js` → load
|
|
480
|
+
* 3. Subdirectory with package.json: `extensions/* /package.json` with OMK manifest → load what it declares
|
|
481
|
+
*
|
|
482
|
+
* No recursion beyond one level. Complex packages must use package.json manifest.
|
|
483
|
+
*/
|
|
484
|
+
function discoverExtensionsInDir(dir) {
|
|
485
|
+
if (!fs.existsSync(dir)) {
|
|
486
|
+
return [];
|
|
487
|
+
}
|
|
488
|
+
const discovered = [];
|
|
489
|
+
try {
|
|
490
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
491
|
+
for (const entry of entries) {
|
|
492
|
+
const entryPath = path.join(dir, entry.name);
|
|
493
|
+
// 1. Direct files: *.ts or *.js
|
|
494
|
+
if ((entry.isFile() || entry.isSymbolicLink()) && isExtensionFile(entry.name)) {
|
|
495
|
+
discovered.push(entryPath);
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
// 2 & 3. Subdirectories
|
|
499
|
+
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
500
|
+
const entries = resolveExtensionEntries(entryPath);
|
|
501
|
+
if (entries) {
|
|
502
|
+
discovered.push(...entries);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
catch {
|
|
508
|
+
return [];
|
|
509
|
+
}
|
|
510
|
+
return discovered;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Discover and load extensions from standard locations.
|
|
514
|
+
*/
|
|
515
|
+
export async function discoverAndLoadExtensions(configuredPaths, cwd, agentDir = getAgentDir(), eventBus) {
|
|
516
|
+
const resolvedCwd = resolvePath(cwd);
|
|
517
|
+
const resolvedAgentDir = resolvePath(agentDir);
|
|
518
|
+
const allPaths = [];
|
|
519
|
+
const seen = new Set();
|
|
520
|
+
const addPaths = (paths) => {
|
|
521
|
+
for (const p of paths) {
|
|
522
|
+
const resolved = path.resolve(p);
|
|
523
|
+
if (!seen.has(resolved)) {
|
|
524
|
+
seen.add(resolved);
|
|
525
|
+
allPaths.push(p);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
// 1. Project-local extensions: cwd/${CONFIG_DIR_NAME}/extensions/
|
|
530
|
+
const localExtDir = path.join(resolvedCwd, CONFIG_DIR_NAME, "extensions");
|
|
531
|
+
addPaths(discoverExtensionsInDir(localExtDir));
|
|
532
|
+
// 2. Global extensions: agentDir/extensions/
|
|
533
|
+
const globalExtDir = path.join(resolvedAgentDir, "extensions");
|
|
534
|
+
addPaths(discoverExtensionsInDir(globalExtDir));
|
|
535
|
+
// 3. Explicitly configured paths
|
|
536
|
+
for (const p of configuredPaths) {
|
|
537
|
+
const resolved = resolvePath(p, resolvedCwd, { normalizeUnicodeSpaces: true });
|
|
538
|
+
if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {
|
|
539
|
+
// Check for package.json with omk manifest or index.ts
|
|
540
|
+
const entries = resolveExtensionEntries(resolved);
|
|
541
|
+
if (entries) {
|
|
542
|
+
addPaths(entries);
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
// No explicit entries - discover individual files in directory
|
|
546
|
+
addPaths(discoverExtensionsInDir(resolved));
|
|
547
|
+
continue;
|
|
548
|
+
}
|
|
549
|
+
addPaths([resolved]);
|
|
550
|
+
}
|
|
551
|
+
return loadExtensions(allPaths, resolvedCwd, eventBus);
|
|
552
|
+
}
|
|
553
|
+
//# sourceMappingURL=loader.js.map
|