@alan512/experienceengine 0.1.2 → 0.1.3

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 (215) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.mcp.json +4 -8
  3. package/LICENSE +21 -0
  4. package/README.md +158 -47
  5. package/README.zh-CN.md +178 -57
  6. package/dist/adapters/codex/instruction-template.d.ts +3 -0
  7. package/dist/adapters/codex/instruction-template.js +12 -0
  8. package/dist/adapters/codex/instruction-template.js.map +1 -0
  9. package/dist/adapters/codex/mcp-server.d.ts +38 -41
  10. package/dist/adapters/codex/mcp-server.js +107 -338
  11. package/dist/adapters/codex/mcp-server.js.map +1 -1
  12. package/dist/analyzer/llm-learning-gate.js +39 -0
  13. package/dist/analyzer/llm-learning-gate.js.map +1 -1
  14. package/dist/cli/commands/claude-hook.js +12 -3
  15. package/dist/cli/commands/claude-hook.js.map +1 -1
  16. package/dist/cli/commands/config.js +88 -2
  17. package/dist/cli/commands/config.js.map +1 -1
  18. package/dist/cli/commands/doctor.d.ts +4 -28
  19. package/dist/cli/commands/doctor.js +136 -68
  20. package/dist/cli/commands/doctor.js.map +1 -1
  21. package/dist/cli/commands/feedback.js +4 -0
  22. package/dist/cli/commands/feedback.js.map +1 -1
  23. package/dist/cli/commands/init.d.ts +28 -0
  24. package/dist/cli/commands/init.js +419 -0
  25. package/dist/cli/commands/init.js.map +1 -0
  26. package/dist/cli/commands/inspect.js +203 -37
  27. package/dist/cli/commands/inspect.js.map +1 -1
  28. package/dist/cli/commands/install.js +9 -0
  29. package/dist/cli/commands/install.js.map +1 -1
  30. package/dist/cli/commands/maintenance.js +1 -1
  31. package/dist/cli/commands/maintenance.js.map +1 -1
  32. package/dist/cli/commands/mcp-server.js +4 -0
  33. package/dist/cli/commands/mcp-server.js.map +1 -1
  34. package/dist/cli/commands/status.js +57 -7
  35. package/dist/cli/commands/status.js.map +1 -1
  36. package/dist/cli/dispatch.js +22 -7
  37. package/dist/cli/dispatch.js.map +1 -1
  38. package/dist/cli/state-model.d.ts +14 -0
  39. package/dist/cli/state-model.js +23 -0
  40. package/dist/cli/state-model.js.map +1 -0
  41. package/dist/config/config-schema.d.ts +32 -0
  42. package/dist/config/config-schema.js +26 -0
  43. package/dist/config/config-schema.js.map +1 -1
  44. package/dist/config/default-config.js +3 -0
  45. package/dist/config/default-config.js.map +1 -1
  46. package/dist/config/load-config.js +19 -1
  47. package/dist/config/load-config.js.map +1 -1
  48. package/dist/config/path-resolver.d.ts +0 -1
  49. package/dist/config/path-resolver.js +0 -2
  50. package/dist/config/path-resolver.js.map +1 -1
  51. package/dist/config/runtime-env.d.ts +8 -0
  52. package/dist/config/runtime-env.js +14 -0
  53. package/dist/config/runtime-env.js.map +1 -0
  54. package/dist/config/secrets-store.d.ts +15 -0
  55. package/dist/config/secrets-store.js +56 -0
  56. package/dist/config/secrets-store.js.map +1 -0
  57. package/dist/config/settings-store.d.ts +10 -0
  58. package/dist/config/settings-store.js +44 -0
  59. package/dist/config/settings-store.js.map +1 -1
  60. package/dist/controller/candidate-retriever.d.ts +35 -2
  61. package/dist/controller/candidate-retriever.js +189 -10
  62. package/dist/controller/candidate-retriever.js.map +1 -1
  63. package/dist/controller/injection-renderer.js +52 -1
  64. package/dist/controller/injection-renderer.js.map +1 -1
  65. package/dist/controller/injection-scorecard.d.ts +14 -2
  66. package/dist/controller/injection-scorecard.js +18 -1
  67. package/dist/controller/injection-scorecard.js.map +1 -1
  68. package/dist/controller/intervention-controller.d.ts +15 -2
  69. package/dist/controller/intervention-controller.js +173 -11
  70. package/dist/controller/intervention-controller.js.map +1 -1
  71. package/dist/controller/lexical-retriever.d.ts +14 -0
  72. package/dist/controller/lexical-retriever.js +117 -0
  73. package/dist/controller/lexical-retriever.js.map +1 -0
  74. package/dist/controller/model-reranker.d.ts +20 -0
  75. package/dist/controller/model-reranker.js +187 -0
  76. package/dist/controller/model-reranker.js.map +1 -0
  77. package/dist/controller/node-ranker.js +1 -0
  78. package/dist/controller/node-ranker.js.map +1 -1
  79. package/dist/controller/query-rewrite.d.ts +8 -0
  80. package/dist/controller/query-rewrite.js +69 -0
  81. package/dist/controller/query-rewrite.js.map +1 -0
  82. package/dist/controller/trigger-evaluator.d.ts +23 -2
  83. package/dist/controller/trigger-evaluator.js +57 -3
  84. package/dist/controller/trigger-evaluator.js.map +1 -1
  85. package/dist/distillation/experience-family.d.ts +4 -0
  86. package/dist/distillation/experience-family.js +14 -0
  87. package/dist/distillation/experience-family.js.map +1 -0
  88. package/dist/distillation/host-llm.d.ts +1 -0
  89. package/dist/distillation/host-llm.js +5 -1
  90. package/dist/distillation/host-llm.js.map +1 -1
  91. package/dist/distillation/llm-distiller.js +4 -0
  92. package/dist/distillation/llm-distiller.js.map +1 -1
  93. package/dist/distillation/merge-decider.js +4 -0
  94. package/dist/distillation/merge-decider.js.map +1 -1
  95. package/dist/distillation/prompt-contract.d.ts +1 -1
  96. package/dist/distillation/prompt-contract.js +3 -0
  97. package/dist/distillation/prompt-contract.js.map +1 -1
  98. package/dist/distillation/queue-worker.js +57 -7
  99. package/dist/distillation/queue-worker.js.map +1 -1
  100. package/dist/feedback/state-transition.js +9 -0
  101. package/dist/feedback/state-transition.js.map +1 -1
  102. package/dist/input/input-adapter.js +2 -1
  103. package/dist/input/input-adapter.js.map +1 -1
  104. package/dist/input/outcome-resolver.js +5 -5
  105. package/dist/input/outcome-resolver.js.map +1 -1
  106. package/dist/input/tasktype-resolver.js +2 -0
  107. package/dist/input/tasktype-resolver.js.map +1 -1
  108. package/dist/input/tool-event-significance.d.ts +5 -0
  109. package/dist/input/tool-event-significance.js +7 -0
  110. package/dist/input/tool-event-significance.js.map +1 -0
  111. package/dist/install/claude-code-doctor.d.ts +7 -2
  112. package/dist/install/claude-code-doctor.js +38 -9
  113. package/dist/install/claude-code-doctor.js.map +1 -1
  114. package/dist/install/claude-marketplace-state.d.ts +14 -0
  115. package/dist/install/claude-marketplace-state.js +47 -0
  116. package/dist/install/claude-marketplace-state.js.map +1 -0
  117. package/dist/install/codex-installer.d.ts +18 -0
  118. package/dist/install/codex-installer.js +91 -1
  119. package/dist/install/codex-installer.js.map +1 -1
  120. package/dist/install/openclaw-installer.d.ts +7 -0
  121. package/dist/install/openclaw-installer.js +16 -0
  122. package/dist/install/openclaw-installer.js.map +1 -1
  123. package/dist/install/public-install.d.ts +14 -4
  124. package/dist/install/public-install.js +20 -7
  125. package/dist/install/public-install.js.map +1 -1
  126. package/dist/interaction/repo-summary.d.ts +3 -17
  127. package/dist/interaction/repo-summary.js +10 -27
  128. package/dist/interaction/repo-summary.js.map +1 -1
  129. package/dist/interaction/service.d.ts +44 -95
  130. package/dist/interaction/service.js +333 -248
  131. package/dist/interaction/service.js.map +1 -1
  132. package/dist/maintenance/scope-merge.d.ts +0 -1
  133. package/dist/maintenance/scope-merge.js +0 -20
  134. package/dist/maintenance/scope-merge.js.map +1 -1
  135. package/dist/plugin/openclaw-plugin.d.ts +23 -0
  136. package/dist/plugin/openclaw-plugin.js +86 -6
  137. package/dist/plugin/openclaw-plugin.js.map +1 -1
  138. package/dist/plugin/openclaw-routine-interaction.d.ts +6 -0
  139. package/dist/plugin/openclaw-routine-interaction.js +296 -0
  140. package/dist/plugin/openclaw-routine-interaction.js.map +1 -0
  141. package/dist/runtime/service.d.ts +0 -1
  142. package/dist/runtime/service.js +20 -29
  143. package/dist/runtime/service.js.map +1 -1
  144. package/dist/store/sqlite/db.js +9 -0
  145. package/dist/store/sqlite/db.js.map +1 -1
  146. package/dist/store/sqlite/repositories/candidate-repo.js +8 -2
  147. package/dist/store/sqlite/repositories/candidate-repo.js.map +1 -1
  148. package/dist/store/sqlite/repositories/injection-repo.d.ts +1 -0
  149. package/dist/store/sqlite/repositories/injection-repo.js +11 -0
  150. package/dist/store/sqlite/repositories/injection-repo.js.map +1 -1
  151. package/dist/store/sqlite/repositories/input-record-repo.d.ts +2 -0
  152. package/dist/store/sqlite/repositories/input-record-repo.js +22 -0
  153. package/dist/store/sqlite/repositories/input-record-repo.js.map +1 -1
  154. package/dist/store/sqlite/repositories/node-repo.js +17 -2
  155. package/dist/store/sqlite/repositories/node-repo.js.map +1 -1
  156. package/dist/store/sqlite/repositories/task-run-repo.d.ts +2 -0
  157. package/dist/store/sqlite/repositories/task-run-repo.js +18 -2
  158. package/dist/store/sqlite/repositories/task-run-repo.js.map +1 -1
  159. package/dist/store/sqlite/schema.sql +9 -49
  160. package/dist/store/vector/api-embedding-provider.d.ts +2 -0
  161. package/dist/store/vector/api-embedding-provider.js +23 -19
  162. package/dist/store/vector/api-embedding-provider.js.map +1 -1
  163. package/dist/store/vector/embeddings.d.ts +1 -1
  164. package/dist/store/vector/embeddings.js +4 -1
  165. package/dist/store/vector/embeddings.js.map +1 -1
  166. package/dist/types/domain.d.ts +30 -46
  167. package/dist/types/plugin.d.ts +2 -1
  168. package/docs/releases/v0.1.2.md +3 -3
  169. package/docs/releases/v0.1.3.md +94 -0
  170. package/docs/user-guide.md +226 -123
  171. package/openclaw.plugin.json +1 -1
  172. package/package.json +3 -2
  173. package/plugins/claude-code-experienceengine/.claude-plugin/plugin.json +1 -1
  174. package/plugins/claude-code-experienceengine/.mcp.json +4 -3
  175. package/plugins/claude-code-experienceengine/scripts/claude-hook.sh +30 -1
  176. package/plugins/claude-code-experienceengine/scripts/install-deps.sh +41 -6
  177. package/dist/cli/commands/pack.d.ts +0 -1
  178. package/dist/cli/commands/pack.js +0 -321
  179. package/dist/cli/commands/pack.js.map +0 -1
  180. package/dist/compiler/agents-renderer.d.ts +0 -4
  181. package/dist/compiler/agents-renderer.js +0 -105
  182. package/dist/compiler/agents-renderer.js.map +0 -1
  183. package/dist/compiler/claude-renderer.d.ts +0 -2
  184. package/dist/compiler/claude-renderer.js +0 -40
  185. package/dist/compiler/claude-renderer.js.map +0 -1
  186. package/dist/compiler/codex-renderer.d.ts +0 -2
  187. package/dist/compiler/codex-renderer.js +0 -40
  188. package/dist/compiler/codex-renderer.js.map +0 -1
  189. package/dist/compiler/compiler.d.ts +0 -4
  190. package/dist/compiler/compiler.js +0 -87
  191. package/dist/compiler/compiler.js.map +0 -1
  192. package/dist/compiler/deployer.d.ts +0 -21
  193. package/dist/compiler/deployer.js +0 -64
  194. package/dist/compiler/deployer.js.map +0 -1
  195. package/dist/compiler/github-renderer.d.ts +0 -2
  196. package/dist/compiler/github-renderer.js +0 -63
  197. package/dist/compiler/github-renderer.js.map +0 -1
  198. package/dist/compiler/types.d.ts +0 -45
  199. package/dist/compiler/types.js +0 -2
  200. package/dist/compiler/types.js.map +0 -1
  201. package/dist/interaction/pack-actions-service.d.ts +0 -59
  202. package/dist/interaction/pack-actions-service.js +0 -172
  203. package/dist/interaction/pack-actions-service.js.map +0 -1
  204. package/dist/packs/fs-registry.d.ts +0 -27
  205. package/dist/packs/fs-registry.js +0 -216
  206. package/dist/packs/fs-registry.js.map +0 -1
  207. package/dist/packs/index-sync.d.ts +0 -9
  208. package/dist/packs/index-sync.js +0 -54
  209. package/dist/packs/index-sync.js.map +0 -1
  210. package/dist/packs/types.d.ts +0 -55
  211. package/dist/packs/types.js +0 -2
  212. package/dist/packs/types.js.map +0 -1
  213. package/dist/store/sqlite/repositories/pack-repo.d.ts +0 -16
  214. package/dist/store/sqlite/repositories/pack-repo.js +0 -192
  215. package/dist/store/sqlite/repositories/pack-repo.js.map +0 -1
