@getfamiliar/shared 0.1.2

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 (83) hide show
  1. package/build/AgentRun.d.ts +187 -0
  2. package/build/AgentRun.js +1 -0
  3. package/build/AgentRunBus.d.ts +147 -0
  4. package/build/AgentRunBus.js +362 -0
  5. package/build/Calendar.d.ts +450 -0
  6. package/build/Calendar.js +37 -0
  7. package/build/ChatMessage.d.ts +53 -0
  8. package/build/ChatMessage.js +11 -0
  9. package/build/ChatMessageBus.d.ts +110 -0
  10. package/build/ChatMessageBus.js +257 -0
  11. package/build/Config.d.ts +83 -0
  12. package/build/Config.js +1 -0
  13. package/build/ContainerTool.d.ts +34 -0
  14. package/build/ContainerTool.js +1 -0
  15. package/build/CronExpression.d.ts +53 -0
  16. package/build/CronExpression.js +77 -0
  17. package/build/Event.d.ts +280 -0
  18. package/build/Event.js +14 -0
  19. package/build/EventBus.d.ts +198 -0
  20. package/build/EventBus.js +482 -0
  21. package/build/HandlerCatalog.d.ts +75 -0
  22. package/build/HandlerCatalog.js +165 -0
  23. package/build/InferenceEvent.d.ts +30 -0
  24. package/build/InferenceEvent.js +1 -0
  25. package/build/InferenceEventBus.d.ts +39 -0
  26. package/build/InferenceEventBus.js +80 -0
  27. package/build/Mail.d.ts +250 -0
  28. package/build/Mail.js +73 -0
  29. package/build/MailStyleTemplate.d.ts +71 -0
  30. package/build/MailStyleTemplate.js +47 -0
  31. package/build/ModelMetaData.d.ts +63 -0
  32. package/build/ModelMetaData.js +12 -0
  33. package/build/PathGlob.d.ts +20 -0
  34. package/build/PathGlob.js +33 -0
  35. package/build/Plugin.d.ts +709 -0
  36. package/build/Plugin.js +29 -0
  37. package/build/PostgresConnection.d.ts +75 -0
  38. package/build/PostgresConnection.js +162 -0
  39. package/build/ScheduledSubagent.d.ts +49 -0
  40. package/build/ScheduledSubagent.js +1 -0
  41. package/build/ScheduledSubagentBus.d.ts +94 -0
  42. package/build/ScheduledSubagentBus.js +187 -0
  43. package/build/Schema.d.ts +84 -0
  44. package/build/Schema.js +570 -0
  45. package/build/StepResult.d.ts +103 -0
  46. package/build/StepResult.js +1 -0
  47. package/build/StepResultBus.d.ts +64 -0
  48. package/build/StepResultBus.js +169 -0
  49. package/build/Timezone.d.ts +58 -0
  50. package/build/Timezone.js +84 -0
  51. package/build/ToolCall.d.ts +25 -0
  52. package/build/ToolCall.js +1 -0
  53. package/build/ToolCallBus.d.ts +65 -0
  54. package/build/ToolCallBus.js +110 -0
  55. package/build/ToolLevel.d.ts +20 -0
  56. package/build/ToolLevel.js +2 -0
  57. package/build/ToolRunner.d.ts +118 -0
  58. package/build/ToolRunner.js +192 -0
  59. package/build/ToolsExpressionUtils.d.ts +80 -0
  60. package/build/ToolsExpressionUtils.js +102 -0
  61. package/build/WorkspaceFile.d.ts +104 -0
  62. package/build/WorkspaceFile.js +7 -0
  63. package/build/estimateTokens.d.ts +16 -0
  64. package/build/estimateTokens.js +18 -0
  65. package/build/index.d.ts +37 -0
  66. package/build/index.js +26 -0
  67. package/build/logging/Logger.d.ts +66 -0
  68. package/build/logging/Logger.js +90 -0
  69. package/build/markdownHtml.d.ts +14 -0
  70. package/build/markdownHtml.js +21 -0
  71. package/build/markdownTerminal.d.ts +14 -0
  72. package/build/markdownTerminal.js +376 -0
  73. package/build/testing/MockAgentRunBus.d.ts +52 -0
  74. package/build/testing/MockAgentRunBus.js +175 -0
  75. package/build/testing/MockBusStore.d.ts +22 -0
  76. package/build/testing/MockBusStore.js +22 -0
  77. package/build/testing/MockEventBus.d.ts +20 -0
  78. package/build/testing/MockEventBus.js +57 -0
  79. package/build/testing/MockLogger.d.ts +52 -0
  80. package/build/testing/MockLogger.js +65 -0
  81. package/build/testing/index.d.ts +4 -0
  82. package/build/testing/index.js +4 -0
  83. package/package.json +63 -0
