oh-my-opencode 4.11.1 → 4.12.1
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/types.d.ts +7 -6
- package/dist/cli/index.js +460 -309
- package/dist/cli-node/index.js +460 -309
- 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/index.js +593 -310
- package/dist/plugin/tool-execute-before.d.ts +2 -0
- package/dist/plugin-handlers/plugin-components-loader.d.ts +1 -0
- package/dist/skills/ultraresearch/SKILL.md +11 -2
- 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/background-task/constants.d.ts +1 -1
- 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 +25 -10
- package/package.json +13 -13
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +24 -2
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +25 -9
- 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 +336 -173
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +284 -33
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +11 -0
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +12 -0
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +34 -0
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +47 -5
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +7 -5
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +58 -96
- 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/codegraph/test/serve-provision.test.ts +48 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +1 -0
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +142 -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/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +12 -92
- 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/dist/cli.js +94 -0
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +17 -0
- package/packages/omo-codex/plugin/components/teammode/package.json +26 -0
- 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/teammode/src/cli.ts +12 -0
- package/packages/omo-codex/plugin/components/teammode/src/codex-hook.ts +125 -0
- package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +116 -0
- package/packages/omo-codex/plugin/components/teammode/tsconfig.json +25 -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-codegraph-init-guidance.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-checking-thread-title-hygiene.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 +30 -22
- package/packages/omo-codex/plugin/package.json +2 -1
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +15 -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/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/agents/openai.yaml +2 -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/SKILL.md +11 -2
- 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 +70 -33
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +6 -2
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +14 -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/component-bundled-cli.test.mjs +4 -3
- package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +24 -0
- package/packages/omo-codex/plugin/test/display-metadata.test.mjs +83 -0
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +31 -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/plugin/test/ultraresearch-skill-contract.test.mjs +48 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +398 -206
- 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/shared-skills/skills/ultraresearch/SKILL.md +11 -2
- 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.1",
|
|
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";
|
|
@@ -7055,13 +7055,83 @@ async function rewriteCachedManifestRoot(pluginRoot, fromRoot, toRoot) {
|
|
|
7055
7055
|
`);
|
|
7056
7056
|
}
|
|
7057
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
|
+
|
|
7058
7128
|
// packages/omo-codex/src/install/codex-cache-install.ts
|
|
7059
7129
|
async function installCachedPlugin(input) {
|
|
7060
7130
|
if (input.buildSource !== false) {
|
|
7061
7131
|
await maybeRunNpmInstall(input.sourcePath, input.runCommand);
|
|
7062
7132
|
await maybeRunNpmBuild(input.sourcePath, input.runCommand);
|
|
7063
7133
|
}
|
|
7064
|
-
const targetPath =
|
|
7134
|
+
const targetPath = join9(input.codexHome, "plugins", "cache", input.marketplaceName, input.name, input.version);
|
|
7065
7135
|
const tempPath = createTempSiblingPath(targetPath);
|
|
7066
7136
|
await rm3(tempPath, { recursive: true, force: true });
|
|
7067
7137
|
try {
|
|
@@ -7069,8 +7139,11 @@ async function installCachedPlugin(input) {
|
|
|
7069
7139
|
await rewriteCachedPackageLocalFileDependencies(tempPath, input.sourcePath);
|
|
7070
7140
|
await copyBundledMcpRuntimeDists({ pluginRoot: tempPath, sourceRoot: input.sourcePath });
|
|
7071
7141
|
await maybeRunNpmInstall(tempPath, input.runCommand, ["ci", "--omit=dev"]);
|
|
7142
|
+
if (input.buildSource === false)
|
|
7143
|
+
await maybeRunNpmSyncSkills(tempPath, input.runCommand);
|
|
7072
7144
|
await rewriteCachedMcpManifest(tempPath, input.sourcePath);
|
|
7073
7145
|
await rewriteCachedManifestRoot(tempPath, tempPath, targetPath);
|
|
7146
|
+
await assertHookCommandTargets(tempPath);
|
|
7074
7147
|
await promoteDirectory(tempPath, targetPath, input.renameDirectory ?? rename);
|
|
7075
7148
|
} catch (error) {
|
|
7076
7149
|
await rm3(tempPath, { recursive: true, force: true });
|
|
@@ -7079,14 +7152,14 @@ async function installCachedPlugin(input) {
|
|
|
7079
7152
|
return { name: input.name, version: input.version, path: targetPath };
|
|
7080
7153
|
}
|
|
7081
7154
|
async function maybeRunNpmInstall(cwd, runCommand, args = ["install"]) {
|
|
7082
|
-
if (!await fileExistsStrict(
|
|
7155
|
+
if (!await fileExistsStrict(join9(cwd, "package.json")))
|
|
7083
7156
|
return;
|
|
7084
7157
|
await runCommand("npm", args, { cwd });
|
|
7085
7158
|
}
|
|
7086
7159
|
async function maybeRunNpmBuild(cwd, runCommand) {
|
|
7087
|
-
if (!await fileExistsStrict(
|
|
7160
|
+
if (!await fileExistsStrict(join9(cwd, "package.json")))
|
|
7088
7161
|
return;
|
|
7089
|
-
const packageJson = JSON.parse(await
|
|
7162
|
+
const packageJson = JSON.parse(await readFile7(join9(cwd, "package.json"), "utf8"));
|
|
7090
7163
|
if (!isPlainRecord(packageJson))
|
|
7091
7164
|
return;
|
|
7092
7165
|
const scripts = packageJson.scripts;
|
|
@@ -7094,11 +7167,22 @@ async function maybeRunNpmBuild(cwd, runCommand) {
|
|
|
7094
7167
|
return;
|
|
7095
7168
|
await runCommand("npm", ["run", "build"], { cwd });
|
|
7096
7169
|
}
|
|
7170
|
+
async function maybeRunNpmSyncSkills(cwd, runCommand) {
|
|
7171
|
+
if (!await fileExistsStrict(join9(cwd, "package.json")))
|
|
7172
|
+
return;
|
|
7173
|
+
const packageJson = JSON.parse(await readFile7(join9(cwd, "package.json"), "utf8"));
|
|
7174
|
+
if (!isPlainRecord(packageJson))
|
|
7175
|
+
return;
|
|
7176
|
+
const scripts = packageJson.scripts;
|
|
7177
|
+
if (!isPlainRecord(scripts) || typeof scripts["sync:skills"] !== "string")
|
|
7178
|
+
return;
|
|
7179
|
+
await runCommand("npm", ["run", "sync:skills"], { cwd });
|
|
7180
|
+
}
|
|
7097
7181
|
function createTempSiblingPath(targetPath) {
|
|
7098
|
-
return
|
|
7182
|
+
return join9(dirname3(targetPath), `.tmp-${basename2(targetPath)}-${process.pid}-${Date.now()}`);
|
|
7099
7183
|
}
|
|
7100
7184
|
function createBackupSiblingPath(targetPath) {
|
|
7101
|
-
return
|
|
7185
|
+
return join9(dirname3(targetPath), `.backup-${basename2(targetPath)}-${process.pid}-${Date.now()}`);
|
|
7102
7186
|
}
|
|
7103
7187
|
async function copyDirectory(sourcePath, targetPath) {
|
|
7104
7188
|
await mkdir3(dirname3(targetPath), { recursive: true });
|
|
@@ -7129,17 +7213,17 @@ async function restoreBackupDirectory(backupPath, targetPath, renameDirectory) {
|
|
|
7129
7213
|
await renameDirectory(backupPath, targetPath);
|
|
7130
7214
|
}
|
|
7131
7215
|
function shouldCopyPluginPath(path, root) {
|
|
7132
|
-
const relative4 = path === root ? "" : path.slice(root.length +
|
|
7216
|
+
const relative4 = path === root ? "" : path.slice(root.length + sep5.length);
|
|
7133
7217
|
if (relative4 === "")
|
|
7134
7218
|
return true;
|
|
7135
|
-
const parts = relative4.split(
|
|
7219
|
+
const parts = relative4.split(sep5);
|
|
7136
7220
|
return !parts.some((part) => part === ".git" || part === "node_modules");
|
|
7137
7221
|
}
|
|
7138
7222
|
// packages/omo-codex/src/install/codex-cache-prune.ts
|
|
7139
7223
|
import { lstat as lstat4, readdir as readdir3, rm as rm4, stat as stat3 } from "node:fs/promises";
|
|
7140
|
-
import { join as
|
|
7224
|
+
import { join as join10 } from "node:path";
|
|
7141
7225
|
async function pruneMarketplaceCache(input) {
|
|
7142
|
-
const cacheRoot =
|
|
7226
|
+
const cacheRoot = join10(input.codexHome, "plugins", "cache", input.marketplaceName);
|
|
7143
7227
|
if (!await fileExistsStrict(cacheRoot))
|
|
7144
7228
|
return;
|
|
7145
7229
|
const keep = new Set(input.keepPluginNames);
|
|
@@ -7147,15 +7231,15 @@ async function pruneMarketplaceCache(input) {
|
|
|
7147
7231
|
for (const entry of entries) {
|
|
7148
7232
|
if (!entry.isDirectory() || keep.has(entry.name))
|
|
7149
7233
|
continue;
|
|
7150
|
-
await rm4(
|
|
7234
|
+
await rm4(join10(cacheRoot, entry.name), { recursive: true, force: true });
|
|
7151
7235
|
}
|
|
7152
7236
|
}
|
|
7153
7237
|
async function pruneMarketplacePluginCaches(input) {
|
|
7154
|
-
const cacheRoot =
|
|
7238
|
+
const cacheRoot = join10(input.codexHome, "plugins", "cache", input.marketplaceName);
|
|
7155
7239
|
if (!await fileExistsStrict(cacheRoot))
|
|
7156
7240
|
return;
|
|
7157
7241
|
for (const pluginName of input.pluginNames) {
|
|
7158
|
-
await rm4(
|
|
7242
|
+
await rm4(join10(cacheRoot, pluginName), { recursive: true, force: true });
|
|
7159
7243
|
}
|
|
7160
7244
|
const remainingEntries = await readCacheEntryNames(cacheRoot);
|
|
7161
7245
|
if (remainingEntries.length === 0) {
|
|
@@ -7202,11 +7286,11 @@ async function isBrokenCacheSymlink(path) {
|
|
|
7202
7286
|
}
|
|
7203
7287
|
// packages/omo-codex/src/install/codex-cached-marketplace-manifest.ts
|
|
7204
7288
|
import { mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
|
|
7205
|
-
import { join as
|
|
7289
|
+
import { join as join11 } from "node:path";
|
|
7206
7290
|
async function writeCachedMarketplaceManifest(input) {
|
|
7207
|
-
const marketplaceDir =
|
|
7291
|
+
const marketplaceDir = join11(input.marketplaceRoot, ".agents", "plugins");
|
|
7208
7292
|
await mkdir4(marketplaceDir, { recursive: true });
|
|
7209
|
-
await writeFile4(
|
|
7293
|
+
await writeFile4(join11(marketplaceDir, "marketplace.json"), `${JSON.stringify({
|
|
7210
7294
|
name: input.marketplaceName,
|
|
7211
7295
|
plugins: input.plugins.map((plugin) => ({
|
|
7212
7296
|
name: plugin.name,
|
|
@@ -7218,8 +7302,8 @@ async function writeCachedMarketplaceManifest(input) {
|
|
|
7218
7302
|
|
|
7219
7303
|
// packages/omo-codex/src/install/codex-package-layout.ts
|
|
7220
7304
|
import { existsSync as existsSync2 } from "node:fs";
|
|
7221
|
-
import { readFile as
|
|
7222
|
-
import { join as
|
|
7305
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
7306
|
+
import { join as join12 } from "node:path";
|
|
7223
7307
|
var PACKAGED_CODEX_INSTALLER_NAMES = new Set([
|
|
7224
7308
|
"@code-yeongyu/lazycodex",
|
|
7225
7309
|
"@code-yeongyu/lazycodex-ai",
|
|
@@ -7229,19 +7313,19 @@ var PACKAGED_CODEX_INSTALLER_NAMES = new Set([
|
|
|
7229
7313
|
"oh-my-openagent"
|
|
7230
7314
|
]);
|
|
7231
7315
|
async function shouldBuildSourcePackages(repoRoot) {
|
|
7232
|
-
if (existsSync2(
|
|
7316
|
+
if (existsSync2(join12(repoRoot, "packages", "omo-opencode", "src", "index.ts")))
|
|
7233
7317
|
return true;
|
|
7234
|
-
const packageJsonPath =
|
|
7318
|
+
const packageJsonPath = join12(repoRoot, "package.json");
|
|
7235
7319
|
if (!existsSync2(packageJsonPath))
|
|
7236
7320
|
return true;
|
|
7237
|
-
const packageJson = JSON.parse(await
|
|
7321
|
+
const packageJson = JSON.parse(await readFile8(packageJsonPath, "utf8"));
|
|
7238
7322
|
if (!isPlainRecord(packageJson) || typeof packageJson.name !== "string")
|
|
7239
7323
|
return true;
|
|
7240
7324
|
return !PACKAGED_CODEX_INSTALLER_NAMES.has(packageJson.name);
|
|
7241
7325
|
}
|
|
7242
7326
|
|
|
7243
7327
|
// packages/omo-codex/src/install/codex-config-toml.ts
|
|
7244
|
-
import { mkdir as mkdir5, readFile as
|
|
7328
|
+
import { mkdir as mkdir5, readFile as readFile10 } from "node:fs/promises";
|
|
7245
7329
|
import { dirname as dirname5 } from "node:path";
|
|
7246
7330
|
|
|
7247
7331
|
// packages/omo-codex/src/install/toml-section-editor.ts
|
|
@@ -7429,12 +7513,12 @@ function tomlKeySegment(value) {
|
|
|
7429
7513
|
|
|
7430
7514
|
// packages/omo-codex/src/install/codex-config-atomic-write.ts
|
|
7431
7515
|
import { lstat as lstat5, readlink as readlink3, realpath, rename as rename2, unlink, writeFile as writeFile5 } from "node:fs/promises";
|
|
7432
|
-
import { basename as basename3, dirname as dirname4, isAbsolute as isAbsolute4, join as
|
|
7516
|
+
import { basename as basename3, dirname as dirname4, isAbsolute as isAbsolute4, join as join13, resolve as resolve5 } from "node:path";
|
|
7433
7517
|
var RENAME_RETRY_DELAYS_MS = [10, 25, 50];
|
|
7434
7518
|
var RETRIABLE_RENAME_CODES = new Set(["EPERM", "EBUSY"]);
|
|
7435
7519
|
async function writeFileAtomic(targetPath, data) {
|
|
7436
7520
|
const writeTarget = await resolveSymlinkTarget(targetPath);
|
|
7437
|
-
const temporaryPath =
|
|
7521
|
+
const temporaryPath = join13(dirname4(writeTarget), `.tmp-${basename3(writeTarget)}-${process.pid}-${Date.now()}`);
|
|
7438
7522
|
await writeFile5(temporaryPath, data);
|
|
7439
7523
|
try {
|
|
7440
7524
|
await renameWithRetry(temporaryPath, writeTarget);
|
|
@@ -7704,8 +7788,8 @@ function isRootSetting(line, key) {
|
|
|
7704
7788
|
}
|
|
7705
7789
|
|
|
7706
7790
|
// packages/omo-codex/src/install/codex-model-catalog.ts
|
|
7707
|
-
import { readFile as
|
|
7708
|
-
import { join as
|
|
7791
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
7792
|
+
import { join as join14 } from "node:path";
|
|
7709
7793
|
var FALLBACK_CODEX_MODEL_CATALOG = {
|
|
7710
7794
|
current: {
|
|
7711
7795
|
model: "gpt-5.5",
|
|
@@ -7724,9 +7808,9 @@ var FALLBACK_CODEX_MODEL_CATALOG = {
|
|
|
7724
7808
|
]
|
|
7725
7809
|
};
|
|
7726
7810
|
async function readCodexModelCatalog(codexPackageRoot) {
|
|
7727
|
-
const catalogPath =
|
|
7811
|
+
const catalogPath = join14(codexPackageRoot, "plugin", "model-catalog.json");
|
|
7728
7812
|
try {
|
|
7729
|
-
const parsed = JSON.parse(await
|
|
7813
|
+
const parsed = JSON.parse(await readFile9(catalogPath, "utf8"));
|
|
7730
7814
|
return parseCodexModelCatalog(parsed) ?? FALLBACK_CODEX_MODEL_CATALOG;
|
|
7731
7815
|
} catch (error) {
|
|
7732
7816
|
if (error instanceof Error)
|
|
@@ -7807,7 +7891,7 @@ async function updateCodexConfig(input) {
|
|
|
7807
7891
|
await mkdir5(dirname5(input.configPath), { recursive: true });
|
|
7808
7892
|
let config = "";
|
|
7809
7893
|
if (await exists(input.configPath))
|
|
7810
|
-
config = await
|
|
7894
|
+
config = await readFile10(input.configPath, "utf8");
|
|
7811
7895
|
const pluginSet = new Set(input.pluginNames);
|
|
7812
7896
|
for (const legacyMarketplaceName of legacyMarketplaceNames(input.marketplaceName)) {
|
|
7813
7897
|
config = removeMarketplaceBlock(config, legacyMarketplaceName);
|
|
@@ -7843,7 +7927,7 @@ async function updateCodexConfig(input) {
|
|
|
7843
7927
|
}
|
|
7844
7928
|
async function exists(path) {
|
|
7845
7929
|
try {
|
|
7846
|
-
await
|
|
7930
|
+
await readFile10(path, "utf8");
|
|
7847
7931
|
return true;
|
|
7848
7932
|
} catch (error) {
|
|
7849
7933
|
if (error instanceof Error)
|
|
@@ -7854,8 +7938,8 @@ async function exists(path) {
|
|
|
7854
7938
|
|
|
7855
7939
|
// packages/omo-codex/src/install/codex-hook-trust.ts
|
|
7856
7940
|
import { createHash } from "node:crypto";
|
|
7857
|
-
import { readFile as
|
|
7858
|
-
import { join as
|
|
7941
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
7942
|
+
import { join as join15 } from "node:path";
|
|
7859
7943
|
var EVENT_LABELS = new Map([
|
|
7860
7944
|
["PreToolUse", "pre_tool_use"],
|
|
7861
7945
|
["PermissionRequest", "permission_request"],
|
|
@@ -7869,21 +7953,37 @@ var EVENT_LABELS = new Map([
|
|
|
7869
7953
|
["Stop", "stop"]
|
|
7870
7954
|
]);
|
|
7871
7955
|
async function trustedHookStatesForPlugin(input) {
|
|
7872
|
-
const manifestPath =
|
|
7956
|
+
const manifestPath = join15(input.pluginRoot, ".codex-plugin", "plugin.json");
|
|
7873
7957
|
if (!await exists2(manifestPath))
|
|
7874
7958
|
return [];
|
|
7875
|
-
const manifest = JSON.parse(await
|
|
7876
|
-
if (!isPlainRecord(manifest)
|
|
7877
|
-
return [];
|
|
7878
|
-
const hooksPath = join14(input.pluginRoot, manifest.hooks);
|
|
7879
|
-
if (!await exists2(hooksPath))
|
|
7959
|
+
const manifest = JSON.parse(await readFile11(manifestPath, "utf8"));
|
|
7960
|
+
if (!isPlainRecord(manifest))
|
|
7880
7961
|
return [];
|
|
7881
|
-
const
|
|
7882
|
-
|
|
7962
|
+
const states = [];
|
|
7963
|
+
for (const hookPath of hookManifestPaths2(manifest.hooks)) {
|
|
7964
|
+
const hooksPath = join15(input.pluginRoot, hookPath);
|
|
7965
|
+
if (!await exists2(hooksPath))
|
|
7966
|
+
continue;
|
|
7967
|
+
const parsed = JSON.parse(await readFile11(hooksPath, "utf8"));
|
|
7968
|
+
if (!isPlainRecord(parsed) || !isPlainRecord(parsed.hooks))
|
|
7969
|
+
continue;
|
|
7970
|
+
states.push(...trustedHookStatesForHooksFile({
|
|
7971
|
+
keySource: `${input.pluginName}@${input.marketplaceName}:${hookPath}`,
|
|
7972
|
+
hooks: parsed.hooks
|
|
7973
|
+
}));
|
|
7974
|
+
}
|
|
7975
|
+
return states;
|
|
7976
|
+
}
|
|
7977
|
+
function hookManifestPaths2(value) {
|
|
7978
|
+
if (typeof value === "string" && value.trim() !== "")
|
|
7979
|
+
return [stripDotSlash2(value)];
|
|
7980
|
+
if (!Array.isArray(value))
|
|
7883
7981
|
return [];
|
|
7884
|
-
|
|
7982
|
+
return value.filter((item) => typeof item === "string" && item.trim() !== "").map(stripDotSlash2);
|
|
7983
|
+
}
|
|
7984
|
+
function trustedHookStatesForHooksFile(input) {
|
|
7885
7985
|
const states = [];
|
|
7886
|
-
for (const [eventName, groups] of Object.entries(
|
|
7986
|
+
for (const [eventName, groups] of Object.entries(input.hooks)) {
|
|
7887
7987
|
if (!Array.isArray(groups))
|
|
7888
7988
|
continue;
|
|
7889
7989
|
const eventLabel = EVENT_LABELS.get(eventName);
|
|
@@ -7899,7 +7999,7 @@ async function trustedHookStatesForPlugin(input) {
|
|
|
7899
7999
|
continue;
|
|
7900
8000
|
if (typeof handler.command !== "string" || handler.command.trim() === "")
|
|
7901
8001
|
continue;
|
|
7902
|
-
const key = `${keySource}:${eventLabel}:${groupIndex}:${handlerIndex}`;
|
|
8002
|
+
const key = `${input.keySource}:${eventLabel}:${groupIndex}:${handlerIndex}`;
|
|
7903
8003
|
states.push({ key, trustedHash: commandHookHash(eventLabel, group.matcher, handler) });
|
|
7904
8004
|
}
|
|
7905
8005
|
}
|
|
@@ -7933,12 +8033,12 @@ function canonicalJson(value) {
|
|
|
7933
8033
|
}
|
|
7934
8034
|
return result;
|
|
7935
8035
|
}
|
|
7936
|
-
function
|
|
8036
|
+
function stripDotSlash2(value) {
|
|
7937
8037
|
return value.startsWith("./") ? value.slice(2) : value;
|
|
7938
8038
|
}
|
|
7939
8039
|
async function exists2(path) {
|
|
7940
8040
|
try {
|
|
7941
|
-
await
|
|
8041
|
+
await readFile11(path, "utf8");
|
|
7942
8042
|
return true;
|
|
7943
8043
|
} catch (error) {
|
|
7944
8044
|
if (error instanceof Error)
|
|
@@ -7989,12 +8089,12 @@ function toCodexResolution(resolution) {
|
|
|
7989
8089
|
}
|
|
7990
8090
|
|
|
7991
8091
|
// packages/omo-codex/src/install/link-cached-plugin-agents.ts
|
|
7992
|
-
import { copyFile, lstat as lstat7, mkdir as mkdir6, readFile as
|
|
7993
|
-
import { basename as basename4, join as
|
|
8092
|
+
import { copyFile, lstat as lstat7, mkdir as mkdir6, readFile as readFile13, readdir as readdir4, rm as rm6, writeFile as writeFile6 } from "node:fs/promises";
|
|
8093
|
+
import { basename as basename4, join as join17 } from "node:path";
|
|
7994
8094
|
|
|
7995
8095
|
// packages/omo-codex/src/install/retired-managed-agent-purge.ts
|
|
7996
|
-
import { lstat as lstat6, readFile as
|
|
7997
|
-
import { join as
|
|
8096
|
+
import { lstat as lstat6, readFile as readFile12, rm as rm5 } from "node:fs/promises";
|
|
8097
|
+
import { join as join16 } from "node:path";
|
|
7998
8098
|
var RETIRED_MANAGED_AGENT_FILES = [
|
|
7999
8099
|
{
|
|
8000
8100
|
fileName: "codex-ultrawork-reviewer.toml",
|
|
@@ -8006,11 +8106,11 @@ var RETIRED_MANAGED_AGENT_FILES = [
|
|
|
8006
8106
|
}
|
|
8007
8107
|
];
|
|
8008
8108
|
async function purgeRetiredManagedAgentFiles(input) {
|
|
8009
|
-
const agentsDir =
|
|
8109
|
+
const agentsDir = join16(input.codexHome, "agents");
|
|
8010
8110
|
if (!await exists3(agentsDir))
|
|
8011
8111
|
return;
|
|
8012
8112
|
for (const retiredAgent of RETIRED_MANAGED_AGENT_FILES) {
|
|
8013
|
-
const agentPath =
|
|
8113
|
+
const agentPath = join16(agentsDir, retiredAgent.fileName);
|
|
8014
8114
|
if (!await exists3(agentPath))
|
|
8015
8115
|
continue;
|
|
8016
8116
|
const agentStat = await lstat6(agentPath);
|
|
@@ -8027,7 +8127,7 @@ function hasRequiredMarkers(content, markers) {
|
|
|
8027
8127
|
}
|
|
8028
8128
|
async function readTextIfExists(path) {
|
|
8029
8129
|
try {
|
|
8030
|
-
return await
|
|
8130
|
+
return await readFile12(path, "utf8");
|
|
8031
8131
|
} catch (error) {
|
|
8032
8132
|
if (nodeErrorCode(error) === "ENOENT")
|
|
8033
8133
|
return null;
|
|
@@ -8053,7 +8153,7 @@ function nodeErrorCode(error) {
|
|
|
8053
8153
|
// packages/omo-codex/src/install/link-cached-plugin-agents.ts
|
|
8054
8154
|
var MANIFEST_FILE = ".installed-agents.json";
|
|
8055
8155
|
async function capturePreservedAgentReasoning(input) {
|
|
8056
|
-
const agentsDir =
|
|
8156
|
+
const agentsDir = join17(input.codexHome, "agents");
|
|
8057
8157
|
if (!await exists4(agentsDir))
|
|
8058
8158
|
return new Map;
|
|
8059
8159
|
const preserved = new Map;
|
|
@@ -8061,7 +8161,7 @@ async function capturePreservedAgentReasoning(input) {
|
|
|
8061
8161
|
for (const entry of agentEntries) {
|
|
8062
8162
|
if (!entry.name.endsWith(".toml"))
|
|
8063
8163
|
continue;
|
|
8064
|
-
const content = await readTextIfExists2(
|
|
8164
|
+
const content = await readTextIfExists2(join17(agentsDir, entry.name));
|
|
8065
8165
|
if (content === null)
|
|
8066
8166
|
continue;
|
|
8067
8167
|
const effort = extractReasoningEffort(content);
|
|
@@ -8071,7 +8171,7 @@ async function capturePreservedAgentReasoning(input) {
|
|
|
8071
8171
|
return preserved;
|
|
8072
8172
|
}
|
|
8073
8173
|
async function capturePreservedAgentServiceTier(input) {
|
|
8074
|
-
const agentsDir =
|
|
8174
|
+
const agentsDir = join17(input.codexHome, "agents");
|
|
8075
8175
|
if (!await exists4(agentsDir))
|
|
8076
8176
|
return new Map;
|
|
8077
8177
|
const preserved = new Map;
|
|
@@ -8079,7 +8179,7 @@ async function capturePreservedAgentServiceTier(input) {
|
|
|
8079
8179
|
for (const entry of agentEntries) {
|
|
8080
8180
|
if (!entry.name.endsWith(".toml"))
|
|
8081
8181
|
continue;
|
|
8082
|
-
const content = await readTextIfExists2(
|
|
8182
|
+
const content = await readTextIfExists2(join17(agentsDir, entry.name));
|
|
8083
8183
|
if (content === null)
|
|
8084
8184
|
continue;
|
|
8085
8185
|
preserved.set(agentNameFromToml(entry.name), extractServiceTier(content));
|
|
@@ -8093,13 +8193,13 @@ async function linkCachedPluginAgents(input) {
|
|
|
8093
8193
|
await writeManifest(input.pluginRoot, []);
|
|
8094
8194
|
return [];
|
|
8095
8195
|
}
|
|
8096
|
-
const agentsDir =
|
|
8196
|
+
const agentsDir = join17(input.codexHome, "agents");
|
|
8097
8197
|
await mkdir6(agentsDir, { recursive: true });
|
|
8098
8198
|
const linked = [];
|
|
8099
8199
|
for (const agentPath of bundledAgents) {
|
|
8100
8200
|
const agentFileName = basename4(agentPath);
|
|
8101
8201
|
const agentName = agentNameFromToml(agentFileName);
|
|
8102
|
-
const linkPath =
|
|
8202
|
+
const linkPath = join17(agentsDir, agentFileName);
|
|
8103
8203
|
await replaceWithCopy(linkPath, agentPath);
|
|
8104
8204
|
await restorePreservedReasoning({
|
|
8105
8205
|
agentName,
|
|
@@ -8120,7 +8220,7 @@ async function linkCachedPluginAgents(input) {
|
|
|
8120
8220
|
async function restorePreservedServiceTier(input) {
|
|
8121
8221
|
if (!input.preserved)
|
|
8122
8222
|
return;
|
|
8123
|
-
const content = await
|
|
8223
|
+
const content = await readFile13(input.linkPath, "utf8");
|
|
8124
8224
|
if (extractServiceTier(content) === input.value)
|
|
8125
8225
|
return;
|
|
8126
8226
|
const replacement = replaceServiceTier(content, input.value);
|
|
@@ -8129,7 +8229,7 @@ async function restorePreservedServiceTier(input) {
|
|
|
8129
8229
|
await writeFile6(input.linkPath, replacement.content);
|
|
8130
8230
|
}
|
|
8131
8231
|
async function discoverBundledAgents(pluginRoot) {
|
|
8132
|
-
const componentsRoot =
|
|
8232
|
+
const componentsRoot = join17(pluginRoot, "components");
|
|
8133
8233
|
if (!await exists4(componentsRoot))
|
|
8134
8234
|
return [];
|
|
8135
8235
|
const componentEntries = await readdir4(componentsRoot, { withFileTypes: true });
|
|
@@ -8137,14 +8237,14 @@ async function discoverBundledAgents(pluginRoot) {
|
|
|
8137
8237
|
for (const entry of componentEntries) {
|
|
8138
8238
|
if (!entry.isDirectory())
|
|
8139
8239
|
continue;
|
|
8140
|
-
const agentsRoot =
|
|
8240
|
+
const agentsRoot = join17(componentsRoot, entry.name, "agents");
|
|
8141
8241
|
if (!await exists4(agentsRoot))
|
|
8142
8242
|
continue;
|
|
8143
8243
|
const agentEntries = await readdir4(agentsRoot, { withFileTypes: true });
|
|
8144
8244
|
for (const file2 of agentEntries) {
|
|
8145
8245
|
if (!file2.isFile() || !file2.name.endsWith(".toml"))
|
|
8146
8246
|
continue;
|
|
8147
|
-
agents.push(
|
|
8247
|
+
agents.push(join17(agentsRoot, file2.name));
|
|
8148
8248
|
}
|
|
8149
8249
|
}
|
|
8150
8250
|
agents.sort();
|
|
@@ -8164,7 +8264,7 @@ async function prepareReplacement(linkPath) {
|
|
|
8164
8264
|
await rm6(linkPath, { force: true });
|
|
8165
8265
|
}
|
|
8166
8266
|
async function writeManifest(pluginRoot, agentPaths) {
|
|
8167
|
-
const manifestPath =
|
|
8267
|
+
const manifestPath = join17(pluginRoot, MANIFEST_FILE);
|
|
8168
8268
|
const payload = { agents: [...agentPaths].sort() };
|
|
8169
8269
|
await writeFile6(manifestPath, `${JSON.stringify(payload, null, "\t")}
|
|
8170
8270
|
`);
|
|
@@ -8172,7 +8272,7 @@ async function writeManifest(pluginRoot, agentPaths) {
|
|
|
8172
8272
|
async function restorePreservedReasoning(input) {
|
|
8173
8273
|
if (input.value === undefined)
|
|
8174
8274
|
return;
|
|
8175
|
-
const content = await
|
|
8275
|
+
const content = await readFile13(input.target, "utf8");
|
|
8176
8276
|
const bundledEffort = extractReasoningEffort(content);
|
|
8177
8277
|
if (bundledEffort === input.value)
|
|
8178
8278
|
return;
|
|
@@ -8183,7 +8283,7 @@ async function restorePreservedReasoning(input) {
|
|
|
8183
8283
|
}
|
|
8184
8284
|
async function readTextIfExists2(path) {
|
|
8185
8285
|
try {
|
|
8186
|
-
return await
|
|
8286
|
+
return await readFile13(path, "utf8");
|
|
8187
8287
|
} catch (error) {
|
|
8188
8288
|
if (nodeErrorCode2(error) === "ENOENT")
|
|
8189
8289
|
return null;
|
|
@@ -8291,12 +8391,12 @@ function nodeErrorCode2(error) {
|
|
|
8291
8391
|
}
|
|
8292
8392
|
|
|
8293
8393
|
// packages/omo-codex/src/install/codex-marketplace.ts
|
|
8294
|
-
import { readFile as
|
|
8295
|
-
import { join as
|
|
8394
|
+
import { readFile as readFile14 } from "node:fs/promises";
|
|
8395
|
+
import { join as join18 } from "node:path";
|
|
8296
8396
|
var DEFAULT_MARKETPLACE_PATH = "packages/omo-codex/marketplace.json";
|
|
8297
8397
|
async function readMarketplace(repoRoot, options) {
|
|
8298
|
-
const marketplacePath = options?.marketplacePath ??
|
|
8299
|
-
const raw = await
|
|
8398
|
+
const marketplacePath = options?.marketplacePath ?? join18(repoRoot, DEFAULT_MARKETPLACE_PATH);
|
|
8399
|
+
const raw = await readFile14(marketplacePath, "utf8");
|
|
8300
8400
|
const parsed = JSON.parse(raw);
|
|
8301
8401
|
if (!isPlainRecord(parsed))
|
|
8302
8402
|
throw new Error("marketplace.json must be an object");
|
|
@@ -8314,10 +8414,10 @@ async function readMarketplace(repoRoot, options) {
|
|
|
8314
8414
|
function resolvePluginSource(repoRoot, plugin, options) {
|
|
8315
8415
|
const sourcePath = localSourcePath(options?.pathOverride ?? plugin.source);
|
|
8316
8416
|
const relativePath = sourcePath.slice(2);
|
|
8317
|
-
return
|
|
8417
|
+
return join18(repoRoot, ...relativePath.split(/[\\/]/));
|
|
8318
8418
|
}
|
|
8319
8419
|
async function readPluginManifest(pluginRoot) {
|
|
8320
|
-
const raw = await
|
|
8420
|
+
const raw = await readFile14(join18(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
|
|
8321
8421
|
const parsed = JSON.parse(raw);
|
|
8322
8422
|
if (!isPlainRecord(parsed))
|
|
8323
8423
|
throw new Error(`${pluginRoot} plugin.json must be an object`);
|
|
@@ -8327,15 +8427,27 @@ async function readPluginManifest(pluginRoot) {
|
|
|
8327
8427
|
if (parsed.version !== undefined && (typeof parsed.version !== "string" || parsed.version.trim() === "")) {
|
|
8328
8428
|
throw new Error(`${pluginRoot} plugin.json version must be a non-empty string`);
|
|
8329
8429
|
}
|
|
8330
|
-
if (parsed.hooks !== undefined && (
|
|
8331
|
-
throw new Error(`${pluginRoot} plugin.json hooks must be a non-empty string`);
|
|
8430
|
+
if (parsed.hooks !== undefined && !isPluginHooksManifestValue(parsed.hooks)) {
|
|
8431
|
+
throw new Error(`${pluginRoot} plugin.json hooks must be a non-empty string or string array`);
|
|
8332
8432
|
}
|
|
8333
8433
|
return {
|
|
8334
8434
|
name: parsed.name,
|
|
8335
8435
|
version: typeof parsed.version === "string" ? parsed.version.trim() : undefined,
|
|
8336
|
-
hooks:
|
|
8436
|
+
hooks: normalizePluginHooksManifestValue(parsed.hooks)
|
|
8337
8437
|
};
|
|
8338
8438
|
}
|
|
8439
|
+
function isPluginHooksManifestValue(value) {
|
|
8440
|
+
if (typeof value === "string")
|
|
8441
|
+
return value.trim() !== "";
|
|
8442
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string" && item.trim() !== "");
|
|
8443
|
+
}
|
|
8444
|
+
function normalizePluginHooksManifestValue(value) {
|
|
8445
|
+
if (typeof value === "string")
|
|
8446
|
+
return value.trim();
|
|
8447
|
+
if (Array.isArray(value))
|
|
8448
|
+
return value.map((item) => item.trim());
|
|
8449
|
+
return;
|
|
8450
|
+
}
|
|
8339
8451
|
function validatePathSegment(value, label) {
|
|
8340
8452
|
if (!/^[A-Za-z0-9._+-]+$/.test(value)) {
|
|
8341
8453
|
throw new Error(`${label} contains unsupported characters: ${value}`);
|
|
@@ -8387,7 +8499,7 @@ function validateLocalSourcePath(path) {
|
|
|
8387
8499
|
|
|
8388
8500
|
// packages/omo-codex/src/install/codex-marketplace-snapshot.ts
|
|
8389
8501
|
import { cp as cp3, mkdir as mkdir7, rename as rename3, rm as rm7, writeFile as writeFile7 } from "node:fs/promises";
|
|
8390
|
-
import { join as
|
|
8502
|
+
import { join as join19, sep as sep6 } from "node:path";
|
|
8391
8503
|
var INSTALLED_MARKETPLACES_DIR = ".tmp/marketplaces";
|
|
8392
8504
|
async function writeInstalledMarketplaceSnapshot(input) {
|
|
8393
8505
|
const marketplaceRoot = installedMarketplaceRoot(input.codexHome, input.marketplace.name);
|
|
@@ -8400,21 +8512,21 @@ async function writeInstalledMarketplaceSnapshot(input) {
|
|
|
8400
8512
|
return snapshotPlugins;
|
|
8401
8513
|
}
|
|
8402
8514
|
function installedMarketplaceRoot(codexHome, marketplaceName) {
|
|
8403
|
-
return
|
|
8515
|
+
return join19(codexHome, INSTALLED_MARKETPLACES_DIR, marketplaceName);
|
|
8404
8516
|
}
|
|
8405
8517
|
async function writeMarketplaceManifest(marketplaceRoot, marketplace) {
|
|
8406
|
-
const manifestDir =
|
|
8518
|
+
const manifestDir = join19(marketplaceRoot, ".agents", "plugins");
|
|
8407
8519
|
await mkdir7(manifestDir, { recursive: true });
|
|
8408
|
-
const tempPath =
|
|
8520
|
+
const tempPath = join19(manifestDir, `.marketplace-${process.pid}-${Date.now()}.json.tmp`);
|
|
8409
8521
|
await writeFile7(tempPath, `${JSON.stringify(marketplace, null, "\t")}
|
|
8410
8522
|
`);
|
|
8411
|
-
await rename3(tempPath,
|
|
8523
|
+
await rename3(tempPath, join19(manifestDir, "marketplace.json"));
|
|
8412
8524
|
}
|
|
8413
8525
|
async function writeSnapshotPlugin(marketplaceRoot, plugin) {
|
|
8414
|
-
const pluginsDir =
|
|
8526
|
+
const pluginsDir = join19(marketplaceRoot, "plugins");
|
|
8415
8527
|
await mkdir7(pluginsDir, { recursive: true });
|
|
8416
|
-
const targetPath =
|
|
8417
|
-
const tempPath =
|
|
8528
|
+
const targetPath = join19(pluginsDir, plugin.name);
|
|
8529
|
+
const tempPath = join19(pluginsDir, `.tmp-${plugin.name}-${process.pid}-${Date.now()}`);
|
|
8418
8530
|
await rm7(tempPath, { recursive: true, force: true });
|
|
8419
8531
|
await cp3(plugin.sourcePath, tempPath, {
|
|
8420
8532
|
recursive: true,
|
|
@@ -8427,19 +8539,19 @@ async function writeSnapshotPlugin(marketplaceRoot, plugin) {
|
|
|
8427
8539
|
return { name: plugin.name, path: targetPath };
|
|
8428
8540
|
}
|
|
8429
8541
|
function shouldCopyMarketplaceSourcePath(path, root) {
|
|
8430
|
-
const relative4 = path === root ? "" : path.slice(root.length +
|
|
8542
|
+
const relative4 = path === root ? "" : path.slice(root.length + sep6.length);
|
|
8431
8543
|
if (relative4 === "")
|
|
8432
8544
|
return true;
|
|
8433
|
-
const parts = relative4.split(
|
|
8545
|
+
const parts = relative4.split(sep6);
|
|
8434
8546
|
return !parts.some((part) => part === ".git" || part === "node_modules");
|
|
8435
8547
|
}
|
|
8436
8548
|
|
|
8437
8549
|
// packages/omo-codex/src/install/lazycodex-version-stamp.ts
|
|
8438
|
-
import { readdir as readdir5, readFile as
|
|
8439
|
-
import { join as
|
|
8550
|
+
import { readdir as readdir5, readFile as readFile15, writeFile as writeFile8 } from "node:fs/promises";
|
|
8551
|
+
import { join as join20 } from "node:path";
|
|
8440
8552
|
async function readDistributionManifest(repoRoot) {
|
|
8441
8553
|
try {
|
|
8442
|
-
const parsed = JSON.parse(await
|
|
8554
|
+
const parsed = JSON.parse(await readFile15(join20(repoRoot, "package.json"), "utf8"));
|
|
8443
8555
|
if (!isPlainRecord(parsed) || typeof parsed.version !== "string" || parsed.version.trim().length === 0)
|
|
8444
8556
|
return;
|
|
8445
8557
|
return {
|
|
@@ -8459,15 +8571,19 @@ function resolveLazyCodexPluginVersion(input) {
|
|
|
8459
8571
|
return input.manifestVersion ?? "local";
|
|
8460
8572
|
}
|
|
8461
8573
|
async function stampLazyCodexPluginVersion(input) {
|
|
8462
|
-
|
|
8463
|
-
await
|
|
8464
|
-
await
|
|
8574
|
+
const manifestPath = join20(input.pluginRoot, ".codex-plugin", "plugin.json");
|
|
8575
|
+
const hookPaths = await readPluginHookPaths(manifestPath);
|
|
8576
|
+
await stampJsonVersion(manifestPath, input.version);
|
|
8577
|
+
await stampJsonVersion(join20(input.pluginRoot, "package.json"), input.version);
|
|
8578
|
+
for (const hookPath of hookPaths) {
|
|
8579
|
+
await stampHookStatusMessages(join20(input.pluginRoot, hookPath), input.version);
|
|
8580
|
+
}
|
|
8465
8581
|
await stampComponentVersions(input);
|
|
8466
8582
|
}
|
|
8467
8583
|
async function writeLazyCodexInstallSnapshot(input) {
|
|
8468
8584
|
if (input.distributionManifest === undefined)
|
|
8469
8585
|
return;
|
|
8470
|
-
await writeFile8(
|
|
8586
|
+
await writeFile8(join20(input.pluginRoot, "lazycodex-install.json"), `${JSON.stringify({
|
|
8471
8587
|
packageName: input.distributionManifest.name,
|
|
8472
8588
|
version: input.distributionManifest.version
|
|
8473
8589
|
}, null, "\t")}
|
|
@@ -8475,7 +8591,7 @@ async function writeLazyCodexInstallSnapshot(input) {
|
|
|
8475
8591
|
}
|
|
8476
8592
|
async function stampJsonVersion(path, version) {
|
|
8477
8593
|
try {
|
|
8478
|
-
const parsed = JSON.parse(await
|
|
8594
|
+
const parsed = JSON.parse(await readFile15(path, "utf8"));
|
|
8479
8595
|
if (!isPlainRecord(parsed))
|
|
8480
8596
|
return;
|
|
8481
8597
|
parsed.version = version;
|
|
@@ -8487,9 +8603,29 @@ async function stampJsonVersion(path, version) {
|
|
|
8487
8603
|
throw error;
|
|
8488
8604
|
}
|
|
8489
8605
|
}
|
|
8606
|
+
async function readPluginHookPaths(manifestPath) {
|
|
8607
|
+
try {
|
|
8608
|
+
const parsed = JSON.parse(await readFile15(manifestPath, "utf8"));
|
|
8609
|
+
if (!isPlainRecord(parsed))
|
|
8610
|
+
return [];
|
|
8611
|
+
if (typeof parsed.hooks === "string" && parsed.hooks.trim().length > 0)
|
|
8612
|
+
return [stripDotSlash3(parsed.hooks)];
|
|
8613
|
+
if (Array.isArray(parsed.hooks)) {
|
|
8614
|
+
return parsed.hooks.filter((hookPath) => typeof hookPath === "string" && hookPath.trim().length > 0).map(stripDotSlash3);
|
|
8615
|
+
}
|
|
8616
|
+
return [];
|
|
8617
|
+
} catch (error) {
|
|
8618
|
+
if (error instanceof Error)
|
|
8619
|
+
return [];
|
|
8620
|
+
throw error;
|
|
8621
|
+
}
|
|
8622
|
+
}
|
|
8623
|
+
function stripDotSlash3(path) {
|
|
8624
|
+
return path.startsWith("./") ? path.slice(2) : path;
|
|
8625
|
+
}
|
|
8490
8626
|
async function stampHookStatusMessages(path, version) {
|
|
8491
8627
|
try {
|
|
8492
|
-
const parsed = JSON.parse(await
|
|
8628
|
+
const parsed = JSON.parse(await readFile15(path, "utf8"));
|
|
8493
8629
|
if (!isPlainRecord(parsed))
|
|
8494
8630
|
return;
|
|
8495
8631
|
stampHookGroups(parsed.hooks, version);
|
|
@@ -8504,16 +8640,16 @@ async function stampHookStatusMessages(path, version) {
|
|
|
8504
8640
|
async function stampComponentVersions(input) {
|
|
8505
8641
|
let entries;
|
|
8506
8642
|
try {
|
|
8507
|
-
entries = await readdir5(
|
|
8643
|
+
entries = await readdir5(join20(input.pluginRoot, "components"));
|
|
8508
8644
|
} catch (error) {
|
|
8509
8645
|
if (error instanceof Error)
|
|
8510
8646
|
return;
|
|
8511
8647
|
throw error;
|
|
8512
8648
|
}
|
|
8513
8649
|
for (const entry of entries) {
|
|
8514
|
-
const componentRoot =
|
|
8515
|
-
await stampJsonVersion(
|
|
8516
|
-
await stampHookStatusMessages(
|
|
8650
|
+
const componentRoot = join20(input.pluginRoot, "components", entry);
|
|
8651
|
+
await stampJsonVersion(join20(componentRoot, "package.json"), input.version);
|
|
8652
|
+
await stampHookStatusMessages(join20(componentRoot, "hooks", "hooks.json"), input.version);
|
|
8517
8653
|
}
|
|
8518
8654
|
}
|
|
8519
8655
|
function stampHookGroups(hooks, version) {
|
|
@@ -8534,12 +8670,12 @@ function stampHookGroups(hooks, version) {
|
|
|
8534
8670
|
function stampHookStatusMessage(hook, version) {
|
|
8535
8671
|
if (!isPlainRecord(hook) || typeof hook.statusMessage !== "string")
|
|
8536
8672
|
return;
|
|
8537
|
-
hook.statusMessage = hook.statusMessage.replace(/^LazyCodex\([^)]+\)
|
|
8673
|
+
hook.statusMessage = hook.statusMessage.replace(/^LazyCodex\([^)]+\):\s*/, "(OmO) ");
|
|
8538
8674
|
}
|
|
8539
8675
|
|
|
8540
8676
|
// packages/omo-codex/src/install/codex-project-local-cleanup.ts
|
|
8541
|
-
import { copyFile as copyFile2, lstat as lstat8, readFile as
|
|
8542
|
-
import { dirname as dirname6, join as
|
|
8677
|
+
import { copyFile as copyFile2, lstat as lstat8, readFile as readFile16, writeFile as writeFile9 } from "node:fs/promises";
|
|
8678
|
+
import { dirname as dirname6, join as join21, resolve as resolve6 } from "node:path";
|
|
8543
8679
|
var LEGACY_AGENT_CONFLICT_KEYS = ["max_threads"];
|
|
8544
8680
|
var PROJECT_LOCAL_ARTIFACT_PATHS = [
|
|
8545
8681
|
".codex/hooks.json",
|
|
@@ -8558,7 +8694,7 @@ async function repairNearestProjectLocalCodexArtifacts(input) {
|
|
|
8558
8694
|
const artifacts = await collectProjectLocalArtifacts(project.artifactRoots);
|
|
8559
8695
|
const configs = [];
|
|
8560
8696
|
for (const configPath of project.configPaths) {
|
|
8561
|
-
const original = await
|
|
8697
|
+
const original = await readFile16(configPath, "utf8");
|
|
8562
8698
|
const repair = repairProjectLocalCodexConfigText(original);
|
|
8563
8699
|
if (!repair.changed) {
|
|
8564
8700
|
configs.push({
|
|
@@ -8642,17 +8778,17 @@ async function findProjectLocalCodexConfigs(startDirectory, codexHome) {
|
|
|
8642
8778
|
if (startDirectoryStat !== null && !startDirectoryStat.isDirectory()) {
|
|
8643
8779
|
throw new ProjectLocalCleanupStartDirectoryError(startDirectory);
|
|
8644
8780
|
}
|
|
8645
|
-
const codexHomeConfigPath = codexHome === undefined ? null :
|
|
8781
|
+
const codexHomeConfigPath = codexHome === undefined ? null : join21(resolve6(codexHome), "config.toml");
|
|
8646
8782
|
let current = resolve6(startDirectory);
|
|
8647
8783
|
const configPathsFromCwd = [];
|
|
8648
8784
|
while (true) {
|
|
8649
|
-
const configPath =
|
|
8785
|
+
const configPath = join21(current, ".codex", "config.toml");
|
|
8650
8786
|
if (await isRegularProjectLocalConfig(current, configPath)) {
|
|
8651
8787
|
if (codexHomeConfigPath === null || resolve6(configPath) !== codexHomeConfigPath) {
|
|
8652
8788
|
configPathsFromCwd.push(configPath);
|
|
8653
8789
|
}
|
|
8654
8790
|
}
|
|
8655
|
-
if (await exists5(
|
|
8791
|
+
if (await exists5(join21(current, ".git"))) {
|
|
8656
8792
|
return configPathsFromCwd.length === 0 ? null : {
|
|
8657
8793
|
projectRoot: current,
|
|
8658
8794
|
configPaths: [...configPathsFromCwd].reverse(),
|
|
@@ -8672,7 +8808,7 @@ async function findProjectLocalCodexConfigs(startDirectory, codexHome) {
|
|
|
8672
8808
|
}
|
|
8673
8809
|
}
|
|
8674
8810
|
async function isRegularProjectLocalConfig(directory, configPath) {
|
|
8675
|
-
const codexDirStat = await maybeLstat(
|
|
8811
|
+
const codexDirStat = await maybeLstat(join21(directory, ".codex"));
|
|
8676
8812
|
if (codexDirStat === null || !codexDirStat.isDirectory() || codexDirStat.isSymbolicLink())
|
|
8677
8813
|
return false;
|
|
8678
8814
|
const configStat = await maybeLstat(configPath);
|
|
@@ -8692,7 +8828,7 @@ async function collectProjectLocalArtifacts(projectRoots) {
|
|
|
8692
8828
|
const seenPaths = new Set;
|
|
8693
8829
|
for (const projectRoot of projectRoots) {
|
|
8694
8830
|
for (const relativePath of PROJECT_LOCAL_ARTIFACT_PATHS) {
|
|
8695
|
-
const artifactPath =
|
|
8831
|
+
const artifactPath = join21(projectRoot, relativePath);
|
|
8696
8832
|
if (seenPaths.has(artifactPath))
|
|
8697
8833
|
continue;
|
|
8698
8834
|
const entryStat = await maybeLstat(artifactPath);
|
|
@@ -8767,13 +8903,13 @@ function formatUnknownError(error) {
|
|
|
8767
8903
|
}
|
|
8768
8904
|
|
|
8769
8905
|
// packages/omo-codex/src/install/lsp-daemon-reaper.ts
|
|
8770
|
-
import { readFile as
|
|
8906
|
+
import { readFile as readFile17, readdir as readdir6, rm as rm8 } from "node:fs/promises";
|
|
8771
8907
|
import { connect } from "node:net";
|
|
8772
|
-
import { join as
|
|
8908
|
+
import { join as join22 } from "node:path";
|
|
8773
8909
|
async function reapLspDaemons(codexHome, deps = {}) {
|
|
8774
8910
|
const killProcess = deps.killProcess ?? sendSigterm;
|
|
8775
8911
|
const isDaemonLive = deps.isDaemonLive ?? probeSocketLive;
|
|
8776
|
-
const daemonRoot =
|
|
8912
|
+
const daemonRoot = join22(codexHome, "codex-lsp", "daemon");
|
|
8777
8913
|
const reaped = [];
|
|
8778
8914
|
let entries;
|
|
8779
8915
|
try {
|
|
@@ -8782,9 +8918,9 @@ async function reapLspDaemons(codexHome, deps = {}) {
|
|
|
8782
8918
|
return reaped;
|
|
8783
8919
|
}
|
|
8784
8920
|
for (const entry of entries) {
|
|
8785
|
-
const versionDir =
|
|
8786
|
-
const pid = await readPidFile(
|
|
8787
|
-
const socketPath = await readEndpointFile(
|
|
8921
|
+
const versionDir = join22(daemonRoot, entry);
|
|
8922
|
+
const pid = await readPidFile(join22(versionDir, "daemon.pid"));
|
|
8923
|
+
const socketPath = await readEndpointFile(join22(versionDir, "daemon.endpoint"));
|
|
8788
8924
|
if (pid !== null && socketPath !== null && await isDaemonLive(socketPath) && killProcess(pid)) {
|
|
8789
8925
|
reaped.push(pid);
|
|
8790
8926
|
}
|
|
@@ -8794,7 +8930,7 @@ async function reapLspDaemons(codexHome, deps = {}) {
|
|
|
8794
8930
|
}
|
|
8795
8931
|
async function readEndpointFile(path) {
|
|
8796
8932
|
try {
|
|
8797
|
-
const content = (await
|
|
8933
|
+
const content = (await readFile17(path, "utf8")).trim();
|
|
8798
8934
|
return content.length > 0 ? content : null;
|
|
8799
8935
|
} catch {
|
|
8800
8936
|
return null;
|
|
@@ -8802,7 +8938,7 @@ async function readEndpointFile(path) {
|
|
|
8802
8938
|
}
|
|
8803
8939
|
async function readPidFile(path) {
|
|
8804
8940
|
try {
|
|
8805
|
-
const pid = Number.parseInt((await
|
|
8941
|
+
const pid = Number.parseInt((await readFile17(path, "utf8")).trim(), 10);
|
|
8806
8942
|
return Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
8807
8943
|
} catch {
|
|
8808
8944
|
return null;
|
|
@@ -8838,7 +8974,7 @@ function sendSigterm(pid) {
|
|
|
8838
8974
|
|
|
8839
8975
|
// packages/omo-codex/src/install/codex-installer-bin-dir.ts
|
|
8840
8976
|
import { homedir } from "node:os";
|
|
8841
|
-
import { join as
|
|
8977
|
+
import { join as join23, resolve as resolve7 } from "node:path";
|
|
8842
8978
|
function resolveCodexInstallerBinDir(input) {
|
|
8843
8979
|
const explicitBinDir = input.binDir ?? input.env?.CODEX_LOCAL_BIN_DIR;
|
|
8844
8980
|
if (explicitBinDir !== undefined && explicitBinDir.trim().length > 0)
|
|
@@ -8847,15 +8983,15 @@ function resolveCodexInstallerBinDir(input) {
|
|
|
8847
8983
|
const defaultCodexHome = resolve7(homeDir, ".codex");
|
|
8848
8984
|
const resolvedCodexHome = resolve7(input.codexHome);
|
|
8849
8985
|
if (resolvedCodexHome !== defaultCodexHome)
|
|
8850
|
-
return
|
|
8986
|
+
return join23(resolvedCodexHome, "bin");
|
|
8851
8987
|
return resolve7(homeDir, ".local", "bin");
|
|
8852
8988
|
}
|
|
8853
8989
|
|
|
8854
8990
|
// packages/omo-codex/src/install/omo-sot-migration.ts
|
|
8855
|
-
import { join as
|
|
8991
|
+
import { join as join24 } from "node:path";
|
|
8856
8992
|
async function seedAndMigrateOmoSot(input) {
|
|
8857
8993
|
const commandEnv = { ...input.env };
|
|
8858
|
-
const scriptPath =
|
|
8994
|
+
const scriptPath = join24(input.repoRoot, "packages", "omo-codex", "plugin", "scripts", "migrate-omo-sot.mjs");
|
|
8859
8995
|
try {
|
|
8860
8996
|
await input.runCommand(process.execPath, [scriptPath, "--seed"], {
|
|
8861
8997
|
cwd: input.repoRoot,
|
|
@@ -8869,7 +9005,7 @@ async function seedAndMigrateOmoSot(input) {
|
|
|
8869
9005
|
}
|
|
8870
9006
|
|
|
8871
9007
|
// packages/omo-codex/src/install/install-ast-grep-sg.ts
|
|
8872
|
-
import { join as
|
|
9008
|
+
import { join as join26 } from "node:path";
|
|
8873
9009
|
|
|
8874
9010
|
// packages/utils/src/deep-merge.ts
|
|
8875
9011
|
var DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
@@ -11841,11 +11977,11 @@ function runtimeSlug(platform = process.platform, arch = process.arch) {
|
|
|
11841
11977
|
// packages/utils/src/ast-grep/install-script.ts
|
|
11842
11978
|
import { spawn as spawn3 } from "node:child_process";
|
|
11843
11979
|
import { existsSync as existsSync3 } from "node:fs";
|
|
11844
|
-
import { join as
|
|
11980
|
+
import { join as join25 } from "node:path";
|
|
11845
11981
|
var AST_GREP_BIN_DIR_ENV_KEY = "OMO_AST_GREP_BIN_DIR";
|
|
11846
11982
|
var AST_GREP_INSTALL_TIMEOUT_MS = 30000;
|
|
11847
11983
|
function astGrepRuntimeDir(baseDir, platform = process.platform, arch = process.arch) {
|
|
11848
|
-
return
|
|
11984
|
+
return join25(baseDir, "runtime", "ast-grep", runtimeSlug(platform, arch));
|
|
11849
11985
|
}
|
|
11850
11986
|
function isMissingExecutable(error) {
|
|
11851
11987
|
if (!("code" in error))
|
|
@@ -11883,7 +12019,7 @@ function defaultSpawnProcess(command, args, options) {
|
|
|
11883
12019
|
};
|
|
11884
12020
|
}
|
|
11885
12021
|
function scriptPathForPlatform(skillDir, platform) {
|
|
11886
|
-
return
|
|
12022
|
+
return join25(skillDir, platform === "win32" ? "install.ps1" : "install.sh");
|
|
11887
12023
|
}
|
|
11888
12024
|
function invocationsForPlatform(scriptPath, platform) {
|
|
11889
12025
|
if (platform !== "win32")
|
|
@@ -12651,7 +12787,7 @@ async function installAstGrepForCodex(options) {
|
|
|
12651
12787
|
return;
|
|
12652
12788
|
const platform = options.platform ?? process.platform;
|
|
12653
12789
|
const targetDir = astGrepRuntimeDir(options.codexHome, platform, options.arch ?? process.arch);
|
|
12654
|
-
const skillDir =
|
|
12790
|
+
const skillDir = join26(plugin.path, "skills", "ast-grep");
|
|
12655
12791
|
const installer = options.installer ?? runAstGrepSkillInstall;
|
|
12656
12792
|
try {
|
|
12657
12793
|
const result = await installer({ platform, skillDir, targetDir });
|
|
@@ -12684,7 +12820,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
12684
12820
|
const env3 = options.env ?? process.env;
|
|
12685
12821
|
const platform = options.platform ?? process.platform;
|
|
12686
12822
|
const repoRoot = resolve10(options.repoRoot ?? findRepoRoot({ importerDir: import.meta.dir, env: env3 }));
|
|
12687
|
-
const codexHome = resolve10(options.codexHome ?? env3.CODEX_HOME ??
|
|
12823
|
+
const codexHome = resolve10(options.codexHome ?? env3.CODEX_HOME ?? join29(homedir2(), ".codex"));
|
|
12688
12824
|
const projectDirectory = resolve10(options.projectDirectory ?? env3.OMO_CODEX_PROJECT ?? process.cwd());
|
|
12689
12825
|
const binDir = resolveCodexInstallerBinDir({ binDir: options.binDir, codexHome, env: env3 });
|
|
12690
12826
|
const runCommand = options.runCommand ?? defaultRunCommand;
|
|
@@ -12702,9 +12838,9 @@ async function runCodexInstaller(options = {}) {
|
|
|
12702
12838
|
if (!gitBashResolution.found) {
|
|
12703
12839
|
throw new Error(gitBashResolution.installHint);
|
|
12704
12840
|
}
|
|
12705
|
-
const codexPackageRoot =
|
|
12841
|
+
const codexPackageRoot = join29(repoRoot, "packages", "omo-codex");
|
|
12706
12842
|
const marketplace = await readMarketplace(repoRoot, {
|
|
12707
|
-
marketplacePath:
|
|
12843
|
+
marketplacePath: join29(codexPackageRoot, "marketplace.json")
|
|
12708
12844
|
});
|
|
12709
12845
|
const distributionManifest = await readDistributionManifest(repoRoot);
|
|
12710
12846
|
const installed = [];
|
|
@@ -12746,7 +12882,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
12746
12882
|
if (runtimeLink !== null)
|
|
12747
12883
|
log2(`Linked ${runtimeLink.name} -> ${runtimeLink.target}`);
|
|
12748
12884
|
else
|
|
12749
|
-
log2(`Warning: skipped the omo runtime wrapper because ${
|
|
12885
|
+
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`);
|
|
12750
12886
|
}
|
|
12751
12887
|
pluginSources.push({ name: entry.name, sourcePath });
|
|
12752
12888
|
installed.push(plugin);
|
|
@@ -12799,13 +12935,13 @@ async function runCodexInstaller(options = {}) {
|
|
|
12799
12935
|
});
|
|
12800
12936
|
}
|
|
12801
12937
|
await reapLspDaemons(codexHome).catch(() => []);
|
|
12802
|
-
const marketplaceRoot =
|
|
12938
|
+
const marketplaceRoot = join29(codexHome, "plugins", "cache", marketplace.name);
|
|
12803
12939
|
await writeCachedMarketplaceManifest({
|
|
12804
12940
|
marketplaceName: marketplace.name,
|
|
12805
12941
|
marketplaceRoot,
|
|
12806
12942
|
plugins: installed
|
|
12807
12943
|
});
|
|
12808
|
-
const configPath =
|
|
12944
|
+
const configPath = join29(codexHome, "config.toml");
|
|
12809
12945
|
await updateCodexConfig({
|
|
12810
12946
|
configPath,
|
|
12811
12947
|
repoRoot: codexPackageRoot,
|
|
@@ -12864,7 +13000,7 @@ function findRepoRootFromImporter(importerDir) {
|
|
|
12864
13000
|
for (let depth = 0;depth <= 7; depth += 1) {
|
|
12865
13001
|
if (isRepoRootWithCodexPlugin(current))
|
|
12866
13002
|
return current;
|
|
12867
|
-
for (const wrapperPackageRoot of [
|
|
13003
|
+
for (const wrapperPackageRoot of [join29(current, "node_modules", "oh-my-openagent"), join29(current, "oh-my-openagent")]) {
|
|
12868
13004
|
if (isRepoRootWithCodexPlugin(wrapperPackageRoot))
|
|
12869
13005
|
return wrapperPackageRoot;
|
|
12870
13006
|
}
|
|
@@ -12882,7 +13018,7 @@ function findRepoRoot(input) {
|
|
|
12882
13018
|
return findRepoRootFromImporter(input.importerDir);
|
|
12883
13019
|
}
|
|
12884
13020
|
function isRepoRootWithCodexPlugin(repoRoot) {
|
|
12885
|
-
return existsSync6(
|
|
13021
|
+
return existsSync6(join29(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
|
|
12886
13022
|
}
|
|
12887
13023
|
function codexMarketplaceSource(marketplaceRoot) {
|
|
12888
13024
|
return { sourceType: "local", source: marketplaceRoot };
|
|
@@ -13092,11 +13228,48 @@ function buildDelegatedOmoInvocation(parsed) {
|
|
|
13092
13228
|
// packages/omo-codex/src/install/lazycodex-manual-update.ts
|
|
13093
13229
|
import { spawn as spawn4, spawnSync as spawnSync2 } from "node:child_process";
|
|
13094
13230
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
13095
|
-
import { dirname as dirname8, join as
|
|
13231
|
+
import { dirname as dirname8, join as join31 } from "node:path";
|
|
13232
|
+
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
13096
13233
|
import { fileURLToPath } from "node:url";
|
|
13234
|
+
|
|
13235
|
+
// packages/omo-codex/src/install/lazycodex-bun-global-paths.ts
|
|
13236
|
+
import { join as join30 } from "node:path";
|
|
13237
|
+
function isBunGlobalEntrypointPath(invokedPath, env3) {
|
|
13238
|
+
if (typeof invokedPath !== "string" || invokedPath.trim().length === 0)
|
|
13239
|
+
return false;
|
|
13240
|
+
const normalizedPath = normalizePathForPrefix(invokedPath);
|
|
13241
|
+
return resolveBunGlobalRoots(env3).some((root) => normalizedPath.startsWith(root));
|
|
13242
|
+
}
|
|
13243
|
+
function resolveBunGlobalRoots(env3) {
|
|
13244
|
+
const bunInstallRoot = env3.BUN_INSTALL?.trim();
|
|
13245
|
+
const homeRoot = env3.HOME?.trim();
|
|
13246
|
+
return [
|
|
13247
|
+
...bunInstallRoot ? [join30(bunInstallRoot, "bin"), join30(bunInstallRoot, "install", "global", "node_modules")] : [],
|
|
13248
|
+
...homeRoot ? [join30(homeRoot, ".bun", "bin"), join30(homeRoot, ".bun", "install", "global", "node_modules")] : []
|
|
13249
|
+
].map(normalizePathForPrefix);
|
|
13250
|
+
}
|
|
13251
|
+
function normalizePathForPrefix(path2) {
|
|
13252
|
+
const normalized = path2.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
13253
|
+
return normalized.endsWith("/node_modules") || normalized.endsWith("/bin") ? `${normalized}/` : normalized;
|
|
13254
|
+
}
|
|
13255
|
+
|
|
13256
|
+
// packages/omo-codex/src/install/lazycodex-manual-update.ts
|
|
13097
13257
|
var DEFAULT_UPDATE_COMMAND = "npx";
|
|
13098
13258
|
var DEFAULT_UPDATE_ARGS = ["--yes", "lazycodex-ai@latest", "install", "--no-tui", "--codex-autonomous"];
|
|
13259
|
+
var BUN_UPDATE_COMMAND = "bun";
|
|
13260
|
+
var BUN_GLOBAL_UPDATE_ARGS = ["update", "-g", "lazycodex-ai@latest"];
|
|
13261
|
+
var BUN_GLOBAL_UNTRUSTED_ARGS = ["pm", "-g", "untrusted"];
|
|
13262
|
+
var BUN_GLOBAL_TRUST_ARGS = ["pm", "-g", "trust"];
|
|
13099
13263
|
var INSTALLED_VERSION_FILE = "lazycodex-install.json";
|
|
13264
|
+
var KNOWN_LAZYCODEX_BUN_TRUST_PACKAGES = new Set([
|
|
13265
|
+
"@ast-grep/cli",
|
|
13266
|
+
"@code-yeongyu/comment-checker",
|
|
13267
|
+
"@sisyphuslabs/omo-codex-plugin",
|
|
13268
|
+
"lazycodex-ai",
|
|
13269
|
+
"oh-my-openagent",
|
|
13270
|
+
"oh-my-opencode"
|
|
13271
|
+
]);
|
|
13272
|
+
var KNOWN_LAZYCODEX_BUN_TRUST_PREFIXES = ["@oh-my-opencode/", "oh-my-openagent-", "oh-my-opencode-"];
|
|
13100
13273
|
async function runLazyCodexManualUpdate(input = {}) {
|
|
13101
13274
|
const env3 = input.env ?? process.env;
|
|
13102
13275
|
const log2 = input.log ?? console.log;
|
|
@@ -13107,7 +13280,9 @@ async function runLazyCodexManualUpdate(input = {}) {
|
|
|
13107
13280
|
currentVersion,
|
|
13108
13281
|
latestVersion,
|
|
13109
13282
|
command: resolveCommand2(env3),
|
|
13110
|
-
args: resolveArgs(env3)
|
|
13283
|
+
args: resolveArgs(env3),
|
|
13284
|
+
env: env3,
|
|
13285
|
+
invokedPath: input.invokedPath ?? process.argv[1]
|
|
13111
13286
|
});
|
|
13112
13287
|
if (!plan.shouldUpdate) {
|
|
13113
13288
|
const printableVersion = currentVersion ?? "unknown";
|
|
@@ -13116,9 +13291,20 @@ async function runLazyCodexManualUpdate(input = {}) {
|
|
|
13116
13291
|
}
|
|
13117
13292
|
if (input.dryRun) {
|
|
13118
13293
|
log2(`${plan.command} ${plan.args.join(" ")}`);
|
|
13294
|
+
if (plan.postUpdate === "bun-global-trust")
|
|
13295
|
+
log2(`${DEFAULT_UPDATE_COMMAND} ${DEFAULT_UPDATE_ARGS.join(" ")}`);
|
|
13119
13296
|
return 0;
|
|
13120
13297
|
}
|
|
13121
13298
|
await commandRunner(plan.command, plan.args, { cwd: process.cwd(), env: env3 });
|
|
13299
|
+
if (plan.postUpdate === "bun-global-trust") {
|
|
13300
|
+
await handleBunGlobalTrust({
|
|
13301
|
+
env: env3,
|
|
13302
|
+
log: log2,
|
|
13303
|
+
commandRunner,
|
|
13304
|
+
isInteractive: input.isInteractive ?? (process.stdin.isTTY === true && process.stdout.isTTY === true)
|
|
13305
|
+
});
|
|
13306
|
+
await commandRunner(DEFAULT_UPDATE_COMMAND, DEFAULT_UPDATE_ARGS, { cwd: process.cwd(), env: env3 });
|
|
13307
|
+
}
|
|
13122
13308
|
return 0;
|
|
13123
13309
|
}
|
|
13124
13310
|
function resolveLazyCodexUpdatePlan(input = {}) {
|
|
@@ -13130,7 +13316,10 @@ function resolveLazyCodexUpdatePlan(input = {}) {
|
|
|
13130
13316
|
return { shouldUpdate: false, reason: "unknown-latest" };
|
|
13131
13317
|
if (compareVersions(latest, current) <= 0)
|
|
13132
13318
|
return { shouldUpdate: false, reason: "up-to-date" };
|
|
13133
|
-
|
|
13319
|
+
if (isBunGlobalEntrypoint(input.invokedPath, input.env ?? process.env)) {
|
|
13320
|
+
return { shouldUpdate: true, command: BUN_UPDATE_COMMAND, args: BUN_GLOBAL_UPDATE_ARGS, postUpdate: "bun-global-trust" };
|
|
13321
|
+
}
|
|
13322
|
+
return { shouldUpdate: true, command: input.command ?? DEFAULT_UPDATE_COMMAND, args: input.args ?? DEFAULT_UPDATE_ARGS, postUpdate: "none" };
|
|
13134
13323
|
}
|
|
13135
13324
|
function resolveCommand2(env3) {
|
|
13136
13325
|
return env3.LAZYCODEX_AUTO_UPDATE_COMMAND?.trim() || DEFAULT_UPDATE_COMMAND;
|
|
@@ -13149,7 +13338,7 @@ function resolveCurrentVersion(env3) {
|
|
|
13149
13338
|
if (env3.LAZYCODEX_CURRENT_VERSION?.trim())
|
|
13150
13339
|
return env3.LAZYCODEX_CURRENT_VERSION.trim();
|
|
13151
13340
|
const pluginRoot = dirname8(dirname8(fileURLToPath(import.meta.url)));
|
|
13152
|
-
return readVersionManifest(resolveInstalledVersionPath(env3, pluginRoot)) ?? readVersionManifest(
|
|
13341
|
+
return readVersionManifest(resolveInstalledVersionPath(env3, pluginRoot)) ?? readVersionManifest(join31(pluginRoot, "..", "..", "..", "package.json")) ?? readVersionManifest(join31(pluginRoot, ".codex-plugin", "plugin.json"));
|
|
13153
13342
|
}
|
|
13154
13343
|
function resolveLatestVersion(env3) {
|
|
13155
13344
|
if (env3.LAZYCODEX_LATEST_VERSION?.trim())
|
|
@@ -13163,6 +13352,57 @@ function resolveLatestVersion(env3) {
|
|
|
13163
13352
|
const version2 = result.stdout.trim();
|
|
13164
13353
|
return version2.length > 0 ? version2 : undefined;
|
|
13165
13354
|
}
|
|
13355
|
+
async function handleBunGlobalTrust(input) {
|
|
13356
|
+
const packageNames = resolveKnownBunGlobalUntrustedPackages(input.env);
|
|
13357
|
+
if (packageNames.length === 0)
|
|
13358
|
+
return;
|
|
13359
|
+
const trustArgs = [...BUN_GLOBAL_TRUST_ARGS, ...packageNames];
|
|
13360
|
+
const trustCommand = [BUN_UPDATE_COMMAND, ...trustArgs].join(" ");
|
|
13361
|
+
if (!input.isInteractive) {
|
|
13362
|
+
input.log(`Bun blocked LazyCodex-related postinstall scripts. Run this command to trust them:
|
|
13363
|
+
${trustCommand}`);
|
|
13364
|
+
return;
|
|
13365
|
+
}
|
|
13366
|
+
if (await confirmBunGlobalTrust(packageNames)) {
|
|
13367
|
+
await input.commandRunner(BUN_UPDATE_COMMAND, trustArgs, { cwd: process.cwd(), env: input.env });
|
|
13368
|
+
return;
|
|
13369
|
+
}
|
|
13370
|
+
input.log(`Skipped Bun postinstall trust. To run it later:
|
|
13371
|
+
${trustCommand}`);
|
|
13372
|
+
}
|
|
13373
|
+
function resolveKnownBunGlobalUntrustedPackages(env3) {
|
|
13374
|
+
const result = spawnSync2(BUN_UPDATE_COMMAND, BUN_GLOBAL_UNTRUSTED_ARGS, {
|
|
13375
|
+
encoding: "utf8",
|
|
13376
|
+
env: env3,
|
|
13377
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
13378
|
+
});
|
|
13379
|
+
if (result.status !== 0)
|
|
13380
|
+
return [];
|
|
13381
|
+
const names = [];
|
|
13382
|
+
for (const match of result.stdout.matchAll(/^\.\/node_modules\/((?:@[^/\s]+\/)?[^\s]+)\s+@/gm)) {
|
|
13383
|
+
const packageName = match[1];
|
|
13384
|
+
if (packageName !== undefined && isKnownLazyCodexBunTrustPackage(packageName) && !names.includes(packageName)) {
|
|
13385
|
+
names.push(packageName);
|
|
13386
|
+
}
|
|
13387
|
+
}
|
|
13388
|
+
return names;
|
|
13389
|
+
}
|
|
13390
|
+
async function confirmBunGlobalTrust(packageNames) {
|
|
13391
|
+
const prompt = `Trust Bun postinstall scripts for ${packageNames.join(", ")}? [y/N] `;
|
|
13392
|
+
const readline = createInterface2({ input: process.stdin, output: process.stdout });
|
|
13393
|
+
try {
|
|
13394
|
+
const answer = (await readline.question(prompt)).trim().toLowerCase();
|
|
13395
|
+
return answer === "y" || answer === "yes";
|
|
13396
|
+
} finally {
|
|
13397
|
+
readline.close();
|
|
13398
|
+
}
|
|
13399
|
+
}
|
|
13400
|
+
function isKnownLazyCodexBunTrustPackage(packageName) {
|
|
13401
|
+
return KNOWN_LAZYCODEX_BUN_TRUST_PACKAGES.has(packageName) || KNOWN_LAZYCODEX_BUN_TRUST_PREFIXES.some((prefix) => packageName.startsWith(prefix));
|
|
13402
|
+
}
|
|
13403
|
+
function isBunGlobalEntrypoint(invokedPath, env3) {
|
|
13404
|
+
return isBunGlobalEntrypointPath(invokedPath, env3);
|
|
13405
|
+
}
|
|
13166
13406
|
function defaultRunCommandForManualUpdate(command, args, options) {
|
|
13167
13407
|
return new Promise((resolve11, reject) => {
|
|
13168
13408
|
const child = spawn4(command, args, {
|
|
@@ -13214,7 +13454,7 @@ function compareVersions(left, right) {
|
|
|
13214
13454
|
function resolveInstalledVersionPath(env3, pluginRoot) {
|
|
13215
13455
|
if (env3.LAZYCODEX_INSTALLED_VERSION_FILE?.trim())
|
|
13216
13456
|
return env3.LAZYCODEX_INSTALLED_VERSION_FILE.trim();
|
|
13217
|
-
return
|
|
13457
|
+
return join31(pluginRoot, INSTALLED_VERSION_FILE);
|
|
13218
13458
|
}
|
|
13219
13459
|
function readVersionManifest(path2) {
|
|
13220
13460
|
try {
|
|
@@ -13230,15 +13470,15 @@ function readVersionManifest(path2) {
|
|
|
13230
13470
|
}
|
|
13231
13471
|
}
|
|
13232
13472
|
// packages/omo-codex/src/install/codex-git-bash-mcp-env.ts
|
|
13233
|
-
import { readFile as
|
|
13234
|
-
import { join as
|
|
13473
|
+
import { readFile as readFile18, writeFile as writeFile10 } from "node:fs/promises";
|
|
13474
|
+
import { join as join32 } from "node:path";
|
|
13235
13475
|
var GIT_BASH_ENV_KEY2 = "OMO_CODEX_GIT_BASH_PATH";
|
|
13236
13476
|
var CODEGRAPH_RELATIVE_ARGS2 = new Set(["components/codegraph/dist/serve.js", "./components/codegraph/dist/serve.js"]);
|
|
13237
13477
|
async function stampGitBashMcpEnv(input) {
|
|
13238
|
-
const manifestPath =
|
|
13478
|
+
const manifestPath = join32(input.pluginRoot, ".mcp.json");
|
|
13239
13479
|
if (!await fileExistsStrict(manifestPath))
|
|
13240
13480
|
return false;
|
|
13241
|
-
const parsed = JSON.parse(await
|
|
13481
|
+
const parsed = JSON.parse(await readFile18(manifestPath, "utf8"));
|
|
13242
13482
|
if (!isPlainRecord(parsed) || !isPlainRecord(parsed["mcpServers"]))
|
|
13243
13483
|
return false;
|
|
13244
13484
|
let changed = stampCodegraphMcpPath(parsed["mcpServers"], input.pluginRoot);
|
|
@@ -13268,57 +13508,9 @@ function stampCodegraphMcpPath(mcpServers, pluginRoot) {
|
|
|
13268
13508
|
const entrypoint = args[0];
|
|
13269
13509
|
if (typeof entrypoint !== "string" || !CODEGRAPH_RELATIVE_ARGS2.has(entrypoint))
|
|
13270
13510
|
return false;
|
|
13271
|
-
codegraphServer["args"] = [
|
|
13511
|
+
codegraphServer["args"] = [join32(pluginRoot, "components", "codegraph", "dist", "serve.js"), ...args.slice(1)];
|
|
13272
13512
|
return true;
|
|
13273
13513
|
}
|
|
13274
|
-
// packages/omo-codex/src/install/codex-hook-targets.ts
|
|
13275
|
-
import { readFile as readFile18 } from "node:fs/promises";
|
|
13276
|
-
import { join as join31, sep as sep8 } from "node:path";
|
|
13277
|
-
var PLUGIN_ROOT_TARGET_PATTERN = /\$\{PLUGIN_ROOT\}\/([^"']+)/g;
|
|
13278
|
-
async function findMissingHookCommandTargets(pluginRoot) {
|
|
13279
|
-
const manifestPath = join31(pluginRoot, "hooks", "hooks.json");
|
|
13280
|
-
if (!await fileExistsStrict(manifestPath))
|
|
13281
|
-
return [];
|
|
13282
|
-
const commands = [];
|
|
13283
|
-
const parsed = JSON.parse(await readFile18(manifestPath, "utf8"));
|
|
13284
|
-
collectCommands(parsed, commands);
|
|
13285
|
-
const missing = [];
|
|
13286
|
-
const seen = new Set;
|
|
13287
|
-
for (const command of commands) {
|
|
13288
|
-
for (const match of command.matchAll(PLUGIN_ROOT_TARGET_PATTERN)) {
|
|
13289
|
-
const targetSuffix = match[1];
|
|
13290
|
-
if (targetSuffix === undefined)
|
|
13291
|
-
continue;
|
|
13292
|
-
const target = join31(pluginRoot, ...targetSuffix.split("/"));
|
|
13293
|
-
if (seen.has(target))
|
|
13294
|
-
continue;
|
|
13295
|
-
seen.add(target);
|
|
13296
|
-
if (!await fileExistsStrict(target))
|
|
13297
|
-
missing.push(target);
|
|
13298
|
-
}
|
|
13299
|
-
}
|
|
13300
|
-
return missing;
|
|
13301
|
-
}
|
|
13302
|
-
async function assertHookCommandTargets(pluginRoot) {
|
|
13303
|
-
const missing = await findMissingHookCommandTargets(pluginRoot);
|
|
13304
|
-
if (missing.length === 0)
|
|
13305
|
-
return;
|
|
13306
|
-
const relativeMissing = missing.map((path2) => path2.split(`${pluginRoot}${sep8}`).join("").split(sep8).join("/"));
|
|
13307
|
-
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.");
|
|
13308
|
-
}
|
|
13309
|
-
function collectCommands(value, commands) {
|
|
13310
|
-
if (Array.isArray(value)) {
|
|
13311
|
-
for (const entry of value)
|
|
13312
|
-
collectCommands(entry, commands);
|
|
13313
|
-
return;
|
|
13314
|
-
}
|
|
13315
|
-
if (!isPlainRecord(value))
|
|
13316
|
-
return;
|
|
13317
|
-
if (value["type"] === "command" && typeof value["command"] === "string")
|
|
13318
|
-
commands.push(value["command"]);
|
|
13319
|
-
for (const entry of Object.values(value))
|
|
13320
|
-
collectCommands(entry, commands);
|
|
13321
|
-
}
|
|
13322
13514
|
|
|
13323
13515
|
// packages/omo-codex/src/install/install-local-cli.ts
|
|
13324
13516
|
async function installMarketplaceLocally(options = {}) {
|
|
@@ -13337,7 +13529,7 @@ async function runLazyCodexInstallLocalCli(input) {
|
|
|
13337
13529
|
return 0;
|
|
13338
13530
|
}
|
|
13339
13531
|
if (parsed.kind === "version") {
|
|
13340
|
-
const packageJson = JSON.parse(await readFile19(
|
|
13532
|
+
const packageJson = JSON.parse(await readFile19(join33(input.defaultRepoRoot, "package.json"), "utf8"));
|
|
13341
13533
|
const version2 = typeof packageJson.version === "string" ? packageJson.version : "unknown";
|
|
13342
13534
|
input.log(`lazycodex-ai ${version2}`);
|
|
13343
13535
|
return 0;
|
|
@@ -13360,7 +13552,7 @@ async function runLazyCodexInstallLocalCli(input) {
|
|
|
13360
13552
|
input.log(`Installed ${result2.installed.length} plugin(s) from ${result2.marketplaceName}.`);
|
|
13361
13553
|
return 0;
|
|
13362
13554
|
}
|
|
13363
|
-
return runLazyCodexManualUpdate({ env: input.env, dryRun: parsed.dryRun, log: input.log });
|
|
13555
|
+
return runLazyCodexManualUpdate({ env: input.env, dryRun: parsed.dryRun, log: input.log, invokedPath: input.invokedPath });
|
|
13364
13556
|
}
|
|
13365
13557
|
const repoRoot = parsed.repoRoot ? resolve11(parsed.repoRoot) : input.defaultRepoRoot;
|
|
13366
13558
|
const result = await installMarketplaceLocally({
|