mulmoclaude 0.6.2 → 0.6.4

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 (182) hide show
  1. package/README.md +26 -0
  2. package/bin/mulmoclaude.js +11 -1
  3. package/client/assets/JsonEditor-D6WBWLoa.js +10 -0
  4. package/client/assets/JsonEditor-Di5xGeZY.css +1 -0
  5. package/client/assets/_plugin-vue_export-helper-BOai-rQB.js +1 -0
  6. package/client/assets/chunk-D8eiyYIV-LcKZGJv5.js +1 -0
  7. package/client/assets/{html2canvas-CDGcmOD3-Bkf2uOth.js → html2canvas-CDGcmOD3-XVrO-eyz.js} +1 -1
  8. package/client/assets/index-CyBr8Mkr.css +2 -0
  9. package/client/assets/index-zZIqEbNX.js +5106 -0
  10. package/client/assets/{index.es-DqtpmBm8-D9mAh_KQ.js → index.es-DqtpmBm8-DHT6q10o.js} +1 -1
  11. package/client/assets/material-symbols-outlined-DtIK7AQn.woff2 +0 -0
  12. package/client/assets/runtime-protocol-vue-D6kcV0wa.js +1 -0
  13. package/client/assets/{runtime-vue-BVUzgYGA.js → runtime-vue-fFYhnNg3.js} +1 -1
  14. package/client/assets/{vue-C8UuIO9J.js → vue-D4w8THF_.js} +1 -1
  15. package/client/assets/vue-i18n-CQbxVmNs.js +3 -0
  16. package/client/assets/vue.runtime.esm-bundler-BTyIdNAI.js +4 -0
  17. package/client/index.html +10 -10
  18. package/package.json +9 -8
  19. package/server/agent/backend/claude-code.ts +34 -0
  20. package/server/agent/backend/fake-echo.ts +370 -0
  21. package/server/agent/backend/index.ts +16 -1
  22. package/server/agent/config.ts +74 -24
  23. package/server/agent/index.ts +104 -80
  24. package/server/agent/mcpFailureMonitor.ts +167 -0
  25. package/server/agent/mcpPreflight.ts +185 -0
  26. package/server/agent/prompt.ts +50 -359
  27. package/server/agent/stdioHttpShim.ts +171 -0
  28. package/server/agent/stream.ts +12 -1
  29. package/server/api/routes/encore.ts +55 -0
  30. package/server/api/routes/files.ts +22 -0
  31. package/server/api/routes/mulmo-script.ts +19 -1
  32. package/server/api/routes/schedulerHandlers.ts +52 -4
  33. package/server/api/routes/sessions.ts +15 -0
  34. package/server/api/routes/skills.ts +263 -0
  35. package/server/build/dispatcher.mjs +299 -0
  36. package/server/encore/INVARIANTS.md +272 -0
  37. package/server/encore/boot.ts +39 -0
  38. package/server/encore/closure.ts +36 -0
  39. package/server/encore/cycle.ts +276 -0
  40. package/server/encore/dispatch.ts +103 -0
  41. package/server/encore/handlers/amend.ts +99 -0
  42. package/server/encore/handlers/appendNote.ts +74 -0
  43. package/server/encore/handlers/defineEncore.ts +42 -0
  44. package/server/encore/handlers/listTickets.ts +107 -0
  45. package/server/encore/handlers/markStepDone.ts +41 -0
  46. package/server/encore/handlers/markTargetSkipped.ts +33 -0
  47. package/server/encore/handlers/query.ts +138 -0
  48. package/server/encore/handlers/recordValues.ts +44 -0
  49. package/server/encore/handlers/resolveNotification.ts +121 -0
  50. package/server/encore/handlers/setup.ts +81 -0
  51. package/server/encore/handlers/shared.ts +137 -0
  52. package/server/encore/handlers/snooze.ts +87 -0
  53. package/server/encore/handlers/startObligationChat.ts +64 -0
  54. package/server/encore/handlers/startSetupChat.ts +50 -0
  55. package/server/encore/lock.ts +61 -0
  56. package/server/encore/notifier.ts +123 -0
  57. package/server/encore/obligation.ts +25 -0
  58. package/server/encore/paths.ts +78 -0
  59. package/server/encore/reconcile.ts +661 -0
  60. package/server/encore/tick.ts +191 -0
  61. package/server/encore/yaml-fm.ts +63 -0
  62. package/server/events/notifications.ts +19 -91
  63. package/server/index.ts +94 -9
  64. package/server/notifier/engine.ts +102 -1
  65. package/server/notifier/macosReminderAdapter.ts +30 -0
  66. package/server/notifier/runtime-api.ts +41 -1
  67. package/server/notifier/types.ts +15 -2
  68. package/server/plugins/runtime.ts +11 -2
  69. package/server/prompts/index.ts +39 -0
  70. package/server/prompts/system/journal-pointer.md +12 -0
  71. package/server/prompts/system/memory-management-atomic.md +33 -0
  72. package/server/prompts/system/memory-management-topic.md +60 -0
  73. package/server/prompts/system/news-concierge.md +24 -0
  74. package/server/prompts/system/sandbox-tools.md +10 -0
  75. package/server/prompts/system/sources-context.md +16 -0
  76. package/server/prompts/system/system.md +91 -0
  77. package/server/system/announceOptionalDeps.ts +57 -0
  78. package/server/system/appVersion.ts +34 -0
  79. package/server/system/config.ts +17 -1
  80. package/server/system/docker.ts +14 -6
  81. package/server/system/env.ts +18 -5
  82. package/server/system/optionalDeps.ts +129 -0
  83. package/server/utils/cli-flags.d.mts +14 -0
  84. package/server/utils/cli-flags.mjs +53 -0
  85. package/server/utils/files/encore-io.ts +111 -0
  86. package/server/utils/time.ts +6 -0
  87. package/server/workspace/helps/business.md +2 -2
  88. package/server/workspace/helps/encore-dsl.md +482 -0
  89. package/server/workspace/helps/index.md +15 -13
  90. package/server/workspace/helps/mulmoscript.md +3 -3
  91. package/server/workspace/helps/sandbox.md +2 -2
  92. package/server/workspace/hooks/dispatcher.ts +7 -5
  93. package/server/workspace/hooks/provision.ts +6 -3
  94. package/server/workspace/paths.ts +13 -4
  95. package/server/workspace/skills/catalog.ts +355 -0
  96. package/server/workspace/skills/external/catalog.ts +283 -0
  97. package/server/workspace/skills/external/clone.ts +129 -0
  98. package/server/workspace/skills/external/id.ts +194 -0
  99. package/server/workspace/skills/external/install.ts +417 -0
  100. package/server/workspace/skills/external/presets.ts +50 -0
  101. package/server/workspace/skills-preset.ts +29 -17
  102. package/server/workspace/workspace.ts +10 -5
  103. package/src/App.vue +37 -8
  104. package/src/components/FileContentRenderer.vue +102 -9
  105. package/src/components/JsonEditor.vue +160 -0
  106. package/src/components/NotificationBell.vue +35 -3
  107. package/src/components/PluginLauncher.vue +20 -41
  108. package/src/components/RightSidebar.vue +19 -0
  109. package/src/components/SettingsMcpTab.vue +58 -11
  110. package/src/components/SettingsModal.vue +22 -1
  111. package/src/components/StackView.vue +10 -1
  112. package/src/components/TodoExplorer.vue +16 -0
  113. package/src/components/todo/TodoKanbanView.vue +34 -6
  114. package/src/composables/useNotifications.ts +21 -1
  115. package/src/config/apiRoutes.ts +0 -6
  116. package/src/config/mcpCatalog.ts +12 -7
  117. package/src/config/mcpTypes.ts +5 -0
  118. package/src/config/roles.ts +52 -15
  119. package/src/config/systemFileDescriptors.ts +12 -0
  120. package/src/lang/de.ts +108 -12
  121. package/src/lang/en.ts +105 -11
  122. package/src/lang/es.ts +106 -11
  123. package/src/lang/fr.ts +106 -11
  124. package/src/lang/ja.ts +104 -11
  125. package/src/lang/ko.ts +105 -11
  126. package/src/lang/pt-BR.ts +106 -11
  127. package/src/lang/zh.ts +103 -11
  128. package/src/main.ts +1 -0
  129. package/src/plugins/_generated/metas.ts +4 -0
  130. package/src/plugins/_generated/registrations.ts +2 -0
  131. package/src/plugins/_generated/server-bindings.ts +5 -0
  132. package/src/plugins/encore/EncoreDashboard.vue +504 -0
  133. package/src/plugins/encore/EncoreRedirect.vue +116 -0
  134. package/src/plugins/encore/View.vue +36 -0
  135. package/src/plugins/encore/defineEncoreDefinition.ts +74 -0
  136. package/src/plugins/encore/defineEncoreMeta.ts +13 -0
  137. package/src/plugins/encore/index.ts +93 -0
  138. package/src/plugins/encore/manageEncoreDefinition.ts +100 -0
  139. package/src/plugins/encore/manageEncoreMeta.ts +36 -0
  140. package/src/plugins/manageSkills/View.vue +832 -30
  141. package/src/plugins/manageSkills/categories.ts +125 -0
  142. package/src/plugins/manageSkills/meta.ts +30 -0
  143. package/src/plugins/markdown/definition.ts +3 -3
  144. package/src/plugins/meta-types.ts +5 -0
  145. package/src/plugins/presentMulmoScript/Preview.vue +3 -3
  146. package/src/plugins/presentMulmoScript/View.vue +157 -33
  147. package/src/plugins/presentMulmoScript/meta.ts +4 -0
  148. package/src/plugins/scheduler/View.vue +45 -9
  149. package/src/plugins/scheduler/calendarDefinition.ts +6 -2
  150. package/src/plugins/scheduler/multiDayHelpers.ts +95 -0
  151. package/src/plugins/skill/View.vue +1 -5
  152. package/src/plugins/spreadsheet/View.vue +3 -3
  153. package/src/plugins/spreadsheet/definition.ts +1 -1
  154. package/src/plugins/textResponse/Preview.vue +14 -1
  155. package/src/plugins/textResponse/View.vue +39 -24
  156. package/src/plugins/wiki/components/WikiPageBody.vue +4 -0
  157. package/src/router/index.ts +11 -0
  158. package/src/router/pageRoutes.ts +1 -0
  159. package/src/types/encore-dsl/at-expression.ts +120 -0
  160. package/src/types/encore-dsl/at-resolver.ts +32 -0
  161. package/src/types/encore-dsl/cadence.ts +289 -0
  162. package/src/types/encore-dsl/schema.ts +288 -0
  163. package/src/types/notification.ts +2 -1
  164. package/src/types/session.ts +6 -0
  165. package/src/types/sse.ts +5 -0
  166. package/src/types/toolCallHistory.ts +7 -0
  167. package/src/utils/agent/eventDispatch.ts +26 -5
  168. package/src/utils/agent/mcpHint.ts +50 -0
  169. package/src/utils/image/htmlSrcAttrs.ts +117 -13
  170. package/src/utils/session/sessionEntries.ts +8 -32
  171. package/client/assets/PluginScopedRoot-YjvQq0Nn.js +0 -3
  172. package/client/assets/chunk-CernVdwh.js +0 -1
  173. package/client/assets/chunk-D8eiyYIV-CAXpUwLd.js +0 -1
  174. package/client/assets/index-BwrlMMHr.js +0 -5005
  175. package/client/assets/index-CvvNuegU.css +0 -2
  176. package/client/assets/material-symbols-outlined-BOZVWuR3.woff2 +0 -0
  177. package/client/assets/runtime-protocol-vue-C1To4M3t.js +0 -1
  178. package/client/assets/vue.runtime.esm-bundler-DQ8Kjjui.js +0 -4
  179. package/server/api/routes/notifications.ts +0 -195
  180. package/server/notifier/legacy-adapters.ts +0 -76
  181. package/server/workspace/hooks/dispatcher.mjs +0 -300
  182. package/src/composables/useSelectedResult.ts +0 -49
