@unson/brainbase-mcp 0.44.0 → 0.44.1

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 (72) hide show
  1. package/contracts/canonical-task/operation-schema.sql +58 -0
  2. package/contracts/canonical-task/search-indexes.sql +10 -0
  3. package/contracts/canonical-task/store-schema.sql +77 -0
  4. package/dist/automation-run.d.ts +213 -0
  5. package/dist/automation-run.js +479 -0
  6. package/dist/canonical-task-operations.d.ts +205 -0
  7. package/dist/canonical-task-operations.js +700 -0
  8. package/dist/canonical-task-postgres.d.ts +139 -0
  9. package/dist/canonical-task-postgres.js +554 -0
  10. package/dist/canonical-task-service.d.ts +13 -0
  11. package/dist/canonical-task-service.js +55 -3
  12. package/dist/canonical-task-store-config.d.ts +31 -0
  13. package/dist/canonical-task-store-config.js +53 -0
  14. package/dist/config-parser.d.ts +298 -0
  15. package/dist/config-parser.js +593 -0
  16. package/dist/connected-onboarding.d.ts +57 -0
  17. package/dist/connected-onboarding.js +37 -0
  18. package/dist/durable-wait-http.d.ts +3 -1
  19. package/dist/durable-wait-http.js +73 -6
  20. package/dist/durable-waits.d.ts +93 -3
  21. package/dist/durable-waits.js +320 -8
  22. package/dist/honcho.d.ts +25 -0
  23. package/dist/honcho.js +81 -0
  24. package/dist/judgment-event-adapter.d.ts +72 -0
  25. package/dist/judgment-event-adapter.js +114 -0
  26. package/dist/judgment-event-outbox.d.ts +182 -0
  27. package/dist/judgment-event-outbox.js +568 -0
  28. package/dist/judgment-execution-outcome.d.ts +46 -0
  29. package/dist/judgment-execution-outcome.js +149 -0
  30. package/dist/judgment-host.d.ts +18 -7
  31. package/dist/judgment-host.js +82 -34
  32. package/dist/judgment-lifecycle-core.d.ts +198 -0
  33. package/dist/judgment-lifecycle-core.js +464 -0
  34. package/dist/judgment-node-evidence.d.ts +57 -0
  35. package/dist/judgment-node-evidence.js +297 -0
  36. package/dist/judgment-runtime-resolution.d.ts +264 -0
  37. package/dist/judgment-runtime-resolution.js +1248 -0
  38. package/dist/judgment-runtime-resolution.public.d.ts +255 -0
  39. package/dist/knowledge-event.d.ts +28 -0
  40. package/dist/knowledge-event.js +114 -0
  41. package/dist/mcp-runtime.d.ts +75 -0
  42. package/dist/mcp-runtime.js +188 -0
  43. package/dist/meeting-automation-runtime.d.ts +102 -0
  44. package/dist/meeting-automation-runtime.js +249 -0
  45. package/dist/meeting-automation.d.ts +155 -0
  46. package/dist/meeting-automation.js +341 -0
  47. package/dist/meeting-minutes-context-receipt.d.ts +91 -0
  48. package/dist/meeting-minutes-context-receipt.js +280 -0
  49. package/dist/meeting-source-sync.d.ts +89 -0
  50. package/dist/meeting-source-sync.js +230 -0
  51. package/dist/mesh.d.ts +58 -0
  52. package/dist/mesh.js +134 -0
  53. package/dist/onboarding-runtime.d.ts +47 -0
  54. package/dist/onboarding-runtime.js +4719 -0
  55. package/dist/routine-cycle.d.ts +51 -0
  56. package/dist/routine-cycle.js +153 -0
  57. package/dist/routine-liveness.d.ts +49 -0
  58. package/dist/routine-liveness.js +227 -0
  59. package/dist/routine-runtime.d.ts +101 -0
  60. package/dist/routine-runtime.js +237 -0
  61. package/dist/routines.d.ts +3 -0
  62. package/dist/routines.js +3 -0
  63. package/dist/run-receipt.d.ts +40 -0
  64. package/dist/run-receipt.js +635 -0
  65. package/dist/runtime-host.d.ts +64 -0
  66. package/dist/runtime-host.js +70 -0
  67. package/dist/world-work.d.ts +16 -0
  68. package/package.json +115 -3
  69. package/ui/objective-editor.js +47 -11
  70. package/ui/world/world-district.js +18 -3
  71. package/ui/world/world-placement.js +13 -0
  72. package/ui/world/world-work-rail.js +7 -1