@@ -7,14 +7,12 @@ import { ExperienceInteractionService } from "../../interaction/service.js";
7
7
  import { ExperienceOperationalService } from "../../interaction/operational-service.js";
8
8
  import { ExperienceOperationalActionsService, } from "../../interaction/operational-actions-service.js";
9
9
  import { ExperienceStateArtifactService } from "../../interaction/state-artifact-service.js";
10
- import { ExperiencePackActionsService } from "../../interaction/pack-actions-service.js";
11
10
  import { ExperienceRuntimeService } from "../../runtime/service.js";
12
11
  import { fetchLatestGitHubReleaseStatus } from "../../version/remote-release.js";
13
- const NODE_STATES = ["candidate", "active", "cooling", "retired"];
12
+ const NODE_STATES = ["candidate", "priority_candidate", "active", "cooling", "retired"];
14
13
  const NODE_TYPES = ["strategy", "warning"];
15
14
  const EXPERIENCE_ADAPTERS = ["openclaw", "claude-code", "codex"];
16
15
  const HIGH_IMPACT_OPERATIONS = ["install", "repair", "upgrade"];
17
- const COMPILER_TARGETS = ["agents", "codex", "github", "claude"];
18
16
  const buildExperienceCapabilities = () => ({
19
17
  model: "agent-first",
20
18
  principles: [
@@ -22,43 +20,12 @@ const buildExperienceCapabilities = () => ({
22
20
  "Low-risk read and preview operations should be direct MCP tools.",
23
21
  "High-risk write operations should use plan -> review -> confirm flows."
24
22
  ],
25
- packs: {
26
- directTools: [
27
- "experienceengine_pack_list",
28
- "experienceengine_pack_inspect",
29
- "experienceengine_pack_status",
30
- "experienceengine_pack_enable",
31
- "experienceengine_pack_disable"
32
- ],
33
- guardedTools: [
34
- "experienceengine_plan_pack_publish",
35
- "experienceengine_plan_pack_rollback",
36
- "experienceengine_execute_planned_pack_operation"
37
- ]
38
- },
39
- compiler: {
40
- directTools: [
41
- "experienceengine_pack_compile",
42
- "experienceengine_pack_deploy_preview"
43
- ],
44
- guardedTools: [
45
- "experienceengine_plan_pack_deploy",
46
- "experienceengine_execute_planned_pack_operation"
47
- ],
48
- targets: [...COMPILER_TARGETS]
49
- },
50
23
  prompts: [
51
- "experienceengine_review_repo_status",
52
- "experienceengine_review_pack_status",
53
- "experienceengine_prepare_pack_publish",
54
- "experienceengine_prepare_pack_rollback",
55
- "experienceengine_prepare_pack_deploy"
24
+ "experienceengine_review_repo_status"
56
25
  ],
57
26
  resources: [
58
27
  "experienceengine://capabilities",
59
28
  "experienceengine://repo-summary",
60
- "experienceengine://packs",
61
- "experienceengine://pack/{id}",
62
29
  "experienceengine://last",
63
30
  "experienceengine://learning/summary"
64
31
  ],
@@ -96,9 +63,7 @@ const createCodexInteractionService = (options = {}) => {
96
63
  }, {
97
64
  env: options.env ?? process.env,
98
65
  homeDir: options.homeDir
99
- }), {
100
- packsDir: paths.packsDir
101
- });
66
+ }));
102
67
  };
