oh-my-opencode 4.11.0 → 4.12.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/.agents/skills/codex-qa/scripts/lib/app-server-client.mjs +132 -82
- package/.agents/skills/codex-qa/scripts/lib/app-server-client.test.js +48 -0
- package/.agents/skills/opencode-qa/scripts/serve-wake-split-probe.sh +361 -84
- package/.agents/skills/work-with-pr/SKILL.md +19 -5
- package/.opencode/skills/work-with-pr/SKILL.md +19 -5
- package/dist/agents/atlas/agent.d.ts +3 -2
- package/dist/agents/sisyphus/glm-5-2.d.ts +4 -0
- package/dist/agents/sisyphus/index.d.ts +1 -0
- package/dist/agents/sisyphus-agent-config.d.ts +1 -0
- package/dist/agents/sisyphus-junior/agent.d.ts +1 -1
- package/dist/agents/sisyphus-junior/glm-5-2.d.ts +1 -0
- package/dist/agents/sisyphus-junior/index.d.ts +1 -0
- package/dist/agents/types.d.ts +7 -6
- package/dist/cli/index.js +449 -318
- package/dist/cli-node/index.js +449 -318
- package/dist/features/background-agent/parent-wake-flush-runner.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-history-state.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-session-history.d.ts +1 -47
- package/dist/features/background-agent/parent-wake-session-message.d.ts +47 -0
- package/dist/hooks/keyword-detector/ultrawork/glm.d.ts +2 -0
- package/dist/hooks/keyword-detector/ultrawork/index.d.ts +4 -2
- package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +5 -4
- package/dist/index.js +1185 -87
- package/dist/plugin/tool-execute-before.d.ts +2 -0
- package/dist/plugin-handlers/plugin-components-loader.d.ts +1 -0
- package/dist/skills/init-deep/SKILL.md +21 -26
- package/dist/skills/programming/SKILL.md +25 -121
- package/dist/skills/programming/references/code-smells.md +390 -0
- package/dist/skills/ulw-plan/SKILL.md +2 -1
- package/dist/skills/ulw-plan/references/full-workflow.md +1 -1
- package/dist/skills/ulw-plan/references/intent-clear.md +2 -2
- package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -2
- package/dist/tools/delegate-task/sync-session-turns.d.ts +3 -0
- package/dist/tui.js +16 -7
- package/package.json +13 -13
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +22 -2
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +51 -21
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +18 -7
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +9 -2
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +8 -7
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +7 -2
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +2 -1
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +20 -19
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +94 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +33 -0
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/test/package-smoke.test.ts +2 -71
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +26 -104
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +2 -2
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +2 -2
- package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +12 -92
- package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +3 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +157 -234
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +227 -15
- package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +62 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +34 -3
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +139 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +111 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +250 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +220 -0
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/test-support/package-smoke-fixture.ts +158 -0
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +76 -49
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +17 -0
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +17 -0
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +16 -0
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +16 -0
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +16 -0
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +16 -0
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +16 -0
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +17 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +16 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +16 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +16 -0
- package/packages/omo-codex/plugin/package-lock.json +12 -22
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +1 -1
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +14 -11
- package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +15 -4
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +37 -0
- package/packages/omo-codex/plugin/skills/ast-grep/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/comment-checker/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/debugging/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/frontend/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/git-master/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +21 -26
- package/packages/omo-codex/plugin/skills/init-deep/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lsp/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +25 -121
- package/packages/omo-codex/plugin/skills/programming/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/programming/references/code-smells.md +390 -0
- package/packages/omo-codex/plugin/skills/refactor/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/remove-ai-slops/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/review-work/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/rules/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +139 -0
- package/packages/omo-codex/plugin/skills/teammode/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +111 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +250 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +220 -0
- package/packages/omo-codex/plugin/skills/ultraresearch/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/skills/visual-qa/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +34 -33
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +5 -2
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +13 -0
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +14 -6
- package/packages/omo-codex/plugin/test/bootstrap-ps-guard.test.mjs +7 -3
- package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +31 -0
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/display-metadata.test.mjs +83 -0
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +30 -19
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +6 -6
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -0
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +9 -4
- package/packages/omo-codex/plugin/test/teammode-safety-fixture.mjs +88 -0
- package/packages/omo-codex/plugin/test/teammode-safety.test.mjs +240 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +412 -216
- package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +24 -0
- package/packages/omo-codex/scripts/install-hook-targets.test.mjs +93 -0
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +2 -2
- package/packages/omo-codex/scripts/install-local-bun-global-update.test.mjs +63 -0
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +109 -1
- package/packages/omo-codex/scripts/install-local.mjs +1 -0
- package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +36 -0
- package/packages/shared-skills/skills/init-deep/SKILL.md +21 -26
- package/packages/shared-skills/skills/programming/SKILL.md +25 -121
- package/packages/shared-skills/skills/programming/references/code-smells.md +390 -0
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +2 -1
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/hooks/hooks.json +0 -214
|
@@ -96,20 +96,20 @@ var init_atomic_write = __esm(() => {
|
|
|
96
96
|
|
|
97
97
|
// packages/telemetry-core/src/activity-state.ts
|
|
98
98
|
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync } from "node:fs";
|
|
99
|
-
import { basename as basename5, join as
|
|
99
|
+
import { basename as basename5, join as join27 } from "node:path";
|
|
100
100
|
function resolveTelemetryStateDir(product, options = {}) {
|
|
101
101
|
const dataDir = resolveXdgDataDir(product.cacheDirName, {
|
|
102
102
|
env: options.env,
|
|
103
103
|
osProvider: options.osProvider
|
|
104
104
|
});
|
|
105
|
-
const xdgStateDir = options.env?.XDG_DATA_HOME === undefined ? undefined :
|
|
105
|
+
const xdgStateDir = options.env?.XDG_DATA_HOME === undefined ? undefined : join27(options.env.XDG_DATA_HOME, product.cacheDirName);
|
|
106
106
|
if (dataDir === xdgStateDir || xdgStateDir === undefined && basename5(dataDir) === product.cacheDirName) {
|
|
107
107
|
return dataDir;
|
|
108
108
|
}
|
|
109
|
-
return
|
|
109
|
+
return join27(dataDir, product.cacheDirName);
|
|
110
110
|
}
|
|
111
111
|
function getTelemetryActivityStateFilePath(stateDir) {
|
|
112
|
-
return
|
|
112
|
+
return join27(stateDir, POSTHOG_ACTIVITY_STATE_FILE);
|
|
113
113
|
}
|
|
114
114
|
function getDailyActiveCaptureState(input) {
|
|
115
115
|
const state = readPostHogActivityState(input.stateDir, input.diagnostics);
|
|
@@ -180,9 +180,9 @@ var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com", DEFAULT_POSTHOG_API_KEY =
|
|
|
180
180
|
|
|
181
181
|
// packages/telemetry-core/src/diagnostics.ts
|
|
182
182
|
import { appendFileSync, existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
183
|
-
import { join as
|
|
183
|
+
import { join as join28 } from "node:path";
|
|
184
184
|
function getTelemetryDiagnosticsFilePath(diagnosticsDir) {
|
|
185
|
-
return
|
|
185
|
+
return join28(diagnosticsDir, DIAGNOSTICS_FILE_NAME);
|
|
186
186
|
}
|
|
187
187
|
function writeTelemetryDiagnostic(input, options) {
|
|
188
188
|
const now = options.now ?? new Date;
|
|
@@ -348,7 +348,7 @@ function getTelemetryDistinctId(machineIdPrefix, osProvider = getDefaultTelemetr
|
|
|
348
348
|
var init_machine_id = () => {};
|
|
349
349
|
|
|
350
350
|
// node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
351
|
-
import { dirname as dirname7, posix, sep as
|
|
351
|
+
import { dirname as dirname7, posix, sep as sep7 } from "node:path";
|
|
352
352
|
function createModulerModifier() {
|
|
353
353
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
354
354
|
return async (frames) => {
|
|
@@ -357,7 +357,7 @@ function createModulerModifier() {
|
|
|
357
357
|
return frames;
|
|
358
358
|
};
|
|
359
359
|
}
|
|
360
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname7(process.argv[1]) : process.cwd(), isWindows =
|
|
360
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname7(process.argv[1]) : process.cwd(), isWindows = sep7 === "\\") {
|
|
361
361
|
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
|
|
362
362
|
return (filename) => {
|
|
363
363
|
if (!filename)
|
|
@@ -3378,9 +3378,9 @@ var init_context_lines_node = __esm(() => {
|
|
|
3378
3378
|
});
|
|
3379
3379
|
|
|
3380
3380
|
// node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
|
|
3381
|
-
import { isAbsolute as isAbsolute5, relative as relative4, sep as
|
|
3381
|
+
import { isAbsolute as isAbsolute5, relative as relative4, sep as sep8 } from "node:path";
|
|
3382
3382
|
function createRelativePathModifier(basePath = process.cwd()) {
|
|
3383
|
-
const isWindows =
|
|
3383
|
+
const isWindows = sep8 === "\\";
|
|
3384
3384
|
const toUnix = (p) => isWindows ? p.replace(/\\/g, "/") : p;
|
|
3385
3385
|
const normalizedBase = toUnix(basePath);
|
|
3386
3386
|
return async (frames) => {
|
|
@@ -5907,7 +5907,7 @@ var package_default;
|
|
|
5907
5907
|
var init_package = __esm(() => {
|
|
5908
5908
|
package_default = {
|
|
5909
5909
|
name: "@oh-my-opencode/omo-codex",
|
|
5910
|
-
version: "4.
|
|
5910
|
+
version: "4.12.0",
|
|
5911
5911
|
type: "module",
|
|
5912
5912
|
private: true,
|
|
5913
5913
|
description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
|
|
@@ -6127,7 +6127,7 @@ var init_telemetry = __esm(() => {
|
|
|
6127
6127
|
|
|
6128
6128
|
// packages/omo-codex/src/install/install-local-cli.ts
|
|
6129
6129
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
6130
|
-
import { dirname as dirname9, join as
|
|
6130
|
+
import { dirname as dirname9, join as join33, resolve as resolve11 } from "node:path";
|
|
6131
6131
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
6132
6132
|
|
|
6133
6133
|
// packages/utils/src/runtime/spawn.ts
|
|
@@ -6395,7 +6395,7 @@ var defaultRunCommand = async (command, args, options) => {
|
|
|
6395
6395
|
};
|
|
6396
6396
|
|
|
6397
6397
|
// packages/omo-codex/src/install/install-codex.ts
|
|
6398
|
-
import { join as
|
|
6398
|
+
import { join as join29, resolve as resolve10 } from "node:path";
|
|
6399
6399
|
import { existsSync as existsSync6 } from "node:fs";
|
|
6400
6400
|
import { homedir as homedir2 } from "node:os";
|
|
6401
6401
|
|
|
@@ -6759,8 +6759,8 @@ async function existingNonSymlink(path) {
|
|
|
6759
6759
|
}
|
|
6760
6760
|
}
|
|
6761
6761
|
// packages/omo-codex/src/install/codex-cache-install.ts
|
|
6762
|
-
import { cp as cp2, mkdir as mkdir3, readFile as
|
|
6763
|
-
import { basename as basename2, dirname as dirname3, join as
|
|
6762
|
+
import { cp as cp2, mkdir as mkdir3, readFile as readFile7, rename, rm as rm3 } from "node:fs/promises";
|
|
6763
|
+
import { basename as basename2, dirname as dirname3, join as join9, sep as sep5 } from "node:path";
|
|
6764
6764
|
|
|
6765
6765
|
// packages/omo-codex/src/install/codex-cache-bundled-mcps.ts
|
|
6766
6766
|
import { cp, mkdir as mkdir2, readFile as readFile3, stat as stat2 } from "node:fs/promises";
|
|
@@ -6979,6 +6979,7 @@ async function collectPackageJsonPaths(directory, root, paths) {
|
|
|
6979
6979
|
// packages/omo-codex/src/install/codex-cache-mcp-manifest.ts
|
|
6980
6980
|
import { readFile as readFile5, writeFile as writeFile3 } from "node:fs/promises";
|
|
6981
6981
|
import { join as join7, sep as sep3 } from "node:path";
|
|
6982
|
+
var CODEGRAPH_RELATIVE_ARGS = new Set(["components/codegraph/dist/serve.js", "./components/codegraph/dist/serve.js"]);
|
|
6982
6983
|
async function rewriteCachedMcpManifest(pluginRoot, sourceRoot = pluginRoot) {
|
|
6983
6984
|
const manifestPath = join7(pluginRoot, ".mcp.json");
|
|
6984
6985
|
if (!await fileExistsStrict(manifestPath))
|
|
@@ -7004,6 +7005,8 @@ async function rewriteCachedMcpManifest(pluginRoot, sourceRoot = pluginRoot) {
|
|
|
7004
7005
|
const bundledMcpRuntimeArg = resolveBundledMcpRuntimeArg(pluginRoot, arg);
|
|
7005
7006
|
if (bundledMcpRuntimeArg !== null)
|
|
7006
7007
|
return bundledMcpRuntimeArg;
|
|
7008
|
+
if (CODEGRAPH_RELATIVE_ARGS.has(arg))
|
|
7009
|
+
return join7(pluginRoot, "components", "codegraph", "dist", "serve.js");
|
|
7007
7010
|
if (arg.startsWith("./") || arg.startsWith("../"))
|
|
7008
7011
|
return resolveCachedRuntimePath(pluginRoot, sourceRoot, arg);
|
|
7009
7012
|
return arg;
|
|
@@ -7052,13 +7055,83 @@ async function rewriteCachedManifestRoot(pluginRoot, fromRoot, toRoot) {
|
|
|
7052
7055
|
`);
|
|
7053
7056
|
}
|
|
7054
7057
|
|
|
7058
|
+
// packages/omo-codex/src/install/codex-hook-targets.ts
|
|
7059
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
7060
|
+
import { join as join8, sep as sep4 } from "node:path";
|
|
7061
|
+
var PLUGIN_ROOT_TARGET_PATTERN = /\$\{PLUGIN_ROOT\}[\\/]+([^"']+)/g;
|
|
7062
|
+
async function findMissingHookCommandTargets(pluginRoot) {
|
|
7063
|
+
const commands = [];
|
|
7064
|
+
for (const manifestPath of await hookManifestPaths(pluginRoot)) {
|
|
7065
|
+
if (!await fileExistsStrict(manifestPath))
|
|
7066
|
+
continue;
|
|
7067
|
+
const parsed = JSON.parse(await readFile6(manifestPath, "utf8"));
|
|
7068
|
+
collectCommands(parsed, commands);
|
|
7069
|
+
}
|
|
7070
|
+
const missing = [];
|
|
7071
|
+
const seen = new Set;
|
|
7072
|
+
for (const command of commands) {
|
|
7073
|
+
for (const match of command.matchAll(PLUGIN_ROOT_TARGET_PATTERN)) {
|
|
7074
|
+
const targetSuffix = match[1];
|
|
7075
|
+
if (targetSuffix === undefined)
|
|
7076
|
+
continue;
|
|
7077
|
+
const target = join8(pluginRoot, ...targetSuffix.split(/[\\/]+/));
|
|
7078
|
+
if (seen.has(target))
|
|
7079
|
+
continue;
|
|
7080
|
+
seen.add(target);
|
|
7081
|
+
if (!await fileExistsStrict(target))
|
|
7082
|
+
missing.push(target);
|
|
7083
|
+
}
|
|
7084
|
+
}
|
|
7085
|
+
return missing;
|
|
7086
|
+
}
|
|
7087
|
+
async function hookManifestPaths(pluginRoot) {
|
|
7088
|
+
const pluginManifestPath = join8(pluginRoot, ".codex-plugin", "plugin.json");
|
|
7089
|
+
if (!await fileExistsStrict(pluginManifestPath))
|
|
7090
|
+
return [join8(pluginRoot, "hooks", "hooks.json")];
|
|
7091
|
+
const parsed = JSON.parse(await readFile6(pluginManifestPath, "utf8"));
|
|
7092
|
+
if (!isPlainRecord(parsed))
|
|
7093
|
+
return [];
|
|
7094
|
+
if (typeof parsed.hooks === "string" && parsed.hooks.trim() !== "") {
|
|
7095
|
+
return [join8(pluginRoot, stripDotSlash(parsed.hooks))];
|
|
7096
|
+
}
|
|
7097
|
+
if (Array.isArray(parsed.hooks)) {
|
|
7098
|
+
return parsed.hooks.filter((hookPath) => typeof hookPath === "string" && hookPath.trim() !== "").map((hookPath) => join8(pluginRoot, stripDotSlash(hookPath)));
|
|
7099
|
+
}
|
|
7100
|
+
return [];
|
|
7101
|
+
}
|
|
7102
|
+
function stripDotSlash(path) {
|
|
7103
|
+
return path.startsWith("./") ? path.slice(2) : path;
|
|
7104
|
+
}
|
|
7105
|
+
async function assertHookCommandTargets(pluginRoot) {
|
|
7106
|
+
const missing = await findMissingHookCommandTargets(pluginRoot);
|
|
7107
|
+
if (missing.length === 0)
|
|
7108
|
+
return;
|
|
7109
|
+
const relativeMissing = missing.map((path) => path.split(`${pluginRoot}${sep4}`).join("").split(sep4).join("/"));
|
|
7110
|
+
throw new Error(`Plugin payload is missing ${missing.length} hook command target(s) referenced by hooks.json: ${relativeMissing.join(", ")}. ` + "The previous plugin cache was left untouched; this payload was not activated.");
|
|
7111
|
+
}
|
|
7112
|
+
function collectCommands(value, commands) {
|
|
7113
|
+
if (Array.isArray(value)) {
|
|
7114
|
+
for (const entry of value)
|
|
7115
|
+
collectCommands(entry, commands);
|
|
7116
|
+
return;
|
|
7117
|
+
}
|
|
7118
|
+
if (!isPlainRecord(value))
|
|
7119
|
+
return;
|
|
7120
|
+
if (value["type"] === "command" && typeof value["command"] === "string")
|
|
7121
|
+
commands.push(value["command"]);
|
|
7122
|
+
if (value["type"] === "command" && typeof value["commandWindows"] === "string")
|
|
7123
|
+
commands.push(value["commandWindows"]);
|
|
7124
|
+
for (const entry of Object.values(value))
|
|
7125
|
+
collectCommands(entry, commands);
|
|
7126
|
+
}
|
|
7127
|
+
|
|
7055
7128
|
// packages/omo-codex/src/install/codex-cache-install.ts
|
|
7056
7129
|
async function installCachedPlugin(input) {
|
|
7057
7130
|
if (input.buildSource !== false) {
|
|
7058
7131
|
await maybeRunNpmInstall(input.sourcePath, input.runCommand);
|
|
7059
7132
|
await maybeRunNpmBuild(input.sourcePath, input.runCommand);
|
|
7060
7133
|
}
|
|
7061
|
-
const targetPath =
|
|
7134
|
+
const targetPath = join9(input.codexHome, "plugins", "cache", input.marketplaceName, input.name, input.version);
|
|
7062
7135
|
const tempPath = createTempSiblingPath(targetPath);
|
|
7063
7136
|
await rm3(tempPath, { recursive: true, force: true });
|
|
7064
7137
|
try {
|
|
@@ -7068,6 +7141,7 @@ async function installCachedPlugin(input) {
|
|
|
7068
7141
|
await maybeRunNpmInstall(tempPath, input.runCommand, ["ci", "--omit=dev"]);
|
|
7069
7142
|
await rewriteCachedMcpManifest(tempPath, input.sourcePath);
|
|
7070
7143
|
await rewriteCachedManifestRoot(tempPath, tempPath, targetPath);
|
|
7144
|
+
await assertHookCommandTargets(tempPath);
|
|
7071
7145
|
await promoteDirectory(tempPath, targetPath, input.renameDirectory ?? rename);
|
|
7072
7146
|
} catch (error) {
|
|
7073
7147
|
await rm3(tempPath, { recursive: true, force: true });
|
|
@@ -7076,14 +7150,14 @@ async function installCachedPlugin(input) {
|
|
|
7076
7150
|
return { name: input.name, version: input.version, path: targetPath };
|
|
7077
7151
|
}
|
|
7078
7152
|
async function maybeRunNpmInstall(cwd, runCommand, args = ["install"]) {
|
|
7079
|
-
if (!await fileExistsStrict(
|
|
7153
|
+
if (!await fileExistsStrict(join9(cwd, "package.json")))
|
|
7080
7154
|
return;
|
|
7081
7155
|
await runCommand("npm", args, { cwd });
|
|
7082
7156
|
}
|
|
7083
7157
|
async function maybeRunNpmBuild(cwd, runCommand) {
|
|
7084
|
-
if (!await fileExistsStrict(
|
|
7158
|
+
if (!await fileExistsStrict(join9(cwd, "package.json")))
|
|
7085
7159
|
return;
|
|
7086
|
-
const packageJson = JSON.parse(await
|
|
7160
|
+
const packageJson = JSON.parse(await readFile7(join9(cwd, "package.json"), "utf8"));
|
|
7087
7161
|
if (!isPlainRecord(packageJson))
|
|
7088
7162
|
return;
|
|
7089
7163
|
const scripts = packageJson.scripts;
|
|
@@ -7092,10 +7166,10 @@ async function maybeRunNpmBuild(cwd, runCommand) {
|
|
|
7092
7166
|
await runCommand("npm", ["run", "build"], { cwd });
|
|
7093
7167
|
}
|
|
7094
7168
|
function createTempSiblingPath(targetPath) {
|
|
7095
|
-
return
|
|
7169
|
+
return join9(dirname3(targetPath), `.tmp-${basename2(targetPath)}-${process.pid}-${Date.now()}`);
|
|
7096
7170
|
}
|
|
7097
7171
|
function createBackupSiblingPath(targetPath) {
|
|
7098
|
-
return
|
|
7172
|
+
return join9(dirname3(targetPath), `.backup-${basename2(targetPath)}-${process.pid}-${Date.now()}`);
|
|
7099
7173
|
}
|
|
7100
7174
|
async function copyDirectory(sourcePath, targetPath) {
|
|
7101
7175
|
await mkdir3(dirname3(targetPath), { recursive: true });
|
|
@@ -7126,17 +7200,17 @@ async function restoreBackupDirectory(backupPath, targetPath, renameDirectory) {
|
|
|
7126
7200
|
await renameDirectory(backupPath, targetPath);
|
|
7127
7201
|
}
|
|
7128
7202
|
function shouldCopyPluginPath(path, root) {
|
|
7129
|
-
const relative4 = path === root ? "" : path.slice(root.length +
|
|
7203
|
+
const relative4 = path === root ? "" : path.slice(root.length + sep5.length);
|
|
7130
7204
|
if (relative4 === "")
|
|
7131
7205
|
return true;
|
|
7132
|
-
const parts = relative4.split(
|
|
7206
|
+
const parts = relative4.split(sep5);
|
|
7133
7207
|
return !parts.some((part) => part === ".git" || part === "node_modules");
|
|
7134
7208
|
}
|
|
7135
7209
|
// packages/omo-codex/src/install/codex-cache-prune.ts
|
|
7136
7210
|
import { lstat as lstat4, readdir as readdir3, rm as rm4, stat as stat3 } from "node:fs/promises";
|
|
7137
|
-
import { join as
|
|
7211
|
+
import { join as join10 } from "node:path";
|
|
7138
7212
|
async function pruneMarketplaceCache(input) {
|
|
7139
|
-
const cacheRoot =
|
|
7213
|
+
const cacheRoot = join10(input.codexHome, "plugins", "cache", input.marketplaceName);
|
|
7140
7214
|
if (!await fileExistsStrict(cacheRoot))
|
|
7141
7215
|
return;
|
|
7142
7216
|
const keep = new Set(input.keepPluginNames);
|
|
@@ -7144,15 +7218,15 @@ async function pruneMarketplaceCache(input) {
|
|
|
7144
7218
|
for (const entry of entries) {
|
|
7145
7219
|
if (!entry.isDirectory() || keep.has(entry.name))
|
|
7146
7220
|
continue;
|
|
7147
|
-
await rm4(
|
|
7221
|
+
await rm4(join10(cacheRoot, entry.name), { recursive: true, force: true });
|
|
7148
7222
|
}
|
|
7149
7223
|
}
|
|
7150
7224
|
async function pruneMarketplacePluginCaches(input) {
|
|
7151
|
-
const cacheRoot =
|
|
7225
|
+
const cacheRoot = join10(input.codexHome, "plugins", "cache", input.marketplaceName);
|
|
7152
7226
|
if (!await fileExistsStrict(cacheRoot))
|
|
7153
7227
|
return;
|
|
7154
7228
|
for (const pluginName of input.pluginNames) {
|
|
7155
|
-
await rm4(
|
|
7229
|
+
await rm4(join10(cacheRoot, pluginName), { recursive: true, force: true });
|
|
7156
7230
|
}
|
|
7157
7231
|
const remainingEntries = await readCacheEntryNames(cacheRoot);
|
|
7158
7232
|
if (remainingEntries.length === 0) {
|
|
@@ -7199,11 +7273,11 @@ async function isBrokenCacheSymlink(path) {
|
|
|
7199
7273
|
}
|
|
7200
7274
|
// packages/omo-codex/src/install/codex-cached-marketplace-manifest.ts
|
|
7201
7275
|
import { mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
|
|
7202
|
-
import { join as
|
|
7276
|
+
import { join as join11 } from "node:path";
|
|
7203
7277
|
async function writeCachedMarketplaceManifest(input) {
|
|
7204
|
-
const marketplaceDir =
|
|
7278
|
+
const marketplaceDir = join11(input.marketplaceRoot, ".agents", "plugins");
|
|
7205
7279
|
await mkdir4(marketplaceDir, { recursive: true });
|
|
7206
|
-
await writeFile4(
|
|
7280
|
+
await writeFile4(join11(marketplaceDir, "marketplace.json"), `${JSON.stringify({
|
|
7207
7281
|
name: input.marketplaceName,
|
|
7208
7282
|
plugins: input.plugins.map((plugin) => ({
|
|
7209
7283
|
name: plugin.name,
|
|
@@ -7215,8 +7289,8 @@ async function writeCachedMarketplaceManifest(input) {
|
|
|
7215
7289
|
|
|
7216
7290
|
// packages/omo-codex/src/install/codex-package-layout.ts
|
|
7217
7291
|
import { existsSync as existsSync2 } from "node:fs";
|
|
7218
|
-
import { readFile as
|
|
7219
|
-
import { join as
|
|
7292
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
7293
|
+
import { join as join12 } from "node:path";
|
|
7220
7294
|
var PACKAGED_CODEX_INSTALLER_NAMES = new Set([
|
|
7221
7295
|
"@code-yeongyu/lazycodex",
|
|
7222
7296
|
"@code-yeongyu/lazycodex-ai",
|
|
@@ -7226,19 +7300,19 @@ var PACKAGED_CODEX_INSTALLER_NAMES = new Set([
|
|
|
7226
7300
|
"oh-my-openagent"
|
|
7227
7301
|
]);
|
|
7228
7302
|
async function shouldBuildSourcePackages(repoRoot) {
|
|
7229
|
-
if (existsSync2(
|
|
7303
|
+
if (existsSync2(join12(repoRoot, "packages", "omo-opencode", "src", "index.ts")))
|
|
7230
7304
|
return true;
|
|
7231
|
-
const packageJsonPath =
|
|
7305
|
+
const packageJsonPath = join12(repoRoot, "package.json");
|
|
7232
7306
|
if (!existsSync2(packageJsonPath))
|
|
7233
7307
|
return true;
|
|
7234
|
-
const packageJson = JSON.parse(await
|
|
7308
|
+
const packageJson = JSON.parse(await readFile8(packageJsonPath, "utf8"));
|
|
7235
7309
|
if (!isPlainRecord(packageJson) || typeof packageJson.name !== "string")
|
|
7236
7310
|
return true;
|
|
7237
7311
|
return !PACKAGED_CODEX_INSTALLER_NAMES.has(packageJson.name);
|
|
7238
7312
|
}
|
|
7239
7313
|
|
|
7240
7314
|
// packages/omo-codex/src/install/codex-config-toml.ts
|
|
7241
|
-
import { mkdir as mkdir5, readFile as
|
|
7315
|
+
import { mkdir as mkdir5, readFile as readFile10 } from "node:fs/promises";
|
|
7242
7316
|
import { dirname as dirname5 } from "node:path";
|
|
7243
7317
|
|
|
7244
7318
|
// packages/omo-codex/src/install/toml-section-editor.ts
|
|
@@ -7426,12 +7500,12 @@ function tomlKeySegment(value) {
|
|
|
7426
7500
|
|
|
7427
7501
|
// packages/omo-codex/src/install/codex-config-atomic-write.ts
|
|
7428
7502
|
import { lstat as lstat5, readlink as readlink3, realpath, rename as rename2, unlink, writeFile as writeFile5 } from "node:fs/promises";
|
|
7429
|
-
import { basename as basename3, dirname as dirname4, isAbsolute as isAbsolute4, join as
|
|
7503
|
+
import { basename as basename3, dirname as dirname4, isAbsolute as isAbsolute4, join as join13, resolve as resolve5 } from "node:path";
|
|
7430
7504
|
var RENAME_RETRY_DELAYS_MS = [10, 25, 50];
|
|
7431
7505
|
var RETRIABLE_RENAME_CODES = new Set(["EPERM", "EBUSY"]);
|
|
7432
7506
|
async function writeFileAtomic(targetPath, data) {
|
|
7433
7507
|
const writeTarget = await resolveSymlinkTarget(targetPath);
|
|
7434
|
-
const temporaryPath =
|
|
7508
|
+
const temporaryPath = join13(dirname4(writeTarget), `.tmp-${basename3(writeTarget)}-${process.pid}-${Date.now()}`);
|
|
7435
7509
|
await writeFile5(temporaryPath, data);
|
|
7436
7510
|
try {
|
|
7437
7511
|
await renameWithRetry(temporaryPath, writeTarget);
|
|
@@ -7701,8 +7775,8 @@ function isRootSetting(line, key) {
|
|
|
7701
7775
|
}
|
|
7702
7776
|
|
|
7703
7777
|
// packages/omo-codex/src/install/codex-model-catalog.ts
|
|
7704
|
-
import { readFile as
|
|
7705
|
-
import { join as
|
|
7778
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
7779
|
+
import { join as join14 } from "node:path";
|
|
7706
7780
|
var FALLBACK_CODEX_MODEL_CATALOG = {
|
|
7707
7781
|
current: {
|
|
7708
7782
|
model: "gpt-5.5",
|
|
@@ -7721,9 +7795,9 @@ var FALLBACK_CODEX_MODEL_CATALOG = {
|
|
|
7721
7795
|
]
|
|
7722
7796
|
};
|
|
7723
7797
|
async function readCodexModelCatalog(codexPackageRoot) {
|
|
7724
|
-
const catalogPath =
|
|
7798
|
+
const catalogPath = join14(codexPackageRoot, "plugin", "model-catalog.json");
|
|
7725
7799
|
try {
|
|
7726
|
-
const parsed = JSON.parse(await
|
|
7800
|
+
const parsed = JSON.parse(await readFile9(catalogPath, "utf8"));
|
|
7727
7801
|
return parseCodexModelCatalog(parsed) ?? FALLBACK_CODEX_MODEL_CATALOG;
|
|
7728
7802
|
} catch (error) {
|
|
7729
7803
|
if (error instanceof Error)
|
|
@@ -7804,7 +7878,7 @@ async function updateCodexConfig(input) {
|
|
|
7804
7878
|
await mkdir5(dirname5(input.configPath), { recursive: true });
|
|
7805
7879
|
let config = "";
|
|
7806
7880
|
if (await exists(input.configPath))
|
|
7807
|
-
config = await
|
|
7881
|
+
config = await readFile10(input.configPath, "utf8");
|
|
7808
7882
|
const pluginSet = new Set(input.pluginNames);
|
|
7809
7883
|
for (const legacyMarketplaceName of legacyMarketplaceNames(input.marketplaceName)) {
|
|
7810
7884
|
config = removeMarketplaceBlock(config, legacyMarketplaceName);
|
|
@@ -7840,7 +7914,7 @@ async function updateCodexConfig(input) {
|
|
|
7840
7914
|
}
|
|
7841
7915
|
async function exists(path) {
|
|
7842
7916
|
try {
|
|
7843
|
-
await
|
|
7917
|
+
await readFile10(path, "utf8");
|
|
7844
7918
|
return true;
|
|
7845
7919
|
} catch (error) {
|
|
7846
7920
|
if (error instanceof Error)
|
|
@@ -7851,8 +7925,8 @@ async function exists(path) {
|
|
|
7851
7925
|
|
|
7852
7926
|
// packages/omo-codex/src/install/codex-hook-trust.ts
|
|
7853
7927
|
import { createHash } from "node:crypto";
|
|
7854
|
-
import { readFile as
|
|
7855
|
-
import { join as
|
|
7928
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
7929
|
+
import { join as join15 } from "node:path";
|
|
7856
7930
|
var EVENT_LABELS = new Map([
|
|
7857
7931
|
["PreToolUse", "pre_tool_use"],
|
|
7858
7932
|
["PermissionRequest", "permission_request"],
|
|
@@ -7866,21 +7940,37 @@ var EVENT_LABELS = new Map([
|
|
|
7866
7940
|
["Stop", "stop"]
|
|
7867
7941
|
]);
|
|
7868
7942
|
async function trustedHookStatesForPlugin(input) {
|
|
7869
|
-
const manifestPath =
|
|
7943
|
+
const manifestPath = join15(input.pluginRoot, ".codex-plugin", "plugin.json");
|
|
7870
7944
|
if (!await exists2(manifestPath))
|
|
7871
7945
|
return [];
|
|
7872
|
-
const manifest = JSON.parse(await
|
|
7873
|
-
if (!isPlainRecord(manifest)
|
|
7946
|
+
const manifest = JSON.parse(await readFile11(manifestPath, "utf8"));
|
|
7947
|
+
if (!isPlainRecord(manifest))
|
|
7874
7948
|
return [];
|
|
7875
|
-
const
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7949
|
+
const states = [];
|
|
7950
|
+
for (const hookPath of hookManifestPaths2(manifest.hooks)) {
|
|
7951
|
+
const hooksPath = join15(input.pluginRoot, hookPath);
|
|
7952
|
+
if (!await exists2(hooksPath))
|
|
7953
|
+
continue;
|
|
7954
|
+
const parsed = JSON.parse(await readFile11(hooksPath, "utf8"));
|
|
7955
|
+
if (!isPlainRecord(parsed) || !isPlainRecord(parsed.hooks))
|
|
7956
|
+
continue;
|
|
7957
|
+
states.push(...trustedHookStatesForHooksFile({
|
|
7958
|
+
keySource: `${input.pluginName}@${input.marketplaceName}:${hookPath}`,
|
|
7959
|
+
hooks: parsed.hooks
|
|
7960
|
+
}));
|
|
7961
|
+
}
|
|
7962
|
+
return states;
|
|
7963
|
+
}
|
|
7964
|
+
function hookManifestPaths2(value) {
|
|
7965
|
+
if (typeof value === "string" && value.trim() !== "")
|
|
7966
|
+
return [stripDotSlash2(value)];
|
|
7967
|
+
if (!Array.isArray(value))
|
|
7880
7968
|
return [];
|
|
7881
|
-
|
|
7969
|
+
return value.filter((item) => typeof item === "string" && item.trim() !== "").map(stripDotSlash2);
|
|
7970
|
+
}
|
|
7971
|
+
function trustedHookStatesForHooksFile(input) {
|
|
7882
7972
|
const states = [];
|
|
7883
|
-
for (const [eventName, groups] of Object.entries(
|
|
7973
|
+
for (const [eventName, groups] of Object.entries(input.hooks)) {
|
|
7884
7974
|
if (!Array.isArray(groups))
|
|
7885
7975
|
continue;
|
|
7886
7976
|
const eventLabel = EVENT_LABELS.get(eventName);
|
|
@@ -7896,7 +7986,7 @@ async function trustedHookStatesForPlugin(input) {
|
|
|
7896
7986
|
continue;
|
|
7897
7987
|
if (typeof handler.command !== "string" || handler.command.trim() === "")
|
|
7898
7988
|
continue;
|
|
7899
|
-
const key = `${keySource}:${eventLabel}:${groupIndex}:${handlerIndex}`;
|
|
7989
|
+
const key = `${input.keySource}:${eventLabel}:${groupIndex}:${handlerIndex}`;
|
|
7900
7990
|
states.push({ key, trustedHash: commandHookHash(eventLabel, group.matcher, handler) });
|
|
7901
7991
|
}
|
|
7902
7992
|
}
|
|
@@ -7930,12 +8020,12 @@ function canonicalJson(value) {
|
|
|
7930
8020
|
}
|
|
7931
8021
|
return result;
|
|
7932
8022
|
}
|
|
7933
|
-
function
|
|
8023
|
+
function stripDotSlash2(value) {
|
|
7934
8024
|
return value.startsWith("./") ? value.slice(2) : value;
|
|
7935
8025
|
}
|
|
7936
8026
|
async function exists2(path) {
|
|
7937
8027
|
try {
|
|
7938
|
-
await
|
|
8028
|
+
await readFile11(path, "utf8");
|
|
7939
8029
|
return true;
|
|
7940
8030
|
} catch (error) {
|
|
7941
8031
|
if (error instanceof Error)
|
|
@@ -7986,12 +8076,12 @@ function toCodexResolution(resolution) {
|
|
|
7986
8076
|
}
|
|
7987
8077
|
|
|
7988
8078
|
// packages/omo-codex/src/install/link-cached-plugin-agents.ts
|
|
7989
|
-
import { copyFile, lstat as lstat7, mkdir as mkdir6, readFile as
|
|
7990
|
-
import { basename as basename4, join as
|
|
8079
|
+
import { copyFile, lstat as lstat7, mkdir as mkdir6, readFile as readFile13, readdir as readdir4, rm as rm6, writeFile as writeFile6 } from "node:fs/promises";
|
|
8080
|
+
import { basename as basename4, join as join17 } from "node:path";
|
|
7991
8081
|
|
|
7992
8082
|
// packages/omo-codex/src/install/retired-managed-agent-purge.ts
|
|
7993
|
-
import { lstat as lstat6, readFile as
|
|
7994
|
-
import { join as
|
|
8083
|
+
import { lstat as lstat6, readFile as readFile12, rm as rm5 } from "node:fs/promises";
|
|
8084
|
+
import { join as join16 } from "node:path";
|
|
7995
8085
|
var RETIRED_MANAGED_AGENT_FILES = [
|
|
7996
8086
|
{
|
|
7997
8087
|
fileName: "codex-ultrawork-reviewer.toml",
|
|
@@ -8003,11 +8093,11 @@ var RETIRED_MANAGED_AGENT_FILES = [
|
|
|
8003
8093
|
}
|
|
8004
8094
|
];
|
|
8005
8095
|
async function purgeRetiredManagedAgentFiles(input) {
|
|
8006
|
-
const agentsDir =
|
|
8096
|
+
const agentsDir = join16(input.codexHome, "agents");
|
|
8007
8097
|
if (!await exists3(agentsDir))
|
|
8008
8098
|
return;
|
|
8009
8099
|
for (const retiredAgent of RETIRED_MANAGED_AGENT_FILES) {
|
|
8010
|
-
const agentPath =
|
|
8100
|
+
const agentPath = join16(agentsDir, retiredAgent.fileName);
|
|
8011
8101
|
if (!await exists3(agentPath))
|
|
8012
8102
|
continue;
|
|
8013
8103
|
const agentStat = await lstat6(agentPath);
|
|
@@ -8024,7 +8114,7 @@ function hasRequiredMarkers(content, markers) {
|
|
|
8024
8114
|
}
|
|
8025
8115
|
async function readTextIfExists(path) {
|
|
8026
8116
|
try {
|
|
8027
|
-
return await
|
|
8117
|
+
return await readFile12(path, "utf8");
|
|
8028
8118
|
} catch (error) {
|
|
8029
8119
|
if (nodeErrorCode(error) === "ENOENT")
|
|
8030
8120
|
return null;
|
|
@@ -8050,7 +8140,7 @@ function nodeErrorCode(error) {
|
|
|
8050
8140
|
// packages/omo-codex/src/install/link-cached-plugin-agents.ts
|
|
8051
8141
|
var MANIFEST_FILE = ".installed-agents.json";
|
|
8052
8142
|
async function capturePreservedAgentReasoning(input) {
|
|
8053
|
-
const agentsDir =
|
|
8143
|
+
const agentsDir = join17(input.codexHome, "agents");
|
|
8054
8144
|
if (!await exists4(agentsDir))
|
|
8055
8145
|
return new Map;
|
|
8056
8146
|
const preserved = new Map;
|
|
@@ -8058,7 +8148,7 @@ async function capturePreservedAgentReasoning(input) {
|
|
|
8058
8148
|
for (const entry of agentEntries) {
|
|
8059
8149
|
if (!entry.name.endsWith(".toml"))
|
|
8060
8150
|
continue;
|
|
8061
|
-
const content = await readTextIfExists2(
|
|
8151
|
+
const content = await readTextIfExists2(join17(agentsDir, entry.name));
|
|
8062
8152
|
if (content === null)
|
|
8063
8153
|
continue;
|
|
8064
8154
|
const effort = extractReasoningEffort(content);
|
|
@@ -8068,7 +8158,7 @@ async function capturePreservedAgentReasoning(input) {
|
|
|
8068
8158
|
return preserved;
|
|
8069
8159
|
}
|
|
8070
8160
|
async function capturePreservedAgentServiceTier(input) {
|
|
8071
|
-
const agentsDir =
|
|
8161
|
+
const agentsDir = join17(input.codexHome, "agents");
|
|
8072
8162
|
if (!await exists4(agentsDir))
|
|
8073
8163
|
return new Map;
|
|
8074
8164
|
const preserved = new Map;
|
|
@@ -8076,7 +8166,7 @@ async function capturePreservedAgentServiceTier(input) {
|
|
|
8076
8166
|
for (const entry of agentEntries) {
|
|
8077
8167
|
if (!entry.name.endsWith(".toml"))
|
|
8078
8168
|
continue;
|
|
8079
|
-
const content = await readTextIfExists2(
|
|
8169
|
+
const content = await readTextIfExists2(join17(agentsDir, entry.name));
|
|
8080
8170
|
if (content === null)
|
|
8081
8171
|
continue;
|
|
8082
8172
|
preserved.set(agentNameFromToml(entry.name), extractServiceTier(content));
|
|
@@ -8090,13 +8180,13 @@ async function linkCachedPluginAgents(input) {
|
|
|
8090
8180
|
await writeManifest(input.pluginRoot, []);
|
|
8091
8181
|
return [];
|
|
8092
8182
|
}
|
|
8093
|
-
const agentsDir =
|
|
8183
|
+
const agentsDir = join17(input.codexHome, "agents");
|
|
8094
8184
|
await mkdir6(agentsDir, { recursive: true });
|
|
8095
8185
|
const linked = [];
|
|
8096
8186
|
for (const agentPath of bundledAgents) {
|
|
8097
8187
|
const agentFileName = basename4(agentPath);
|
|
8098
8188
|
const agentName = agentNameFromToml(agentFileName);
|
|
8099
|
-
const linkPath =
|
|
8189
|
+
const linkPath = join17(agentsDir, agentFileName);
|
|
8100
8190
|
await replaceWithCopy(linkPath, agentPath);
|
|
8101
8191
|
await restorePreservedReasoning({
|
|
8102
8192
|
agentName,
|
|
@@ -8117,7 +8207,7 @@ async function linkCachedPluginAgents(input) {
|
|
|
8117
8207
|
async function restorePreservedServiceTier(input) {
|
|
8118
8208
|
if (!input.preserved)
|
|
8119
8209
|
return;
|
|
8120
|
-
const content = await
|
|
8210
|
+
const content = await readFile13(input.linkPath, "utf8");
|
|
8121
8211
|
if (extractServiceTier(content) === input.value)
|
|
8122
8212
|
return;
|
|
8123
8213
|
const replacement = replaceServiceTier(content, input.value);
|
|
@@ -8126,7 +8216,7 @@ async function restorePreservedServiceTier(input) {
|
|
|
8126
8216
|
await writeFile6(input.linkPath, replacement.content);
|
|
8127
8217
|
}
|
|
8128
8218
|
async function discoverBundledAgents(pluginRoot) {
|
|
8129
|
-
const componentsRoot =
|
|
8219
|
+
const componentsRoot = join17(pluginRoot, "components");
|
|
8130
8220
|
if (!await exists4(componentsRoot))
|
|
8131
8221
|
return [];
|
|
8132
8222
|
const componentEntries = await readdir4(componentsRoot, { withFileTypes: true });
|
|
@@ -8134,14 +8224,14 @@ async function discoverBundledAgents(pluginRoot) {
|
|
|
8134
8224
|
for (const entry of componentEntries) {
|
|
8135
8225
|
if (!entry.isDirectory())
|
|
8136
8226
|
continue;
|
|
8137
|
-
const agentsRoot =
|
|
8227
|
+
const agentsRoot = join17(componentsRoot, entry.name, "agents");
|
|
8138
8228
|
if (!await exists4(agentsRoot))
|
|
8139
8229
|
continue;
|
|
8140
8230
|
const agentEntries = await readdir4(agentsRoot, { withFileTypes: true });
|
|
8141
8231
|
for (const file2 of agentEntries) {
|
|
8142
8232
|
if (!file2.isFile() || !file2.name.endsWith(".toml"))
|
|
8143
8233
|
continue;
|
|
8144
|
-
agents.push(
|
|
8234
|
+
agents.push(join17(agentsRoot, file2.name));
|
|
8145
8235
|
}
|
|
8146
8236
|
}
|
|
8147
8237
|
agents.sort();
|
|
@@ -8161,7 +8251,7 @@ async function prepareReplacement(linkPath) {
|
|
|
8161
8251
|
await rm6(linkPath, { force: true });
|
|
8162
8252
|
}
|
|
8163
8253
|
async function writeManifest(pluginRoot, agentPaths) {
|
|
8164
|
-
const manifestPath =
|
|
8254
|
+
const manifestPath = join17(pluginRoot, MANIFEST_FILE);
|
|
8165
8255
|
const payload = { agents: [...agentPaths].sort() };
|
|
8166
8256
|
await writeFile6(manifestPath, `${JSON.stringify(payload, null, "\t")}
|
|
8167
8257
|
`);
|
|
@@ -8169,7 +8259,7 @@ async function writeManifest(pluginRoot, agentPaths) {
|
|
|
8169
8259
|
async function restorePreservedReasoning(input) {
|
|
8170
8260
|
if (input.value === undefined)
|
|
8171
8261
|
return;
|
|
8172
|
-
const content = await
|
|
8262
|
+
const content = await readFile13(input.target, "utf8");
|
|
8173
8263
|
const bundledEffort = extractReasoningEffort(content);
|
|
8174
8264
|
if (bundledEffort === input.value)
|
|
8175
8265
|
return;
|
|
@@ -8180,7 +8270,7 @@ async function restorePreservedReasoning(input) {
|
|
|
8180
8270
|
}
|
|
8181
8271
|
async function readTextIfExists2(path) {
|
|
8182
8272
|
try {
|
|
8183
|
-
return await
|
|
8273
|
+
return await readFile13(path, "utf8");
|
|
8184
8274
|
} catch (error) {
|
|
8185
8275
|
if (nodeErrorCode2(error) === "ENOENT")
|
|
8186
8276
|
return null;
|
|
@@ -8288,12 +8378,12 @@ function nodeErrorCode2(error) {
|
|
|
8288
8378
|
}
|
|
8289
8379
|
|
|
8290
8380
|
// packages/omo-codex/src/install/codex-marketplace.ts
|
|
8291
|
-
import { readFile as
|
|
8292
|
-
import { join as
|
|
8381
|
+
import { readFile as readFile14 } from "node:fs/promises";
|
|
8382
|
+
import { join as join18 } from "node:path";
|
|
8293
8383
|
var DEFAULT_MARKETPLACE_PATH = "packages/omo-codex/marketplace.json";
|
|
8294
8384
|
async function readMarketplace(repoRoot, options) {
|
|
8295
|
-
const marketplacePath = options?.marketplacePath ??
|
|
8296
|
-
const raw = await
|
|
8385
|
+
const marketplacePath = options?.marketplacePath ?? join18(repoRoot, DEFAULT_MARKETPLACE_PATH);
|
|
8386
|
+
const raw = await readFile14(marketplacePath, "utf8");
|
|
8297
8387
|
const parsed = JSON.parse(raw);
|
|
8298
8388
|
if (!isPlainRecord(parsed))
|
|
8299
8389
|
throw new Error("marketplace.json must be an object");
|
|
@@ -8311,10 +8401,10 @@ async function readMarketplace(repoRoot, options) {
|
|
|
8311
8401
|
function resolvePluginSource(repoRoot, plugin, options) {
|
|
8312
8402
|
const sourcePath = localSourcePath(options?.pathOverride ?? plugin.source);
|
|
8313
8403
|
const relativePath = sourcePath.slice(2);
|
|
8314
|
-
return
|
|
8404
|
+
return join18(repoRoot, ...relativePath.split(/[\\/]/));
|
|
8315
8405
|
}
|
|
8316
8406
|
async function readPluginManifest(pluginRoot) {
|
|
8317
|
-
const raw = await
|
|
8407
|
+
const raw = await readFile14(join18(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
|
|
8318
8408
|
const parsed = JSON.parse(raw);
|
|
8319
8409
|
if (!isPlainRecord(parsed))
|
|
8320
8410
|
throw new Error(`${pluginRoot} plugin.json must be an object`);
|
|
@@ -8324,15 +8414,27 @@ async function readPluginManifest(pluginRoot) {
|
|
|
8324
8414
|
if (parsed.version !== undefined && (typeof parsed.version !== "string" || parsed.version.trim() === "")) {
|
|
8325
8415
|
throw new Error(`${pluginRoot} plugin.json version must be a non-empty string`);
|
|
8326
8416
|
}
|
|
8327
|
-
if (parsed.hooks !== undefined && (
|
|
8328
|
-
throw new Error(`${pluginRoot} plugin.json hooks must be a non-empty string`);
|
|
8417
|
+
if (parsed.hooks !== undefined && !isPluginHooksManifestValue(parsed.hooks)) {
|
|
8418
|
+
throw new Error(`${pluginRoot} plugin.json hooks must be a non-empty string or string array`);
|
|
8329
8419
|
}
|
|
8330
8420
|
return {
|
|
8331
8421
|
name: parsed.name,
|
|
8332
8422
|
version: typeof parsed.version === "string" ? parsed.version.trim() : undefined,
|
|
8333
|
-
hooks:
|
|
8423
|
+
hooks: normalizePluginHooksManifestValue(parsed.hooks)
|
|
8334
8424
|
};
|
|
8335
8425
|
}
|
|
8426
|
+
function isPluginHooksManifestValue(value) {
|
|
8427
|
+
if (typeof value === "string")
|
|
8428
|
+
return value.trim() !== "";
|
|
8429
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string" && item.trim() !== "");
|
|
8430
|
+
}
|
|
8431
|
+
function normalizePluginHooksManifestValue(value) {
|
|
8432
|
+
if (typeof value === "string")
|
|
8433
|
+
return value.trim();
|
|
8434
|
+
if (Array.isArray(value))
|
|
8435
|
+
return value.map((item) => item.trim());
|
|
8436
|
+
return;
|
|
8437
|
+
}
|
|
8336
8438
|
function validatePathSegment(value, label) {
|
|
8337
8439
|
if (!/^[A-Za-z0-9._+-]+$/.test(value)) {
|
|
8338
8440
|
throw new Error(`${label} contains unsupported characters: ${value}`);
|
|
@@ -8384,7 +8486,7 @@ function validateLocalSourcePath(path) {
|
|
|
8384
8486
|
|
|
8385
8487
|
// packages/omo-codex/src/install/codex-marketplace-snapshot.ts
|
|
8386
8488
|
import { cp as cp3, mkdir as mkdir7, rename as rename3, rm as rm7, writeFile as writeFile7 } from "node:fs/promises";
|
|
8387
|
-
import { join as
|
|
8489
|
+
import { join as join19, sep as sep6 } from "node:path";
|
|
8388
8490
|
var INSTALLED_MARKETPLACES_DIR = ".tmp/marketplaces";
|
|
8389
8491
|
async function writeInstalledMarketplaceSnapshot(input) {
|
|
8390
8492
|
const marketplaceRoot = installedMarketplaceRoot(input.codexHome, input.marketplace.name);
|
|
@@ -8397,21 +8499,21 @@ async function writeInstalledMarketplaceSnapshot(input) {
|
|
|
8397
8499
|
return snapshotPlugins;
|
|
8398
8500
|
}
|
|
8399
8501
|
function installedMarketplaceRoot(codexHome, marketplaceName) {
|
|
8400
|
-
return
|
|
8502
|
+
return join19(codexHome, INSTALLED_MARKETPLACES_DIR, marketplaceName);
|
|
8401
8503
|
}
|
|
8402
8504
|
async function writeMarketplaceManifest(marketplaceRoot, marketplace) {
|
|
8403
|
-
const manifestDir =
|
|
8505
|
+
const manifestDir = join19(marketplaceRoot, ".agents", "plugins");
|
|
8404
8506
|
await mkdir7(manifestDir, { recursive: true });
|
|
8405
|
-
const tempPath =
|
|
8507
|
+
const tempPath = join19(manifestDir, `.marketplace-${process.pid}-${Date.now()}.json.tmp`);
|
|
8406
8508
|
await writeFile7(tempPath, `${JSON.stringify(marketplace, null, "\t")}
|
|
8407
8509
|
`);
|
|
8408
|
-
await rename3(tempPath,
|
|
8510
|
+
await rename3(tempPath, join19(manifestDir, "marketplace.json"));
|
|
8409
8511
|
}
|
|
8410
8512
|
async function writeSnapshotPlugin(marketplaceRoot, plugin) {
|
|
8411
|
-
const pluginsDir =
|
|
8513
|
+
const pluginsDir = join19(marketplaceRoot, "plugins");
|
|
8412
8514
|
await mkdir7(pluginsDir, { recursive: true });
|
|
8413
|
-
const targetPath =
|
|
8414
|
-
const tempPath =
|
|
8515
|
+
const targetPath = join19(pluginsDir, plugin.name);
|
|
8516
|
+
const tempPath = join19(pluginsDir, `.tmp-${plugin.name}-${process.pid}-${Date.now()}`);
|
|
8415
8517
|
await rm7(tempPath, { recursive: true, force: true });
|
|
8416
8518
|
await cp3(plugin.sourcePath, tempPath, {
|
|
8417
8519
|
recursive: true,
|
|
@@ -8424,19 +8526,19 @@ async function writeSnapshotPlugin(marketplaceRoot, plugin) {
|
|
|
8424
8526
|
return { name: plugin.name, path: targetPath };
|
|
8425
8527
|
}
|
|
8426
8528
|
function shouldCopyMarketplaceSourcePath(path, root) {
|
|
8427
|
-
const relative4 = path === root ? "" : path.slice(root.length +
|
|
8529
|
+
const relative4 = path === root ? "" : path.slice(root.length + sep6.length);
|
|
8428
8530
|
if (relative4 === "")
|
|
8429
8531
|
return true;
|
|
8430
|
-
const parts = relative4.split(
|
|
8532
|
+
const parts = relative4.split(sep6);
|
|
8431
8533
|
return !parts.some((part) => part === ".git" || part === "node_modules");
|
|
8432
8534
|
}
|
|
8433
8535
|
|
|
8434
8536
|
// packages/omo-codex/src/install/lazycodex-version-stamp.ts
|
|
8435
|
-
import { readdir as readdir5, readFile as
|
|
8436
|
-
import { join as
|
|
8537
|
+
import { readdir as readdir5, readFile as readFile15, writeFile as writeFile8 } from "node:fs/promises";
|
|
8538
|
+
import { join as join20 } from "node:path";
|
|
8437
8539
|
async function readDistributionManifest(repoRoot) {
|
|
8438
8540
|
try {
|
|
8439
|
-
const parsed = JSON.parse(await
|
|
8541
|
+
const parsed = JSON.parse(await readFile15(join20(repoRoot, "package.json"), "utf8"));
|
|
8440
8542
|
if (!isPlainRecord(parsed) || typeof parsed.version !== "string" || parsed.version.trim().length === 0)
|
|
8441
8543
|
return;
|
|
8442
8544
|
return {
|
|
@@ -8456,15 +8558,19 @@ function resolveLazyCodexPluginVersion(input) {
|
|
|
8456
8558
|
return input.manifestVersion ?? "local";
|
|
8457
8559
|
}
|
|
8458
8560
|
async function stampLazyCodexPluginVersion(input) {
|
|
8459
|
-
|
|
8460
|
-
await
|
|
8461
|
-
await
|
|
8561
|
+
const manifestPath = join20(input.pluginRoot, ".codex-plugin", "plugin.json");
|
|
8562
|
+
const hookPaths = await readPluginHookPaths(manifestPath);
|
|
8563
|
+
await stampJsonVersion(manifestPath, input.version);
|
|
8564
|
+
await stampJsonVersion(join20(input.pluginRoot, "package.json"), input.version);
|
|
8565
|
+
for (const hookPath of hookPaths) {
|
|
8566
|
+
await stampHookStatusMessages(join20(input.pluginRoot, hookPath), input.version);
|
|
8567
|
+
}
|
|
8462
8568
|
await stampComponentVersions(input);
|
|
8463
8569
|
}
|
|
8464
8570
|
async function writeLazyCodexInstallSnapshot(input) {
|
|
8465
8571
|
if (input.distributionManifest === undefined)
|
|
8466
8572
|
return;
|
|
8467
|
-
await writeFile8(
|
|
8573
|
+
await writeFile8(join20(input.pluginRoot, "lazycodex-install.json"), `${JSON.stringify({
|
|
8468
8574
|
packageName: input.distributionManifest.name,
|
|
8469
8575
|
version: input.distributionManifest.version
|
|
8470
8576
|
}, null, "\t")}
|
|
@@ -8472,7 +8578,7 @@ async function writeLazyCodexInstallSnapshot(input) {
|
|
|
8472
8578
|
}
|
|
8473
8579
|
async function stampJsonVersion(path, version) {
|
|
8474
8580
|
try {
|
|
8475
|
-
const parsed = JSON.parse(await
|
|
8581
|
+
const parsed = JSON.parse(await readFile15(path, "utf8"));
|
|
8476
8582
|
if (!isPlainRecord(parsed))
|
|
8477
8583
|
return;
|
|
8478
8584
|
parsed.version = version;
|
|
@@ -8484,9 +8590,29 @@ async function stampJsonVersion(path, version) {
|
|
|
8484
8590
|
throw error;
|
|
8485
8591
|
}
|
|
8486
8592
|
}
|
|
8593
|
+
async function readPluginHookPaths(manifestPath) {
|
|
8594
|
+
try {
|
|
8595
|
+
const parsed = JSON.parse(await readFile15(manifestPath, "utf8"));
|
|
8596
|
+
if (!isPlainRecord(parsed))
|
|
8597
|
+
return [];
|
|
8598
|
+
if (typeof parsed.hooks === "string" && parsed.hooks.trim().length > 0)
|
|
8599
|
+
return [stripDotSlash3(parsed.hooks)];
|
|
8600
|
+
if (Array.isArray(parsed.hooks)) {
|
|
8601
|
+
return parsed.hooks.filter((hookPath) => typeof hookPath === "string" && hookPath.trim().length > 0).map(stripDotSlash3);
|
|
8602
|
+
}
|
|
8603
|
+
return [];
|
|
8604
|
+
} catch (error) {
|
|
8605
|
+
if (error instanceof Error)
|
|
8606
|
+
return [];
|
|
8607
|
+
throw error;
|
|
8608
|
+
}
|
|
8609
|
+
}
|
|
8610
|
+
function stripDotSlash3(path) {
|
|
8611
|
+
return path.startsWith("./") ? path.slice(2) : path;
|
|
8612
|
+
}
|
|
8487
8613
|
async function stampHookStatusMessages(path, version) {
|
|
8488
8614
|
try {
|
|
8489
|
-
const parsed = JSON.parse(await
|
|
8615
|
+
const parsed = JSON.parse(await readFile15(path, "utf8"));
|
|
8490
8616
|
if (!isPlainRecord(parsed))
|
|
8491
8617
|
return;
|
|
8492
8618
|
stampHookGroups(parsed.hooks, version);
|
|
@@ -8501,16 +8627,16 @@ async function stampHookStatusMessages(path, version) {
|
|
|
8501
8627
|
async function stampComponentVersions(input) {
|
|
8502
8628
|
let entries;
|
|
8503
8629
|
try {
|
|
8504
|
-
entries = await readdir5(
|
|
8630
|
+
entries = await readdir5(join20(input.pluginRoot, "components"));
|
|
8505
8631
|
} catch (error) {
|
|
8506
8632
|
if (error instanceof Error)
|
|
8507
8633
|
return;
|
|
8508
8634
|
throw error;
|
|
8509
8635
|
}
|
|
8510
8636
|
for (const entry of entries) {
|
|
8511
|
-
const componentRoot =
|
|
8512
|
-
await stampJsonVersion(
|
|
8513
|
-
await stampHookStatusMessages(
|
|
8637
|
+
const componentRoot = join20(input.pluginRoot, "components", entry);
|
|
8638
|
+
await stampJsonVersion(join20(componentRoot, "package.json"), input.version);
|
|
8639
|
+
await stampHookStatusMessages(join20(componentRoot, "hooks", "hooks.json"), input.version);
|
|
8514
8640
|
}
|
|
8515
8641
|
}
|
|
8516
8642
|
function stampHookGroups(hooks, version) {
|
|
@@ -8531,12 +8657,12 @@ function stampHookGroups(hooks, version) {
|
|
|
8531
8657
|
function stampHookStatusMessage(hook, version) {
|
|
8532
8658
|
if (!isPlainRecord(hook) || typeof hook.statusMessage !== "string")
|
|
8533
8659
|
return;
|
|
8534
|
-
hook.statusMessage = hook.statusMessage.replace(/^LazyCodex\([^)]+\)
|
|
8660
|
+
hook.statusMessage = hook.statusMessage.replace(/^LazyCodex\([^)]+\):\s*/, "(OmO) ");
|
|
8535
8661
|
}
|
|
8536
8662
|
|
|
8537
8663
|
// packages/omo-codex/src/install/codex-project-local-cleanup.ts
|
|
8538
|
-
import { copyFile as copyFile2, lstat as lstat8, readFile as
|
|
8539
|
-
import { dirname as dirname6, join as
|
|
8664
|
+
import { copyFile as copyFile2, lstat as lstat8, readFile as readFile16, writeFile as writeFile9 } from "node:fs/promises";
|
|
8665
|
+
import { dirname as dirname6, join as join21, resolve as resolve6 } from "node:path";
|
|
8540
8666
|
var LEGACY_AGENT_CONFLICT_KEYS = ["max_threads"];
|
|
8541
8667
|
var PROJECT_LOCAL_ARTIFACT_PATHS = [
|
|
8542
8668
|
".codex/hooks.json",
|
|
@@ -8555,7 +8681,7 @@ async function repairNearestProjectLocalCodexArtifacts(input) {
|
|
|
8555
8681
|
const artifacts = await collectProjectLocalArtifacts(project.artifactRoots);
|
|
8556
8682
|
const configs = [];
|
|
8557
8683
|
for (const configPath of project.configPaths) {
|
|
8558
|
-
const original = await
|
|
8684
|
+
const original = await readFile16(configPath, "utf8");
|
|
8559
8685
|
const repair = repairProjectLocalCodexConfigText(original);
|
|
8560
8686
|
if (!repair.changed) {
|
|
8561
8687
|
configs.push({
|
|
@@ -8639,17 +8765,17 @@ async function findProjectLocalCodexConfigs(startDirectory, codexHome) {
|
|
|
8639
8765
|
if (startDirectoryStat !== null && !startDirectoryStat.isDirectory()) {
|
|
8640
8766
|
throw new ProjectLocalCleanupStartDirectoryError(startDirectory);
|
|
8641
8767
|
}
|
|
8642
|
-
const codexHomeConfigPath = codexHome === undefined ? null :
|
|
8768
|
+
const codexHomeConfigPath = codexHome === undefined ? null : join21(resolve6(codexHome), "config.toml");
|
|
8643
8769
|
let current = resolve6(startDirectory);
|
|
8644
8770
|
const configPathsFromCwd = [];
|
|
8645
8771
|
while (true) {
|
|
8646
|
-
const configPath =
|
|
8772
|
+
const configPath = join21(current, ".codex", "config.toml");
|
|
8647
8773
|
if (await isRegularProjectLocalConfig(current, configPath)) {
|
|
8648
8774
|
if (codexHomeConfigPath === null || resolve6(configPath) !== codexHomeConfigPath) {
|
|
8649
8775
|
configPathsFromCwd.push(configPath);
|
|
8650
8776
|
}
|
|
8651
8777
|
}
|
|
8652
|
-
if (await exists5(
|
|
8778
|
+
if (await exists5(join21(current, ".git"))) {
|
|
8653
8779
|
return configPathsFromCwd.length === 0 ? null : {
|
|
8654
8780
|
projectRoot: current,
|
|
8655
8781
|
configPaths: [...configPathsFromCwd].reverse(),
|
|
@@ -8669,7 +8795,7 @@ async function findProjectLocalCodexConfigs(startDirectory, codexHome) {
|
|
|
8669
8795
|
}
|
|
8670
8796
|
}
|
|
8671
8797
|
async function isRegularProjectLocalConfig(directory, configPath) {
|
|
8672
|
-
const codexDirStat = await maybeLstat(
|
|
8798
|
+
const codexDirStat = await maybeLstat(join21(directory, ".codex"));
|
|
8673
8799
|
if (codexDirStat === null || !codexDirStat.isDirectory() || codexDirStat.isSymbolicLink())
|
|
8674
8800
|
return false;
|
|
8675
8801
|
const configStat = await maybeLstat(configPath);
|
|
@@ -8689,7 +8815,7 @@ async function collectProjectLocalArtifacts(projectRoots) {
|
|
|
8689
8815
|
const seenPaths = new Set;
|
|
8690
8816
|
for (const projectRoot of projectRoots) {
|
|
8691
8817
|
for (const relativePath of PROJECT_LOCAL_ARTIFACT_PATHS) {
|
|
8692
|
-
const artifactPath =
|
|
8818
|
+
const artifactPath = join21(projectRoot, relativePath);
|
|
8693
8819
|
if (seenPaths.has(artifactPath))
|
|
8694
8820
|
continue;
|
|
8695
8821
|
const entryStat = await maybeLstat(artifactPath);
|
|
@@ -8764,13 +8890,13 @@ function formatUnknownError(error) {
|
|
|
8764
8890
|
}
|
|
8765
8891
|
|
|
8766
8892
|
// packages/omo-codex/src/install/lsp-daemon-reaper.ts
|
|
8767
|
-
import { readFile as
|
|
8893
|
+
import { readFile as readFile17, readdir as readdir6, rm as rm8 } from "node:fs/promises";
|
|
8768
8894
|
import { connect } from "node:net";
|
|
8769
|
-
import { join as
|
|
8895
|
+
import { join as join22 } from "node:path";
|
|
8770
8896
|
async function reapLspDaemons(codexHome, deps = {}) {
|
|
8771
8897
|
const killProcess = deps.killProcess ?? sendSigterm;
|
|
8772
8898
|
const isDaemonLive = deps.isDaemonLive ?? probeSocketLive;
|
|
8773
|
-
const daemonRoot =
|
|
8899
|
+
const daemonRoot = join22(codexHome, "codex-lsp", "daemon");
|
|
8774
8900
|
const reaped = [];
|
|
8775
8901
|
let entries;
|
|
8776
8902
|
try {
|
|
@@ -8779,9 +8905,9 @@ async function reapLspDaemons(codexHome, deps = {}) {
|
|
|
8779
8905
|
return reaped;
|
|
8780
8906
|
}
|
|
8781
8907
|
for (const entry of entries) {
|
|
8782
|
-
const versionDir =
|
|
8783
|
-
const pid = await readPidFile(
|
|
8784
|
-
const socketPath = await readEndpointFile(
|
|
8908
|
+
const versionDir = join22(daemonRoot, entry);
|
|
8909
|
+
const pid = await readPidFile(join22(versionDir, "daemon.pid"));
|
|
8910
|
+
const socketPath = await readEndpointFile(join22(versionDir, "daemon.endpoint"));
|
|
8785
8911
|
if (pid !== null && socketPath !== null && await isDaemonLive(socketPath) && killProcess(pid)) {
|
|
8786
8912
|
reaped.push(pid);
|
|
8787
8913
|
}
|
|
@@ -8791,7 +8917,7 @@ async function reapLspDaemons(codexHome, deps = {}) {
|
|
|
8791
8917
|
}
|
|
8792
8918
|
async function readEndpointFile(path) {
|
|
8793
8919
|
try {
|
|
8794
|
-
const content = (await
|
|
8920
|
+
const content = (await readFile17(path, "utf8")).trim();
|
|
8795
8921
|
return content.length > 0 ? content : null;
|
|
8796
8922
|
} catch {
|
|
8797
8923
|
return null;
|
|
@@ -8799,7 +8925,7 @@ async function readEndpointFile(path) {
|
|
|
8799
8925
|
}
|
|
8800
8926
|
async function readPidFile(path) {
|
|
8801
8927
|
try {
|
|
8802
|
-
const pid = Number.parseInt((await
|
|
8928
|
+
const pid = Number.parseInt((await readFile17(path, "utf8")).trim(), 10);
|
|
8803
8929
|
return Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
8804
8930
|
} catch {
|
|
8805
8931
|
return null;
|
|
@@ -8835,7 +8961,7 @@ function sendSigterm(pid) {
|
|
|
8835
8961
|
|
|
8836
8962
|
// packages/omo-codex/src/install/codex-installer-bin-dir.ts
|
|
8837
8963
|
import { homedir } from "node:os";
|
|
8838
|
-
import { join as
|
|
8964
|
+
import { join as join23, resolve as resolve7 } from "node:path";
|
|
8839
8965
|
function resolveCodexInstallerBinDir(input) {
|
|
8840
8966
|
const explicitBinDir = input.binDir ?? input.env?.CODEX_LOCAL_BIN_DIR;
|
|
8841
8967
|
if (explicitBinDir !== undefined && explicitBinDir.trim().length > 0)
|
|
@@ -8844,15 +8970,15 @@ function resolveCodexInstallerBinDir(input) {
|
|
|
8844
8970
|
const defaultCodexHome = resolve7(homeDir, ".codex");
|
|
8845
8971
|
const resolvedCodexHome = resolve7(input.codexHome);
|
|
8846
8972
|
if (resolvedCodexHome !== defaultCodexHome)
|
|
8847
|
-
return
|
|
8973
|
+
return join23(resolvedCodexHome, "bin");
|
|
8848
8974
|
return resolve7(homeDir, ".local", "bin");
|
|
8849
8975
|
}
|
|
8850
8976
|
|
|
8851
8977
|
// packages/omo-codex/src/install/omo-sot-migration.ts
|
|
8852
|
-
import { join as
|
|
8978
|
+
import { join as join24 } from "node:path";
|
|
8853
8979
|
async function seedAndMigrateOmoSot(input) {
|
|
8854
8980
|
const commandEnv = { ...input.env };
|
|
8855
|
-
const scriptPath =
|
|
8981
|
+
const scriptPath = join24(input.repoRoot, "packages", "omo-codex", "plugin", "scripts", "migrate-omo-sot.mjs");
|
|
8856
8982
|
try {
|
|
8857
8983
|
await input.runCommand(process.execPath, [scriptPath, "--seed"], {
|
|
8858
8984
|
cwd: input.repoRoot,
|
|
@@ -8866,7 +8992,7 @@ async function seedAndMigrateOmoSot(input) {
|
|
|
8866
8992
|
}
|
|
8867
8993
|
|
|
8868
8994
|
// packages/omo-codex/src/install/install-ast-grep-sg.ts
|
|
8869
|
-
import { join as
|
|
8995
|
+
import { join as join26 } from "node:path";
|
|
8870
8996
|
|
|
8871
8997
|
// packages/utils/src/deep-merge.ts
|
|
8872
8998
|
var DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
@@ -11838,11 +11964,11 @@ function runtimeSlug(platform = process.platform, arch = process.arch) {
|
|
|
11838
11964
|
// packages/utils/src/ast-grep/install-script.ts
|
|
11839
11965
|
import { spawn as spawn3 } from "node:child_process";
|
|
11840
11966
|
import { existsSync as existsSync3 } from "node:fs";
|
|
11841
|
-
import { join as
|
|
11967
|
+
import { join as join25 } from "node:path";
|
|
11842
11968
|
var AST_GREP_BIN_DIR_ENV_KEY = "OMO_AST_GREP_BIN_DIR";
|
|
11843
11969
|
var AST_GREP_INSTALL_TIMEOUT_MS = 30000;
|
|
11844
11970
|
function astGrepRuntimeDir(baseDir, platform = process.platform, arch = process.arch) {
|
|
11845
|
-
return
|
|
11971
|
+
return join25(baseDir, "runtime", "ast-grep", runtimeSlug(platform, arch));
|
|
11846
11972
|
}
|
|
11847
11973
|
function isMissingExecutable(error) {
|
|
11848
11974
|
if (!("code" in error))
|
|
@@ -11880,7 +12006,7 @@ function defaultSpawnProcess(command, args, options) {
|
|
|
11880
12006
|
};
|
|
11881
12007
|
}
|
|
11882
12008
|
function scriptPathForPlatform(skillDir, platform) {
|
|
11883
|
-
return
|
|
12009
|
+
return join25(skillDir, platform === "win32" ? "install.ps1" : "install.sh");
|
|
11884
12010
|
}
|
|
11885
12011
|
function invocationsForPlatform(scriptPath, platform) {
|
|
11886
12012
|
if (platform !== "win32")
|
|
@@ -12648,7 +12774,7 @@ async function installAstGrepForCodex(options) {
|
|
|
12648
12774
|
return;
|
|
12649
12775
|
const platform = options.platform ?? process.platform;
|
|
12650
12776
|
const targetDir = astGrepRuntimeDir(options.codexHome, platform, options.arch ?? process.arch);
|
|
12651
|
-
const skillDir =
|
|
12777
|
+
const skillDir = join26(plugin.path, "skills", "ast-grep");
|
|
12652
12778
|
const installer = options.installer ?? runAstGrepSkillInstall;
|
|
12653
12779
|
try {
|
|
12654
12780
|
const result = await installer({ platform, skillDir, targetDir });
|
|
@@ -12681,7 +12807,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
12681
12807
|
const env3 = options.env ?? process.env;
|
|
12682
12808
|
const platform = options.platform ?? process.platform;
|
|
12683
12809
|
const repoRoot = resolve10(options.repoRoot ?? findRepoRoot({ importerDir: import.meta.dir, env: env3 }));
|
|
12684
|
-
const codexHome = resolve10(options.codexHome ?? env3.CODEX_HOME ??
|
|
12810
|
+
const codexHome = resolve10(options.codexHome ?? env3.CODEX_HOME ?? join29(homedir2(), ".codex"));
|
|
12685
12811
|
const projectDirectory = resolve10(options.projectDirectory ?? env3.OMO_CODEX_PROJECT ?? process.cwd());
|
|
12686
12812
|
const binDir = resolveCodexInstallerBinDir({ binDir: options.binDir, codexHome, env: env3 });
|
|
12687
12813
|
const runCommand = options.runCommand ?? defaultRunCommand;
|
|
@@ -12699,9 +12825,9 @@ async function runCodexInstaller(options = {}) {
|
|
|
12699
12825
|
if (!gitBashResolution.found) {
|
|
12700
12826
|
throw new Error(gitBashResolution.installHint);
|
|
12701
12827
|
}
|
|
12702
|
-
const codexPackageRoot =
|
|
12828
|
+
const codexPackageRoot = join29(repoRoot, "packages", "omo-codex");
|
|
12703
12829
|
const marketplace = await readMarketplace(repoRoot, {
|
|
12704
|
-
marketplacePath:
|
|
12830
|
+
marketplacePath: join29(codexPackageRoot, "marketplace.json")
|
|
12705
12831
|
});
|
|
12706
12832
|
const distributionManifest = await readDistributionManifest(repoRoot);
|
|
12707
12833
|
const installed = [];
|
|
@@ -12743,7 +12869,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
12743
12869
|
if (runtimeLink !== null)
|
|
12744
12870
|
log2(`Linked ${runtimeLink.name} -> ${runtimeLink.target}`);
|
|
12745
12871
|
else
|
|
12746
|
-
log2(`Warning: skipped the omo runtime wrapper because ${
|
|
12872
|
+
log2(`Warning: skipped the omo runtime wrapper because ${join29(repoRoot, "dist", "cli", "index.js")} is missing; omo sparkshell/ulw-loop commands will be unavailable until a package shipping dist/cli is installed`);
|
|
12747
12873
|
}
|
|
12748
12874
|
pluginSources.push({ name: entry.name, sourcePath });
|
|
12749
12875
|
installed.push(plugin);
|
|
@@ -12796,13 +12922,13 @@ async function runCodexInstaller(options = {}) {
|
|
|
12796
12922
|
});
|
|
12797
12923
|
}
|
|
12798
12924
|
await reapLspDaemons(codexHome).catch(() => []);
|
|
12799
|
-
const marketplaceRoot =
|
|
12925
|
+
const marketplaceRoot = join29(codexHome, "plugins", "cache", marketplace.name);
|
|
12800
12926
|
await writeCachedMarketplaceManifest({
|
|
12801
12927
|
marketplaceName: marketplace.name,
|
|
12802
12928
|
marketplaceRoot,
|
|
12803
12929
|
plugins: installed
|
|
12804
12930
|
});
|
|
12805
|
-
const configPath =
|
|
12931
|
+
const configPath = join29(codexHome, "config.toml");
|
|
12806
12932
|
await updateCodexConfig({
|
|
12807
12933
|
configPath,
|
|
12808
12934
|
repoRoot: codexPackageRoot,
|
|
@@ -12861,7 +12987,7 @@ function findRepoRootFromImporter(importerDir) {
|
|
|
12861
12987
|
for (let depth = 0;depth <= 7; depth += 1) {
|
|
12862
12988
|
if (isRepoRootWithCodexPlugin(current))
|
|
12863
12989
|
return current;
|
|
12864
|
-
for (const wrapperPackageRoot of [
|
|
12990
|
+
for (const wrapperPackageRoot of [join29(current, "node_modules", "oh-my-openagent"), join29(current, "oh-my-openagent")]) {
|
|
12865
12991
|
if (isRepoRootWithCodexPlugin(wrapperPackageRoot))
|
|
12866
12992
|
return wrapperPackageRoot;
|
|
12867
12993
|
}
|
|
@@ -12879,7 +13005,7 @@ function findRepoRoot(input) {
|
|
|
12879
13005
|
return findRepoRootFromImporter(input.importerDir);
|
|
12880
13006
|
}
|
|
12881
13007
|
function isRepoRootWithCodexPlugin(repoRoot) {
|
|
12882
|
-
return existsSync6(
|
|
13008
|
+
return existsSync6(join29(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
|
|
12883
13009
|
}
|
|
12884
13010
|
function codexMarketplaceSource(marketplaceRoot) {
|
|
12885
13011
|
return { sourceType: "local", source: marketplaceRoot };
|
|
@@ -13089,11 +13215,48 @@ function buildDelegatedOmoInvocation(parsed) {
|
|
|
13089
13215
|
// packages/omo-codex/src/install/lazycodex-manual-update.ts
|
|
13090
13216
|
import { spawn as spawn4, spawnSync as spawnSync2 } from "node:child_process";
|
|
13091
13217
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
13092
|
-
import { dirname as dirname8, join as
|
|
13218
|
+
import { dirname as dirname8, join as join31 } from "node:path";
|
|
13219
|
+
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
13093
13220
|
import { fileURLToPath } from "node:url";
|
|
13221
|
+
|
|
13222
|
+
// packages/omo-codex/src/install/lazycodex-bun-global-paths.ts
|
|
13223
|
+
import { join as join30 } from "node:path";
|
|
13224
|
+
function isBunGlobalEntrypointPath(invokedPath, env3) {
|
|
13225
|
+
if (typeof invokedPath !== "string" || invokedPath.trim().length === 0)
|
|
13226
|
+
return false;
|
|
13227
|
+
const normalizedPath = normalizePathForPrefix(invokedPath);
|
|
13228
|
+
return resolveBunGlobalRoots(env3).some((root) => normalizedPath.startsWith(root));
|
|
13229
|
+
}
|
|
13230
|
+
function resolveBunGlobalRoots(env3) {
|
|
13231
|
+
const bunInstallRoot = env3.BUN_INSTALL?.trim();
|
|
13232
|
+
const homeRoot = env3.HOME?.trim();
|
|
13233
|
+
return [
|
|
13234
|
+
...bunInstallRoot ? [join30(bunInstallRoot, "bin"), join30(bunInstallRoot, "install", "global", "node_modules")] : [],
|
|
13235
|
+
...homeRoot ? [join30(homeRoot, ".bun", "bin"), join30(homeRoot, ".bun", "install", "global", "node_modules")] : []
|
|
13236
|
+
].map(normalizePathForPrefix);
|
|
13237
|
+
}
|
|
13238
|
+
function normalizePathForPrefix(path2) {
|
|
13239
|
+
const normalized = path2.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
13240
|
+
return normalized.endsWith("/node_modules") || normalized.endsWith("/bin") ? `${normalized}/` : normalized;
|
|
13241
|
+
}
|
|
13242
|
+
|
|
13243
|
+
// packages/omo-codex/src/install/lazycodex-manual-update.ts
|
|
13094
13244
|
var DEFAULT_UPDATE_COMMAND = "npx";
|
|
13095
13245
|
var DEFAULT_UPDATE_ARGS = ["--yes", "lazycodex-ai@latest", "install", "--no-tui", "--codex-autonomous"];
|
|
13246
|
+
var BUN_UPDATE_COMMAND = "bun";
|
|
13247
|
+
var BUN_GLOBAL_UPDATE_ARGS = ["update", "-g", "lazycodex-ai@latest"];
|
|
13248
|
+
var BUN_GLOBAL_UNTRUSTED_ARGS = ["pm", "-g", "untrusted"];
|
|
13249
|
+
var BUN_GLOBAL_TRUST_ARGS = ["pm", "-g", "trust"];
|
|
13096
13250
|
var INSTALLED_VERSION_FILE = "lazycodex-install.json";
|
|
13251
|
+
var KNOWN_LAZYCODEX_BUN_TRUST_PACKAGES = new Set([
|
|
13252
|
+
"@ast-grep/cli",
|
|
13253
|
+
"@code-yeongyu/comment-checker",
|
|
13254
|
+
"@sisyphuslabs/omo-codex-plugin",
|
|
13255
|
+
"lazycodex-ai",
|
|
13256
|
+
"oh-my-openagent",
|
|
13257
|
+
"oh-my-opencode"
|
|
13258
|
+
]);
|
|
13259
|
+
var KNOWN_LAZYCODEX_BUN_TRUST_PREFIXES = ["@oh-my-opencode/", "oh-my-openagent-", "oh-my-opencode-"];
|
|
13097
13260
|
async function runLazyCodexManualUpdate(input = {}) {
|
|
13098
13261
|
const env3 = input.env ?? process.env;
|
|
13099
13262
|
const log2 = input.log ?? console.log;
|
|
@@ -13104,7 +13267,9 @@ async function runLazyCodexManualUpdate(input = {}) {
|
|
|
13104
13267
|
currentVersion,
|
|
13105
13268
|
latestVersion,
|
|
13106
13269
|
command: resolveCommand2(env3),
|
|
13107
|
-
args: resolveArgs(env3)
|
|
13270
|
+
args: resolveArgs(env3),
|
|
13271
|
+
env: env3,
|
|
13272
|
+
invokedPath: input.invokedPath ?? process.argv[1]
|
|
13108
13273
|
});
|
|
13109
13274
|
if (!plan.shouldUpdate) {
|
|
13110
13275
|
const printableVersion = currentVersion ?? "unknown";
|
|
@@ -13113,9 +13278,20 @@ async function runLazyCodexManualUpdate(input = {}) {
|
|
|
13113
13278
|
}
|
|
13114
13279
|
if (input.dryRun) {
|
|
13115
13280
|
log2(`${plan.command} ${plan.args.join(" ")}`);
|
|
13281
|
+
if (plan.postUpdate === "bun-global-trust")
|
|
13282
|
+
log2(`${DEFAULT_UPDATE_COMMAND} ${DEFAULT_UPDATE_ARGS.join(" ")}`);
|
|
13116
13283
|
return 0;
|
|
13117
13284
|
}
|
|
13118
13285
|
await commandRunner(plan.command, plan.args, { cwd: process.cwd(), env: env3 });
|
|
13286
|
+
if (plan.postUpdate === "bun-global-trust") {
|
|
13287
|
+
await handleBunGlobalTrust({
|
|
13288
|
+
env: env3,
|
|
13289
|
+
log: log2,
|
|
13290
|
+
commandRunner,
|
|
13291
|
+
isInteractive: input.isInteractive ?? (process.stdin.isTTY === true && process.stdout.isTTY === true)
|
|
13292
|
+
});
|
|
13293
|
+
await commandRunner(DEFAULT_UPDATE_COMMAND, DEFAULT_UPDATE_ARGS, { cwd: process.cwd(), env: env3 });
|
|
13294
|
+
}
|
|
13119
13295
|
return 0;
|
|
13120
13296
|
}
|
|
13121
13297
|
function resolveLazyCodexUpdatePlan(input = {}) {
|
|
@@ -13127,7 +13303,10 @@ function resolveLazyCodexUpdatePlan(input = {}) {
|
|
|
13127
13303
|
return { shouldUpdate: false, reason: "unknown-latest" };
|
|
13128
13304
|
if (compareVersions(latest, current) <= 0)
|
|
13129
13305
|
return { shouldUpdate: false, reason: "up-to-date" };
|
|
13130
|
-
|
|
13306
|
+
if (isBunGlobalEntrypoint(input.invokedPath, input.env ?? process.env)) {
|
|
13307
|
+
return { shouldUpdate: true, command: BUN_UPDATE_COMMAND, args: BUN_GLOBAL_UPDATE_ARGS, postUpdate: "bun-global-trust" };
|
|
13308
|
+
}
|
|
13309
|
+
return { shouldUpdate: true, command: input.command ?? DEFAULT_UPDATE_COMMAND, args: input.args ?? DEFAULT_UPDATE_ARGS, postUpdate: "none" };
|
|
13131
13310
|
}
|
|
13132
13311
|
function resolveCommand2(env3) {
|
|
13133
13312
|
return env3.LAZYCODEX_AUTO_UPDATE_COMMAND?.trim() || DEFAULT_UPDATE_COMMAND;
|
|
@@ -13146,7 +13325,7 @@ function resolveCurrentVersion(env3) {
|
|
|
13146
13325
|
if (env3.LAZYCODEX_CURRENT_VERSION?.trim())
|
|
13147
13326
|
return env3.LAZYCODEX_CURRENT_VERSION.trim();
|
|
13148
13327
|
const pluginRoot = dirname8(dirname8(fileURLToPath(import.meta.url)));
|
|
13149
|
-
return readVersionManifest(resolveInstalledVersionPath(env3, pluginRoot)) ?? readVersionManifest(
|
|
13328
|
+
return readVersionManifest(resolveInstalledVersionPath(env3, pluginRoot)) ?? readVersionManifest(join31(pluginRoot, "..", "..", "..", "package.json")) ?? readVersionManifest(join31(pluginRoot, ".codex-plugin", "plugin.json"));
|
|
13150
13329
|
}
|
|
13151
13330
|
function resolveLatestVersion(env3) {
|
|
13152
13331
|
if (env3.LAZYCODEX_LATEST_VERSION?.trim())
|
|
@@ -13160,6 +13339,57 @@ function resolveLatestVersion(env3) {
|
|
|
13160
13339
|
const version2 = result.stdout.trim();
|
|
13161
13340
|
return version2.length > 0 ? version2 : undefined;
|
|
13162
13341
|
}
|
|
13342
|
+
async function handleBunGlobalTrust(input) {
|
|
13343
|
+
const packageNames = resolveKnownBunGlobalUntrustedPackages(input.env);
|
|
13344
|
+
if (packageNames.length === 0)
|
|
13345
|
+
return;
|
|
13346
|
+
const trustArgs = [...BUN_GLOBAL_TRUST_ARGS, ...packageNames];
|
|
13347
|
+
const trustCommand = [BUN_UPDATE_COMMAND, ...trustArgs].join(" ");
|
|
13348
|
+
if (!input.isInteractive) {
|
|
13349
|
+
input.log(`Bun blocked LazyCodex-related postinstall scripts. Run this command to trust them:
|
|
13350
|
+
${trustCommand}`);
|
|
13351
|
+
return;
|
|
13352
|
+
}
|
|
13353
|
+
if (await confirmBunGlobalTrust(packageNames)) {
|
|
13354
|
+
await input.commandRunner(BUN_UPDATE_COMMAND, trustArgs, { cwd: process.cwd(), env: input.env });
|
|
13355
|
+
return;
|
|
13356
|
+
}
|
|
13357
|
+
input.log(`Skipped Bun postinstall trust. To run it later:
|
|
13358
|
+
${trustCommand}`);
|
|
13359
|
+
}
|
|
13360
|
+
function resolveKnownBunGlobalUntrustedPackages(env3) {
|
|
13361
|
+
const result = spawnSync2(BUN_UPDATE_COMMAND, BUN_GLOBAL_UNTRUSTED_ARGS, {
|
|
13362
|
+
encoding: "utf8",
|
|
13363
|
+
env: env3,
|
|
13364
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
13365
|
+
});
|
|
13366
|
+
if (result.status !== 0)
|
|
13367
|
+
return [];
|
|
13368
|
+
const names = [];
|
|
13369
|
+
for (const match of result.stdout.matchAll(/^\.\/node_modules\/((?:@[^/\s]+\/)?[^\s]+)\s+@/gm)) {
|
|
13370
|
+
const packageName = match[1];
|
|
13371
|
+
if (packageName !== undefined && isKnownLazyCodexBunTrustPackage(packageName) && !names.includes(packageName)) {
|
|
13372
|
+
names.push(packageName);
|
|
13373
|
+
}
|
|
13374
|
+
}
|
|
13375
|
+
return names;
|
|
13376
|
+
}
|
|
13377
|
+
async function confirmBunGlobalTrust(packageNames) {
|
|
13378
|
+
const prompt = `Trust Bun postinstall scripts for ${packageNames.join(", ")}? [y/N] `;
|
|
13379
|
+
const readline = createInterface2({ input: process.stdin, output: process.stdout });
|
|
13380
|
+
try {
|
|
13381
|
+
const answer = (await readline.question(prompt)).trim().toLowerCase();
|
|
13382
|
+
return answer === "y" || answer === "yes";
|
|
13383
|
+
} finally {
|
|
13384
|
+
readline.close();
|
|
13385
|
+
}
|
|
13386
|
+
}
|
|
13387
|
+
function isKnownLazyCodexBunTrustPackage(packageName) {
|
|
13388
|
+
return KNOWN_LAZYCODEX_BUN_TRUST_PACKAGES.has(packageName) || KNOWN_LAZYCODEX_BUN_TRUST_PREFIXES.some((prefix) => packageName.startsWith(prefix));
|
|
13389
|
+
}
|
|
13390
|
+
function isBunGlobalEntrypoint(invokedPath, env3) {
|
|
13391
|
+
return isBunGlobalEntrypointPath(invokedPath, env3);
|
|
13392
|
+
}
|
|
13163
13393
|
function defaultRunCommandForManualUpdate(command, args, options) {
|
|
13164
13394
|
return new Promise((resolve11, reject) => {
|
|
13165
13395
|
const child = spawn4(command, args, {
|
|
@@ -13211,7 +13441,7 @@ function compareVersions(left, right) {
|
|
|
13211
13441
|
function resolveInstalledVersionPath(env3, pluginRoot) {
|
|
13212
13442
|
if (env3.LAZYCODEX_INSTALLED_VERSION_FILE?.trim())
|
|
13213
13443
|
return env3.LAZYCODEX_INSTALLED_VERSION_FILE.trim();
|
|
13214
|
-
return
|
|
13444
|
+
return join31(pluginRoot, INSTALLED_VERSION_FILE);
|
|
13215
13445
|
}
|
|
13216
13446
|
function readVersionManifest(path2) {
|
|
13217
13447
|
try {
|
|
@@ -13227,80 +13457,46 @@ function readVersionManifest(path2) {
|
|
|
13227
13457
|
}
|
|
13228
13458
|
}
|
|
13229
13459
|
// packages/omo-codex/src/install/codex-git-bash-mcp-env.ts
|
|
13230
|
-
import { readFile as
|
|
13231
|
-
import { join as
|
|
13460
|
+
import { readFile as readFile18, writeFile as writeFile10 } from "node:fs/promises";
|
|
13461
|
+
import { join as join32 } from "node:path";
|
|
13232
13462
|
var GIT_BASH_ENV_KEY2 = "OMO_CODEX_GIT_BASH_PATH";
|
|
13463
|
+
var CODEGRAPH_RELATIVE_ARGS2 = new Set(["components/codegraph/dist/serve.js", "./components/codegraph/dist/serve.js"]);
|
|
13233
13464
|
async function stampGitBashMcpEnv(input) {
|
|
13234
|
-
|
|
13235
|
-
return false;
|
|
13236
|
-
const rawOverride = input.env?.[GIT_BASH_ENV_KEY2];
|
|
13237
|
-
const override = typeof rawOverride === "string" ? rawOverride.trim() : "";
|
|
13238
|
-
if (override === "")
|
|
13239
|
-
return false;
|
|
13240
|
-
const manifestPath = join30(input.pluginRoot, ".mcp.json");
|
|
13465
|
+
const manifestPath = join32(input.pluginRoot, ".mcp.json");
|
|
13241
13466
|
if (!await fileExistsStrict(manifestPath))
|
|
13242
13467
|
return false;
|
|
13243
|
-
const parsed = JSON.parse(await
|
|
13468
|
+
const parsed = JSON.parse(await readFile18(manifestPath, "utf8"));
|
|
13244
13469
|
if (!isPlainRecord(parsed) || !isPlainRecord(parsed["mcpServers"]))
|
|
13245
13470
|
return false;
|
|
13246
|
-
|
|
13247
|
-
if (
|
|
13248
|
-
|
|
13249
|
-
|
|
13250
|
-
|
|
13471
|
+
let changed = stampCodegraphMcpPath(parsed["mcpServers"], input.pluginRoot);
|
|
13472
|
+
if (input.platform === "win32") {
|
|
13473
|
+
const rawOverride = input.env?.[GIT_BASH_ENV_KEY2];
|
|
13474
|
+
const override = typeof rawOverride === "string" ? rawOverride.trim() : "";
|
|
13475
|
+
const gitBashServer = parsed["mcpServers"]["git_bash"];
|
|
13476
|
+
if (override !== "" && isPlainRecord(gitBashServer)) {
|
|
13477
|
+
const serverEnv = isPlainRecord(gitBashServer["env"]) ? gitBashServer["env"] : {};
|
|
13478
|
+
if (serverEnv[GIT_BASH_ENV_KEY2] !== override) {
|
|
13479
|
+
gitBashServer["env"] = { ...serverEnv, [GIT_BASH_ENV_KEY2]: override };
|
|
13480
|
+
changed = true;
|
|
13481
|
+
}
|
|
13482
|
+
}
|
|
13483
|
+
}
|
|
13484
|
+
if (!changed)
|
|
13251
13485
|
return false;
|
|
13252
|
-
gitBashServer["env"] = { ...serverEnv, [GIT_BASH_ENV_KEY2]: override };
|
|
13253
13486
|
await writeFile10(manifestPath, `${JSON.stringify(parsed, null, "\t")}
|
|
13254
13487
|
`);
|
|
13255
13488
|
return true;
|
|
13256
13489
|
}
|
|
13257
|
-
|
|
13258
|
-
|
|
13259
|
-
|
|
13260
|
-
|
|
13261
|
-
|
|
13262
|
-
const
|
|
13263
|
-
if (!
|
|
13264
|
-
return
|
|
13265
|
-
|
|
13266
|
-
|
|
13267
|
-
collectCommands(parsed, commands);
|
|
13268
|
-
const missing = [];
|
|
13269
|
-
const seen = new Set;
|
|
13270
|
-
for (const command of commands) {
|
|
13271
|
-
for (const match of command.matchAll(PLUGIN_ROOT_TARGET_PATTERN)) {
|
|
13272
|
-
const targetSuffix = match[1];
|
|
13273
|
-
if (targetSuffix === undefined)
|
|
13274
|
-
continue;
|
|
13275
|
-
const target = join31(pluginRoot, ...targetSuffix.split("/"));
|
|
13276
|
-
if (seen.has(target))
|
|
13277
|
-
continue;
|
|
13278
|
-
seen.add(target);
|
|
13279
|
-
if (!await fileExistsStrict(target))
|
|
13280
|
-
missing.push(target);
|
|
13281
|
-
}
|
|
13282
|
-
}
|
|
13283
|
-
return missing;
|
|
13284
|
-
}
|
|
13285
|
-
async function assertHookCommandTargets(pluginRoot) {
|
|
13286
|
-
const missing = await findMissingHookCommandTargets(pluginRoot);
|
|
13287
|
-
if (missing.length === 0)
|
|
13288
|
-
return;
|
|
13289
|
-
const relativeMissing = missing.map((path2) => path2.split(`${pluginRoot}${sep8}`).join("").split(sep8).join("/"));
|
|
13290
|
-
throw new Error(`Plugin payload is missing ${missing.length} hook command target(s) referenced by hooks.json: ${relativeMissing.join(", ")}. ` + "The previous plugin cache was left untouched; this payload was not activated.");
|
|
13291
|
-
}
|
|
13292
|
-
function collectCommands(value, commands) {
|
|
13293
|
-
if (Array.isArray(value)) {
|
|
13294
|
-
for (const entry of value)
|
|
13295
|
-
collectCommands(entry, commands);
|
|
13296
|
-
return;
|
|
13297
|
-
}
|
|
13298
|
-
if (!isPlainRecord(value))
|
|
13299
|
-
return;
|
|
13300
|
-
if (value["type"] === "command" && typeof value["command"] === "string")
|
|
13301
|
-
commands.push(value["command"]);
|
|
13302
|
-
for (const entry of Object.values(value))
|
|
13303
|
-
collectCommands(entry, commands);
|
|
13490
|
+
function stampCodegraphMcpPath(mcpServers, pluginRoot) {
|
|
13491
|
+
const codegraphServer = mcpServers["codegraph"];
|
|
13492
|
+
if (!isPlainRecord(codegraphServer) || !Array.isArray(codegraphServer["args"]))
|
|
13493
|
+
return false;
|
|
13494
|
+
const args = codegraphServer["args"];
|
|
13495
|
+
const entrypoint = args[0];
|
|
13496
|
+
if (typeof entrypoint !== "string" || !CODEGRAPH_RELATIVE_ARGS2.has(entrypoint))
|
|
13497
|
+
return false;
|
|
13498
|
+
codegraphServer["args"] = [join32(pluginRoot, "components", "codegraph", "dist", "serve.js"), ...args.slice(1)];
|
|
13499
|
+
return true;
|
|
13304
13500
|
}
|
|
13305
13501
|
|
|
13306
13502
|
// packages/omo-codex/src/install/install-local-cli.ts
|
|
@@ -13320,7 +13516,7 @@ async function runLazyCodexInstallLocalCli(input) {
|
|
|
13320
13516
|
return 0;
|
|
13321
13517
|
}
|
|
13322
13518
|
if (parsed.kind === "version") {
|
|
13323
|
-
const packageJson = JSON.parse(await readFile19(
|
|
13519
|
+
const packageJson = JSON.parse(await readFile19(join33(input.defaultRepoRoot, "package.json"), "utf8"));
|
|
13324
13520
|
const version2 = typeof packageJson.version === "string" ? packageJson.version : "unknown";
|
|
13325
13521
|
input.log(`lazycodex-ai ${version2}`);
|
|
13326
13522
|
return 0;
|
|
@@ -13343,7 +13539,7 @@ async function runLazyCodexInstallLocalCli(input) {
|
|
|
13343
13539
|
input.log(`Installed ${result2.installed.length} plugin(s) from ${result2.marketplaceName}.`);
|
|
13344
13540
|
return 0;
|
|
13345
13541
|
}
|
|
13346
|
-
return runLazyCodexManualUpdate({ env: input.env, dryRun: parsed.dryRun, log: input.log });
|
|
13542
|
+
return runLazyCodexManualUpdate({ env: input.env, dryRun: parsed.dryRun, log: input.log, invokedPath: input.invokedPath });
|
|
13347
13543
|
}
|
|
13348
13544
|
const repoRoot = parsed.repoRoot ? resolve11(parsed.repoRoot) : input.defaultRepoRoot;
|
|
13349
13545
|
const result = await installMarketplaceLocally({
|