@robosystems/core 0.12.0 → 0.13.0

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.
@@ -6,6 +6,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
6
6
  import { HiTerminal } from 'react-icons/hi';
7
7
  import { useGraphContext } from '../../contexts';
8
8
  import { useStreamingQuery } from '../../hooks';
9
+ import { emitGraphWrites, readGraphWrites, } from '../../lib/graph-writes';
9
10
  import { ConsoleMarkdown } from './ConsoleMarkdown';
10
11
  import { ProgressiveText } from './ProgressiveText';
11
12
  function generateMessageId() {
@@ -53,6 +54,23 @@ function downloadText(filename, text, mime) {
53
54
  anchor.click();
54
55
  URL.revokeObjectURL(url);
55
56
  }
57
+ const WRITE_LABELS = {
58
+ 'create-taxonomy-block': 'Created taxonomy block',
59
+ 'create-information-block': 'Created block',
60
+ 'update-information-block': 'Updated block',
61
+ 'assert-metrics': 'Asserted metrics',
62
+ 'compute-metrics': 'Computed metrics',
63
+ 'compute-forecast': 'Computed forecast',
64
+ 'create-agent': 'Created counterparty',
65
+ 'update-agent': 'Updated counterparty',
66
+ remember: 'Saved memory',
67
+ };
68
+ function describeWrite(write) {
69
+ var _a, _b;
70
+ const label = (_a = WRITE_LABELS[write.operation]) !== null && _a !== void 0 ? _a : write.operation;
71
+ const subject = (_b = write.name) !== null && _b !== void 0 ? _b : write.id;
72
+ return subject ? `${label}: ${subject}` : label;
73
+ }
56
74
  function copyRowsJson(rows) {
57
75
  var _a;
58
76
  (_a = navigator.clipboard) === null || _a === void 0 ? void 0 : _a.writeText(JSON.stringify(rows, null, 2));
@@ -102,6 +120,9 @@ export function ConsoleContent({ config }) {
102
120
  (config.enableRecall
103
121
  ? ` /recall - Recall semantic memories\n`
104
122
  : '') +
123
+ (config.enableAuthor
124
+ ? ` /do - Make a change (a block, a counterparty, a memory)\n`
125
+ : '') +
105
126
  ` /mcp - Connect an MCP client (sign in — no key)\n` +
106
127
  ` /mcp key - Mint a graph-scoped API key for header-only clients\n` +
107
128
  ` /help - Show this help message\n` +
@@ -145,6 +166,7 @@ export function ConsoleContent({ config }) {
145
166
  setTerminalMessages((prev) => [...prev, message]);
146
167
  }, []);
147
168
  const addResultMessage = useCallback((content, data, cypher, opts) => {
169
+ var _a;
148
170
  const message = {
149
171
  id: generateMessageId(),
150
172
  type: 'system',
@@ -154,6 +176,7 @@ export function ConsoleContent({ config }) {
154
176
  cypher,
155
177
  markdown: opts === null || opts === void 0 ? void 0 : opts.markdown,
156
178
  footer: opts === null || opts === void 0 ? void 0 : opts.footer,
179
+ writes: ((_a = opts === null || opts === void 0 ? void 0 : opts.writes) === null || _a === void 0 ? void 0 : _a.length) ? opts.writes : undefined,
157
180
  };
158
181
  setTerminalMessages((prev) => [...prev, message]);
159
182
  }, []);
@@ -328,7 +351,9 @@ export function ConsoleContent({ config }) {
328
351
  setCurrentQueryStartTime(null);
329
352
  }
330
353
  };
331
- const executeOperatorQuery = async (userQuery) => {
354
+ // `operatorType` names an operator (`author` for /do); unset, the API
355
+ // chooses one for a question.
356
+ const executeOperatorQuery = async (userQuery, operatorType) => {
332
357
  var _a;
333
358
  if (!graphId) {
334
359
  addErrorMessage(config.noSelectionError);
@@ -342,10 +367,11 @@ export function ConsoleContent({ config }) {
342
367
  try {
343
368
  const { clients } = await import('@robosystems/client/clients');
344
369
  const history = conversationRef.current;
345
- const result = await clients.operator.executeQuery(graphId, Object.assign({ message: userQuery,
370
+ const request = Object.assign({ message: userQuery,
346
371
  // `standard` gives the operator loop six tool turns; `quick` (three)
347
372
  // was exhausted by schema + examples before the first query ran.
348
- mode: 'standard' }, (history.length > 0 ? { history } : {})), {
373
+ mode: 'standard' }, (history.length > 0 ? { history } : {}));
374
+ const options = {
349
375
  mode: 'auto',
350
376
  onProgress: (message, percentage) => {
351
377
  if (isStale())
@@ -356,7 +382,10 @@ export function ConsoleContent({ config }) {
356
382
  percentage,
357
383
  });
358
384
  },
359
- });
385
+ };
386
+ const result = operatorType
387
+ ? await clients.operator.executeOperator(graphId, operatorType, request, options)
388
+ : await clients.operator.executeQuery(graphId, request, options);
360
389
  // The user switched graphs while the operator ran: the reset already
361
390
  // cleared the console, so drop the answer rather than print it (and
362
391
  // record it as history) under the new graph.
@@ -378,6 +407,9 @@ export function ConsoleContent({ config }) {
378
407
  }
379
408
  const duration = Date.now() - startTime;
380
409
  const metadata = (result.metadata || {});
410
+ const writes = readGraphWrites(metadata);
411
+ // Pages showing this graph reload what the console just changed.
412
+ emitGraphWrites(requestGraphId, writes);
381
413
  const creditsUsed = metadata.credits_consumed;
382
414
  const resultCount = metadata.result_count;
383
415
  // Prefer the structured outputs the operator loop now returns
@@ -429,7 +461,11 @@ export function ConsoleContent({ config }) {
429
461
  // otherwise collapse under markdown). With no narrative, fall back to the
430
462
  // plain footer, matching the direct-query result style.
431
463
  if (narrative) {
432
- addResultMessage(narrative, rows, cypher, { markdown: true, footer });
464
+ addResultMessage(narrative, rows, cypher, {
465
+ markdown: true,
466
+ footer,
467
+ writes,
468
+ });
433
469
  // Record the exchange for follow-ups. Only a narrative answer is
434
470
  // worth carrying; the answer is clipped so history stays cheap.
435
471
  conversationRef.current = [
@@ -439,7 +475,7 @@ export function ConsoleContent({ config }) {
439
475
  ].slice(-6);
440
476
  }
441
477
  else {
442
- addResultMessage(footer, rows, cypher);
478
+ addResultMessage(footer, rows, cypher, { writes });
443
479
  }
444
480
  }
445
481
  catch (error) {
@@ -596,6 +632,17 @@ export function ConsoleContent({ config }) {
596
632
  }
597
633
  return;
598
634
  }
635
+ // Handle /do — the author operator, which may change the graph. Writes
636
+ // are never inferred from a question; they need this command.
637
+ if (config.enableAuthor && /^\/do(\s|$)/i.test(command)) {
638
+ const request = command.slice(3).trim();
639
+ if (!request) {
640
+ addErrorMessage('Usage: /do <change>\n\nExamples:\n /do add Notion Labs as a vendor\n /do remember that we report ARPC on subscription revenue only');
641
+ return;
642
+ }
643
+ await executeOperatorQuery(request, 'author');
644
+ return;
645
+ }
599
646
  // Handle /recall command — built-in only when the target supports
600
647
  // semantic memory (user graphs; shared repositories reject it). When
601
648
  // disabled it falls through to the unknown-command branch below.
@@ -702,7 +749,10 @@ export function ConsoleContent({ config }) {
702
749
  ? 'text-green-400'
703
750
  : message.type === 'error'
704
751
  ? 'text-red-400'
705
- : 'text-gray-300'}`, children: [message.type === 'user' && (_jsx("span", { className: "mr-2 text-green-500", children: "$" })), message.isAnimating ? (_jsx(ProgressiveText, { text: message.content, onComplete: () => handleAnimationComplete(message.id), onUpdate: scrollToBottom })) : message.markdown ? (_jsx(ConsoleMarkdown, { content: message.content })) : (message.content)] }), message.footer && (_jsx("div", { className: "mt-3 text-xs whitespace-pre-wrap text-gray-500", children: message.footer })), message.cypher && (_jsxs("div", { className: "mt-3 overflow-hidden rounded border border-gray-800 bg-gray-900/40", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-800 px-3 py-1.5", children: [_jsx("span", { className: "text-xs tracking-wider text-gray-500 uppercase", children: "Generated Cypher" }), _jsx("button", { onClick: () => { var _a; return handleCommand(`/query ${(_a = message.cypher) !== null && _a !== void 0 ? _a : ''}`); }, className: "rounded bg-cyan-600/90 px-2 py-0.5 text-xs font-medium text-white transition-colors hover:bg-cyan-600", children: "Run" })] }), _jsx("pre", { className: "overflow-x-auto px-3 py-2 font-mono text-xs whitespace-pre-wrap text-cyan-300", children: message.cypher })] })), message.data && message.data.length > 0 && (_jsxs("div", { className: "mt-3 overflow-hidden rounded border border-gray-800", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-800 bg-gray-900 px-4 py-2", children: [_jsxs("span", { className: "text-xs text-gray-500", children: [message.data.length, " row", message.data.length === 1 ? '' : 's'] }), _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { onClick: () => copyRowsJson(message.data), className: "rounded border border-gray-700 px-2 py-0.5 text-xs text-gray-300 transition-colors hover:bg-gray-800", children: "Copy JSON" }), _jsx("button", { onClick: () => downloadText('results.csv', rowsToCsv(message.data), 'text/csv'), className: "rounded border border-gray-700 px-2 py-0.5 text-xs text-gray-300 transition-colors hover:bg-gray-800", children: "Download CSV" })] })] }), _jsx("div", { className: "max-h-96 overflow-auto", children: _jsxs("table", { className: "w-full border-collapse text-xs", children: [_jsx("thead", { className: "sticky top-0", children: _jsx("tr", { className: "border-b border-gray-800 bg-gray-900", children: Object.keys(message.data[0]).map((key) => (_jsx("th", { className: "px-4 py-2 text-left font-semibold whitespace-nowrap text-cyan-400", children: key }, key))) }) }), _jsx("tbody", { children: message.data
752
+ : 'text-gray-300'}`, children: [message.type === 'user' && (_jsx("span", { className: "mr-2 text-green-500", children: "$" })), message.isAnimating ? (_jsx(ProgressiveText, { text: message.content, onComplete: () => handleAnimationComplete(message.id), onUpdate: scrollToBottom })) : message.markdown ? (_jsx(ConsoleMarkdown, { content: message.content })) : (message.content)] }), message.writes && (_jsxs("div", { className: "mt-3 rounded border border-emerald-900/60 bg-emerald-950/30 px-3 py-2", children: [_jsx("div", { className: "text-xs tracking-wider text-emerald-400 uppercase", children: "Changes made" }), _jsx("ul", { className: "mt-1 space-y-0.5 text-sm text-emerald-200", children: message.writes.map((write, idx) => {
753
+ var _a;
754
+ return (_jsxs("li", { children: ["\u2713 ", describeWrite(write)] }, `${write.operation}-${(_a = write.id) !== null && _a !== void 0 ? _a : idx}`));
755
+ }) })] })), message.footer && (_jsx("div", { className: "mt-3 text-xs whitespace-pre-wrap text-gray-500", children: message.footer })), message.cypher && (_jsxs("div", { className: "mt-3 overflow-hidden rounded border border-gray-800 bg-gray-900/40", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-800 px-3 py-1.5", children: [_jsx("span", { className: "text-xs tracking-wider text-gray-500 uppercase", children: "Generated Cypher" }), _jsx("button", { onClick: () => { var _a; return handleCommand(`/query ${(_a = message.cypher) !== null && _a !== void 0 ? _a : ''}`); }, className: "rounded bg-cyan-600/90 px-2 py-0.5 text-xs font-medium text-white transition-colors hover:bg-cyan-600", children: "Run" })] }), _jsx("pre", { className: "overflow-x-auto px-3 py-2 font-mono text-xs whitespace-pre-wrap text-cyan-300", children: message.cypher })] })), message.data && message.data.length > 0 && (_jsxs("div", { className: "mt-3 overflow-hidden rounded border border-gray-800", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-800 bg-gray-900 px-4 py-2", children: [_jsxs("span", { className: "text-xs text-gray-500", children: [message.data.length, " row", message.data.length === 1 ? '' : 's'] }), _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { onClick: () => copyRowsJson(message.data), className: "rounded border border-gray-700 px-2 py-0.5 text-xs text-gray-300 transition-colors hover:bg-gray-800", children: "Copy JSON" }), _jsx("button", { onClick: () => downloadText('results.csv', rowsToCsv(message.data), 'text/csv'), className: "rounded border border-gray-700 px-2 py-0.5 text-xs text-gray-300 transition-colors hover:bg-gray-800", children: "Download CSV" })] })] }), _jsx("div", { className: "max-h-96 overflow-auto", children: _jsxs("table", { className: "w-full border-collapse text-xs", children: [_jsx("thead", { className: "sticky top-0", children: _jsx("tr", { className: "border-b border-gray-800 bg-gray-900", children: Object.keys(message.data[0]).map((key) => (_jsx("th", { className: "px-4 py-2 text-left font-semibold whitespace-nowrap text-cyan-400", children: key }, key))) }) }), _jsx("tbody", { children: message.data
706
756
  .slice(0, MAX_TABLE_ROWS)
707
757
  .map((row, idx) => (_jsx("tr", { className: "border-b border-gray-900 hover:bg-gray-900/50", children: Object.keys(message.data[0]).map((key) => {
708
758
  const value = row[key];
@@ -404,6 +404,8 @@ export function buildGraphAwareConsoleConfig(graph, branding) {
404
404
  noSelectionError: (_c = branding.noSelectionError) !== null && _c !== void 0 ? _c : 'No graph selected. Please select a graph first.',
405
405
  // Semantic memory is per-user-graph; shared repositories reject it.
406
406
  enableRecall: !isRepository,
407
+ // Writes need a user graph; the API also checks the write role.
408
+ enableAuthor: !isRepository,
407
409
  };
408
410
  }
409
411
  /**
@@ -1,3 +1,4 @@
1
+ import type { GraphWrite } from '../../lib/graph-writes';
1
2
  export interface SampleQuery {
2
3
  name: string;
3
4
  query: string;
@@ -65,6 +66,9 @@ export interface ConsoleConfig {
65
66
  * shared repositories don't support memory, so the graph-aware builder
66
67
  * enables it only for user graphs. */
67
68
  enableRecall?: boolean;
69
+ /** Enable `/do`, which runs the write-capable author operator. The API
70
+ * gates it on the graph write role; off for shared repositories. */
71
+ enableAuthor?: boolean;
68
72
  /** Extra slash commands beyond the built-in set */
69
73
  extraCommands?: ConsoleExtraCommand[];
70
74
  }
@@ -90,4 +94,6 @@ export interface TerminalMessage {
90
94
  * breaks survive markdown rendering.
91
95
  */
92
96
  footer?: string;
97
+ /** Changes the author operator made, shown as a receipt below the answer. */
98
+ writes?: GraphWrite[];
93
99
  }
package/hooks/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { useApiError } from './use-api-error';
2
2
  export { useCrossAppLink, type CrossAppTarget, type OpenCrossAppOptions, type UseCrossAppLinkResult, } from './use-cross-app-link';
3
+ export { useGraphWrites } from './use-graph-writes';
3
4
  export { useMediaQuery } from './use-media-query';
4
5
  export { useStreamingQuery } from './use-streaming-query';
5
6
  export { useToast, type ToastMessage } from './use-toast';
package/hooks/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { useApiError } from './use-api-error';
2
2
  export { useCrossAppLink, } from './use-cross-app-link';
3
+ export { useGraphWrites } from './use-graph-writes';
3
4
  export { useMediaQuery } from './use-media-query';
4
5
  export { useStreamingQuery } from './use-streaming-query';
5
6
  export { useToast } from './use-toast';
@@ -0,0 +1,6 @@
1
+ import { type GraphWrite } from '../lib/graph-writes';
2
+ /**
3
+ * Calls `onWrites` when the console changes the graph a page is showing, so
4
+ * the page can reload what it displays. Writes to other graphs are ignored.
5
+ */
6
+ export declare function useGraphWrites(graphId: string | null | undefined, onWrites: (writes: GraphWrite[]) => void): void;
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+ import { useEffect, useRef } from 'react';
3
+ import { GRAPH_WRITES_EVENT, } from '../lib/graph-writes';
4
+ /**
5
+ * Calls `onWrites` when the console changes the graph a page is showing, so
6
+ * the page can reload what it displays. Writes to other graphs are ignored.
7
+ */
8
+ export function useGraphWrites(graphId, onWrites) {
9
+ const onWritesRef = useRef(onWrites);
10
+ onWritesRef.current = onWrites;
11
+ useEffect(() => {
12
+ if (!graphId)
13
+ return;
14
+ const handler = (event) => {
15
+ const detail = event.detail;
16
+ if ((detail === null || detail === void 0 ? void 0 : detail.graphId) === graphId)
17
+ onWritesRef.current(detail.writes);
18
+ };
19
+ window.addEventListener(GRAPH_WRITES_EVENT, handler);
20
+ return () => window.removeEventListener(GRAPH_WRITES_EVENT, handler);
21
+ }, [graphId]);
22
+ }
package/index.d.ts CHANGED
@@ -2,9 +2,9 @@ export * as AuthCore from './auth-core';
2
2
  export { clearToken, getAuthHeader, getRefreshToken, getToken, getValidToken, handleAuthResponse, hasValidToken, storeToken, } from './auth-core/token-storage';
3
3
  export { clearUserCookies, clearUserLocalStorage, clearUserSessionStorage, listUserData, performLogoutCleanup, resetUIState, } from './auth-core/cleanup';
4
4
  export { AppSwitcher, AuthGuard, AuthProvider, LoginRedirector, SignInForm, SignUpForm, useAuth, } from './auth-components';
5
- export { useApiError, useMediaQuery, useToast, useUser, useUserLimits, type ToastMessage, } from './hooks';
5
+ export { useApiError, useGraphWrites, useMediaQuery, useToast, useUser, useUserLimits, type ToastMessage, } from './hooks';
6
6
  export { createGraphContext, createGraphProvider, createUseGraphContext, EntityProvider, GraphContext, GraphProvider, OrgProvider, ServiceOfferingsProvider, SidebarProvider, useEntity, useGraphContext, useOrg, useServiceOfferings, useSidebarContext, type EntityContextValue, type EntityProviderProps, type GraphContextValue, type GraphProviderProps, type GraphState, type OrgContextState, type OrgContextValue, type OrgProviderProps, type ServiceOfferings, } from './contexts';
7
- export { clientGraphCookie, clientSidebarCookie, createMcpConnectorUrl, entityCookie, graphCookie, sidebarCookie, type EntityCookie, type GraphCookie, type McpConnectorUrl, type SidebarCookie, } from './lib';
7
+ export { clientGraphCookie, clientSidebarCookie, createMcpConnectorUrl, emitGraphWrites, entityCookie, GRAPH_WRITES_EVENT, graphCookie, readGraphWrites, sidebarCookie, type EntityCookie, type GraphCookie, type GraphWrite, type GraphWritesDetail, type McpConnectorUrl, type SidebarCookie, } from './lib';
8
8
  export { ApiError, errorStatus, extractErrorDetail, isApiError, isSessionRejection, isTransientError, toApiError, unwrapSdk, type SdkResult, } from './lib/sdk-errors';
9
9
  export { generateEntityUri, isUUID, UUID_REGEX } from './utils';
10
10
  export { clearGraphSelection, getGraphSelection, persistGraphSelection, } from './actions/graph-actions';
package/index.js CHANGED
@@ -8,7 +8,7 @@ export { clearUserCookies, clearUserLocalStorage, clearUserSessionStorage, listU
8
8
  // Export auth-components
9
9
  export { AppSwitcher, AuthGuard, AuthProvider, LoginRedirector, SignInForm, SignUpForm, useAuth, } from './auth-components';
10
10
  // Export hooks
11
- export { useApiError, useMediaQuery, useToast, useUser, useUserLimits, } from './hooks';
11
+ export { useApiError, useGraphWrites, useMediaQuery, useToast, useUser, useUserLimits, } from './hooks';
12
12
  // Export contexts
13
13
  export {
14
14
  // Graph context exports
@@ -20,7 +20,7 @@ OrgProvider,
20
20
  // Service offerings context
21
21
  ServiceOfferingsProvider, SidebarProvider, useEntity, useGraphContext, useOrg, useServiceOfferings, useSidebarContext, } from './contexts';
22
22
  // Export lib utilities
23
- export { clientGraphCookie, clientSidebarCookie, createMcpConnectorUrl, entityCookie, graphCookie, sidebarCookie, } from './lib';
23
+ export { clientGraphCookie, clientSidebarCookie, createMcpConnectorUrl, emitGraphWrites, entityCookie, GRAPH_WRITES_EVENT, graphCookie, readGraphWrites, sidebarCookie, } from './lib';
24
24
  // Export the SDK error seam (unwrap an SDK result or throw ApiError)
25
25
  export { ApiError, errorStatus, extractErrorDetail, isApiError, isSessionRejection, isTransientError, toApiError, unwrapSdk, } from './lib/sdk-errors';
26
26
  // Export utils
@@ -0,0 +1,20 @@
1
+ /**
2
+ * A write an operator made, as the API reports it in `metadata.writes`.
3
+ * `id` is null when the tool returned no object id (for example a memory).
4
+ */
5
+ export interface GraphWrite {
6
+ operation: string;
7
+ id: string | null;
8
+ name: string | null;
9
+ block_type?: string;
10
+ }
11
+ export interface GraphWritesDetail {
12
+ graphId: string;
13
+ writes: GraphWrite[];
14
+ }
15
+ /** Window event fired after the console changes a graph. */
16
+ export declare const GRAPH_WRITES_EVENT = "robosystems:graph-writes";
17
+ /** Tell any page showing `graphId` that it changed. No-op when nothing was written. */
18
+ export declare function emitGraphWrites(graphId: string, writes: GraphWrite[]): void;
19
+ /** Read `metadata.writes` defensively: anything malformed yields no writes. */
20
+ export declare function readGraphWrites(metadata: unknown): GraphWrite[];
@@ -0,0 +1,19 @@
1
+ /** Window event fired after the console changes a graph. */
2
+ export const GRAPH_WRITES_EVENT = 'robosystems:graph-writes';
3
+ /** Tell any page showing `graphId` that it changed. No-op when nothing was written. */
4
+ export function emitGraphWrites(graphId, writes) {
5
+ if (typeof window === 'undefined' || writes.length === 0)
6
+ return;
7
+ window.dispatchEvent(new CustomEvent(GRAPH_WRITES_EVENT, {
8
+ detail: { graphId, writes },
9
+ }));
10
+ }
11
+ /** Read `metadata.writes` defensively: anything malformed yields no writes. */
12
+ export function readGraphWrites(metadata) {
13
+ const writes = metadata === null || metadata === void 0 ? void 0 : metadata.writes;
14
+ if (!Array.isArray(writes))
15
+ return [];
16
+ return writes.filter((w) => typeof w === 'object' &&
17
+ w !== null &&
18
+ typeof w.operation === 'string');
19
+ }
package/lib/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { clientSidebarCookie, sidebarCookie, type SidebarCookie, } from './sidebar-cookie';
2
2
  export { clientGraphCookie, graphCookie, type GraphCookie, } from './graph-cookie';
3
3
  export { entityCookie, type EntityCookie } from './entity-cookie';
4
+ export { GRAPH_WRITES_EVENT, emitGraphWrites, readGraphWrites, type GraphWrite, type GraphWritesDetail, } from './graph-writes';
4
5
  export { createMcpConnectorUrl, type McpConnectorUrl } from './mcp-connector';
5
6
  export { ApiError, errorStatus, extractErrorDetail, isApiError, isSessionRejection, isTransientError, toApiError, unwrapSdk, type SdkResult, } from './sdk-errors';
package/lib/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { clientSidebarCookie, sidebarCookie, } from './sidebar-cookie';
2
2
  export { clientGraphCookie, graphCookie, } from './graph-cookie';
3
3
  export { entityCookie } from './entity-cookie';
4
+ export { GRAPH_WRITES_EVENT, emitGraphWrites, readGraphWrites, } from './graph-writes';
4
5
  export { createMcpConnectorUrl } from './mcp-connector';
5
6
  export { ApiError, errorStatus, extractErrorDetail, isApiError, isSessionRejection, isTransientError, toApiError, unwrapSdk, } from './sdk-errors';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robosystems/core",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Shared RoboSystems frontend core library (auth, contexts, task monitoring, UI components) for the RoboSystems Next.js apps",
5
5
  "license": "MIT",
6
6
  "private": false,