@@ -0,0 +1,52 @@
1
+ import type { AgentRunPatch, AgentRunRow, NewAgentRun } from "../AgentRun.js";
2
+ import type { MockBusStore } from "./MockBusStore.js";
3
+ /**
4
+ * Listener for {@link MockAgentRunBus.subscribe}. Fires synchronously
5
+ * after every state-affecting write so test code can advance the
6
+ * Scheduler in lock-step with mutations.
7
+ */
8
+ export type MockAgentRunBusListener = (row: AgentRunRow) => void;
9
+ /**
10
+ * In-memory {@link AgentRunBus} replacement for unit tests. Stores
11
+ * agentruns in a {@link MockBusStore} so it can recompute the parent
12
+ * event's terminal state when a row settles — the same coupling the
13
+ * production schema's `EVENT_TERMINAL_UPDATE_SQL` enforces.
14
+ *
15
+ * Listeners (subscribed via {@link subscribe}) fire synchronously
16
+ * after every state-affecting write, replacing postgres NOTIFY for
17
+ * test purposes.
18
+ *
19
+ * The class is intentionally not typed as `implements AgentRunBus`:
20
+ * the production class carries private postgres fields that block
21
+ * structural compat. The Scheduler (and any other consumer wanting
22
+ * test-friendliness) should accept a structural subset of the bus —
23
+ * e.g. `Pick<AgentRunBus, 'add' | 'update' | …>` — which this class
24
+ * satisfies by shape.
25
+ */
26
+ export declare class MockAgentRunBus {
27
+ private readonly store;
28
+ private readonly listeners;
29
+ constructor(store: MockBusStore);
30
+ /** No-op — kept for shape compatibility with the production bus. */
31
+ installSchema(): Promise<void>;
32
+ add(run: NewAgentRun): Promise<AgentRunRow>;
33
+ update(id: string, patch: AgentRunPatch): Promise<void>;
34
+ settle(id: string, toState: "done" | "failed", outcome?: {
35
+ readonly result?: unknown;
36
+ readonly resultText?: string | null;
37
+ readonly error?: string | null;
38
+ }): Promise<void>;
39
+ getById(id: string): Promise<AgentRunRow | undefined>;
40
+ listEligible(): Promise<readonly AgentRunRow[]>;
41
+ areAllStartedChildrenSettled(parentId: string): Promise<boolean>;
42
+ listSince(since: Date): Promise<AgentRunRow[]>;
43
+ listByEventId(eventId: string): Promise<readonly AgentRunRow[]>;
44
+ postpone(id: string, runAfter: Date, errorText: string | null): Promise<void>;
45
+ /**
46
+ * Test-only: subscribe to row-change notifications. Replaces
47
+ * postgres NOTIFY for test code. Returns an unsubscriber.
48
+ */
49
+ subscribe(listener: MockAgentRunBusListener): () => void;
50
+ private fire;
51
+ private recomputeEventTerminal;
52
+ }
@@ -0,0 +1,175 @@
1
+ /**
2
+ * In-memory {@link AgentRunBus} replacement for unit tests. Stores
3
+ * agentruns in a {@link MockBusStore} so it can recompute the parent
4
+ * event's terminal state when a row settles — the same coupling the
5
+ * production schema's `EVENT_TERMINAL_UPDATE_SQL` enforces.
6
+ *
7
+ * Listeners (subscribed via {@link subscribe}) fire synchronously
8
+ * after every state-affecting write, replacing postgres NOTIFY for
9
+ * test purposes.
10
+ *
11
+ * The class is intentionally not typed as `implements AgentRunBus`:
12
+ * the production class carries private postgres fields that block
13
+ * structural compat. The Scheduler (and any other consumer wanting
14
+ * test-friendliness) should accept a structural subset of the bus —
15
+ * e.g. `Pick<AgentRunBus, 'add' | 'update' | …>` — which this class
16
+ * satisfies by shape.
17
+ */
18
+ export class MockAgentRunBus {
19
+ store;
20
+ listeners = [];
21
+ constructor(store) {
22
+ this.store = store;
23
+ }
24
+ /** No-op — kept for shape compatibility with the production bus. */
25
+ async installSchema() {
26
+ // intentionally empty
27
+ }
28
+ async add(run) {
29
+ const id = String(this.store.nextAgentrunId++);
30
+ const now = new Date();
31
+ const row = {
32
+ id,
33
+ eventId: run.eventId,
34
+ parentAgentrunId: run.parentAgentrunId ?? null,
35
+ topic: run.topic,
36
+ handler: run.handler,
37
+ priority: run.priority ?? 50,
38
+ state: run.state ?? "pending",
39
+ prompt: run.prompt ?? null,
40
+ payload: run.payload ?? {},
41
+ result: null,
42
+ resultText: null,
43
+ error: null,
44
+ privileged: run.privileged ?? false,
45
+ calltype: (run.calltype ?? null),
46
+ retryCount: 0,
47
+ notBefore: null,
48
+ model: null,
49
+ systemPrompt: null,
50
+ initialMessages: null,
51
+ createdAt: now,
52
+ updatedAt: now,
53
+ };
54
+ this.store.agentruns.set(id, row);
55
+ this.fire(row);
56
+ return row;
57
+ }
58
+ async update(id, patch) {
59
+ const row = this.store.agentruns.get(id);
60
+ if (!row) {
61
+ throw new Error(`Agentrun ${id} not found`);
62
+ }
63
+ const next = {
64
+ ...row,
65
+ state: patch.state ?? row.state,
66
+ payload: patch.payload === undefined ? row.payload : patch.payload,
67
+ result: patch.result === undefined ? row.result : patch.result,
68
+ resultText: patch.resultText === undefined ? row.resultText : patch.resultText,
69
+ error: patch.error === undefined ? row.error : patch.error,
70
+ priority: patch.priority ?? row.priority,
71
+ model: patch.model === undefined ? row.model : patch.model,
72
+ systemPrompt: patch.systemPrompt === undefined ? row.systemPrompt : patch.systemPrompt,
73
+ initialMessages: patch.initialMessages === undefined ? row.initialMessages : patch.initialMessages,
74
+ calltype: patch.calltype === undefined ? row.calltype : patch.calltype,
75
+ updatedAt: new Date(),
76
+ };
77
+ this.store.agentruns.set(id, next);
78
+ this.fire(next);
79
+ }
80
+ async settle(id, toState, outcome = {}) {
81
+ const row = this.store.agentruns.get(id);
82
+ if (!row) {
83
+ throw new Error(`Agentrun ${id} not found`);
84
+ }
85
+ const next = {
86
+ ...row,
87
+ state: toState,
88
+ result: outcome.result === undefined ? row.result : outcome.result,
89
+ resultText: outcome.resultText === undefined ? row.resultText : outcome.resultText,
90
+ error: outcome.error === undefined ? row.error : outcome.error,
91
+ updatedAt: new Date(),
92
+ };
93
+ this.store.agentruns.set(id, next);
94
+ // Mirror EVENT_TERMINAL_UPDATE_SQL: the event's terminal state
95
+ // mirrors the root agentrun's terminal state. Settling a
96
+ // non-root agentrun is a no-op for the event.
97
+ this.recomputeEventTerminal(row, toState);
98
+ this.fire(next);
99
+ }
100
+ async getById(id) {
101
+ return this.store.agentruns.get(id);
102
+ }
103
+ async listEligible() {
104
+ const now = Date.now();
105
+ return [...this.store.agentruns.values()]
106
+ .filter((r) => r.state === "pending" && (r.notBefore === null || r.notBefore.getTime() <= now))
107
+ .sort((a, b) => b.priority - a.priority || Number(a.id) - Number(b.id));
108
+ }
109
+ async areAllStartedChildrenSettled(parentId) {
110
+ for (const row of this.store.agentruns.values()) {
111
+ if (row.parentAgentrunId === parentId &&
112
+ row.calltype === "started" &&
113
+ row.state !== "done" &&
114
+ row.state !== "failed") {
115
+ return false;
116
+ }
117
+ }
118
+ return true;
119
+ }
120
+ async listSince(since) {
121
+ return [...this.store.agentruns.values()]
122
+ .filter((r) => r.updatedAt.getTime() >= since.getTime())
123
+ .sort((a, b) => a.updatedAt.getTime() - b.updatedAt.getTime() || Number(a.id) - Number(b.id));
124
+ }
125
+ async listByEventId(eventId) {
126
+ return [...this.store.agentruns.values()]
127
+ .filter((r) => r.eventId === eventId)
128
+ .sort((a, b) => Number(a.id) - Number(b.id));
129
+ }
130
+ async postpone(id, runAfter, errorText) {
131
+ const row = this.store.agentruns.get(id);
132
+ if (!row) {
133
+ throw new Error(`Agentrun ${id} not found`);
134
+ }
135
+ const next = {
136
+ ...row,
137
+ state: "pending",
138
+ retryCount: row.retryCount + 1,
139
+ notBefore: runAfter,
140
+ error: errorText,
141
+ updatedAt: new Date(),
142
+ };
143
+ this.store.agentruns.set(id, next);
144
+ this.fire(next);
145
+ }
146
+ /**
147
+ * Test-only: subscribe to row-change notifications. Replaces
148
+ * postgres NOTIFY for test code. Returns an unsubscriber.
149
+ */
150
+ subscribe(listener) {
151
+ this.listeners.push(listener);
152
+ return () => {
153
+ const idx = this.listeners.indexOf(listener);
154
+ if (idx >= 0) {
155
+ this.listeners.splice(idx, 1);
156
+ }
157
+ };
158
+ }
159
+ fire(row) {
160
+ for (const l of this.listeners) {
161
+ l(row);
162
+ }
163
+ }
164
+ recomputeEventTerminal(settledRow, settledState) {
165
+ if (settledRow.parentAgentrunId !== null) {
166
+ return;
167
+ }
168
+ const event = this.store.events.get(settledRow.eventId);
169
+ if (!event || event.state !== "running") {
170
+ return;
171
+ }
172
+ const next = { ...event, state: settledState, updatedAt: new Date() };
173
+ this.store.events.set(settledRow.eventId, next);
174
+ }
175
+ }
@@ -0,0 +1,22 @@
1
+ import type { AgentRunRow } from "../AgentRun.js";
2
+ import type { EventRow } from "../Event.js";
3
+ /**
4
+ * Shared in-memory backing store for {@link MockAgentRunBus} and
5
+ * {@link MockEventBus}. Lets `settle()` on the agentrun bus recompute
6
+ * the parent event's terminal state — the cross-table coupling the
7
+ * production schema enforces via {@link EVENT_TERMINAL_UPDATE_SQL} —
8
+ * without separate processes or a real postgres.
9
+ *
10
+ * Construct one store per test and pass it into both bus mocks.
11
+ * `nextEventId` / `nextAgentrunId` mirror postgres's `bigserial`,
12
+ * yielding deterministic ids `"1"`, `"2"`, … in the order rows are
13
+ * inserted.
14
+ */
15
+ export declare class MockBusStore {
16
+ readonly events: Map<string, EventRow>;
17
+ readonly agentruns: Map<string, AgentRunRow>;
18
+ nextEventId: number;
19
+ nextAgentrunId: number;
20
+ /** All agentruns whose parent_agentrun_id matches `parentId`. */
21
+ childrenOf(parentId: string): AgentRunRow[];
22
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Shared in-memory backing store for {@link MockAgentRunBus} and
3
+ * {@link MockEventBus}. Lets `settle()` on the agentrun bus recompute
4
+ * the parent event's terminal state — the cross-table coupling the
5
+ * production schema enforces via {@link EVENT_TERMINAL_UPDATE_SQL} —
6
+ * without separate processes or a real postgres.
7
+ *
8
+ * Construct one store per test and pass it into both bus mocks.
9
+ * `nextEventId` / `nextAgentrunId` mirror postgres's `bigserial`,
10
+ * yielding deterministic ids `"1"`, `"2"`, … in the order rows are
11
+ * inserted.
12
+ */
13
+ export class MockBusStore {
14
+ events = new Map();
15
+ agentruns = new Map();
16
+ nextEventId = 1;
17
+ nextAgentrunId = 1;
18
+ /** All agentruns whose parent_agentrun_id matches `parentId`. */
19
+ childrenOf(parentId) {
20
+ return [...this.agentruns.values()].filter((r) => r.parentAgentrunId === parentId);
21
+ }
22
+ }
@@ -0,0 +1,20 @@
1
+ import type { EventPatch, EventRow, NewEvent } from "../Event.js";
2
+ import type { MockBusStore } from "./MockBusStore.js";
3
+ /**
4
+ * In-memory {@link EventBus} replacement for unit tests. The Scheduler
5
+ * tests need only a tiny slice of the surface — `getById`, occasional
6
+ * `update`, and an `add` helper to seed events. Anything beyond that
7
+ * is not needed yet and intentionally absent.
8
+ *
9
+ * Stored in a shared {@link MockBusStore} so `MockAgentRunBus.settle`
10
+ * can recompute the parent event's terminal state on the same data.
11
+ */
12
+ export declare class MockEventBus {
13
+ private readonly store;
14
+ constructor(store: MockBusStore);
15
+ /** No-op — kept for shape compatibility with the production bus. */
16
+ installSchema(): Promise<void>;
17
+ add(event: NewEvent): Promise<EventRow>;
18
+ getById(id: string): Promise<EventRow | undefined>;
19
+ update(id: string, patch: EventPatch): Promise<void>;
20
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * In-memory {@link EventBus} replacement for unit tests. The Scheduler
3
+ * tests need only a tiny slice of the surface — `getById`, occasional
4
+ * `update`, and an `add` helper to seed events. Anything beyond that
5
+ * is not needed yet and intentionally absent.
6
+ *
7
+ * Stored in a shared {@link MockBusStore} so `MockAgentRunBus.settle`
8
+ * can recompute the parent event's terminal state on the same data.
9
+ */
10
+ export class MockEventBus {
11
+ store;
12
+ constructor(store) {
13
+ this.store = store;
14
+ }
15
+ /** No-op — kept for shape compatibility with the production bus. */
16
+ async installSchema() {
17
+ // intentionally empty
18
+ }
19
+ async add(event) {
20
+ const id = String(this.store.nextEventId++);
21
+ const now = new Date();
22
+ const row = {
23
+ id,
24
+ topic: event.topic,
25
+ priority: event.priority ?? 50,
26
+ state: "pending",
27
+ payload: event.payload ?? {},
28
+ idempotencyKey: event.idempotencyKey ?? null,
29
+ isChat: event.isChat === true,
30
+ preferredChatChannelId: event.preferredChatChannelId ?? null,
31
+ prompt: event.prompt ?? null,
32
+ startHandler: event.startHandler ?? null,
33
+ privileged: event.privileged === true,
34
+ outputChatOnFailure: event.outputChatOnFailure === true,
35
+ createdAt: now,
36
+ updatedAt: now,
37
+ };
38
+ this.store.events.set(id, row);
39
+ return row;
40
+ }
41
+ async getById(id) {
42
+ return this.store.events.get(id);
43
+ }
44
+ async update(id, patch) {
45
+ const row = this.store.events.get(id);
46
+ if (!row) {
47
+ throw new Error(`Event ${id} not found`);
48
+ }
49
+ const next = {
50
+ ...row,
51
+ state: patch.state ?? row.state,
52
+ payload: patch.payload === undefined ? row.payload : patch.payload,
53
+ updatedAt: new Date(),
54
+ };
55
+ this.store.events.set(id, next);
56
+ }
57
+ }
@@ -0,0 +1,52 @@
1
+ import type { Logger, LogLevel } from "../logging/Logger.js";
2
+ /**
3
+ * One captured log call. `obj` is whatever the caller passed as the
4
+ * structured payload (an object or `undefined` for plain-message
5
+ * variants); `msg` is the rendered message string.
6
+ */
7
+ export interface MockLogEntry {
8
+ readonly level: LogLevel;
9
+ readonly msg: string;
10
+ readonly obj: object | undefined;
11
+ /**
12
+ * Accumulated child-logger bindings. A root logger has no bindings;
13
+ * a child via `.child({ component: 'x' })` adds `{ component: 'x' }`.
14
+ */
15
+ readonly bindings: ReadonlyArray<Record<string, unknown>>;
16
+ }
17
+ /**
18
+ * In-memory {@link Logger} that records every call into a flat
19
+ * {@link entries} array, suitable for assertions in unit tests.
20
+ *
21
+ * Children share the same backing entries array and accumulate
22
+ * bindings — so `logger.child({ a: 1 }).child({ b: 2 }).info('hi')`
23
+ * records `{ bindings: [{a:1}, {b:2}], msg: 'hi', ... }`.
24
+ *
25
+ * Lives in `shared/` because every package that depends on
26
+ * `@getfamiliar/shared` already has the `Logger` interface visible,
27
+ * and the same mock works for host- and container-side tests.
28
+ */
29
+ export declare class MockLogger implements Logger {
30
+ /** Every call observed by this logger (and its children). */
31
+ readonly entries: MockLogEntry[];
32
+ private readonly bindings;
33
+ constructor(bindings?: ReadonlyArray<Record<string, unknown>>);
34
+ debug(obj: object, msg?: string): void;
35
+ debug(msg: string): void;
36
+ info(obj: object, msg?: string): void;
37
+ info(msg: string): void;
38
+ warn(obj: object, msg?: string): void;
39
+ warn(msg: string): void;
40
+ error(obj: object, msg?: string): void;
41
+ error(msg: string): void;
42
+ child(bindings: Record<string, unknown>): Logger;
43
+ /**
44
+ * Convenience query: does an entry at `level` with a message
45
+ * matching `match` exist? `match` is either a substring or a
46
+ * RegExp.
47
+ */
48
+ hasEntry(level: LogLevel, match: string | RegExp): boolean;
49
+ /** Drop all recorded entries. Useful between assertions. */
50
+ clear(): void;
51
+ private record;
52
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * In-memory {@link Logger} that records every call into a flat
3
+ * {@link entries} array, suitable for assertions in unit tests.
4
+ *
5
+ * Children share the same backing entries array and accumulate
6
+ * bindings — so `logger.child({ a: 1 }).child({ b: 2 }).info('hi')`
7
+ * records `{ bindings: [{a:1}, {b:2}], msg: 'hi', ... }`.
8
+ *
9
+ * Lives in `shared/` because every package that depends on
10
+ * `@getfamiliar/shared` already has the `Logger` interface visible,
11
+ * and the same mock works for host- and container-side tests.
12
+ */
13
+ export class MockLogger {
14
+ /** Every call observed by this logger (and its children). */
15
+ entries = [];
16
+ bindings;
17
+ constructor(bindings = []) {
18
+ this.bindings = bindings;
19
+ }
20
+ debug(a, b) {
21
+ this.record("debug", a, b);
22
+ }
23
+ info(a, b) {
24
+ this.record("info", a, b);
25
+ }
26
+ warn(a, b) {
27
+ this.record("warn", a, b);
28
+ }
29
+ error(a, b) {
30
+ this.record("error", a, b);
31
+ }
32
+ child(bindings) {
33
+ const child = new MockLogger([...this.bindings, bindings]);
34
+ // Share the entries array so parent observations see child
35
+ // writes too — matches `pino.child` semantics from the test's
36
+ // POV.
37
+ child.entries = this.entries;
38
+ return child;
39
+ }
40
+ /**
41
+ * Convenience query: does an entry at `level` with a message
42
+ * matching `match` exist? `match` is either a substring or a
43
+ * RegExp.
44
+ */
45
+ hasEntry(level, match) {
46
+ return this.entries.some((e) => e.level === level &&
47
+ (typeof match === "string" ? e.msg.includes(match) : match.test(e.msg)));
48
+ }
49
+ /** Drop all recorded entries. Useful between assertions. */
50
+ clear() {
51
+ this.entries.length = 0;
52
+ }
53
+ record(level, a, b) {
54
+ if (typeof a === "string") {
55
+ this.entries.push({ level, msg: a, obj: undefined, bindings: this.bindings });
56
+ return;
57
+ }
58
+ this.entries.push({
59
+ level,
60
+ msg: b ?? "",
61
+ obj: a,
62
+ bindings: this.bindings,
63
+ });
64
+ }
65
+ }
@@ -0,0 +1,4 @@
1
+ export { MockAgentRunBus, type MockAgentRunBusListener } from "./MockAgentRunBus.js";
2
+ export { MockBusStore } from "./MockBusStore.js";
3
+ export { MockEventBus } from "./MockEventBus.js";
4
+ export { type MockLogEntry, MockLogger } from "./MockLogger.js";
@@ -0,0 +1,4 @@
1
+ export { MockAgentRunBus } from "./MockAgentRunBus.js";
2
+ export { MockBusStore } from "./MockBusStore.js";
3
+ export { MockEventBus } from "./MockEventBus.js";
4
+ export { MockLogger } from "./MockLogger.js";
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@getfamiliar/shared",
3
+ "type": "module",
4
+ "version": "0.1.2",
5
+ "description": "Familiar — shared types and bus-state client between host and container.",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "main": "build/index.js",
10
+ "types": "build/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./build/index.d.ts",
14
+ "default": "./build/index.js"
15
+ },
16
+ "./testing": {
17
+ "types": "./build/testing/index.d.ts",
18
+ "default": "./build/testing/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "build"
23
+ ],
24
+ "engines": {
25
+ "node": ">=24"
26
+ },
27
+ "scripts": {
28
+ "build": "tsc",
29
+ "format": "biome format --write --config-path .. src/",
30
+ "format:check": "biome format --config-path .. src/",
31
+ "lint": "biome lint --config-path .. src/",
32
+ "check": "biome check --config-path .. src/",
33
+ "test": "tsx --test 'src/**/*.test.ts'"
34
+ },
35
+ "license": "MIT",
36
+ "dependencies": {
37
+ "@modelcontextprotocol/sdk": "^1.29.0",
38
+ "chalk": "^5.4.1",
39
+ "citty": "^0.1.6",
40
+ "cli-highlight": "^2.1.11",
41
+ "cli-table3": "^0.6.5",
42
+ "croner": "^10.0.1",
43
+ "friendly-node-cron": "^1.5.0",
44
+ "luxon": "^3.7.2",
45
+ "marked": "^15.0.12",
46
+ "pg": "^8.13.1",
47
+ "pino": "^9.14.0",
48
+ "supports-hyperlinks": "^3.2.0",
49
+ "wrap-ansi": "^9.0.2"
50
+ },
51
+ "devDependencies": {
52
+ "@biomejs/biome": "^2.4.12",
53
+ "@types/luxon": "^3.7.1",
54
+ "@types/node": "^25.6.0",
55
+ "@types/pg": "^8.11.10",
56
+ "typescript": "^6.0.3"
57
+ },
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "git+https://github.com/getfamiliar/familiar.git",
61
+ "directory": "shared"
62
+ }
63
+ }