lazycodex-ai 5.0.0-beta.48 → 5.0.0-beta.49
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/README.ja.md +35 -27
- package/README.ko.md +35 -27
- package/README.md +19 -34
- package/README.ru.md +33 -28
- package/README.zh-cn.md +31 -27
- package/dist/cli/index.js +19 -15
- package/dist/cli-node/index.js +19 -15
- package/package.json +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +2 -2
- 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/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/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/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- 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/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- 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/ultrawork/dist/cli.js +11 -10
- 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/src/directive-content.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/AGENTS.md +3 -3
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/README.md +3 -3
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/directive.md +4 -4
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/dist/cli.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -13
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/src/codex-hook.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/src/types.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/test/cli.test.ts +3 -7
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/test/codex-hook.test.ts +16 -0
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +11 -10
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +8 -15
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +88 -67
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +3 -4
- package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +13 -16
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +47 -26
- package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +14 -4
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +17 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +8 -14
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +5 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +3 -4
- package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +4 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +21 -16
- package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +52 -25
- package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +16 -4
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +11 -12
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-fields-messages.test.ts +98 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-lazycodex-surface.test.ts +93 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +9 -4
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +10 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +70 -7
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +18 -0
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +12 -12
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +61 -33
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +4 -2
- package/packages/omo-codex/plugin/skills/refactor/SKILL.md +4 -2
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +4 -2
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +13 -3
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +11 -10
- package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +11 -6
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +24 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -2
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +4 -2
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +8 -4
- package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +62 -0
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +23 -1
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +36 -16
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
- package/packages/prompts-core/prompts/ultrawork/codex.md +11 -10
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +0 -17
|
@@ -36,17 +36,29 @@ export type UlwLoopGateSection = "codeReview" | "manualQa" | "gateReview" | "ite
|
|
|
36
36
|
|
|
37
37
|
export const REQUIRED_GATE_SECTIONS_BY_SURFACE: Readonly<Record<UlwLoopToolkitSurface, readonly UlwLoopGateSection[]>> =
|
|
38
38
|
{
|
|
39
|
-
lazycodex: ["
|
|
39
|
+
lazycodex: ["manualQa", "gateReview", "iteration", "criteriaCoverage"],
|
|
40
40
|
"omo-senpi": ["manualQa", "gateReview", "iteration", "criteriaCoverage"],
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
export const OPTIONAL_GATE_SECTIONS_BY_SURFACE: Readonly<Record<UlwLoopToolkitSurface, readonly UlwLoopGateSection[]>> =
|
|
44
|
+
{
|
|
45
|
+
lazycodex: ["codeReview"],
|
|
46
|
+
"omo-senpi": [],
|
|
47
|
+
};
|
|
48
|
+
|
|
43
49
|
export const GATE_SECTION_BY_ACCEPTOR: Readonly<
|
|
44
50
|
Record<UlwLoopToolkitSurface, Readonly<Partial<Record<UlwLoopGateSection, readonly string[]>>>>
|
|
45
51
|
> = {
|
|
46
52
|
lazycodex: {
|
|
47
|
-
codeReview: [REVIEWER_ROLES_BY_SURFACE.lazycodex.codeReview],
|
|
48
|
-
manualQa: [REVIEWER_ROLES_BY_SURFACE.lazycodex.manualQa],
|
|
49
|
-
gateReview: [
|
|
53
|
+
codeReview: [REVIEWER_ROLES_BY_SURFACE.lazycodex.codeReview, "main-session"],
|
|
54
|
+
manualQa: [REVIEWER_ROLES_BY_SURFACE.lazycodex.manualQa, "main-session"],
|
|
55
|
+
gateReview: [
|
|
56
|
+
REVIEWER_ROLES_BY_SURFACE.lazycodex.gateReview,
|
|
57
|
+
"category:deep",
|
|
58
|
+
"category:unspecified-high",
|
|
59
|
+
"category:unspecified-low",
|
|
60
|
+
"main-session",
|
|
61
|
+
],
|
|
50
62
|
},
|
|
51
63
|
"omo-senpi": {
|
|
52
64
|
manualQa: ["main-session"],
|
|
@@ -47,7 +47,7 @@ describe("checkpointUlwLoop final story surface resolution", () => {
|
|
|
47
47
|
expect(result.plan.aggregateCompletion?.status).toBe("complete");
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
it("#given the same codeReview-free gate #when the surface is lazycodex #then the final story
|
|
50
|
+
it("#given the same codeReview-free gate #when the surface is lazycodex #then the final story completes", async () => {
|
|
51
51
|
const repo = await repoWith(
|
|
52
52
|
plan([passGoal("G001", { status: "complete" }), passGoal("G002")], { activeGoalId: "G002" }),
|
|
53
53
|
);
|
|
@@ -59,17 +59,16 @@ describe("checkpointUlwLoop final story surface resolution", () => {
|
|
|
59
59
|
requiredSection(gate, "manualQa")["by"] = "main-session";
|
|
60
60
|
requiredSection(gate, "gateReview")["by"] = "category:deep";
|
|
61
61
|
|
|
62
|
-
await
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
);
|
|
62
|
+
const result = await checkpointUlwLoop(repo, {
|
|
63
|
+
goalId: "G002",
|
|
64
|
+
status: "complete",
|
|
65
|
+
evidence: "final work complete and validation passed",
|
|
66
|
+
codexGoalJson: snapshot("complete"),
|
|
67
|
+
qualityGateJson: JSON.stringify(gate),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
expect(result.aggregateCompletion?.status).toBe("complete");
|
|
71
|
+
expect(result.plan.aggregateCompletion?.status).toBe("complete");
|
|
73
72
|
});
|
|
74
73
|
|
|
75
74
|
it("#given the omo-senpi surface #when the gate includes codeReview #then the final story is rejected", async () => {
|
package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-fields-messages.test.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { ULW_LOOP_HELP } from "../src/cli-output.js";
|
|
4
|
+
import { validateQualityGate } from "../src/quality-gate.js";
|
|
5
|
+
import { statusNextActions } from "../src/status-next-actions.js";
|
|
6
|
+
import type { UlwLoopPlan } from "../src/types.js";
|
|
7
|
+
|
|
8
|
+
const NOW = "2026-05-23T00:00:00.000Z";
|
|
9
|
+
|
|
10
|
+
const GATE_WITHOUT_MANUAL_QA = {
|
|
11
|
+
codeReview: {
|
|
12
|
+
by: "lazycodex-code-reviewer",
|
|
13
|
+
recommendation: "APPROVE",
|
|
14
|
+
codeQualityStatus: "CLEAR",
|
|
15
|
+
reportPath: "code-review.md",
|
|
16
|
+
evidence: "Reviewed the diff; no blocking issues remain.",
|
|
17
|
+
blockers: [],
|
|
18
|
+
},
|
|
19
|
+
gateReview: {
|
|
20
|
+
by: "lazycodex-gate-reviewer",
|
|
21
|
+
recommendation: "APPROVE",
|
|
22
|
+
reportPath: "gate-review.md",
|
|
23
|
+
evidence: "Gate is approved.",
|
|
24
|
+
blockers: [],
|
|
25
|
+
},
|
|
26
|
+
iteration: {
|
|
27
|
+
fullRerun: true,
|
|
28
|
+
status: "passed",
|
|
29
|
+
rerunCommands: ["true"],
|
|
30
|
+
evidence: "Rerun passed.",
|
|
31
|
+
},
|
|
32
|
+
criteriaCoverage: {
|
|
33
|
+
totalCriteria: 1,
|
|
34
|
+
passCount: 1,
|
|
35
|
+
originalIntent: "Ship a complete gate.",
|
|
36
|
+
desiredOutcome: "The gate names accepted input forms.",
|
|
37
|
+
userOutcomeReview: "Outcome matches the request.",
|
|
38
|
+
adversarialClassesCovered: ["malformed_input"],
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function thrownMessage(run: () => unknown): string {
|
|
43
|
+
try {
|
|
44
|
+
run();
|
|
45
|
+
} catch (error) {
|
|
46
|
+
return error instanceof Error ? error.message : String(error);
|
|
47
|
+
}
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
describe("quality-gate field and status messages", () => {
|
|
52
|
+
it("missing-manualQa error contains accepted input and names bare-object and top-level qualityGate forms", () => {
|
|
53
|
+
const message = thrownMessage(() => validateQualityGate(GATE_WITHOUT_MANUAL_QA));
|
|
54
|
+
|
|
55
|
+
expect(message).toContain("accepted input");
|
|
56
|
+
expect(message).toContain("bare object");
|
|
57
|
+
expect(message).toContain('top-level "qualityGate" key');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("status next-action text mentions currentAttemptDir", () => {
|
|
61
|
+
const plan: UlwLoopPlan = {
|
|
62
|
+
version: 1,
|
|
63
|
+
createdAt: NOW,
|
|
64
|
+
updatedAt: NOW,
|
|
65
|
+
briefPath: ".omo/ulw-loop/brief.md",
|
|
66
|
+
goalsPath: ".omo/ulw-loop/goals.json",
|
|
67
|
+
ledgerPath: ".omo/ulw-loop/ledger.jsonl",
|
|
68
|
+
activeGoalId: "G001",
|
|
69
|
+
goals: [
|
|
70
|
+
{
|
|
71
|
+
id: "G001",
|
|
72
|
+
title: "Goal one",
|
|
73
|
+
objective: "Complete goal one",
|
|
74
|
+
status: "in_progress",
|
|
75
|
+
successCriteria: [
|
|
76
|
+
{
|
|
77
|
+
id: "C001",
|
|
78
|
+
scenario: "works",
|
|
79
|
+
userModel: "happy",
|
|
80
|
+
expectedEvidence: "proof",
|
|
81
|
+
capturedEvidence: "passed",
|
|
82
|
+
status: "pass",
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
attempt: 1,
|
|
86
|
+
createdAt: NOW,
|
|
87
|
+
updatedAt: NOW,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
expect(statusNextActions(plan).join("\n")).toContain("currentAttemptDir");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("CLI help mentions currentAttemptDir", () => {
|
|
96
|
+
expect(ULW_LOOP_HELP).toContain("currentAttemptDir");
|
|
97
|
+
});
|
|
98
|
+
});
|
package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-lazycodex-surface.test.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { expect, it } from "vitest";
|
|
2
|
+
import { validateQualityGate } from "../src/quality-gate.js";
|
|
3
|
+
|
|
4
|
+
const base = {
|
|
5
|
+
manualQa: {
|
|
6
|
+
by: "main-session",
|
|
7
|
+
status: "passed",
|
|
8
|
+
evidence: "qa",
|
|
9
|
+
surfaceEvidence: [
|
|
10
|
+
{ id: "s", criterionRef: "C1", surface: "cli", invocation: "true", verdict: "passed", artifactRefs: ["a"] },
|
|
11
|
+
],
|
|
12
|
+
adversarialCases: [
|
|
13
|
+
{
|
|
14
|
+
id: "x",
|
|
15
|
+
criterionRef: "C1",
|
|
16
|
+
scenario: "x",
|
|
17
|
+
expectedBehavior: "x",
|
|
18
|
+
verdict: "not_applicable",
|
|
19
|
+
reason: "x",
|
|
20
|
+
artifactRefs: ["a"],
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
artifactRefs: [{ id: "a", kind: "cli-transcript", description: "a", path: "qa.txt" }],
|
|
24
|
+
},
|
|
25
|
+
gateReview: {
|
|
26
|
+
by: "category:unspecified-high",
|
|
27
|
+
recommendation: "APPROVE",
|
|
28
|
+
reportPath: "gate.md",
|
|
29
|
+
evidence: "gate",
|
|
30
|
+
blockers: [],
|
|
31
|
+
},
|
|
32
|
+
iteration: { fullRerun: true, status: "passed", rerunCommands: ["true"], evidence: "rerun" },
|
|
33
|
+
criteriaCoverage: {
|
|
34
|
+
totalCriteria: 1,
|
|
35
|
+
passCount: 1,
|
|
36
|
+
originalIntent: "i",
|
|
37
|
+
desiredOutcome: "d",
|
|
38
|
+
userOutcomeReview: "u",
|
|
39
|
+
adversarialClassesCovered: ["x"],
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
it("accepts lazycodex self-review gate without codeReview", () =>
|
|
43
|
+
expect(() => validateQualityGate(base)).not.toThrow());
|
|
44
|
+
it("accepts wrapped and optional codeReview forms", () => {
|
|
45
|
+
expect(() => validateQualityGate({ qualityGate: base })).not.toThrow();
|
|
46
|
+
expect(() =>
|
|
47
|
+
validateQualityGate({
|
|
48
|
+
...base,
|
|
49
|
+
codeReview: {
|
|
50
|
+
by: "lazycodex-code-reviewer",
|
|
51
|
+
recommendation: "APPROVE",
|
|
52
|
+
codeQualityStatus: "CLEAR",
|
|
53
|
+
reportPath: "code.md",
|
|
54
|
+
evidence: "review",
|
|
55
|
+
blockers: [],
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
).not.toThrow();
|
|
59
|
+
});
|
|
60
|
+
it("#given main-session codeReview #when validated #then preserves the accepted author", () => {
|
|
61
|
+
const gate = validateQualityGate({
|
|
62
|
+
...base,
|
|
63
|
+
codeReview: {
|
|
64
|
+
by: "main-session",
|
|
65
|
+
recommendation: "APPROVE",
|
|
66
|
+
codeQualityStatus: "CLEAR",
|
|
67
|
+
reportPath: "code.md",
|
|
68
|
+
evidence: "review",
|
|
69
|
+
blockers: [],
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
expect(gate.surface).toBe("lazycodex");
|
|
73
|
+
if (gate.surface === "lazycodex") expect(gate.codeReview?.by).toBe("main-session");
|
|
74
|
+
});
|
|
75
|
+
it("#given random codeReview author #when validated #then rejects the lane", () => {
|
|
76
|
+
expect(() =>
|
|
77
|
+
validateQualityGate({
|
|
78
|
+
...base,
|
|
79
|
+
codeReview: {
|
|
80
|
+
by: "random",
|
|
81
|
+
recommendation: "APPROVE",
|
|
82
|
+
codeQualityStatus: "CLEAR",
|
|
83
|
+
reportPath: "code.md",
|
|
84
|
+
evidence: "review",
|
|
85
|
+
blockers: [],
|
|
86
|
+
},
|
|
87
|
+
}),
|
|
88
|
+
).toThrow(/codeReview\.by/);
|
|
89
|
+
});
|
|
90
|
+
it("rejects an unknown gate acceptor", () =>
|
|
91
|
+
expect(() => validateQualityGate({ ...base, gateReview: { ...base.gateReview, by: "random-agent" } })).toThrow(
|
|
92
|
+
/gateReview\.by/,
|
|
93
|
+
));
|
|
@@ -132,10 +132,15 @@ describe("validateQualityGate reviewer roles", () => {
|
|
|
132
132
|
expect(error.message).toContain("no codeReview lane");
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
-
it("#given a four-section
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
135
|
+
it("#given a four-section gate #when validated on the default lazycodex surface #then codeReview is optional", () => {
|
|
136
|
+
expect(() =>
|
|
137
|
+
validateQualityGate(
|
|
138
|
+
senpiGate({
|
|
139
|
+
manualQa: { ...BASE_GATE.manualQa, by: "main-session" },
|
|
140
|
+
gateReview: { ...BASE_GATE.gateReview, by: "category:deep" },
|
|
141
|
+
}),
|
|
142
|
+
),
|
|
143
|
+
).not.toThrow();
|
|
139
144
|
});
|
|
140
145
|
|
|
141
146
|
it("#given swapped omo-senpi reviewer roles #when validated on the omo-senpi surface #then section-specific roles are enforced", () => {
|
|
@@ -136,6 +136,16 @@ describe("validateQualityGate", () => {
|
|
|
136
136
|
expect(gate.manualQa.artifactRefs).toHaveLength(5);
|
|
137
137
|
});
|
|
138
138
|
|
|
139
|
+
it("#given missing manualQa section #when validated #then it explains accepted input forms", () => {
|
|
140
|
+
const input = makeGate();
|
|
141
|
+
delete input["manualQa"];
|
|
142
|
+
|
|
143
|
+
const error = getQualityGateError(input);
|
|
144
|
+
|
|
145
|
+
expect(error.message).toContain("accepted input");
|
|
146
|
+
expect(error.message).toContain('top-level "qualityGate" key');
|
|
147
|
+
});
|
|
148
|
+
|
|
139
149
|
it("#given missing manualQa surface evidence #when validated #then it fails closed", () => {
|
|
140
150
|
// given
|
|
141
151
|
const input = makeGate({
|
|
@@ -2,18 +2,22 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { mkdtemp, rm } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
+
import { Readable, Writable } from "node:stream";
|
|
5
6
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
6
7
|
|
|
7
8
|
import type { PreToolUsePayload } from "../src/codex-hook.ts";
|
|
8
|
-
import { applySpawnGuards } from "../src/spawn-guard.ts";
|
|
9
|
+
import { applySpawnGuards, DEFAULT_FANOUT_LIMIT, runSpawnAdmissionRecorderCli } from "../src/spawn-guard.ts";
|
|
9
10
|
|
|
10
11
|
let workDir: string;
|
|
11
12
|
let originalLimit: string | undefined;
|
|
12
13
|
let originalReviewLimit: string | undefined;
|
|
13
14
|
let originalToolkitSurface: string | undefined;
|
|
15
|
+
let originalPluginData: string | undefined;
|
|
14
16
|
|
|
15
17
|
beforeEach(async () => {
|
|
16
18
|
workDir = await mkdtemp(join(tmpdir(), "ulw-spawn-guard-"));
|
|
19
|
+
originalPluginData = process.env["PLUGIN_DATA"];
|
|
20
|
+
process.env["PLUGIN_DATA"] = join(workDir, "plugin-data");
|
|
17
21
|
originalLimit = process.env["OMO_SPAWN_FANOUT_LIMIT"];
|
|
18
22
|
originalReviewLimit = process.env["OMO_ULW_LOOP_REVIEW_SPAWN_LIMIT"];
|
|
19
23
|
originalToolkitSurface = process.env["OMO_AGENT_TOOLKIT_SURFACE"];
|
|
@@ -30,6 +34,8 @@ afterEach(async () => {
|
|
|
30
34
|
else process.env["OMO_ULW_LOOP_REVIEW_SPAWN_LIMIT"] = originalReviewLimit;
|
|
31
35
|
if (originalToolkitSurface === undefined) delete process.env["OMO_AGENT_TOOLKIT_SURFACE"];
|
|
32
36
|
else process.env["OMO_AGENT_TOOLKIT_SURFACE"] = originalToolkitSurface;
|
|
37
|
+
if (originalPluginData === undefined) delete process.env["PLUGIN_DATA"];
|
|
38
|
+
else process.env["PLUGIN_DATA"] = originalPluginData;
|
|
33
39
|
await rm(workDir, { recursive: true, force: true });
|
|
34
40
|
});
|
|
35
41
|
|
|
@@ -98,7 +104,66 @@ function deny(output: string): { permissionDecision: string; permissionDecisionR
|
|
|
98
104
|
return JSON.parse(output).hookSpecificOutput;
|
|
99
105
|
}
|
|
100
106
|
|
|
107
|
+
describe("spawn admission breaker", () => {
|
|
108
|
+
async function record(response: unknown): Promise<string> {
|
|
109
|
+
let output = "";
|
|
110
|
+
const stdout = new Writable({
|
|
111
|
+
write(chunk, _encoding, callback) {
|
|
112
|
+
output += chunk.toString();
|
|
113
|
+
callback();
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
await runSpawnAdmissionRecorderCli(
|
|
117
|
+
Readable.from([
|
|
118
|
+
JSON.stringify({
|
|
119
|
+
...payload("spawn_agent", { message: "scan" }),
|
|
120
|
+
hook_event_name: "PostToolUse",
|
|
121
|
+
tool_response: response,
|
|
122
|
+
}),
|
|
123
|
+
]),
|
|
124
|
+
stdout,
|
|
125
|
+
);
|
|
126
|
+
return output;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
it.each(["too many active cells", "AgentLimitReached", "max_threads", "max_concurrent_threads_per_session"])(
|
|
130
|
+
"records %s silently and denies without a plan while isolating other sessions",
|
|
131
|
+
async (reason) => {
|
|
132
|
+
expect(await record(reason)).toBe("");
|
|
133
|
+
const marker = JSON.parse(readFileSync(join(workDir, "plugin-data", "spawn-breaker", "s1.json"), "utf8"));
|
|
134
|
+
expect(Object.keys(marker).sort()).toEqual(["at", "reason"]);
|
|
135
|
+
expect(marker.reason).toBe(reason);
|
|
136
|
+
expect(Number.isFinite(Date.parse(marker.at))).toBe(true);
|
|
137
|
+
expect(deny(applySpawnGuards(payload("spawn_agent", {}))).permissionDecision).toBe("deny");
|
|
138
|
+
expect(applySpawnGuards({ ...payload("spawn_agent", {}), session_id: "clean" })).toBe("");
|
|
139
|
+
},
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
it("does not record a successful admission", async () => {
|
|
143
|
+
expect(await record({ agent_id: "worker-1" })).toBe("");
|
|
144
|
+
expect(existsSync(join(workDir, "plugin-data", "spawn-breaker", "s1.json"))).toBe(false);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("denies before artifact, quota, and state lock guards", async () => {
|
|
148
|
+
writeGoals();
|
|
149
|
+
writeFileSync(
|
|
150
|
+
join(sessionDir(), ".state.lock"),
|
|
151
|
+
JSON.stringify({ pid: process.pid, createdAt: new Date().toISOString(), token: "live" }),
|
|
152
|
+
);
|
|
153
|
+
await record("AgentLimitReached");
|
|
154
|
+
const output = deny(
|
|
155
|
+
applySpawnGuards(payload("spawn_agent", { agent_type: "lazycodex-gate-reviewer" }), { lockTimeoutMs: 0 }),
|
|
156
|
+
);
|
|
157
|
+
expect(output.permissionDecisionReason).toContain("AgentLimitReached");
|
|
158
|
+
expect(existsSync(join(sessionDir(), "spawn-count.json"))).toBe(false);
|
|
159
|
+
expect(existsSync(join(sessionDir(), "review-spawn-counts.json"))).toBe(false);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
101
163
|
describe("applySpawnGuards fan-out cap", () => {
|
|
164
|
+
it("defaults to 24 spawns", () => {
|
|
165
|
+
expect(DEFAULT_FANOUT_LIMIT).toBe(24);
|
|
166
|
+
});
|
|
102
167
|
it("#given spawns under the limit #when guarded #then allows and counts", () => {
|
|
103
168
|
writeGoals();
|
|
104
169
|
|
|
@@ -251,7 +316,7 @@ describe("applySpawnGuards gate-artifact guard", () => {
|
|
|
251
316
|
);
|
|
252
317
|
|
|
253
318
|
expect(output).not.toBe("");
|
|
254
|
-
expect(deny(output).permissionDecisionReason).toContain("g1-
|
|
319
|
+
expect(deny(output).permissionDecisionReason).toContain("g1-manual-qa.md");
|
|
255
320
|
expect(existsSync(join(sessionDir(), "review-spawn-counts.json"))).toBe(false);
|
|
256
321
|
});
|
|
257
322
|
|
|
@@ -265,7 +330,7 @@ describe("applySpawnGuards gate-artifact guard", () => {
|
|
|
265
330
|
const parsed = deny(output);
|
|
266
331
|
expect(parsed.permissionDecision).toBe("deny");
|
|
267
332
|
expect(parsed.permissionDecisionReason).toContain("missing");
|
|
268
|
-
expect(parsed.permissionDecisionReason).toContain("g1-
|
|
333
|
+
expect(parsed.permissionDecisionReason).toContain("g1-manual-qa.md");
|
|
269
334
|
});
|
|
270
335
|
|
|
271
336
|
it("#given senpi main-session QA is present but code review is absent #when the gate reviewer spawns #then the self-check allows it", () => {
|
|
@@ -366,10 +431,9 @@ describe("applySpawnGuards gate-artifact guard", () => {
|
|
|
366
431
|
expect(counters["lazycodex-code-reviewer:g1:a1"]).toBeUndefined();
|
|
367
432
|
});
|
|
368
433
|
|
|
369
|
-
it("#given v1
|
|
434
|
+
it("#given only v1 manual QA on disk #when the gate spawns #then allows", () => {
|
|
370
435
|
writeGoals();
|
|
371
436
|
mkdirSync(join(workDir, ".omo", "evidence"), { recursive: true });
|
|
372
|
-
writeFileSync(join(workDir, ".omo", "evidence", "g1-code-review.md"), "report\n");
|
|
373
437
|
writeFileSync(join(workDir, ".omo", "evidence", "g1-manual-qa.md"), "matrix\n");
|
|
374
438
|
|
|
375
439
|
const output = applySpawnGuards(
|
|
@@ -388,14 +452,13 @@ describe("applySpawnGuards gate-artifact guard", () => {
|
|
|
388
452
|
payload("spawn_agent", { agent_type: "lazycodex-gate-reviewer", message: "final gate review" }),
|
|
389
453
|
);
|
|
390
454
|
|
|
391
|
-
expect(deny(output).permissionDecisionReason).toContain(".omo/evidence/ulw/s1/g1/a1/g1-
|
|
455
|
+
expect(deny(output).permissionDecisionReason).toContain(".omo/evidence/ulw/s1/g1/a1/g1-manual-qa.md");
|
|
392
456
|
});
|
|
393
457
|
|
|
394
458
|
it("#given a v2 plan with attempt-dir artifacts #when the gate spawns #then allows", () => {
|
|
395
459
|
writeGoals({ evidenceLayoutVersion: 2 });
|
|
396
460
|
const attemptDir = join(workDir, ".omo", "evidence", "ulw", "s1", "g1", "a1");
|
|
397
461
|
mkdirSync(attemptDir, { recursive: true });
|
|
398
|
-
writeFileSync(join(attemptDir, "g1-code-review.md"), "report\n");
|
|
399
462
|
writeFileSync(join(attemptDir, "g1-manual-qa.md"), "matrix\n");
|
|
400
463
|
|
|
401
464
|
const output = applySpawnGuards(
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/git-bash/dist/cli.js\" hook post-compact",
|
|
9
9
|
"timeout": 5,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Resetting Git Bash MCP Reminder",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\git-bash\\dist\\cli.js\" hook post-compact"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/lsp/dist/cli.js\" hook post-compact",
|
|
9
9
|
"timeout": 5,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Resetting LSP Diagnostics Cache",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lsp\\dist\\cli.js\" hook post-compact"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook post-compact",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Resetting Project Rule Cache",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook post-compact"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/comment-checker/dist/cli.js\" hook post-tool-use",
|
|
9
9
|
"timeout": 30,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Checking Comments",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\comment-checker\\dist\\cli.js\" hook post-tool-use"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/lsp/dist/cli.js\" hook post-tool-use",
|
|
9
9
|
"timeout": 60,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Checking LSP Diagnostics",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lsp\\dist\\cli.js\" hook post-tool-use"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/components/teammode/dist/cli.js\" hook post-tool-use",
|
|
10
10
|
"timeout": 10,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Checking Thread Title Hygiene",
|
|
12
12
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\teammode\\dist\\cli.js\" hook post-tool-use"
|
|
13
13
|
}
|
|
14
14
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook post-tool-use",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Matching Project Rules",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook post-tool-use"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"PostToolUse": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "^(spawn_agent|collaborationspawn_agent|collaboration\\.spawn_agent)$",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook post-tool-use-spawn",
|
|
10
|
+
"timeout": 5,
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Recording Spawn Admission",
|
|
12
|
+
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook post-tool-use-spawn"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook pre-tool-use",
|
|
9
9
|
"timeout": 5,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Enforcing Unlimited Goal Budget",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook pre-tool-use"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook pre-tool-use-spawn",
|
|
10
10
|
"timeout": 5,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Guarding Ulw-Loop Spawns",
|
|
12
12
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook pre-tool-use-spawn"
|
|
13
13
|
}
|
|
14
14
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/git-bash/dist/cli.js\" hook pre-tool-use",
|
|
9
9
|
"timeout": 5,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Recommending Git Bash MCP",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\git-bash\\dist\\cli.js\" hook pre-tool-use"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/scripts/auto-update.mjs\" hook session-start",
|
|
9
9
|
"timeout": 15,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Checking Auto Update",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\scripts\\auto-update.mjs\" hook session-start"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/bootstrap/dist/cli.js\" hook session-start",
|
|
9
9
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1\"",
|
|
10
10
|
"timeout": 30,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Checking Bootstrap Provisioning"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook session-start",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Loading Project Rules",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook session-start"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/telemetry/dist/cli.js\" hook session-start",
|
|
9
9
|
"timeout": 15,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Recording Session Telemetry",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\telemetry\\dist\\cli.js\" hook session-start"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/ulw-execute-continuation/dist/cli.js\" hook stop",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Checking Ulw-Execute Continuation",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-execute-continuation\\dist\\cli.js\" hook stop"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook stop",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Checking Ulw-Loop Resume",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook stop"
|
|
12
12
|
}
|
|
13
13
|
]
|
package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.49) Verifying LazyCodex Executor Evidence",
|
|
11
11
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lazycodex-executor-verify\\dist\\cli.js\" hook subagent-stop"
|
|
12
12
|
}
|
|
13
13
|
],
|