open-multi-agent-kit 0.90.9 → 0.92.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/CHANGELOG.md +39 -4
  2. package/README.md +14 -1
  3. package/dist/core/agent-session.d.ts +27 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +196 -32
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/command-safety.d.ts.map +1 -1
  8. package/dist/core/command-safety.js +0 -58
  9. package/dist/core/command-safety.js.map +1 -1
  10. package/dist/core/compaction/transaction.d.ts.map +1 -1
  11. package/dist/core/compaction/transaction.js +7 -3
  12. package/dist/core/compaction/transaction.js.map +1 -1
  13. package/dist/core/context-budget-headroom-candidates.d.ts.map +1 -1
  14. package/dist/core/context-budget-headroom-candidates.js +21 -11
  15. package/dist/core/context-budget-headroom-candidates.js.map +1 -1
  16. package/dist/core/context-budget-system-prompt-items.d.ts +1 -0
  17. package/dist/core/context-budget-system-prompt-items.d.ts.map +1 -1
  18. package/dist/core/context-budget-system-prompt-items.js +7 -8
  19. package/dist/core/context-budget-system-prompt-items.js.map +1 -1
  20. package/dist/core/footer-data-provider.d.ts +7 -1
  21. package/dist/core/footer-data-provider.d.ts.map +1 -1
  22. package/dist/core/footer-data-provider.js +12 -0
  23. package/dist/core/footer-data-provider.js.map +1 -1
  24. package/dist/core/index.d.ts +1 -0
  25. package/dist/core/index.d.ts.map +1 -1
  26. package/dist/core/index.js +1 -0
  27. package/dist/core/index.js.map +1 -1
  28. package/dist/core/loadouts.d.ts.map +1 -1
  29. package/dist/core/loadouts.js +27 -48
  30. package/dist/core/loadouts.js.map +1 -1
  31. package/dist/core/metrics-sampler.d.ts +20 -0
  32. package/dist/core/metrics-sampler.d.ts.map +1 -1
  33. package/dist/core/metrics-sampler.js +52 -0
  34. package/dist/core/metrics-sampler.js.map +1 -1
  35. package/dist/core/model-registry.d.ts.map +1 -1
  36. package/dist/core/model-registry.js +4 -1
  37. package/dist/core/model-registry.js.map +1 -1
  38. package/dist/core/model-resolver.d.ts.map +1 -1
  39. package/dist/core/model-resolver.js +15 -6
  40. package/dist/core/model-resolver.js.map +1 -1
  41. package/dist/core/provider-resilience.d.ts +51 -0
  42. package/dist/core/provider-resilience.d.ts.map +1 -0
  43. package/dist/core/provider-resilience.js +86 -0
  44. package/dist/core/provider-resilience.js.map +1 -0
  45. package/dist/core/run-journal.d.ts.map +1 -1
  46. package/dist/core/run-journal.js +14 -22
  47. package/dist/core/run-journal.js.map +1 -1
  48. package/dist/core/session-termination.d.ts +8 -2
  49. package/dist/core/session-termination.d.ts.map +1 -1
  50. package/dist/core/session-termination.js +45 -3
  51. package/dist/core/session-termination.js.map +1 -1
  52. package/dist/core/settings-manager.d.ts +30 -0
  53. package/dist/core/settings-manager.d.ts.map +1 -1
  54. package/dist/core/settings-manager.js +17 -0
  55. package/dist/core/settings-manager.js.map +1 -1
  56. package/dist/core/system-prompt.d.ts.map +1 -1
  57. package/dist/core/system-prompt.js +35 -30
  58. package/dist/core/system-prompt.js.map +1 -1
  59. package/dist/core/tools/grep.d.ts.map +1 -1
  60. package/dist/core/tools/grep.js +47 -0
  61. package/dist/core/tools/grep.js.map +1 -1
  62. package/dist/core/tools/omp-pure-seams.d.ts +41 -0
  63. package/dist/core/tools/omp-pure-seams.d.ts.map +1 -0
  64. package/dist/core/tools/omp-pure-seams.js +142 -0
  65. package/dist/core/tools/omp-pure-seams.js.map +1 -0
  66. package/dist/core/tools/omp-seam-runtime.d.ts +100 -0
  67. package/dist/core/tools/omp-seam-runtime.d.ts.map +1 -0
  68. package/dist/core/tools/omp-seam-runtime.js +40 -0
  69. package/dist/core/tools/omp-seam-runtime.js.map +1 -0
  70. package/dist/core/tools/read.d.ts.map +1 -1
  71. package/dist/core/tools/read.js +34 -1
  72. package/dist/core/tools/read.js.map +1 -1
  73. package/dist/main.d.ts.map +1 -1
  74. package/dist/main.js +112 -11
  75. package/dist/main.js.map +1 -1
  76. package/dist/modes/interactive/components/footer.d.ts +1 -1
  77. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  78. package/dist/modes/interactive/components/footer.js +11 -8
  79. package/dist/modes/interactive/components/footer.js.map +1 -1
  80. package/dist/modes/interactive/theme/omk-aurora-dark.json +80 -0
  81. package/dist/modes/interactive/theme/omk-aurora-light.json +80 -0
  82. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  83. package/dist/modes/interactive/theme/theme.js +5 -0
  84. package/dist/modes/interactive/theme/theme.js.map +1 -1
  85. package/dist/modes/print-mode.d.ts.map +1 -1
  86. package/dist/modes/print-mode.js +9 -0
  87. package/dist/modes/print-mode.js.map +1 -1
  88. package/docs/adaptorch-preview-spec.md +174 -0
  89. package/docs/adaptorch-preview.md +2 -2
  90. package/docs/compaction.md +13 -13
  91. package/docs/correctness-wall.md +13 -5
  92. package/docs/custom-provider.md +8 -8
  93. package/docs/development.md +2 -2
  94. package/docs/extensions.md +8 -8
  95. package/docs/json.md +4 -4
  96. package/docs/provider-resilience.md +87 -0
  97. package/docs/providers.md +1 -1
  98. package/docs/session-format.md +5 -5
  99. package/docs/settings.md +30 -0
  100. package/docs/skills.md +2 -0
  101. package/docs/themes.md +4 -2
  102. package/docs/tui.md +4 -4
  103. package/docs/usage.md +4 -0
  104. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  105. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  106. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  107. package/examples/extensions/gondolin/package-lock.json +2 -2
  108. package/examples/extensions/gondolin/package.json +1 -1
  109. package/examples/extensions/sandbox/package-lock.json +2 -2
  110. package/examples/extensions/sandbox/package.json +1 -1
  111. package/examples/extensions/subagent/README.md +35 -10
  112. package/examples/extensions/subagent/adaptive-agent-runtime.test.ts +234 -0
  113. package/examples/extensions/subagent/adaptive-agent-runtime.ts +240 -0
  114. package/examples/extensions/subagent/adaptive-result.ts +112 -0
  115. package/examples/extensions/subagent/checkpoint-runtime.test.ts +125 -0
  116. package/examples/extensions/subagent/checkpoint-runtime.ts +198 -0
  117. package/examples/extensions/subagent/deadline-budget.test.ts +135 -0
  118. package/examples/extensions/subagent/deadline-budget.ts +242 -0
  119. package/examples/extensions/subagent/deadline-profile-store.test.ts +72 -0
  120. package/examples/extensions/subagent/deadline-profile-store.ts +172 -0
  121. package/examples/extensions/subagent/fixtures/fake-omk-json.mjs +13 -0
  122. package/examples/extensions/subagent/fixtures/hanging-process-tree.mjs +40 -0
  123. package/examples/extensions/subagent/index.ts +253 -137
  124. package/examples/extensions/subagent/managed-process.test.ts +178 -0
  125. package/examples/extensions/subagent/managed-process.ts +236 -0
  126. package/examples/extensions/subagent/subagent-extension-smoke.test.ts +112 -0
  127. package/examples/extensions/subagent/subagent-runtime-types.ts +76 -0
  128. package/examples/extensions/with-deps/package-lock.json +2 -2
  129. package/examples/extensions/with-deps/package.json +1 -1
  130. package/npm-shrinkwrap.json +28 -19
  131. package/package.json +6 -5
