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
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use",
|
|
10
10
|
"timeout": 5,
|
|
11
|
-
"statusMessage": "
|
|
11
|
+
"statusMessage": "(OmO) Recommending Git Bash MCP"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"type": "command",
|
|
21
21
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
|
|
22
22
|
"timeout": 5,
|
|
23
|
-
"statusMessage": "
|
|
23
|
+
"statusMessage": "(OmO) Resetting Git Bash MCP Reminder"
|
|
24
24
|
}
|
|
25
25
|
]
|
|
26
26
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
|
|
10
10
|
"timeout": 10,
|
|
11
|
-
"statusMessage": "
|
|
11
|
+
"statusMessage": "(OmO) Verifying LazyCodex Executor Evidence"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
|
|
10
10
|
"timeout": 60,
|
|
11
|
-
"statusMessage": "
|
|
11
|
+
"statusMessage": "(OmO) Checking LSP Diagnostics"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"type": "command",
|
|
22
22
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
|
|
23
23
|
"timeout": 5,
|
|
24
|
-
"statusMessage": "
|
|
24
|
+
"statusMessage": "(OmO) Resetting LSP Diagnostics Cache"
|
|
25
25
|
}
|
|
26
26
|
]
|
|
27
27
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/codex-lsp",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.0",
|
|
4
4
|
"description": "Codex plugin that exposes Language Server Protocol tools and post-edit diagnostics.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "npm@11.12.1",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"bootstrap": "node scripts/build-lsp-tools.mjs && node scripts/build-lsp-daemon.mjs",
|
|
40
40
|
"prebuild": "node scripts/build-lsp-tools.mjs && node scripts/build-lsp-daemon.mjs",
|
|
41
41
|
"build": "node scripts/clean-dist.mjs && tsc -p tsconfig.build.json",
|
|
42
|
-
"pretest": "
|
|
42
|
+
"pretest": "npm run build --silent",
|
|
43
43
|
"test": "node scripts/test.mjs",
|
|
44
44
|
"test:watch": "vitest",
|
|
45
45
|
"pretypecheck": "node scripts/build-lsp-tools.mjs && node scripts/build-lsp-daemon.mjs",
|
|
@@ -1,53 +1,12 @@
|
|
|
1
|
-
import { readdirSync, readFileSync } from "node:fs";
|
|
2
1
|
import { describe, expect, it } from "vitest";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
type HookCommand = {
|
|
14
|
-
readonly command: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
type HookEntry = {
|
|
18
|
-
readonly hooks: readonly HookCommand[];
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
type HooksJson = {
|
|
22
|
-
readonly hooks: Record<string, readonly HookEntry[]>;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
type McpServer = {
|
|
26
|
-
readonly command: string;
|
|
27
|
-
readonly args: readonly string[];
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
type McpJson = {
|
|
31
|
-
readonly mcpServers: Record<string, McpServer>;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
function readPackageJson(path: string): PackageJson {
|
|
35
|
-
const parsed: unknown = JSON.parse(readFileSync(path, "utf8"));
|
|
36
|
-
if (!isPackageJson(parsed)) throw new TypeError(`Invalid package metadata: ${path}`);
|
|
37
|
-
return parsed;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function readHooksJson(path: string): HooksJson {
|
|
41
|
-
const parsed: unknown = JSON.parse(readFileSync(path, "utf8"));
|
|
42
|
-
if (!isHooksJson(parsed)) throw new TypeError(`Invalid hooks metadata: ${path}`);
|
|
43
|
-
return parsed;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function readMcpJson(path: string): McpJson {
|
|
47
|
-
const parsed: unknown = JSON.parse(readFileSync(path, "utf8"));
|
|
48
|
-
if (!isMcpJson(parsed)) throw new TypeError(`Invalid MCP metadata: ${path}`);
|
|
49
|
-
return parsed;
|
|
50
|
-
}
|
|
2
|
+
import {
|
|
3
|
+
listDirectoryEntries,
|
|
4
|
+
readHooksJson,
|
|
5
|
+
readMcpJson,
|
|
6
|
+
readPackageJson,
|
|
7
|
+
readTextFile,
|
|
8
|
+
requireScripts,
|
|
9
|
+
} from "../../test-support/package-smoke-fixture.js";
|
|
51
10
|
|
|
52
11
|
describe("plugin package metadata", () => {
|
|
53
12
|
it("#given packaged component files #when validating entrypoints #then hook command stays local and MCP command references the package", () => {
|
|
@@ -55,10 +14,11 @@ describe("plugin package metadata", () => {
|
|
|
55
14
|
const packageJson = readPackageJson("package.json");
|
|
56
15
|
const hooksJson = readHooksJson("hooks/hooks.json");
|
|
57
16
|
const mcpJson = readMcpJson(".mcp.json");
|
|
58
|
-
const cliSource =
|
|
59
|
-
const codexHookCliSource =
|
|
60
|
-
const codexHookSource =
|
|
61
|
-
const sourceFiles =
|
|
17
|
+
const cliSource = readTextFile("src/cli.ts");
|
|
18
|
+
const codexHookCliSource = readTextFile("src/codex-hook-cli.ts");
|
|
19
|
+
const codexHookSource = readTextFile("src/codex-hook.ts");
|
|
20
|
+
const sourceFiles = listDirectoryEntries("src");
|
|
21
|
+
const scripts = requireScripts(packageJson, "package.json");
|
|
62
22
|
|
|
63
23
|
// when
|
|
64
24
|
const postToolUseCommand = hooksJson.hooks["PostToolUse"]?.[0]?.hooks[0]?.command;
|
|
@@ -74,7 +34,8 @@ describe("plugin package metadata", () => {
|
|
|
74
34
|
});
|
|
75
35
|
expect(packageJson.bin["omo-lsp"]).toBe("./dist/cli.js");
|
|
76
36
|
expect(packageJson.bin["codex-lsp"]).toBeUndefined();
|
|
77
|
-
expect(
|
|
37
|
+
expect(scripts["build"]).toBe("node scripts/clean-dist.mjs && tsc -p tsconfig.build.json");
|
|
38
|
+
expect(scripts["pretest"]).toBe("npm run build --silent");
|
|
78
39
|
expect(cliSource.startsWith("#!/usr/bin/env node")).toBe(true);
|
|
79
40
|
expect(cliSource).toContain("Usage: omo-lsp [mcp | hook post-tool-use | hook post-compact]");
|
|
80
41
|
expect(postToolUseCommand).toBe(`node "${pluginRoot}/dist/cli.js" hook post-tool-use`);
|
|
@@ -91,55 +52,16 @@ describe("plugin package metadata", () => {
|
|
|
91
52
|
expect(sourceFiles.filter((name) => name.startsWith("lazy-mcp") || name === "lazy-lsp-mcp.ts")).toEqual([]);
|
|
92
53
|
});
|
|
93
54
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return (
|
|
98
|
-
isRecord(value) &&
|
|
99
|
-
typeof value["version"] === "string" &&
|
|
100
|
-
value["type"] === "module" &&
|
|
101
|
-
value["packageManager"] === "npm@11.12.1" &&
|
|
102
|
-
isStringRecord(value["bin"]) &&
|
|
103
|
-
isStringRecord(value["dependencies"]) &&
|
|
104
|
-
isStringRecord(value["scripts"])
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function isHooksJson(value: unknown): value is HooksJson {
|
|
109
|
-
if (!isRecord(value) || !isRecord(value["hooks"])) return false;
|
|
110
|
-
return Object.values(value["hooks"]).every(isHookEntries);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function isHookEntries(value: unknown): value is readonly HookEntry[] {
|
|
114
|
-
return Array.isArray(value) && value.every(isHookEntry);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function isHookEntry(value: unknown): value is HookEntry {
|
|
118
|
-
return isRecord(value) && Array.isArray(value["hooks"]) && value["hooks"].every(isHookCommand);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function isHookCommand(value: unknown): value is HookCommand {
|
|
122
|
-
return isRecord(value) && typeof value["command"] === "string";
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function isMcpJson(value: unknown): value is McpJson {
|
|
126
|
-
if (!isRecord(value) || !isRecord(value["mcpServers"])) return false;
|
|
127
|
-
return Object.values(value["mcpServers"]).every(isMcpServer);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function isMcpServer(value: unknown): value is McpServer {
|
|
131
|
-
return (
|
|
132
|
-
isRecord(value) &&
|
|
133
|
-
typeof value["command"] === "string" &&
|
|
134
|
-
Array.isArray(value["args"]) &&
|
|
135
|
-
value["args"].every((item) => typeof item === "string")
|
|
136
|
-
);
|
|
137
|
-
}
|
|
55
|
+
it("#given LSP skill guidance #when validating MCP tool instructions #then tool names are not framed as shell commands", () => {
|
|
56
|
+
// given
|
|
57
|
+
const skill = readTextFile("skills/lsp/SKILL.md");
|
|
138
58
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
59
|
+
// when
|
|
60
|
+
const mentionsToolInterface = skill.includes("through the tool interface");
|
|
61
|
+
const rejectsShellExecution = skill.includes("not shell commands");
|
|
142
62
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
63
|
+
// then
|
|
64
|
+
expect(mentionsToolInterface).toBe(true);
|
|
65
|
+
expect(rejectsShellExecution).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -4036,9 +4036,9 @@ function getSparkShellRuntimeAwareness(env = process.env, deps = {}) {
|
|
|
4036
4036
|
`- Use \`${command} sparkshell --shell '<command>'\` only when shell metacharacters are required.`,
|
|
4037
4037
|
`- Use \`${command} sparkshell --tmux-pane <pane-id> --tail-lines 400\` to inspect an existing tmux pane. Tail lines must stay between 100 and 1000.`,
|
|
4038
4038
|
"- When no native sidecar or appserver is available, Sparkshell silently falls back to raw command execution. `OMO_SPARKSHELL_BIN` selects a native sidecar path.",
|
|
4039
|
-
"- When `CODEX_THREAD_ID` identifies a Codex session, Sparkshell
|
|
4039
|
+
"- When `CODEX_THREAD_ID` identifies a Codex session, Sparkshell feeds recent session context (first/latest user request + last 5 conversation messages) into oversized-output condensation for relevance ranking, but never appends that context to command output. `OMO_SPARKSHELL_SESSION_CONTEXT=0` disables the lookup.",
|
|
4040
4040
|
`- Route potentially huge output (full log files, big diffs, \`cat\`/\`grep\` over large artifacts) through \`${command} sparkshell\` instead of reading it raw: oversized output is condensed to a budget while preserving error signatures, repeated patterns, session-goal-relevant lines, and head/tail. Tune with \`--budget <chars>\`; disable with \`OMO_SPARKSHELL_CONDENSE=0\`.`,
|
|
4041
|
-
"- Oversized output is first summarized by the spark model (`codex exec`, default `gpt-5.3-codex-spark`) fed with the session context: the summary
|
|
4041
|
+
"- Oversized output is first summarized by the spark model (`codex exec`, default `gpt-5.3-codex-spark`) fed with the shell output plus session context: the summary keeps selected output as-is (no masking) and ends with a `[sparkshell caption]` line describing what ran, what the full output contained, and which lines were omitted. `OMO_SPARKSHELL_SPARK=0` skips the model and uses deterministic condensation directly."
|
|
4042
4042
|
].join(`
|
|
4043
4043
|
`);
|
|
4044
4044
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook session-start",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "
|
|
10
|
+
"statusMessage": "(OmO) Loading Project Rules"
|
|
11
11
|
}
|
|
12
12
|
]
|
|
13
13
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"type": "command",
|
|
20
20
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook user-prompt-submit",
|
|
21
21
|
"timeout": 10,
|
|
22
|
-
"statusMessage": "
|
|
22
|
+
"statusMessage": "(OmO) Loading Project Rules"
|
|
23
23
|
}
|
|
24
24
|
]
|
|
25
25
|
}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"type": "command",
|
|
33
33
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
|
|
34
34
|
"timeout": 10,
|
|
35
|
-
"statusMessage": "
|
|
35
|
+
"statusMessage": "(OmO) Matching Project Rules"
|
|
36
36
|
}
|
|
37
37
|
]
|
|
38
38
|
}
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"type": "command",
|
|
46
46
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
|
|
47
47
|
"timeout": 10,
|
|
48
|
-
"statusMessage": "
|
|
48
|
+
"statusMessage": "(OmO) Resetting Project Rule Cache"
|
|
49
49
|
}
|
|
50
50
|
]
|
|
51
51
|
}
|
|
@@ -85,9 +85,9 @@ export function getSparkShellRuntimeAwareness(env: RuntimeEnv = process.env, dep
|
|
|
85
85
|
`- Use \`${command} sparkshell --shell '<command>'\` only when shell metacharacters are required.`,
|
|
86
86
|
`- Use \`${command} sparkshell --tmux-pane <pane-id> --tail-lines 400\` to inspect an existing tmux pane. Tail lines must stay between 100 and 1000.`,
|
|
87
87
|
"- When no native sidecar or appserver is available, Sparkshell silently falls back to raw command execution. `OMO_SPARKSHELL_BIN` selects a native sidecar path.",
|
|
88
|
-
"- When `CODEX_THREAD_ID` identifies a Codex session, Sparkshell
|
|
88
|
+
"- When `CODEX_THREAD_ID` identifies a Codex session, Sparkshell feeds recent session context (first/latest user request + last 5 conversation messages) into oversized-output condensation for relevance ranking, but never appends that context to command output. `OMO_SPARKSHELL_SESSION_CONTEXT=0` disables the lookup.",
|
|
89
89
|
`- Route potentially huge output (full log files, big diffs, \`cat\`/\`grep\` over large artifacts) through \`${command} sparkshell\` instead of reading it raw: oversized output is condensed to a budget while preserving error signatures, repeated patterns, session-goal-relevant lines, and head/tail. Tune with \`--budget <chars>\`; disable with \`OMO_SPARKSHELL_CONDENSE=0\`.`,
|
|
90
|
-
"- Oversized output is first summarized by the spark model (`codex exec`, default `gpt-5.3-codex-spark`) fed with the session context: the summary
|
|
90
|
+
"- Oversized output is first summarized by the spark model (`codex exec`, default `gpt-5.3-codex-spark`) fed with the shell output plus session context: the summary keeps selected output as-is (no masking) and ends with a `[sparkshell caption]` line describing what ran, what the full output contained, and which lines were omitted. `OMO_SPARKSHELL_SPARK=0` skips the model and uses deterministic condensation directly.",
|
|
91
91
|
].join("\n");
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -1,48 +1,12 @@
|
|
|
1
|
-
import { readdirSync, readFileSync } from "node:fs";
|
|
2
1
|
import { describe, expect, it } from "vitest";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
type PluginJson = {
|
|
13
|
-
readonly hooks: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
type HookCommand = {
|
|
17
|
-
readonly command: string;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
type HookEntry = {
|
|
21
|
-
readonly matcher?: string;
|
|
22
|
-
readonly hooks: readonly HookCommand[];
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
type HooksJson = {
|
|
26
|
-
readonly hooks: Record<string, readonly HookEntry[]>;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
function readPackageJson(path: string): PackageJson {
|
|
30
|
-
const parsed: unknown = JSON.parse(readFileSync(path, "utf8"));
|
|
31
|
-
if (!isPackageJson(parsed)) throw new TypeError(`Invalid package metadata: ${path}`);
|
|
32
|
-
return parsed;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function readPluginJson(path: string): PluginJson {
|
|
36
|
-
const parsed: unknown = JSON.parse(readFileSync(path, "utf8"));
|
|
37
|
-
if (!isPluginJson(parsed)) throw new TypeError(`Invalid plugin metadata: ${path}`);
|
|
38
|
-
return parsed;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function readHooksJson(path: string): HooksJson {
|
|
42
|
-
const parsed: unknown = JSON.parse(readFileSync(path, "utf8"));
|
|
43
|
-
if (!isHooksJson(parsed)) throw new TypeError(`Invalid hooks metadata: ${path}`);
|
|
44
|
-
return parsed;
|
|
45
|
-
}
|
|
2
|
+
import {
|
|
3
|
+
listDirectoryEntries,
|
|
4
|
+
readHooksJson,
|
|
5
|
+
readPackageJson,
|
|
6
|
+
readPluginJson,
|
|
7
|
+
readTextFile,
|
|
8
|
+
requireFiles,
|
|
9
|
+
} from "../../test-support/package-smoke-fixture.js";
|
|
46
10
|
|
|
47
11
|
describe("plugin package metadata", () => {
|
|
48
12
|
it("#given packaged plugin files #when validating entrypoints #then hook commands use portable plugin root interpolation", () => {
|
|
@@ -50,8 +14,9 @@ describe("plugin package metadata", () => {
|
|
|
50
14
|
const packageJson = readPackageJson("package.json");
|
|
51
15
|
const pluginJson = readPluginJson(".codex-plugin/plugin.json");
|
|
52
16
|
const hooksJson = readHooksJson("hooks/hooks.json");
|
|
53
|
-
const cliSource =
|
|
54
|
-
const
|
|
17
|
+
const cliSource = readTextFile("src/cli.ts");
|
|
18
|
+
const packageFiles = requireFiles(packageJson, "package.json");
|
|
19
|
+
const bundledRules = [...listDirectoryEntries("bundled-rules")].sort();
|
|
55
20
|
|
|
56
21
|
// when
|
|
57
22
|
const hookConfig = hooksJson.hooks;
|
|
@@ -69,7 +34,7 @@ describe("plugin package metadata", () => {
|
|
|
69
34
|
expect(packageJson.packageManager).toBe("npm@11.12.1");
|
|
70
35
|
expect(packageJson.dependencies ?? {}).toEqual({ picomatch: "^4.0.3" });
|
|
71
36
|
expect(packageJson.bin["omo-rules"]).toBe("./dist/cli.js");
|
|
72
|
-
expect(
|
|
37
|
+
expect(packageFiles).toContain("bundled-rules");
|
|
73
38
|
expect(bundledRules).toContain("windows-git-bash.md");
|
|
74
39
|
expect(pluginJson.hooks).toBe("./hooks/hooks.json");
|
|
75
40
|
expect(cliSource.startsWith("#!/usr/bin/env node")).toBe(true);
|
|
@@ -106,48 +71,3 @@ describe("plugin package metadata", () => {
|
|
|
106
71
|
).toBe(false);
|
|
107
72
|
});
|
|
108
73
|
});
|
|
109
|
-
|
|
110
|
-
function isPackageJson(value: unknown): value is PackageJson {
|
|
111
|
-
if (!isRecord(value)) return false;
|
|
112
|
-
const dependencies = value["dependencies"];
|
|
113
|
-
return (
|
|
114
|
-
value["type"] === "module" &&
|
|
115
|
-
value["packageManager"] === "npm@11.12.1" &&
|
|
116
|
-
isStringRecord(value["bin"]) &&
|
|
117
|
-
isStringArray(value["files"]) &&
|
|
118
|
-
(dependencies === undefined || isRecord(dependencies))
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function isStringArray(value: unknown): value is readonly string[] {
|
|
123
|
-
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function isPluginJson(value: unknown): value is PluginJson {
|
|
127
|
-
return isRecord(value) && typeof value["hooks"] === "string";
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function isHooksJson(value: unknown): value is HooksJson {
|
|
131
|
-
if (!isRecord(value) || !isRecord(value["hooks"])) return false;
|
|
132
|
-
return Object.values(value["hooks"]).every(isHookEntries);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function isHookEntries(value: unknown): value is readonly HookEntry[] {
|
|
136
|
-
return Array.isArray(value) && value.every(isHookEntry);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function isHookEntry(value: unknown): value is HookEntry {
|
|
140
|
-
return isRecord(value) && Array.isArray(value["hooks"]) && value["hooks"].every(isHookCommand);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function isHookCommand(value: unknown): value is HookCommand {
|
|
144
|
-
return isRecord(value) && typeof value["command"] === "string";
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function isStringRecord(value: unknown): value is Record<string, string> {
|
|
148
|
-
return isRecord(value) && Object.values(value).every((item) => typeof item === "string");
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
152
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
153
|
-
}
|
|
@@ -90,7 +90,10 @@ describe("Codex Sparkshell awareness", () => {
|
|
|
90
90
|
expect(parseAdditionalContext(output)).toContain("OMO_SPARKSHELL_CONDENSE");
|
|
91
91
|
expect(parseAdditionalContext(output)).toContain("OMO_SPARKSHELL_SPARK");
|
|
92
92
|
expect(parseAdditionalContext(output)).toContain("[sparkshell caption]");
|
|
93
|
+
expect(parseAdditionalContext(output)).toContain("never appends that context to command output");
|
|
94
|
+
expect(parseAdditionalContext(output)).toContain("what the full output contained");
|
|
93
95
|
expect(parseAdditionalContext(output)).not.toContain("[REDACTED]");
|
|
96
|
+
expect(parseAdditionalContext(output)).not.toContain("appends recent session context");
|
|
94
97
|
});
|
|
95
98
|
|
|
96
99
|
it("#given inactive env #when SessionStart runs #then emits no Sparkshell guidance", async () => {
|