@rubytech/create-sitedesk-code 0.1.551 → 0.1.552

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 (82) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +5 -0
  3. package/payload/platform/plugins/scheduling/PLUGIN.md +22 -0
  4. package/payload/platform/plugins/scheduling/mcp/dist/index.js +107 -6
  5. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  6. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-freebusy.test.d.ts +2 -0
  7. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-freebusy.test.d.ts.map +1 -0
  8. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-freebusy.test.js +216 -0
  9. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-freebusy.test.js.map +1 -0
  10. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.d.ts +2 -0
  11. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.d.ts.map +1 -0
  12. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js +128 -0
  13. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js.map +1 -0
  14. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.d.ts +2 -0
  15. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.d.ts.map +1 -0
  16. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js +135 -0
  17. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js.map +1 -0
  18. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-audit.test.js +132 -0
  19. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-audit.test.js.map +1 -1
  20. package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-freebusy.d.ts +86 -0
  21. package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-freebusy.d.ts.map +1 -0
  22. package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-freebusy.js +240 -0
  23. package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-freebusy.js.map +1 -0
  24. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +92 -0
  25. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -0
  26. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js +193 -0
  27. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -0
  28. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts +8 -1
  29. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts.map +1 -1
  30. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js.map +1 -1
  31. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts +94 -1
  32. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -1
  33. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +299 -0
  34. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
  35. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.d.ts +2 -0
  36. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.d.ts.map +1 -0
  37. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js +146 -0
  38. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js.map +1 -0
  39. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +27 -0
  40. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
  41. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +18 -0
  42. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
  43. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +119 -64
  44. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  45. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-connector-busy-sync.test.js +84 -1
  46. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-connector-busy-sync.test.js.map +1 -1
  47. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.d.ts +2 -0
  48. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.d.ts.map +1 -0
  49. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js +218 -0
  50. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js.map +1 -0
  51. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.d.ts +2 -0
  52. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.d.ts.map +1 -0
  53. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +291 -0
  54. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map +1 -0
  55. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.d.ts +26 -2
  56. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.d.ts.map +1 -1
  57. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.js +51 -2
  58. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.js.map +1 -1
  59. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +31 -0
  60. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
  61. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +44 -1
  62. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
  63. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts +3 -1
  64. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
  65. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +57 -3
  66. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
  67. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts +148 -0
  68. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts.map +1 -0
  69. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +410 -0
  70. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -0
  71. package/payload/platform/plugins/scheduling/mcp/package.json +1 -0
  72. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  73. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  74. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  75. package/payload/platform/services/claude-session-manager/dist/pty-census.d.ts +51 -4
  76. package/payload/platform/services/claude-session-manager/dist/pty-census.d.ts.map +1 -1
  77. package/payload/platform/services/claude-session-manager/dist/pty-census.js +60 -10
  78. package/payload/platform/services/claude-session-manager/dist/pty-census.js.map +1 -1
  79. package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.d.ts +64 -1
  80. package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.d.ts.map +1 -1
  81. package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.js +189 -6
  82. package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.js.map +1 -1
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Task 2381 — reading the account's calendar free/busy without a model turn.
3
+ *
4
+ * The "Booking calendar connector sync" routine spawned a model every 30 minutes
5
+ * to do two mechanical things: work out which connector the account had
6
+ * authorised, and read 15 days of free/busy from it. Neither is a decision. This
7
+ * module does both deterministically so the routine can run on the headless
8
+ * `action` rail.
9
+ *
10
+ * The provider is reached by SPAWNING its own MCP server, not by importing it. No
11
+ * plugin in this tree imports another plugin's source (the only cross-boundary
12
+ * imports are built artifacts under `platform/lib`), the provider owns the
13
+ * decryption of its own tokens, and `dispatchAction` in `check-due-events.ts`
14
+ * already reaches plugins exactly this way.
15
+ */
16
+ import { readFileSync } from "node:fs";
17
+ import { join } from "node:path";
18
+ import { detectCalendarConnectors } from "./connector-sync-provision.js";
19
+ import { callPluginTool } from "./gate.js";
20
+ /**
21
+ * The account's calendar connector, decided rather than chosen by a model.
22
+ *
23
+ * `detectCalendarConnectors` returns a sorted list, so google precedes m365 and
24
+ * the pick is deterministic. The stored `connector` is a single enum; an account
25
+ * holding both is real, and the skipped one is named on the resolution line so an
26
+ * ignored calendar is visible rather than silent.
27
+ */
28
+ export function resolveConnector(accountDir) {
29
+ const found = detectCalendarConnectors(accountDir);
30
+ if (found.length === 0)
31
+ return { connector: "none", skipped: null };
32
+ return { connector: found[0], skipped: found[1] ?? null };
33
+ }
34
+ /**
35
+ * The environment a provider MCP needs, assembled for the action rail.
36
+ *
37
+ * The heartbeat's cron line sets only `PLATFORM_ROOT`, `NEO4J_URI` and
38
+ * `MAXY_UI_INTERNAL_PORT` (create-maxy-code/src/cron-registration.ts), so a child
39
+ * spawned from it inherits none of the per-plugin credentials a session-manager
40
+ * spawn would stamp from the `PLUGIN.md` `mcp.env` block. They are read from
41
+ * `brand.json` instead, which is the same source those placeholders resolve from.
42
+ *
43
+ * A missing client id throws. Returning an env without one would let the provider
44
+ * boot, refuse the call for want of a vendor app, and be indistinguishable
45
+ * downstream from an account whose calendar is genuinely empty.
46
+ */
47
+ export function providerEnv(platformRoot, accountId, connector) {
48
+ const brandPath = join(platformRoot, "config", "brand.json");
49
+ let brand;
50
+ try {
51
+ brand = JSON.parse(readFileSync(brandPath, "utf-8"));
52
+ }
53
+ catch (err) {
54
+ throw new Error(`cannot read ${brandPath}: ${err.message}`);
55
+ }
56
+ const str = (v) => (typeof v === "string" ? v : "");
57
+ const env = { PLATFORM_ROOT: platformRoot, ACCOUNT_ID: accountId };
58
+ if (connector === "google") {
59
+ const id = str(brand.googleClientId);
60
+ const secret = str(brand.googleClientSecret);
61
+ if (!id || !secret) {
62
+ throw new Error("this brand ships no Google vendor app (client id and secret must both be present)");
63
+ }
64
+ env.GOOGLE_CLIENT_ID = id;
65
+ env.GOOGLE_CLIENT_SECRET = secret;
66
+ return env;
67
+ }
68
+ const id = str(brand.outlookClientId);
69
+ if (!id)
70
+ throw new Error("this brand ships no Outlook vendor app (outlookClientId is empty)");
71
+ env.OUTLOOK_CLIENT_ID = id;
72
+ env.OUTLOOK_TENANT_ID = str(brand.outlookTenantId) || "common";
73
+ return env;
74
+ }
75
+ function isInterval(v) {
76
+ const o = v;
77
+ return !!o && typeof o.start === "string" && typeof o.end === "string";
78
+ }
79
+ /** Google returns one busy list per requested calendar; with no `calendars`
80
+ * argument that is the account's primary calendar alone. Every list is
81
+ * flattened: the booking page blocks on any busy time, whichever calendar it
82
+ * came from. */
83
+ async function readGoogleBusy(opts) {
84
+ const raw = await opts.call("google", "google-calendar-freebusy", {
85
+ start: opts.from,
86
+ end: opts.to,
87
+ });
88
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
89
+ throw new Error(`unexpected google-calendar-freebusy payload: ${JSON.stringify(raw).slice(0, 200)}`);
90
+ }
91
+ const out = [];
92
+ for (const slots of Object.values(raw)) {
93
+ if (!Array.isArray(slots)) {
94
+ throw new Error("unexpected google-calendar-freebusy payload: calendar value is not an array");
95
+ }
96
+ for (const s of slots) {
97
+ if (!isInterval(s)) {
98
+ throw new Error("unexpected google-calendar-freebusy payload: busy entry has no start/end");
99
+ }
100
+ out.push({ start: s.start, end: s.end });
101
+ }
102
+ }
103
+ return out;
104
+ }
105
+ /**
106
+ * Graph returns `scheduleItems[].start.dateTime` with a sibling `timeZone` field
107
+ * that the outlook plugin's tool drops, so what arrives here carries no zone
108
+ * designator. The window is requested in UTC, so a zone-less instant is UTC and
109
+ * is stamped as such. A string already carrying `Z` or an offset is left alone —
110
+ * re-stamping it would move the interval.
111
+ */
112
+ export function normaliseGraphInstant(dateTime) {
113
+ if (/(Z|[+-]\d{2}:?\d{2})$/.test(dateTime))
114
+ return dateTime;
115
+ return `${dateTime}Z`;
116
+ }
117
+ /**
118
+ * The one mailbox whose schedule this account's busy sync reads.
119
+ *
120
+ * The mailbox directory name under `secrets/outlook/mailboxes/` is a sanitised
121
+ * `graphUserId` and the address lives inside the encrypted token blob, so it
122
+ * cannot be read off disk by a process that is not the outlook plugin. Zero or
123
+ * two-or-more addressable mailboxes both throw, mirroring the outlook plugin's
124
+ * own sole-mailbox rule: guessing one would publish the wrong person's free time.
125
+ */
126
+ async function resolveM365Address(opts) {
127
+ const raw = await opts.call("outlook", "outlook-mailbox-list", {});
128
+ const rows = raw?.mailboxes;
129
+ const addressable = (Array.isArray(rows) ? rows : [])
130
+ .filter((m) => m.status === "ok" && typeof m.mail === "string" && m.mail.length > 0)
131
+ .map((m) => m.mail);
132
+ if (addressable.length === 0) {
133
+ throw new Error("no addressable Outlook mailbox for this account; run outlook-account-register");
134
+ }
135
+ if (addressable.length > 1) {
136
+ throw new Error(`two or more Outlook mailboxes are addressable (${addressable.join(", ")}); the busy sync cannot choose between them`);
137
+ }
138
+ return addressable[0];
139
+ }
140
+ async function readM365Busy(opts) {
141
+ const address = await resolveM365Address(opts);
142
+ const raw = await opts.call("outlook", "outlook-calendar-freebusy", {
143
+ schedules: [address],
144
+ start: { dateTime: opts.from, timeZone: "UTC" },
145
+ end: { dateTime: opts.to, timeZone: "UTC" },
146
+ });
147
+ const availability = raw?.availability;
148
+ if (!Array.isArray(availability)) {
149
+ throw new Error(`unexpected outlook-calendar-freebusy payload: ${JSON.stringify(raw).slice(0, 200)}`);
150
+ }
151
+ const out = [];
152
+ let loggedRaw = false;
153
+ for (const entry of availability) {
154
+ // An address Graph could not resolve comes back with an error and an EMPTY
155
+ // busy list, which is byte-identical to a free calendar. Reading it as free
156
+ // would publish the operator's booked time as available.
157
+ if (entry.error) {
158
+ throw new Error(`Graph could not resolve the mailbox schedule: ${String(entry.error)}`);
159
+ }
160
+ for (const b of Array.isArray(entry.busy) ? entry.busy : []) {
161
+ if (!isInterval(b)) {
162
+ throw new Error("unexpected outlook-calendar-freebusy payload: busy entry has no start/end");
163
+ }
164
+ if (!loggedRaw) {
165
+ // One raw line per read. The UTC reading above is an assumption about a
166
+ // Graph response this tree holds no fixture for; the unparsed value makes
167
+ // a wrong assumption visible in the log rather than silently shifting
168
+ // every slot on the booking page by the account's offset.
169
+ console.error(`[connector-busy-sync] op=m365-raw-interval start=${JSON.stringify(b.start)} end=${JSON.stringify(b.end)}`);
170
+ loggedRaw = true;
171
+ }
172
+ out.push({ start: normaliseGraphInstant(b.start), end: normaliseGraphInstant(b.end) });
173
+ }
174
+ }
175
+ return out;
176
+ }
177
+ /**
178
+ * The account's busy intervals over the window, read from its own connector.
179
+ *
180
+ * Every failure throws. Returning `[]` on a failed read would clear the stored
181
+ * busy set and publish the operator's booked time as free, and a booking page
182
+ * serving its last successful write looks correct either way — so an empty list
183
+ * must only ever mean the calendar is genuinely free.
184
+ */
185
+ export async function readConnectorBusy(opts) {
186
+ if (opts.connector === "google")
187
+ return readGoogleBusy(opts);
188
+ return readM365Busy(opts);
189
+ }
190
+ // ---------------------------------------------------------------------------
191
+ // The provider spawn
192
+ // ---------------------------------------------------------------------------
193
+ /**
194
+ * A `ProviderCall` that reaches the provider plugin's own MCP server.
195
+ *
196
+ * The transport is `callPluginTool`, the one Task 2378 extracted from
197
+ * `dispatchAction`. Sharing it rather than writing a second one is the point:
198
+ * this call is spawned from the same heartbeat, so it needs the same timeout,
199
+ * the same `ACCOUNT_ID` scoping, the same captured child stderr, and above all
200
+ * the same `PLATFORM_PORT` bridge — the cron line does not export that name and
201
+ * every plugin resolves its loopback base URL from it, so a transport without it
202
+ * throws on port resolution before the tool runs.
203
+ *
204
+ * It is a spawn rather than an import because no plugin in this tree imports
205
+ * another plugin's source, and because the provider owns the decryption of its
206
+ * own tokens.
207
+ */
208
+ export function spawnProviderCall(platformRoot, accountId, connector) {
209
+ // Resolved once, outside the returned closure: a brand shipping no vendor app
210
+ // for this connector must fail before any child is spawned.
211
+ const credentials = providerEnv(platformRoot, accountId, connector);
212
+ return async (plugin, tool, args) => {
213
+ let call;
214
+ try {
215
+ call = await callPluginTool(plugin, tool, JSON.stringify(args), accountId, credentials);
216
+ }
217
+ catch (err) {
218
+ // A transport failure carries the child's stderr, which is where a
219
+ // provider's own refusal reason (an expired refresh token, a missing
220
+ // vendor app) is written. Dropping it would leave `op=read-failed`
221
+ // reporting only that something went wrong.
222
+ const e = err;
223
+ const detail = e.childStderr ? `${e.message} — child stderr: ${e.childStderr.trim()}` : String(e.message);
224
+ throw new Error(`${tool} failed: ${detail}`);
225
+ }
226
+ const text = (Array.isArray(call.result.content) ? call.result.content : [])
227
+ .filter((c) => c.type === "text")
228
+ .map((c) => String(c.text))
229
+ .join("\n");
230
+ if (call.result.isError === true)
231
+ throw new Error(`${tool} returned an error: ${text}`);
232
+ try {
233
+ return JSON.parse(text);
234
+ }
235
+ catch {
236
+ throw new Error(`${tool} returned a non-JSON payload: ${text.slice(0, 200)}`);
237
+ }
238
+ };
239
+ }
240
+ //# sourceMappingURL=connector-freebusy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connector-freebusy.js","sourceRoot":"","sources":["../../src/lib/connector-freebusy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import type { EventGate } from "../scripts/agent-turn-dispatch.js";
2
+ /**
3
+ * The 10-minute ceiling `dispatchAction` has always used. Re-exported here
4
+ * because `callPluginTool` now owns the timeout for both callers, so a gate and
5
+ * an action cannot drift apart on how long a plugin tool may run.
6
+ */
7
+ export declare const DISPATCH_TIMEOUT_MS = 600000;
8
+ /**
9
+ * A tool call's outcome, structurally typed rather than imported from the MCP
10
+ * SDK. The SDK ships dual ESM/CJS packages with conditional exports and the
11
+ * plugin workspaces pin their own copies, so importing its result type here
12
+ * would couple this module's compilation to the consumer's resolution mode —
13
+ * the same constraint `lib/mcp-eager/src/index.ts` records for `ZodRawShape`.
14
+ * Only three members are read anywhere in this plugin.
15
+ */
16
+ export interface ToolCallResult {
17
+ isError?: boolean;
18
+ content?: unknown;
19
+ structuredContent?: Record<string, unknown>;
20
+ }
21
+ export interface PluginToolCall {
22
+ result: ToolCallResult;
23
+ /** Child stderr, capped at 4KB. Captured on every call, read on failure. */
24
+ childStderr: string;
25
+ }
26
+ /**
27
+ * A transport-level failure, distinct from a tool that ran and returned
28
+ * `isError`. `kind` separates the timeout from every other failure because the
29
+ * two are recorded differently: `dispatchAction` writes `timeout` rather than
30
+ * `error` to `lastDispatchResult`, and the gate's fail-open line names which of
31
+ * the two it was.
32
+ */
33
+ export declare class PluginToolError extends Error {
34
+ readonly kind: "timeout" | "error";
35
+ readonly childStderr: string;
36
+ constructor(message: string, kind: "timeout" | "error", childStderr: string);
37
+ }
38
+ /**
39
+ * Spawn a plugin's MCP server over stdio, call one tool, close.
40
+ *
41
+ * Extracted from `dispatchAction` so the gate inherits the whole of its
42
+ * transport contract unchanged: the dispatch timeout, `ACCOUNT_ID` env scoping,
43
+ * and captured child stderr. Two callers sharing one body is the point — a gate
44
+ * that connected differently from an action would be a second transport to keep
45
+ * correct.
46
+ *
47
+ * Returns the raw result, including a result carrying `isError: true`. Deciding
48
+ * what an errored tool means belongs to the caller: an action treats it as a
49
+ * failed dispatch, a gate treats it as fail-open.
50
+ */
51
+ export declare function callPluginTool(plugin: string, tool: string, args: string | null, accountId: string, extraEnv?: Record<string, string>): Promise<PluginToolCall>;
52
+ /**
53
+ * What the dispatcher does about this fire.
54
+ *
55
+ * `has-work` and every `fail-open` variant dispatch; only `no-work` skips. They
56
+ * are separate cases rather than one boolean because the log line differs and
57
+ * because a fail-open must never be readable as a gate that returned false —
58
+ * that confusion is exactly how a silently muted routine would be missed.
59
+ */
60
+ export type GateVerdict = {
61
+ kind: "has-work";
62
+ } | {
63
+ kind: "no-work";
64
+ } | {
65
+ kind: "fail-open";
66
+ reason: "error" | "timeout" | "no-structured-result";
67
+ detail: string;
68
+ };
69
+ /** Injectable for tests; production passes `callPluginTool`. */
70
+ export type PluginToolCaller = (plugin: string, tool: string, args: string | null, accountId: string) => Promise<PluginToolCall>;
71
+ /**
72
+ * Evaluate one gate and say whether this fire reaches the model.
73
+ *
74
+ * Reads `structuredContent.hasWork` and nothing else. `content[]` is prose and
75
+ * is never consulted for control flow: parsing a third-party tool's wording to
76
+ * decide whether to spend a model turn is the failure mode the plugin doctrine
77
+ * names outright.
78
+ *
79
+ * Fails OPEN on every unreadable outcome — a throw, a timeout, an errored
80
+ * result, an absent `structuredContent`, a `hasWork` that is not a boolean.
81
+ * Failing closed would silently mute a routine and produce the Task 2313
82
+ * "looks live and delivers nothing" class with no alarm; failing open costs at
83
+ * worst the fires that were already happening before this task.
84
+ *
85
+ * Emits exactly one line, `op=evaluated` or `op=fail-open`, never both and never
86
+ * neither. `op=skipped` is the caller's, because only the caller knows the skip
87
+ * actually happened.
88
+ *
89
+ * Never throws — the sweep's contract. One broken gate must not abort the tick.
90
+ */
91
+ export declare function evaluateGate(gate: EventGate, eventId: string, accountId: string, call?: PluginToolCaller): Promise<GateVerdict>;
92
+ //# sourceMappingURL=gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/lib/gate.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,SAAU,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,cAAc,CAAC;IACvB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IAGtC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM;gBAF5B,OAAO,EAAE,MAAM,EACN,IAAI,EAAE,SAAS,GAAG,OAAO,EACzB,WAAW,EAAE,MAAM;CAK/B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,SAAS,EAAE,MAAM,EAOjB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACpC,OAAO,CAAC,cAAc,CAAC,CAoFzB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,sBAAsB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhG,gEAAgE;AAChE,MAAM,MAAM,gBAAgB,GAAG,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,gBAAiC,GACtC,OAAO,CAAC,WAAW,CAAC,CA4CtB"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Task 2378 — the precondition gate: a headless MCP call that decides whether a
3
+ * due agent-bearing routine reaches the model at all.
4
+ *
5
+ * Before this, an agent-bearing `:Event` fired because `nextRun` was due and
6
+ * nothing else was consulted. On the one routine measured in depth, 535 of 564
7
+ * fires (95%) sent nothing and still cost a median 24,830 output tokens each,
8
+ * because the operator's "only message me if something is new" rule lives inside
9
+ * the `agentPrompt` and is therefore read AFTER the spawn and after the sweep.
10
+ * It gates the outbound message, never the invocation.
11
+ *
12
+ * This module lives outside `check-due-events.ts` for the reason
13
+ * `dispatchGapReason` and `targetOf` already do: that module calls `main()` at
14
+ * import time and so cannot be imported by a test. The task's Touches list names
15
+ * `check-due-events.ts` for `callPluginTool`; putting it there would make the
16
+ * fail-open branches — the ones most likely to be inverted by a later edit —
17
+ * untestable, which is the opposite of what the task asks for.
18
+ */
19
+ import { existsSync } from "node:fs";
20
+ import { resolve } from "node:path";
21
+ /**
22
+ * The 10-minute ceiling `dispatchAction` has always used. Re-exported here
23
+ * because `callPluginTool` now owns the timeout for both callers, so a gate and
24
+ * an action cannot drift apart on how long a plugin tool may run.
25
+ */
26
+ export const DISPATCH_TIMEOUT_MS = 600_000;
27
+ /**
28
+ * A transport-level failure, distinct from a tool that ran and returned
29
+ * `isError`. `kind` separates the timeout from every other failure because the
30
+ * two are recorded differently: `dispatchAction` writes `timeout` rather than
31
+ * `error` to `lastDispatchResult`, and the gate's fail-open line names which of
32
+ * the two it was.
33
+ */
34
+ export class PluginToolError extends Error {
35
+ kind;
36
+ childStderr;
37
+ constructor(message, kind, childStderr) {
38
+ super(message);
39
+ this.kind = kind;
40
+ this.childStderr = childStderr;
41
+ this.name = "PluginToolError";
42
+ }
43
+ }
44
+ /**
45
+ * Spawn a plugin's MCP server over stdio, call one tool, close.
46
+ *
47
+ * Extracted from `dispatchAction` so the gate inherits the whole of its
48
+ * transport contract unchanged: the dispatch timeout, `ACCOUNT_ID` env scoping,
49
+ * and captured child stderr. Two callers sharing one body is the point — a gate
50
+ * that connected differently from an action would be a second transport to keep
51
+ * correct.
52
+ *
53
+ * Returns the raw result, including a result carrying `isError: true`. Deciding
54
+ * what an errored tool means belongs to the caller: an action treats it as a
55
+ * failed dispatch, a gate treats it as fail-open.
56
+ */
57
+ export async function callPluginTool(plugin, tool, args, accountId,
58
+ // Task 2381 — per-plugin credentials the caller already resolved, overlaid
59
+ // last. The connector busy sync reaches the google and outlook plugins from
60
+ // this same heartbeat, and those need a client id and secret that only their
61
+ // own PLUGIN.md mcp.env block would otherwise stamp. A second transport that
62
+ // differed on the timeout, on ACCOUNT_ID scoping or on the PLATFORM_PORT
63
+ // bridge below is exactly what this function exists to prevent.
64
+ extraEnv = {}) {
65
+ const platformRoot = process.env.PLATFORM_ROOT;
66
+ const serverPath = resolve(platformRoot, "plugins", plugin, "mcp", "dist", "index.js");
67
+ if (!existsSync(serverPath)) {
68
+ throw new PluginToolError(`MCP server not found: ${serverPath}`, "error", "");
69
+ }
70
+ // Dynamic import — the MCP SDK Client is only needed when actually calling.
71
+ const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
72
+ const { StdioClientTransport } = await import("@modelcontextprotocol/sdk/client/stdio.js");
73
+ // Build env: inherit parent env (for NEO4J_*, OLLAMA_*, etc.) + set ACCOUNT_ID
74
+ const env = {};
75
+ for (const [k, v] of Object.entries(process.env)) {
76
+ if (v !== undefined)
77
+ env[k] = v;
78
+ }
79
+ env.PLATFORM_ROOT = platformRoot;
80
+ env.ACCOUNT_ID = accountId;
81
+ // Task 2378 — the cron heartbeat exports PLATFORM_ROOT, NEO4J_URI and
82
+ // MAXY_UI_INTERNAL_PORT and nothing else (create-maxy-code/src/cron-registration.ts),
83
+ // while every plugin resolves its loopback base URL from PLATFORM_PORT
84
+ // (storage-broker/mcp/src/index.ts:28). A plugin tool spawned from the
85
+ // heartbeat therefore threw on port resolution before it could run a single
86
+ // check. The systemd/launchd unit already sets both names to the same value
87
+ // (create-maxy-code/src/port-resolution.ts:350-351), so this makes the cron
88
+ // env match the unit rather than inventing a port. Never overwrites a
89
+ // PLATFORM_PORT that is already present.
90
+ if (!env.PLATFORM_PORT && env.MAXY_UI_INTERNAL_PORT) {
91
+ env.PLATFORM_PORT = env.MAXY_UI_INTERNAL_PORT;
92
+ }
93
+ Object.assign(env, extraEnv);
94
+ const transport = new StdioClientTransport({
95
+ command: process.execPath,
96
+ args: [serverPath],
97
+ env,
98
+ stderr: "pipe",
99
+ });
100
+ // Collect child stderr for diagnostics on failure
101
+ let childStderr = "";
102
+ const stderrStream = transport.stderr;
103
+ if (stderrStream) {
104
+ stderrStream.on("data", (chunk) => {
105
+ // Cap at 4KB to avoid unbounded memory
106
+ if (childStderr.length < 4096) {
107
+ childStderr += chunk.toString("utf-8").slice(0, 4096 - childStderr.length);
108
+ }
109
+ });
110
+ }
111
+ const client = new Client({ name: "event-dispatcher", version: "1.0.0" });
112
+ let timedOut = false;
113
+ // The timeout kills the child process via client.close(), which causes
114
+ // the pending callTool() promise to reject — unlike AbortController,
115
+ // this actually stops the work.
116
+ const timeout = setTimeout(() => {
117
+ timedOut = true;
118
+ client.close().catch(() => { });
119
+ }, DISPATCH_TIMEOUT_MS);
120
+ try {
121
+ await client.connect(transport);
122
+ const parsed = args ? JSON.parse(args) : {};
123
+ const result = (await client.callTool({ name: tool, arguments: parsed }));
124
+ return { result, childStderr };
125
+ }
126
+ catch (err) {
127
+ throw new PluginToolError(err instanceof Error ? err.message : String(err), timedOut ? "timeout" : "error", childStderr);
128
+ }
129
+ finally {
130
+ clearTimeout(timeout);
131
+ if (!timedOut) {
132
+ try {
133
+ await client.close();
134
+ }
135
+ catch {
136
+ // Best-effort cleanup
137
+ }
138
+ }
139
+ }
140
+ }
141
+ /**
142
+ * Evaluate one gate and say whether this fire reaches the model.
143
+ *
144
+ * Reads `structuredContent.hasWork` and nothing else. `content[]` is prose and
145
+ * is never consulted for control flow: parsing a third-party tool's wording to
146
+ * decide whether to spend a model turn is the failure mode the plugin doctrine
147
+ * names outright.
148
+ *
149
+ * Fails OPEN on every unreadable outcome — a throw, a timeout, an errored
150
+ * result, an absent `structuredContent`, a `hasWork` that is not a boolean.
151
+ * Failing closed would silently mute a routine and produce the Task 2313
152
+ * "looks live and delivers nothing" class with no alarm; failing open costs at
153
+ * worst the fires that were already happening before this task.
154
+ *
155
+ * Emits exactly one line, `op=evaluated` or `op=fail-open`, never both and never
156
+ * neither. `op=skipped` is the caller's, because only the caller knows the skip
157
+ * actually happened.
158
+ *
159
+ * Never throws — the sweep's contract. One broken gate must not abort the tick.
160
+ */
161
+ export async function evaluateGate(gate, eventId, accountId, call = callPluginTool) {
162
+ const started = Date.now();
163
+ const id8 = eventId.slice(0, 8);
164
+ const failOpen = (reason, detail) => {
165
+ console.error(`[schedule-gate] op=fail-open eventId=${id8} reason=${reason} detail=${detail}`);
166
+ return { kind: "fail-open", reason, detail };
167
+ };
168
+ let call_;
169
+ try {
170
+ call_ = await call(gate.plugin, gate.tool, gate.args, accountId);
171
+ }
172
+ catch (err) {
173
+ const kind = err instanceof PluginToolError ? err.kind : "error";
174
+ return failOpen(kind, err instanceof Error ? err.message : String(err));
175
+ }
176
+ // A tool that ran and reported failure is as unreadable as one that threw.
177
+ if (call_.result.isError === true) {
178
+ return failOpen("error", "tool returned isError");
179
+ }
180
+ const hasWork = call_.result.structuredContent?.hasWork;
181
+ if (typeof hasWork !== "boolean") {
182
+ // Names both the absent case and the wrong-type case, because a gate
183
+ // returning `hasWork: "false"` is exactly as unusable as one returning
184
+ // nothing, and a truthiness read of that string would skip every fire.
185
+ return failOpen("no-structured-result", call_.result.structuredContent === undefined
186
+ ? "no structuredContent"
187
+ : `hasWork is ${typeof hasWork}`);
188
+ }
189
+ console.error(`[schedule-gate] op=evaluated eventId=${id8} plugin=${gate.plugin} tool=${gate.tool} ` +
190
+ `hasWork=${hasWork} ms=${Date.now() - started}`);
191
+ return hasWork ? { kind: "has-work" } : { kind: "no-work" };
192
+ }
193
+ //# sourceMappingURL=gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/lib/gate.ts"],"names":[],"mappings":"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"}
@@ -12,8 +12,15 @@ export type RunMode = "agent" | "action" | "none";
12
12
  * (ui/server/routes/channel/schedule-inject.ts), so `finished` can never be
13
13
  * established here. It is reached only by `promoteRoutineRuns` on the reconcile
14
14
  * tick, from evidence in the transcript.
15
+ *
16
+ * Task 2378 — `gated` is the fourth: the routine was due, its `nextRun` was
17
+ * advanced, and its precondition reported no work, so no turn was injected. It
18
+ * is a distinct outcome rather than a variety of `no-destination` because the
19
+ * two mean opposite things — `no-destination` is a routine that cannot deliver,
20
+ * `gated` is one working exactly as configured — and `auditGateAlwaysSkipping`
21
+ * counts this value to find a gate stuck on false.
15
22
  */
16
- export type RunOutcome = "accepted" | "failed" | "no-destination";
23
+ export type RunOutcome = "accepted" | "failed" | "no-destination" | "gated";
17
24
  /** Records are kept for 30 days. A quarter-hourly routine settles at ~2,900 per account. */
18
25
  export declare const RETENTION_DAYS = 30;
19
26
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"routine-run.d.ts","sourceRoot":"","sources":["../../src/lib/routine-run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routine-run.d.ts","sourceRoot":"","sources":["../../src/lib/routine-run.ts"],"names":[],"mappings":"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"}