@@ -62,31 +62,23 @@ export const BUILTIN_LOADOUTS = {
62
62
  inspect: {
63
63
  schemaVersion: "omk.loadout.v1",
64
64
  name: "inspect",
65
- authority: "read-only",
66
- tools: { allow: ["read", "grep", "find", "ls"] },
67
- skills: allowNames("skill", ["understand-chat", "analyze"]),
68
- mcp: allowNames("mcp", ["filesystem-readonly", "memory"]),
69
- hooks: allowNames("hook", ["pre-shell-guard", "protect-secrets"]),
65
+ authority: "write-scoped",
66
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
67
+ commands: { mode: "scoped-shell" },
70
68
  },
71
69
  plan: {
72
70
  schemaVersion: "omk.loadout.v1",
73
71
  name: "plan",
74
- authority: "advisory",
75
- tools: { allow: ["read", "grep", "find", "ls"] },
76
- skills: allowNames("skill", ["adaptorch-route", "writing-plans", "ddd-software-architecture"]),
77
- mcp: allowNames("mcp", ["memory", "adaptorch"]),
78
- hooks: allowNames("hook", ["session-context", "precompact-checkpoint"]),
72
+ authority: "write-scoped",
73
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
74
+ commands: { mode: "scoped-shell" },
79
75
  },
80
76
  architect: {
81
77
  schemaVersion: "omk.loadout.v1",
82
78
  name: "architect",
83
- authority: "review-only",
84
- tools: { allow: ["read", "grep", "find", "ls", "bash", "report_finding"] },
85
- skills: allowNames("skill", ["ddd-software-architecture", "code-review", "security-review"]),
86
- mcp: allowNames("mcp", ["filesystem-readonly", "memory", "context7"]),
87
- hooks: allowNames("hook", ["pre-shell-guard", "protect-secrets", "stop-verify", "subagent-stop-audit"]),
88
- commands: { mode: "read-only-shell" },
89
- evidence: { required: true, outputPattern: ".omk/runs/<goal>/architect.md" },
79
+ authority: "write-scoped",
80
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash", "report_finding"] },
81
+ commands: { mode: "scoped-shell" },
90
82
  },
91
83
  code: {
92
84
  schemaVersion: "omk.loadout.v1",
@@ -112,48 +104,36 @@ export const BUILTIN_LOADOUTS = {
112
104
  test: {
113
105
  schemaVersion: "omk.loadout.v1",
114
106
  name: "test",
115
- authority: "execute-tests",
116
- tools: { allow: ["read", "grep", "find", "ls", "bash"] },
117
- skills: allowNames("skill", ["verification-before-completion"]),
118
- mcp: allowNames("mcp", ["filesystem"]),
119
- hooks: allowNames("hook", ["pre-shell-guard", "stop-verify"]),
120
- commands: { mode: "tests-only" },
107
+ authority: "write-scoped",
108
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
109
+ commands: { mode: "scoped-shell" },
121
110
  },
122
111
  review: {
123
112
  schemaVersion: "omk.loadout.v1",
124
113
  name: "review",
125
- authority: "review-only",
126
- tools: { allow: ["read", "grep", "find", "ls"] },
127
- skills: allowNames("skill", ["code-review", "differential-review"]),
128
- mcp: allowNames("mcp", ["memory"]),
129
- hooks: allowNames("hook", ["stop-verify", "subagent-stop-audit"]),
114
+ authority: "write-scoped",
115
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
116
+ commands: { mode: "scoped-shell" },
130
117
  },
131
118
  critic: {
132
119
  schemaVersion: "omk.loadout.v1",
133
120
  name: "critic",
134
- authority: "review-only",
135
- tools: { allow: ["read", "grep", "find", "ls", "bash"] },
136
- skills: allowNames("skill", ["code-review", "verification-before-completion", "scientific-critical-thinking"]),
137
- mcp: allowNames("mcp", ["filesystem-readonly", "memory", "context7"]),
138
- hooks: allowNames("hook", ["pre-shell-guard", "protect-secrets", "stop-verify", "subagent-stop-audit"]),
139
- commands: { mode: "read-only-shell" },
140
- evidence: { required: true, outputPattern: ".omk/runs/<goal>/critic.md" },
121
+ authority: "write-scoped",
122
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
123
+ commands: { mode: "scoped-shell" },
141
124
  },
142
125
  security: {
143
126
  schemaVersion: "omk.loadout.v1",
144
127
  name: "security",
145
- authority: "security-review",
146
- tools: { allow: ["read", "grep", "find", "ls", "bash"] },
147
- skills: allowNames("skill", ["security-review", "differential-review"]),
148
- mcp: allowNames("mcp", ["filesystem-readonly", "memory"]),
149
- hooks: allowNames("hook", ["pre-shell-guard", "protect-secrets", "stop-verify"]),
150
- commands: { mode: "read-only-shell" },
128
+ authority: "write-scoped",
129
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
130
+ commands: { mode: "scoped-shell" },
151
131
  },
152
132
  "visual-qa": {
153
133
  schemaVersion: "omk.loadout.v1",
154
134
  name: "visual-qa",
155
- authority: "execute-tests",
156
- tools: { allow: ["read", "grep", "find", "ls", "bash"] },
135
+ authority: "write-scoped",
136
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
157
137
  skills: allowNames("skill", [
158
138
  "clone-website",
159
139
  "visual-qa",
@@ -171,8 +151,7 @@ export const BUILTIN_LOADOUTS = {
171
151
  "protect-secrets",
172
152
  "stop-verify",
173
153
  ]),
174
- commands: { mode: "tests-only" },
175
- evidence: { required: true, outputPattern: ".omk/runs/<goal>/visual-qa.md" },
154
+ commands: { mode: "scoped-shell" },
176
155
  },
177
156
  "rhwp-doc": {
178
157
  schemaVersion: "omk.loadout.v1",
@@ -229,9 +208,9 @@ export const BUILTIN_LOADOUTS = {
229
208
  none: {
230
209
  schemaVersion: "omk.loadout.v1",
231
210
  name: "none",
232
- authority: "advisory",
233
- tools: { allow: [], defaultMode: "no-tools" },
234
- commands: { mode: "none" },
211
+ authority: "write-scoped",
212
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
213
+ commands: { mode: "scoped-shell" },
235
214
  },
236
215
  };
237
216
  export function inferLoadoutForRole(role) {
@@ -1 +1 @@
1
- {"version":3,"file":"loadouts.js","sourceRoot":"","sources":["../../src/core/loadouts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure loadout / lane-profile algorithms for the OMK control plane.\n *\n * This module is I/O-free. It owns the loadout schema, built-in presets,\n * capability gating (allow/exclude/require selectors), profile validation, and\n * the derivation of scheduler read/write/parallelizable fields from a lane's\n * optional assigned paths. Runtime wiring (AgentSession tool registry, skill\n * prompt construction, MCP runtime, scheduler admission) lives in sibling\n * modules and consumes the decisions made here.\n *\n * Schema and presets follow the OMK package hardening loadout plan.\n *\n * Erasable TypeScript only (no enum/namespace/parameter properties).\n */\n\nimport type { HookPolicyMetadata } from \"./hooks/index.ts\";\n\nexport type LoadoutAuthority =\n\t| \"advisory\"\n\t| \"read-only\"\n\t| \"execute-tests\"\n\t| \"write-scoped\"\n\t| \"review-only\"\n\t| \"security-review\";\n\nexport type LoadoutRole =\n\t| \"planner\"\n\t| \"explorer\"\n\t| \"architect\"\n\t| \"coder\"\n\t| \"executor\"\n\t| \"tester\"\n\t| \"reviewer\"\n\t| \"critic\"\n\t| \"security\"\n\t| \"visual-qa\"\n\t| \"rhwp-doc\"\n\t| \"synthesizer\"\n\t| \"package-maintainer\";\n\n/** Resource kinds the loadout layer can describe. Only the last four are gated here. */\nexport type ResourceKind = \"extension\" | \"skill\" | \"prompt\" | \"theme\" | \"tool\" | \"mcp\" | \"hook\";\nexport type ResourceOrigin = \"package\" | \"top-level\";\nexport type SourceScope = \"user\" | \"project\" | \"temporary\" | \"builtin\";\nexport type CommandMode = \"none\" | \"read-only-shell\" | \"tests-only\" | \"scoped-shell\";\nexport type ToolDefaultMode = \"default-builtins\" | \"no-tools\" | \"no-builtin-tools\";\n\nexport interface NamedResource {\n\tkind: ResourceKind;\n\tname: string;\n\tsource?: string;\n\tscope?: SourceScope;\n\t/** Package-relative or absolute resource path, when meaningful (skills/prompts). */\n\tpath?: string;\n\torigin?: ResourceOrigin;\n\tpolicy?: HookPolicyMetadata;\n}\n\n/**\n * A selector matches inventory resources by name and/or provenance criteria.\n * A resource matches when its kind equals `kind` and every defined criterion\n * matches (names is an OR over the listed names; paths/sources are OR over globs).\n */\nexport interface ResourceSelector {\n\tkind: ResourceKind;\n\tnames?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.path`. */\n\tpaths?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.source`. */\n\tsources?: readonly string[];\n\tscopes?: readonly SourceScope[];\n\torigins?: readonly ResourceOrigin[];\n\t/** Marker only; requirement is expressed by placement in `CapabilityGate.require`. */\n\trequired?: boolean;\n}\n\n/** Tool gating uses flat name arrays (mapped to SDK tools / setActiveTools). */\nexport interface ToolGate {\n\tallow?: readonly string[];\n\texclude?: readonly string[];\n\trequire?: readonly string[];\n\tdefaultMode?: ToolDefaultMode;\n}\n\n/** Skills / MCP / hooks gating uses selector arrays. */\nexport interface CapabilityGate {\n\tallow?: readonly ResourceSelector[];\n\texclude?: readonly ResourceSelector[];\n\trequire?: readonly ResourceSelector[];\n}\n\nexport interface LoadoutCommands {\n\tmode: CommandMode;\n\tallowPatterns?: readonly string[];\n\tblockPatterns?: readonly string[];\n}\n\nexport interface LoadoutEvidence {\n\trequired: boolean;\n\toutputPattern: string;\n}\n\nexport interface LoadoutProfile {\n\tschemaVersion: \"omk.loadout.v1\";\n\tname: string;\n\tdescription?: string;\n\tauthority: LoadoutAuthority;\n\ttools: ToolGate;\n\tskills?: CapabilityGate;\n\tmcp?: CapabilityGate;\n\thooks?: CapabilityGate;\n\tcommands?: LoadoutCommands;\n\tevidence?: LoadoutEvidence;\n}\n\nexport interface CapabilityInventory {\n\ttools: readonly NamedResource[];\n\tskills: readonly NamedResource[];\n\tmcp: readonly NamedResource[];\n\thooks: readonly NamedResource[];\n}\n\nexport interface LaneDefaults {\n\tloadout: string;\n\tauthority: LoadoutAuthority;\n\tparallelizable: boolean;\n\treadOnly: boolean;\n\twritesProductFiles: boolean;\n}\n\nexport interface AppliedLoadout {\n\tprofileName: string;\n\tauthority: LoadoutAuthority;\n\tactiveTools: string[];\n\tactiveSkills: string[];\n\tactiveMcp: string[];\n\tactiveHooks: string[];\n\tblockers: string[];\n\twarnings: string[];\n}\n\nexport interface LoadoutValidation {\n\tvalid: boolean;\n\terrors: string[];\n}\n\n/** A scheduler access entry; shape matches `AccessSetEntry` in the orchestration layer. */\nexport interface LoadoutAccessEntry {\n\tpath: string;\n\tsymbols?: readonly string[];\n}\n\nexport interface SchedulerFields {\n\treadSet: LoadoutAccessEntry[];\n\twriteSet: LoadoutAccessEntry[];\n\tparallelizable: boolean;\n}\n\nexport interface SchedulerDerivationInput {\n\trole: LoadoutRole;\n\tassignedReadPaths?: readonly string[];\n\tassignedWritePaths?: readonly string[];\n}\n\nconst AUTHORITY_RANK: Record<LoadoutAuthority, number> = {\n\tadvisory: 0,\n\t\"read-only\": 1,\n\t\"review-only\": 1,\n\t\"security-review\": 2,\n\t\"execute-tests\": 3,\n\t\"write-scoped\": 4,\n};\n\nconst KNOWN_RESOURCE_KINDS: ReadonlySet<ResourceKind> = new Set([\n\t\"extension\",\n\t\"skill\",\n\t\"prompt\",\n\t\"theme\",\n\t\"tool\",\n\t\"mcp\",\n\t\"hook\",\n]);\n\nconst KNOWN_COMMAND_MODES: ReadonlySet<CommandMode> = new Set([\n\t\"none\",\n\t\"read-only-shell\",\n\t\"tests-only\",\n\t\"scoped-shell\",\n]);\n\nconst KNOWN_TOOL_DEFAULT_MODES: ReadonlySet<ToolDefaultMode> = new Set([\n\t\"default-builtins\",\n\t\"no-tools\",\n\t\"no-builtin-tools\",\n]);\n\n/** Roles permitted to declare a non-empty writeSet during scheduler derivation. */\nconst WRITING_ROLES: ReadonlySet<LoadoutRole> = new Set([\n\t\"coder\",\n\t\"executor\",\n\t\"tester\",\n\t\"rhwp-doc\",\n\t\"synthesizer\",\n\t\"package-maintainer\",\n]);\n\nconst LOCKFILE_BASENAMES: ReadonlySet<string> = new Set([\n\t\"package-lock.json\",\n\t\"npm-shrinkwrap.json\",\n\t\"yarn.lock\",\n\t\"pnpm-lock.yaml\",\n]);\n\nfunction allowNames(kind: ResourceKind, names: readonly string[]): CapabilityGate {\n\treturn { allow: [{ kind, names }] };\n}\n\nexport const BUILTIN_LOADOUTS: Readonly<Record<string, LoadoutProfile>> = {\n\tinspect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"inspect\",\n\t\tauthority: \"read-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\"] },\n\t\tskills: allowNames(\"skill\", [\"understand-chat\", \"analyze\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\"]),\n\t},\n\tplan: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"plan\",\n\t\tauthority: \"advisory\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\"] },\n\t\tskills: allowNames(\"skill\", [\"adaptorch-route\", \"writing-plans\", \"ddd-software-architecture\"]),\n\t\tmcp: allowNames(\"mcp\", [\"memory\", \"adaptorch\"]),\n\t\thooks: allowNames(\"hook\", [\"session-context\", \"precompact-checkpoint\"]),\n\t},\n\tarchitect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"architect\",\n\t\tauthority: \"review-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\", \"report_finding\"] },\n\t\tskills: allowNames(\"skill\", [\"ddd-software-architecture\", \"code-review\", \"security-review\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\", \"subagent-stop-audit\"]),\n\t\tcommands: { mode: \"read-only-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/architect.md\" },\n\t},\n\tcode: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"code\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\texecutor: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"executor\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\", \"verification-before-completion\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\", \"stop-verify\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/implementation.md\" },\n\t},\n\ttest: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"test\",\n\t\tauthority: \"execute-tests\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"verification-before-completion\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"stop-verify\"]),\n\t\tcommands: { mode: \"tests-only\" },\n\t},\n\treview: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"review\",\n\t\tauthority: \"review-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\"] },\n\t\tskills: allowNames(\"skill\", [\"code-review\", \"differential-review\"]),\n\t\tmcp: allowNames(\"mcp\", [\"memory\"]),\n\t\thooks: allowNames(\"hook\", [\"stop-verify\", \"subagent-stop-audit\"]),\n\t},\n\tcritic: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"critic\",\n\t\tauthority: \"review-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"code-review\", \"verification-before-completion\", \"scientific-critical-thinking\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\", \"subagent-stop-audit\"]),\n\t\tcommands: { mode: \"read-only-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/critic.md\" },\n\t},\n\tsecurity: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"security\",\n\t\tauthority: \"security-review\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"security-review\", \"differential-review\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\"]),\n\t\tcommands: { mode: \"read-only-shell\" },\n\t},\n\t\"visual-qa\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"visual-qa\",\n\t\tauthority: \"execute-tests\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"clone-website\",\n\t\t\t\"visual-qa\",\n\t\t\t\"visual-diff\",\n\t\t\t\"visual-regression\",\n\t\t\t\"browser-qa\",\n\t\t\t\"web-quality-audit\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"chrome-devtools\", \"playwright\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"component-spec-before-build\",\n\t\t\t\"visual-diff-after-edit\",\n\t\t\t\"typecheck-after-edit\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"tests-only\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/visual-qa.md\" },\n\t},\n\t\"rhwp-doc\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"rhwp-doc\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"rhwp\",\n\t\t\t\"rhwp-doc\",\n\t\t\t\"document-extraction\",\n\t\t\t\"document-conversion\",\n\t\t\t\"technical-writing\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\", \"playwright\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"document-artifact-guard\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"pre-shell-guard\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/rhwp-doc.md\" },\n\t},\n\t\"package-maintainer\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"package-maintainer\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"exact-pin\",\n\t\t\t\"no-lifecycle-scripts\",\n\t\t\t\"security-review\",\n\t\t\t\"verification-before-completion\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"npm-audit-summary\", \"stop-verify\"]),\n\t\tcommands: {\n\t\t\tmode: \"scoped-shell\",\n\t\t\tallowPatterns: [\n\t\t\t\t\"npm install --ignore-scripts*\",\n\t\t\t\t\"npm ci --ignore-scripts*\",\n\t\t\t\t\"npm install --package-lock-only --ignore-scripts*\",\n\t\t\t\t\"node scripts/generate-coding-agent-shrinkwrap.mjs*\",\n\t\t\t],\n\t\t\tblockPatterns: [\n\t\t\t\t\"*@latest*\",\n\t\t\t\t\"npm install *--ignore-scripts=false*\",\n\t\t\t\t\"npm ci *--ignore-scripts=false*\",\n\t\t\t\t\"npm rebuild*\",\n\t\t\t],\n\t\t},\n\t},\n\tnone: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"none\",\n\t\tauthority: \"advisory\",\n\t\ttools: { allow: [], defaultMode: \"no-tools\" },\n\t\tcommands: { mode: \"none\" },\n\t},\n};\n\nexport function inferLoadoutForRole(role: LoadoutRole): string {\n\tswitch (role) {\n\t\tcase \"planner\":\n\t\t\treturn \"plan\";\n\t\tcase \"explorer\":\n\t\t\treturn \"inspect\";\n\t\tcase \"architect\":\n\t\t\treturn \"architect\";\n\t\tcase \"coder\":\n\t\t\treturn \"code\";\n\t\tcase \"executor\":\n\t\t\treturn \"executor\";\n\t\tcase \"tester\":\n\t\t\treturn \"test\";\n\t\tcase \"reviewer\":\n\t\t\treturn \"review\";\n\t\tcase \"critic\":\n\t\t\treturn \"critic\";\n\t\tcase \"security\":\n\t\t\treturn \"security\";\n\t\tcase \"visual-qa\":\n\t\t\treturn \"visual-qa\";\n\t\tcase \"rhwp-doc\":\n\t\t\treturn \"rhwp-doc\";\n\t\tcase \"package-maintainer\":\n\t\t\treturn \"package-maintainer\";\n\t\tcase \"synthesizer\":\n\t\t\treturn \"plan\";\n\t}\n}\n\nexport function authorityWithinGrant(requested: LoadoutAuthority, grant: LoadoutAuthority): boolean {\n\treturn AUTHORITY_RANK[requested] <= AUTHORITY_RANK[grant];\n}\n\nexport function laneDefaultsForRole(role: LoadoutRole): LaneDefaults {\n\tconst loadout = inferLoadoutForRole(role);\n\tconst profile = BUILTIN_LOADOUTS[loadout];\n\treturn {\n\t\tloadout,\n\t\tauthority: profile.authority,\n\t\tparallelizable: profile.authority !== \"write-scoped\",\n\t\treadOnly:\n\t\t\tprofile.authority === \"read-only\" || profile.authority === \"review-only\" || profile.authority === \"advisory\",\n\t\twritesProductFiles: profile.authority === \"write-scoped\",\n\t};\n}\n\nexport function applyLoadoutProfile(\n\tprofile: LoadoutProfile,\n\tinventory: CapabilityInventory,\n\toptions: { grantAuthority?: LoadoutAuthority } = {},\n): AppliedLoadout {\n\tconst blockers: string[] = [];\n\tconst warnings: string[] = [];\n\t// Deterministic blocker order: authority, then tool/skill/mcp/hook requires.\n\tif (options.grantAuthority && !authorityWithinGrant(profile.authority, options.grantAuthority)) {\n\t\tblockers.push(`loadout authority ${profile.authority} exceeds grant ${options.grantAuthority}`);\n\t}\n\n\tconst activeTools = applyToolGate(profile.tools, inventory.tools, blockers, warnings);\n\tconst activeSkills = applyCapabilityGate(\"skill\", profile.skills, inventory.skills, blockers, warnings);\n\tconst activeMcp = applyCapabilityGate(\"mcp\", profile.mcp, inventory.mcp, blockers, warnings);\n\tconst activeHooks = applyCapabilityGate(\"hook\", profile.hooks, inventory.hooks, blockers, warnings);\n\n\treturn {\n\t\tprofileName: profile.name,\n\t\tauthority: profile.authority,\n\t\tactiveTools,\n\t\tactiveSkills,\n\t\tactiveMcp,\n\t\tactiveHooks,\n\t\tblockers,\n\t\twarnings,\n\t};\n}\n\n/**\n * Fail-closed structural validation of a loadout profile. Errors are returned\n * in a deterministic order: schemaVersion, name, authority, tools, skills, mcp,\n * hooks, commands.\n */\nexport function validateLoadoutProfile(profile: LoadoutProfile): LoadoutValidation {\n\tconst errors: string[] = [];\n\tif (profile.schemaVersion !== \"omk.loadout.v1\") {\n\t\terrors.push(`unknown schemaVersion: ${String(profile.schemaVersion)}`);\n\t}\n\tif (typeof profile.name !== \"string\" || profile.name.trim() === \"\") {\n\t\terrors.push(\"missing loadout name\");\n\t}\n\tif (!(profile.authority in AUTHORITY_RANK)) {\n\t\terrors.push(`unknown authority: ${String(profile.authority)}`);\n\t}\n\tvalidateToolGate(profile.tools, errors);\n\tvalidateCapabilityGate(\"skills\", \"skill\", profile.skills, errors);\n\tvalidateCapabilityGate(\"mcp\", \"mcp\", profile.mcp, errors);\n\tvalidateCapabilityGate(\"hooks\", \"hook\", profile.hooks, errors);\n\tif (profile.commands) {\n\t\tif (!KNOWN_COMMAND_MODES.has(profile.commands.mode)) {\n\t\t\terrors.push(`unknown command mode: ${String(profile.commands.mode)}`);\n\t\t} else if (profile.authority in AUTHORITY_RANK) {\n\t\t\tconst conflict = commandModeAuthorityConflict(profile.commands.mode, profile.authority);\n\t\t\tif (conflict) errors.push(conflict);\n\t\t}\n\t}\n\treturn { valid: errors.length === 0, errors };\n}\n\n/**\n * Derive scheduler readSet/writeSet/parallelizable from a lane role plus the\n * optional paths granted to that lane. Non-writing roles never produce a\n * writeSet. parallelizable is false when a write-scoped lane writes anything,\n * or when any write touches a lockfile, package config, snapshot, or git index.\n */\nexport function deriveSchedulerFields(input: SchedulerDerivationInput): SchedulerFields {\n\tconst defaults = laneDefaultsForRole(input.role);\n\tconst readSet = toAccessSet(input.assignedReadPaths);\n\tconst writeSet = WRITING_ROLES.has(input.role) ? toAccessSet(input.assignedWritePaths) : [];\n\tconst parallelizable = deriveParallelizable(defaults.authority, writeSet);\n\treturn { readSet, writeSet, parallelizable };\n}\n\nfunction deriveParallelizable(authority: LoadoutAuthority, writeSet: readonly LoadoutAccessEntry[]): boolean {\n\tif (writeSet.length === 0) return true;\n\tif (authority === \"write-scoped\") return false;\n\tif (writeSet.some((entry) => isSerializeTriggerPath(entry.path))) return false;\n\treturn true;\n}\n\n/** Lockfile, package config, snapshot, or git-index writes force serialization. */\nexport function isSerializeTriggerPath(path: string): boolean {\n\tconst normalized = path.replaceAll(\"\\\\\", \"/\");\n\tconst base = normalized.slice(normalized.lastIndexOf(\"/\") + 1);\n\tif (LOCKFILE_BASENAMES.has(base)) return true;\n\tif (base === \"package.json\") return true;\n\tif (base.endsWith(\".snap\")) return true;\n\tif (normalized === \".git/index\" || normalized.startsWith(\".git/\") || normalized.includes(\"/.git/\")) return true;\n\treturn false;\n}\n\nfunction toAccessSet(paths: readonly string[] | undefined): LoadoutAccessEntry[] {\n\tif (!paths) return [];\n\tconst seen = new Set<string>();\n\tconst entries: LoadoutAccessEntry[] = [];\n\tfor (const raw of paths) {\n\t\tconst path = raw.trim();\n\t\tif (path === \"\" || seen.has(path)) continue;\n\t\tseen.add(path);\n\t\tentries.push({ path });\n\t}\n\tentries.sort((a, b) => compareString(a.path, b.path));\n\treturn entries;\n}\n\nfunction resourceNames(resources: readonly NamedResource[]): Set<string> {\n\treturn new Set(resources.map((resource) => resource.name));\n}\n\nfunction applyToolGate(\n\tgate: ToolGate,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tconst available = resourceNames(resources);\n\tfor (const required of gate.require ?? []) {\n\t\tif (!available.has(required)) blockers.push(`missing required tool: ${required}`);\n\t}\n\tconst base = gate.defaultMode === \"no-tools\" ? [] : (gate.allow ?? resources.map((resource) => resource.name));\n\tconst excluded = new Set(gate.exclude ?? []);\n\tconst active: string[] = [];\n\tfor (const tool of base) {\n\t\tif (!available.has(tool)) {\n\t\t\twarnings.push(`optional tool not available: ${tool}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!excluded.has(tool)) active.push(tool);\n\t}\n\treturn [...new Set(active)].sort(compareString);\n}\n\nfunction applyCapabilityGate(\n\tkind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tif (!gate) return [];\n\tconst active = new Set<string>();\n\n\t// require: every required selector must resolve, else a deterministic blocker.\n\tfor (const selector of gate.require ?? []) {\n\t\tresolveRequireSelector(kind, selector, resources, blockers, active);\n\t}\n\n\t// allow: union of matches; warn on named-but-missing optional capabilities.\n\tfor (const selector of gate.allow ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) active.add(match.name);\n\t\tfor (const name of selector.names ?? []) {\n\t\t\tif (!resources.some((resource) => resource.name === name && matchesCriteria(selector, resource))) {\n\t\t\t\twarnings.push(`optional ${kind} not available: ${name}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// exclude: applied last.\n\tconst excluded = new Set<string>();\n\tfor (const selector of gate.exclude ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) excluded.add(match.name);\n\t}\n\n\tconst result = [...active].filter((name) => !excluded.has(name));\n\treturn [...new Set(result)].sort(compareString);\n}\n\nfunction resolveRequireSelector(\n\tkind: ResourceKind,\n\tselector: ResourceSelector,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\tactive: Set<string>,\n): void {\n\tif (selector.names && selector.names.length > 0) {\n\t\tfor (const name of selector.names) {\n\t\t\tconst matched = resources.some((resource) => resource.name === name && matchesCriteria(selector, resource));\n\t\t\tif (matched) active.add(name);\n\t\t\telse blockers.push(`missing required ${kind}: ${name}`);\n\t\t}\n\t\treturn;\n\t}\n\tconst matches = matchSelector(selector, resources);\n\tif (matches.length === 0) {\n\t\tblockers.push(`missing required ${kind}: ${describeSelector(selector)}`);\n\t\treturn;\n\t}\n\tfor (const match of matches) active.add(match.name);\n}\n\nfunction matchSelector(selector: ResourceSelector, resources: readonly NamedResource[]): NamedResource[] {\n\treturn resources.filter((resource) => {\n\t\tif (selector.names && !selector.names.includes(resource.name)) return false;\n\t\treturn matchesCriteria(selector, resource);\n\t});\n}\n\nfunction matchesCriteria(selector: ResourceSelector, resource: NamedResource): boolean {\n\tif (resource.kind !== selector.kind) return false;\n\tif (selector.scopes && (resource.scope === undefined || !selector.scopes.includes(resource.scope))) return false;\n\tif (selector.origins && (resource.origin === undefined || !selector.origins.includes(resource.origin))) return false;\n\tif (selector.sources && !selector.sources.some((glob) => globMatch(glob, resource.source ?? \"\"))) return false;\n\tif (selector.paths && !selector.paths.some((glob) => globMatch(glob, resource.path ?? \"\"))) return false;\n\treturn true;\n}\n\nfunction describeSelector(selector: ResourceSelector): string {\n\tconst parts: string[] = [`kind=${selector.kind}`];\n\tif (selector.paths) parts.push(`paths=${selector.paths.join(\",\")}`);\n\tif (selector.sources) parts.push(`sources=${selector.sources.join(\",\")}`);\n\tif (selector.scopes) parts.push(`scopes=${selector.scopes.join(\",\")}`);\n\tif (selector.origins) parts.push(`origins=${selector.origins.join(\",\")}`);\n\treturn parts.join(\" \");\n}\n\nfunction validateToolGate(gate: ToolGate | undefined, errors: string[]): void {\n\tif (!gate) {\n\t\terrors.push(\"missing tools gate\");\n\t\treturn;\n\t}\n\tif (gate.defaultMode !== undefined && !KNOWN_TOOL_DEFAULT_MODES.has(gate.defaultMode)) {\n\t\terrors.push(`unknown tool defaultMode: ${String(gate.defaultMode)}`);\n\t}\n}\n\nfunction validateCapabilityGate(\n\tgateName: string,\n\texpectedKind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\terrors: string[],\n): void {\n\tif (!gate) return;\n\tfor (const group of [\"allow\", \"exclude\", \"require\"] as const) {\n\t\tconst selectors = gate[group];\n\t\tif (!selectors) continue;\n\t\tfor (const selector of selectors) {\n\t\t\tif (!KNOWN_RESOURCE_KINDS.has(selector.kind)) {\n\t\t\t\terrors.push(`unknown resource kind in ${gateName}.${group}: ${String(selector.kind)}`);\n\t\t\t} else if (selector.kind !== expectedKind) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`mismatched selector kind in ${gateName}.${group}: expected ${expectedKind}, got ${selector.kind}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction commandModeAuthorityConflict(mode: CommandMode, authority: LoadoutAuthority): string | undefined {\n\tif (mode === \"scoped-shell\" && authority !== \"write-scoped\") {\n\t\treturn `command mode scoped-shell requires write-scoped authority, got ${authority}`;\n\t}\n\tif (mode === \"tests-only\" && authority !== \"execute-tests\" && authority !== \"write-scoped\") {\n\t\treturn `command mode tests-only requires execute-tests or write-scoped authority, got ${authority}`;\n\t}\n\treturn undefined;\n}\n\nfunction globMatch(glob: string, value: string): boolean {\n\treturn globToRegExp(glob).test(value);\n}\n\nfunction globToRegExp(glob: string): RegExp {\n\tlet pattern = \"\";\n\tfor (let index = 0; index < glob.length; index++) {\n\t\tconst char = glob[index];\n\t\tif (char === \"*\") {\n\t\t\tif (glob[index + 1] === \"*\") {\n\t\t\t\tpattern += \".*\";\n\t\t\t\tindex++;\n\t\t\t} else {\n\t\t\t\tpattern += \"[^/]*\";\n\t\t\t}\n\t\t} else if (char === \"?\") {\n\t\t\tpattern += \".\";\n\t\t} else {\n\t\t\tpattern += char.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\t\t}\n\t}\n\treturn new RegExp(`^${pattern}$`);\n}\n\nfunction compareString(a: string, b: string): number {\n\tif (a < b) return -1;\n\tif (a > b) return 1;\n\treturn 0;\n}\n"]}
1
+ {"version":3,"file":"loadouts.js","sourceRoot":"","sources":["../../src/core/loadouts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure loadout / lane-profile algorithms for the OMK control plane.\n *\n * This module is I/O-free. It owns the loadout schema, built-in presets,\n * capability gating (allow/exclude/require selectors), profile validation, and\n * the derivation of scheduler read/write/parallelizable fields from a lane's\n * optional assigned paths. Runtime wiring (AgentSession tool registry, skill\n * prompt construction, MCP runtime, scheduler admission) lives in sibling\n * modules and consumes the decisions made here.\n *\n * Schema and presets follow the OMK package hardening loadout plan.\n *\n * Erasable TypeScript only (no enum/namespace/parameter properties).\n */\n\nimport type { HookPolicyMetadata } from \"./hooks/index.ts\";\n\nexport type LoadoutAuthority =\n\t| \"advisory\"\n\t| \"read-only\"\n\t| \"execute-tests\"\n\t| \"write-scoped\"\n\t| \"review-only\"\n\t| \"security-review\";\n\nexport type LoadoutRole =\n\t| \"planner\"\n\t| \"explorer\"\n\t| \"architect\"\n\t| \"coder\"\n\t| \"executor\"\n\t| \"tester\"\n\t| \"reviewer\"\n\t| \"critic\"\n\t| \"security\"\n\t| \"visual-qa\"\n\t| \"rhwp-doc\"\n\t| \"synthesizer\"\n\t| \"package-maintainer\";\n\n/** Resource kinds the loadout layer can describe. Only the last four are gated here. */\nexport type ResourceKind = \"extension\" | \"skill\" | \"prompt\" | \"theme\" | \"tool\" | \"mcp\" | \"hook\";\nexport type ResourceOrigin = \"package\" | \"top-level\";\nexport type SourceScope = \"user\" | \"project\" | \"temporary\" | \"builtin\";\nexport type CommandMode = \"none\" | \"read-only-shell\" | \"tests-only\" | \"scoped-shell\";\nexport type ToolDefaultMode = \"default-builtins\" | \"no-tools\" | \"no-builtin-tools\";\n\nexport interface NamedResource {\n\tkind: ResourceKind;\n\tname: string;\n\tsource?: string;\n\tscope?: SourceScope;\n\t/** Package-relative or absolute resource path, when meaningful (skills/prompts). */\n\tpath?: string;\n\torigin?: ResourceOrigin;\n\tpolicy?: HookPolicyMetadata;\n}\n\n/**\n * A selector matches inventory resources by name and/or provenance criteria.\n * A resource matches when its kind equals `kind` and every defined criterion\n * matches (names is an OR over the listed names; paths/sources are OR over globs).\n */\nexport interface ResourceSelector {\n\tkind: ResourceKind;\n\tnames?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.path`. */\n\tpaths?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.source`. */\n\tsources?: readonly string[];\n\tscopes?: readonly SourceScope[];\n\torigins?: readonly ResourceOrigin[];\n\t/** Marker only; requirement is expressed by placement in `CapabilityGate.require`. */\n\trequired?: boolean;\n}\n\n/** Tool gating uses flat name arrays (mapped to SDK tools / setActiveTools). */\nexport interface ToolGate {\n\tallow?: readonly string[];\n\texclude?: readonly string[];\n\trequire?: readonly string[];\n\tdefaultMode?: ToolDefaultMode;\n}\n\n/** Skills / MCP / hooks gating uses selector arrays. */\nexport interface CapabilityGate {\n\tallow?: readonly ResourceSelector[];\n\texclude?: readonly ResourceSelector[];\n\trequire?: readonly ResourceSelector[];\n}\n\nexport interface LoadoutCommands {\n\tmode: CommandMode;\n\tallowPatterns?: readonly string[];\n\tblockPatterns?: readonly string[];\n}\n\nexport interface LoadoutEvidence {\n\trequired: boolean;\n\toutputPattern: string;\n}\n\nexport interface LoadoutProfile {\n\tschemaVersion: \"omk.loadout.v1\";\n\tname: string;\n\tdescription?: string;\n\tauthority: LoadoutAuthority;\n\ttools: ToolGate;\n\tskills?: CapabilityGate;\n\tmcp?: CapabilityGate;\n\thooks?: CapabilityGate;\n\tcommands?: LoadoutCommands;\n\tevidence?: LoadoutEvidence;\n}\n\nexport interface CapabilityInventory {\n\ttools: readonly NamedResource[];\n\tskills: readonly NamedResource[];\n\tmcp: readonly NamedResource[];\n\thooks: readonly NamedResource[];\n}\n\nexport interface LaneDefaults {\n\tloadout: string;\n\tauthority: LoadoutAuthority;\n\tparallelizable: boolean;\n\treadOnly: boolean;\n\twritesProductFiles: boolean;\n}\n\nexport interface AppliedLoadout {\n\tprofileName: string;\n\tauthority: LoadoutAuthority;\n\tactiveTools: string[];\n\tactiveSkills: string[];\n\tactiveMcp: string[];\n\tactiveHooks: string[];\n\tblockers: string[];\n\twarnings: string[];\n}\n\nexport interface LoadoutValidation {\n\tvalid: boolean;\n\terrors: string[];\n}\n\n/** A scheduler access entry; shape matches `AccessSetEntry` in the orchestration layer. */\nexport interface LoadoutAccessEntry {\n\tpath: string;\n\tsymbols?: readonly string[];\n}\n\nexport interface SchedulerFields {\n\treadSet: LoadoutAccessEntry[];\n\twriteSet: LoadoutAccessEntry[];\n\tparallelizable: boolean;\n}\n\nexport interface SchedulerDerivationInput {\n\trole: LoadoutRole;\n\tassignedReadPaths?: readonly string[];\n\tassignedWritePaths?: readonly string[];\n}\n\nconst AUTHORITY_RANK: Record<LoadoutAuthority, number> = {\n\tadvisory: 0,\n\t\"read-only\": 1,\n\t\"review-only\": 1,\n\t\"security-review\": 2,\n\t\"execute-tests\": 3,\n\t\"write-scoped\": 4,\n};\n\nconst KNOWN_RESOURCE_KINDS: ReadonlySet<ResourceKind> = new Set([\n\t\"extension\",\n\t\"skill\",\n\t\"prompt\",\n\t\"theme\",\n\t\"tool\",\n\t\"mcp\",\n\t\"hook\",\n]);\n\nconst KNOWN_COMMAND_MODES: ReadonlySet<CommandMode> = new Set([\n\t\"none\",\n\t\"read-only-shell\",\n\t\"tests-only\",\n\t\"scoped-shell\",\n]);\n\nconst KNOWN_TOOL_DEFAULT_MODES: ReadonlySet<ToolDefaultMode> = new Set([\n\t\"default-builtins\",\n\t\"no-tools\",\n\t\"no-builtin-tools\",\n]);\n\n/** Roles permitted to declare a non-empty writeSet during scheduler derivation. */\nconst WRITING_ROLES: ReadonlySet<LoadoutRole> = new Set([\n\t\"coder\",\n\t\"executor\",\n\t\"tester\",\n\t\"rhwp-doc\",\n\t\"synthesizer\",\n\t\"package-maintainer\",\n]);\n\nconst LOCKFILE_BASENAMES: ReadonlySet<string> = new Set([\n\t\"package-lock.json\",\n\t\"npm-shrinkwrap.json\",\n\t\"yarn.lock\",\n\t\"pnpm-lock.yaml\",\n]);\n\nfunction allowNames(kind: ResourceKind, names: readonly string[]): CapabilityGate {\n\treturn { allow: [{ kind, names }] };\n}\n\nexport const BUILTIN_LOADOUTS: Readonly<Record<string, LoadoutProfile>> = {\n\tinspect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"inspect\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tplan: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"plan\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tarchitect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"architect\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\", \"report_finding\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tcode: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"code\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\texecutor: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"executor\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\", \"verification-before-completion\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\", \"stop-verify\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/implementation.md\" },\n\t},\n\ttest: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"test\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\treview: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"review\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tcritic: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"critic\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tsecurity: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"security\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\t\"visual-qa\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"visual-qa\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"clone-website\",\n\t\t\t\"visual-qa\",\n\t\t\t\"visual-diff\",\n\t\t\t\"visual-regression\",\n\t\t\t\"browser-qa\",\n\t\t\t\"web-quality-audit\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"chrome-devtools\", \"playwright\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"component-spec-before-build\",\n\t\t\t\"visual-diff-after-edit\",\n\t\t\t\"typecheck-after-edit\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\t\"rhwp-doc\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"rhwp-doc\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"rhwp\",\n\t\t\t\"rhwp-doc\",\n\t\t\t\"document-extraction\",\n\t\t\t\"document-conversion\",\n\t\t\t\"technical-writing\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\", \"playwright\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"document-artifact-guard\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"pre-shell-guard\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/rhwp-doc.md\" },\n\t},\n\t\"package-maintainer\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"package-maintainer\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"exact-pin\",\n\t\t\t\"no-lifecycle-scripts\",\n\t\t\t\"security-review\",\n\t\t\t\"verification-before-completion\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"npm-audit-summary\", \"stop-verify\"]),\n\t\tcommands: {\n\t\t\tmode: \"scoped-shell\",\n\t\t\tallowPatterns: [\n\t\t\t\t\"npm install --ignore-scripts*\",\n\t\t\t\t\"npm ci --ignore-scripts*\",\n\t\t\t\t\"npm install --package-lock-only --ignore-scripts*\",\n\t\t\t\t\"node scripts/generate-coding-agent-shrinkwrap.mjs*\",\n\t\t\t],\n\t\t\tblockPatterns: [\n\t\t\t\t\"*@latest*\",\n\t\t\t\t\"npm install *--ignore-scripts=false*\",\n\t\t\t\t\"npm ci *--ignore-scripts=false*\",\n\t\t\t\t\"npm rebuild*\",\n\t\t\t],\n\t\t},\n\t},\n\tnone: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"none\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n};\n\nexport function inferLoadoutForRole(role: LoadoutRole): string {\n\tswitch (role) {\n\t\tcase \"planner\":\n\t\t\treturn \"plan\";\n\t\tcase \"explorer\":\n\t\t\treturn \"inspect\";\n\t\tcase \"architect\":\n\t\t\treturn \"architect\";\n\t\tcase \"coder\":\n\t\t\treturn \"code\";\n\t\tcase \"executor\":\n\t\t\treturn \"executor\";\n\t\tcase \"tester\":\n\t\t\treturn \"test\";\n\t\tcase \"reviewer\":\n\t\t\treturn \"review\";\n\t\tcase \"critic\":\n\t\t\treturn \"critic\";\n\t\tcase \"security\":\n\t\t\treturn \"security\";\n\t\tcase \"visual-qa\":\n\t\t\treturn \"visual-qa\";\n\t\tcase \"rhwp-doc\":\n\t\t\treturn \"rhwp-doc\";\n\t\tcase \"package-maintainer\":\n\t\t\treturn \"package-maintainer\";\n\t\tcase \"synthesizer\":\n\t\t\treturn \"plan\";\n\t}\n}\n\nexport function authorityWithinGrant(requested: LoadoutAuthority, grant: LoadoutAuthority): boolean {\n\treturn AUTHORITY_RANK[requested] <= AUTHORITY_RANK[grant];\n}\n\nexport function laneDefaultsForRole(role: LoadoutRole): LaneDefaults {\n\tconst loadout = inferLoadoutForRole(role);\n\tconst profile = BUILTIN_LOADOUTS[loadout];\n\treturn {\n\t\tloadout,\n\t\tauthority: profile.authority,\n\t\tparallelizable: profile.authority !== \"write-scoped\",\n\t\treadOnly:\n\t\t\tprofile.authority === \"read-only\" || profile.authority === \"review-only\" || profile.authority === \"advisory\",\n\t\twritesProductFiles: profile.authority === \"write-scoped\",\n\t};\n}\n\nexport function applyLoadoutProfile(\n\tprofile: LoadoutProfile,\n\tinventory: CapabilityInventory,\n\toptions: { grantAuthority?: LoadoutAuthority } = {},\n): AppliedLoadout {\n\tconst blockers: string[] = [];\n\tconst warnings: string[] = [];\n\t// Deterministic blocker order: authority, then tool/skill/mcp/hook requires.\n\tif (options.grantAuthority && !authorityWithinGrant(profile.authority, options.grantAuthority)) {\n\t\tblockers.push(`loadout authority ${profile.authority} exceeds grant ${options.grantAuthority}`);\n\t}\n\n\tconst activeTools = applyToolGate(profile.tools, inventory.tools, blockers, warnings);\n\tconst activeSkills = applyCapabilityGate(\"skill\", profile.skills, inventory.skills, blockers, warnings);\n\tconst activeMcp = applyCapabilityGate(\"mcp\", profile.mcp, inventory.mcp, blockers, warnings);\n\tconst activeHooks = applyCapabilityGate(\"hook\", profile.hooks, inventory.hooks, blockers, warnings);\n\n\treturn {\n\t\tprofileName: profile.name,\n\t\tauthority: profile.authority,\n\t\tactiveTools,\n\t\tactiveSkills,\n\t\tactiveMcp,\n\t\tactiveHooks,\n\t\tblockers,\n\t\twarnings,\n\t};\n}\n\n/**\n * Fail-closed structural validation of a loadout profile. Errors are returned\n * in a deterministic order: schemaVersion, name, authority, tools, skills, mcp,\n * hooks, commands.\n */\nexport function validateLoadoutProfile(profile: LoadoutProfile): LoadoutValidation {\n\tconst errors: string[] = [];\n\tif (profile.schemaVersion !== \"omk.loadout.v1\") {\n\t\terrors.push(`unknown schemaVersion: ${String(profile.schemaVersion)}`);\n\t}\n\tif (typeof profile.name !== \"string\" || profile.name.trim() === \"\") {\n\t\terrors.push(\"missing loadout name\");\n\t}\n\tif (!(profile.authority in AUTHORITY_RANK)) {\n\t\terrors.push(`unknown authority: ${String(profile.authority)}`);\n\t}\n\tvalidateToolGate(profile.tools, errors);\n\tvalidateCapabilityGate(\"skills\", \"skill\", profile.skills, errors);\n\tvalidateCapabilityGate(\"mcp\", \"mcp\", profile.mcp, errors);\n\tvalidateCapabilityGate(\"hooks\", \"hook\", profile.hooks, errors);\n\tif (profile.commands) {\n\t\tif (!KNOWN_COMMAND_MODES.has(profile.commands.mode)) {\n\t\t\terrors.push(`unknown command mode: ${String(profile.commands.mode)}`);\n\t\t} else if (profile.authority in AUTHORITY_RANK) {\n\t\t\tconst conflict = commandModeAuthorityConflict(profile.commands.mode, profile.authority);\n\t\t\tif (conflict) errors.push(conflict);\n\t\t}\n\t}\n\treturn { valid: errors.length === 0, errors };\n}\n\n/**\n * Derive scheduler readSet/writeSet/parallelizable from a lane role plus the\n * optional paths granted to that lane. Non-writing roles never produce a\n * writeSet. parallelizable is false when a write-scoped lane writes anything,\n * or when any write touches a lockfile, package config, snapshot, or git index.\n */\nexport function deriveSchedulerFields(input: SchedulerDerivationInput): SchedulerFields {\n\tconst defaults = laneDefaultsForRole(input.role);\n\tconst readSet = toAccessSet(input.assignedReadPaths);\n\tconst writeSet = WRITING_ROLES.has(input.role) ? toAccessSet(input.assignedWritePaths) : [];\n\tconst parallelizable = deriveParallelizable(defaults.authority, writeSet);\n\treturn { readSet, writeSet, parallelizable };\n}\n\nfunction deriveParallelizable(authority: LoadoutAuthority, writeSet: readonly LoadoutAccessEntry[]): boolean {\n\tif (writeSet.length === 0) return true;\n\tif (authority === \"write-scoped\") return false;\n\tif (writeSet.some((entry) => isSerializeTriggerPath(entry.path))) return false;\n\treturn true;\n}\n\n/** Lockfile, package config, snapshot, or git-index writes force serialization. */\nexport function isSerializeTriggerPath(path: string): boolean {\n\tconst normalized = path.replaceAll(\"\\\\\", \"/\");\n\tconst base = normalized.slice(normalized.lastIndexOf(\"/\") + 1);\n\tif (LOCKFILE_BASENAMES.has(base)) return true;\n\tif (base === \"package.json\") return true;\n\tif (base.endsWith(\".snap\")) return true;\n\tif (normalized === \".git/index\" || normalized.startsWith(\".git/\") || normalized.includes(\"/.git/\")) return true;\n\treturn false;\n}\n\nfunction toAccessSet(paths: readonly string[] | undefined): LoadoutAccessEntry[] {\n\tif (!paths) return [];\n\tconst seen = new Set<string>();\n\tconst entries: LoadoutAccessEntry[] = [];\n\tfor (const raw of paths) {\n\t\tconst path = raw.trim();\n\t\tif (path === \"\" || seen.has(path)) continue;\n\t\tseen.add(path);\n\t\tentries.push({ path });\n\t}\n\tentries.sort((a, b) => compareString(a.path, b.path));\n\treturn entries;\n}\n\nfunction resourceNames(resources: readonly NamedResource[]): Set<string> {\n\treturn new Set(resources.map((resource) => resource.name));\n}\n\nfunction applyToolGate(\n\tgate: ToolGate,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tconst available = resourceNames(resources);\n\tfor (const required of gate.require ?? []) {\n\t\tif (!available.has(required)) blockers.push(`missing required tool: ${required}`);\n\t}\n\tconst base = gate.defaultMode === \"no-tools\" ? [] : (gate.allow ?? resources.map((resource) => resource.name));\n\tconst excluded = new Set(gate.exclude ?? []);\n\tconst active: string[] = [];\n\tfor (const tool of base) {\n\t\tif (!available.has(tool)) {\n\t\t\twarnings.push(`optional tool not available: ${tool}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!excluded.has(tool)) active.push(tool);\n\t}\n\treturn [...new Set(active)].sort(compareString);\n}\n\nfunction applyCapabilityGate(\n\tkind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tif (!gate) return [];\n\tconst active = new Set<string>();\n\n\t// require: every required selector must resolve, else a deterministic blocker.\n\tfor (const selector of gate.require ?? []) {\n\t\tresolveRequireSelector(kind, selector, resources, blockers, active);\n\t}\n\n\t// allow: union of matches; warn on named-but-missing optional capabilities.\n\tfor (const selector of gate.allow ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) active.add(match.name);\n\t\tfor (const name of selector.names ?? []) {\n\t\t\tif (!resources.some((resource) => resource.name === name && matchesCriteria(selector, resource))) {\n\t\t\t\twarnings.push(`optional ${kind} not available: ${name}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// exclude: applied last.\n\tconst excluded = new Set<string>();\n\tfor (const selector of gate.exclude ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) excluded.add(match.name);\n\t}\n\n\tconst result = [...active].filter((name) => !excluded.has(name));\n\treturn [...new Set(result)].sort(compareString);\n}\n\nfunction resolveRequireSelector(\n\tkind: ResourceKind,\n\tselector: ResourceSelector,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\tactive: Set<string>,\n): void {\n\tif (selector.names && selector.names.length > 0) {\n\t\tfor (const name of selector.names) {\n\t\t\tconst matched = resources.some((resource) => resource.name === name && matchesCriteria(selector, resource));\n\t\t\tif (matched) active.add(name);\n\t\t\telse blockers.push(`missing required ${kind}: ${name}`);\n\t\t}\n\t\treturn;\n\t}\n\tconst matches = matchSelector(selector, resources);\n\tif (matches.length === 0) {\n\t\tblockers.push(`missing required ${kind}: ${describeSelector(selector)}`);\n\t\treturn;\n\t}\n\tfor (const match of matches) active.add(match.name);\n}\n\nfunction matchSelector(selector: ResourceSelector, resources: readonly NamedResource[]): NamedResource[] {\n\treturn resources.filter((resource) => {\n\t\tif (selector.names && !selector.names.includes(resource.name)) return false;\n\t\treturn matchesCriteria(selector, resource);\n\t});\n}\n\nfunction matchesCriteria(selector: ResourceSelector, resource: NamedResource): boolean {\n\tif (resource.kind !== selector.kind) return false;\n\tif (selector.scopes && (resource.scope === undefined || !selector.scopes.includes(resource.scope))) return false;\n\tif (selector.origins && (resource.origin === undefined || !selector.origins.includes(resource.origin))) return false;\n\tif (selector.sources && !selector.sources.some((glob) => globMatch(glob, resource.source ?? \"\"))) return false;\n\tif (selector.paths && !selector.paths.some((glob) => globMatch(glob, resource.path ?? \"\"))) return false;\n\treturn true;\n}\n\nfunction describeSelector(selector: ResourceSelector): string {\n\tconst parts: string[] = [`kind=${selector.kind}`];\n\tif (selector.paths) parts.push(`paths=${selector.paths.join(\",\")}`);\n\tif (selector.sources) parts.push(`sources=${selector.sources.join(\",\")}`);\n\tif (selector.scopes) parts.push(`scopes=${selector.scopes.join(\",\")}`);\n\tif (selector.origins) parts.push(`origins=${selector.origins.join(\",\")}`);\n\treturn parts.join(\" \");\n}\n\nfunction validateToolGate(gate: ToolGate | undefined, errors: string[]): void {\n\tif (!gate) {\n\t\terrors.push(\"missing tools gate\");\n\t\treturn;\n\t}\n\tif (gate.defaultMode !== undefined && !KNOWN_TOOL_DEFAULT_MODES.has(gate.defaultMode)) {\n\t\terrors.push(`unknown tool defaultMode: ${String(gate.defaultMode)}`);\n\t}\n}\n\nfunction validateCapabilityGate(\n\tgateName: string,\n\texpectedKind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\terrors: string[],\n): void {\n\tif (!gate) return;\n\tfor (const group of [\"allow\", \"exclude\", \"require\"] as const) {\n\t\tconst selectors = gate[group];\n\t\tif (!selectors) continue;\n\t\tfor (const selector of selectors) {\n\t\t\tif (!KNOWN_RESOURCE_KINDS.has(selector.kind)) {\n\t\t\t\terrors.push(`unknown resource kind in ${gateName}.${group}: ${String(selector.kind)}`);\n\t\t\t} else if (selector.kind !== expectedKind) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`mismatched selector kind in ${gateName}.${group}: expected ${expectedKind}, got ${selector.kind}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction commandModeAuthorityConflict(mode: CommandMode, authority: LoadoutAuthority): string | undefined {\n\tif (mode === \"scoped-shell\" && authority !== \"write-scoped\") {\n\t\treturn `command mode scoped-shell requires write-scoped authority, got ${authority}`;\n\t}\n\tif (mode === \"tests-only\" && authority !== \"execute-tests\" && authority !== \"write-scoped\") {\n\t\treturn `command mode tests-only requires execute-tests or write-scoped authority, got ${authority}`;\n\t}\n\treturn undefined;\n}\n\nfunction globMatch(glob: string, value: string): boolean {\n\treturn globToRegExp(glob).test(value);\n}\n\nfunction globToRegExp(glob: string): RegExp {\n\tlet pattern = \"\";\n\tfor (let index = 0; index < glob.length; index++) {\n\t\tconst char = glob[index];\n\t\tif (char === \"*\") {\n\t\t\tif (glob[index + 1] === \"*\") {\n\t\t\t\tpattern += \".*\";\n\t\t\t\tindex++;\n\t\t\t} else {\n\t\t\t\tpattern += \"[^/]*\";\n\t\t\t}\n\t\t} else if (char === \"?\") {\n\t\t\tpattern += \".\";\n\t\t} else {\n\t\t\tpattern += char.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\t\t}\n\t}\n\treturn new RegExp(`^${pattern}$`);\n}\n\nfunction compareString(a: string, b: string): number {\n\tif (a < b) return -1;\n\tif (a > b) return 1;\n\treturn 0;\n}\n"]}
@@ -4,6 +4,14 @@ type MetricsSamplerOptions = {
4
4
  readMemory?: () => {
5
5
  rss: number;
6
6
  };
7
+ readSystemCpuTimes?: () => {
8
+ idle: number;
9
+ total: number;
10
+ };
11
+ readSystemMemory?: () => {
12
+ total: number;
13
+ free: number;
14
+ };
7
15
  cpuCount?: number;
8
16
  emaAlpha?: number;
9
17
  historySize?: number;
@@ -24,6 +32,8 @@ export declare class MetricsSampler {
24
32
  private readonly now;
25
33
  private readonly readCpu;
26
34
  private readonly readMemory;
35
+ private readonly readSystemCpuTimes;
36
+ private readonly readSystemMemory;
27
37
  private timer;
28
38
  private prevCpu;
29
39
  private prevTime;
@@ -38,6 +48,10 @@ export declare class MetricsSampler {
38
48
  private readonly spikeThreshold;
39
49
  private cpuSpikeCount;
40
50
  private wasCpuSpike;
51
+ private prevSysCpu;
52
+ private systemCpuPercent;
53
+ private systemMemoryUsedBytes;
54
+ private systemMemoryTotalBytes;
41
55
  /**
42
56
  * Create a sampler. All dependencies can be injected for deterministic
43
57
  * testing; omitted options default to real process/OS sources.
@@ -54,6 +68,12 @@ export declare class MetricsSampler {
54
68
  getCpuPercent(): number | null;
55
69
  /** The most recently sampled RSS memory size in bytes, or `null` before the first sample. */
56
70
  getMemoryRssBytes(): number | null;
71
+ /** System-wide CPU busy percent (0-100) across all cores, or `null` before the first sample. */
72
+ getSystemCpuPercent(): number | null;
73
+ /** System-wide used memory in bytes (total - free), or `null` before the first sample. */
74
+ getSystemMemoryUsedBytes(): number | null;
75
+ /** System total physical memory in bytes, or `null` before the first sample. */
76
+ getSystemMemoryTotalBytes(): number | null;
57
77
  /** The highest smoothed CPU percent observed since start, or `null` before the first sample. */
58
78
  getCpuPeak(): number | null;
59
79
  getCpuSpikeCount(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"metrics-sampler.d.ts","sourceRoot":"","sources":["../../src/core/metrics-sampler.ts"],"names":[],"mappings":"AAWA,KAAK,qBAAqB,GAAG;IAC5B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC;IACtD,UAAU,CAAC,EAAE,MAAM;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;;;;;;GASG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8C;IACtE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwB;IAEnD,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgB;IAChD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,WAAW,CAAS;IAE5B;;;OAGG;IACH,YAAY,OAAO,CAAC,EAAE,qBAAqB,EAwB1C;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,SAAO,GAAG,IAAI,CAa7B;IAED,2DAA2D;IAC3D,IAAI,IAAI,IAAI,CAaX;IAED,sGAAsG;IACtG,aAAa,IAAI,MAAM,GAAG,IAAI,CAE7B;IAED,6FAA6F;IAC7F,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAEjC;IAED,gGAAgG;IAChG,UAAU,IAAI,MAAM,GAAG,IAAI,CAE1B;IAED,gBAAgB,IAAI,MAAM,CAEzB;IAED;;;OAGG;IACH,gBAAgB,CAAC,MAAM,SAAyB,GAAG,MAAM,GAAG,IAAI,CAc/D;IAED,OAAO,CAAC,MAAM;CA+Cd","sourcesContent":["import * as os from \"node:os\";\n\nconst DEFAULT_EMA_ALPHA = 0.3;\nconst DEFAULT_CPU_HISTORY_SIZE = 120;\nconst DEFAULT_ROLLING_WINDOW_SIZE = 5;\nconst DEFAULT_SPIKE_THRESHOLD = 80;\nconst MIN_CPU_HISTORY_SIZE = 1;\nconst MAX_CPU_HISTORY_SIZE = 120;\nconst MIN_SPIKE_THRESHOLD = 0;\nconst MAX_SPIKE_THRESHOLD = 100;\n\ntype MetricsSamplerOptions = {\n\tnow?: () => number;\n\treadCpu?: (prev?: NodeJS.CpuUsage) => NodeJS.CpuUsage;\n\treadMemory?: () => { rss: number };\n\tcpuCount?: number;\n\temaAlpha?: number;\n\thistorySize?: number;\n\trollingWindowSize?: number;\n\tspikeThreshold?: number;\n};\n\n/**\n * Samples process CPU and memory usage on a fixed interval.\n *\n * CPU% is computed from `process.cpuUsage(prev)` deltas normalized by elapsed\n * wall-clock time and the number of logical CPUs. The raw delta percent is\n * then smoothed with an exponential moving average (EMA). Memory is read from\n * `process.memoryUsage().rss`.\n *\n * The interval timer is `unref()`-ed so it never keeps the process alive.\n */\nexport class MetricsSampler {\n\tprivate readonly now: () => number;\n\tprivate readonly readCpu: (prev?: NodeJS.CpuUsage) => NodeJS.CpuUsage;\n\tprivate readonly readMemory: () => { rss: number };\n\n\tprivate timer: ReturnType<typeof setInterval> | null = null;\n\tprivate prevCpu: NodeJS.CpuUsage | null = null;\n\tprivate prevTime: number | null = null;\n\tprivate cpuPercent: number | null = null;\n\tprivate memoryRssBytes: number | null = null;\n\tprivate cpuCount: number;\n\tprivate cpuPeak: number | null = null;\n\tprivate readonly smoothedHistory: number[] = [];\n\tprivate readonly emaAlpha: number;\n\tprivate readonly historySize: number;\n\tprivate readonly rollingWindowSize: number;\n\tprivate readonly spikeThreshold: number;\n\tprivate cpuSpikeCount = 0;\n\tprivate wasCpuSpike = false;\n\n\t/**\n\t * Create a sampler. All dependencies can be injected for deterministic\n\t * testing; omitted options default to real process/OS sources.\n\t */\n\tconstructor(options?: MetricsSamplerOptions) {\n\t\tthis.now = options?.now ?? (() => Date.now());\n\t\tthis.readCpu = options?.readCpu ?? ((prev?: NodeJS.CpuUsage) => process.cpuUsage(prev));\n\t\tthis.readMemory = options?.readMemory ?? (() => process.memoryUsage());\n\t\tthis.cpuCount = sanitizeInteger(options?.cpuCount, os.cpus().length, 1, Number.MAX_SAFE_INTEGER);\n\t\tthis.emaAlpha = sanitizeNumber(options?.emaAlpha, DEFAULT_EMA_ALPHA, 0, 1);\n\t\tthis.historySize = sanitizeInteger(\n\t\t\toptions?.historySize,\n\t\t\tDEFAULT_CPU_HISTORY_SIZE,\n\t\t\tMIN_CPU_HISTORY_SIZE,\n\t\t\tMAX_CPU_HISTORY_SIZE,\n\t\t);\n\t\tthis.rollingWindowSize = sanitizeInteger(\n\t\t\toptions?.rollingWindowSize,\n\t\t\tMath.min(DEFAULT_ROLLING_WINDOW_SIZE, this.historySize),\n\t\t\tMIN_CPU_HISTORY_SIZE,\n\t\t\tthis.historySize,\n\t\t);\n\t\tthis.spikeThreshold = sanitizeNumber(\n\t\t\toptions?.spikeThreshold,\n\t\t\tDEFAULT_SPIKE_THRESHOLD,\n\t\t\tMIN_SPIKE_THRESHOLD,\n\t\t\tMAX_SPIKE_THRESHOLD,\n\t\t);\n\t}\n\n\t/**\n\t * Start sampling. If already running, the existing timer is stopped and\n\t * restarted with the new interval.\n\t */\n\tstart(intervalMs = 2000): void {\n\t\tthis.stop();\n\t\tthis.prevCpu = this.readCpu();\n\t\tthis.prevTime = this.now();\n\t\tthis.cpuPercent = null;\n\t\tthis.memoryRssBytes = null;\n\t\tthis.cpuPeak = null;\n\t\tthis.cpuSpikeCount = 0;\n\t\tthis.wasCpuSpike = false;\n\t\tthis.smoothedHistory.length = 0;\n\n\t\tthis.timer = setInterval(() => this.sample(), intervalMs);\n\t\tthis.timer.unref();\n\t}\n\n\t/** Stop sampling and reset all cached values to `null`. */\n\tstop(): void {\n\t\tif (this.timer) {\n\t\t\tclearInterval(this.timer);\n\t\t\tthis.timer = null;\n\t\t}\n\t\tthis.prevCpu = null;\n\t\tthis.prevTime = null;\n\t\tthis.cpuPercent = null;\n\t\tthis.memoryRssBytes = null;\n\t\tthis.cpuPeak = null;\n\t\tthis.cpuSpikeCount = 0;\n\t\tthis.wasCpuSpike = false;\n\t\tthis.smoothedHistory.length = 0;\n\t}\n\n\t/** The most recently sampled, EMA-smoothed CPU percent (0-100), or `null` before the first sample. */\n\tgetCpuPercent(): number | null {\n\t\treturn this.cpuPercent;\n\t}\n\n\t/** The most recently sampled RSS memory size in bytes, or `null` before the first sample. */\n\tgetMemoryRssBytes(): number | null {\n\t\treturn this.memoryRssBytes;\n\t}\n\n\t/** The highest smoothed CPU percent observed since start, or `null` before the first sample. */\n\tgetCpuPeak(): number | null {\n\t\treturn this.cpuPeak;\n\t}\n\n\tgetCpuSpikeCount(): number {\n\t\treturn this.cpuSpikeCount;\n\t}\n\n\t/**\n\t * The mean of the last `window` smoothed CPU percent samples, or `null` if\n\t * fewer than `window` samples have been collected.\n\t */\n\tgetCpuRollingAvg(window = this.rollingWindowSize): number | null {\n\t\tif (!Number.isFinite(window) || window <= 0) {\n\t\t\treturn null;\n\t\t}\n\t\tconst sampleWindow = Math.floor(window);\n\t\tif (this.smoothedHistory.length < sampleWindow) {\n\t\t\treturn null;\n\t\t}\n\t\tconst start = this.smoothedHistory.length - sampleWindow;\n\t\tlet sum = 0;\n\t\tfor (let i = start; i < this.smoothedHistory.length; i++) {\n\t\t\tsum += this.smoothedHistory[i];\n\t\t}\n\t\treturn sum / sampleWindow;\n\t}\n\n\tprivate sample(): void {\n\t\tif (!this.prevCpu || this.prevTime === null) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst now = this.now();\n\t\tconst elapsedMs = now - this.prevTime;\n\t\tif (elapsedMs <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst delta = this.readCpu(this.prevCpu);\n\t\tconst deltaMicroseconds = delta.user + delta.system;\n\n\t\t// Convert microseconds of CPU time into a percentage of total CPU capacity.\n\t\t// One core-second per elapsed wall second is 100% of one core; dividing by\n\t\t// cpuCount gives the percentage of total system CPU capacity.\n\t\tconst coreFraction = deltaMicroseconds / (elapsedMs * 1000);\n\t\tconst rawPercent = (coreFraction / this.cpuCount) * 100;\n\t\tconst clampedRaw = clamp(rawPercent, 0, 100);\n\n\t\t// First sample seeds the EMA; subsequent samples blend with prior value.\n\t\tconst smoothed =\n\t\t\tthis.cpuPercent === null ? clampedRaw : this.emaAlpha * clampedRaw + (1 - this.emaAlpha) * this.cpuPercent;\n\n\t\tthis.cpuPercent = smoothed;\n\t\tthis.memoryRssBytes = this.readMemory().rss;\n\t\tthis.smoothedHistory.push(smoothed);\n\t\tif (this.smoothedHistory.length > this.historySize) {\n\t\t\tthis.smoothedHistory.shift();\n\t\t}\n\t\tif (this.cpuPeak === null || smoothed > this.cpuPeak) {\n\t\t\tthis.cpuPeak = smoothed;\n\t\t}\n\t\tconst isCpuSpike = smoothed > this.spikeThreshold;\n\t\tif (isCpuSpike && !this.wasCpuSpike) {\n\t\t\tthis.cpuSpikeCount++;\n\t\t}\n\t\tthis.wasCpuSpike = isCpuSpike;\n\n\t\t// Accumulate the delta so the next sample computes from the same baseline.\n\t\tthis.prevCpu = {\n\t\t\tuser: this.prevCpu.user + delta.user,\n\t\t\tsystem: this.prevCpu.system + delta.system,\n\t\t};\n\t\tthis.prevTime = now;\n\t}\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.max(min, Math.min(max, value));\n}\n\nfunction sanitizeNumber(value: unknown, fallback: number, min: number, max: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\treturn fallback;\n\t}\n\treturn clamp(value, min, max);\n}\n\nfunction sanitizeInteger(value: unknown, fallback: number, min: number, max: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(clamp(value, min, max));\n}\n"]}
1
+ {"version":3,"file":"metrics-sampler.d.ts","sourceRoot":"","sources":["../../src/core/metrics-sampler.ts"],"names":[],"mappings":"AAWA,KAAK,qBAAqB,GAAG;IAC5B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC;IACtD,UAAU,CAAC,EAAE,MAAM;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,kBAAkB,CAAC,EAAE,MAAM;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,gBAAgB,CAAC,EAAE,MAAM;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;;;;;;GASG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8C;IACtE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwB;IACnD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAwC;IAC3E,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwC;IAEzE,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgB;IAChD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAgD;IAClE,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,sBAAsB,CAAuB;IAErD;;;OAGG;IACH,YAAY,OAAO,CAAC,EAAE,qBAAqB,EA0B1C;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,SAAO,GAAG,IAAI,CAiB7B;IAED,2DAA2D;IAC3D,IAAI,IAAI,IAAI,CAiBX;IAED,sGAAsG;IACtG,aAAa,IAAI,MAAM,GAAG,IAAI,CAE7B;IAED,6FAA6F;IAC7F,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAEjC;IAED,gGAAgG;IAChG,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAEnC;IAED,0FAA0F;IAC1F,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAExC;IAED,gFAAgF;IAChF,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAEzC;IAED,gGAAgG;IAChG,UAAU,IAAI,MAAM,GAAG,IAAI,CAE1B;IAED,gBAAgB,IAAI,MAAM,CAEzB;IAED;;;OAGG;IACH,gBAAgB,CAAC,MAAM,SAAyB,GAAG,MAAM,GAAG,IAAI,CAc/D;IAED,OAAO,CAAC,MAAM;CA+Dd","sourcesContent":["import * as os from \"node:os\";\n\nconst DEFAULT_EMA_ALPHA = 0.3;\nconst DEFAULT_CPU_HISTORY_SIZE = 120;\nconst DEFAULT_ROLLING_WINDOW_SIZE = 5;\nconst DEFAULT_SPIKE_THRESHOLD = 80;\nconst MIN_CPU_HISTORY_SIZE = 1;\nconst MAX_CPU_HISTORY_SIZE = 120;\nconst MIN_SPIKE_THRESHOLD = 0;\nconst MAX_SPIKE_THRESHOLD = 100;\n\ntype MetricsSamplerOptions = {\n\tnow?: () => number;\n\treadCpu?: (prev?: NodeJS.CpuUsage) => NodeJS.CpuUsage;\n\treadMemory?: () => { rss: number };\n\treadSystemCpuTimes?: () => { idle: number; total: number };\n\treadSystemMemory?: () => { total: number; free: number };\n\tcpuCount?: number;\n\temaAlpha?: number;\n\thistorySize?: number;\n\trollingWindowSize?: number;\n\tspikeThreshold?: number;\n};\n\n/**\n * Samples process CPU and memory usage on a fixed interval.\n *\n * CPU% is computed from `process.cpuUsage(prev)` deltas normalized by elapsed\n * wall-clock time and the number of logical CPUs. The raw delta percent is\n * then smoothed with an exponential moving average (EMA). Memory is read from\n * `process.memoryUsage().rss`.\n *\n * The interval timer is `unref()`-ed so it never keeps the process alive.\n */\nexport class MetricsSampler {\n\tprivate readonly now: () => number;\n\tprivate readonly readCpu: (prev?: NodeJS.CpuUsage) => NodeJS.CpuUsage;\n\tprivate readonly readMemory: () => { rss: number };\n\tprivate readonly readSystemCpuTimes: () => { idle: number; total: number };\n\tprivate readonly readSystemMemory: () => { total: number; free: number };\n\n\tprivate timer: ReturnType<typeof setInterval> | null = null;\n\tprivate prevCpu: NodeJS.CpuUsage | null = null;\n\tprivate prevTime: number | null = null;\n\tprivate cpuPercent: number | null = null;\n\tprivate memoryRssBytes: number | null = null;\n\tprivate cpuCount: number;\n\tprivate cpuPeak: number | null = null;\n\tprivate readonly smoothedHistory: number[] = [];\n\tprivate readonly emaAlpha: number;\n\tprivate readonly historySize: number;\n\tprivate readonly rollingWindowSize: number;\n\tprivate readonly spikeThreshold: number;\n\tprivate cpuSpikeCount = 0;\n\tprivate wasCpuSpike = false;\n\tprivate prevSysCpu: { idle: number; total: number } | null = null;\n\tprivate systemCpuPercent: number | null = null;\n\tprivate systemMemoryUsedBytes: number | null = null;\n\tprivate systemMemoryTotalBytes: number | null = null;\n\n\t/**\n\t * Create a sampler. All dependencies can be injected for deterministic\n\t * testing; omitted options default to real process/OS sources.\n\t */\n\tconstructor(options?: MetricsSamplerOptions) {\n\t\tthis.now = options?.now ?? (() => Date.now());\n\t\tthis.readCpu = options?.readCpu ?? ((prev?: NodeJS.CpuUsage) => process.cpuUsage(prev));\n\t\tthis.readMemory = options?.readMemory ?? (() => process.memoryUsage());\n\t\tthis.cpuCount = sanitizeInteger(options?.cpuCount, os.cpus().length, 1, Number.MAX_SAFE_INTEGER);\n\t\tthis.emaAlpha = sanitizeNumber(options?.emaAlpha, DEFAULT_EMA_ALPHA, 0, 1);\n\t\tthis.historySize = sanitizeInteger(\n\t\t\toptions?.historySize,\n\t\t\tDEFAULT_CPU_HISTORY_SIZE,\n\t\t\tMIN_CPU_HISTORY_SIZE,\n\t\t\tMAX_CPU_HISTORY_SIZE,\n\t\t);\n\t\tthis.rollingWindowSize = sanitizeInteger(\n\t\t\toptions?.rollingWindowSize,\n\t\t\tMath.min(DEFAULT_ROLLING_WINDOW_SIZE, this.historySize),\n\t\t\tMIN_CPU_HISTORY_SIZE,\n\t\t\tthis.historySize,\n\t\t);\n\t\tthis.spikeThreshold = sanitizeNumber(\n\t\t\toptions?.spikeThreshold,\n\t\t\tDEFAULT_SPIKE_THRESHOLD,\n\t\t\tMIN_SPIKE_THRESHOLD,\n\t\t\tMAX_SPIKE_THRESHOLD,\n\t\t);\n\t\tthis.readSystemCpuTimes = options?.readSystemCpuTimes ?? (() => readOsCpuTimes());\n\t\tthis.readSystemMemory = options?.readSystemMemory ?? (() => ({ total: os.totalmem(), free: os.freemem() }));\n\t}\n\n\t/**\n\t * Start sampling. If already running, the existing timer is stopped and\n\t * restarted with the new interval.\n\t */\n\tstart(intervalMs = 2000): void {\n\t\tthis.stop();\n\t\tthis.prevCpu = this.readCpu();\n\t\tthis.prevTime = this.now();\n\t\tthis.cpuPercent = null;\n\t\tthis.memoryRssBytes = null;\n\t\tthis.prevSysCpu = this.readSystemCpuTimes();\n\t\tthis.systemCpuPercent = null;\n\t\tthis.systemMemoryUsedBytes = null;\n\t\tthis.systemMemoryTotalBytes = null;\n\t\tthis.cpuPeak = null;\n\t\tthis.cpuSpikeCount = 0;\n\t\tthis.wasCpuSpike = false;\n\t\tthis.smoothedHistory.length = 0;\n\n\t\tthis.timer = setInterval(() => this.sample(), intervalMs);\n\t\tthis.timer.unref();\n\t}\n\n\t/** Stop sampling and reset all cached values to `null`. */\n\tstop(): void {\n\t\tif (this.timer) {\n\t\t\tclearInterval(this.timer);\n\t\t\tthis.timer = null;\n\t\t}\n\t\tthis.prevCpu = null;\n\t\tthis.prevTime = null;\n\t\tthis.cpuPercent = null;\n\t\tthis.memoryRssBytes = null;\n\t\tthis.cpuPeak = null;\n\t\tthis.cpuSpikeCount = 0;\n\t\tthis.wasCpuSpike = false;\n\t\tthis.prevSysCpu = null;\n\t\tthis.systemCpuPercent = null;\n\t\tthis.systemMemoryUsedBytes = null;\n\t\tthis.systemMemoryTotalBytes = null;\n\t\tthis.smoothedHistory.length = 0;\n\t}\n\n\t/** The most recently sampled, EMA-smoothed CPU percent (0-100), or `null` before the first sample. */\n\tgetCpuPercent(): number | null {\n\t\treturn this.cpuPercent;\n\t}\n\n\t/** The most recently sampled RSS memory size in bytes, or `null` before the first sample. */\n\tgetMemoryRssBytes(): number | null {\n\t\treturn this.memoryRssBytes;\n\t}\n\n\t/** System-wide CPU busy percent (0-100) across all cores, or `null` before the first sample. */\n\tgetSystemCpuPercent(): number | null {\n\t\treturn this.systemCpuPercent;\n\t}\n\n\t/** System-wide used memory in bytes (total - free), or `null` before the first sample. */\n\tgetSystemMemoryUsedBytes(): number | null {\n\t\treturn this.systemMemoryUsedBytes;\n\t}\n\n\t/** System total physical memory in bytes, or `null` before the first sample. */\n\tgetSystemMemoryTotalBytes(): number | null {\n\t\treturn this.systemMemoryTotalBytes;\n\t}\n\n\t/** The highest smoothed CPU percent observed since start, or `null` before the first sample. */\n\tgetCpuPeak(): number | null {\n\t\treturn this.cpuPeak;\n\t}\n\n\tgetCpuSpikeCount(): number {\n\t\treturn this.cpuSpikeCount;\n\t}\n\n\t/**\n\t * The mean of the last `window` smoothed CPU percent samples, or `null` if\n\t * fewer than `window` samples have been collected.\n\t */\n\tgetCpuRollingAvg(window = this.rollingWindowSize): number | null {\n\t\tif (!Number.isFinite(window) || window <= 0) {\n\t\t\treturn null;\n\t\t}\n\t\tconst sampleWindow = Math.floor(window);\n\t\tif (this.smoothedHistory.length < sampleWindow) {\n\t\t\treturn null;\n\t\t}\n\t\tconst start = this.smoothedHistory.length - sampleWindow;\n\t\tlet sum = 0;\n\t\tfor (let i = start; i < this.smoothedHistory.length; i++) {\n\t\t\tsum += this.smoothedHistory[i];\n\t\t}\n\t\treturn sum / sampleWindow;\n\t}\n\n\tprivate sample(): void {\n\t\tif (!this.prevCpu || this.prevTime === null) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst now = this.now();\n\t\tconst elapsedMs = now - this.prevTime;\n\t\tif (elapsedMs <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst delta = this.readCpu(this.prevCpu);\n\t\tconst deltaMicroseconds = delta.user + delta.system;\n\n\t\t// Convert microseconds of CPU time into a percentage of total CPU capacity.\n\t\t// One core-second per elapsed wall second is 100% of one core; dividing by\n\t\t// cpuCount gives the percentage of total system CPU capacity.\n\t\tconst coreFraction = deltaMicroseconds / (elapsedMs * 1000);\n\t\tconst rawPercent = (coreFraction / this.cpuCount) * 100;\n\t\tconst clampedRaw = clamp(rawPercent, 0, 100);\n\n\t\t// First sample seeds the EMA; subsequent samples blend with prior value.\n\t\tconst smoothed =\n\t\t\tthis.cpuPercent === null ? clampedRaw : this.emaAlpha * clampedRaw + (1 - this.emaAlpha) * this.cpuPercent;\n\n\t\tthis.cpuPercent = smoothed;\n\t\tthis.memoryRssBytes = this.readMemory().rss;\n\n\t\t// System-wide sampling (whole computer): CPU busy% from os.cpus() time\n\t\t// deltas, memory from totalmem/freemem.\n\t\tif (this.prevSysCpu) {\n\t\t\tconst sys = this.readSystemCpuTimes();\n\t\t\tconst totalDelta = sys.total - this.prevSysCpu.total;\n\t\t\tconst idleDelta = sys.idle - this.prevSysCpu.idle;\n\t\t\tif (totalDelta > 0) {\n\t\t\t\tthis.systemCpuPercent = clamp(((totalDelta - idleDelta) / totalDelta) * 100, 0, 100);\n\t\t\t}\n\t\t\tthis.prevSysCpu = sys;\n\t\t}\n\t\tconst sysMem = this.readSystemMemory();\n\t\tthis.systemMemoryTotalBytes = sysMem.total;\n\t\tthis.systemMemoryUsedBytes = Math.max(0, sysMem.total - sysMem.free);\n\n\t\tthis.smoothedHistory.push(smoothed);\n\t\tif (this.smoothedHistory.length > this.historySize) {\n\t\t\tthis.smoothedHistory.shift();\n\t\t}\n\t\tif (this.cpuPeak === null || smoothed > this.cpuPeak) {\n\t\t\tthis.cpuPeak = smoothed;\n\t\t}\n\t\tconst isCpuSpike = smoothed > this.spikeThreshold;\n\t\tif (isCpuSpike && !this.wasCpuSpike) {\n\t\t\tthis.cpuSpikeCount++;\n\t\t}\n\t\tthis.wasCpuSpike = isCpuSpike;\n\n\t\t// Accumulate the delta so the next sample computes from the same baseline.\n\t\tthis.prevCpu = {\n\t\t\tuser: this.prevCpu.user + delta.user,\n\t\t\tsystem: this.prevCpu.system + delta.system,\n\t\t};\n\t\tthis.prevTime = now;\n\t}\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.max(min, Math.min(max, value));\n}\n\n/** Aggregate os.cpus() times into { idle, total } jiffies (ms) across all cores. */\nfunction readOsCpuTimes(): { idle: number; total: number } {\n\tlet idle = 0;\n\tlet total = 0;\n\tfor (const cpu of os.cpus()) {\n\t\tidle += cpu.times.idle;\n\t\ttotal += cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.idle + cpu.times.irq;\n\t}\n\treturn { idle, total };\n}\n\nfunction sanitizeNumber(value: unknown, fallback: number, min: number, max: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\treturn fallback;\n\t}\n\treturn clamp(value, min, max);\n}\n\nfunction sanitizeInteger(value: unknown, fallback: number, min: number, max: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(clamp(value, min, max));\n}\n"]}
@@ -21,6 +21,8 @@ export class MetricsSampler {
21
21
  now;
22
22
  readCpu;
23
23
  readMemory;
24
+ readSystemCpuTimes;
25
+ readSystemMemory;
24
26
  timer = null;
25
27
  prevCpu = null;
26
28
  prevTime = null;
@@ -35,6 +37,10 @@ export class MetricsSampler {
35
37
  spikeThreshold;
36
38
  cpuSpikeCount = 0;
37
39
  wasCpuSpike = false;
40
+ prevSysCpu = null;
41
+ systemCpuPercent = null;
42
+ systemMemoryUsedBytes = null;
43
+ systemMemoryTotalBytes = null;
38
44
  /**
39
45
  * Create a sampler. All dependencies can be injected for deterministic
40
46
  * testing; omitted options default to real process/OS sources.
@@ -48,6 +54,8 @@ export class MetricsSampler {
48
54
  this.historySize = sanitizeInteger(options?.historySize, DEFAULT_CPU_HISTORY_SIZE, MIN_CPU_HISTORY_SIZE, MAX_CPU_HISTORY_SIZE);
49
55
  this.rollingWindowSize = sanitizeInteger(options?.rollingWindowSize, Math.min(DEFAULT_ROLLING_WINDOW_SIZE, this.historySize), MIN_CPU_HISTORY_SIZE, this.historySize);
50
56
  this.spikeThreshold = sanitizeNumber(options?.spikeThreshold, DEFAULT_SPIKE_THRESHOLD, MIN_SPIKE_THRESHOLD, MAX_SPIKE_THRESHOLD);
57
+ this.readSystemCpuTimes = options?.readSystemCpuTimes ?? (() => readOsCpuTimes());
58
+ this.readSystemMemory = options?.readSystemMemory ?? (() => ({ total: os.totalmem(), free: os.freemem() }));
51
59
  }
52
60
  /**
53
61
  * Start sampling. If already running, the existing timer is stopped and
@@ -59,6 +67,10 @@ export class MetricsSampler {
59
67
  this.prevTime = this.now();
60
68
  this.cpuPercent = null;
61
69
  this.memoryRssBytes = null;
70
+ this.prevSysCpu = this.readSystemCpuTimes();
71
+ this.systemCpuPercent = null;
72
+ this.systemMemoryUsedBytes = null;
73
+ this.systemMemoryTotalBytes = null;
62
74
  this.cpuPeak = null;
63
75
  this.cpuSpikeCount = 0;
64
76
  this.wasCpuSpike = false;
@@ -79,6 +91,10 @@ export class MetricsSampler {
79
91
  this.cpuPeak = null;
80
92
  this.cpuSpikeCount = 0;
81
93
  this.wasCpuSpike = false;
94
+ this.prevSysCpu = null;
95
+ this.systemCpuPercent = null;
96
+ this.systemMemoryUsedBytes = null;
97
+ this.systemMemoryTotalBytes = null;
82
98
  this.smoothedHistory.length = 0;
83
99
  }
84
100
  /** The most recently sampled, EMA-smoothed CPU percent (0-100), or `null` before the first sample. */
@@ -89,6 +105,18 @@ export class MetricsSampler {
89
105
  getMemoryRssBytes() {
90
106
  return this.memoryRssBytes;
91
107
  }
108
+ /** System-wide CPU busy percent (0-100) across all cores, or `null` before the first sample. */
109
+ getSystemCpuPercent() {
110
+ return this.systemCpuPercent;
111
+ }
112
+ /** System-wide used memory in bytes (total - free), or `null` before the first sample. */
113
+ getSystemMemoryUsedBytes() {
114
+ return this.systemMemoryUsedBytes;
115
+ }
116
+ /** System total physical memory in bytes, or `null` before the first sample. */
117
+ getSystemMemoryTotalBytes() {
118
+ return this.systemMemoryTotalBytes;
119
+ }
92
120
  /** The highest smoothed CPU percent observed since start, or `null` before the first sample. */
93
121
  getCpuPeak() {
94
122
  return this.cpuPeak;
@@ -136,6 +164,20 @@ export class MetricsSampler {
136
164
  const smoothed = this.cpuPercent === null ? clampedRaw : this.emaAlpha * clampedRaw + (1 - this.emaAlpha) * this.cpuPercent;
137
165
  this.cpuPercent = smoothed;
138
166
  this.memoryRssBytes = this.readMemory().rss;
167
+ // System-wide sampling (whole computer): CPU busy% from os.cpus() time
168
+ // deltas, memory from totalmem/freemem.
169
+ if (this.prevSysCpu) {
170
+ const sys = this.readSystemCpuTimes();
171
+ const totalDelta = sys.total - this.prevSysCpu.total;
172
+ const idleDelta = sys.idle - this.prevSysCpu.idle;
173
+ if (totalDelta > 0) {
174
+ this.systemCpuPercent = clamp(((totalDelta - idleDelta) / totalDelta) * 100, 0, 100);
175
+ }
176
+ this.prevSysCpu = sys;
177
+ }
178
+ const sysMem = this.readSystemMemory();
179
+ this.systemMemoryTotalBytes = sysMem.total;
180
+ this.systemMemoryUsedBytes = Math.max(0, sysMem.total - sysMem.free);
139
181
  this.smoothedHistory.push(smoothed);
140
182
  if (this.smoothedHistory.length > this.historySize) {
141
183
  this.smoothedHistory.shift();
@@ -159,6 +201,16 @@ export class MetricsSampler {
159
201
  function clamp(value, min, max) {
160
202
  return Math.max(min, Math.min(max, value));
161
203
  }
204
+ /** Aggregate os.cpus() times into { idle, total } jiffies (ms) across all cores. */
205
+ function readOsCpuTimes() {
206
+ let idle = 0;
207
+ let total = 0;
208
+ for (const cpu of os.cpus()) {
209
+ idle += cpu.times.idle;
210
+ total += cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.idle + cpu.times.irq;
211
+ }
212
+ return { idle, total };
213
+ }
162
214
  function sanitizeNumber(value, fallback, min, max) {
163
215
  if (typeof value !== "number" || !Number.isFinite(value)) {
164
216
  return fallback;