oh-my-copilot 4.13.2 → 4.13.21
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/bridge/cli.cjs +2522 -949
- package/bridge/mcp-server.cjs +97 -9
- package/bridge/runtime-cli.cjs +1256 -133
- package/bridge/team.js +1241 -65
- package/dist/__tests__/auto-slash-aliases.test.js +91 -0
- package/dist/__tests__/auto-slash-aliases.test.js.map +1 -1
- package/dist/__tests__/hud/labels.test.d.ts +2 -0
- package/dist/__tests__/hud/labels.test.d.ts.map +1 -0
- package/dist/__tests__/hud/labels.test.js +158 -0
- package/dist/__tests__/hud/labels.test.js.map +1 -0
- package/dist/__tests__/hud/render-rate-limits-priority.test.js +26 -0
- package/dist/__tests__/hud/render-rate-limits-priority.test.js.map +1 -1
- package/dist/__tests__/hud-marketplace-resolution.test.js +34 -0
- package/dist/__tests__/hud-marketplace-resolution.test.js.map +1 -1
- package/dist/__tests__/installer-hud-skip.test.js +6 -0
- package/dist/__tests__/installer-hud-skip.test.js.map +1 -1
- package/dist/__tests__/installer-omc-reference.test.js +1 -1
- package/dist/__tests__/installer-omc-reference.test.js.map +1 -1
- package/dist/__tests__/mnemosyne/detector.test.js +2 -0
- package/dist/__tests__/mnemosyne/detector.test.js.map +1 -1
- package/dist/__tests__/notepad.test.js +2 -2
- package/dist/__tests__/notepad.test.js.map +1 -1
- package/dist/__tests__/pre-tool-enforcer.test.js +84 -1
- package/dist/__tests__/pre-tool-enforcer.test.js.map +1 -1
- package/dist/__tests__/ralph-prd-mandatory.test.js +11 -1
- package/dist/__tests__/ralph-prd-mandatory.test.js.map +1 -1
- package/dist/__tests__/ralph-prd.test.js +40 -2
- package/dist/__tests__/ralph-prd.test.js.map +1 -1
- package/dist/__tests__/skills.test.js +363 -4
- package/dist/__tests__/skills.test.js.map +1 -1
- package/dist/__tests__/state-root-resolution.test.js +56 -6
- package/dist/__tests__/state-root-resolution.test.js.map +1 -1
- package/dist/autoresearch/__tests__/runtime.test.js +225 -28
- package/dist/autoresearch/__tests__/runtime.test.js.map +1 -1
- package/dist/autoresearch/runtime.d.ts.map +1 -1
- package/dist/autoresearch/runtime.js +9 -5
- package/dist/autoresearch/runtime.js.map +1 -1
- package/dist/cli/autoresearch.d.ts +1 -1
- package/dist/cli/autoresearch.d.ts.map +1 -1
- package/dist/cli/autoresearch.js +4 -4
- package/dist/cli/commands/team.d.ts +1 -0
- package/dist/cli/commands/team.d.ts.map +1 -1
- package/dist/cli/commands/team.js +14 -2
- package/dist/cli/commands/team.js.map +1 -1
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/team.d.ts +6 -0
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +23 -1
- package/dist/cli/team.js.map +1 -1
- package/dist/config/__tests__/loader.test.js.map +1 -1
- package/dist/features/boulder-state/constants.d.ts +1 -1
- package/dist/features/boulder-state/constants.d.ts.map +1 -1
- package/dist/features/builtin-skills/skills.d.ts.map +1 -1
- package/dist/features/builtin-skills/skills.js +11 -3
- package/dist/features/builtin-skills/skills.js.map +1 -1
- package/dist/features/builtin-skills/types.d.ts +7 -0
- package/dist/features/builtin-skills/types.d.ts.map +1 -1
- package/dist/features/magic-keywords.d.ts.map +1 -1
- package/dist/features/magic-keywords.js +30 -1
- package/dist/features/magic-keywords.js.map +1 -1
- package/dist/features/rate-limit-wait/tmux-detector.d.ts +4 -4
- package/dist/features/rate-limit-wait/tmux-detector.js +9 -9
- package/dist/features/rate-limit-wait/tmux-detector.js.map +1 -1
- package/dist/hooks/__tests__/bridge-routing.test.js +156 -0
- package/dist/hooks/__tests__/bridge-routing.test.js.map +1 -1
- package/dist/hooks/auto-slash-command/constants.d.ts.map +1 -1
- package/dist/hooks/auto-slash-command/constants.js +1 -0
- package/dist/hooks/auto-slash-command/constants.js.map +1 -1
- package/dist/hooks/auto-slash-command/executor.d.ts.map +1 -1
- package/dist/hooks/auto-slash-command/executor.js +29 -0
- package/dist/hooks/auto-slash-command/executor.js.map +1 -1
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +184 -1
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/learner/detector.js +1 -1
- package/dist/hooks/mode-registry/__tests__/session-isolation.test.js +16 -0
- package/dist/hooks/mode-registry/__tests__/session-isolation.test.js.map +1 -1
- package/dist/hooks/notepad/index.d.ts +4 -1
- package/dist/hooks/notepad/index.d.ts.map +1 -1
- package/dist/hooks/notepad/index.js +7 -4
- package/dist/hooks/notepad/index.js.map +1 -1
- package/dist/hooks/persistent-mode/__tests__/ralph-verification-flow.test.js +70 -3
- package/dist/hooks/persistent-mode/__tests__/ralph-verification-flow.test.js.map +1 -1
- package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/index.js +10 -9
- package/dist/hooks/persistent-mode/index.js.map +1 -1
- package/dist/hooks/persistent-mode/stop-hook-blocking.test.js +64 -9
- package/dist/hooks/persistent-mode/stop-hook-blocking.test.js.map +1 -1
- package/dist/hooks/project-memory/__tests__/integration.test.js +117 -3
- package/dist/hooks/project-memory/__tests__/integration.test.js.map +1 -1
- package/dist/hooks/project-memory/__tests__/storage.test.js +11 -11
- package/dist/hooks/project-memory/__tests__/storage.test.js.map +1 -1
- package/dist/hooks/project-memory/index.d.ts.map +1 -1
- package/dist/hooks/project-memory/index.js +24 -12
- package/dist/hooks/project-memory/index.js.map +1 -1
- package/dist/hooks/ralph/index.d.ts +1 -1
- package/dist/hooks/ralph/index.d.ts.map +1 -1
- package/dist/hooks/ralph/index.js +1 -1
- package/dist/hooks/ralph/index.js.map +1 -1
- package/dist/hooks/ralph/loop.d.ts +6 -6
- package/dist/hooks/ralph/loop.d.ts.map +1 -1
- package/dist/hooks/ralph/loop.js +18 -18
- package/dist/hooks/ralph/loop.js.map +1 -1
- package/dist/hooks/ralph/prd.d.ts +23 -12
- package/dist/hooks/ralph/prd.d.ts.map +1 -1
- package/dist/hooks/ralph/prd.js +88 -42
- package/dist/hooks/ralph/prd.js.map +1 -1
- package/dist/hooks/session-end/__tests__/mode-state-cleanup.test.js +20 -0
- package/dist/hooks/session-end/__tests__/mode-state-cleanup.test.js.map +1 -1
- package/dist/hooks/session-end/index.d.ts +9 -0
- package/dist/hooks/session-end/index.d.ts.map +1 -1
- package/dist/hooks/session-end/index.js +67 -0
- package/dist/hooks/session-end/index.js.map +1 -1
- package/dist/hooks/skill-bridge.cjs +6 -5
- package/dist/hooks/skill-state/index.d.ts.map +1 -1
- package/dist/hooks/skill-state/index.js +1 -0
- package/dist/hooks/skill-state/index.js.map +1 -1
- package/dist/hud/__tests__/git-status.test.js +18 -0
- package/dist/hud/__tests__/git-status.test.js.map +1 -1
- package/dist/hud/elements/background.d.ts +3 -3
- package/dist/hud/elements/background.d.ts.map +1 -1
- package/dist/hud/elements/background.js +5 -4
- package/dist/hud/elements/background.js.map +1 -1
- package/dist/hud/elements/call-counts.d.ts +2 -2
- package/dist/hud/elements/call-counts.d.ts.map +1 -1
- package/dist/hud/elements/call-counts.js +7 -6
- package/dist/hud/elements/call-counts.js.map +1 -1
- package/dist/hud/elements/context.d.ts +3 -3
- package/dist/hud/elements/context.d.ts.map +1 -1
- package/dist/hud/elements/context.js +5 -4
- package/dist/hud/elements/context.js.map +1 -1
- package/dist/hud/elements/git.d.ts +2 -1
- package/dist/hud/elements/git.d.ts.map +1 -1
- package/dist/hud/elements/git.js +7 -6
- package/dist/hud/elements/git.js.map +1 -1
- package/dist/hud/elements/ralph.d.ts +2 -2
- package/dist/hud/elements/ralph.d.ts.map +1 -1
- package/dist/hud/elements/ralph.js +3 -2
- package/dist/hud/elements/ralph.js.map +1 -1
- package/dist/hud/elements/thinking.d.ts +2 -2
- package/dist/hud/elements/thinking.d.ts.map +1 -1
- package/dist/hud/elements/thinking.js +3 -2
- package/dist/hud/elements/thinking.js.map +1 -1
- package/dist/hud/elements/token-usage.d.ts +2 -2
- package/dist/hud/elements/token-usage.d.ts.map +1 -1
- package/dist/hud/elements/token-usage.js +3 -2
- package/dist/hud/elements/token-usage.js.map +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +11 -10
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +18 -1
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/types.d.ts +26 -0
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js +58 -0
- package/dist/hud/types.js.map +1 -1
- package/dist/installer/__tests__/hud-cache-wrapper.test.d.ts +2 -0
- package/dist/installer/__tests__/hud-cache-wrapper.test.d.ts.map +1 -0
- package/dist/installer/__tests__/hud-cache-wrapper.test.js +235 -0
- package/dist/installer/__tests__/hud-cache-wrapper.test.js.map +1 -0
- package/dist/installer/__tests__/standalone-hook-reconcile.test.js +2 -0
- package/dist/installer/__tests__/standalone-hook-reconcile.test.js.map +1 -1
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +19 -7
- package/dist/installer/index.js.map +1 -1
- package/dist/lib/__tests__/worktree-paths.test.js +162 -39
- package/dist/lib/__tests__/worktree-paths.test.js.map +1 -1
- package/dist/lib/worktree-paths.d.ts +87 -9
- package/dist/lib/worktree-paths.d.ts.map +1 -1
- package/dist/lib/worktree-paths.js +209 -27
- package/dist/lib/worktree-paths.js.map +1 -1
- package/dist/team/__tests__/auto-merge-restart.test.d.ts +2 -0
- package/dist/team/__tests__/auto-merge-restart.test.d.ts.map +1 -0
- package/dist/team/__tests__/auto-merge-restart.test.js +128 -0
- package/dist/team/__tests__/auto-merge-restart.test.js.map +1 -0
- package/dist/team/__tests__/auto-merge.perf.test.d.ts +2 -0
- package/dist/team/__tests__/auto-merge.perf.test.d.ts.map +1 -0
- package/dist/team/__tests__/auto-merge.perf.test.js +85 -0
- package/dist/team/__tests__/auto-merge.perf.test.js.map +1 -0
- package/dist/team/__tests__/conflict-mailbox.test.d.ts +2 -0
- package/dist/team/__tests__/conflict-mailbox.test.d.ts.map +1 -0
- package/dist/team/__tests__/conflict-mailbox.test.js +238 -0
- package/dist/team/__tests__/conflict-mailbox.test.js.map +1 -0
- package/dist/team/__tests__/helpers/git-fixture.d.ts +72 -0
- package/dist/team/__tests__/helpers/git-fixture.d.ts.map +1 -0
- package/dist/team/__tests__/helpers/git-fixture.js +252 -0
- package/dist/team/__tests__/helpers/git-fixture.js.map +1 -0
- package/dist/team/__tests__/leader-inbox.test.d.ts +2 -0
- package/dist/team/__tests__/leader-inbox.test.d.ts.map +1 -0
- package/dist/team/__tests__/leader-inbox.test.js +152 -0
- package/dist/team/__tests__/leader-inbox.test.js.map +1 -0
- package/dist/team/__tests__/merge-orchestrator.test.d.ts +2 -0
- package/dist/team/__tests__/merge-orchestrator.test.d.ts.map +1 -0
- package/dist/team/__tests__/merge-orchestrator.test.js +779 -0
- package/dist/team/__tests__/merge-orchestrator.test.js.map +1 -0
- package/dist/team/__tests__/rebase-smoke.test.d.ts +2 -0
- package/dist/team/__tests__/rebase-smoke.test.d.ts.map +1 -0
- package/dist/team/__tests__/rebase-smoke.test.js +272 -0
- package/dist/team/__tests__/rebase-smoke.test.js.map +1 -0
- package/dist/team/__tests__/runtime-cli.test.js +9 -1
- package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
- package/dist/team/__tests__/runtime-v2.dispatch.test.js +150 -1
- package/dist/team/__tests__/runtime-v2.dispatch.test.js.map +1 -1
- package/dist/team/__tests__/teardown-invariant.test.d.ts +2 -0
- package/dist/team/__tests__/teardown-invariant.test.d.ts.map +1 -0
- package/dist/team/__tests__/teardown-invariant.test.js +176 -0
- package/dist/team/__tests__/teardown-invariant.test.js.map +1 -0
- package/dist/team/__tests__/worker-commit-cadence.test.d.ts +2 -0
- package/dist/team/__tests__/worker-commit-cadence.test.d.ts.map +1 -0
- package/dist/team/__tests__/worker-commit-cadence.test.js +315 -0
- package/dist/team/__tests__/worker-commit-cadence.test.js.map +1 -0
- package/dist/team/__tests__/worktree-runtime-e2e.test.d.ts +2 -0
- package/dist/team/__tests__/worktree-runtime-e2e.test.d.ts.map +1 -0
- package/dist/team/__tests__/worktree-runtime-e2e.test.js +182 -0
- package/dist/team/__tests__/worktree-runtime-e2e.test.js.map +1 -0
- package/dist/team/conflict-mailbox.d.ts +49 -0
- package/dist/team/conflict-mailbox.d.ts.map +1 -0
- package/dist/team/conflict-mailbox.js +98 -0
- package/dist/team/conflict-mailbox.js.map +1 -0
- package/dist/team/leader-inbox.d.ts +28 -0
- package/dist/team/leader-inbox.d.ts.map +1 -0
- package/dist/team/leader-inbox.js +68 -0
- package/dist/team/leader-inbox.js.map +1 -0
- package/dist/team/merge-coordinator.d.ts +6 -0
- package/dist/team/merge-coordinator.d.ts.map +1 -1
- package/dist/team/merge-coordinator.js +6 -2
- package/dist/team/merge-coordinator.js.map +1 -1
- package/dist/team/merge-orchestrator.d.ts +41 -0
- package/dist/team/merge-orchestrator.d.ts.map +1 -0
- package/dist/team/merge-orchestrator.js +736 -0
- package/dist/team/merge-orchestrator.js.map +1 -0
- package/dist/team/runtime-cli.d.ts +1 -0
- package/dist/team/runtime-cli.d.ts.map +1 -1
- package/dist/team/runtime-cli.js +15 -2
- package/dist/team/runtime-cli.js.map +1 -1
- package/dist/team/runtime-flags.d.ts +5 -0
- package/dist/team/runtime-flags.d.ts.map +1 -0
- package/dist/team/runtime-flags.js +12 -0
- package/dist/team/runtime-flags.js.map +1 -0
- package/dist/team/runtime-v2.d.ts +7 -1
- package/dist/team/runtime-v2.d.ts.map +1 -1
- package/dist/team/runtime-v2.js +185 -8
- package/dist/team/runtime-v2.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts +4 -0
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +10 -1
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/team/worker-commit-cadence.d.ts +70 -0
- package/dist/team/worker-commit-cadence.d.ts.map +1 -0
- package/dist/team/worker-commit-cadence.js +271 -0
- package/dist/team/worker-commit-cadence.js.map +1 -0
- package/dist/tools/__tests__/memory-tools.test.js +4 -4
- package/dist/tools/__tests__/memory-tools.test.js.map +1 -1
- package/dist/tools/__tests__/state-tools.test.js +13 -1
- package/dist/tools/__tests__/state-tools.test.js.map +1 -1
- package/docs/GETTING-STARTED.md +415 -0
- package/docs/MIGRATION.md +66 -66
- package/docs/REFERENCE.md +21 -4
- package/docs/company-context-interface.md +5 -16
- package/docs/copilot-instructions.md +1 -1
- package/package.json +1 -1
- package/scripts/lib/hud-cache-wrapper.sh +122 -0
- package/scripts/plugin-setup.mjs +10 -1
- package/scripts/post-tool-verifier.mjs +118 -5
- package/scripts/pre-tool-enforcer.mjs +54 -6
- package/scripts/session-start.mjs +171 -3
- package/skills/AGENTS.md +22 -91
- package/skills/ai-slop-cleaner/SKILL.md +118 -120
- package/skills/ask/SKILL.md +6 -8
- package/skills/autopilot/SKILL.md +1 -28
- package/skills/autoresearch/SKILL.md +5 -5
- package/skills/cancel/SKILL.md +13 -13
- package/skills/cccg/SKILL.md +1 -0
- package/skills/configure-notifications/SKILL.md +80 -215
- package/skills/debug/SKILL.md +3 -2
- package/skills/deep-dive/SKILL.md +20 -9
- package/skills/deep-interview/SKILL.md +32 -4
- package/skills/deepinit/SKILL.md +1 -0
- package/skills/external-context/SKILL.md +2 -1
- package/skills/hud/SKILL.md +22 -52
- package/skills/learner/SKILL.md +90 -57
- package/skills/mcp-setup/SKILL.md +45 -60
- package/skills/omc-doctor/SKILL.md +1 -1
- package/skills/omc-reference/SKILL.md +6 -6
- package/skills/omc-setup/SKILL.md +30 -74
- package/skills/omc-setup/phases/01-install-claude-md.md +97 -0
- package/skills/omc-setup/phases/02-configure.md +25 -40
- package/skills/omc-setup/phases/03-integrations.md +100 -69
- package/skills/omc-setup/phases/04-welcome.md +102 -44
- package/skills/omc-teams/SKILL.md +63 -26
- package/skills/plan/SKILL.md +11 -9
- package/skills/ralph/SKILL.md +42 -41
- package/skills/ralplan/SKILL.md +3 -10
- package/skills/release/SKILL.md +168 -57
- package/skills/remember/SKILL.md +2 -1
- package/skills/sciomc/SKILL.md +12 -11
- package/skills/self-improve/SKILL.md +4 -4
- package/skills/setup/SKILL.md +1 -0
- package/skills/skill/SKILL.md +21 -20
- package/skills/skillify/SKILL.md +34 -3
- package/skills/team/SKILL.md +62 -44
- package/skills/ultraqa/SKILL.md +1 -2
- package/skills/ultrawork/SKILL.md +28 -21
- package/skills/verify/SKILL.md +2 -1
- package/skills/writer-memory/SKILL.md +2 -1
- package/templates/hooks/pre-tool-use.mjs +144 -45
|
@@ -747,11 +747,116 @@ function extractTextFromKnownToolResponseField(value, depth = 0) {
|
|
|
747
747
|
return texts;
|
|
748
748
|
}
|
|
749
749
|
|
|
750
|
-
function
|
|
750
|
+
function isStructuredEnvelopePayloadField(fieldName) {
|
|
751
|
+
return new Set([
|
|
752
|
+
'content',
|
|
753
|
+
'oldstring',
|
|
754
|
+
'newstring',
|
|
755
|
+
'originalfile',
|
|
756
|
+
'structuredpatch',
|
|
757
|
+
'patch',
|
|
758
|
+
'diff',
|
|
759
|
+
'lines',
|
|
760
|
+
'line',
|
|
761
|
+
]).has(fieldName.toLowerCase());
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
function isStructuredEnvelopeStatusTextField(fieldName) {
|
|
765
|
+
return new Set(['message', 'output', 'stdout', 'stderr', 'text', 'result'])
|
|
766
|
+
.has(fieldName.toLowerCase());
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
function hasExplicitStructuredFailureIndicator(value, depth = 0, fieldName = '') {
|
|
770
|
+
if (!value || typeof value === 'string' || depth > 4) return false;
|
|
771
|
+
if (fieldName && isStructuredEnvelopePayloadField(fieldName)) return false;
|
|
772
|
+
|
|
773
|
+
if (Array.isArray(value)) {
|
|
774
|
+
return value.some(item => hasExplicitStructuredFailureIndicator(item, depth + 1, fieldName));
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
if (typeof value !== 'object') return false;
|
|
778
|
+
|
|
779
|
+
for (const [key, fieldValue] of Object.entries(value)) {
|
|
780
|
+
const normalizedKey = key.toLowerCase();
|
|
781
|
+
if (
|
|
782
|
+
typeof fieldValue === 'string' &&
|
|
783
|
+
isStructuredEnvelopeStatusTextField(key) &&
|
|
784
|
+
detectWriteFailure(fieldValue)
|
|
785
|
+
) {
|
|
786
|
+
return true;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
if (
|
|
790
|
+
(normalizedKey.includes('error') || normalizedKey.includes('fail')) &&
|
|
791
|
+
fieldValue !== false &&
|
|
792
|
+
fieldValue !== 0 &&
|
|
793
|
+
fieldValue !== null &&
|
|
794
|
+
fieldValue !== undefined &&
|
|
795
|
+
!(typeof fieldValue === 'string' && fieldValue.trim() === '') &&
|
|
796
|
+
!(Array.isArray(fieldValue) && fieldValue.length === 0)
|
|
797
|
+
) {
|
|
798
|
+
return true;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (hasExplicitStructuredFailureIndicator(fieldValue, depth + 1, key)) {
|
|
802
|
+
return true;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
return false;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
function hasEditEnvelopeSuccess(value, depth = 0) {
|
|
810
|
+
if (!value || typeof value === 'string' || depth > 4) return false;
|
|
811
|
+
|
|
812
|
+
if (Array.isArray(value)) {
|
|
813
|
+
return value.some(item => hasEditEnvelopeSuccess(item, depth + 1));
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if (typeof value !== 'object') return false;
|
|
817
|
+
|
|
818
|
+
if (hasExplicitStructuredFailureIndicator(value, depth)) return false;
|
|
819
|
+
|
|
820
|
+
if (typeof value.filePath === 'string' && Array.isArray(value.structuredPatch)) {
|
|
821
|
+
return true;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
return Object.values(value).some(item => hasEditEnvelopeSuccess(item, depth + 1));
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
function hasWriteEnvelopeSuccess(value, depth = 0) {
|
|
828
|
+
if (!value || typeof value === 'string' || depth > 4) return false;
|
|
829
|
+
|
|
830
|
+
if (Array.isArray(value)) {
|
|
831
|
+
return value.some(item => hasWriteEnvelopeSuccess(item, depth + 1));
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
if (typeof value !== 'object') return false;
|
|
835
|
+
|
|
836
|
+
if (hasExplicitStructuredFailureIndicator(value, depth)) return false;
|
|
837
|
+
|
|
838
|
+
if (
|
|
839
|
+
typeof value.filePath === 'string' &&
|
|
840
|
+
(value.type === 'create' || value.type === 'update')
|
|
841
|
+
) {
|
|
842
|
+
return true;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
return Object.values(value).some(item => hasWriteEnvelopeSuccess(item, depth + 1));
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
function hasStructuredWriteSuccess(rawResponse, toolName = '') {
|
|
751
849
|
if (!rawResponse || typeof rawResponse === 'string') return false;
|
|
850
|
+
if (toolName === 'Edit' && hasEditEnvelopeSuccess(rawResponse)) return true;
|
|
851
|
+
if (toolName === 'Write' && hasWriteEnvelopeSuccess(rawResponse)) return true;
|
|
752
852
|
return extractTextFromKnownToolResponseField(rawResponse).some(isCopilotCliWriteSuccess);
|
|
753
853
|
}
|
|
754
854
|
|
|
855
|
+
function hasStructuredWriteFailure(rawResponse) {
|
|
856
|
+
if (!rawResponse || typeof rawResponse === 'string') return false;
|
|
857
|
+
return hasExplicitStructuredFailureIndicator(rawResponse);
|
|
858
|
+
}
|
|
859
|
+
|
|
755
860
|
// Get agent completion summary from tracking state
|
|
756
861
|
function getAgentCompletionSummary(directory, quietLevel = QUIET_LEVEL) {
|
|
757
862
|
const trackingFile = join(directory, '.omcp', 'state', 'subagent-tracking.json');
|
|
@@ -780,7 +885,12 @@ function getAgentCompletionSummary(directory, quietLevel = QUIET_LEVEL) {
|
|
|
780
885
|
|
|
781
886
|
// Generate contextual message
|
|
782
887
|
function generateMessage(toolName, toolOutput, sessionId, toolCount, directory, options = {}) {
|
|
783
|
-
const {
|
|
888
|
+
const {
|
|
889
|
+
wasTruncated = false,
|
|
890
|
+
rawLength = 0,
|
|
891
|
+
structuredWriteSuccess = false,
|
|
892
|
+
structuredWriteFailure = false,
|
|
893
|
+
} = options;
|
|
784
894
|
let message = '';
|
|
785
895
|
|
|
786
896
|
switch (toolName) {
|
|
@@ -831,7 +941,7 @@ function generateMessage(toolName, toolOutput, sessionId, toolCount, directory,
|
|
|
831
941
|
}
|
|
832
942
|
|
|
833
943
|
case 'Edit':
|
|
834
|
-
if (!structuredWriteSuccess && !isCopilotCliWriteSuccess(toolOutput) && detectWriteFailure(toolOutput)) {
|
|
944
|
+
if (structuredWriteFailure || (!structuredWriteSuccess && !isCopilotCliWriteSuccess(toolOutput) && detectWriteFailure(toolOutput))) {
|
|
835
945
|
message = 'Edit operation failed. Verify file exists and content matches exactly.';
|
|
836
946
|
} else if (QUIET_LEVEL === 0) {
|
|
837
947
|
message = 'Code modified. Verify changes work as expected before marking complete.';
|
|
@@ -839,7 +949,7 @@ function generateMessage(toolName, toolOutput, sessionId, toolCount, directory,
|
|
|
839
949
|
break;
|
|
840
950
|
|
|
841
951
|
case 'Write':
|
|
842
|
-
if (!structuredWriteSuccess && !isCopilotCliWriteSuccess(toolOutput) && detectWriteFailure(toolOutput)) {
|
|
952
|
+
if (structuredWriteFailure || (!structuredWriteSuccess && !isCopilotCliWriteSuccess(toolOutput) && detectWriteFailure(toolOutput))) {
|
|
843
953
|
message = 'Write operation failed. Check file permissions and directory existence.';
|
|
844
954
|
} else if (QUIET_LEVEL === 0) {
|
|
845
955
|
message = 'File written. Test the changes to ensure they work correctly.';
|
|
@@ -897,7 +1007,9 @@ async function main() {
|
|
|
897
1007
|
const toolName = data.tool_name || data.toolName || '';
|
|
898
1008
|
const rawResponse = data.tool_response || data.toolOutput || '';
|
|
899
1009
|
const structuredWriteSuccess =
|
|
900
|
-
(toolName === 'Write' || toolName === 'Edit') && hasStructuredWriteSuccess(rawResponse);
|
|
1010
|
+
(toolName === 'Write' || toolName === 'Edit') && hasStructuredWriteSuccess(rawResponse, toolName);
|
|
1011
|
+
const structuredWriteFailure =
|
|
1012
|
+
(toolName === 'Write' || toolName === 'Edit') && hasStructuredWriteFailure(rawResponse);
|
|
901
1013
|
const toolOutput = typeof rawResponse === 'string' ? rawResponse : JSON.stringify(rawResponse);
|
|
902
1014
|
const { clipped: clippedToolOutput, wasTruncated } = clipToolOutputForAnalysis(toolName, toolOutput);
|
|
903
1015
|
const sessionId = data.session_id || data.sessionId || 'unknown';
|
|
@@ -944,6 +1056,7 @@ async function main() {
|
|
|
944
1056
|
wasTruncated,
|
|
945
1057
|
rawLength: toolOutput.length,
|
|
946
1058
|
structuredWriteSuccess,
|
|
1059
|
+
structuredWriteFailure,
|
|
947
1060
|
}),
|
|
948
1061
|
maybeBuildPreemptiveCompactionMessage(toolName, data, directory),
|
|
949
1062
|
);
|
|
@@ -10,7 +10,7 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, writeFile
|
|
|
10
10
|
import { dirname, join, resolve } from 'path';
|
|
11
11
|
import { execSync } from 'child_process';
|
|
12
12
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
13
|
-
import {
|
|
13
|
+
import { getCopilotConfigDir } from './lib/config-dir.mjs';
|
|
14
14
|
import { evaluateAgentHeavyPreflight } from './lib/pre-tool-enforcer-preflight.mjs';
|
|
15
15
|
import { resolveOmcStateRoot } from './lib/state-root.mjs';
|
|
16
16
|
import { readStdin } from './lib/stdin.mjs';
|
|
@@ -29,6 +29,53 @@ function hasExtendedContextSuffix(modelId) {
|
|
|
29
29
|
function isSubagentSafeModelId(modelId) {
|
|
30
30
|
return isProviderSpecificModelId(modelId) && !hasExtendedContextSuffix(modelId);
|
|
31
31
|
}
|
|
32
|
+
function isBedrockProviderEnv() {
|
|
33
|
+
if (process.env.CLAUDE_CODE_USE_BEDROCK === '1') return true;
|
|
34
|
+
const modelId = process.env.CLAUDE_MODEL || process.env.ANTHROPIC_MODEL || '';
|
|
35
|
+
if (/^((us|eu|ap|global)\.anthropic\.|anthropic\.claude)/i.test(modelId)) return true;
|
|
36
|
+
if (
|
|
37
|
+
/^arn:aws(-[^:]+)?:bedrock:/i.test(modelId)
|
|
38
|
+
&& /:(inference-profile|application-inference-profile)\//i.test(modelId)
|
|
39
|
+
&& modelId.toLowerCase().includes('claude')
|
|
40
|
+
) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
function isVertexProviderEnv() {
|
|
46
|
+
if (process.env.CLAUDE_CODE_USE_VERTEX === '1') return true;
|
|
47
|
+
const modelId = process.env.CLAUDE_MODEL || process.env.ANTHROPIC_MODEL || '';
|
|
48
|
+
return !!modelId && modelId.toLowerCase().startsWith('vertex_ai/');
|
|
49
|
+
}
|
|
50
|
+
function getActiveModelIds() {
|
|
51
|
+
return [process.env.CLAUDE_MODEL || '', process.env.ANTHROPIC_MODEL || ''].filter(Boolean);
|
|
52
|
+
}
|
|
53
|
+
function isNormalClaudeModelId(modelId) {
|
|
54
|
+
const lower = (modelId || '').toLowerCase();
|
|
55
|
+
return Boolean(lower) && lower.includes('claude') && !isProviderSpecificModelId(modelId);
|
|
56
|
+
}
|
|
57
|
+
function hasNormalClaudeActiveModel() {
|
|
58
|
+
return getActiveModelIds().some(isNormalClaudeModelId);
|
|
59
|
+
}
|
|
60
|
+
function isConfigForceInheritProxyEnv() {
|
|
61
|
+
const config = loadOmcConfig();
|
|
62
|
+
return config.routing?.forceInherit === true && !hasNormalClaudeActiveModel();
|
|
63
|
+
}
|
|
64
|
+
function isNonClaudeProviderEnv() {
|
|
65
|
+
if (isBedrockProviderEnv() || isVertexProviderEnv()) return true;
|
|
66
|
+
const modelId = process.env.CLAUDE_MODEL || process.env.ANTHROPIC_MODEL || '';
|
|
67
|
+
if (modelId && !modelId.toLowerCase().includes('claude')) return true;
|
|
68
|
+
const baseUrl = process.env.ANTHROPIC_BASE_URL || '';
|
|
69
|
+
if (baseUrl && !baseUrl.includes('anthropic.com')) return true;
|
|
70
|
+
return isConfigForceInheritProxyEnv();
|
|
71
|
+
}
|
|
72
|
+
function acceptsProxyAnthropicDefaultTierValue(key, value) {
|
|
73
|
+
return key.startsWith('ANTHROPIC_DEFAULT_')
|
|
74
|
+
&& Boolean(value)
|
|
75
|
+
&& isNonClaudeProviderEnv()
|
|
76
|
+
&& !isBedrockProviderEnv()
|
|
77
|
+
&& !isVertexProviderEnv();
|
|
78
|
+
}
|
|
32
79
|
const TIER_ALIASES = new Set(['sonnet', 'opus', 'haiku']);
|
|
33
80
|
function isTierAlias(modelId) {
|
|
34
81
|
return TIER_ALIASES.has((modelId || '').toLowerCase());
|
|
@@ -55,9 +102,10 @@ function resolveTierAliasToSafeModel(tierAlias) {
|
|
|
55
102
|
// model resolution, which handles [1m] suffixes correctly for explicit model= calls.
|
|
56
103
|
// OMC-internal vars (OMC_SUBAGENT_MODEL, OMC_MODEL_*) are not read by CC, so a [1m]
|
|
57
104
|
// value there is not a valid routing proof — keep the stricter isSubagentSafeModelId check.
|
|
58
|
-
const
|
|
105
|
+
const isAnthropicDefaultTierVar = key.startsWith('ANTHROPIC_DEFAULT_');
|
|
106
|
+
const isNativeCcVar = isAnthropicDefaultTierVar || key.startsWith('CLAUDE_CODE_BEDROCK_');
|
|
59
107
|
const validator = isNativeCcVar ? isProviderSpecificModelId : isSubagentSafeModelId;
|
|
60
|
-
if (value && validator(value)) return value;
|
|
108
|
+
if (value && (validator(value) || acceptsProxyAnthropicDefaultTierValue(key, value))) return value;
|
|
61
109
|
}
|
|
62
110
|
return '';
|
|
63
111
|
}
|
|
@@ -167,7 +215,7 @@ function resolveTranscriptPath(transcriptPath, cwd) {
|
|
|
167
215
|
const lastSep = transcriptPath.lastIndexOf('/');
|
|
168
216
|
const sessionFile = lastSep !== -1 ? transcriptPath.substring(lastSep + 1) : '';
|
|
169
217
|
if (sessionFile) {
|
|
170
|
-
const configDir =
|
|
218
|
+
const configDir = getCopilotConfigDir();
|
|
171
219
|
const projectsDir = join(configDir, 'projects');
|
|
172
220
|
if (existsSync(projectsDir)) {
|
|
173
221
|
const encodedMain = mainRepoRoot.replace(/[/\\]/g, '-');
|
|
@@ -518,8 +566,8 @@ function getSkillProtectionLevel(skillName, rawSkillName) {
|
|
|
518
566
|
// Load OMC config to check forceInherit setting (issues #1135, #1201)
|
|
519
567
|
function loadOmcConfig() {
|
|
520
568
|
const configPaths = [
|
|
521
|
-
join(
|
|
522
|
-
join(process.cwd(), '.
|
|
569
|
+
join(getCopilotConfigDir(), '.omc-config.json'),
|
|
570
|
+
join(process.cwd(), '.omcp', 'config.json'),
|
|
523
571
|
];
|
|
524
572
|
for (const configPath of configPaths) {
|
|
525
573
|
try {
|
|
@@ -48,12 +48,10 @@ function readJsonFile(path) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
const SESSION_ID_ALLOWLIST = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/;
|
|
53
51
|
const WORKFLOW_SLOT_TOMBSTONE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
54
52
|
|
|
55
53
|
function isWorkflowSlotTombstonedForMode(omcRoot, mode, sessionId) {
|
|
56
|
-
const safeSessionId = typeof sessionId === 'string' &&
|
|
54
|
+
const safeSessionId = typeof sessionId === 'string' && SAFE_SESSION_ID_PATTERN.test(sessionId) ? sessionId : '';
|
|
57
55
|
const ledgerPath = safeSessionId
|
|
58
56
|
? join(omcRoot, 'state', 'sessions', safeSessionId, 'skill-active-state.json')
|
|
59
57
|
: join(omcRoot, 'state', 'skill-active-state.json');
|
|
@@ -72,6 +70,158 @@ function shouldRestoreModeState(omcRoot, mode, state, sessionId) {
|
|
|
72
70
|
return true;
|
|
73
71
|
}
|
|
74
72
|
|
|
73
|
+
function readLinuxBootId() {
|
|
74
|
+
try {
|
|
75
|
+
if (!existsSync(LINUX_BOOT_ID_PATH)) return undefined;
|
|
76
|
+
const bootId = readFileSync(LINUX_BOOT_ID_PATH, 'utf-8').trim();
|
|
77
|
+
return bootId || undefined;
|
|
78
|
+
} catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function sessionStateDir(omcRoot, sessionId) {
|
|
84
|
+
return join(omcRoot, 'state', 'sessions', sessionId);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function sessionStartedMarkerPath(omcRoot, sessionId) {
|
|
88
|
+
return join(sessionStateDir(omcRoot, sessionId), SESSION_STARTED_MARKER_FILE);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function writeSessionStartedMarker(omcRoot, directory, sessionId) {
|
|
92
|
+
if (!sessionId || !SAFE_SESSION_ID_PATTERN.test(sessionId)) return;
|
|
93
|
+
try {
|
|
94
|
+
const dir = sessionStateDir(omcRoot, sessionId);
|
|
95
|
+
mkdirSync(dir, { recursive: true });
|
|
96
|
+
writeFileSync(
|
|
97
|
+
sessionStartedMarkerPath(omcRoot, sessionId),
|
|
98
|
+
JSON.stringify({
|
|
99
|
+
session_id: sessionId,
|
|
100
|
+
started_at: new Date().toISOString(),
|
|
101
|
+
cwd: directory,
|
|
102
|
+
pid: process.pid,
|
|
103
|
+
// Do not persist process.ppid here: installed hooks run through
|
|
104
|
+
// scripts/run.cjs, whose short-lived process exits as soon as this
|
|
105
|
+
// hook returns. Treating that runner PID as owner liveness caused
|
|
106
|
+
// later SessionStart hooks to falsely clean live session state.
|
|
107
|
+
boot_id: readLinuxBootId(),
|
|
108
|
+
}, null, 2),
|
|
109
|
+
{ encoding: 'utf-8', mode: 0o600 },
|
|
110
|
+
);
|
|
111
|
+
} catch {
|
|
112
|
+
// Best-effort only; SessionStart must remain non-blocking.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function removeSessionStartedMarker(omcRoot, sessionId) {
|
|
117
|
+
if (!sessionId || !SAFE_SESSION_ID_PATTERN.test(sessionId)) return;
|
|
118
|
+
try {
|
|
119
|
+
const markerPath = sessionStartedMarkerPath(omcRoot, sessionId);
|
|
120
|
+
if (existsSync(markerPath)) unlinkSync(markerPath);
|
|
121
|
+
} catch {
|
|
122
|
+
// Best-effort only.
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Return true only when SessionStart has durable abandonment evidence.
|
|
128
|
+
*
|
|
129
|
+
* Claude Code SessionStart input currently provides session metadata such as
|
|
130
|
+
* session_id, transcript_path, cwd, source, model, and agent_type, but no
|
|
131
|
+
* stable owner process for the interactive session. In installed OMC hooks the
|
|
132
|
+
* immediate hook parent belongs to scripts/run.cjs and is intentionally
|
|
133
|
+
* short-lived, so same-boot PID liveness checks are not reliable here. SessionEnd
|
|
134
|
+
* remains the primary same-boot cleanup path; SessionStart only reconciles
|
|
135
|
+
* durable leftovers, such as markers from a previous OS boot.
|
|
136
|
+
*/
|
|
137
|
+
function hasDurableAbandonmentEvidence(marker) {
|
|
138
|
+
const storedBootId = typeof marker?.boot_id === 'string' ? marker.boot_id : undefined;
|
|
139
|
+
const currentBootId = readLinuxBootId();
|
|
140
|
+
if (storedBootId && currentBootId && storedBootId !== currentBootId) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Same-boot hard-kill cleanup requires a durable owner signal. Claude Code
|
|
145
|
+
// does not currently provide one to hooks, so keep active state rather than
|
|
146
|
+
// guessing from hook-runner process ancestry or transcript metadata.
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function cleanupSessionModeState(omcRoot, sessionId) {
|
|
151
|
+
const sessionDir = sessionStateDir(omcRoot, sessionId);
|
|
152
|
+
for (const file of SESSION_END_MODE_STATE_FILES) {
|
|
153
|
+
try {
|
|
154
|
+
const filePath = join(sessionDir, file);
|
|
155
|
+
const state = readJsonFile(filePath);
|
|
156
|
+
if (state?.active === true || file === 'skill-active-state.json') {
|
|
157
|
+
unlinkSync(filePath);
|
|
158
|
+
}
|
|
159
|
+
} catch {
|
|
160
|
+
// Leave ambiguous/unreadable state untouched.
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function cleanupMissionStateForSession(omcRoot, sessionId) {
|
|
166
|
+
const missionStatePath = join(omcRoot, 'state', 'mission-state.json');
|
|
167
|
+
const parsed = readJsonFile(missionStatePath);
|
|
168
|
+
if (!Array.isArray(parsed?.missions)) return;
|
|
169
|
+
|
|
170
|
+
const before = parsed.missions.length;
|
|
171
|
+
parsed.missions = parsed.missions.filter((mission) => {
|
|
172
|
+
if (mission?.source !== 'session') return true;
|
|
173
|
+
const missionId = typeof mission.id === 'string' ? mission.id : '';
|
|
174
|
+
return !missionId.includes(sessionId);
|
|
175
|
+
});
|
|
176
|
+
if (parsed.missions.length !== before) {
|
|
177
|
+
parsed.updatedAt = new Date().toISOString();
|
|
178
|
+
try {
|
|
179
|
+
writeFileSync(missionStatePath, JSON.stringify(parsed, null, 2));
|
|
180
|
+
} catch {
|
|
181
|
+
// Best-effort only.
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function reconcileAbandonedSessionStarts(omcRoot, currentSessionId) {
|
|
187
|
+
const sessionsDir = join(omcRoot, 'state', 'sessions');
|
|
188
|
+
if (!existsSync(sessionsDir)) return;
|
|
189
|
+
|
|
190
|
+
let entries = [];
|
|
191
|
+
try {
|
|
192
|
+
entries = readdirSync(sessionsDir);
|
|
193
|
+
} catch {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
for (const sessionId of entries) {
|
|
198
|
+
if (!SAFE_SESSION_ID_PATTERN.test(sessionId) || sessionId === currentSessionId) continue;
|
|
199
|
+
|
|
200
|
+
const marker = readJsonFile(sessionStartedMarkerPath(omcRoot, sessionId));
|
|
201
|
+
if (!marker || marker.session_id !== sessionId) continue;
|
|
202
|
+
|
|
203
|
+
if (existsSync(join(omcRoot, 'sessions', `${sessionId}.json`))) {
|
|
204
|
+
removeSessionStartedMarker(omcRoot, sessionId);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (!hasDurableAbandonmentEvidence(marker)) continue;
|
|
209
|
+
|
|
210
|
+
cleanupSessionModeState(omcRoot, sessionId);
|
|
211
|
+
cleanupMissionStateForSession(omcRoot, sessionId);
|
|
212
|
+
removeSessionStartedMarker(omcRoot, sessionId);
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
const sessionDir = sessionStateDir(omcRoot, sessionId);
|
|
216
|
+
if (readdirSync(sessionDir).length === 0) {
|
|
217
|
+
rmSync(sessionDir, { recursive: false, force: true });
|
|
218
|
+
}
|
|
219
|
+
} catch {
|
|
220
|
+
// Leave non-empty/unreadable directories untouched.
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
75
225
|
function getRuntimeBaseDir() {
|
|
76
226
|
return process.env.PLUGIN_ROOT || process.env.CLAUDE_PLUGIN_ROOT || join(__dirname, '..');
|
|
77
227
|
}
|
|
@@ -169,6 +319,21 @@ function semverCompare(a, b) {
|
|
|
169
319
|
|
|
170
320
|
const SESSION_START_CONTEXT_BUDGET = 6000;
|
|
171
321
|
const SESSION_START_OMISSION_NOTICE = '[Additional SessionStart context omitted to preserve the 6000-character aggregate budget.]';
|
|
322
|
+
const SESSION_STARTED_MARKER_FILE = 'session-started.json';
|
|
323
|
+
const SAFE_SESSION_ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/;
|
|
324
|
+
const LINUX_BOOT_ID_PATH = '/proc/sys/kernel/random/boot_id';
|
|
325
|
+
const SESSION_END_MODE_STATE_FILES = [
|
|
326
|
+
'autopilot-state.json',
|
|
327
|
+
'autoresearch-state.json',
|
|
328
|
+
'team-state.json',
|
|
329
|
+
'ralph-state.json',
|
|
330
|
+
'ultrawork-state.json',
|
|
331
|
+
'ultraqa-state.json',
|
|
332
|
+
'ralplan-state.json',
|
|
333
|
+
'deep-interview-state.json',
|
|
334
|
+
'self-improve-state.json',
|
|
335
|
+
'skill-active-state.json',
|
|
336
|
+
];
|
|
172
337
|
|
|
173
338
|
function compactBudgetedText(text, maxChars) {
|
|
174
339
|
const notice = '\n...[truncated to preserve SessionStart context budget]';
|
|
@@ -456,6 +621,9 @@ async function main() {
|
|
|
456
621
|
const messages = [];
|
|
457
622
|
const projectMemoryModules = await loadProjectMemoryModules();
|
|
458
623
|
|
|
624
|
+
writeSessionStartedMarker(omcRoot, directory, sessionId);
|
|
625
|
+
reconcileAbandonedSessionStarts(omcRoot, sessionId);
|
|
626
|
+
|
|
459
627
|
// Check for version drift between components
|
|
460
628
|
const driftInfo = detectVersionDrift();
|
|
461
629
|
if (driftInfo && shouldNotifyDrift(driftInfo)) {
|
package/skills/AGENTS.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# skills
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
30 skill directories for workflow automation and specialized behaviors.
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
9
9
|
|
|
@@ -31,18 +31,7 @@ Skills are reusable workflow templates that can be invoked via `/oh-my-copilot:s
|
|
|
31
31
|
| `plan/SKILL.md` | omc-plan | Strategic planning with interview workflow |
|
|
32
32
|
| `ralplan/SKILL.md` | ralplan | Iterative planning (Planner+Architect+Critic) with RALPLAN-DR structured deliberation (`--deliberate` for high-risk) |
|
|
33
33
|
| `deep-interview/SKILL.md` | deep-interview | Socratic deep interview with mathematical ambiguity gating (Ouroboros-inspired) |
|
|
34
|
-
| `
|
|
35
|
-
|
|
36
|
-
### Analysis Skills
|
|
37
|
-
|
|
38
|
-
| File | Skill | Purpose |
|
|
39
|
-
|-----------|-------|---------|
|
|
40
|
-
| `critique/SKILL.md` | critique | Pre-push adversarial critique of unpushed commits via independent devils-advocate agent |
|
|
41
|
-
| `deep-review/SKILL.md` | deep-review | Multi-pass code review with security, quality, structural analysis, and validation |
|
|
42
|
-
| `discover/SKILL.md` | discover | Spawn parallel specialist agents to scan the codebase and produce a prioritized improvement backlog |
|
|
43
|
-
| `trace/SKILL.md` | trace | Evidence-driven causal tracing with competing hypotheses |
|
|
44
|
-
| `verify/SKILL.md` | verify | Verify changes work before claiming completion |
|
|
45
|
-
| `debug/SKILL.md` | debug | Diagnose session or repo state using logs, traces, state, and focused reproduction |
|
|
34
|
+
| `ralph-init/SKILL.md` | ralph-init | Initialize PRD for structured ralph |
|
|
46
35
|
|
|
47
36
|
### Exploration Skills
|
|
48
37
|
|
|
@@ -50,8 +39,6 @@ Skills are reusable workflow templates that can be invoked via `/oh-my-copilot:s
|
|
|
50
39
|
|-----------|-------|---------|
|
|
51
40
|
| `deepinit/SKILL.md` | deepinit | Generate hierarchical AGENTS.md |
|
|
52
41
|
| `sciomc/SKILL.md` | sciomc | Parallel scientist orchestration |
|
|
53
|
-
| `external-context/SKILL.md` | external-context | Parallel document-specialist agents for external web searches and documentation lookup |
|
|
54
|
-
| `self-improve/SKILL.md` | self-improve | Autonomous evolutionary code improvement engine with tournament selection |
|
|
55
42
|
|
|
56
43
|
### Visual Skills
|
|
57
44
|
|
|
@@ -59,57 +46,23 @@ Skills are reusable workflow templates that can be invoked via `/oh-my-copilot:s
|
|
|
59
46
|
|-----------|-------|---------|
|
|
60
47
|
| `visual-verdict/SKILL.md` | visual-verdict | Structured visual QA verdict for screenshot/reference comparisons |
|
|
61
48
|
|
|
62
|
-
### Orchestration Skills
|
|
63
|
-
|
|
64
|
-
| File | Skill | Purpose |
|
|
65
|
-
|-----------|-------|---------|
|
|
66
|
-
| `cccg/SKILL.md` | cccg | Quadri-model orchestration — Claude, Codex, Gemini provide independent analysis, Copilot synthesizes |
|
|
67
|
-
| `omc-teams/SKILL.md` | omc-teams | CLI-team runtime for claude, codex, or gemini workers in tmux panes |
|
|
68
|
-
| `omc-reference/SKILL.md` | omc-reference | OMC agent catalog, tools, team pipeline routing, commit protocol, and skills registry |
|
|
69
|
-
|
|
70
|
-
### Notification Skills
|
|
71
|
-
|
|
72
|
-
| File | Skill | Purpose |
|
|
73
|
-
|-----------|-------|---------|
|
|
74
|
-
| `configure-notifications/SKILL.md` | configure-notifications | Configure notification integrations (Telegram, Discord, Slack, Teams) |
|
|
75
|
-
|
|
76
|
-
### Azure DevOps Skills
|
|
77
|
-
|
|
78
|
-
| File | Skill | Purpose |
|
|
79
|
-
|-----------|-------|---------|
|
|
80
|
-
| `omc-ado-setup/SKILL.md` | omc-ado-setup | Configure Azure DevOps integration |
|
|
81
|
-
| `omc-ado-review/SKILL.md` | omc-ado-review | Review Azure DevOps pull requests |
|
|
82
|
-
| `omc-ado-auto-review/SKILL.md` | omc-ado-auto-review | Automated Azure DevOps PR review |
|
|
83
|
-
| `omc-ado-sprint/SKILL.md` | omc-ado-sprint | Azure DevOps sprint management |
|
|
84
|
-
| `omc-ado-triage/SKILL.md` | omc-ado-triage | Azure DevOps work item triage |
|
|
85
|
-
|
|
86
|
-
### GitHub Skills
|
|
87
|
-
|
|
88
|
-
| File | Skill | Purpose |
|
|
89
|
-
|-----------|-------|---------|
|
|
90
|
-
| `omc-gh-setup/SKILL.md` | omc-gh-setup | Configure GitHub integration |
|
|
91
|
-
| `omc-gh-triage/SKILL.md` | omc-gh-triage | Issue/PR/CI triage dashboard |
|
|
92
|
-
| `omc-gh-review/SKILL.md` | omc-gh-review | Interactive PR review |
|
|
93
|
-
| `omc-gh-auto-review/SKILL.md` | omc-gh-auto-review | Automated PR code review |
|
|
94
|
-
| `omc-gh-project/SKILL.md` | omc-gh-project | GitHub Projects board management |
|
|
95
|
-
|
|
96
49
|
### Utility Skills
|
|
97
50
|
|
|
98
51
|
| File | Skill | Purpose |
|
|
99
52
|
|-----------|-------|---------|
|
|
100
53
|
| `ai-slop-cleaner/SKILL.md` | ai-slop-cleaner | Regression-safe cleanup workflow for AI-generated code slop |
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
54
|
+
| `skillify/SKILL.md` | skillify | Extract reusable skill from session |
|
|
55
|
+
| `learner/SKILL.md` | learner | Deprecated compatibility alias/internal implementation history for skillify |
|
|
56
|
+
| `ask/SKILL.md` | ask | Ask Claude, Codex, or Gemini via `omc ask` and capture an artifact |
|
|
57
|
+
| `note/SKILL.md` | note | Save notes for compaction resilience |
|
|
103
58
|
| `cancel/SKILL.md` | cancel | Cancel any active OMC mode |
|
|
104
|
-
| `hud/SKILL.md` | hud | Configure HUD display
|
|
59
|
+
| `hud/SKILL.md` | hud | Configure HUD display |
|
|
105
60
|
| `omc-doctor/SKILL.md` | omc-doctor | Diagnose installation issues |
|
|
106
|
-
| `remember/SKILL.md` | remember | Review reusable project knowledge and decide what belongs in project memory, notepad, or docs |
|
|
107
61
|
| `setup/SKILL.md` | setup | Unified setup entrypoint for install, diagnostics, and MCP configuration |
|
|
108
62
|
| `omc-setup/SKILL.md` | omc-setup | One-time setup wizard |
|
|
63
|
+
| `omc-help/SKILL.md` | omc-help | Usage guide |
|
|
109
64
|
| `mcp-setup/SKILL.md` | mcp-setup | Configure MCP servers |
|
|
110
65
|
| `skill/SKILL.md` | skill | Manage local skills |
|
|
111
|
-
| `skillify/SKILL.md` | skillify | Turn a repeatable workflow into a reusable OMC skill draft |
|
|
112
|
-
| `wiki/SKILL.md` | wiki | Persistent markdown knowledge base that compounds across sessions |
|
|
113
66
|
|
|
114
67
|
### Domain Skills
|
|
115
68
|
|
|
@@ -117,22 +70,7 @@ Skills are reusable workflow templates that can be invoked via `/oh-my-copilot:s
|
|
|
117
70
|
|-----------|-------|---------|
|
|
118
71
|
| `project-session-manager/SKILL.md` | project-session-manager (+ `psm` alias) | Isolated dev environments |
|
|
119
72
|
| `writer-memory/SKILL.md` | writer-memory | Agentic memory for writers |
|
|
120
|
-
| `release/SKILL.md` | release |
|
|
121
|
-
| `ralph-experiment/SKILL.md` | ralph-experiment | Hypothesis-driven experiment loop with structured notebook and git checkpoints |
|
|
122
|
-
|
|
123
|
-
## Permission Model
|
|
124
|
-
|
|
125
|
-
All plugin MCP tools use a **three-tier auto-approval system** so agents can operate without `/yolo`:
|
|
126
|
-
|
|
127
|
-
- **Tier 1** (read-only): LSP nav, code search, state/memory reads — always auto-approved via `readOnlyHint` annotation
|
|
128
|
-
- **Tier 2** (write): State/memory writes, AST replace, LSP rename — auto-approved via `permissions.allow` in `settings.local.json`
|
|
129
|
-
- **Tier 3** (destructive): `shared_memory_delete`, `shared_memory_cleanup`, `kill_job` — always prompt user
|
|
130
|
-
|
|
131
|
-
Safe bash patterns (git, npm, dotnet, gh, az, grep, find, ls) are auto-approved by the `permissionRequest` hook. Shell metacharacters are always rejected.
|
|
132
|
-
|
|
133
|
-
Deny escalation: 3 consecutive or 20 total denials stops the session. All decisions are audit-logged to `.omcp/logs/permissions.log`.
|
|
134
|
-
|
|
135
|
-
See [permission architecture](../docs/architecture/permissions.md) for details.
|
|
73
|
+
| `release/SKILL.md` | release | Generic release assistant — analyzes repo CI/rules, caches in `.omcp/RELEASE_RULE.md`, guides the release |
|
|
136
74
|
|
|
137
75
|
## For AI Agents
|
|
138
76
|
|
|
@@ -149,6 +87,10 @@ triggers:
|
|
|
149
87
|
- "keyword2"
|
|
150
88
|
agent: executor # Optional: which agent to use
|
|
151
89
|
model: sonnet # Optional: model override
|
|
90
|
+
pipeline: [skill-name, follow-up-skill] # Optional: standardized multi-skill flow
|
|
91
|
+
next-skill: follow-up-skill # Optional: explicit handoff target
|
|
92
|
+
next-skill-args: --direct # Optional: arguments for the next skill
|
|
93
|
+
handoff: .omcp/plans/example.md # Optional: artifact/context handed to next skill
|
|
152
94
|
---
|
|
153
95
|
|
|
154
96
|
# Skill Name
|
|
@@ -187,7 +129,7 @@ Any configurable options.
|
|
|
187
129
|
2. Define purpose, workflow, and usage
|
|
188
130
|
3. Add to skill registry (auto-detected from frontmatter)
|
|
189
131
|
4. Optionally add activation triggers
|
|
190
|
-
5. Create corresponding `
|
|
132
|
+
5. Create corresponding plugin-scoped skill/slash surface via `skills/new-skill/SKILL.md` (and generated artifacts when the build requires them)
|
|
191
133
|
6. Update `docs/REFERENCE.md` (Skills section, count)
|
|
192
134
|
7. If execution mode skill, also create `src/hooks/new-skill/` hook
|
|
193
135
|
|
|
@@ -202,6 +144,8 @@ Any configurable options.
|
|
|
202
144
|
4. Invoke `qa-tester` for verification
|
|
203
145
|
```
|
|
204
146
|
|
|
147
|
+
If `pipeline` / `next-skill` metadata is present, OMC appends a standardized **Skill Pipeline** handoff block to the rendered skill prompt so downstream steps are explicit.
|
|
148
|
+
|
|
205
149
|
**Conditional behavior:**
|
|
206
150
|
```markdown
|
|
207
151
|
## Workflow
|
|
@@ -232,18 +176,12 @@ None - pure markdown files.
|
|
|
232
176
|
|
|
233
177
|
| Category | Skills | Trigger Keywords |
|
|
234
178
|
|----------|--------|------------------|
|
|
235
|
-
| Execution | autopilot, ultrawork, ralph, team, ultraqa
|
|
236
|
-
|
|
|
237
|
-
|
|
|
238
|
-
| Exploration | deepinit, sciomc, external-context | "deepinit", "
|
|
239
|
-
|
|
|
240
|
-
|
|
|
241
|
-
| Cleanup | ai-slop-cleaner | "deslop", "anti-slop" |
|
|
242
|
-
| Azure DevOps | omc-ado-setup, omc-ado-review, omc-ado-auto-review, omc-ado-sprint, omc-ado-triage | "ado setup", "ado triage" |
|
|
243
|
-
| GitHub | omc-gh-setup, omc-gh-triage, omc-gh-review, omc-gh-auto-review, omc-gh-project | "gh setup", "gh triage", "gh review" |
|
|
244
|
-
| Notifications | configure-notifications | "configure discord", "setup telegram" |
|
|
245
|
-
| Utility | learner, ask, cancel, setup, omc-doctor, omc-setup, mcp-setup, skill, skillify, wiki, hud, remember | "cancelomc", "stopomc", "wiki", "skillify" |
|
|
246
|
-
| Domain | project-session-manager, writer-memory, release | psm context |
|
|
179
|
+
| Execution | autopilot, ultrawork, ralph, team, ultraqa | "autopilot", "ulw", "ralph", "team" |
|
|
180
|
+
| Cleanup | ai-slop-cleaner | "deslop", "anti-slop", cleanup/refactor + slop smells |
|
|
181
|
+
| Planning | omc-plan, ralplan, deep-interview, ralph-init | "plan this", "interview me", "ouroboros" |
|
|
182
|
+
| Exploration | deepinit, sciomc, external-context | "deepinit", "research" |
|
|
183
|
+
| Utility | skillify, learner (deprecated alias), note, cancel, hud, setup, omc-doctor, omc-setup, omc-help, mcp-setup | "stop", "cancel" |
|
|
184
|
+
| Domain | psm, writer-memory, release | psm context |
|
|
247
185
|
|
|
248
186
|
## Auto-Activation
|
|
249
187
|
|
|
@@ -255,13 +193,6 @@ Some skills activate automatically based on context:
|
|
|
255
193
|
| ultrawork | "ulw", "ultrawork" |
|
|
256
194
|
| ralph | "ralph", "don't stop until" |
|
|
257
195
|
| deep-interview | "deep interview", "interview me", "ouroboros", "don't assume" |
|
|
258
|
-
| critique | "critique", "review before push", "critique my changes" |
|
|
259
|
-
| self-improve | "self-improve" |
|
|
260
|
-
| ai-slop-cleaner | "deslop", "anti-slop", "clean slop" |
|
|
261
|
-
| discover | "discover" |
|
|
262
|
-
| trace | "trace" |
|
|
263
|
-
| verify | "verify" |
|
|
264
|
-
| wiki | "wiki" |
|
|
265
196
|
| cancel | "stop", "cancel", "abort" |
|
|
266
197
|
|
|
267
198
|
<!-- MANUAL:
|