@@ -0,0 +1,74 @@
1
+ // MCP ToolDefinition for `defineEncore` — the structural tool that
2
+ // composes or modifies an Encore DSL document.
3
+ //
4
+ // Discriminator: `obligationId` presence.
5
+ // - absent → setup (server generates `id` from `displayName`,
6
+ // rejects with 409 if the slug collides with an existing
7
+ // obligation — see `requireUniqueObligationId` in dispatch.ts)
8
+ // - present → amend the named obligation (shallow-merge top-level)
9
+ //
10
+ // The choice to use parameter PRESENCE as the discriminator (instead
11
+ // of a `kind: "setup" | "amendDefinition"` enum) gives the LLM a
12
+ // natural mental model: "I have an id" / "I don't". The setup vs
13
+ // amend intent IS the parameter shape, no redundant flag.
14
+ //
15
+ // The `dsl` JSON Schema is AUTO-DERIVED from the runtime Zod
16
+ // validator (`z.toJSONSchema(EncoreDslInput)`) — so the LLM sees
17
+ // the same field names, types, and oneOf branches the server
18
+ // enforces, with zero drift risk. The schema lives at
19
+ // `src/types/encore-dsl/` (was `server/encore/dsl/`) so plugin
20
+ // code can import it without crossing the no-server-imports lint
21
+ // boundary.
22
+
23
+ import { z } from "zod";
24
+ import type { ToolDefinition } from "gui-chat-protocol";
25
+ import { EncoreDslInput } from "../../types/encore-dsl/schema";
26
+ import { META } from "./defineEncoreMeta";
27
+
28
+ export const TOOL_NAME = META.toolName;
29
+
30
+ // Strip `$schema` — that's a top-level JSON Schema declaration, not
31
+ // valid as a property subschema. The rest (`oneOf` / `type` /
32
+ // `properties` / ...) is what we want inside `parameters.dsl`.
33
+ const generatedDslSchema = z.toJSONSchema(EncoreDslInput) as Record<string, unknown>;
34
+ const { $schema: __ignored, ...dslJsonSchema } = generatedDslSchema;
35
+
36
+ const toolDefinition: ToolDefinition = {
37
+ type: "function",
38
+ name: TOOL_NAME,
39
+ prompt:
40
+ "Use defineEncore to compose a NEW Encore obligation (no `obligationId` argument) or AMEND an existing one (pass its `obligationId`). " +
41
+ "The `dsl` argument is an OBJECT LITERAL — never a JSON-encoded string. " +
42
+ "Setup: provide the complete DSL document (version / displayName / type / cadence / targets / steps / formSchema). " +
43
+ "Amend: provide ONLY the top-level fields you want to change — the server shallow-merges onto the existing DSL. " +
44
+ "Read `config/helps/encore-dsl.md` for the full grammar, severity rules, and worked examples.",
45
+ description:
46
+ "Compose a new Encore obligation, or amend an existing one (pass obligationId). Operational actions (markStepDone, snooze, query, …) live on the sibling manageEncore tool.",
47
+ parameters: {
48
+ type: "object",
49
+ properties: {
50
+ kind: {
51
+ type: "string",
52
+ enum: [TOOL_NAME],
53
+ description: "Fixed value; the tool's only kind.",
54
+ },
55
+ dsl: {
56
+ ...dslJsonSchema,
57
+ description:
58
+ "Encore DSL document (OBJECT LITERAL — do NOT pass a JSON-encoded string). " +
59
+ "For setup (no obligationId): provide every required field shown in the schema. " +
60
+ "For amend (with obligationId): provide ONLY the top-level fields you want to change — others are preserved from the existing DSL. " +
61
+ "See `config/helps/encore-dsl.md` for cross-field rules and worked examples.",
62
+ },
63
+ obligationId: {
64
+ type: "string",
65
+ description:
66
+ "Present → amend the named obligation. Absent → setup a new one (server generates the id from displayName). If you intend to amend but forget this, the server rejects with 409 and tells you the id to pass.",
67
+ },
68
+ },
69
+ required: ["kind", "dsl"],
70
+ additionalProperties: false,
71
+ },
72
+ };
73
+
74
+ export default toolDefinition;
@@ -0,0 +1,13 @@
1
+ // Encore plugin — second META (toolName-only sibling to manageEncoreMeta).
2
+ //
3
+ // Same pattern as `scheduler/automationsMeta.ts`: two tools share one
4
+ // apiNamespace, so only ONE meta declares apiNamespace/apiRoutes/
5
+ // workspaceDirs/mcpDispatch (the full one lives in `manageEncoreMeta.ts`).
6
+ // This file exists purely so the host aggregator's `TOOL_NAMES`
7
+ // records the second tool name; everything else is shared.
8
+
9
+ import { definePluginMeta } from "../meta-types";
10
+
11
+ export const META = definePluginMeta({
12
+ toolName: "defineEncore",
13
+ });
@@ -0,0 +1,93 @@
1
+ // Encore plugin registration — two MCP tools sharing one apiNamespace
2
+ // (same pattern as scheduler/{calendar,automations}):
3
+ //
4
+ // - `defineEncore` — structural; composes or amends a DSL document.
5
+ // - `manageEncore` — operational; records progress, queries, etc.
6
+ //
7
+ // Both POST to the same `/api/encore` dispatch endpoint. The server's
8
+ // dispatch.ts routes by the `kind` field in the body (`defineEncore`
9
+ // for the structural tool, `markStepDone` / `snooze` / `query` / ...
10
+ // for the operational one).
11
+ //
12
+ // Vue surface:
13
+ // - One View at `/encore` (chat-on-mount for bell clicks). Shared
14
+ // between both tools — the page only handles `resolveNotification`
15
+ // and that's tool-independent.
16
+ //
17
+ // See plans/feat-encore-as-builtin.md for the original build plan,
18
+ // plans/feat-encore-plugin.md for the DSL spec, and
19
+ // plans/feat-encore-define-tool.md for why the tool was split.
20
+
21
+ import type { ToolResult } from "gui-chat-protocol";
22
+ import type { PluginEntry, PluginRegistration, ToolPlugin } from "../../tools/types";
23
+ import { pluginEndpoints } from "../api";
24
+ import { wrapWithScope } from "../scope";
25
+ import { apiCall } from "../../utils/api";
26
+ import { makeUuid } from "../../utils/id";
27
+ import View from "./View.vue";
28
+ import manageEncoreDefinition, { TOOL_NAME as MANAGE_ENCORE, type EncoreEndpoints } from "./manageEncoreDefinition";
29
+ import defineEncoreDefinition, { TOOL_NAME as DEFINE_ENCORE } from "./defineEncoreDefinition";
30
+ import { META as MANAGE_META } from "./manageEncoreMeta";
31
+
32
+ export interface EncoreData {
33
+ kind?: string;
34
+ ok?: boolean;
35
+ message?: string;
36
+ [key: string]: unknown;
37
+ }
38
+
39
+ /** Generate an `execute` function bound to a specific toolName so
40
+ * the result envelope carries the matching name through to chat
41
+ * history and View lookup. Both tools POST to the same dispatch
42
+ * endpoint (resolved from `MANAGE_META.apiNamespace`, which both
43
+ * tools share). */
44
+ function makeExecute(toolName: typeof MANAGE_ENCORE | typeof DEFINE_ENCORE): ToolPlugin<EncoreData>["execute"] {
45
+ return async function execute(_context, args) {
46
+ const endpoints = pluginEndpoints<EncoreEndpoints>(MANAGE_META.apiNamespace);
47
+ const { method, url } = endpoints.dispatch;
48
+ const result = await apiCall<ToolResult<EncoreData>>(url, { method, body: args });
49
+ if (!result.ok) {
50
+ return {
51
+ toolName,
52
+ uuid: makeUuid(),
53
+ message: result.error,
54
+ };
55
+ }
56
+ return {
57
+ ...result.data,
58
+ toolName,
59
+ uuid: result.data.uuid ?? makeUuid(),
60
+ };
61
+ };
62
+ }
63
+
64
+ export const manageEncorePlugin: ToolPlugin<EncoreData> = {
65
+ toolDefinition: manageEncoreDefinition,
66
+ execute: makeExecute(MANAGE_ENCORE),
67
+ isEnabled: () => true,
68
+ generatingMessage: "Updating Encore...",
69
+ viewComponent: wrapWithScope("encore", View),
70
+ };
71
+
72
+ export const defineEncorePlugin: ToolPlugin<EncoreData> = {
73
+ toolDefinition: defineEncoreDefinition,
74
+ execute: makeExecute(DEFINE_ENCORE),
75
+ isEnabled: () => true,
76
+ generatingMessage: "Composing Encore obligation...",
77
+ // Reuse the same View — `defineEncore` doesn't produce its own
78
+ // bell entries (it produces the obligation; the tick produces the
79
+ // bells), so there's nothing tool-specific to render. The shared
80
+ // View handles the chat-on-mount flow for any Encore bell.
81
+ viewComponent: wrapWithScope("encore", View),
82
+ };
83
+
84
+ const manageEntry: PluginEntry = manageEncorePlugin as unknown as PluginEntry;
85
+ const defineEntry: PluginEntry = defineEncorePlugin as unknown as PluginEntry;
86
+
87
+ // One plugin module, two tool registrations — scheduler pattern.
88
+ export const REGISTRATIONS: PluginRegistration[] = [
89
+ { toolName: MANAGE_ENCORE, entry: manageEntry },
90
+ { toolName: DEFINE_ENCORE, entry: defineEntry },
91
+ ];
92
+
93
+ export default manageEncorePlugin;
@@ -0,0 +1,100 @@
1
+ // MCP ToolDefinition for `manageEncore` (operational kinds only).
2
+ //
3
+ // Structural kinds (setup / amendDefinition) moved to the sibling
4
+ // `defineEncoreDefinition.ts`. The server-side dispatcher still
5
+ // accepts them on the wire for backward compat (the new
6
+ // `handleDefineEncore` translates to them internally), but the
7
+ // LLM-facing enum here is narrower so the LLM picks `defineEncore`
8
+ // for DSL composition and `manageEncore` for everything that
9
+ // happens after the obligation exists.
10
+ //
11
+ // Schema details live in the help file (`config/helps/encore-dsl.md`)
12
+ // which the host syncs into the workspace at every startup — keeping
13
+ // this `description` short and letting Claude lazy-read the help file
14
+ // for full grammar is the teaching strategy (see
15
+ // plans/feat-encore-plugin.md "Teaching the DSL to Claude").
16
+
17
+ import type { ToolDefinition } from "gui-chat-protocol";
18
+ import type { ResolvedRoute } from "../meta-types";
19
+ import { META } from "./manageEncoreMeta";
20
+
21
+ // Derive TOOL_NAME from META so the schema, MCP-bridge dispatch,
22
+ // and Vue executor can't drift apart. The host aggregators
23
+ // (TOOL_NAMES, API_ROUTES, WORKSPACE_PATHS) read META; everything
24
+ // downstream reads from here.
25
+ export const TOOL_NAME = META.toolName;
26
+
27
+ /** Resolved-route shape Encore exposes to the browser via
28
+ * `pluginEndpoints("encore")`. Derived from META so adding a new
29
+ * apiRoutes key flows into the type without manual edits. Shared
30
+ * between manageEncore and defineEncore — both POST to the same
31
+ * dispatch endpoint. */
32
+ export type EncoreEndpoints = { readonly [K in keyof typeof META.apiRoutes]: ResolvedRoute };
33
+
34
+ /** Action kinds the LLM is allowed to invoke via the `manageEncore`
35
+ * MCP tool. Operational only — structural (setup / amendDefinition)
36
+ * lives on the `defineEncore` tool. `resolveNotification` is
37
+ * deliberately excluded because it's a browser-only action
38
+ * dispatched by the /encore page on mount (calls `startChat`
39
+ * server-side; calling it from inside an existing chat would spawn
40
+ * a duplicate chat).
41
+ *
42
+ * When adding a new action kind, decide whether it's structural
43
+ * (writes/edits a DSL document → add to defineEncore) or
44
+ * operational (acts on existing obligation state → add here). */
45
+ export const LLM_ENCORE_KINDS = ["markStepDone", "markTargetSkipped", "recordValues", "query", "appendNote", "snooze", "unsnooze"] as const;
46
+
47
+ /** Every action kind the server-side dispatch handles, including
48
+ * browser-only ones and the structural kinds the server keeps for
49
+ * backward compat. NOT the enum exposed to Claude — used by the
50
+ * dispatch.ts switch and by tests. */
51
+ export const ALL_ENCORE_KINDS = [...LLM_ENCORE_KINDS, "resolveNotification", "setup", "amendDefinition", "defineEncore"] as const;
52
+
53
+ const toolDefinition: ToolDefinition = {
54
+ type: "function",
55
+ name: TOOL_NAME,
56
+ prompt:
57
+ "Once an Encore obligation exists, use manageEncore to record what happened (markStepDone / markTargetSkipped / recordValues / appendNote), to defer reminders (snooze / unsnooze), or to query (query). " +
58
+ "For composing a NEW obligation or amending an existing one's DSL, use the sibling defineEncore tool. " +
59
+ "Read `config/helps/encore-dsl.md` before calling — it documents every action's call shape and bell-clearing semantics.",
60
+ description: "Record progress on existing Encore obligations — close steps, skip targets, snooze, query.",
61
+ parameters: {
62
+ type: "object",
63
+ properties: {
64
+ kind: {
65
+ type: "string",
66
+ enum: [...LLM_ENCORE_KINDS],
67
+ description: "Which Encore action to perform.",
68
+ },
69
+ // Per-field type hints stay sparse — the handler validates the
70
+ // rest of the args per-kind with Zod (see
71
+ // server/encore/dispatch.ts), and a strict JSON-schema validator
72
+ // can't express cross-field rules anyway. We declare ONLY the
73
+ // fields where the LLM most often produces a structurally wrong
74
+ // shape (and the resulting Zod error reads as a "schema problem"
75
+ // that the LLM tends to loop on rather than self-correct).
76
+ //
77
+ // `values` (markStepDone / recordValues): the LLM commonly
78
+ // JSON.stringify's it or wraps a single field-map in an array
79
+ // (`"[{\"laps\": 0}]"`). Declaring `type: "object"` gives the LLM
80
+ // a strong "this is an object literal" hint at compose time.
81
+ values: {
82
+ type: "object",
83
+ description:
84
+ 'Flat field-map keyed by field name — e.g. `{"amount": 5000, "paidOn": "2026-05-16"}`. ' +
85
+ "Do NOT pass a JSON-encoded string. Do NOT wrap in an array. Do NOT nest by targetId. " +
86
+ "One call per target; the `values` are for that single target.",
87
+ additionalProperties: true,
88
+ },
89
+ },
90
+ required: ["kind"],
91
+ // The remaining args (`obligationId` / `cycleId` / `targetId` /
92
+ // `stepId` / `pendingId` / `body` / `range`) are short strings
93
+ // or scalars the LLM gets right most of the time; documenting
94
+ // them in the help file is cheaper than a JSON-schema constraint
95
+ // that doesn't know which fields apply per kind.
96
+ additionalProperties: true,
97
+ },
98
+ };
99
+
100
+ export default toolDefinition;
@@ -0,0 +1,36 @@
1
+ // Encore plugin META — the central-registry-facing metadata.
2
+ // Imported by host aggregators (`src/config/*` and
3
+ // `server/workspace/paths.ts`) which iterate over every plugin's META
4
+ // and merge automatically. Host code holds zero plugin-specific
5
+ // literals.
6
+ //
7
+ // Browser-safe: no Vue / no Node-only imports.
8
+ //
9
+ // See plans/feat-encore-as-builtin.md for the architecture and
10
+ // plans/feat-encore-plugin.md for the DSL spec the handlers
11
+ // implement.
12
+
13
+ import { definePluginMeta } from "../meta-types";
14
+
15
+ export const META = definePluginMeta({
16
+ toolName: "manageEncore",
17
+ apiNamespace: "encore",
18
+ apiRoutes: {
19
+ /** POST /api/encore — single dispatch with `kind` discriminator
20
+ * (setup / amendDefinition / markStepDone / markTargetSkipped /
21
+ * recordValues / query / appendNote / snooze / resolveNotification).
22
+ * Both the MCP bridge and the chat-on-mount page (`View.vue`,
23
+ * which dispatches `resolveNotification` on mount to start
24
+ * the chat server-side) POST here; the server splits by
25
+ * `kind`. */
26
+ dispatch: { method: "POST", path: "" },
27
+ },
28
+ mcpDispatch: "dispatch",
29
+ // `data/plugins/encore/` is the plain-name layout chosen for the
30
+ // built-in (vs. the URL-encoded `%40mulmoclaude%2Fencore-plugin`
31
+ // path the prior runtime-preset attempt used). See
32
+ // plans/feat-encore-as-builtin.md "What's intentionally different".
33
+ workspaceDirs: {
34
+ encore: "data/plugins/encore",
35
+ },
36
+ });