103
68
  const createCodexOperationalService = (options = {}) => {
104
69
  if (!options.fetchImpl) {
@@ -117,11 +82,6 @@ const createCodexStateArtifactService = (options = {}) => options.stateArtifactS
117
82
  env: options.env ?? process.env,
118
83
  homeDir: options.homeDir
119
84
  });
120
- const createCodexPackActionsService = (options = {}) => options.packActionsService ??
121
- new ExperiencePackActionsService({
122
- env: options.env ?? process.env,
123
- homeDir: options.homeDir
124
- });
125
85
  const toTextToolResult = (result) => ({
126
86
  content: [
127
87
  {
@@ -186,11 +146,72 @@ const createJsonResourceLink = (uri, name, description) => ({
186
146
  mimeType: "application/json",
187
147
  description
188
148
  });
149
+ const summarizeActionReason = (scorecard) => {
150
+ if (scorecard.mode === "inject_conservative") {
151
+ if (scorecard.decisionReason === "ambiguous_same_family_candidate") {
152
+ return "ExperienceEngine found a promising same-family match and chose conservative injection instead of skipping.";
153
+ }
154
+ if (scorecard.decisionReason === "promising_candidate_quality") {
155
+ return "ExperienceEngine found a credible candidate, but kept the injection conservative until it has stronger runtime proof.";
156
+ }
157
+ return "ExperienceEngine chose conservative injection because the best match still needs more runtime evidence.";
158
+ }
159
+ if (scorecard.decisionReason === "mature_validated_candidate") {
160
+ return "A mature validated candidate cleared the fast path, so ExperienceEngine injected it normally.";
161
+ }
162
+ if (scorecard.decisionReason === "candidate_quality_positive") {
163
+ return "Candidate quality was strong enough to justify intervention for this task.";
164
+ }
165
+ if (scorecard.mode === "inject") {
166
+ return "ExperienceEngine injected the best available reusable guidance for this task.";
167
+ }
168
+ return undefined;
169
+ };
170
+ const summarizeTrust = (scorecard) => {
171
+ const primaryNode = scorecard.nodes?.[0];
172
+ if (!scorecard.riskLevel || !primaryNode?.state) {
173
+ return undefined;
174
+ }
175
+ return `${scorecard.riskLevel}-risk ${primaryNode.state} guidance with ${primaryNode.helped ?? 0} helped and ${primaryNode.harmed ?? 0} harmed signal(s).`;
176
+ };
177
+ const summarizeRetrievalNotes = (scorecard) => {
178
+ const notes = [];
179
+ if (scorecard.queryRewriteApplied) {
180
+ notes.push("Query rewrite preserved retrieval intent for this task.");
181
+ }
182
+ const rerankSource = scorecard.topCandidates?.[0]?.rerankSource;
183
+ if (rerankSource === "model") {
184
+ notes.push("Model reranking participated in the final ordering.");
185
+ }
186
+ if (scorecard.fastPathApplied) {
187
+ notes.push("A strong candidate fast path was used.");
188
+ }
189
+ return notes;
190
+ };
191
+ const summarizeScorecard = (scorecard) => scorecard
192
+ ? {
193
+ mode: scorecard.mode,
194
+ riskLevel: scorecard.riskLevel,
195
+ recommendation: scorecard.recommendation,
196
+ actionReason: summarizeActionReason(scorecard),
197
+ trustSummary: summarizeTrust(scorecard),
198
+ retrievalNotes: summarizeRetrievalNotes(scorecard),
199
+ reasons: scorecard.reasons?.slice(0, 2),
200
+ nodes: scorecard.nodes?.slice(0, 3).map((node) => ({
201
+ id: node.id,
202
+ state: node.state,
203
+ riskLevel: node.riskLevel,
204
+ helped: node.helped,
205
+ harmed: node.harmed
206
+ })) ?? []
207
+ }
208
+ : undefined;
189
209
  export const createCodexBehaviorLoop = (options = {}) => {
190
210
  const runtime = createCodexRuntime(options);
191
211
  return {
192
212
  async lookupHints(args) {
193
213
  const result = await runtime.beforePromptBuild({
214
+ host: "codex",
194
215
  sessionId: args.sessionId,
195
216
  cwd: args.cwd,
196
217
  userMessage: args.prompt,
@@ -201,7 +222,7 @@ export const createCodexBehaviorLoop = (options = {}) => {
201
222
  text: result.text,
202
223
  notice: result.notice,
203
224
  injectedNodeIds: result.input.injected_node_ids,
204
- scorecard: result.scorecard,
225
+ summary: summarizeScorecard(result.scorecard),
205
226
  deliveryMode: result.deliveryMode,
206
227
  delivered: result.delivered
207
228
  };
@@ -217,33 +238,31 @@ export const createCodexBehaviorLoop = (options = {}) => {
217
238
  status: args.status
218
239
  });
219
240
  return {
241
+ status: "recorded",
220
242
  toolName: event.tool_name,
221
- status: event.status,
222
- inputSummary: event.input_summary,
223
- outputSummary: event.output_summary,
224
- errorSignature: event.error_signature,
243
+ eventStatus: event.status,
244
+ hasErrorSignature: Boolean(event.error_signature),
225
245
  exitCode: event.exit_code
226
246
  };
227
247
  },
228
248
  async finalizeTask(args) {
229
249
  const input = await runtime.finalizeTask({
250
+ host: "codex",
230
251
  sessionId: args.sessionId,
231
252
  cwd: args.cwd,
232
- userMessage: args.prompt,
253
+ userMessage: args.prompt ?? "",
233
254
  taskSummary: args.prompt,
234
255
  contextSummary: args.contextSummary
235
256
  });
236
257
  return {
258
+ status: "finalized",
237
259
  taskType: input.task_type,
238
- taskSummary: input.task_summary,
239
260
  outcomeSignal: input.outcome_signal,
240
261
  injectedNodeIds: input.injected_node_ids,
262
+ recordedToolEvents: input.tool_events.length,
241
263
  feedbackHint: input.injected_node_ids.length > 0
242
264
  ? "If the injected guidance helped or harmed this task, call experienceengine_quick_feedback."
243
- : undefined,
244
- evidence: input.tool_events.map((event) => [event.tool_name, event.status, event.error_signature ?? event.output_summary]
245
- .filter(Boolean)
246
- .join(": "))
265
+ : undefined
247
266
  };
248
267
  }
249
268
  };
@@ -266,27 +285,6 @@ export const createCodexInteractionSurface = (options = {}) => {
266
285
  async inspectNode(args) {
267
286
  return interaction.inspectNode(args.nodeId);
268
287
  },
269
- async listPacks() {
270
- return interaction.listPacks();
271
- },
272
- async inspectPack(args) {
273
- return interaction.inspectPack(args.packId);
274
- },
275
- async enablePack(args) {
276
- return interaction.enablePack(args);
277
- },
278
- async disablePack(args) {
279
- return interaction.disablePack(args);
280
- },
281
- async inspectPackDeploymentStatus(args) {
282
- return interaction.inspectPackDeploymentStatus(args);
283
- },
284
- async compilePack(args) {
285
- return interaction.compilePack(args);
286
- },
287
- async deployPackPreview(args) {
288
- return interaction.deployPackPreview(args);
289
- },
290
288
  async listNodesByState(args) {
291
289
  return interaction.listNodesByState(args.state);
292
290
  },
@@ -328,11 +326,10 @@ export const createCodexMcpServer = (options = {}) => {
328
326
  const interactionSurface = createCodexInteractionSurface(options);
329
327
  const operationalSurface = createCodexOperationalService(options);
330
328
  const operationalActions = createCodexOperationalActionsService(options);
331
- const packActions = createCodexPackActionsService(options);
332
329
  const stateArtifacts = createCodexStateArtifactService(options);
333
330
  const server = new McpServer({
334
331
  name: "experienceengine",
335
- version: "0.1.2"
332
+ version: "0.1.3"
336
333
  });
337
334
  server.registerResource("experienceengine_doctor", new ResourceTemplate("experienceengine://doctor/{adapter}", {
338
335
  list: undefined,
@@ -385,21 +382,9 @@ export const createCodexMcpServer = (options = {}) => {
385
382
  }, async (uri) => toJsonResourceResult(uri.toString(), buildExperienceCapabilities()));
386
383
  server.registerResource("experienceengine_repo_summary", "experienceengine://repo-summary", {
387
384
  title: "ExperienceEngine Repo Summary",
388
- description: "Repo-level ExperienceEngine summary for the current scope, including benchmark, packs, deployment, and next action.",
385
+ description: "Repo-level ExperienceEngine summary for the current scope, including benchmark and next action.",
389
386
  mimeType: "application/json"
390
387
  }, async (uri) => toJsonResourceResult(uri.toString(), await interactionSurface.inspectRepoSummary()));
391
- server.registerResource("experienceengine_packs", "experienceengine://packs", {
392
- title: "ExperienceEngine Packs",
393
- description: "Published and draft local Experience Pack assets in the shared registry.",
394
- mimeType: "application/json"
395
- }, async (uri) => toJsonResourceResult(uri.toString(), await interactionSurface.listPacks()));
396
- server.registerResource("experienceengine_pack", new ResourceTemplate("experienceengine://pack/{id}", {
397
- list: undefined
398
- }), {
399
- title: "ExperienceEngine Pack Detail",
400
- description: "A single Experience Pack and its current version detail.",
401
- mimeType: "application/json"
402
- }, async (uri, variables) => toJsonResourceResult(uri.toString(), await interactionSurface.inspectPack({ packId: String(variables.id) })));
403
388
  server.registerResource("experienceengine_learning_summary", "experienceengine://learning/summary", {
404
389
  title: "ExperienceEngine Learning Summary",
405
390
  description: "Candidate, distillation, and formal node counts across the learning pipeline.",
@@ -450,21 +435,21 @@ export const createCodexMcpServer = (options = {}) => {
450
435
  role: "user",
451
436
  content: {
452
437
  type: "text",
453
- text: "First read the experienceengine://repo-summary resource. Then call experienceengine_get_repo_summary if you need the structured form. Summarize the repo benchmark verdict, suggested mode, active packs, deploy status, and the most conservative next action."
438
+ text: "Read experienceengine://repo-summary first. Summarize the repo verdict, suggested mode, and safest next action."
454
439
  }
455
440
  }
456
441
  ]
457
442
  }));
458
443
  server.registerPrompt("experienceengine_review_capabilities", {
459
444
  title: "ExperienceEngine Review Capabilities",
460
- description: "Guide the host agent to review ExperienceEngine's agent-first MCP surface before operating packs or compiler targets."
445
+ description: "Guide the host agent to review ExperienceEngine's agent-first MCP surface before using advanced ExperienceEngine operations."
461
446
  }, async () => ({
462
447
  messages: [
463
448
  {
464
449
  role: "user",
465
450
  content: {
466
451
  type: "text",
467
- text: "First read the experienceengine://capabilities resource. Then summarize which ExperienceEngine operations are direct low-risk tools, which require confirmation, and which CLI fallbacks remain outside the normal host-agent flow."
452
+ text: "Read experienceengine://capabilities first. Summarize which ExperienceEngine actions are direct tools, which need confirmation, and which stay CLI/operator-only."
468
453
  }
469
454
  }
470
455
  ]
@@ -496,7 +481,7 @@ export const createCodexMcpServer = (options = {}) => {
496
481
  role: "user",
497
482
  content: {
498
483
  type: "text",
499
- text: `First call ${planTool}${suffix}. Review the returned summary, effects, and artifact path with the user. Only if the user explicitly confirms should you call experienceengine_execute_planned_state_operation with the returned planId and confirmationToken.`
484
+ text: `Call ${planTool}${suffix} first. Review the summary, effects, and artifact path with the user. Only after explicit confirmation should you call experienceengine_execute_planned_state_operation with the returned planId and confirmationToken.`
500
485
  }
501
486
  }
502
487
  ]
@@ -515,80 +500,7 @@ export const createCodexMcpServer = (options = {}) => {
515
500
  role: "user",
516
501
  content: {
517
502
  type: "text",
518
- text: `First call experienceengine_plan_${operation} with adapter=${adapter}. Review the returned summary, effects, and commandHint with the user. Only if the user explicitly confirms should you call experienceengine_execute_planned_operation with the returned planId and confirmationToken.`
519
- }
520
- }
521
- ]
522
- }));
523
- server.registerPrompt("experienceengine_review_pack_status", {
524
- title: "ExperienceEngine Review Pack Status",
525
- description: "Guide the agent to inspect one pack, its compile state, and current repo deployment status.",
526
- argsSchema: {
527
- packId: z.string().min(1),
528
- target: z.enum(COMPILER_TARGETS),
529
- repoPath: z.string().min(1)
530
- }
531
- }, async ({ packId, target, repoPath }) => ({
532
- messages: [
533
- {
534
- role: "user",
535
- content: {
536
- type: "text",
537
- text: `Review the Experience Pack ${packId}. First call experienceengine_pack_inspect to inspect the pack itself. Then call experienceengine_pack_status with target=${target} and repoPath=${repoPath} to inspect whether the current repository is missing, up to date, or drifted. Summarize the pack state, compile state, deployment state, and the next recommended action.`
538
- }
539
- }
540
- ]
541
- }));
542
- server.registerPrompt("experienceengine_prepare_pack_publish", {
543
- title: "ExperienceEngine Prepare Pack Publish",
544
- description: "Guide the agent through the confirmation flow for publishing an Experience Pack.",
545
- argsSchema: {
546
- packId: z.string().min(1)
547
- }
548
- }, async ({ packId }) => ({
549
- messages: [
550
- {
551
- role: "user",
552
- content: {
553
- type: "text",
554
- text: `First call experienceengine_plan_pack_publish with packId=${packId}. Review the returned summary, effects, and commandHint with the user. Only if the user explicitly confirms should you call experienceengine_execute_planned_pack_operation with the returned planId and confirmationToken.`
555
- }
556
- }
557
- ]
558
- }));
559
- server.registerPrompt("experienceengine_prepare_pack_rollback", {
560
- title: "ExperienceEngine Prepare Pack Rollback",
561
- description: "Guide the agent through the confirmation flow for rolling an Experience Pack back to a selected version.",
562
- argsSchema: {
563
- packId: z.string().min(1),
564
- version: z.string().min(1)
565
- }
566
- }, async ({ packId, version }) => ({
567
- messages: [
568
- {
569
- role: "user",
570
- content: {
571
- type: "text",
572
- text: `First call experienceengine_plan_pack_rollback with packId=${packId} and version=${version}. Review the returned summary, effects, and commandHint with the user. Only if the user explicitly confirms should you call experienceengine_execute_planned_pack_operation with the returned planId and confirmationToken.`
573
- }
574
- }
575
- ]
576
- }));
577
- server.registerPrompt("experienceengine_prepare_pack_deploy", {
578
- title: "ExperienceEngine Prepare Pack Deploy",
579
- description: "Guide the agent through the confirmation flow for deploying a compiled Experience Pack into a repository.",
580
- argsSchema: {
581
- packId: z.string().min(1),
582
- target: z.enum(COMPILER_TARGETS),
583
- repoPath: z.string().min(1)
584
- }
585
- }, async ({ packId, target, repoPath }) => ({
586
- messages: [
587
- {
588
- role: "user",
589
- content: {
590
- type: "text",
591
- text: `First call experienceengine_plan_pack_deploy with packId=${packId}, target=${target}, and repoPath=${repoPath}. Review the returned summary, effects, and commandHint with the user. Only if the user explicitly confirms should you call experienceengine_execute_planned_pack_operation with the returned planId and confirmationToken.`
503
+ text: `Call experienceengine_plan_${operation} with adapter=${adapter} first. Review the summary, effects, and commandHint with the user. Only after explicit confirmation should you call experienceengine_execute_planned_operation with the returned planId and confirmationToken.`
592
504
  }
593
505
  }
594
506
  ]
@@ -602,7 +514,7 @@ export const createCodexMcpServer = (options = {}) => {
602
514
  role: "user",
603
515
  content: {
604
516
  type: "text",
605
- text: "Review the latest ExperienceEngine interaction. Summarize whether guidance was injected, which nodes were involved, and what outcome was recorded."
517
+ text: "Review the latest ExperienceEngine interaction in this Codex session. Summarize whether guidance was injected, which nodes were involved, and the recorded outcome. Use CLI fallback only if the host surface is unavailable."
606
518
  }
607
519
  },
608
520
  {
@@ -626,7 +538,7 @@ export const createCodexMcpServer = (options = {}) => {
626
538
  role: "user",
627
539
  content: {
628
540
  type: "text",
629
- text: `Review the ${resolvedLimit} most recent ExperienceEngine turns that injected guidance. Summarize recurring successful patterns and any harmful repeats.`
541
+ text: `Review the ${resolvedLimit} most recent ExperienceEngine turns that injected guidance. Summarize recurring wins and harmful repeats.`
630
542
  }
631
543
  },
632
544
  {
@@ -645,7 +557,7 @@ export const createCodexMcpServer = (options = {}) => {
645
557
  role: "user",
646
558
  content: {
647
559
  type: "text",
648
- text: "Review the current ExperienceEngine warning nodes. Identify noisy or stale warnings, and call out any warning that appears to be over-firing or no longer useful."
560
+ text: "Review the current ExperienceEngine warning nodes. Identify stale warnings and any warning that appears noisy or over-firing."
649
561
  }
650
562
  },
651
563
  {
@@ -666,7 +578,7 @@ export const createCodexMcpServer = (options = {}) => {
666
578
  role: "user",
667
579
  content: {
668
580
  type: "text",
669
- text: `Pause ExperienceEngine interventions for the current project${cwd ? ` at ${cwd}` : ""}. Confirm this action before calling the experienceengine_disable_scope tool, then summarize which scope was changed.`
581
+ text: `Pause ExperienceEngine interventions for the current project${cwd ? ` at ${cwd}` : ""}. Confirm first, then call experienceengine_set_scope_intervention_state with action=disable and summarize the changed scope.`
670
582
  }
671
583
  }
672
584
  ]
@@ -683,7 +595,7 @@ export const createCodexMcpServer = (options = {}) => {
683
595
  role: "user",
684
596
  content: {
685
597
  type: "text",
686
- text: `Resume ExperienceEngine interventions for the current project${cwd ? ` at ${cwd}` : ""}. Confirm this action before calling the experienceengine_enable_scope tool, then summarize which scope was changed.`
598
+ text: `Resume ExperienceEngine interventions for the current project${cwd ? ` at ${cwd}` : ""}. Confirm first, then call experienceengine_set_scope_intervention_state with action=enable and summarize the changed scope.`
687
599
  }
688
600
  }
689
601
  ]
@@ -697,7 +609,7 @@ export const createCodexMcpServer = (options = {}) => {
697
609
  role: "user",
698
610
  content: {
699
611
  type: "text",
700
- text: "Mark the last injected ExperienceEngine guidance as helpful. Confirm with the user if needed, then call the experienceengine_feedback_last tool with feedback=helped and summarize which nodes were updated."
612
+ text: "Mark the last injected ExperienceEngine guidance as helpful in this Codex session. If needed, confirm first, call experienceengine_feedback_last with feedback=helped, and summarize updated nodes. Use CLI fallback only if the host path is unavailable."
701
613
  }
702
614
  }
703
615
  ]
@@ -711,7 +623,7 @@ export const createCodexMcpServer = (options = {}) => {
711
623
  role: "user",
712
624
  content: {
713
625
  type: "text",
714
- text: "Mark the last injected ExperienceEngine guidance as harmful. Confirm with the user if needed, then call the experienceengine_feedback_last tool with feedback=harmed and summarize which nodes were updated."
626
+ text: "Mark the last injected ExperienceEngine guidance as harmful in this Codex session. If needed, confirm first, call experienceengine_feedback_last with feedback=harmed, and summarize updated nodes. Use CLI fallback only if the host path is unavailable."
715
627
  }
716
628
  }
717
629
  ]
@@ -797,115 +709,6 @@ export const createCodexMcpServer = (options = {}) => {
797
709
  openWorldHint: true
798
710
  }
799
711
  }, async ({ adapter }) => toTextToolResult(await operationalSurface.checkUpdate(adapter)));
800
- server.registerTool("experienceengine_plan_pack_publish", {
801
- title: "ExperienceEngine Plan Pack Publish",
802
- description: "Create a structured confirmation plan for publishing an Experience Pack.",
803
- inputSchema: z.object({
804
- packId: z.string().min(1)
805
- })
806
- }, async ({ packId }) => toStructuredToolResult(packActions.planPublish(packId)));
807
- server.registerTool("experienceengine_plan_pack_rollback", {
808
- title: "ExperienceEngine Plan Pack Rollback",
809
- description: "Create a structured confirmation plan for rolling an Experience Pack back to an earlier version.",
810
- inputSchema: z.object({
811
- packId: z.string().min(1),
812
- version: z.string().min(1)
813
- })
814
- }, async ({ packId, version }) => toStructuredToolResult(packActions.planRollback(packId, version)));
815
- server.registerTool("experienceengine_plan_pack_deploy", {
816
- title: "ExperienceEngine Plan Pack Deploy",
817
- description: "Create a structured confirmation plan for deploying a compiled Experience Pack into a repository.",
818
- inputSchema: z.object({
819
- packId: z.string().min(1),
820
- version: z.string().optional(),
821
- target: z.enum(COMPILER_TARGETS),
822
- repoPath: z.string().min(1)
823
- })
824
- }, async ({ packId, version, target, repoPath }) => toStructuredToolResult(packActions.planDeploy(packId, target, repoPath, version)));
825
- server.registerTool("experienceengine_execute_planned_pack_operation", {
826
- title: "ExperienceEngine Execute Planned Pack Operation",
827
- description: "Execute a previously planned pack publish, rollback, or deploy after explicit confirmation.",
828
- inputSchema: z.object({
829
- planId: z.string().min(1),
830
- confirmationToken: z.string().min(1)
831
- })
832
- }, async ({ planId, confirmationToken }) => toStructuredToolResult(packActions.executePlannedOperation({ planId, confirmationToken })));
833
- server.registerTool("experienceengine_pack_list", {
834
- title: "ExperienceEngine Pack List",
835
- description: "List local Experience Packs available in the shared registry.",
836
- inputSchema: z.object({}),
837
- annotations: {
838
- readOnlyHint: true,
839
- openWorldHint: false
840
- }
841
- }, async () => toStructuredToolResult({ packs: await interactionSurface.listPacks() }));
842
- server.registerTool("experienceengine_pack_inspect", {
843
- title: "ExperienceEngine Pack Inspect",
844
- description: "Inspect one Experience Pack, including its current version, nodes, activations, and compiled artifacts.",
845
- inputSchema: z.object({
846
- packId: z.string().min(1)
847
- }),
848
- annotations: {
849
- readOnlyHint: true,
850
- openWorldHint: false
851
- }
852
- }, async ({ packId }) => toStructuredToolResult(await interactionSurface.inspectPack({ packId })));
853
- server.registerTool("experienceengine_pack_enable", {
854
- title: "ExperienceEngine Pack Enable",
855
- description: "Enable an Experience Pack for the current repository scope.",
856
- inputSchema: z.object({
857
- packId: z.string().min(1),
858
- cwd: z.string().optional()
859
- })
860
- }, async ({ packId, cwd }) => toStructuredToolResult(await interactionSurface.enablePack({ packId, cwd })));
861
- server.registerTool("experienceengine_pack_disable", {
862
- title: "ExperienceEngine Pack Disable",
863
- description: "Disable an Experience Pack for the current repository scope.",
864
- inputSchema: z.object({
865
- packId: z.string().min(1),
866
- cwd: z.string().optional()
867
- })
868
- }, async ({ packId, cwd }) => toStructuredToolResult(await interactionSurface.disablePack({ packId, cwd })));
869
- server.registerTool("experienceengine_pack_status", {
870
- title: "ExperienceEngine Pack Status",
871
- description: "Inspect whether a compiled Experience Pack target is missing, up to date, or drifted in a repository.",
872
- inputSchema: z.object({
873
- packId: z.string().min(1),
874
- version: z.string().optional(),
875
- target: z.enum(COMPILER_TARGETS),
876
- repoPath: z.string().min(1)
877
- }),
878
- annotations: {
879
- readOnlyHint: true,
880
- openWorldHint: false
881
- }
882
- }, async ({ packId, version, target, repoPath }) => toStructuredToolResult(await interactionSurface.inspectPackDeploymentStatus({ packId, version, target, repoPath })));
883
- server.registerTool("experienceengine_pack_compile", {
884
- title: "ExperienceEngine Pack Compile",
885
- description: "Compile a published Experience Pack into a host-friendly artifact without deploying it.",
886
- inputSchema: z.object({
887
- packId: z.string().min(1),
888
- version: z.string().optional(),
889
- target: z.enum(COMPILER_TARGETS)
890
- })
891
- }, async ({ packId, version, target }) => toStructuredToolResult(await interactionSurface.compilePack({ packId, version, target })));
892
- server.registerTool("experienceengine_pack_deploy_preview", {
893
- title: "ExperienceEngine Pack Deploy Preview",
894
- description: "Preview where a compiled Experience Pack artifact would deploy and whether it would overwrite drifted content.",
895
- inputSchema: z.object({
896
- packId: z.string().min(1),
897
- version: z.string().optional(),
898
- target: z.enum(COMPILER_TARGETS),
899
- repoPath: z.string().min(1)
900
- })
901
- }, async ({ packId, version, target, repoPath }) => toStructuredToolResult(await interactionSurface.deployPackPreview({ packId, version, target, repoPath })));
902
- server.registerTool("experienceengine_get_repo_summary", {
903
- title: "ExperienceEngine Get Repo Summary",
904
- description: "Read the current repo-level ExperienceEngine summary for the active or specified cwd.",
905
- inputSchema: {
906
- cwd: z.string().optional()
907
- }
908
- }, async ({ cwd }) => toStructuredToolResult(await interactionSurface.inspectRepoSummary({ cwd })));
909
712
  server.registerTool("experienceengine_get_capabilities", {
910
713
  title: "ExperienceEngine Capabilities",
911
714
  description: "Read the current ExperienceEngine MCP capabilities, including direct tools, guarded flows, prompts, and CLI-only fallbacks.",
@@ -917,7 +720,7 @@ export const createCodexMcpServer = (options = {}) => {
917
720
  }, async () => toStructuredToolResult(buildExperienceCapabilities()));
918
721
  server.registerTool("experienceengine_lookup_hints", {
919
722
  title: "ExperienceEngine Lookup Hints",
920
- description: "Look up concise prior experience hints for the current coding task without assuming host lifecycle hooks.",
723
+ description: "Use once at task start for a real coding or debugging task to check whether ExperienceEngine has relevant prior guidance.",
921
724
  inputSchema: z.object({
922
725
  cwd: z.string().optional(),
923
726
  prompt: z.string().min(1),
@@ -926,7 +729,7 @@ export const createCodexMcpServer = (options = {}) => {
926
729
  }, async ({ cwd, prompt, sessionId }) => toTextToolResult(await behaviorLoop.lookupHints({ cwd, prompt, sessionId })));
927
730
  server.registerTool("experienceengine_record_tool_result", {
928
731
  title: "ExperienceEngine Record Tool Result",
929
- description: "Record a Codex tool result into the active ExperienceEngine session before finalization.",
732
+ description: "Record only important tool outcomes that changed the task direction, especially notable shell, test, build, or edit results, before finalization.",
930
733
  inputSchema: z.object({
931
734
  sessionId: z.string().min(1),
932
735
  toolName: z.string().min(1),
@@ -939,31 +742,17 @@ export const createCodexMcpServer = (options = {}) => {
939
742
  }, async (args) => toTextToolResult(await behaviorLoop.recordToolResult(args)));
940
743
  server.registerTool("experienceengine_finalize_task", {
941
744
  title: "ExperienceEngine Finalize Task",
942
- description: "Finalize a Codex task after hint lookup and optional tool-result recording to persist outcomes and feedback.",
745
+ description: "Call at task end after hint lookup and any important tool-result recording to persist the learning loop outcome. Omit prompt when the task is unchanged from the earlier lookup in the same session.",
943
746
  inputSchema: z.object({
944
747
  sessionId: z.string().min(1),
945
748
  cwd: z.string().optional(),
946
- prompt: z.string().min(1),
749
+ prompt: z.string().min(1).optional(),
947
750
  contextSummary: z.string().optional()
948
751
  })
949
752
  }, async (args) => toTextToolResult(await behaviorLoop.finalizeTask(args)));
950
- server.registerTool("experienceengine_quick_feedback", {
951
- title: "ExperienceEngine Quick Feedback",
952
- description: "Record helped or harmed feedback for the last injected ExperienceEngine guidance using the shortest possible interaction path.",
953
- inputSchema: z.object({
954
- feedback: z.enum(["helped", "harmed"])
955
- }),
956
- outputSchema: z.object({
957
- status: z.enum(["updated", "not_found"]),
958
- feedback: z.enum(["helped", "harmed"]).optional(),
959
- nodeIds: z.array(z.string()).optional(),
960
- reason: z.enum(["last_injected_missing", "node_missing"]).optional(),
961
- nodeId: z.string().optional()
962
- })
963
- }, async ({ feedback }) => toStructuredToolResult(await interactionSurface.feedbackLast({ feedback })));
964
753
  server.registerTool("experienceengine_feedback_last", {
965
754
  title: "ExperienceEngine Feedback Last",
966
- description: "Record helped or harmed feedback for the last injected ExperienceEngine node set.",
755
+ description: "Record helped or harmed feedback after injected guidance for the last injected ExperienceEngine node set.",
967
756
  inputSchema: z.object({
968
757
  feedback: z.enum(["helped", "harmed"])
969
758
  }),
@@ -990,24 +779,11 @@ export const createCodexMcpServer = (options = {}) => {
990
779
  nodeId: z.string().optional()
991
780
  })
992
781
  }, async ({ nodeId, feedback }) => toStructuredToolResult(await interactionSurface.feedbackNode({ nodeId, feedback })));
993
- server.registerTool("experienceengine_disable_scope", {
994
- title: "ExperienceEngine Disable Scope",
995
- description: "Disable ExperienceEngine interventions for the provided working directory scope.",
996
- inputSchema: z.object({
997
- cwd: z.string().optional()
998
- }),
999
- outputSchema: z.object({
1000
- scopeId: z.string(),
1001
- scopeName: z.string(),
1002
- rootPath: z.string().optional(),
1003
- isDisabled: z.boolean(),
1004
- changed: z.boolean()
1005
- })
1006
- }, async ({ cwd }) => toStructuredToolResult(await interactionSurface.disableScope({ cwd })));
1007
- server.registerTool("experienceengine_enable_scope", {
1008
- title: "ExperienceEngine Enable Scope",
1009
- description: "Enable ExperienceEngine interventions for the provided working directory scope.",
782
+ server.registerTool("experienceengine_set_scope_intervention_state", {
783
+ title: "ExperienceEngine Set Scope Intervention State",
784
+ description: "Enable or disable ExperienceEngine interventions for the provided working directory scope.",
1010
785
  inputSchema: z.object({
786
+ action: z.enum(["enable", "disable"]),
1011
787
  cwd: z.string().optional()
1012
788
  }),
1013
789
  outputSchema: z.object({
@@ -1017,31 +793,24 @@ export const createCodexMcpServer = (options = {}) => {
1017
793
  isDisabled: z.boolean(),
1018
794
  changed: z.boolean()
1019
795
  })
1020
- }, async ({ cwd }) => toStructuredToolResult(await interactionSurface.enableScope({ cwd })));
1021
- server.registerTool("experienceengine_cool_node", {
1022
- title: "ExperienceEngine Cool Node",
1023
- description: "Move a specific ExperienceEngine node into cooling state.",
1024
- inputSchema: z.object({
1025
- nodeId: z.string().min(1)
1026
- }),
1027
- outputSchema: z.object({
1028
- status: z.enum(["updated", "not_found"]),
1029
- nodeId: z.string(),
1030
- state: z.enum(["candidate", "active", "cooling", "retired"]).optional()
1031
- })
1032
- }, async ({ nodeId }) => toStructuredToolResult(await interactionSurface.coolNode({ nodeId })));
1033
- server.registerTool("experienceengine_retire_node", {
1034
- title: "ExperienceEngine Retire Node",
1035
- description: "Retire a specific ExperienceEngine node so it is no longer injected.",
796
+ }, async ({ action, cwd }) => toStructuredToolResult(action === "disable"
797
+ ? await interactionSurface.disableScope({ cwd })
798
+ : await interactionSurface.enableScope({ cwd })));
799
+ server.registerTool("experienceengine_set_node_lifecycle", {
800
+ title: "ExperienceEngine Set Node Lifecycle",
801
+ description: "Move a specific ExperienceEngine node into cooling or retired lifecycle state.",
1036
802
  inputSchema: z.object({
803
+ action: z.enum(["cool", "retire"]),
1037
804
  nodeId: z.string().min(1)
1038
805
  }),
1039
806
  outputSchema: z.object({
1040
807
  status: z.enum(["updated", "not_found"]),
1041
808
  nodeId: z.string(),
1042
- state: z.enum(["candidate", "active", "cooling", "retired"]).optional()
809
+ state: z.enum(["candidate", "priority_candidate", "active", "cooling", "retired"]).optional()
1043
810
  })
1044
- }, async ({ nodeId }) => toStructuredToolResult(await interactionSurface.retireNode({ nodeId })));
811
+ }, async ({ action, nodeId }) => toStructuredToolResult(action === "cool"
812
+ ? await interactionSurface.coolNode({ nodeId })
813
+ : await interactionSurface.retireNode({ nodeId })));
1045
814
  return server;
1046
815
  };
1047
816
  export const runCodexMcpServer = async () => {