@@ -0,0 +1,237 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { normalizeRunReceipt } from './run-receipt.js';
4
+ import { resolveRuntimeHostContext } from './runtime-host.js';
5
+ function fail(index, field, message) {
6
+ throw new Error(`expectations[${index}].${field} ${message}`);
7
+ }
8
+ function requireString(value, index, field) {
9
+ if (typeof value !== 'string' || value.trim() === '' || value !== value.trim()) {
10
+ fail(index, field, 'must be a non-empty trimmed string');
11
+ }
12
+ return value;
13
+ }
14
+ function requireInteger(value, index, field, minimum, maximum) {
15
+ if (!Number.isInteger(value) || value < minimum || value > maximum) {
16
+ fail(index, field, `must be an integer from ${minimum} to ${maximum}`);
17
+ }
18
+ return value;
19
+ }
20
+ /**
21
+ * Parse a routine expectation document without assuming an organization,
22
+ * tenant, timezone, or scheduler. Consumers that need those constraints pass
23
+ * them explicitly, which keeps the common package portable.
24
+ */
25
+ export function parseRoutineExpectations(value, constraints = {}) {
26
+ if (!Array.isArray(value) || value.length === 0) {
27
+ throw new Error('expectations must be a non-empty array');
28
+ }
29
+ const routines = new Set();
30
+ const automationIds = new Set();
31
+ return value.map((entry, index) => {
32
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
33
+ throw new Error(`expectations[${index}] must be an object`);
34
+ }
35
+ const record = entry;
36
+ const routine = requireString(record.routine, index, 'routine');
37
+ const automationId = requireString(record.automation_id, index, 'automation_id');
38
+ if (routines.has(routine))
39
+ fail(index, 'routine', 'must be unique');
40
+ if (automationIds.has(automationId))
41
+ fail(index, 'automation_id', 'must be unique');
42
+ routines.add(routine);
43
+ automationIds.add(automationId);
44
+ const sourceType = requireString(record.source_type, index, 'source_type');
45
+ const projectId = requireString(record.project_id, index, 'project_id');
46
+ const timezone = requireString(record.timezone, index, 'timezone');
47
+ if (constraints.sourceType !== undefined && sourceType !== constraints.sourceType) {
48
+ fail(index, 'source_type', `must be ${constraints.sourceType}`);
49
+ }
50
+ if (constraints.projectId !== undefined && projectId !== constraints.projectId) {
51
+ fail(index, 'project_id', `must be ${constraints.projectId}`);
52
+ }
53
+ if (constraints.timezone !== undefined && timezone !== constraints.timezone) {
54
+ fail(index, 'timezone', `must be ${constraints.timezone}`);
55
+ }
56
+ const scheduleValue = record.schedule;
57
+ if (!scheduleValue || typeof scheduleValue !== 'object' || Array.isArray(scheduleValue)) {
58
+ fail(index, 'schedule', 'must be an object');
59
+ }
60
+ const scheduleRecord = scheduleValue;
61
+ const kind = requireString(scheduleRecord.kind, index, 'schedule.kind');
62
+ if (kind !== 'daily' && kind !== 'weekly') {
63
+ fail(index, 'schedule.kind', 'must be daily or weekly');
64
+ }
65
+ const schedule = {
66
+ kind,
67
+ hour: requireInteger(scheduleRecord.hour, index, 'schedule.hour', 0, 23),
68
+ minute: requireInteger(scheduleRecord.minute, index, 'schedule.minute', 0, 59)
69
+ };
70
+ if (kind === 'weekly') {
71
+ schedule.day_of_week = requireInteger(scheduleRecord.day_of_week, index, 'schedule.day_of_week', 0, 6);
72
+ }
73
+ const graceMinutes = requireInteger(record.grace_minutes, index, 'grace_minutes', 1, 24 * 60);
74
+ if (!Array.isArray(record.required_artifacts) || record.required_artifacts.length === 0) {
75
+ fail(index, 'required_artifacts', 'must be a non-empty array');
76
+ }
77
+ const requiredArtifacts = record.required_artifacts.map((artifact, artifactIndex) => requireString(artifact, index, `required_artifacts[${artifactIndex}]`));
78
+ if (new Set(requiredArtifacts).size !== requiredArtifacts.length) {
79
+ fail(index, 'required_artifacts', 'must not contain duplicates');
80
+ }
81
+ return {
82
+ routine,
83
+ automation_id: automationId,
84
+ source_type: sourceType,
85
+ project_id: projectId,
86
+ timezone,
87
+ schedule,
88
+ grace_minutes: graceMinutes,
89
+ required_artifacts: requiredArtifacts
90
+ };
91
+ });
92
+ }
93
+ export function loadRoutineExpectations(filePath, constraints = {}) {
94
+ return parseRoutineExpectations(JSON.parse(fs.readFileSync(filePath, 'utf8')), constraints);
95
+ }
96
+ /** Read routine dead-letter files without interpreting organization data. */
97
+ export async function listRoutineDeadLetters({ directory }) {
98
+ if (!fs.existsSync(directory))
99
+ return [];
100
+ const items = [];
101
+ for (const name of fs.readdirSync(directory).filter((entry) => entry.endsWith('.json')).sort()) {
102
+ const filePath = path.resolve(directory, name);
103
+ const receipt = JSON.parse(fs.readFileSync(filePath, 'utf8'));
104
+ const workflowId = receipt.source?.workflow_id;
105
+ const automationId = workflowId && workflowId !== '__connector_observation__'
106
+ ? workflowId
107
+ : receipt.source?.name;
108
+ if (typeof automationId !== 'string' || automationId.trim() === '')
109
+ continue;
110
+ items.push({
111
+ automation_id: automationId,
112
+ created_at: fs.statSync(filePath).mtime.toISOString(),
113
+ path: name
114
+ });
115
+ }
116
+ return items.sort((left, right) => right.created_at.localeCompare(left.created_at)
117
+ || left.automation_id.localeCompare(right.automation_id));
118
+ }
119
+ export async function countRoutineOutbox({ directory }) {
120
+ if (!fs.existsSync(directory))
121
+ return 0;
122
+ return fs.readdirSync(directory).filter((entry) => entry.endsWith('.json')).length;
123
+ }
124
+ function assertRoutineRequest(request) {
125
+ if (!request || typeof request !== 'object') {
126
+ throw new Error('routine request is required');
127
+ }
128
+ for (const [name, value] of [
129
+ ['routine', request.routine],
130
+ ['automationId', request.automationId]
131
+ ]) {
132
+ if (typeof value !== 'string' || value.trim() === '') {
133
+ throw new Error(`routine request ${name} must be a non-empty string`);
134
+ }
135
+ }
136
+ }
137
+ function assertRoutinePorts(ports) {
138
+ if (!ports.runner || typeof ports.runner !== 'object' || typeof ports.runner.start !== 'function') {
139
+ throw new Error('routine runner port with start is required');
140
+ }
141
+ if (!ports.receipt || typeof ports.receipt !== 'object'
142
+ || typeof ports.receipt.persist !== 'function'
143
+ || typeof ports.receipt.query !== 'function') {
144
+ throw new Error('routine receipt port with persist and query is required');
145
+ }
146
+ }
147
+ export class RoutineRuntimeService {
148
+ ports;
149
+ constructor(ports) {
150
+ assertRoutinePorts(ports);
151
+ this.ports = ports;
152
+ }
153
+ async start(request) {
154
+ return this.execute('routine.start', request, (context) => this.ports.runner.start({ request, context }));
155
+ }
156
+ async retry(request, previousRunId) {
157
+ assertRoutineRequest(request);
158
+ if (typeof previousRunId !== 'string' || previousRunId.trim() === '') {
159
+ throw new Error('previousRunId must be a non-empty string');
160
+ }
161
+ if (typeof this.ports.runner.retry !== 'function') {
162
+ throw new Error('routine runner retry port is required');
163
+ }
164
+ return this.execute('routine.retry', request, (context) => this.ports.runner.retry({ request, context, previousRunId }));
165
+ }
166
+ async history(request) {
167
+ assertRoutineRequest(request);
168
+ const input = {
169
+ operation: 'routine.history',
170
+ routine: request.routine,
171
+ automationId: request.automationId,
172
+ request
173
+ };
174
+ const context = await resolveRuntimeHostContext(this.ports, input);
175
+ return this.ports.receipt.query({ request, context });
176
+ }
177
+ async execute(operation, request, run) {
178
+ assertRoutineRequest(request);
179
+ const input = {
180
+ operation,
181
+ routine: request.routine,
182
+ automationId: request.automationId,
183
+ request
184
+ };
185
+ const context = await resolveRuntimeHostContext(this.ports, input);
186
+ const runnerResult = await run(context);
187
+ if (!runnerResult || typeof runnerResult !== 'object' || !('receipt' in runnerResult)) {
188
+ throw new Error(`routine runner ${operation} must return a receipt`);
189
+ }
190
+ const result = runnerResult;
191
+ const normalizedReceipt = normalizeRunReceipt(result.receipt);
192
+ const persistedReceipt = await this.ports.receipt.persist({
193
+ payload: result.receipt,
194
+ normalized: normalizedReceipt,
195
+ context
196
+ });
197
+ return {
198
+ runnerResult: result.result,
199
+ normalizedReceipt,
200
+ persistedReceipt,
201
+ context
202
+ };
203
+ }
204
+ }
205
+ export function createRoutineRuntime(ports) {
206
+ return new RoutineRuntimeService(ports);
207
+ }
208
+ const WEEKDAY_TO_NUMBER = {
209
+ Sunday: 0,
210
+ Monday: 1,
211
+ Tuesday: 2,
212
+ Wednesday: 3,
213
+ Thursday: 4,
214
+ Friday: 5,
215
+ Saturday: 6
216
+ };
217
+ /** Return whether an expectation's scheduled minute matches the supplied instant. */
218
+ export function routineScheduleMatches(expectation, instant) {
219
+ if (!(instant instanceof Date) || Number.isNaN(instant.getTime())) {
220
+ throw new Error('instant must be a valid Date');
221
+ }
222
+ const parts = new Intl.DateTimeFormat('en-US', {
223
+ timeZone: expectation.timezone,
224
+ hour12: false,
225
+ weekday: 'long',
226
+ hour: '2-digit',
227
+ minute: '2-digit'
228
+ }).formatToParts(instant);
229
+ const values = Object.fromEntries(parts.map((part) => [part.type, part.value]));
230
+ const hour = Number(values.hour);
231
+ const minute = Number(values.minute);
232
+ if (hour !== expectation.schedule.hour || minute !== expectation.schedule.minute)
233
+ return false;
234
+ if (expectation.schedule.kind === 'daily')
235
+ return true;
236
+ return WEEKDAY_TO_NUMBER[values.weekday] === expectation.schedule.day_of_week;
237
+ }
@@ -1,3 +1,6 @@
1
+ export * from './routine-runtime.js';
2
+ export * from './routine-cycle.js';
3
+ export * from './routine-liveness.js';
1
4
  export type RoutineKind = 'ohayo' | 'oyasumi' | 'retro';
