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.
- package/README.md +26 -0
- package/bin/mulmoclaude.js +11 -1
- package/client/assets/JsonEditor-D6WBWLoa.js +10 -0
- package/client/assets/JsonEditor-Di5xGeZY.css +1 -0
- package/client/assets/_plugin-vue_export-helper-BOai-rQB.js +1 -0
- package/client/assets/chunk-D8eiyYIV-LcKZGJv5.js +1 -0
- package/client/assets/{html2canvas-CDGcmOD3-Bkf2uOth.js → html2canvas-CDGcmOD3-XVrO-eyz.js} +1 -1
- package/client/assets/index-CyBr8Mkr.css +2 -0
- package/client/assets/index-zZIqEbNX.js +5106 -0
- package/client/assets/{index.es-DqtpmBm8-D9mAh_KQ.js → index.es-DqtpmBm8-DHT6q10o.js} +1 -1
- package/client/assets/material-symbols-outlined-DtIK7AQn.woff2 +0 -0
- package/client/assets/runtime-protocol-vue-D6kcV0wa.js +1 -0
- package/client/assets/{runtime-vue-BVUzgYGA.js → runtime-vue-fFYhnNg3.js} +1 -1
- package/client/assets/{vue-C8UuIO9J.js → vue-D4w8THF_.js} +1 -1
- package/client/assets/vue-i18n-CQbxVmNs.js +3 -0
- package/client/assets/vue.runtime.esm-bundler-BTyIdNAI.js +4 -0
- package/client/index.html +10 -10
- package/package.json +9 -8
- package/server/agent/backend/claude-code.ts +34 -0
- package/server/agent/backend/fake-echo.ts +370 -0
- package/server/agent/backend/index.ts +16 -1
- package/server/agent/config.ts +74 -24
- package/server/agent/index.ts +104 -80
- package/server/agent/mcpFailureMonitor.ts +167 -0
- package/server/agent/mcpPreflight.ts +185 -0
- package/server/agent/prompt.ts +50 -359
- package/server/agent/stdioHttpShim.ts +171 -0
- package/server/agent/stream.ts +12 -1
- package/server/api/routes/encore.ts +55 -0
- package/server/api/routes/files.ts +22 -0
- package/server/api/routes/mulmo-script.ts +19 -1
- package/server/api/routes/schedulerHandlers.ts +52 -4
- package/server/api/routes/sessions.ts +15 -0
- package/server/api/routes/skills.ts +263 -0
- package/server/build/dispatcher.mjs +299 -0
- package/server/encore/INVARIANTS.md +272 -0
- package/server/encore/boot.ts +39 -0
- package/server/encore/closure.ts +36 -0
- package/server/encore/cycle.ts +276 -0
- package/server/encore/dispatch.ts +103 -0
- package/server/encore/handlers/amend.ts +99 -0
- package/server/encore/handlers/appendNote.ts +74 -0
- package/server/encore/handlers/defineEncore.ts +42 -0
- package/server/encore/handlers/listTickets.ts +107 -0
- package/server/encore/handlers/markStepDone.ts +41 -0
- package/server/encore/handlers/markTargetSkipped.ts +33 -0
- package/server/encore/handlers/query.ts +138 -0
- package/server/encore/handlers/recordValues.ts +44 -0
- package/server/encore/handlers/resolveNotification.ts +121 -0
- package/server/encore/handlers/setup.ts +81 -0
- package/server/encore/handlers/shared.ts +137 -0
- package/server/encore/handlers/snooze.ts +87 -0
- package/server/encore/handlers/startObligationChat.ts +64 -0
- package/server/encore/handlers/startSetupChat.ts +50 -0
- package/server/encore/lock.ts +61 -0
- package/server/encore/notifier.ts +123 -0
- package/server/encore/obligation.ts +25 -0
- package/server/encore/paths.ts +78 -0
- package/server/encore/reconcile.ts +661 -0
- package/server/encore/tick.ts +191 -0
- package/server/encore/yaml-fm.ts +63 -0
- package/server/events/notifications.ts +19 -91
- package/server/index.ts +94 -9
- package/server/notifier/engine.ts +102 -1
- package/server/notifier/macosReminderAdapter.ts +30 -0
- package/server/notifier/runtime-api.ts +41 -1
- package/server/notifier/types.ts +15 -2
- package/server/plugins/runtime.ts +11 -2
- package/server/prompts/index.ts +39 -0
- package/server/prompts/system/journal-pointer.md +12 -0
- package/server/prompts/system/memory-management-atomic.md +33 -0
- package/server/prompts/system/memory-management-topic.md +60 -0
- package/server/prompts/system/news-concierge.md +24 -0
- package/server/prompts/system/sandbox-tools.md +10 -0
- package/server/prompts/system/sources-context.md +16 -0
- package/server/prompts/system/system.md +91 -0
- package/server/system/announceOptionalDeps.ts +57 -0
- package/server/system/appVersion.ts +34 -0
- package/server/system/config.ts +17 -1
- package/server/system/docker.ts +14 -6
- package/server/system/env.ts +18 -5
- package/server/system/optionalDeps.ts +129 -0
- package/server/utils/cli-flags.d.mts +14 -0
- package/server/utils/cli-flags.mjs +53 -0
- package/server/utils/files/encore-io.ts +111 -0
- package/server/utils/time.ts +6 -0
- package/server/workspace/helps/business.md +2 -2
- package/server/workspace/helps/encore-dsl.md +482 -0
- package/server/workspace/helps/index.md +15 -13
- package/server/workspace/helps/mulmoscript.md +3 -3
- package/server/workspace/helps/sandbox.md +2 -2
- package/server/workspace/hooks/dispatcher.ts +7 -5
- package/server/workspace/hooks/provision.ts +6 -3
- package/server/workspace/paths.ts +13 -4
- package/server/workspace/skills/catalog.ts +355 -0
- package/server/workspace/skills/external/catalog.ts +283 -0
- package/server/workspace/skills/external/clone.ts +129 -0
- package/server/workspace/skills/external/id.ts +194 -0
- package/server/workspace/skills/external/install.ts +417 -0
- package/server/workspace/skills/external/presets.ts +50 -0
- package/server/workspace/skills-preset.ts +29 -17
- package/server/workspace/workspace.ts +10 -5
- package/src/App.vue +37 -8
- package/src/components/FileContentRenderer.vue +102 -9
- package/src/components/JsonEditor.vue +160 -0
- package/src/components/NotificationBell.vue +35 -3
- package/src/components/PluginLauncher.vue +20 -41
- package/src/components/RightSidebar.vue +19 -0
- package/src/components/SettingsMcpTab.vue +58 -11
- package/src/components/SettingsModal.vue +22 -1
- package/src/components/StackView.vue +10 -1
- package/src/components/TodoExplorer.vue +16 -0
- package/src/components/todo/TodoKanbanView.vue +34 -6
- package/src/composables/useNotifications.ts +21 -1
- package/src/config/apiRoutes.ts +0 -6
- package/src/config/mcpCatalog.ts +12 -7
- package/src/config/mcpTypes.ts +5 -0
- package/src/config/roles.ts +52 -15
- package/src/config/systemFileDescriptors.ts +12 -0
- package/src/lang/de.ts +108 -12
- package/src/lang/en.ts +105 -11
- package/src/lang/es.ts +106 -11
- package/src/lang/fr.ts +106 -11
- package/src/lang/ja.ts +104 -11
- package/src/lang/ko.ts +105 -11
- package/src/lang/pt-BR.ts +106 -11
- package/src/lang/zh.ts +103 -11
- package/src/main.ts +1 -0
- package/src/plugins/_generated/metas.ts +4 -0
- package/src/plugins/_generated/registrations.ts +2 -0
- package/src/plugins/_generated/server-bindings.ts +5 -0
- package/src/plugins/encore/EncoreDashboard.vue +504 -0
- package/src/plugins/encore/EncoreRedirect.vue +116 -0
- package/src/plugins/encore/View.vue +36 -0
- package/src/plugins/encore/defineEncoreDefinition.ts +74 -0
- package/src/plugins/encore/defineEncoreMeta.ts +13 -0
- package/src/plugins/encore/index.ts +93 -0
- package/src/plugins/encore/manageEncoreDefinition.ts +100 -0
- package/src/plugins/encore/manageEncoreMeta.ts +36 -0
- package/src/plugins/manageSkills/View.vue +832 -30
- package/src/plugins/manageSkills/categories.ts +125 -0
- package/src/plugins/manageSkills/meta.ts +30 -0
- package/src/plugins/markdown/definition.ts +3 -3
- package/src/plugins/meta-types.ts +5 -0
- package/src/plugins/presentMulmoScript/Preview.vue +3 -3
- package/src/plugins/presentMulmoScript/View.vue +157 -33
- package/src/plugins/presentMulmoScript/meta.ts +4 -0
- package/src/plugins/scheduler/View.vue +45 -9
- package/src/plugins/scheduler/calendarDefinition.ts +6 -2
- package/src/plugins/scheduler/multiDayHelpers.ts +95 -0
- package/src/plugins/skill/View.vue +1 -5
- package/src/plugins/spreadsheet/View.vue +3 -3
- package/src/plugins/spreadsheet/definition.ts +1 -1
- package/src/plugins/textResponse/Preview.vue +14 -1
- package/src/plugins/textResponse/View.vue +39 -24
- package/src/plugins/wiki/components/WikiPageBody.vue +4 -0
- package/src/router/index.ts +11 -0
- package/src/router/pageRoutes.ts +1 -0
- package/src/types/encore-dsl/at-expression.ts +120 -0
- package/src/types/encore-dsl/at-resolver.ts +32 -0
- package/src/types/encore-dsl/cadence.ts +289 -0
- package/src/types/encore-dsl/schema.ts +288 -0
- package/src/types/notification.ts +2 -1
- package/src/types/session.ts +6 -0
- package/src/types/sse.ts +5 -0
- package/src/types/toolCallHistory.ts +7 -0
- package/src/utils/agent/eventDispatch.ts +26 -5
- package/src/utils/agent/mcpHint.ts +50 -0
- package/src/utils/image/htmlSrcAttrs.ts +117 -13
- package/src/utils/session/sessionEntries.ts +8 -32
- package/client/assets/PluginScopedRoot-YjvQq0Nn.js +0 -3
- package/client/assets/chunk-CernVdwh.js +0 -1
- package/client/assets/chunk-D8eiyYIV-CAXpUwLd.js +0 -1
- package/client/assets/index-BwrlMMHr.js +0 -5005
- package/client/assets/index-CvvNuegU.css +0 -2
- package/client/assets/material-symbols-outlined-BOZVWuR3.woff2 +0 -0
- package/client/assets/runtime-protocol-vue-C1To4M3t.js +0 -1
- package/client/assets/vue.runtime.esm-bundler-DQ8Kjjui.js +0 -4
- package/server/api/routes/notifications.ts +0 -195
- package/server/notifier/legacy-adapters.ts +0 -76
- package/server/workspace/hooks/dispatcher.mjs +0 -300
- 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
|
+
});
|