oh-my-copilot 4.13.21 → 4.13.45
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 +8 -0
- package/agents/code-reviewer.agent.md +24 -6
- package/agents/designer.agent.md +12 -0
- package/bridge/cli.cjs +1978 -1214
- package/bridge/mcp-server.cjs +678 -261
- package/bridge/runtime-cli.cjs +55 -8
- package/bridge/team.js +507 -38
- package/dist/__tests__/agent-registry.test.js +92 -1
- package/dist/__tests__/agent-registry.test.js.map +1 -1
- package/dist/__tests__/bedrock-model-routing.test.js +18 -17
- package/dist/__tests__/bedrock-model-routing.test.js.map +1 -1
- package/dist/__tests__/delegation-enforcer.test.js +46 -6
- package/dist/__tests__/delegation-enforcer.test.js.map +1 -1
- package/dist/__tests__/hooks/session-end-cleanup.test.d.ts +2 -0
- package/dist/__tests__/hooks/session-end-cleanup.test.d.ts.map +1 -0
- package/dist/__tests__/hooks/session-end-cleanup.test.js +93 -0
- package/dist/__tests__/hooks/session-end-cleanup.test.js.map +1 -0
- package/dist/__tests__/hud/stdin.test.d.ts +2 -0
- package/dist/__tests__/hud/stdin.test.d.ts.map +1 -0
- package/dist/__tests__/hud/stdin.test.js +556 -0
- package/dist/__tests__/hud/stdin.test.js.map +1 -0
- package/dist/__tests__/model-routing-override-three-site-sync.test.d.ts +2 -0
- package/dist/__tests__/model-routing-override-three-site-sync.test.d.ts.map +1 -0
- package/dist/__tests__/model-routing-override-three-site-sync.test.js +75 -0
- package/dist/__tests__/model-routing-override-three-site-sync.test.js.map +1 -0
- package/dist/__tests__/non-claude-provider-detection.test.js +37 -0
- package/dist/__tests__/non-claude-provider-detection.test.js.map +1 -1
- package/dist/__tests__/package-dir-resolution-regression.test.js +25 -0
- package/dist/__tests__/package-dir-resolution-regression.test.js.map +1 -1
- package/dist/__tests__/pre-tool-enforcer.test.js +51 -0
- package/dist/__tests__/pre-tool-enforcer.test.js.map +1 -1
- package/dist/__tests__/session-start-script-context.test.js +121 -0
- package/dist/__tests__/session-start-script-context.test.js.map +1 -1
- package/dist/__tests__/setup-claude-md-script.test.js +44 -1
- package/dist/__tests__/setup-claude-md-script.test.js.map +1 -1
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +2 -1
- package/dist/agents/definitions.js.map +1 -1
- package/dist/autoresearch/__tests__/decide-outcome.test.d.ts +2 -0
- package/dist/autoresearch/__tests__/decide-outcome.test.d.ts.map +1 -0
- package/dist/autoresearch/__tests__/decide-outcome.test.js +69 -0
- package/dist/autoresearch/__tests__/decide-outcome.test.js.map +1 -0
- package/dist/autoresearch/runtime.d.ts.map +1 -1
- package/dist/autoresearch/runtime.js +16 -2
- package/dist/autoresearch/runtime.js.map +1 -1
- package/dist/cli/__tests__/launch.test.js +23 -0
- package/dist/cli/__tests__/launch.test.js.map +1 -1
- package/dist/cli/__tests__/self-improve-paths.test.js +3 -2
- package/dist/cli/__tests__/self-improve-paths.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +100 -0
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/commands/__tests__/team-role-shorthand.test.js +30 -0
- package/dist/cli/commands/__tests__/team-role-shorthand.test.js.map +1 -1
- package/dist/cli/commands/__tests__/team.test.js +48 -1
- package/dist/cli/commands/__tests__/team.test.js.map +1 -1
- package/dist/cli/commands/team.d.ts +2 -0
- package/dist/cli/commands/team.d.ts.map +1 -1
- package/dist/cli/commands/team.js +9 -2
- package/dist/cli/commands/team.js.map +1 -1
- package/dist/cli/launch.d.ts.map +1 -1
- package/dist/cli/launch.js +7 -0
- package/dist/cli/launch.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +34 -3
- package/dist/cli/team.js.map +1 -1
- package/dist/config/__tests__/loader.test.js +35 -4
- package/dist/config/__tests__/loader.test.js.map +1 -1
- package/dist/config/__tests__/models.test.js +126 -3
- package/dist/config/__tests__/models.test.js.map +1 -1
- package/dist/config/models.d.ts +8 -0
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +119 -8
- package/dist/config/models.js.map +1 -1
- package/dist/features/delegation-enforcer.d.ts.map +1 -1
- package/dist/features/delegation-enforcer.js +10 -9
- package/dist/features/delegation-enforcer.js.map +1 -1
- package/dist/hooks/__tests__/bridge-routing.test.js +1 -0
- package/dist/hooks/__tests__/bridge-routing.test.js.map +1 -1
- package/dist/hooks/autopilot/enforcement.d.ts.map +1 -1
- package/dist/hooks/autopilot/enforcement.js +19 -0
- package/dist/hooks/autopilot/enforcement.js.map +1 -1
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +26 -4
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/persistent-mode/stop-hook-blocking.test.js +37 -1
- package/dist/hooks/persistent-mode/stop-hook-blocking.test.js.map +1 -1
- package/dist/hooks/session-end/index.d.ts +9 -2
- package/dist/hooks/session-end/index.d.ts.map +1 -1
- package/dist/hooks/session-end/index.js +90 -35
- package/dist/hooks/session-end/index.js.map +1 -1
- package/dist/hud/stdin.d.ts +12 -1
- package/dist/hud/stdin.d.ts.map +1 -1
- package/dist/hud/stdin.js +123 -18
- package/dist/hud/stdin.js.map +1 -1
- package/dist/hud/types.d.ts +1 -0
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js.map +1 -1
- package/dist/installer/__tests__/session-start-template.test.d.ts +2 -0
- package/dist/installer/__tests__/session-start-template.test.d.ts.map +1 -0
- package/dist/installer/__tests__/session-start-template.test.js +174 -0
- package/dist/installer/__tests__/session-start-template.test.js.map +1 -0
- package/dist/lib/__tests__/mode-state-io.test.js +75 -12
- package/dist/lib/__tests__/mode-state-io.test.js.map +1 -1
- package/dist/lib/mode-state-io.d.ts +11 -0
- package/dist/lib/mode-state-io.d.ts.map +1 -1
- package/dist/lib/mode-state-io.js +64 -0
- package/dist/lib/mode-state-io.js.map +1 -1
- package/dist/lib/worktree-paths.d.ts +12 -0
- package/dist/lib/worktree-paths.d.ts.map +1 -1
- package/dist/lib/worktree-paths.js +75 -0
- package/dist/lib/worktree-paths.js.map +1 -1
- package/dist/planning/__tests__/artifacts.test.d.ts +2 -0
- package/dist/planning/__tests__/artifacts.test.d.ts.map +1 -0
- package/dist/planning/__tests__/artifacts.test.js +486 -0
- package/dist/planning/__tests__/artifacts.test.js.map +1 -0
- package/dist/planning/artifact-names.d.ts +13 -0
- package/dist/planning/artifact-names.d.ts.map +1 -0
- package/dist/planning/artifact-names.js +108 -0
- package/dist/planning/artifact-names.js.map +1 -0
- package/dist/planning/artifacts.d.ts +47 -0
- package/dist/planning/artifacts.d.ts.map +1 -0
- package/dist/planning/artifacts.js +221 -0
- package/dist/planning/artifacts.js.map +1 -0
- package/dist/team/__tests__/api-interop.compatibility.test.js +194 -5
- package/dist/team/__tests__/api-interop.compatibility.test.js.map +1 -1
- package/dist/team/__tests__/model-contract.test.js +92 -2
- package/dist/team/__tests__/model-contract.test.js.map +1 -1
- package/dist/team/__tests__/runtime-v2.dispatch.test.js +30 -0
- package/dist/team/__tests__/runtime-v2.dispatch.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +39 -1
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +6 -0
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +89 -2
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/delegation-evidence.d.ts +5 -0
- package/dist/team/delegation-evidence.d.ts.map +1 -0
- package/dist/team/delegation-evidence.js +29 -0
- package/dist/team/delegation-evidence.js.map +1 -0
- package/dist/team/model-contract.d.ts +8 -0
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +13 -0
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/runtime-v2.d.ts +2 -1
- package/dist/team/runtime-v2.d.ts.map +1 -1
- package/dist/team/runtime-v2.js +3 -1
- package/dist/team/runtime-v2.js.map +1 -1
- package/dist/team/state/tasks.d.ts +4 -1
- package/dist/team/state/tasks.d.ts.map +1 -1
- package/dist/team/state/tasks.js +38 -1
- package/dist/team/state/tasks.js.map +1 -1
- package/dist/team/team-ops.d.ts +4 -1
- package/dist/team/team-ops.d.ts.map +1 -1
- package/dist/team/team-ops.js +2 -2
- package/dist/team/team-ops.js.map +1 -1
- package/dist/team/types.d.ts +22 -1
- package/dist/team/types.d.ts.map +1 -1
- package/dist/team/types.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +6 -1
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/tools/__tests__/state-tools.test.js +322 -5
- package/dist/tools/__tests__/state-tools.test.js.map +1 -1
- package/dist/tools/__tests__/wiki-tools-working-directory.test.d.ts +2 -0
- package/dist/tools/__tests__/wiki-tools-working-directory.test.d.ts.map +1 -0
- package/dist/tools/__tests__/wiki-tools-working-directory.test.js +66 -0
- package/dist/tools/__tests__/wiki-tools-working-directory.test.js.map +1 -0
- package/dist/tools/state-tools.d.ts +3 -10
- package/dist/tools/state-tools.d.ts.map +1 -1
- package/dist/tools/state-tools.js +393 -91
- package/dist/tools/state-tools.js.map +1 -1
- package/dist/tools/wiki-tools.js +8 -8
- package/dist/tools/wiki-tools.js.map +1 -1
- package/docs/GETTING-STARTED.md +7 -0
- package/docs/copilot-instructions.md +1 -1
- package/package.json +1 -1
- package/scripts/lib/model-routing-override-message.mjs +21 -0
- package/scripts/persistent-mode.cjs +36 -0
- package/scripts/persistent-mode.mjs +36 -0
- package/scripts/post-tool-verifier.mjs +1 -0
- package/scripts/pre-tool-enforcer.mjs +60 -0
- package/scripts/session-start.mjs +63 -0
- package/scripts/setup-copilot-instructions.sh +12 -2
- package/skills/configure-notifications/SKILL.md +3 -3
- package/skills/mcp-setup/SKILL.md +60 -45
- package/skills/omc-setup/SKILL.md +3 -3
- package/skills/omc-setup/phases/01-install-claude-md.md +1 -1
- package/skills/omc-setup/phases/04-welcome.md +8 -8
- package/skills/project-session-manager/SKILL.md +2 -2
- package/skills/project-session-manager/psm.sh +1 -1
- package/templates/hooks/lib/model-routing-override-message.mjs +21 -0
- package/templates/hooks/session-start.mjs +62 -0
package/bridge/mcp-server.cjs
CHANGED
|
@@ -31100,6 +31100,66 @@ function validateWorkingDirectory(workingDirectory) {
|
|
|
31100
31100
|
}
|
|
31101
31101
|
return trustedRoot;
|
|
31102
31102
|
}
|
|
31103
|
+
function getGitCommonDir(cwd) {
|
|
31104
|
+
try {
|
|
31105
|
+
const commonDir = (0, import_child_process8.execSync)("git rev-parse --path-format=absolute --git-common-dir", {
|
|
31106
|
+
cwd,
|
|
31107
|
+
encoding: "utf-8",
|
|
31108
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
31109
|
+
timeout: 5e3
|
|
31110
|
+
}).trim();
|
|
31111
|
+
return (0, import_fs9.realpathSync)(commonDir);
|
|
31112
|
+
} catch {
|
|
31113
|
+
return null;
|
|
31114
|
+
}
|
|
31115
|
+
}
|
|
31116
|
+
function validateWorkingDirectoryOrLinkedWorktree(workingDirectory) {
|
|
31117
|
+
const trustedRoot = getWorktreeRoot(process.cwd()) || process.cwd();
|
|
31118
|
+
if (!workingDirectory) {
|
|
31119
|
+
return trustedRoot;
|
|
31120
|
+
}
|
|
31121
|
+
const resolved = (0, import_path11.resolve)(workingDirectory);
|
|
31122
|
+
let trustedRootReal;
|
|
31123
|
+
try {
|
|
31124
|
+
trustedRootReal = (0, import_fs9.realpathSync)(trustedRoot);
|
|
31125
|
+
} catch {
|
|
31126
|
+
trustedRootReal = trustedRoot;
|
|
31127
|
+
}
|
|
31128
|
+
const providedRoot = getWorktreeRoot(resolved);
|
|
31129
|
+
if (providedRoot) {
|
|
31130
|
+
let providedRootReal;
|
|
31131
|
+
try {
|
|
31132
|
+
providedRootReal = (0, import_fs9.realpathSync)(providedRoot);
|
|
31133
|
+
} catch {
|
|
31134
|
+
throw new Error(`workingDirectory '${workingDirectory}' does not exist or is not accessible.`);
|
|
31135
|
+
}
|
|
31136
|
+
if (providedRootReal === trustedRootReal) {
|
|
31137
|
+
return providedRoot;
|
|
31138
|
+
}
|
|
31139
|
+
const trustedCommonDir = getGitCommonDir(trustedRoot);
|
|
31140
|
+
const providedCommonDir = getGitCommonDir(providedRoot);
|
|
31141
|
+
if (trustedCommonDir && providedCommonDir && providedCommonDir === trustedCommonDir) {
|
|
31142
|
+
return providedRoot;
|
|
31143
|
+
}
|
|
31144
|
+
console.error("[worktree] workingDirectory resolved to different git worktree root, using trusted root", {
|
|
31145
|
+
workingDirectory: resolved,
|
|
31146
|
+
providedRoot: providedRootReal,
|
|
31147
|
+
trustedRoot: trustedRootReal
|
|
31148
|
+
});
|
|
31149
|
+
return trustedRoot;
|
|
31150
|
+
}
|
|
31151
|
+
let resolvedReal;
|
|
31152
|
+
try {
|
|
31153
|
+
resolvedReal = (0, import_fs9.realpathSync)(resolved);
|
|
31154
|
+
} catch {
|
|
31155
|
+
throw new Error(`workingDirectory '${workingDirectory}' does not exist or is not accessible.`);
|
|
31156
|
+
}
|
|
31157
|
+
const rel = (0, import_path11.relative)(trustedRootReal, resolvedReal);
|
|
31158
|
+
if (rel.startsWith("..") || (0, import_path11.isAbsolute)(rel)) {
|
|
31159
|
+
throw new Error(`workingDirectory '${workingDirectory}' is outside the trusted worktree root '${trustedRoot}'.`);
|
|
31160
|
+
}
|
|
31161
|
+
return trustedRoot;
|
|
31162
|
+
}
|
|
31103
31163
|
|
|
31104
31164
|
// src/tools/ast-tools.ts
|
|
31105
31165
|
var import_meta2 = {};
|
|
@@ -32450,7 +32510,8 @@ var pythonReplTool = {
|
|
|
32450
32510
|
};
|
|
32451
32511
|
|
|
32452
32512
|
// src/tools/state-tools.ts
|
|
32453
|
-
var
|
|
32513
|
+
var import_fs13 = require("fs");
|
|
32514
|
+
var import_path15 = require("path");
|
|
32454
32515
|
|
|
32455
32516
|
// src/lib/payload-limits.ts
|
|
32456
32517
|
var DEFAULT_PAYLOAD_LIMITS = {
|
|
@@ -32509,9 +32570,84 @@ function validatePayload(payload, limits = {}) {
|
|
|
32509
32570
|
return { valid: true };
|
|
32510
32571
|
}
|
|
32511
32572
|
|
|
32512
|
-
// src/
|
|
32573
|
+
// src/lib/mode-state-io.ts
|
|
32513
32574
|
var import_fs11 = require("fs");
|
|
32514
32575
|
var import_path13 = require("path");
|
|
32576
|
+
function getStateSessionOwner(state) {
|
|
32577
|
+
if (!state || typeof state !== "object") {
|
|
32578
|
+
return void 0;
|
|
32579
|
+
}
|
|
32580
|
+
const meta3 = state._meta;
|
|
32581
|
+
if (meta3 && typeof meta3 === "object") {
|
|
32582
|
+
const metaSessionId = meta3.sessionId;
|
|
32583
|
+
if (typeof metaSessionId === "string" && metaSessionId) {
|
|
32584
|
+
return metaSessionId;
|
|
32585
|
+
}
|
|
32586
|
+
}
|
|
32587
|
+
const topLevelSessionId = state.session_id;
|
|
32588
|
+
return typeof topLevelSessionId === "string" && topLevelSessionId ? topLevelSessionId : void 0;
|
|
32589
|
+
}
|
|
32590
|
+
function canClearStateForSession(state, sessionId) {
|
|
32591
|
+
const ownerSessionId = getStateSessionOwner(state);
|
|
32592
|
+
return !ownerSessionId || ownerSessionId === sessionId;
|
|
32593
|
+
}
|
|
32594
|
+
function resolveStateRoot(directory) {
|
|
32595
|
+
const baseDir = directory || process.cwd();
|
|
32596
|
+
return getWorktreeRoot(baseDir) || baseDir;
|
|
32597
|
+
}
|
|
32598
|
+
function hasSessionEndSummary(baseDir, sessionId) {
|
|
32599
|
+
return (0, import_fs11.existsSync)((0, import_path13.join)(getOmcRoot(baseDir), "sessions", `${sessionId}.json`));
|
|
32600
|
+
}
|
|
32601
|
+
function findSessionOwnedStateFiles(mode, sessionId, directory) {
|
|
32602
|
+
const matches = /* @__PURE__ */ new Set();
|
|
32603
|
+
const baseDir = resolveStateRoot(directory);
|
|
32604
|
+
const expectedPath = resolveSessionStatePath(mode, sessionId, baseDir);
|
|
32605
|
+
if ((0, import_fs11.existsSync)(expectedPath)) {
|
|
32606
|
+
matches.add(expectedPath);
|
|
32607
|
+
}
|
|
32608
|
+
for (const sid of listSessionIds(baseDir)) {
|
|
32609
|
+
const candidatePath = resolveSessionStatePath(mode, sid, baseDir);
|
|
32610
|
+
if (!(0, import_fs11.existsSync)(candidatePath)) {
|
|
32611
|
+
continue;
|
|
32612
|
+
}
|
|
32613
|
+
try {
|
|
32614
|
+
const raw = JSON.parse((0, import_fs11.readFileSync)(candidatePath, "utf-8"));
|
|
32615
|
+
if (getStateSessionOwner(raw) === sessionId) {
|
|
32616
|
+
matches.add(candidatePath);
|
|
32617
|
+
}
|
|
32618
|
+
} catch {
|
|
32619
|
+
}
|
|
32620
|
+
}
|
|
32621
|
+
return [...matches];
|
|
32622
|
+
}
|
|
32623
|
+
function findCompletedSessionStateFiles(mode, directory, requesterSessionId) {
|
|
32624
|
+
const matches = /* @__PURE__ */ new Set();
|
|
32625
|
+
const baseDir = resolveStateRoot(directory);
|
|
32626
|
+
for (const sid of listSessionIds(baseDir)) {
|
|
32627
|
+
if (requesterSessionId && sid === requesterSessionId) {
|
|
32628
|
+
continue;
|
|
32629
|
+
}
|
|
32630
|
+
if (!hasSessionEndSummary(baseDir, sid)) {
|
|
32631
|
+
continue;
|
|
32632
|
+
}
|
|
32633
|
+
const candidatePath = resolveSessionStatePath(mode, sid, baseDir);
|
|
32634
|
+
if (!(0, import_fs11.existsSync)(candidatePath)) {
|
|
32635
|
+
continue;
|
|
32636
|
+
}
|
|
32637
|
+
try {
|
|
32638
|
+
const raw = JSON.parse((0, import_fs11.readFileSync)(candidatePath, "utf-8"));
|
|
32639
|
+
if (raw.active === true) {
|
|
32640
|
+
matches.add(candidatePath);
|
|
32641
|
+
}
|
|
32642
|
+
} catch {
|
|
32643
|
+
}
|
|
32644
|
+
}
|
|
32645
|
+
return [...matches];
|
|
32646
|
+
}
|
|
32647
|
+
|
|
32648
|
+
// src/hooks/mode-registry/index.ts
|
|
32649
|
+
var import_fs12 = require("fs");
|
|
32650
|
+
var import_path14 = require("path");
|
|
32515
32651
|
|
|
32516
32652
|
// src/lib/mode-names.ts
|
|
32517
32653
|
var MODE_NAMES = {
|
|
@@ -32619,26 +32755,26 @@ var MODE_CONFIGS = {
|
|
|
32619
32755
|
};
|
|
32620
32756
|
var EXCLUSIVE_MODES = [MODE_NAMES.AUTOPILOT, MODE_NAMES.AUTORESEARCH];
|
|
32621
32757
|
function getStateDir(cwd) {
|
|
32622
|
-
return (0,
|
|
32758
|
+
return (0, import_path14.join)(getOmcRoot(cwd), "state");
|
|
32623
32759
|
}
|
|
32624
32760
|
function getStateFilePath(cwd, mode, sessionId) {
|
|
32625
32761
|
const config2 = MODE_CONFIGS[mode];
|
|
32626
32762
|
if (sessionId) {
|
|
32627
32763
|
return resolveSessionStatePath(mode, sessionId, cwd);
|
|
32628
32764
|
}
|
|
32629
|
-
return (0,
|
|
32765
|
+
return (0, import_path14.join)(getStateDir(cwd), config2.stateFile);
|
|
32630
32766
|
}
|
|
32631
32767
|
function getMarkerFilePath(cwd, mode) {
|
|
32632
32768
|
const config2 = MODE_CONFIGS[mode];
|
|
32633
32769
|
if (!config2.markerFile) return null;
|
|
32634
|
-
return (0,
|
|
32770
|
+
return (0, import_path14.join)(getStateDir(cwd), config2.markerFile);
|
|
32635
32771
|
}
|
|
32636
32772
|
var WORKFLOW_SLOT_TOMBSTONE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
32637
32773
|
function isWorkflowSlotTombstonedForMode(cwd, mode, sessionId, now = Date.now()) {
|
|
32638
32774
|
try {
|
|
32639
|
-
const ledgerPath = sessionId ? resolveSessionStatePath("skill-active", sessionId, cwd) : (0,
|
|
32640
|
-
if (!(0,
|
|
32641
|
-
const raw = JSON.parse((0,
|
|
32775
|
+
const ledgerPath = sessionId ? resolveSessionStatePath("skill-active", sessionId, cwd) : (0, import_path14.join)(getStateDir(cwd), "skill-active-state.json");
|
|
32776
|
+
if (!(0, import_fs12.existsSync)(ledgerPath)) return false;
|
|
32777
|
+
const raw = JSON.parse((0, import_fs12.readFileSync)(ledgerPath, "utf-8"));
|
|
32642
32778
|
const slots = raw.active_skills;
|
|
32643
32779
|
if (!slots || typeof slots !== "object") return false;
|
|
32644
32780
|
const slot = slots[mode];
|
|
@@ -32661,7 +32797,7 @@ function isJsonModeActive(cwd, mode, sessionId) {
|
|
|
32661
32797
|
}
|
|
32662
32798
|
const sessionStateFile = resolveSessionStatePath(mode, sessionId, cwd);
|
|
32663
32799
|
try {
|
|
32664
|
-
const content = (0,
|
|
32800
|
+
const content = (0, import_fs12.readFileSync)(sessionStateFile, "utf-8");
|
|
32665
32801
|
const state = JSON.parse(content);
|
|
32666
32802
|
if (state.session_id && state.session_id !== sessionId) {
|
|
32667
32803
|
return false;
|
|
@@ -32679,7 +32815,7 @@ function isJsonModeActive(cwd, mode, sessionId) {
|
|
|
32679
32815
|
}
|
|
32680
32816
|
const stateFile = getStateFilePath(cwd, mode);
|
|
32681
32817
|
try {
|
|
32682
|
-
const content = (0,
|
|
32818
|
+
const content = (0, import_fs12.readFileSync)(stateFile, "utf-8");
|
|
32683
32819
|
const state = JSON.parse(content);
|
|
32684
32820
|
if (config2.activeProperty) {
|
|
32685
32821
|
return state[config2.activeProperty] === true;
|
|
@@ -32719,7 +32855,7 @@ function clearModeState(mode, cwd, sessionId) {
|
|
|
32719
32855
|
if (isSessionScopedClear && sessionId) {
|
|
32720
32856
|
const sessionStateFile = resolveSessionStatePath(mode, sessionId, cwd);
|
|
32721
32857
|
try {
|
|
32722
|
-
(0,
|
|
32858
|
+
(0, import_fs12.unlinkSync)(sessionStateFile);
|
|
32723
32859
|
} catch (err) {
|
|
32724
32860
|
if (err.code !== "ENOENT") {
|
|
32725
32861
|
success2 = false;
|
|
@@ -32733,7 +32869,7 @@ function clearModeState(mode, cwd, sessionId) {
|
|
|
32733
32869
|
cwd
|
|
32734
32870
|
);
|
|
32735
32871
|
try {
|
|
32736
|
-
(0,
|
|
32872
|
+
(0, import_fs12.unlinkSync)(sessionMarkerFile);
|
|
32737
32873
|
} catch (err) {
|
|
32738
32874
|
if (err.code !== "ENOENT") {
|
|
32739
32875
|
success2 = false;
|
|
@@ -32742,11 +32878,11 @@ function clearModeState(mode, cwd, sessionId) {
|
|
|
32742
32878
|
}
|
|
32743
32879
|
if (markerFile) {
|
|
32744
32880
|
try {
|
|
32745
|
-
const markerRaw = JSON.parse((0,
|
|
32881
|
+
const markerRaw = JSON.parse((0, import_fs12.readFileSync)(markerFile, "utf-8"));
|
|
32746
32882
|
const markerSessionId = markerRaw.session_id ?? markerRaw.sessionId;
|
|
32747
32883
|
if (!markerSessionId || markerSessionId === sessionId) {
|
|
32748
32884
|
try {
|
|
32749
|
-
(0,
|
|
32885
|
+
(0, import_fs12.unlinkSync)(markerFile);
|
|
32750
32886
|
} catch (err) {
|
|
32751
32887
|
if (err.code !== "ENOENT") {
|
|
32752
32888
|
success2 = false;
|
|
@@ -32755,7 +32891,7 @@ function clearModeState(mode, cwd, sessionId) {
|
|
|
32755
32891
|
}
|
|
32756
32892
|
} catch {
|
|
32757
32893
|
try {
|
|
32758
|
-
(0,
|
|
32894
|
+
(0, import_fs12.unlinkSync)(markerFile);
|
|
32759
32895
|
} catch (err) {
|
|
32760
32896
|
if (err.code !== "ENOENT") {
|
|
32761
32897
|
success2 = false;
|
|
@@ -32767,7 +32903,7 @@ function clearModeState(mode, cwd, sessionId) {
|
|
|
32767
32903
|
const stateFile = getStateFilePath(cwd, mode);
|
|
32768
32904
|
if (!isSessionScopedClear) {
|
|
32769
32905
|
try {
|
|
32770
|
-
(0,
|
|
32906
|
+
(0, import_fs12.unlinkSync)(stateFile);
|
|
32771
32907
|
} catch (err) {
|
|
32772
32908
|
if (err.code !== "ENOENT") {
|
|
32773
32909
|
success2 = false;
|
|
@@ -32777,11 +32913,11 @@ function clearModeState(mode, cwd, sessionId) {
|
|
|
32777
32913
|
if (markerFile) {
|
|
32778
32914
|
if (isSessionScopedClear) {
|
|
32779
32915
|
try {
|
|
32780
|
-
const markerRaw = JSON.parse((0,
|
|
32916
|
+
const markerRaw = JSON.parse((0, import_fs12.readFileSync)(markerFile, "utf-8"));
|
|
32781
32917
|
const markerSessionId = markerRaw.session_id ?? markerRaw.sessionId;
|
|
32782
32918
|
if (!markerSessionId || markerSessionId === sessionId) {
|
|
32783
32919
|
try {
|
|
32784
|
-
(0,
|
|
32920
|
+
(0, import_fs12.unlinkSync)(markerFile);
|
|
32785
32921
|
} catch (err) {
|
|
32786
32922
|
if (err.code !== "ENOENT") {
|
|
32787
32923
|
success2 = false;
|
|
@@ -32790,7 +32926,7 @@ function clearModeState(mode, cwd, sessionId) {
|
|
|
32790
32926
|
}
|
|
32791
32927
|
} catch {
|
|
32792
32928
|
try {
|
|
32793
|
-
(0,
|
|
32929
|
+
(0, import_fs12.unlinkSync)(markerFile);
|
|
32794
32930
|
} catch (err) {
|
|
32795
32931
|
if (err.code !== "ENOENT") {
|
|
32796
32932
|
success2 = false;
|
|
@@ -32799,7 +32935,7 @@ function clearModeState(mode, cwd, sessionId) {
|
|
|
32799
32935
|
}
|
|
32800
32936
|
} else {
|
|
32801
32937
|
try {
|
|
32802
|
-
(0,
|
|
32938
|
+
(0, import_fs12.unlinkSync)(markerFile);
|
|
32803
32939
|
} catch (err) {
|
|
32804
32940
|
if (err.code !== "ENOENT") {
|
|
32805
32941
|
success2 = false;
|
|
@@ -32833,12 +32969,165 @@ var STATE_TOOL_MODES = [
|
|
|
32833
32969
|
];
|
|
32834
32970
|
var EXTRA_STATE_ONLY_MODES = ["ralplan", "omc-teams", "skill-active"];
|
|
32835
32971
|
var CANCEL_SIGNAL_TTL_MS = 3e4;
|
|
32972
|
+
function readTeamNamesFromStateFile(statePath) {
|
|
32973
|
+
if (!(0, import_fs13.existsSync)(statePath)) return [];
|
|
32974
|
+
try {
|
|
32975
|
+
const raw = JSON.parse((0, import_fs13.readFileSync)(statePath, "utf-8"));
|
|
32976
|
+
const teamName = typeof raw.team_name === "string" ? raw.team_name.trim() : typeof raw.teamName === "string" ? raw.teamName.trim() : "";
|
|
32977
|
+
return teamName ? [teamName] : [];
|
|
32978
|
+
} catch {
|
|
32979
|
+
return [];
|
|
32980
|
+
}
|
|
32981
|
+
}
|
|
32982
|
+
function pruneMissionBoardTeams(root, teamNames) {
|
|
32983
|
+
const missionStatePath = (0, import_path15.join)(getOmcRoot(root), "state", "mission-state.json");
|
|
32984
|
+
if (!(0, import_fs13.existsSync)(missionStatePath)) return 0;
|
|
32985
|
+
try {
|
|
32986
|
+
const parsed = JSON.parse((0, import_fs13.readFileSync)(missionStatePath, "utf-8"));
|
|
32987
|
+
if (!Array.isArray(parsed.missions)) return 0;
|
|
32988
|
+
const shouldRemoveAll = teamNames == null;
|
|
32989
|
+
const teamNameSet = new Set(teamNames ?? []);
|
|
32990
|
+
const remainingMissions = parsed.missions.filter((mission) => {
|
|
32991
|
+
if (mission.source !== "team") return true;
|
|
32992
|
+
if (shouldRemoveAll) return false;
|
|
32993
|
+
const missionTeamName = typeof mission.teamName === "string" ? mission.teamName.trim() : typeof mission.name === "string" ? mission.name.trim() : "";
|
|
32994
|
+
return !missionTeamName || !teamNameSet.has(missionTeamName);
|
|
32995
|
+
});
|
|
32996
|
+
const removed = parsed.missions.length - remainingMissions.length;
|
|
32997
|
+
if (removed > 0) {
|
|
32998
|
+
(0, import_fs13.writeFileSync)(missionStatePath, JSON.stringify({
|
|
32999
|
+
...parsed,
|
|
33000
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
33001
|
+
missions: remainingMissions
|
|
33002
|
+
}, null, 2));
|
|
33003
|
+
}
|
|
33004
|
+
return removed;
|
|
33005
|
+
} catch {
|
|
33006
|
+
return 0;
|
|
33007
|
+
}
|
|
33008
|
+
}
|
|
33009
|
+
function cleanupTeamRuntimeState(root, teamNames) {
|
|
33010
|
+
const teamStateRoot = (0, import_path15.join)(getOmcRoot(root), "state", "team");
|
|
33011
|
+
if (!(0, import_fs13.existsSync)(teamStateRoot)) return 0;
|
|
33012
|
+
const shouldRemoveAll = teamNames == null;
|
|
33013
|
+
let removed = 0;
|
|
33014
|
+
if (shouldRemoveAll) {
|
|
33015
|
+
try {
|
|
33016
|
+
(0, import_fs13.rmSync)(teamStateRoot, { recursive: true, force: true });
|
|
33017
|
+
return 1;
|
|
33018
|
+
} catch {
|
|
33019
|
+
return 0;
|
|
33020
|
+
}
|
|
33021
|
+
}
|
|
33022
|
+
for (const teamName of teamNames ?? []) {
|
|
33023
|
+
if (!teamName) continue;
|
|
33024
|
+
try {
|
|
33025
|
+
(0, import_fs13.rmSync)((0, import_path15.join)(teamStateRoot, teamName), { recursive: true, force: true });
|
|
33026
|
+
removed += 1;
|
|
33027
|
+
} catch {
|
|
33028
|
+
}
|
|
33029
|
+
}
|
|
33030
|
+
return removed;
|
|
33031
|
+
}
|
|
32836
33032
|
function getStatePath(mode, root) {
|
|
32837
33033
|
if (MODE_CONFIGS[mode]) {
|
|
32838
33034
|
return getStateFilePath(root, mode);
|
|
32839
33035
|
}
|
|
32840
33036
|
return resolveStatePath(mode, root);
|
|
32841
33037
|
}
|
|
33038
|
+
function getLegacyStateFileCandidates(mode, root) {
|
|
33039
|
+
const normalizedName = mode.endsWith("-state") ? mode : `${mode}-state`;
|
|
33040
|
+
const candidates = [
|
|
33041
|
+
getStatePath(mode, root),
|
|
33042
|
+
(0, import_path15.join)(getOmcRoot(root), `${normalizedName}.json`)
|
|
33043
|
+
];
|
|
33044
|
+
return [...new Set(candidates)];
|
|
33045
|
+
}
|
|
33046
|
+
function clearLegacyStateCandidates(mode, root, sessionId) {
|
|
33047
|
+
let cleared = 0;
|
|
33048
|
+
let hadFailure = false;
|
|
33049
|
+
for (const legacyPath of getLegacyStateFileCandidates(mode, root)) {
|
|
33050
|
+
if (!(0, import_fs13.existsSync)(legacyPath)) {
|
|
33051
|
+
continue;
|
|
33052
|
+
}
|
|
33053
|
+
try {
|
|
33054
|
+
if (sessionId) {
|
|
33055
|
+
const raw = JSON.parse((0, import_fs13.readFileSync)(legacyPath, "utf-8"));
|
|
33056
|
+
if (!canClearStateForSession(raw, sessionId)) {
|
|
33057
|
+
continue;
|
|
33058
|
+
}
|
|
33059
|
+
}
|
|
33060
|
+
(0, import_fs13.unlinkSync)(legacyPath);
|
|
33061
|
+
cleared++;
|
|
33062
|
+
} catch {
|
|
33063
|
+
hadFailure = true;
|
|
33064
|
+
}
|
|
33065
|
+
}
|
|
33066
|
+
return { cleared, hadFailure };
|
|
33067
|
+
}
|
|
33068
|
+
function clearSessionOwnedStateCandidates(mode, root, sessionId) {
|
|
33069
|
+
let cleared = 0;
|
|
33070
|
+
let hadFailure = false;
|
|
33071
|
+
const paths = findSessionOwnedStateFiles(mode, sessionId, root);
|
|
33072
|
+
for (const statePath of paths) {
|
|
33073
|
+
try {
|
|
33074
|
+
(0, import_fs13.unlinkSync)(statePath);
|
|
33075
|
+
cleared++;
|
|
33076
|
+
} catch {
|
|
33077
|
+
hadFailure = true;
|
|
33078
|
+
}
|
|
33079
|
+
}
|
|
33080
|
+
return { cleared, hadFailure, paths };
|
|
33081
|
+
}
|
|
33082
|
+
function clearCompletedSessionStateCandidates(mode, root, requesterSessionId) {
|
|
33083
|
+
let cleared = 0;
|
|
33084
|
+
let hadFailure = false;
|
|
33085
|
+
const paths = findCompletedSessionStateFiles(mode, root, requesterSessionId);
|
|
33086
|
+
for (const statePath of paths) {
|
|
33087
|
+
try {
|
|
33088
|
+
(0, import_fs13.unlinkSync)(statePath);
|
|
33089
|
+
cleared++;
|
|
33090
|
+
} catch {
|
|
33091
|
+
hadFailure = true;
|
|
33092
|
+
}
|
|
33093
|
+
}
|
|
33094
|
+
return { cleared, hadFailure, paths };
|
|
33095
|
+
}
|
|
33096
|
+
function getModeRuntimeArtifactNames(mode) {
|
|
33097
|
+
return [
|
|
33098
|
+
`${mode}-stop-breaker.json`,
|
|
33099
|
+
`${mode}-last-steer-at`,
|
|
33100
|
+
`${mode}-continue-steer.lock`
|
|
33101
|
+
];
|
|
33102
|
+
}
|
|
33103
|
+
function clearModeRuntimeArtifacts(mode, root, sessionId) {
|
|
33104
|
+
let cleared = 0;
|
|
33105
|
+
let hadFailure = false;
|
|
33106
|
+
const stateRoot = (0, import_path15.join)(getOmcRoot(root), "state");
|
|
33107
|
+
const candidateDirs = /* @__PURE__ */ new Set([stateRoot]);
|
|
33108
|
+
if (sessionId) {
|
|
33109
|
+
candidateDirs.add((0, import_path15.join)(stateRoot, "sessions", sessionId));
|
|
33110
|
+
} else {
|
|
33111
|
+
for (const sid of listSessionIds(root)) {
|
|
33112
|
+
candidateDirs.add((0, import_path15.join)(stateRoot, "sessions", sid));
|
|
33113
|
+
}
|
|
33114
|
+
}
|
|
33115
|
+
for (const dir of candidateDirs) {
|
|
33116
|
+
for (const artifactName of getModeRuntimeArtifactNames(mode)) {
|
|
33117
|
+
const artifactPath = (0, import_path15.join)(dir, artifactName);
|
|
33118
|
+
if (!(0, import_fs13.existsSync)(artifactPath)) {
|
|
33119
|
+
continue;
|
|
33120
|
+
}
|
|
33121
|
+
try {
|
|
33122
|
+
(0, import_fs13.unlinkSync)(artifactPath);
|
|
33123
|
+
cleared++;
|
|
33124
|
+
} catch {
|
|
33125
|
+
hadFailure = true;
|
|
33126
|
+
}
|
|
33127
|
+
}
|
|
33128
|
+
}
|
|
33129
|
+
return { cleared, hadFailure };
|
|
33130
|
+
}
|
|
32842
33131
|
function writeSessionCancelSignal(root, sessionId, mode) {
|
|
32843
33132
|
const now = Date.now();
|
|
32844
33133
|
const cancelSignalPath = resolveSessionStatePath("cancel-signal", sessionId, root);
|
|
@@ -32855,11 +33144,11 @@ function isSessionModeActive(mode, root, sessionId) {
|
|
|
32855
33144
|
return isModeActive(mode, root, sessionId);
|
|
32856
33145
|
}
|
|
32857
33146
|
const statePath = resolveSessionStatePath(mode, sessionId, root);
|
|
32858
|
-
if (!(0,
|
|
33147
|
+
if (!(0, import_fs13.existsSync)(statePath)) {
|
|
32859
33148
|
return false;
|
|
32860
33149
|
}
|
|
32861
33150
|
try {
|
|
32862
|
-
const state = JSON.parse((0,
|
|
33151
|
+
const state = JSON.parse((0, import_fs13.readFileSync)(statePath, "utf-8"));
|
|
32863
33152
|
return state.active === true;
|
|
32864
33153
|
} catch {
|
|
32865
33154
|
return false;
|
|
@@ -32886,7 +33175,31 @@ var stateReadTool = {
|
|
|
32886
33175
|
if (sessionId) {
|
|
32887
33176
|
validateSessionId(sessionId);
|
|
32888
33177
|
const statePath2 = MODE_CONFIGS[mode] ? getStateFilePath(root, mode, sessionId) : resolveSessionStatePath(mode, sessionId, root);
|
|
32889
|
-
if (!(0,
|
|
33178
|
+
if (!(0, import_fs13.existsSync)(statePath2)) {
|
|
33179
|
+
const completedSessionPaths = findCompletedSessionStateFiles(mode, root, sessionId);
|
|
33180
|
+
if (completedSessionPaths.length > 0) {
|
|
33181
|
+
const orphanList = completedSessionPaths.map((orphanPath) => {
|
|
33182
|
+
const sessionMarker = `${(0, import_path15.join)("state", "sessions")}/`;
|
|
33183
|
+
const markerIndex = orphanPath.indexOf(sessionMarker);
|
|
33184
|
+
if (markerIndex === -1) return `- ${orphanPath}`;
|
|
33185
|
+
const rest = orphanPath.slice(markerIndex + sessionMarker.length);
|
|
33186
|
+
const orphanSessionId = rest.split(/[\\/]/)[0] || "unknown";
|
|
33187
|
+
return `- session: ${orphanSessionId}
|
|
33188
|
+
path: ${orphanPath}`;
|
|
33189
|
+
}).join("\n");
|
|
33190
|
+
return {
|
|
33191
|
+
content: [{
|
|
33192
|
+
type: "text",
|
|
33193
|
+
text: `No state found for mode: ${mode} in session: ${sessionId}
|
|
33194
|
+
Expected path: ${statePath2}
|
|
33195
|
+
|
|
33196
|
+
Discovered ${completedSessionPaths.length} completed-session orphan state file${completedSessionPaths.length === 1 ? "" : "s"} for this mode:
|
|
33197
|
+
${orphanList}
|
|
33198
|
+
|
|
33199
|
+
Run state_clear(mode="${mode}", session_id="${sessionId}") to clear the current session plus these completed-session orphan files.`
|
|
33200
|
+
}]
|
|
33201
|
+
};
|
|
33202
|
+
}
|
|
32890
33203
|
return {
|
|
32891
33204
|
content: [{
|
|
32892
33205
|
type: "text",
|
|
@@ -32895,7 +33208,7 @@ Expected path: ${statePath2}`
|
|
|
32895
33208
|
}]
|
|
32896
33209
|
};
|
|
32897
33210
|
}
|
|
32898
|
-
const content = (0,
|
|
33211
|
+
const content = (0, import_fs13.readFileSync)(statePath2, "utf-8");
|
|
32899
33212
|
const state = JSON.parse(content);
|
|
32900
33213
|
return {
|
|
32901
33214
|
content: [{
|
|
@@ -32911,12 +33224,12 @@ ${JSON.stringify(state, null, 2)}
|
|
|
32911
33224
|
};
|
|
32912
33225
|
}
|
|
32913
33226
|
const statePath = getStatePath(mode, root);
|
|
32914
|
-
const legacyExists = (0,
|
|
33227
|
+
const legacyExists = (0, import_fs13.existsSync)(statePath);
|
|
32915
33228
|
const sessionIds = listSessionIds(root);
|
|
32916
33229
|
const activeSessions = [];
|
|
32917
33230
|
for (const sid of sessionIds) {
|
|
32918
33231
|
const sessionStatePath = MODE_CONFIGS[mode] ? getStateFilePath(root, mode, sid) : resolveSessionStatePath(mode, sid, root);
|
|
32919
|
-
if ((0,
|
|
33232
|
+
if ((0, import_fs13.existsSync)(sessionStatePath)) {
|
|
32920
33233
|
activeSessions.push(sid);
|
|
32921
33234
|
}
|
|
32922
33235
|
}
|
|
@@ -32939,7 +33252,7 @@ Note: Reading from legacy/aggregate path (no session_id). This may include state
|
|
|
32939
33252
|
`;
|
|
32940
33253
|
if (legacyExists) {
|
|
32941
33254
|
try {
|
|
32942
|
-
const content = (0,
|
|
33255
|
+
const content = (0, import_fs13.readFileSync)(statePath, "utf-8");
|
|
32943
33256
|
const state = JSON.parse(content);
|
|
32944
33257
|
output += `### Legacy Path (shared)
|
|
32945
33258
|
Path: ${statePath}
|
|
@@ -32964,7 +33277,7 @@ Path: ${statePath}
|
|
|
32964
33277
|
for (const sid of activeSessions) {
|
|
32965
33278
|
const sessionStatePath = MODE_CONFIGS[mode] ? getStateFilePath(root, mode, sid) : resolveSessionStatePath(mode, sid, root);
|
|
32966
33279
|
try {
|
|
32967
|
-
const content = (0,
|
|
33280
|
+
const content = (0, import_fs13.readFileSync)(sessionStatePath, "utf-8");
|
|
32968
33281
|
const state = JSON.parse(content);
|
|
32969
33282
|
output += `**Session: ${sid}**
|
|
32970
33283
|
Path: ${sessionStatePath}
|
|
@@ -33120,124 +33433,209 @@ var stateClearTool = {
|
|
|
33120
33433
|
session_id: external_exports3.string().optional().describe("Session ID for session-scoped state isolation. When provided, the tool operates only within that session. When omitted, the tool aggregates legacy state plus all session-scoped state (may include other sessions).")
|
|
33121
33434
|
},
|
|
33122
33435
|
handler: async (args) => {
|
|
33123
|
-
const {
|
|
33436
|
+
const { workingDirectory, session_id } = args;
|
|
33437
|
+
const mode = args.mode;
|
|
33124
33438
|
try {
|
|
33125
33439
|
const root = validateWorkingDirectory(workingDirectory);
|
|
33126
33440
|
const sessionId = session_id;
|
|
33441
|
+
const cleanedTeamNames = /* @__PURE__ */ new Set();
|
|
33442
|
+
const collectTeamNamesForCleanup = (statePath) => {
|
|
33443
|
+
if (mode !== "team") return;
|
|
33444
|
+
for (const teamName of readTeamNamesFromStateFile(statePath)) {
|
|
33445
|
+
cleanedTeamNames.add(teamName);
|
|
33446
|
+
}
|
|
33447
|
+
};
|
|
33127
33448
|
if (sessionId) {
|
|
33128
33449
|
validateSessionId(sessionId);
|
|
33450
|
+
const requestedSessionOwnedPaths = findSessionOwnedStateFiles(mode, sessionId, root);
|
|
33451
|
+
for (const teamStatePath of findSessionOwnedStateFiles("team", sessionId, root)) {
|
|
33452
|
+
collectTeamNamesForCleanup(teamStatePath);
|
|
33453
|
+
}
|
|
33454
|
+
if (mode === "team") {
|
|
33455
|
+
for (const teamStatePath of findCompletedSessionStateFiles("team", root, sessionId)) {
|
|
33456
|
+
collectTeamNamesForCleanup(teamStatePath);
|
|
33457
|
+
}
|
|
33458
|
+
}
|
|
33459
|
+
const completedSessionCleanup = clearCompletedSessionStateCandidates(mode, root, sessionId);
|
|
33460
|
+
const runtimeCleanup2 = clearModeRuntimeArtifacts(mode, root, sessionId);
|
|
33129
33461
|
writeSessionCancelSignal(root, sessionId, mode);
|
|
33130
33462
|
if (MODE_CONFIGS[mode]) {
|
|
33131
|
-
const requesterStatePath = getStateFilePath(root, mode, sessionId);
|
|
33132
|
-
const hadRequesterState2 = (0, import_fs12.existsSync)(requesterStatePath);
|
|
33133
33463
|
const success2 = clearModeState(mode, root, sessionId);
|
|
33134
|
-
|
|
33135
|
-
|
|
33136
|
-
const legacyPath = getStateFilePath(root, mode);
|
|
33137
|
-
if ((0, import_fs12.existsSync)(legacyPath)) {
|
|
33138
|
-
const raw = JSON.parse((0, import_fs12.readFileSync)(legacyPath, "utf-8"));
|
|
33139
|
-
const meta3 = raw._meta;
|
|
33140
|
-
if (!meta3 || meta3.sessionId === sessionId) {
|
|
33141
|
-
(0, import_fs12.unlinkSync)(legacyPath);
|
|
33142
|
-
ghostCleaned2 = true;
|
|
33143
|
-
}
|
|
33144
|
-
}
|
|
33145
|
-
} catch {
|
|
33146
|
-
}
|
|
33464
|
+
const sessionCleanup2 = clearSessionOwnedStateCandidates(mode, root, sessionId);
|
|
33465
|
+
const legacyCleanup2 = clearLegacyStateCandidates(mode, root, sessionId);
|
|
33147
33466
|
let ownerSessionId2;
|
|
33148
|
-
|
|
33467
|
+
let ownerSessionCleanup2 = { cleared: 0, hadFailure: false, paths: [] };
|
|
33468
|
+
let ownerLegacyCleanup2 = { cleared: 0, hadFailure: false };
|
|
33469
|
+
if (requestedSessionOwnedPaths.length === 0 && completedSessionCleanup.cleared === 0 && sessionCleanup2.cleared === 0 && legacyCleanup2.cleared === 0) {
|
|
33149
33470
|
ownerSessionId2 = findSingleOwningSessionForMode(mode, root, sessionId);
|
|
33150
33471
|
if (ownerSessionId2) {
|
|
33472
|
+
if (mode === "team") {
|
|
33473
|
+
for (const teamStatePath of findSessionOwnedStateFiles("team", ownerSessionId2, root)) {
|
|
33474
|
+
collectTeamNamesForCleanup(teamStatePath);
|
|
33475
|
+
}
|
|
33476
|
+
}
|
|
33151
33477
|
writeSessionCancelSignal(root, ownerSessionId2, mode);
|
|
33478
|
+
const ownerRuntimeCleanup = clearModeRuntimeArtifacts(mode, root, ownerSessionId2);
|
|
33479
|
+
runtimeCleanup2.cleared += ownerRuntimeCleanup.cleared;
|
|
33480
|
+
runtimeCleanup2.hadFailure ||= ownerRuntimeCleanup.hadFailure;
|
|
33152
33481
|
clearModeState(mode, root, ownerSessionId2);
|
|
33482
|
+
ownerSessionCleanup2 = clearSessionOwnedStateCandidates(mode, root, ownerSessionId2);
|
|
33483
|
+
ownerLegacyCleanup2 = clearLegacyStateCandidates(mode, root, ownerSessionId2);
|
|
33153
33484
|
}
|
|
33154
33485
|
}
|
|
33155
|
-
const
|
|
33156
|
-
|
|
33157
|
-
|
|
33486
|
+
const ghostNoteParts2 = [];
|
|
33487
|
+
if (legacyCleanup2.cleared > 0) {
|
|
33488
|
+
ghostNoteParts2.push("ghost legacy file also removed");
|
|
33489
|
+
}
|
|
33490
|
+
if (completedSessionCleanup.cleared > 0) {
|
|
33491
|
+
ghostNoteParts2.push(`removed ${completedSessionCleanup.cleared} completed-session orphan file${completedSessionCleanup.cleared === 1 ? "" : "s"}`);
|
|
33492
|
+
}
|
|
33493
|
+
if (sessionCleanup2.cleared > 0) {
|
|
33494
|
+
ghostNoteParts2.push(`removed ${sessionCleanup2.cleared} recovered session file${sessionCleanup2.cleared === 1 ? "" : "s"}`);
|
|
33495
|
+
}
|
|
33496
|
+
if (runtimeCleanup2.cleared > 0) {
|
|
33497
|
+
ghostNoteParts2.push(`removed ${runtimeCleanup2.cleared} runtime artifact${runtimeCleanup2.cleared === 1 ? "" : "s"}`);
|
|
33498
|
+
}
|
|
33499
|
+
if (ownerSessionId2) {
|
|
33500
|
+
ghostNoteParts2.push(`cleared owning session: ${ownerSessionId2}`);
|
|
33501
|
+
}
|
|
33502
|
+
const ghostNote2 = ghostNoteParts2.length > 0 ? ` (${ghostNoteParts2.join(", ")})` : "";
|
|
33503
|
+
const runtimeCleanupNote2 = (() => {
|
|
33504
|
+
if (mode !== "team") return "";
|
|
33505
|
+
const teamNames = [...cleanedTeamNames];
|
|
33506
|
+
const removedRoots = cleanupTeamRuntimeState(root, teamNames);
|
|
33507
|
+
const prunedMissions = pruneMissionBoardTeams(root, teamNames);
|
|
33508
|
+
const details = [];
|
|
33509
|
+
if (removedRoots > 0) details.push(`removed ${removedRoots} team runtime root(s)`);
|
|
33510
|
+
if (prunedMissions > 0) details.push(`pruned ${prunedMissions} HUD mission entry(ies)`);
|
|
33511
|
+
return details.length > 0 ? ` (${details.join(", ")})` : "";
|
|
33512
|
+
})();
|
|
33513
|
+
if (success2 && !legacyCleanup2.hadFailure && !sessionCleanup2.hadFailure && !completedSessionCleanup.hadFailure && !ownerSessionCleanup2.hadFailure && !ownerLegacyCleanup2.hadFailure && !runtimeCleanup2.hadFailure) {
|
|
33158
33514
|
return {
|
|
33159
33515
|
content: [{
|
|
33160
33516
|
type: "text",
|
|
33161
|
-
text: `Successfully cleared state for mode: ${mode} in session: ${sessionId}${ghostNote2}${
|
|
33517
|
+
text: `Successfully cleared state for mode: ${mode} in session: ${sessionId}${ghostNote2}${runtimeCleanupNote2}`
|
|
33162
33518
|
}]
|
|
33163
33519
|
};
|
|
33164
33520
|
} else {
|
|
33165
33521
|
return {
|
|
33166
33522
|
content: [{
|
|
33167
33523
|
type: "text",
|
|
33168
|
-
text: `Warning: Some files could not be removed for mode: ${mode} in session: ${sessionId}${ghostNote2}${
|
|
33524
|
+
text: `Warning: Some files could not be removed for mode: ${mode} in session: ${sessionId}${ghostNote2}${runtimeCleanupNote2}`
|
|
33169
33525
|
}]
|
|
33170
33526
|
};
|
|
33171
33527
|
}
|
|
33172
33528
|
}
|
|
33173
|
-
const
|
|
33174
|
-
const
|
|
33175
|
-
if (hadRequesterState) {
|
|
33176
|
-
(0, import_fs12.unlinkSync)(statePath);
|
|
33177
|
-
}
|
|
33178
|
-
let ghostCleaned = false;
|
|
33179
|
-
try {
|
|
33180
|
-
const legacyPath = resolveStatePath(mode, root);
|
|
33181
|
-
if ((0, import_fs12.existsSync)(legacyPath)) {
|
|
33182
|
-
const raw = JSON.parse((0, import_fs12.readFileSync)(legacyPath, "utf-8"));
|
|
33183
|
-
const meta3 = raw._meta;
|
|
33184
|
-
if (!meta3 || meta3.sessionId === sessionId) {
|
|
33185
|
-
(0, import_fs12.unlinkSync)(legacyPath);
|
|
33186
|
-
ghostCleaned = true;
|
|
33187
|
-
}
|
|
33188
|
-
}
|
|
33189
|
-
} catch {
|
|
33190
|
-
}
|
|
33529
|
+
const sessionCleanup = clearSessionOwnedStateCandidates(mode, root, sessionId);
|
|
33530
|
+
const legacyCleanup = clearLegacyStateCandidates(mode, root, sessionId);
|
|
33191
33531
|
let ownerSessionId;
|
|
33192
|
-
|
|
33532
|
+
let ownerSessionCleanup = { cleared: 0, hadFailure: false, paths: [] };
|
|
33533
|
+
let ownerLegacyCleanup = { cleared: 0, hadFailure: false };
|
|
33534
|
+
if (requestedSessionOwnedPaths.length === 0 && completedSessionCleanup.cleared === 0 && sessionCleanup.cleared === 0 && legacyCleanup.cleared === 0) {
|
|
33193
33535
|
ownerSessionId = findSingleOwningSessionForMode(mode, root, sessionId);
|
|
33194
33536
|
if (ownerSessionId) {
|
|
33195
|
-
|
|
33196
|
-
|
|
33197
|
-
|
|
33198
|
-
try {
|
|
33199
|
-
(0, import_fs12.unlinkSync)(ownerStatePath);
|
|
33200
|
-
} catch {
|
|
33537
|
+
if (mode === "team") {
|
|
33538
|
+
for (const teamStatePath of findSessionOwnedStateFiles("team", ownerSessionId, root)) {
|
|
33539
|
+
collectTeamNamesForCleanup(teamStatePath);
|
|
33201
33540
|
}
|
|
33202
33541
|
}
|
|
33542
|
+
writeSessionCancelSignal(root, ownerSessionId, mode);
|
|
33543
|
+
const ownerRuntimeCleanup = clearModeRuntimeArtifacts(mode, root, ownerSessionId);
|
|
33544
|
+
runtimeCleanup2.cleared += ownerRuntimeCleanup.cleared;
|
|
33545
|
+
runtimeCleanup2.hadFailure ||= ownerRuntimeCleanup.hadFailure;
|
|
33546
|
+
ownerSessionCleanup = clearSessionOwnedStateCandidates(mode, root, ownerSessionId);
|
|
33547
|
+
ownerLegacyCleanup = clearLegacyStateCandidates(mode, root, ownerSessionId);
|
|
33203
33548
|
}
|
|
33204
33549
|
}
|
|
33205
|
-
const
|
|
33206
|
-
|
|
33550
|
+
const ghostNoteParts = [];
|
|
33551
|
+
if (legacyCleanup.cleared > 0) {
|
|
33552
|
+
ghostNoteParts.push("ghost legacy file also removed");
|
|
33553
|
+
}
|
|
33554
|
+
if (completedSessionCleanup.cleared > 0) {
|
|
33555
|
+
ghostNoteParts.push(`removed ${completedSessionCleanup.cleared} completed-session orphan file${completedSessionCleanup.cleared === 1 ? "" : "s"}`);
|
|
33556
|
+
}
|
|
33557
|
+
if (sessionCleanup.cleared > 0) {
|
|
33558
|
+
ghostNoteParts.push(`removed ${sessionCleanup.cleared} recovered session file${sessionCleanup.cleared === 1 ? "" : "s"}`);
|
|
33559
|
+
}
|
|
33560
|
+
if (runtimeCleanup2.cleared > 0) {
|
|
33561
|
+
ghostNoteParts.push(`removed ${runtimeCleanup2.cleared} runtime artifact${runtimeCleanup2.cleared === 1 ? "" : "s"}`);
|
|
33562
|
+
}
|
|
33563
|
+
if (ownerSessionId) {
|
|
33564
|
+
ghostNoteParts.push(`cleared owning session: ${ownerSessionId}`);
|
|
33565
|
+
}
|
|
33566
|
+
const ghostNote = ghostNoteParts.length > 0 ? ` (${ghostNoteParts.join(", ")})` : "";
|
|
33567
|
+
const runtimeCleanupNote = (() => {
|
|
33568
|
+
if (mode !== "team") return "";
|
|
33569
|
+
const teamNames = [...cleanedTeamNames];
|
|
33570
|
+
const removedRoots = cleanupTeamRuntimeState(root, teamNames);
|
|
33571
|
+
const prunedMissions = pruneMissionBoardTeams(root, teamNames);
|
|
33572
|
+
const details = [];
|
|
33573
|
+
if (removedRoots > 0) details.push(`removed ${removedRoots} team runtime root(s)`);
|
|
33574
|
+
if (prunedMissions > 0) details.push(`pruned ${prunedMissions} HUD mission entry(ies)`);
|
|
33575
|
+
return details.length > 0 ? ` (${details.join(", ")})` : "";
|
|
33576
|
+
})();
|
|
33207
33577
|
return {
|
|
33208
33578
|
content: [{
|
|
33209
33579
|
type: "text",
|
|
33210
|
-
text:
|
|
33580
|
+
text: `${legacyCleanup.hadFailure || sessionCleanup.hadFailure || completedSessionCleanup.hadFailure || ownerSessionCleanup.hadFailure || ownerLegacyCleanup.hadFailure || runtimeCleanup2.hadFailure ? "Warning: Some files could not be removed" : "Successfully cleared state"} for mode: ${mode} in session: ${sessionId}${ghostNote}${runtimeCleanupNote}`
|
|
33211
33581
|
}]
|
|
33212
33582
|
};
|
|
33213
33583
|
}
|
|
33584
|
+
{
|
|
33585
|
+
const now = Date.now();
|
|
33586
|
+
const cancelSignalPayload = {
|
|
33587
|
+
active: true,
|
|
33588
|
+
requested_at: new Date(now).toISOString(),
|
|
33589
|
+
expires_at: new Date(now + CANCEL_SIGNAL_TTL_MS).toISOString(),
|
|
33590
|
+
mode,
|
|
33591
|
+
source: "state_clear"
|
|
33592
|
+
};
|
|
33593
|
+
const legacySignalPath = (0, import_path15.join)(getOmcRoot(root), "state", "cancel-signal-state.json");
|
|
33594
|
+
try {
|
|
33595
|
+
atomicWriteJsonSync(legacySignalPath, cancelSignalPayload);
|
|
33596
|
+
} catch {
|
|
33597
|
+
}
|
|
33598
|
+
for (const sid of listSessionIds(root)) {
|
|
33599
|
+
try {
|
|
33600
|
+
const sessionSignalPath = resolveSessionStatePath("cancel-signal", sid, root);
|
|
33601
|
+
atomicWriteJsonSync(sessionSignalPath, cancelSignalPayload);
|
|
33602
|
+
} catch {
|
|
33603
|
+
}
|
|
33604
|
+
}
|
|
33605
|
+
}
|
|
33606
|
+
const runtimeCleanup = clearModeRuntimeArtifacts(mode, root);
|
|
33214
33607
|
let clearedCount = 0;
|
|
33215
33608
|
const errors = [];
|
|
33609
|
+
if (mode === "team") {
|
|
33610
|
+
collectTeamNamesForCleanup(getStateFilePath(root, "team"));
|
|
33611
|
+
}
|
|
33216
33612
|
if (MODE_CONFIGS[mode]) {
|
|
33217
|
-
const
|
|
33218
|
-
if ((0,
|
|
33613
|
+
const primaryLegacyStatePath = getStateFilePath(root, mode);
|
|
33614
|
+
if ((0, import_fs13.existsSync)(primaryLegacyStatePath)) {
|
|
33219
33615
|
if (clearModeState(mode, root)) {
|
|
33220
33616
|
clearedCount++;
|
|
33221
33617
|
} else {
|
|
33222
33618
|
errors.push("legacy path");
|
|
33223
33619
|
}
|
|
33224
33620
|
}
|
|
33225
|
-
}
|
|
33226
|
-
|
|
33227
|
-
|
|
33228
|
-
|
|
33229
|
-
|
|
33230
|
-
|
|
33231
|
-
|
|
33232
|
-
|
|
33233
|
-
|
|
33234
|
-
}
|
|
33621
|
+
}
|
|
33622
|
+
const extraLegacyCleanup = clearLegacyStateCandidates(mode, root);
|
|
33623
|
+
clearedCount += extraLegacyCleanup.cleared;
|
|
33624
|
+
if (extraLegacyCleanup.hadFailure) {
|
|
33625
|
+
errors.push("legacy path");
|
|
33626
|
+
}
|
|
33627
|
+
clearedCount += runtimeCleanup.cleared;
|
|
33628
|
+
if (runtimeCleanup.hadFailure) {
|
|
33629
|
+
errors.push("runtime artifacts");
|
|
33235
33630
|
}
|
|
33236
33631
|
const sessionIds = listSessionIds(root);
|
|
33237
33632
|
for (const sid of sessionIds) {
|
|
33633
|
+
if (mode === "team") {
|
|
33634
|
+
collectTeamNamesForCleanup(resolveSessionStatePath("team", sid, root));
|
|
33635
|
+
}
|
|
33238
33636
|
if (MODE_CONFIGS[mode]) {
|
|
33239
33637
|
const sessionStatePath = getStateFilePath(root, mode, sid);
|
|
33240
|
-
if ((0,
|
|
33638
|
+
if ((0, import_fs13.existsSync)(sessionStatePath)) {
|
|
33241
33639
|
if (clearModeState(mode, root, sid)) {
|
|
33242
33640
|
clearedCount++;
|
|
33243
33641
|
} else {
|
|
@@ -33246,9 +33644,9 @@ var stateClearTool = {
|
|
|
33246
33644
|
}
|
|
33247
33645
|
} else {
|
|
33248
33646
|
const statePath = resolveSessionStatePath(mode, sid, root);
|
|
33249
|
-
if ((0,
|
|
33647
|
+
if ((0, import_fs13.existsSync)(statePath)) {
|
|
33250
33648
|
try {
|
|
33251
|
-
(0,
|
|
33649
|
+
(0, import_fs13.unlinkSync)(statePath);
|
|
33252
33650
|
clearedCount++;
|
|
33253
33651
|
} catch {
|
|
33254
33652
|
errors.push(`session: ${sid}`);
|
|
@@ -33256,7 +33654,15 @@ var stateClearTool = {
|
|
|
33256
33654
|
}
|
|
33257
33655
|
}
|
|
33258
33656
|
}
|
|
33259
|
-
|
|
33657
|
+
let removedTeamRoots = 0;
|
|
33658
|
+
let prunedMissionEntries = 0;
|
|
33659
|
+
if (mode === "team") {
|
|
33660
|
+
const teamNames = [...cleanedTeamNames];
|
|
33661
|
+
const removeSelector = teamNames.length > 0 ? teamNames : void 0;
|
|
33662
|
+
removedTeamRoots = cleanupTeamRuntimeState(root, removeSelector);
|
|
33663
|
+
prunedMissionEntries = pruneMissionBoardTeams(root, removeSelector);
|
|
33664
|
+
}
|
|
33665
|
+
if (clearedCount === 0 && errors.length === 0 && removedTeamRoots === 0 && prunedMissionEntries === 0) {
|
|
33260
33666
|
return {
|
|
33261
33667
|
content: [{
|
|
33262
33668
|
type: "text",
|
|
@@ -33270,6 +33676,16 @@ var stateClearTool = {
|
|
|
33270
33676
|
message += `
|
|
33271
33677
|
- Errors: ${errors.join(", ")}`;
|
|
33272
33678
|
}
|
|
33679
|
+
if (mode === "team") {
|
|
33680
|
+
if (removedTeamRoots > 0) {
|
|
33681
|
+
message += `
|
|
33682
|
+
- Team runtime roots removed: ${removedTeamRoots}`;
|
|
33683
|
+
}
|
|
33684
|
+
if (prunedMissionEntries > 0) {
|
|
33685
|
+
message += `
|
|
33686
|
+
- HUD mission entries pruned: ${prunedMissionEntries}`;
|
|
33687
|
+
}
|
|
33688
|
+
}
|
|
33273
33689
|
message += "\nWARNING: No session_id provided. Cleared legacy plus all session-scoped state; this is a broad operation that may affect other sessions.";
|
|
33274
33690
|
return {
|
|
33275
33691
|
content: [{
|
|
@@ -33307,8 +33723,8 @@ var stateListActiveTool = {
|
|
|
33307
33723
|
for (const mode of EXTRA_STATE_ONLY_MODES) {
|
|
33308
33724
|
try {
|
|
33309
33725
|
const statePath = resolveSessionStatePath(mode, sessionId, root);
|
|
33310
|
-
if ((0,
|
|
33311
|
-
const content = (0,
|
|
33726
|
+
if ((0, import_fs13.existsSync)(statePath)) {
|
|
33727
|
+
const content = (0, import_fs13.readFileSync)(statePath, "utf-8");
|
|
33312
33728
|
const state = JSON.parse(content);
|
|
33313
33729
|
if (state.active) {
|
|
33314
33730
|
activeModes.push(mode);
|
|
@@ -33341,9 +33757,9 @@ ${modeList}`
|
|
|
33341
33757
|
const legacyActiveModes = [...getActiveModes(root)];
|
|
33342
33758
|
for (const mode of EXTRA_STATE_ONLY_MODES) {
|
|
33343
33759
|
const statePath = getStatePath(mode, root);
|
|
33344
|
-
if ((0,
|
|
33760
|
+
if ((0, import_fs13.existsSync)(statePath)) {
|
|
33345
33761
|
try {
|
|
33346
|
-
const content = (0,
|
|
33762
|
+
const content = (0, import_fs13.readFileSync)(statePath, "utf-8");
|
|
33347
33763
|
const state = JSON.parse(content);
|
|
33348
33764
|
if (state.active) {
|
|
33349
33765
|
legacyActiveModes.push(mode);
|
|
@@ -33364,8 +33780,8 @@ ${modeList}`
|
|
|
33364
33780
|
for (const mode of EXTRA_STATE_ONLY_MODES) {
|
|
33365
33781
|
try {
|
|
33366
33782
|
const statePath = resolveSessionStatePath(mode, sid, root);
|
|
33367
|
-
if ((0,
|
|
33368
|
-
const content = (0,
|
|
33783
|
+
if ((0, import_fs13.existsSync)(statePath)) {
|
|
33784
|
+
const content = (0, import_fs13.readFileSync)(statePath, "utf-8");
|
|
33369
33785
|
const state = JSON.parse(content);
|
|
33370
33786
|
if (state.active) {
|
|
33371
33787
|
sessionActiveModes.push(mode);
|
|
@@ -33421,7 +33837,8 @@ var stateGetStatusTool = {
|
|
|
33421
33837
|
session_id: external_exports3.string().optional().describe("Session ID for session-scoped state isolation. When provided, the tool operates only within that session. When omitted, the tool aggregates legacy state plus all session-scoped state (may include other sessions).")
|
|
33422
33838
|
},
|
|
33423
33839
|
handler: async (args) => {
|
|
33424
|
-
const {
|
|
33840
|
+
const { workingDirectory, session_id } = args;
|
|
33841
|
+
const mode = args.mode;
|
|
33425
33842
|
try {
|
|
33426
33843
|
const root = validateWorkingDirectory(workingDirectory);
|
|
33427
33844
|
const sessionId = session_id;
|
|
@@ -33431,9 +33848,9 @@ var stateGetStatusTool = {
|
|
|
33431
33848
|
if (sessionId) {
|
|
33432
33849
|
validateSessionId(sessionId);
|
|
33433
33850
|
const statePath = MODE_CONFIGS[mode] ? getStateFilePath(root, mode, sessionId) : resolveSessionStatePath(mode, sessionId, root);
|
|
33434
|
-
const active = MODE_CONFIGS[mode] ? isModeActive(mode, root, sessionId) : (0,
|
|
33851
|
+
const active = MODE_CONFIGS[mode] ? isModeActive(mode, root, sessionId) : (0, import_fs13.existsSync)(statePath) && (() => {
|
|
33435
33852
|
try {
|
|
33436
|
-
const content = (0,
|
|
33853
|
+
const content = (0, import_fs13.readFileSync)(statePath, "utf-8");
|
|
33437
33854
|
const state = JSON.parse(content);
|
|
33438
33855
|
return state.active === true;
|
|
33439
33856
|
} catch {
|
|
@@ -33441,9 +33858,9 @@ var stateGetStatusTool = {
|
|
|
33441
33858
|
}
|
|
33442
33859
|
})();
|
|
33443
33860
|
let statePreview = "No state file";
|
|
33444
|
-
if ((0,
|
|
33861
|
+
if ((0, import_fs13.existsSync)(statePath)) {
|
|
33445
33862
|
try {
|
|
33446
|
-
const content = (0,
|
|
33863
|
+
const content = (0, import_fs13.readFileSync)(statePath, "utf-8");
|
|
33447
33864
|
const state = JSON.parse(content);
|
|
33448
33865
|
statePreview = JSON.stringify(state, null, 2).slice(0, 500);
|
|
33449
33866
|
if (statePreview.length >= 500) statePreview += "\n...(truncated)";
|
|
@@ -33454,7 +33871,7 @@ var stateGetStatusTool = {
|
|
|
33454
33871
|
lines2.push(`### Session: ${sessionId}`);
|
|
33455
33872
|
lines2.push(`- **Active:** ${active ? "Yes" : "No"}`);
|
|
33456
33873
|
lines2.push(`- **State Path:** ${statePath}`);
|
|
33457
|
-
lines2.push(`- **Exists:** ${(0,
|
|
33874
|
+
lines2.push(`- **Exists:** ${(0, import_fs13.existsSync)(statePath) ? "Yes" : "No"}`);
|
|
33458
33875
|
lines2.push(`
|
|
33459
33876
|
### State Preview
|
|
33460
33877
|
\`\`\`json
|
|
@@ -33468,9 +33885,9 @@ ${statePreview}
|
|
|
33468
33885
|
};
|
|
33469
33886
|
}
|
|
33470
33887
|
const legacyPath = getStatePath(mode, root);
|
|
33471
|
-
const legacyActive = MODE_CONFIGS[mode] ? isModeActive(mode, root) : (0,
|
|
33888
|
+
const legacyActive = MODE_CONFIGS[mode] ? isModeActive(mode, root) : (0, import_fs13.existsSync)(legacyPath) && (() => {
|
|
33472
33889
|
try {
|
|
33473
|
-
const content = (0,
|
|
33890
|
+
const content = (0, import_fs13.readFileSync)(legacyPath, "utf-8");
|
|
33474
33891
|
const state = JSON.parse(content);
|
|
33475
33892
|
return state.active === true;
|
|
33476
33893
|
} catch {
|
|
@@ -33480,13 +33897,13 @@ ${statePreview}
|
|
|
33480
33897
|
lines2.push(`### Legacy Path`);
|
|
33481
33898
|
lines2.push(`- **Active:** ${legacyActive ? "Yes" : "No"}`);
|
|
33482
33899
|
lines2.push(`- **State Path:** ${legacyPath}`);
|
|
33483
|
-
lines2.push(`- **Exists:** ${(0,
|
|
33900
|
+
lines2.push(`- **Exists:** ${(0, import_fs13.existsSync)(legacyPath) ? "Yes" : "No"}
|
|
33484
33901
|
`);
|
|
33485
33902
|
const activeSessions = MODE_CONFIGS[mode] ? getActiveSessionsForMode(mode, root) : listSessionIds(root).filter((sid) => {
|
|
33486
33903
|
try {
|
|
33487
33904
|
const sessionPath = resolveSessionStatePath(mode, sid, root);
|
|
33488
|
-
if ((0,
|
|
33489
|
-
const content = (0,
|
|
33905
|
+
if ((0, import_fs13.existsSync)(sessionPath)) {
|
|
33906
|
+
const content = (0, import_fs13.readFileSync)(sessionPath, "utf-8");
|
|
33490
33907
|
const state = JSON.parse(content);
|
|
33491
33908
|
return state.active === true;
|
|
33492
33909
|
}
|
|
@@ -33528,9 +33945,9 @@ No active sessions for this mode.`);
|
|
|
33528
33945
|
for (const mode2 of EXTRA_STATE_ONLY_MODES) {
|
|
33529
33946
|
const statePath = sessionId ? resolveSessionStatePath(mode2, sessionId, root) : getStatePath(mode2, root);
|
|
33530
33947
|
let active = false;
|
|
33531
|
-
if ((0,
|
|
33948
|
+
if ((0, import_fs13.existsSync)(statePath)) {
|
|
33532
33949
|
try {
|
|
33533
|
-
const content = (0,
|
|
33950
|
+
const content = (0, import_fs13.readFileSync)(statePath, "utf-8");
|
|
33534
33951
|
const state = JSON.parse(content);
|
|
33535
33952
|
active = state.active === true;
|
|
33536
33953
|
} catch {
|
|
@@ -33566,21 +33983,21 @@ var stateTools = [
|
|
|
33566
33983
|
];
|
|
33567
33984
|
|
|
33568
33985
|
// src/hooks/notepad/index.ts
|
|
33569
|
-
var
|
|
33570
|
-
var
|
|
33986
|
+
var import_fs15 = require("fs");
|
|
33987
|
+
var import_path16 = require("path");
|
|
33571
33988
|
|
|
33572
33989
|
// src/lib/file-lock.ts
|
|
33573
|
-
var
|
|
33990
|
+
var import_fs14 = require("fs");
|
|
33574
33991
|
var path6 = __toESM(require("path"), 1);
|
|
33575
33992
|
var DEFAULT_STALE_LOCK_MS = 3e4;
|
|
33576
33993
|
var DEFAULT_RETRY_DELAY_MS = 50;
|
|
33577
33994
|
function isLockStale(lockPath, staleLockMs) {
|
|
33578
33995
|
try {
|
|
33579
|
-
const stat = (0,
|
|
33996
|
+
const stat = (0, import_fs14.statSync)(lockPath);
|
|
33580
33997
|
const ageMs = Date.now() - stat.mtimeMs;
|
|
33581
33998
|
if (ageMs < staleLockMs) return false;
|
|
33582
33999
|
try {
|
|
33583
|
-
const raw = (0,
|
|
34000
|
+
const raw = (0, import_fs14.readFileSync)(lockPath, "utf-8");
|
|
33584
34001
|
const payload = JSON.parse(raw);
|
|
33585
34002
|
if (payload.pid && isProcessAlive(payload.pid)) return false;
|
|
33586
34003
|
} catch {
|
|
@@ -33596,21 +34013,21 @@ function lockPathFor(filePath) {
|
|
|
33596
34013
|
function tryAcquireSync(lockPath, staleLockMs) {
|
|
33597
34014
|
ensureDirSync(path6.dirname(lockPath));
|
|
33598
34015
|
try {
|
|
33599
|
-
const fd = (0,
|
|
34016
|
+
const fd = (0, import_fs14.openSync)(
|
|
33600
34017
|
lockPath,
|
|
33601
|
-
|
|
34018
|
+
import_fs14.constants.O_CREAT | import_fs14.constants.O_EXCL | import_fs14.constants.O_WRONLY,
|
|
33602
34019
|
384
|
|
33603
34020
|
);
|
|
33604
34021
|
try {
|
|
33605
34022
|
const payload = JSON.stringify({ pid: process.pid, timestamp: Date.now() });
|
|
33606
|
-
(0,
|
|
34023
|
+
(0, import_fs14.writeSync)(fd, payload, null, "utf-8");
|
|
33607
34024
|
} catch (writeErr) {
|
|
33608
34025
|
try {
|
|
33609
|
-
(0,
|
|
34026
|
+
(0, import_fs14.closeSync)(fd);
|
|
33610
34027
|
} catch {
|
|
33611
34028
|
}
|
|
33612
34029
|
try {
|
|
33613
|
-
(0,
|
|
34030
|
+
(0, import_fs14.unlinkSync)(lockPath);
|
|
33614
34031
|
} catch {
|
|
33615
34032
|
}
|
|
33616
34033
|
throw writeErr;
|
|
@@ -33620,25 +34037,25 @@ function tryAcquireSync(lockPath, staleLockMs) {
|
|
|
33620
34037
|
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
33621
34038
|
if (isLockStale(lockPath, staleLockMs)) {
|
|
33622
34039
|
try {
|
|
33623
|
-
(0,
|
|
34040
|
+
(0, import_fs14.unlinkSync)(lockPath);
|
|
33624
34041
|
} catch {
|
|
33625
34042
|
}
|
|
33626
34043
|
try {
|
|
33627
|
-
const fd = (0,
|
|
34044
|
+
const fd = (0, import_fs14.openSync)(
|
|
33628
34045
|
lockPath,
|
|
33629
|
-
|
|
34046
|
+
import_fs14.constants.O_CREAT | import_fs14.constants.O_EXCL | import_fs14.constants.O_WRONLY,
|
|
33630
34047
|
384
|
|
33631
34048
|
);
|
|
33632
34049
|
try {
|
|
33633
34050
|
const payload = JSON.stringify({ pid: process.pid, timestamp: Date.now() });
|
|
33634
|
-
(0,
|
|
34051
|
+
(0, import_fs14.writeSync)(fd, payload, null, "utf-8");
|
|
33635
34052
|
} catch (writeErr) {
|
|
33636
34053
|
try {
|
|
33637
|
-
(0,
|
|
34054
|
+
(0, import_fs14.closeSync)(fd);
|
|
33638
34055
|
} catch {
|
|
33639
34056
|
}
|
|
33640
34057
|
try {
|
|
33641
|
-
(0,
|
|
34058
|
+
(0, import_fs14.unlinkSync)(lockPath);
|
|
33642
34059
|
} catch {
|
|
33643
34060
|
}
|
|
33644
34061
|
throw writeErr;
|
|
@@ -33678,11 +34095,11 @@ function acquireFileLockSync(lockPath, opts) {
|
|
|
33678
34095
|
}
|
|
33679
34096
|
function releaseFileLockSync(handle) {
|
|
33680
34097
|
try {
|
|
33681
|
-
(0,
|
|
34098
|
+
(0, import_fs14.closeSync)(handle.fd);
|
|
33682
34099
|
} catch {
|
|
33683
34100
|
}
|
|
33684
34101
|
try {
|
|
33685
|
-
(0,
|
|
34102
|
+
(0, import_fs14.unlinkSync)(handle.path);
|
|
33686
34103
|
} catch {
|
|
33687
34104
|
}
|
|
33688
34105
|
}
|
|
@@ -33756,19 +34173,19 @@ function getSectionRegexSet(header) {
|
|
|
33756
34173
|
return SECTION_REGEXES[header] ?? createSectionRegexSet(header);
|
|
33757
34174
|
}
|
|
33758
34175
|
function getNotepadPath(directory) {
|
|
33759
|
-
return (0,
|
|
34176
|
+
return (0, import_path16.join)(getSharedOmcRoot(directory), NOTEPAD_FILENAME);
|
|
33760
34177
|
}
|
|
33761
34178
|
function initNotepad(directory) {
|
|
33762
34179
|
const omcDir = getSharedOmcRoot(directory);
|
|
33763
|
-
if (!(0,
|
|
34180
|
+
if (!(0, import_fs15.existsSync)(omcDir)) {
|
|
33764
34181
|
try {
|
|
33765
|
-
(0,
|
|
34182
|
+
(0, import_fs15.mkdirSync)(omcDir, { recursive: true });
|
|
33766
34183
|
} catch {
|
|
33767
34184
|
return false;
|
|
33768
34185
|
}
|
|
33769
34186
|
}
|
|
33770
34187
|
const notepadPath = getNotepadPath(directory);
|
|
33771
|
-
if ((0,
|
|
34188
|
+
if ((0, import_fs15.existsSync)(notepadPath)) {
|
|
33772
34189
|
return true;
|
|
33773
34190
|
}
|
|
33774
34191
|
const content = `# Notepad
|
|
@@ -33793,11 +34210,11 @@ ${MANUAL_HEADER}
|
|
|
33793
34210
|
}
|
|
33794
34211
|
function readNotepad(directory) {
|
|
33795
34212
|
const notepadPath = getNotepadPath(directory);
|
|
33796
|
-
if (!(0,
|
|
34213
|
+
if (!(0, import_fs15.existsSync)(notepadPath)) {
|
|
33797
34214
|
return null;
|
|
33798
34215
|
}
|
|
33799
34216
|
try {
|
|
33800
|
-
return (0,
|
|
34217
|
+
return (0, import_fs15.readFileSync)(notepadPath, "utf-8");
|
|
33801
34218
|
} catch {
|
|
33802
34219
|
return null;
|
|
33803
34220
|
}
|
|
@@ -33841,7 +34258,7 @@ function getManualSection(directory) {
|
|
|
33841
34258
|
return extractSection(content, MANUAL_HEADER);
|
|
33842
34259
|
}
|
|
33843
34260
|
function setPriorityContext(directory, content, config2 = DEFAULT_CONFIG) {
|
|
33844
|
-
if (!(0,
|
|
34261
|
+
if (!(0, import_fs15.existsSync)(getNotepadPath(directory))) {
|
|
33845
34262
|
if (!initNotepad(directory)) {
|
|
33846
34263
|
return { success: false };
|
|
33847
34264
|
}
|
|
@@ -33849,7 +34266,7 @@ function setPriorityContext(directory, content, config2 = DEFAULT_CONFIG) {
|
|
|
33849
34266
|
const notepadPath = getNotepadPath(directory);
|
|
33850
34267
|
try {
|
|
33851
34268
|
return withFileLockSync(lockPathFor(notepadPath), () => {
|
|
33852
|
-
let notepadContent = (0,
|
|
34269
|
+
let notepadContent = (0, import_fs15.readFileSync)(notepadPath, "utf-8");
|
|
33853
34270
|
const warning = content.length > config2.priorityMaxChars ? `Priority Context exceeds ${config2.priorityMaxChars} chars (${content.length} chars). Consider condensing.` : void 0;
|
|
33854
34271
|
notepadContent = replaceSection(notepadContent, PRIORITY_HEADER, content);
|
|
33855
34272
|
atomicWriteFileSync(notepadPath, notepadContent);
|
|
@@ -33860,7 +34277,7 @@ function setPriorityContext(directory, content, config2 = DEFAULT_CONFIG) {
|
|
|
33860
34277
|
}
|
|
33861
34278
|
}
|
|
33862
34279
|
function addWorkingMemoryEntry(directory, content) {
|
|
33863
|
-
if (!(0,
|
|
34280
|
+
if (!(0, import_fs15.existsSync)(getNotepadPath(directory))) {
|
|
33864
34281
|
if (!initNotepad(directory)) {
|
|
33865
34282
|
return false;
|
|
33866
34283
|
}
|
|
@@ -33868,7 +34285,7 @@ function addWorkingMemoryEntry(directory, content) {
|
|
|
33868
34285
|
const notepadPath = getNotepadPath(directory);
|
|
33869
34286
|
try {
|
|
33870
34287
|
return withFileLockSync(lockPathFor(notepadPath), () => {
|
|
33871
|
-
let notepadContent = (0,
|
|
34288
|
+
let notepadContent = (0, import_fs15.readFileSync)(notepadPath, "utf-8");
|
|
33872
34289
|
const currentMemory = extractSection(notepadContent, WORKING_MEMORY_HEADER) || "";
|
|
33873
34290
|
const now = /* @__PURE__ */ new Date();
|
|
33874
34291
|
const timestamp = now.toISOString().slice(0, 16).replace("T", " ");
|
|
@@ -33889,7 +34306,7 @@ ${content}
|
|
|
33889
34306
|
}
|
|
33890
34307
|
}
|
|
33891
34308
|
function addManualEntry(directory, content) {
|
|
33892
|
-
if (!(0,
|
|
34309
|
+
if (!(0, import_fs15.existsSync)(getNotepadPath(directory))) {
|
|
33893
34310
|
if (!initNotepad(directory)) {
|
|
33894
34311
|
return false;
|
|
33895
34312
|
}
|
|
@@ -33897,7 +34314,7 @@ function addManualEntry(directory, content) {
|
|
|
33897
34314
|
const notepadPath = getNotepadPath(directory);
|
|
33898
34315
|
try {
|
|
33899
34316
|
return withFileLockSync(lockPathFor(notepadPath), () => {
|
|
33900
|
-
let notepadContent = (0,
|
|
34317
|
+
let notepadContent = (0, import_fs15.readFileSync)(notepadPath, "utf-8");
|
|
33901
34318
|
const currentManual = extractSection(notepadContent, MANUAL_HEADER) || "";
|
|
33902
34319
|
const now = /* @__PURE__ */ new Date();
|
|
33903
34320
|
const timestamp = now.toISOString().slice(0, 16).replace("T", " ");
|
|
@@ -33915,12 +34332,12 @@ ${content}
|
|
|
33915
34332
|
}
|
|
33916
34333
|
function pruneOldEntries(directory, daysOld = DEFAULT_CONFIG.workingMemoryDays) {
|
|
33917
34334
|
const notepadPath = getNotepadPath(directory);
|
|
33918
|
-
if (!(0,
|
|
34335
|
+
if (!(0, import_fs15.existsSync)(notepadPath)) {
|
|
33919
34336
|
return { pruned: 0, remaining: 0 };
|
|
33920
34337
|
}
|
|
33921
34338
|
try {
|
|
33922
34339
|
return withFileLockSync(lockPathFor(notepadPath), () => {
|
|
33923
|
-
let notepadContent = (0,
|
|
34340
|
+
let notepadContent = (0, import_fs15.readFileSync)(notepadPath, "utf-8");
|
|
33924
34341
|
const workingMemory = extractSection(notepadContent, WORKING_MEMORY_HEADER);
|
|
33925
34342
|
if (!workingMemory) {
|
|
33926
34343
|
return { pruned: 0, remaining: 0 };
|
|
@@ -33958,7 +34375,7 @@ ${entry.content}`).join("\n\n");
|
|
|
33958
34375
|
}
|
|
33959
34376
|
function getNotepadStats(directory) {
|
|
33960
34377
|
const notepadPath = getNotepadPath(directory);
|
|
33961
|
-
if (!(0,
|
|
34378
|
+
if (!(0, import_fs15.existsSync)(notepadPath)) {
|
|
33962
34379
|
return {
|
|
33963
34380
|
exists: false,
|
|
33964
34381
|
totalSize: 0,
|
|
@@ -33967,7 +34384,7 @@ function getNotepadStats(directory) {
|
|
|
33967
34384
|
oldestEntry: null
|
|
33968
34385
|
};
|
|
33969
34386
|
}
|
|
33970
|
-
const content = (0,
|
|
34387
|
+
const content = (0, import_fs15.readFileSync)(notepadPath, "utf-8");
|
|
33971
34388
|
const priorityContext = extractSection(content, PRIORITY_HEADER) || "";
|
|
33972
34389
|
const workingMemory = extractSection(content, WORKING_MEMORY_HEADER) || "";
|
|
33973
34390
|
const wmMatches = workingMemory.match(
|
|
@@ -34286,7 +34703,7 @@ var notepadTools = [
|
|
|
34286
34703
|
];
|
|
34287
34704
|
|
|
34288
34705
|
// src/hooks/project-memory/index.ts
|
|
34289
|
-
var
|
|
34706
|
+
var import_path24 = __toESM(require("path"), 1);
|
|
34290
34707
|
|
|
34291
34708
|
// src/features/context-injector/collector.ts
|
|
34292
34709
|
var PRIORITY_ORDER = {
|
|
@@ -34396,18 +34813,18 @@ var ContextCollector = class {
|
|
|
34396
34813
|
var contextCollector = new ContextCollector();
|
|
34397
34814
|
|
|
34398
34815
|
// src/hooks/rules-injector/finder.ts
|
|
34399
|
-
var
|
|
34400
|
-
var
|
|
34816
|
+
var import_fs16 = require("fs");
|
|
34817
|
+
var import_path18 = require("path");
|
|
34401
34818
|
|
|
34402
34819
|
// src/hooks/rules-injector/constants.ts
|
|
34403
|
-
var
|
|
34820
|
+
var import_path17 = require("path");
|
|
34404
34821
|
var import_os4 = require("os");
|
|
34405
|
-
var OMC_STORAGE_DIR = (0,
|
|
34406
|
-
var RULES_INJECTOR_STORAGE = (0,
|
|
34822
|
+
var OMC_STORAGE_DIR = (0, import_path17.join)((0, import_os4.homedir)(), ".omcp");
|
|
34823
|
+
var RULES_INJECTOR_STORAGE = (0, import_path17.join)(OMC_STORAGE_DIR, "rules-injector");
|
|
34407
34824
|
|
|
34408
34825
|
// src/hooks/project-memory/storage.ts
|
|
34409
34826
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
34410
|
-
var
|
|
34827
|
+
var import_path19 = __toESM(require("path"), 1);
|
|
34411
34828
|
|
|
34412
34829
|
// src/hooks/project-memory/constants.ts
|
|
34413
34830
|
var CACHE_EXPIRY_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -34431,7 +34848,7 @@ async function loadProjectMemory(projectRoot) {
|
|
|
34431
34848
|
}
|
|
34432
34849
|
async function saveProjectMemory(projectRoot, memory) {
|
|
34433
34850
|
const memoryPath = getMemoryPath(projectRoot);
|
|
34434
|
-
const omcDir =
|
|
34851
|
+
const omcDir = import_path19.default.dirname(memoryPath);
|
|
34435
34852
|
try {
|
|
34436
34853
|
await import_promises.default.mkdir(omcDir, { recursive: true });
|
|
34437
34854
|
await atomicWriteJson(memoryPath, memory);
|
|
@@ -34447,17 +34864,17 @@ async function withProjectMemoryLock(projectRoot, fn) {
|
|
|
34447
34864
|
|
|
34448
34865
|
// src/hooks/project-memory/detector.ts
|
|
34449
34866
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
34450
|
-
var
|
|
34867
|
+
var import_path21 = __toESM(require("path"), 1);
|
|
34451
34868
|
|
|
34452
34869
|
// src/hooks/project-memory/directory-mapper.ts
|
|
34453
34870
|
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
34454
|
-
var
|
|
34871
|
+
var import_path20 = __toESM(require("path"), 1);
|
|
34455
34872
|
|
|
34456
34873
|
// src/hooks/project-memory/formatter.ts
|
|
34457
|
-
var
|
|
34874
|
+
var import_path23 = __toESM(require("path"), 1);
|
|
34458
34875
|
|
|
34459
34876
|
// src/hooks/project-memory/hot-path-tracker.ts
|
|
34460
|
-
var
|
|
34877
|
+
var import_path22 = __toESM(require("path"), 1);
|
|
34461
34878
|
|
|
34462
34879
|
// src/hooks/project-memory/directive-detector.ts
|
|
34463
34880
|
function addDirective(directives, newDirective) {
|
|
@@ -34842,27 +35259,27 @@ var memoryTools = [
|
|
|
34842
35259
|
];
|
|
34843
35260
|
|
|
34844
35261
|
// src/tools/trace-tools.ts
|
|
34845
|
-
var
|
|
34846
|
-
var
|
|
35262
|
+
var import_fs18 = require("fs");
|
|
35263
|
+
var import_path26 = require("path");
|
|
34847
35264
|
|
|
34848
35265
|
// src/hooks/subagent-tracker/session-replay.ts
|
|
34849
|
-
var
|
|
34850
|
-
var
|
|
35266
|
+
var import_fs17 = require("fs");
|
|
35267
|
+
var import_path25 = require("path");
|
|
34851
35268
|
var REPLAY_PREFIX = "agent-replay-";
|
|
34852
35269
|
var MAX_REPLAY_SIZE_BYTES = 5 * 1024 * 1024;
|
|
34853
35270
|
function getReplayFilePath(directory, sessionId) {
|
|
34854
|
-
const stateDir = (0,
|
|
34855
|
-
if (!(0,
|
|
34856
|
-
(0,
|
|
35271
|
+
const stateDir = (0, import_path25.join)(getOmcRoot(directory), "state");
|
|
35272
|
+
if (!(0, import_fs17.existsSync)(stateDir)) {
|
|
35273
|
+
(0, import_fs17.mkdirSync)(stateDir, { recursive: true });
|
|
34857
35274
|
}
|
|
34858
35275
|
const safeId = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
34859
|
-
return (0,
|
|
35276
|
+
return (0, import_path25.join)(stateDir, `${REPLAY_PREFIX}${safeId}.jsonl`);
|
|
34860
35277
|
}
|
|
34861
35278
|
function readReplayEvents(directory, sessionId) {
|
|
34862
35279
|
const filePath = getReplayFilePath(directory, sessionId);
|
|
34863
|
-
if (!(0,
|
|
35280
|
+
if (!(0, import_fs17.existsSync)(filePath)) return [];
|
|
34864
35281
|
try {
|
|
34865
|
-
const content = (0,
|
|
35282
|
+
const content = (0, import_fs17.readFileSync)(filePath, "utf-8");
|
|
34866
35283
|
return content.split("\n").filter((line) => line.trim()).map((line) => {
|
|
34867
35284
|
try {
|
|
34868
35285
|
return JSON.parse(line);
|
|
@@ -35035,12 +35452,12 @@ function getReplaySummary(directory, sessionId) {
|
|
|
35035
35452
|
// src/tools/trace-tools.ts
|
|
35036
35453
|
var REPLAY_PREFIX2 = "agent-replay-";
|
|
35037
35454
|
function findLatestSessionId(directory) {
|
|
35038
|
-
const stateDir = (0,
|
|
35455
|
+
const stateDir = (0, import_path26.join)(directory, ".omcp", "state");
|
|
35039
35456
|
try {
|
|
35040
|
-
const files = (0,
|
|
35457
|
+
const files = (0, import_fs18.readdirSync)(stateDir).filter((f) => f.startsWith(REPLAY_PREFIX2) && f.endsWith(".jsonl")).map((f) => ({
|
|
35041
35458
|
name: f,
|
|
35042
35459
|
sessionId: f.slice(REPLAY_PREFIX2.length, -".jsonl".length),
|
|
35043
|
-
mtime: (0,
|
|
35460
|
+
mtime: (0, import_fs18.statSync)((0, import_path26.join)(stateDir, f)).mtimeMs
|
|
35044
35461
|
})).sort((a, b) => b.mtime - a.mtime);
|
|
35045
35462
|
return files.length > 0 ? files[0].sessionId : null;
|
|
35046
35463
|
} catch {
|
|
@@ -35384,18 +35801,18 @@ No events recorded.`
|
|
|
35384
35801
|
var traceTools = [traceTimelineTool, traceSummaryTool];
|
|
35385
35802
|
|
|
35386
35803
|
// src/lib/shared-memory.ts
|
|
35387
|
-
var
|
|
35388
|
-
var
|
|
35804
|
+
var import_fs19 = require("fs");
|
|
35805
|
+
var import_path27 = require("path");
|
|
35389
35806
|
var CONFIG_FILE_NAME = ".omc-config.json";
|
|
35390
35807
|
function isSharedMemoryEnabled() {
|
|
35391
35808
|
try {
|
|
35392
|
-
const configPath = (0,
|
|
35809
|
+
const configPath = (0, import_path27.join)(
|
|
35393
35810
|
process.env.HOME || process.env.USERPROFILE || "",
|
|
35394
35811
|
".copilot",
|
|
35395
35812
|
CONFIG_FILE_NAME
|
|
35396
35813
|
);
|
|
35397
|
-
if (!(0,
|
|
35398
|
-
const raw = JSON.parse((0,
|
|
35814
|
+
if (!(0, import_fs19.existsSync)(configPath)) return true;
|
|
35815
|
+
const raw = JSON.parse((0, import_fs19.readFileSync)(configPath, "utf-8"));
|
|
35399
35816
|
const enabled = raw?.agents?.sharedMemory?.enabled;
|
|
35400
35817
|
if (typeof enabled === "boolean") return enabled;
|
|
35401
35818
|
return true;
|
|
@@ -35429,16 +35846,16 @@ function validateKey(key) {
|
|
|
35429
35846
|
function getNamespaceDir(namespace, worktreeRoot) {
|
|
35430
35847
|
validateNamespace(namespace);
|
|
35431
35848
|
const omcRoot = getOmcRoot(worktreeRoot);
|
|
35432
|
-
return (0,
|
|
35849
|
+
return (0, import_path27.join)(omcRoot, SHARED_MEMORY_DIR, namespace);
|
|
35433
35850
|
}
|
|
35434
35851
|
function getEntryPath(namespace, key, worktreeRoot) {
|
|
35435
35852
|
validateKey(key);
|
|
35436
|
-
return (0,
|
|
35853
|
+
return (0, import_path27.join)(getNamespaceDir(namespace, worktreeRoot), `${key}.json`);
|
|
35437
35854
|
}
|
|
35438
35855
|
function ensureNamespaceDir(namespace, worktreeRoot) {
|
|
35439
35856
|
const dir = getNamespaceDir(namespace, worktreeRoot);
|
|
35440
|
-
if (!(0,
|
|
35441
|
-
(0,
|
|
35857
|
+
if (!(0, import_fs19.existsSync)(dir)) {
|
|
35858
|
+
(0, import_fs19.mkdirSync)(dir, { recursive: true });
|
|
35442
35859
|
}
|
|
35443
35860
|
return dir;
|
|
35444
35861
|
}
|
|
@@ -35453,9 +35870,9 @@ function writeEntry(namespace, key, value, ttl, worktreeRoot) {
|
|
|
35453
35870
|
const lockPath = filePath + ".lock";
|
|
35454
35871
|
const doWrite = () => {
|
|
35455
35872
|
let existingCreatedAt = now;
|
|
35456
|
-
if ((0,
|
|
35873
|
+
if ((0, import_fs19.existsSync)(filePath)) {
|
|
35457
35874
|
try {
|
|
35458
|
-
const existing = JSON.parse((0,
|
|
35875
|
+
const existing = JSON.parse((0, import_fs19.readFileSync)(filePath, "utf-8"));
|
|
35459
35876
|
existingCreatedAt = existing.createdAt || now;
|
|
35460
35877
|
} catch {
|
|
35461
35878
|
}
|
|
@@ -35472,11 +35889,11 @@ function writeEntry(namespace, key, value, ttl, worktreeRoot) {
|
|
|
35472
35889
|
entry.expiresAt = new Date(Date.now() + ttl * 1e3).toISOString();
|
|
35473
35890
|
}
|
|
35474
35891
|
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
35475
|
-
(0,
|
|
35476
|
-
(0,
|
|
35892
|
+
(0, import_fs19.writeFileSync)(tmpPath, JSON.stringify(entry, null, 2), "utf-8");
|
|
35893
|
+
(0, import_fs19.renameSync)(tmpPath, filePath);
|
|
35477
35894
|
try {
|
|
35478
35895
|
const legacyTmp = filePath + ".tmp";
|
|
35479
|
-
if ((0,
|
|
35896
|
+
if ((0, import_fs19.existsSync)(legacyTmp)) (0, import_fs19.unlinkSync)(legacyTmp);
|
|
35480
35897
|
} catch {
|
|
35481
35898
|
}
|
|
35482
35899
|
return entry;
|
|
@@ -35491,12 +35908,12 @@ function readEntry(namespace, key, worktreeRoot) {
|
|
|
35491
35908
|
validateNamespace(namespace);
|
|
35492
35909
|
validateKey(key);
|
|
35493
35910
|
const filePath = getEntryPath(namespace, key, worktreeRoot);
|
|
35494
|
-
if (!(0,
|
|
35911
|
+
if (!(0, import_fs19.existsSync)(filePath)) return null;
|
|
35495
35912
|
try {
|
|
35496
|
-
const entry = JSON.parse((0,
|
|
35913
|
+
const entry = JSON.parse((0, import_fs19.readFileSync)(filePath, "utf-8"));
|
|
35497
35914
|
if (isExpired(entry)) {
|
|
35498
35915
|
try {
|
|
35499
|
-
(0,
|
|
35916
|
+
(0, import_fs19.unlinkSync)(filePath);
|
|
35500
35917
|
} catch {
|
|
35501
35918
|
}
|
|
35502
35919
|
return null;
|
|
@@ -35509,14 +35926,14 @@ function readEntry(namespace, key, worktreeRoot) {
|
|
|
35509
35926
|
function listEntries(namespace, worktreeRoot) {
|
|
35510
35927
|
validateNamespace(namespace);
|
|
35511
35928
|
const dir = getNamespaceDir(namespace, worktreeRoot);
|
|
35512
|
-
if (!(0,
|
|
35929
|
+
if (!(0, import_fs19.existsSync)(dir)) return [];
|
|
35513
35930
|
const items = [];
|
|
35514
35931
|
try {
|
|
35515
|
-
const files = (0,
|
|
35932
|
+
const files = (0, import_fs19.readdirSync)(dir).filter((f) => f.endsWith(".json"));
|
|
35516
35933
|
for (const file2 of files) {
|
|
35517
35934
|
try {
|
|
35518
|
-
const filePath = (0,
|
|
35519
|
-
const entry = JSON.parse((0,
|
|
35935
|
+
const filePath = (0, import_path27.join)(dir, file2);
|
|
35936
|
+
const entry = JSON.parse((0, import_fs19.readFileSync)(filePath, "utf-8"));
|
|
35520
35937
|
if (!isExpired(entry)) {
|
|
35521
35938
|
items.push({
|
|
35522
35939
|
key: entry.key,
|
|
@@ -35535,9 +35952,9 @@ function deleteEntry(namespace, key, worktreeRoot) {
|
|
|
35535
35952
|
validateNamespace(namespace);
|
|
35536
35953
|
validateKey(key);
|
|
35537
35954
|
const filePath = getEntryPath(namespace, key, worktreeRoot);
|
|
35538
|
-
if (!(0,
|
|
35955
|
+
if (!(0, import_fs19.existsSync)(filePath)) return false;
|
|
35539
35956
|
try {
|
|
35540
|
-
(0,
|
|
35957
|
+
(0, import_fs19.unlinkSync)(filePath);
|
|
35541
35958
|
return true;
|
|
35542
35959
|
} catch {
|
|
35543
35960
|
return false;
|
|
@@ -35545,15 +35962,15 @@ function deleteEntry(namespace, key, worktreeRoot) {
|
|
|
35545
35962
|
}
|
|
35546
35963
|
function cleanupExpired(namespace, worktreeRoot) {
|
|
35547
35964
|
const omcRoot = getOmcRoot(worktreeRoot);
|
|
35548
|
-
const sharedMemDir = (0,
|
|
35549
|
-
if (!(0,
|
|
35965
|
+
const sharedMemDir = (0, import_path27.join)(omcRoot, SHARED_MEMORY_DIR);
|
|
35966
|
+
if (!(0, import_fs19.existsSync)(sharedMemDir)) return { removed: 0, namespaces: [] };
|
|
35550
35967
|
const namespacesToClean = [];
|
|
35551
35968
|
if (namespace) {
|
|
35552
35969
|
validateNamespace(namespace);
|
|
35553
35970
|
namespacesToClean.push(namespace);
|
|
35554
35971
|
} else {
|
|
35555
35972
|
try {
|
|
35556
|
-
const entries = (0,
|
|
35973
|
+
const entries = (0, import_fs19.readdirSync)(sharedMemDir, { withFileTypes: true });
|
|
35557
35974
|
for (const entry of entries) {
|
|
35558
35975
|
if (entry.isDirectory()) {
|
|
35559
35976
|
namespacesToClean.push(entry.name);
|
|
@@ -35566,17 +35983,17 @@ function cleanupExpired(namespace, worktreeRoot) {
|
|
|
35566
35983
|
let removed = 0;
|
|
35567
35984
|
const cleanedNamespaces = [];
|
|
35568
35985
|
for (const ns of namespacesToClean) {
|
|
35569
|
-
const nsDir = (0,
|
|
35570
|
-
if (!(0,
|
|
35986
|
+
const nsDir = (0, import_path27.join)(sharedMemDir, ns);
|
|
35987
|
+
if (!(0, import_fs19.existsSync)(nsDir)) continue;
|
|
35571
35988
|
let nsRemoved = 0;
|
|
35572
35989
|
try {
|
|
35573
|
-
const files = (0,
|
|
35990
|
+
const files = (0, import_fs19.readdirSync)(nsDir).filter((f) => f.endsWith(".json"));
|
|
35574
35991
|
for (const file2 of files) {
|
|
35575
35992
|
try {
|
|
35576
|
-
const filePath = (0,
|
|
35577
|
-
const entry = JSON.parse((0,
|
|
35993
|
+
const filePath = (0, import_path27.join)(nsDir, file2);
|
|
35994
|
+
const entry = JSON.parse((0, import_fs19.readFileSync)(filePath, "utf-8"));
|
|
35578
35995
|
if (isExpired(entry)) {
|
|
35579
|
-
(0,
|
|
35996
|
+
(0, import_fs19.unlinkSync)(filePath);
|
|
35580
35997
|
nsRemoved++;
|
|
35581
35998
|
}
|
|
35582
35999
|
} catch {
|
|
@@ -35593,10 +36010,10 @@ function cleanupExpired(namespace, worktreeRoot) {
|
|
|
35593
36010
|
}
|
|
35594
36011
|
function listNamespaces(worktreeRoot) {
|
|
35595
36012
|
const omcRoot = getOmcRoot(worktreeRoot);
|
|
35596
|
-
const sharedMemDir = (0,
|
|
35597
|
-
if (!(0,
|
|
36013
|
+
const sharedMemDir = (0, import_path27.join)(omcRoot, SHARED_MEMORY_DIR);
|
|
36014
|
+
if (!(0, import_fs19.existsSync)(sharedMemDir)) return [];
|
|
35598
36015
|
try {
|
|
35599
|
-
const entries = (0,
|
|
36016
|
+
const entries = (0, import_fs19.readdirSync)(sharedMemDir, { withFileTypes: true });
|
|
35600
36017
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
|
|
35601
36018
|
} catch {
|
|
35602
36019
|
return [];
|
|
@@ -36152,28 +36569,28 @@ var DEFAULT_WIKI_CONFIG = {
|
|
|
36152
36569
|
};
|
|
36153
36570
|
|
|
36154
36571
|
// src/hooks/wiki/storage.ts
|
|
36155
|
-
var
|
|
36156
|
-
var
|
|
36572
|
+
var import_fs20 = require("fs");
|
|
36573
|
+
var import_path28 = require("path");
|
|
36157
36574
|
var WIKI_DIR = "wiki";
|
|
36158
36575
|
var INDEX_FILE = "index.md";
|
|
36159
36576
|
var LOG_FILE = "log.md";
|
|
36160
36577
|
var ENVIRONMENT_FILE = "environment.md";
|
|
36161
36578
|
var RESERVED_FILES = /* @__PURE__ */ new Set([INDEX_FILE, LOG_FILE, ENVIRONMENT_FILE]);
|
|
36162
36579
|
function getOmcDir(root) {
|
|
36163
|
-
return (0,
|
|
36580
|
+
return (0, import_path28.join)(root, ".omcp");
|
|
36164
36581
|
}
|
|
36165
36582
|
function getWikiDir(root) {
|
|
36166
|
-
return (0,
|
|
36583
|
+
return (0, import_path28.join)(getOmcDir(root), WIKI_DIR);
|
|
36167
36584
|
}
|
|
36168
36585
|
function ensureWikiDir(root) {
|
|
36169
36586
|
const wikiDir = getWikiDir(root);
|
|
36170
|
-
if (!(0,
|
|
36171
|
-
(0,
|
|
36587
|
+
if (!(0, import_fs20.existsSync)(wikiDir)) {
|
|
36588
|
+
(0, import_fs20.mkdirSync)(wikiDir, { recursive: true });
|
|
36172
36589
|
}
|
|
36173
36590
|
const omcRoot = getOmcDir(root);
|
|
36174
|
-
const gitignorePath = (0,
|
|
36175
|
-
if ((0,
|
|
36176
|
-
const content = (0,
|
|
36591
|
+
const gitignorePath = (0, import_path28.join)(omcRoot, ".gitignore");
|
|
36592
|
+
if ((0, import_fs20.existsSync)(gitignorePath)) {
|
|
36593
|
+
const content = (0, import_fs20.readFileSync)(gitignorePath, "utf-8");
|
|
36177
36594
|
if (!content.includes("wiki/")) {
|
|
36178
36595
|
atomicWriteFileSync(gitignorePath, content.trimEnd() + "\nwiki/\n");
|
|
36179
36596
|
}
|
|
@@ -36184,7 +36601,7 @@ function ensureWikiDir(root) {
|
|
|
36184
36601
|
}
|
|
36185
36602
|
function withWikiLock(root, fn) {
|
|
36186
36603
|
const wikiDir = ensureWikiDir(root);
|
|
36187
|
-
const lockPath = lockPathFor((0,
|
|
36604
|
+
const lockPath = lockPathFor((0, import_path28.join)(wikiDir, ".wiki-lock"));
|
|
36188
36605
|
return withFileLockSync(lockPath, fn, { timeoutMs: 5e3, retryDelayMs: 50 });
|
|
36189
36606
|
}
|
|
36190
36607
|
function parseFrontmatter(raw) {
|
|
@@ -36266,9 +36683,9 @@ function safeWikiPath(wikiDir, filename) {
|
|
|
36266
36683
|
if (filename.includes("/") || filename.includes("\\") || filename.includes("..")) {
|
|
36267
36684
|
return null;
|
|
36268
36685
|
}
|
|
36269
|
-
const filePath = (0,
|
|
36270
|
-
const resolved = (0,
|
|
36271
|
-
if (!resolved.startsWith((0,
|
|
36686
|
+
const filePath = (0, import_path28.join)(wikiDir, filename);
|
|
36687
|
+
const resolved = (0, import_path28.resolve)(filePath);
|
|
36688
|
+
if (!resolved.startsWith((0, import_path28.resolve)(wikiDir) + import_path28.sep)) {
|
|
36272
36689
|
return null;
|
|
36273
36690
|
}
|
|
36274
36691
|
return filePath;
|
|
@@ -36277,9 +36694,9 @@ function readPage(root, filename) {
|
|
|
36277
36694
|
const wikiDir = getWikiDir(root);
|
|
36278
36695
|
const filePath = safeWikiPath(wikiDir, filename);
|
|
36279
36696
|
if (!filePath) return null;
|
|
36280
|
-
if (!(0,
|
|
36697
|
+
if (!(0, import_fs20.existsSync)(filePath)) return null;
|
|
36281
36698
|
try {
|
|
36282
|
-
const raw = (0,
|
|
36699
|
+
const raw = (0, import_fs20.readFileSync)(filePath, "utf-8");
|
|
36283
36700
|
const parsed = parseFrontmatter(raw);
|
|
36284
36701
|
if (!parsed) return null;
|
|
36285
36702
|
return {
|
|
@@ -36293,16 +36710,16 @@ function readPage(root, filename) {
|
|
|
36293
36710
|
}
|
|
36294
36711
|
function listPages(root) {
|
|
36295
36712
|
const wikiDir = getWikiDir(root);
|
|
36296
|
-
if (!(0,
|
|
36297
|
-
return (0,
|
|
36713
|
+
if (!(0, import_fs20.existsSync)(wikiDir)) return [];
|
|
36714
|
+
return (0, import_fs20.readdirSync)(wikiDir).filter((f) => f.endsWith(".md") && !RESERVED_FILES.has(f)).sort();
|
|
36298
36715
|
}
|
|
36299
36716
|
function readAllPages(root) {
|
|
36300
36717
|
return listPages(root).map((f) => readPage(root, f)).filter((p) => p !== null);
|
|
36301
36718
|
}
|
|
36302
36719
|
function readIndex(root) {
|
|
36303
|
-
const indexPath = (0,
|
|
36304
|
-
if (!(0,
|
|
36305
|
-
return (0,
|
|
36720
|
+
const indexPath = (0, import_path28.join)(getWikiDir(root), INDEX_FILE);
|
|
36721
|
+
if (!(0, import_fs20.existsSync)(indexPath)) return null;
|
|
36722
|
+
return (0, import_fs20.readFileSync)(indexPath, "utf-8");
|
|
36306
36723
|
}
|
|
36307
36724
|
function writePageUnsafe(root, page) {
|
|
36308
36725
|
if (RESERVED_FILES.has(page.filename)) {
|
|
@@ -36317,8 +36734,8 @@ function deletePageUnsafe(root, filename) {
|
|
|
36317
36734
|
const wikiDir = getWikiDir(root);
|
|
36318
36735
|
const filePath = safeWikiPath(wikiDir, filename);
|
|
36319
36736
|
if (!filePath) return false;
|
|
36320
|
-
if (!(0,
|
|
36321
|
-
(0,
|
|
36737
|
+
if (!(0, import_fs20.existsSync)(filePath)) return false;
|
|
36738
|
+
(0, import_fs20.unlinkSync)(filePath);
|
|
36322
36739
|
return true;
|
|
36323
36740
|
}
|
|
36324
36741
|
function updateIndexUnsafe(root) {
|
|
@@ -36347,19 +36764,19 @@ function updateIndexUnsafe(root) {
|
|
|
36347
36764
|
lines.push("");
|
|
36348
36765
|
}
|
|
36349
36766
|
const wikiDir = ensureWikiDir(root);
|
|
36350
|
-
atomicWriteFileSync((0,
|
|
36767
|
+
atomicWriteFileSync((0, import_path28.join)(wikiDir, INDEX_FILE), lines.join("\n"));
|
|
36351
36768
|
}
|
|
36352
36769
|
function appendLogUnsafe(root, entry) {
|
|
36353
36770
|
const wikiDir = ensureWikiDir(root);
|
|
36354
|
-
const logPath = (0,
|
|
36771
|
+
const logPath = (0, import_path28.join)(wikiDir, LOG_FILE);
|
|
36355
36772
|
const logLine = `## [${entry.timestamp}] ${entry.operation}
|
|
36356
36773
|
- **Pages:** ${entry.pagesAffected.join(", ") || "none"}
|
|
36357
36774
|
- **Summary:** ${entry.summary}
|
|
36358
36775
|
|
|
36359
36776
|
`;
|
|
36360
36777
|
let existing = "";
|
|
36361
|
-
if ((0,
|
|
36362
|
-
existing = (0,
|
|
36778
|
+
if ((0, import_fs20.existsSync)(logPath)) {
|
|
36779
|
+
existing = (0, import_fs20.readFileSync)(logPath, "utf-8");
|
|
36363
36780
|
} else {
|
|
36364
36781
|
existing = "# Wiki Log\n\n";
|
|
36365
36782
|
}
|
|
@@ -36691,7 +37108,7 @@ var wikiIngestTool = {
|
|
|
36691
37108
|
},
|
|
36692
37109
|
handler: async (args) => {
|
|
36693
37110
|
try {
|
|
36694
|
-
const root =
|
|
37111
|
+
const root = validateWorkingDirectoryOrLinkedWorktree(args.workingDirectory);
|
|
36695
37112
|
const result = ingestKnowledge(root, {
|
|
36696
37113
|
title: args.title,
|
|
36697
37114
|
content: args.content,
|
|
@@ -36732,7 +37149,7 @@ var wikiQueryTool = {
|
|
|
36732
37149
|
},
|
|
36733
37150
|
handler: async (args) => {
|
|
36734
37151
|
try {
|
|
36735
|
-
const root =
|
|
37152
|
+
const root = validateWorkingDirectoryOrLinkedWorktree(args.workingDirectory);
|
|
36736
37153
|
const matches = queryWiki(root, args.query, {
|
|
36737
37154
|
tags: args.tags,
|
|
36738
37155
|
category: args.category,
|
|
@@ -36781,7 +37198,7 @@ var wikiLintTool = {
|
|
|
36781
37198
|
},
|
|
36782
37199
|
handler: async (args) => {
|
|
36783
37200
|
try {
|
|
36784
|
-
const root =
|
|
37201
|
+
const root = validateWorkingDirectoryOrLinkedWorktree(args.workingDirectory);
|
|
36785
37202
|
const report = lintWiki(root);
|
|
36786
37203
|
if (report.issues.length === 0) {
|
|
36787
37204
|
return {
|
|
@@ -36829,7 +37246,7 @@ var wikiAddTool = {
|
|
|
36829
37246
|
},
|
|
36830
37247
|
handler: async (args) => {
|
|
36831
37248
|
try {
|
|
36832
|
-
const root =
|
|
37249
|
+
const root = validateWorkingDirectoryOrLinkedWorktree(args.workingDirectory);
|
|
36833
37250
|
const slug = titleToSlug(args.title);
|
|
36834
37251
|
if (readPage(root, slug)) {
|
|
36835
37252
|
return {
|
|
@@ -36872,7 +37289,7 @@ var wikiListTool = {
|
|
|
36872
37289
|
},
|
|
36873
37290
|
handler: async (args) => {
|
|
36874
37291
|
try {
|
|
36875
|
-
const root =
|
|
37292
|
+
const root = validateWorkingDirectoryOrLinkedWorktree(args.workingDirectory);
|
|
36876
37293
|
const index = readIndex(root);
|
|
36877
37294
|
if (!index) {
|
|
36878
37295
|
const pages = listPages(root);
|
|
@@ -36918,7 +37335,7 @@ var wikiReadTool = {
|
|
|
36918
37335
|
},
|
|
36919
37336
|
handler: async (args) => {
|
|
36920
37337
|
try {
|
|
36921
|
-
const root =
|
|
37338
|
+
const root = validateWorkingDirectoryOrLinkedWorktree(args.workingDirectory);
|
|
36922
37339
|
const filename = args.page.endsWith(".md") ? args.page : `${args.page}.md`;
|
|
36923
37340
|
const page = readPage(root, filename);
|
|
36924
37341
|
if (!page) {
|
|
@@ -36966,7 +37383,7 @@ var wikiDeleteTool = {
|
|
|
36966
37383
|
},
|
|
36967
37384
|
handler: async (args) => {
|
|
36968
37385
|
try {
|
|
36969
|
-
const root =
|
|
37386
|
+
const root = validateWorkingDirectoryOrLinkedWorktree(args.workingDirectory);
|
|
36970
37387
|
const filename = args.page.endsWith(".md") ? args.page : `${args.page}.md`;
|
|
36971
37388
|
const deleted = deletePage(root, filename);
|
|
36972
37389
|
if (!deleted) {
|
|
@@ -37012,23 +37429,23 @@ var wikiTools = [
|
|
|
37012
37429
|
];
|
|
37013
37430
|
|
|
37014
37431
|
// src/tools/skills-tools.ts
|
|
37015
|
-
var
|
|
37432
|
+
var import_path32 = require("path");
|
|
37016
37433
|
var import_os6 = require("os");
|
|
37017
37434
|
|
|
37018
37435
|
// src/hooks/learner/loader.ts
|
|
37019
|
-
var
|
|
37436
|
+
var import_fs22 = require("fs");
|
|
37020
37437
|
var import_crypto3 = require("crypto");
|
|
37021
|
-
var
|
|
37438
|
+
var import_path31 = require("path");
|
|
37022
37439
|
|
|
37023
37440
|
// src/hooks/learner/finder.ts
|
|
37024
|
-
var
|
|
37025
|
-
var
|
|
37441
|
+
var import_fs21 = require("fs");
|
|
37442
|
+
var import_path30 = require("path");
|
|
37026
37443
|
|
|
37027
37444
|
// src/hooks/learner/constants.ts
|
|
37028
|
-
var
|
|
37445
|
+
var import_path29 = require("path");
|
|
37029
37446
|
var import_os5 = require("os");
|
|
37030
|
-
var USER_SKILLS_DIR = (0,
|
|
37031
|
-
var GLOBAL_SKILLS_DIR = (0,
|
|
37447
|
+
var USER_SKILLS_DIR = (0, import_path29.join)(getConfigDir(), "skills", "omc-learned");
|
|
37448
|
+
var GLOBAL_SKILLS_DIR = (0, import_path29.join)((0, import_os5.homedir)(), ".omcp", "skills");
|
|
37032
37449
|
var PROJECT_SKILLS_SUBDIR = OmgPaths.SKILLS;
|
|
37033
37450
|
var MAX_RECURSION_DEPTH = 10;
|
|
37034
37451
|
var SKILL_EXTENSION = ".md";
|
|
@@ -37036,12 +37453,12 @@ var DEBUG_ENABLED = process.env.OMC_DEBUG === "1";
|
|
|
37036
37453
|
|
|
37037
37454
|
// src/hooks/learner/finder.ts
|
|
37038
37455
|
function findSkillFilesRecursive(dir, results, depth = 0) {
|
|
37039
|
-
if (!(0,
|
|
37456
|
+
if (!(0, import_fs21.existsSync)(dir)) return;
|
|
37040
37457
|
if (depth > MAX_RECURSION_DEPTH) return;
|
|
37041
37458
|
try {
|
|
37042
|
-
const entries = (0,
|
|
37459
|
+
const entries = (0, import_fs21.readdirSync)(dir, { withFileTypes: true });
|
|
37043
37460
|
for (const entry of entries) {
|
|
37044
|
-
const fullPath = (0,
|
|
37461
|
+
const fullPath = (0, import_path30.join)(dir, entry.name);
|
|
37045
37462
|
if (entry.isDirectory()) {
|
|
37046
37463
|
findSkillFilesRecursive(fullPath, results, depth + 1);
|
|
37047
37464
|
} else if (entry.isFile() && entry.name.endsWith(SKILL_EXTENSION)) {
|
|
@@ -37056,22 +37473,22 @@ function findSkillFilesRecursive(dir, results, depth = 0) {
|
|
|
37056
37473
|
}
|
|
37057
37474
|
function safeRealpathSync(filePath) {
|
|
37058
37475
|
try {
|
|
37059
|
-
return (0,
|
|
37476
|
+
return (0, import_fs21.realpathSync)(filePath);
|
|
37060
37477
|
} catch {
|
|
37061
37478
|
return filePath;
|
|
37062
37479
|
}
|
|
37063
37480
|
}
|
|
37064
37481
|
function isWithinBoundary(realPath, boundary) {
|
|
37065
|
-
const normalizedReal = (0,
|
|
37066
|
-
const normalizedBoundary = (0,
|
|
37067
|
-
return normalizedReal === normalizedBoundary || normalizedReal.startsWith(normalizedBoundary +
|
|
37482
|
+
const normalizedReal = (0, import_path30.normalize)(realPath);
|
|
37483
|
+
const normalizedBoundary = (0, import_path30.normalize)(safeRealpathSync(boundary));
|
|
37484
|
+
return normalizedReal === normalizedBoundary || normalizedReal.startsWith(normalizedBoundary + import_path30.sep);
|
|
37068
37485
|
}
|
|
37069
37486
|
function findSkillFiles(projectRoot, options) {
|
|
37070
37487
|
const candidates = [];
|
|
37071
37488
|
const seenRealPaths = /* @__PURE__ */ new Set();
|
|
37072
37489
|
const scope = options?.scope ?? "all";
|
|
37073
37490
|
if (projectRoot && (scope === "project" || scope === "all")) {
|
|
37074
|
-
const projectSkillsDir = (0,
|
|
37491
|
+
const projectSkillsDir = (0, import_path30.join)(projectRoot, PROJECT_SKILLS_SUBDIR);
|
|
37075
37492
|
const projectFiles = [];
|
|
37076
37493
|
findSkillFilesRecursive(projectSkillsDir, projectFiles);
|
|
37077
37494
|
for (const filePath of projectFiles) {
|
|
@@ -37277,7 +37694,7 @@ function loadAllSkills(projectRoot) {
|
|
|
37277
37694
|
const seenIds = /* @__PURE__ */ new Map();
|
|
37278
37695
|
for (const candidate of candidates) {
|
|
37279
37696
|
try {
|
|
37280
|
-
const rawContent = (0,
|
|
37697
|
+
const rawContent = (0, import_fs22.readFileSync)(candidate.path, "utf-8");
|
|
37281
37698
|
const { metadata, content, valid, errors } = parseSkillFile(rawContent);
|
|
37282
37699
|
if (!valid) {
|
|
37283
37700
|
if (DEBUG_ENABLED) {
|
|
@@ -37286,7 +37703,7 @@ function loadAllSkills(projectRoot) {
|
|
|
37286
37703
|
continue;
|
|
37287
37704
|
}
|
|
37288
37705
|
const skillId = metadata.id;
|
|
37289
|
-
const relativePath = (0,
|
|
37706
|
+
const relativePath = (0, import_path31.normalize)((0, import_path31.relative)(candidate.sourceDir, candidate.path));
|
|
37290
37707
|
const skill = {
|
|
37291
37708
|
path: candidate.path,
|
|
37292
37709
|
relativePath,
|
|
@@ -37312,13 +37729,13 @@ function loadAllSkills(projectRoot) {
|
|
|
37312
37729
|
// src/tools/skills-tools.ts
|
|
37313
37730
|
var ALLOWED_BOUNDARIES = [process.cwd(), (0, import_os6.homedir)()];
|
|
37314
37731
|
function validateProjectRoot(input) {
|
|
37315
|
-
const normalized = (0,
|
|
37732
|
+
const normalized = (0, import_path32.normalize)((0, import_path32.resolve)(input));
|
|
37316
37733
|
if (input.includes("..")) {
|
|
37317
37734
|
throw new Error("Invalid project root: path traversal not allowed");
|
|
37318
37735
|
}
|
|
37319
37736
|
const isWithinAllowed = ALLOWED_BOUNDARIES.some((boundary) => {
|
|
37320
|
-
const normalizedBoundary = (0,
|
|
37321
|
-
return normalized === normalizedBoundary || normalized.startsWith(normalizedBoundary +
|
|
37737
|
+
const normalizedBoundary = (0, import_path32.normalize)(boundary);
|
|
37738
|
+
return normalized === normalizedBoundary || normalized.startsWith(normalizedBoundary + import_path32.sep);
|
|
37322
37739
|
});
|
|
37323
37740
|
if (!isWithinAllowed) {
|
|
37324
37741
|
throw new Error("Invalid project root: path is outside allowed directories");
|