2
5
  export type RoutineTarget = 'codex' | 'claude';
3
6
  export interface ScheduleOptions {
package/dist/routines.js CHANGED
@@ -1,3 +1,6 @@
1
+ export * from './routine-runtime.js';
2
+ export * from './routine-cycle.js';
3
+ export * from './routine-liveness.js';
1
4
  const ALL_KINDS = ['ohayo', 'oyasumi', 'retro'];
2
5
  const DOW_TO_RRULE = {
3
6
  MON: 'MO', TUE: 'TU', WED: 'WE', THU: 'TH', FRI: 'FR', SAT: 'SA', SUN: 'SU'
@@ -0,0 +1,40 @@
1
+ export type RunReceiptSourceType = 'mana' | 'codex_automations' | 'github_actions' | 'salestailor' | 'openryoko' | 'openclaw';
2
+ export type RunReceiptStatus = 'success' | 'failed' | 'blocked' | 'waiting_human' | 'cancelled';
3
+ export type RunReceiptEvidenceState = 'confirmed' | 'unconfirmed' | 'no_data';
4
+ export type RunReceiptObservationKind = 'source_run' | 'connector_observation';
5
+ export type RunReceiptAction = 'none' | 'check_error' | 'resolve_blocker' | 'review_run' | 'retry_run' | 'reauthorize' | 'contact_owner';
6
+ export type RunReceiptEvidenceKind = 'url' | 'artifact_ref' | 'log_ref';
7
+ export interface RunReceiptIdentity {
8
+ digest: string;
9
+ idempotency_key: string;
10
+ run_id: string;
11
+ workflow_id: string;
12
+ }
13
+ export interface RunReceiptProjection {
14
+ status: string;
15
+ closure_state: string;
16
+ action_required: string;
17
+ human_waiting: boolean;
18
+ }
19
+ export interface NormalizedRunReceipt {
20
+ contract_version: 'run_receipt.v1';
21
+ source: Record<string, unknown>;
22
+ run: Record<string, unknown>;
23
+ delivery: Record<string, unknown>;
24
+ immutable: Record<string, unknown>;
25
+ identity: RunReceiptIdentity;
26
+ payload_digest: string;
27
+ projection: RunReceiptProjection;
28
+ }
29
+ export declare class RunReceiptContractError extends Error {
30
+ readonly code: string;
31
+ readonly details: Record<string, unknown>;
32
+ constructor(code: string, message: string, details?: Record<string, unknown>);
33
+ }
34
+ export declare function createRunReceiptIdentity({ projectId, sourceType, externalRunId, sourceWorkflowId }: {
35
+ projectId: string;
36
+ sourceType: RunReceiptSourceType;
37
+ externalRunId: string;
38
+ sourceWorkflowId: string;
39
+ }): RunReceiptIdentity;
40
+ export declare function normalizeRunReceipt(payload: unknown): NormalizedRunReceipt;