@asaidimu/utils-workspace 6.0.0 → 6.2.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.
package/index.d.ts CHANGED
@@ -42,7 +42,7 @@ declare class TransactionContext {
42
42
  * Stages a single write operation against a store.
43
43
  * Does NOT touch the store — no I/O happens until commit().
44
44
  */
45
- addOp<T extends Record<string, any>>(store: Store<T>, type: "put" | "delete" | "add", data: any): Promise<void>;
45
+ addOp<T extends Record<string, any>>(store: Store$1<T>, type: "put" | "delete" | "add", data: any): Promise<void>;
46
46
  /**
47
47
  * Commits all staged operations atomically.
48
48
  *
@@ -122,7 +122,7 @@ type BufferedOperation<T> = {
122
122
  *
123
123
  * @template T - The type of objects stored. Must include the key path property.
124
124
  */
125
- interface Store<T extends Record<string, any> = Record<string, any>> {
125
+ interface Store$1<T extends Record<string, any> = Record<string, any>> {
126
126
  /**
127
127
  * Returns the name of this store (the IDB object store / collection name).
128
128
  * Used by TransactionContext to group operations and open a correctly-scoped
@@ -883,44 +883,45 @@ interface Preference {
883
883
  /** UTC timestamp of when this preference was established or last updated. */
884
884
  timestamp: Timestamp;
885
885
  }
886
- /** Discriminated union of types that can be injected into the AI context. */
887
- type ContextContent = {
888
- /** Denotes raw, unstructured text. */
886
+ /** Supported payload for text-based context. */
887
+ type TextContextContent = {
889
888
  kind: "text";
890
- /** The text payload to inject. */
891
889
  value: string;
892
- } | {
893
- /** Denotes structured JSON data. */
890
+ };
891
+ /** Supported payload for structured JSON context. */
892
+ type JsonContextContent = {
894
893
  kind: "json";
895
- /** The JSON payload. */
896
894
  value: unknown;
897
- } | {
898
- /** Denotes a reference to a registered blob in the workspace store. */
895
+ };
896
+ /** Supported payload for blob-based context. */
897
+ type BlobContextContent = {
899
898
  kind: "blob";
900
- /** The hash linking to the full blob record. */
901
899
  sha256: SHA256;
902
- /** The mime-type of the blob. */
903
900
  mediaType: BlobMediaType;
904
- /** File size in bytes. */
905
901
  sizeBytes: number;
906
- /** Human-readable filename. */
907
902
  filename?: string;
908
- } | {
909
- /** Denotes data living at an external HTTP URI. */
903
+ };
904
+ /** Supported payload for remote URI context. */
905
+ type RemoteContextContent = {
910
906
  kind: "remote";
911
- /** The fully qualified URI to the external resource. */
912
907
  uri: URI;
913
- /** Optional hint for the expected mime-type at the remote destination. */
914
908
  mediaType?: BlobMediaType;
915
909
  };
910
+ /** Union of built-in context types. */
911
+ type DefaultContextContent = TextContextContent | JsonContextContent | BlobContextContent | RemoteContextContent;
912
+ /**
913
+ * Discriminated union of types that can be injected into the AI context.
914
+ * Extensions provide their own T which MUST include a unique 'kind' discriminator.
915
+ */
916
+ type ContextContent<T = any> = DefaultContextContent | T;
916
917
  /** A contextual item (file, snippet, or data) attached to a session or prompt. */
917
- interface Context {
918
+ interface Context<T = any> {
918
919
  /** Unique lookup key for this context entry. */
919
920
  key: string;
920
921
  /** Topics linking this context to relevant sessions or roles. */
921
922
  topics: string[];
922
923
  /** The actual payload of the context block. */
923
- content: ContextContent;
924
+ content: ContextContent<T>;
924
925
  /** UTC timestamp of when the context was added. */
925
926
  timestamp: Timestamp;
926
927
  /** Extensible key-value store for application-specific contextual metadata. */
@@ -988,6 +989,8 @@ interface PreferenceSummary {
988
989
  interface ContextSummary {
989
990
  /** The unique key for the context item. */
990
991
  key: string;
992
+ /** The kind of context (e.g. 'text', 'blob', 'task'). Used for routing. */
993
+ kind: string;
991
994
  /** Associated semantic topics. */
992
995
  topics: string[];
993
996
  /** UTC timestamp of addition. */
@@ -1097,6 +1100,15 @@ interface CreateWorkspace extends BaseCommand {
1097
1100
  project: Project;
1098
1101
  };
1099
1102
  }
1103
+ interface SyncWorkspace extends BaseCommand {
1104
+ type: "workspace:sync";
1105
+ /** If provided, updates these root properties during sync. */
1106
+ payload: {
1107
+ id?: UUID;
1108
+ settings?: Settings;
1109
+ project?: Project;
1110
+ } | undefined;
1111
+ }
1100
1112
  interface AddRole extends BaseCommand {
1101
1113
  type: "role:add";
1102
1114
  /** The complete role object to inject into the workspace. */
@@ -1378,7 +1390,7 @@ interface ToolCallCommand extends BaseCommand {
1378
1390
  payload: ToolCall;
1379
1391
  }
1380
1392
  /** Union of all possible commands that can be dispatched to the Workspace Manager. */
1381
- type Command = CreateWorkspace | AddRole | UpdateRole | DeleteRole | AddPreference | UpdatePreference | DeletePreference | CreateSession | UpdateSession | ForkSession | DeleteSession | SwitchSessionRole | AddSessionTopics | OverrideSessionPreferences | AddContext | UpdateContext | DeleteContext | UpdateTurn | AddTurn | EditTurn | BranchTurn | DeleteTurn | RegisterBlob | RetainBlob | ReleaseBlob | PurgeBlob | RecordBlobRemoteId | AddTopic | UpdateTopic | DeleteTopic | MergeTopics | ToolCallCommand;
1393
+ type Command = CreateWorkspace | SyncWorkspace | AddRole | UpdateRole | DeleteRole | AddPreference | UpdatePreference | DeletePreference | CreateSession | UpdateSession | ForkSession | DeleteSession | SwitchSessionRole | AddSessionTopics | OverrideSessionPreferences | AddContext | UpdateContext | DeleteContext | UpdateTurn | AddTurn | EditTurn | BranchTurn | DeleteTurn | RegisterBlob | RetainBlob | ReleaseBlob | PurgeBlob | RecordBlobRemoteId | AddTopic | UpdateTopic | DeleteTopic | MergeTopics | ToolCallCommand;
1382
1394
  /**
1383
1395
  * Standard reducer pattern for updating workspace state.
1384
1396
  * @template T - Custom contextual additions for the reducer parameters.
@@ -1424,6 +1436,8 @@ interface ResolvedSession {
1424
1436
  interface WorkspaceEvents {
1425
1437
  /** Emitted when the index or core settings change. */
1426
1438
  "workspace:changed": DeepPartial<Workspace>;
1439
+ /** Emitted when a full sync has completed. */
1440
+ "workspace:synced": void;
1427
1441
  /** Emitted when a blob is registered, updated, or removed. */
1428
1442
  "blobs:changed": {
1429
1443
  /** Hash of the affected blob. */
@@ -1463,6 +1477,265 @@ interface SessionSnapshot {
1463
1477
  };
1464
1478
  }
1465
1479
 
1480
+ /**
1481
+ * Registry for managing context kind definitions and their behaviors.
1482
+ */
1483
+ declare class ContextRegistry {
1484
+ private readonly store;
1485
+ constructor();
1486
+ private registerDefaults;
1487
+ /**
1488
+ * Registers a new context definition.
1489
+ * @param definition The context definition to register.
1490
+ */
1491
+ register(definition: ContextDefinition): void;
1492
+ /**
1493
+ * Retrieves a context definition by kind.
1494
+ * @param kind The context kind to retrieve.
1495
+ */
1496
+ get(kind: string): ContextDefinition | undefined;
1497
+ /**
1498
+ * Lists all registered context definitions.
1499
+ */
1500
+ list(): ContextDefinition[];
1501
+ }
1502
+
1503
+ /**
1504
+ * Optional filter passed to schema(), description(), and rules() to control
1505
+ * which block definitions are included in the output.
1506
+ *
1507
+ * Resolution order:
1508
+ * 1. `emittable` gate is always applied first — non-emittable blocks never
1509
+ * appear in schema/description/rules regardless of other filters.
1510
+ * 2. If `only` is provided, only those types are included. `exclude` is ignored.
1511
+ * 3. If `exclude` is provided (and `only` is not), those types are removed.
1512
+ */
1513
+ interface BlockFilter {
1514
+ /**
1515
+ * Whitelist of block type strings to include.
1516
+ * When present, `exclude` is ignored entirely.
1517
+ */
1518
+ only?: string[];
1519
+ /**
1520
+ * Blacklist of block type strings to remove.
1521
+ * Ignored when `only` is present.
1522
+ */
1523
+ exclude?: string[];
1524
+ }
1525
+
1526
+ declare class ContentBlockRegistry {
1527
+ private readonly store;
1528
+ constructor();
1529
+ /** Register a new block type. Throws if type already exists. */
1530
+ register(definition: ContentBlockDefinition): void;
1531
+ /** Remove a block type and its mappings. */
1532
+ unregister(type: string): void;
1533
+ /** Replace an existing block definition entirely, or upsert. */
1534
+ update(type: string, partial: Partial<ContentBlockDefinition>): void;
1535
+ /** Get a single definition by type string. */
1536
+ get(type: string): ContentBlockDefinition | undefined;
1537
+ /** Return all registered definitions. */
1538
+ list(): ContentBlockDefinition[];
1539
+ isType<T extends BaseContentBlock<any> = BaseContentBlock<any>>(block: BaseContentBlock<any>, type: string): block is T;
1540
+ guard<T extends BaseContentBlock<any> = BaseContentBlock<any>>(type: string): (block: BaseContentBlock<any>) => block is T;
1541
+ /**
1542
+ * Returns a plain JSON Schema object scoped to emittable block definitions.
1543
+ * The adapter converts this to a provider-specific format (e.g. Gemini Type enum).
1544
+ */
1545
+ schema(filter?: BlockFilter): Record<string, unknown>;
1546
+ /**
1547
+ * Returns the system-prompt section describing all emittable block types.
1548
+ * Per-block rules are rendered as bullet points beneath each block's description.
1549
+ */
1550
+ description(filter?: BlockFilter): string;
1551
+ /**
1552
+ * Returns all rules across the filtered set of emittable block definitions,
1553
+ * keyed by block type. Blocks with no rules are included with an empty array.
1554
+ *
1555
+ * The prompt assembler uses this to build a consolidated constraints section
1556
+ * or to reason about per-block policies before dispatching to the model.
1557
+ */
1558
+ rules(filter?: BlockFilter): Record<string, string[]>;
1559
+ /**
1560
+ * Replace the rules for a specific block type.
1561
+ * Convenience over update(type, { rules }) — more explicit at call sites.
1562
+ * Throws if the type is not registered.
1563
+ */
1564
+ setRules(type: string, rules: string[]): void;
1565
+ /**
1566
+ * Converts a raw JSON object from a model response into a workspace block.
1567
+ *
1568
+ * Resolution order:
1569
+ * 1. If a provider mapping exists for providerId, delegate to mapping.from(raw).
1570
+ * 2. Otherwise, naive field-copy with a fresh UUID.
1571
+ *
1572
+ * Returns null if the type is unregistered or the mapping explicitly rejects the input.
1573
+ */
1574
+ parse(raw: {
1575
+ type: string;
1576
+ [key: string]: any;
1577
+ }, providerId?: string): BaseContentBlock<any> | null;
1578
+ /**
1579
+ * Constructs a new block instance of the given type with a fresh UUID.
1580
+ * Throws if the type is not registered.
1581
+ */
1582
+ create<T extends BaseContentBlock<any> = BaseContentBlock<any>>(type: string, defaults?: Partial<T>): T;
1583
+ /**
1584
+ * Deep clones an existing block, assigning a new UUID and applying any overrides.
1585
+ */
1586
+ clone<T extends BaseContentBlock<any> = BaseContentBlock<any>>(block: T, overrides?: Partial<T>): T;
1587
+ }
1588
+
1589
+ /**
1590
+ * An additional section injected by the adapter or application layer.
1591
+ * Slots relative to a named core section anchor.
1592
+ *
1593
+ * Core section labels (fixed order):
1594
+ * 'operating-system' → 'persona' → 'preferences' → 'context' → 'instructions'
1595
+ *
1596
+ * Anchor format:
1597
+ * 'before:<label>' — inserted immediately before the named core section
1598
+ * 'after:<label>' — inserted immediately after the named core section
1599
+ * 'prepend' — inserted before all core sections
1600
+ * 'append' — inserted after all core sections (default when omitted)
1601
+ */
1602
+ interface AssemblerExtension extends PromptSection {
1603
+ /**
1604
+ * Where to slot this section relative to the core sections.
1605
+ * Defaults to 'append' when omitted.
1606
+ *
1607
+ * @example 'after:instructions' // place registry description after instructions
1608
+ * @example 'before:context' // place tool list before context
1609
+ * @example 'prepend' // place before everything
1610
+ * @example 'append' // place after everything (default)
1611
+ */
1612
+ position?: `before:${string}` | `after:${string}` | "prepend" | "append";
1613
+ }
1614
+ /**
1615
+ * Provider-agnostic system prompt assembler.
1616
+ *
1617
+ * Builds an ordered array of labelled sections from a Prompt plus any
1618
+ * adapter-injected extensions. The adapter calls join() to produce the
1619
+ * final string it wraps in its provider envelope.
1620
+ *
1621
+ * Responsibilities:
1622
+ * - Render core sections from Prompt fields in canonical order.
1623
+ * - Slot extensions at their declared anchor positions.
1624
+ * - Produce a consistent, inspectable section array.
1625
+ * - Join sections into a single string on demand.
1626
+ *
1627
+ * Not responsible for:
1628
+ * - Provider-specific wrapping (Content, system message, etc.).
1629
+ * - Block architecture text — the adapter injects that as an extension.
1630
+ * - Truncation — that is the adapter's concern.
1631
+ */
1632
+ interface SystemPromptAssembler {
1633
+ /**
1634
+ * Builds the ordered array of prompt sections.
1635
+ *
1636
+ * Core sections are always rendered in this order:
1637
+ * 1. operating-system — static workspace operating constraints
1638
+ * 2. persona — role.persona string
1639
+ * 3. preferences — active user preferences
1640
+ * 4. context — injected context entries
1641
+ * 5. instructions — global or session-level instructions (if present)
1642
+ *
1643
+ * Extensions are slotted relative to their declared `position` anchor.
1644
+ * Multiple extensions targeting the same anchor are inserted in the order
1645
+ * they appear in the extensions array.
1646
+ *
1647
+ * Core sections with no content (e.g. empty preferences, absent instructions)
1648
+ * are omitted from the output entirely.
1649
+ *
1650
+ * @param prompt - The fully built Prompt from PromptBuilder.
1651
+ * @param extensions - Additional sections injected by the adapter or app layer.
1652
+ */
1653
+ build(prompt: Prompt, extensions?: AssemblerExtension[]): PromptSection[];
1654
+ /**
1655
+ * Joins an array of PromptSections into a single string suitable for
1656
+ * passing to the model. Uses a consistent separator that works across providers.
1657
+ *
1658
+ * @param sections - The output of build().
1659
+ */
1660
+ join(sections: PromptSection[]): string;
1661
+ }
1662
+ /**
1663
+ * A registered content block — self-contained and provider-agnostic.
1664
+ */
1665
+ interface ContentBlockDefinition {
1666
+ /** Discriminator used in the "type" field of the block. */
1667
+ type: string;
1668
+ /** JSON Schema fragment for this block's shape (used in responseSchema). */
1669
+ schema: Record<string, unknown>;
1670
+ /** Human/LLM-readable description of the block, injected into the system prompt. */
1671
+ description: string;
1672
+ /**
1673
+ * Whether the model can produce this block type via structured JSON output.
1674
+ *
1675
+ * - `true` → included in schema(), description(), and rules()
1676
+ * - `false` → workspace-internal only; invisible to the model
1677
+ */
1678
+ emittable: boolean;
1679
+ /**
1680
+ * Ordered list of behavioural rules for this block type.
1681
+ * Rendered as bullet points beneath the block's description in the system prompt,
1682
+ * and also available separately via registry.rules().
1683
+ *
1684
+ * Examples:
1685
+ * - 'Never emit more than one summary block per turn.'
1686
+ * - 'Only emit when explicitly instructed by the system.'
1687
+ */
1688
+ rules: string[];
1689
+ /**
1690
+ * Provider-specific mapping functions, keyed by provider ID (e.g. "google", "openai").
1691
+ * Each entry tells the adapter how to serialise/deserialise this block.
1692
+ */
1693
+ mappings?: Record<string, {
1694
+ /**
1695
+ * Convert a workspace block into a provider-specific part.
1696
+ * The return type is `unknown` — the adapter casts it internally.
1697
+ */
1698
+ to(block: BaseContentBlock<string>): unknown;
1699
+ /**
1700
+ * Convert a provider-extracted raw JSON object into a workspace block.
1701
+ * Return `null` if parsing fails.
1702
+ */
1703
+ from(raw: any): BaseContentBlock<any> | null;
1704
+ }>;
1705
+ }
1706
+ /**
1707
+ * Application-layer services injected into every LLMAdapter.
1708
+ * All services operate on workspace domain types only — no provider SDKs.
1709
+ */
1710
+ interface WorkspaceServices {
1711
+ /**
1712
+ * Assembles the system prompt from a Prompt and adapter-injected extensions.
1713
+ * The adapter calls assembler.build() to get the inspectable section array,
1714
+ * then assembler.join() to get the string it wraps in its provider envelope.
1715
+ */
1716
+ assembler: SystemPromptAssembler;
1717
+ /**
1718
+ * Scans an assistant turn for actionable blocks and emits workspace commands.
1719
+ */
1720
+ processor: TurnProcessor;
1721
+ /**
1722
+ * Resolves BlobRefs to inline data or remote file mappings.
1723
+ */
1724
+ blobResolver: BlobResolver;
1725
+ /**
1726
+ * Self-describing catalogue of all known content block types.
1727
+ */
1728
+ blockRegistry: ContentBlockRegistry;
1729
+ /**
1730
+ * Registry for managing custom context kinds.
1731
+ */
1732
+ contextRegistry: ContextRegistry;
1733
+ /**
1734
+ * Model registry
1735
+ */
1736
+ models: ModelRegistry;
1737
+ }
1738
+
1466
1739
  /**
1467
1740
  * Output of PromptBuilder.build(). Input to LLMAdapter.resolve().
1468
1741
  *
@@ -1489,6 +1762,8 @@ interface Prompt {
1489
1762
  /** Ranked context entries (text and json kinds only). Blob context is
1490
1763
  * represented as referential blocks in the transcript instead. */
1491
1764
  context: Context[];
1765
+ /** Additional sections injected by the adapter or application layer. */
1766
+ extensions?: AssemblerExtension[];
1492
1767
  };
1493
1768
  /** Active conversation chain, oldest to newest. May include synthetic turns.
1494
1769
  * Image and document blocks carry a BlobRef only; the adapter resolves them. */
@@ -1549,7 +1824,7 @@ interface AdapterStatus {
1549
1824
  };
1550
1825
  /** Pricing tiers for this model. */
1551
1826
  pricing: Array<{
1552
- unit: 'token' | 'call' | "image";
1827
+ unit: "token" | "call" | "image";
1553
1828
  /** Exponent: price is per 10^scale units. */
1554
1829
  scale: number;
1555
1830
  /** Price per unit in USD. */
@@ -1570,7 +1845,7 @@ interface AdapterStatus {
1570
1845
  timeout?: number;
1571
1846
  /** The hard limits enforced by the provider. */
1572
1847
  capacity: Array<{
1573
- unit: 'token' | 'call' | string;
1848
+ unit: "token" | "call" | string;
1574
1849
  /** Maximum units allowed per period. */
1575
1850
  max: number;
1576
1851
  /** Period length in seconds. */
@@ -1631,7 +1906,7 @@ interface PreparedPrompt {
1631
1906
  /** Total input tokens — estimated or exact. */
1632
1907
  total: number;
1633
1908
  /** Whether total is an estimate or exact (provider-supplied). */
1634
- source: 'estimated' | 'exact';
1909
+ source: "estimated" | "exact";
1635
1910
  /** Maximum output tokens configured for this request. */
1636
1911
  output?: number;
1637
1912
  /** Tokens remaining in the context window after this prompt. */
@@ -1750,22 +2025,86 @@ declare class BlobStore {
1750
2025
  resolveMany(refs: BlobRef[], adapter?: string): Promise<Result<Map<SHA256, ResolvedBlob>, WorkspaceError>>;
1751
2026
  }
1752
2027
 
1753
- declare class ContextStore {
2028
+ interface WorkspaceDatabase {
2029
+ /**
2030
+ * Open the database. Registers core schemas followed by any extension
2031
+ * schemas supplied by the caller (domain plugins).
2032
+ *
2033
+ * Idempotent — safe to call multiple times; subsequent calls are no-ops
2034
+ * if the database is already open.
2035
+ */
2036
+ open(extensionSchemas?: SchemaDefinition[]): Promise<void>;
2037
+ /**
2038
+ * Access a collection by schema name.
2039
+ * Throws if the schema has not been registered.
2040
+ */
2041
+ collection<T>(schemaName: string): Promise<Collection<T>>;
2042
+ /**
2043
+ * Close the database connection.
2044
+ */
2045
+ close(): void;
2046
+ /** get the underlying database connection. */
2047
+ database(): Database;
2048
+ }
2049
+ /**
2050
+ * Standard interface for all workspace entity stores.
2051
+ * @template T - The full entity type.
2052
+ * @template S - The summary type used for indexing.
2053
+ * @template K - The primary key type.
2054
+ */
2055
+ interface Store<T, S = T, K = string> {
2056
+ get(key: K): Promise<T | null>;
2057
+ add(entity: T): Promise<void>;
2058
+ update(key: K, updates: Partial<T>): Promise<T | null>;
2059
+ delete(key: K): Promise<boolean>;
2060
+ list(): Promise<T[]>;
2061
+ /**
2062
+ * Distills a full entity into a lightweight summary for the index.
2063
+ */
2064
+ summarize(entity: T): S;
2065
+ }
2066
+ declare function createWorkspaceDatabase(db: Database): WorkspaceDatabase;
2067
+ /**
2068
+ * Collection name constants
2069
+ * Defines the names of the collections used in the Workspace database.
2070
+ * Use these instead of raw strings throughout the codebase so a typo is a
2071
+ * compile-time error rather than a silent runtime miss.
2072
+ */
2073
+ declare const COLLECTIONS: {
2074
+ readonly WORKSPACE: "workspace";
2075
+ readonly ROLE: "role";
2076
+ readonly PREFERENCE: "preference";
2077
+ readonly CONTEXT: "context";
2078
+ readonly SESSION: "session";
2079
+ readonly TURN: "turn";
2080
+ readonly BLOB: "blob";
2081
+ readonly TOPIC: "topic";
2082
+ };
2083
+ type Collections = (typeof COLLECTIONS)[keyof typeof COLLECTIONS];
2084
+
2085
+ declare class ContextStore implements Store<Context, ContextSummary, string> {
1754
2086
  private readonly collection;
1755
2087
  private readonly cache;
1756
- constructor(collection: Collection<Context>, cache: LRUCache<string, Context>);
1757
- get(key: string): Promise<Context | null>;
2088
+ private readonly registry?;
2089
+ private readonly delegates;
2090
+ constructor(collection: Collection<Context>, cache: LRUCache<string, Context>, registry?: ContextRegistry | undefined);
2091
+ /**
2092
+ * Registers a specialized store for a specific context kind.
2093
+ */
2094
+ registerDelegate(kind: string, store: Store<Context, ContextSummary, string>): void;
2095
+ get(key: string, kind?: string): Promise<Context | null>;
1758
2096
  add(context: Context): Promise<void>;
1759
2097
  list(): Promise<Context[]>;
1760
- update(key: string, updates: Partial<Context>): Promise<Context | null>;
1761
- delete(key: string): Promise<boolean>;
2098
+ update(key: string, updates: Partial<Context>, kind?: string): Promise<Context | null>;
2099
+ delete(key: string, kind?: string): Promise<boolean>;
1762
2100
  /**
1763
2101
  * Retrieves all context items referenced by the given topics using the in-memory index.
1764
2102
  */
1765
2103
  getByTopics(index: Index, topics: string[]): Promise<Context[]>;
2104
+ summarize(context: Context): ContextSummary;
1766
2105
  }
1767
2106
 
1768
- declare class PreferenceStore {
2107
+ declare class PreferenceStore implements Store<Preference, PreferenceSummary, UUID> {
1769
2108
  private readonly collection;
1770
2109
  private readonly cache;
1771
2110
  constructor(collection: Collection<Preference>, cache: LRUCache<UUID, Preference>);
@@ -1775,13 +2114,14 @@ declare class PreferenceStore {
1775
2114
  delete(id: UUID): Promise<boolean>;
1776
2115
  load(ids: UUID[]): Promise<Preference[]>;
1777
2116
  list(): Promise<Preference[]>;
2117
+ summarize(preference: Preference): PreferenceSummary;
1778
2118
  }
1779
2119
 
1780
2120
  /**
1781
2121
  * Atomic store for Role entities.
1782
2122
  * Receives a pre-resolved Collection and manages its own LRU cache.
1783
2123
  */
1784
- declare class RoleStore {
2124
+ declare class RoleStore implements Store<Role, RoleSummary> {
1785
2125
  private readonly collection;
1786
2126
  private readonly cache;
1787
2127
  constructor(collection: Collection<Role>, cache: LRUCache<string, Role>);
@@ -1805,9 +2145,13 @@ declare class RoleStore {
1805
2145
  * Lists all roles.
1806
2146
  */
1807
2147
  list(): Promise<Role[]>;
2148
+ /**
2149
+ * Distills a full role into a lightweight summary for the index.
2150
+ */
2151
+ summarize(role: Role): RoleSummary;
1808
2152
  }
1809
2153
 
1810
- declare class SessionStore {
2154
+ declare class SessionStore implements Store<SessionMetadata, SessionMetadata, UUID> {
1811
2155
  private readonly collection;
1812
2156
  private readonly cache;
1813
2157
  constructor(collection: Collection<SessionMetadata>, cache: LRUCache<UUID, SessionMetadata>);
@@ -1815,9 +2159,14 @@ declare class SessionStore {
1815
2159
  add(session: SessionMetadata): Promise<void>;
1816
2160
  update(id: UUID, updates: Partial<SessionMetadata>): Promise<SessionMetadata | null>;
1817
2161
  delete(id: UUID): Promise<boolean>;
2162
+ /**
2163
+ * Lists all sessions.
2164
+ */
2165
+ list(): Promise<SessionMetadata[]>;
2166
+ summarize(session: SessionMetadata): SessionMetadata;
1818
2167
  }
1819
2168
 
1820
- declare class TopicStore {
2169
+ declare class TopicStore implements Store<Topic, TopicIndex, string> {
1821
2170
  private readonly collection;
1822
2171
  private readonly cache;
1823
2172
  constructor(collection: Collection<Topic>, cache: LRUCache<string, Topic>);
@@ -1826,10 +2175,12 @@ declare class TopicStore {
1826
2175
  update(name: string, updates: Partial<Topic>): Promise<Topic | null>;
1827
2176
  delete(name: string): Promise<boolean>;
1828
2177
  getMany(names: string[]): Promise<Topic[]>;
2178
+ list(): Promise<Topic[]>;
1829
2179
  /**
1830
2180
  * Checks if a topic is referenced by any entity in the workspace index.
1831
2181
  */
1832
2182
  referencedBy(name: string, index: Index): boolean;
2183
+ summarize(topic: Topic): TopicIndex;
1833
2184
  }
1834
2185
 
1835
2186
  declare class TurnStore {
@@ -1849,50 +2200,86 @@ declare class TurnStore {
1849
2200
  delete(key: TurnKey): Promise<boolean>;
1850
2201
  }
1851
2202
 
1852
- interface WorkspaceDatabase {
2203
+ interface WorkspaceMetadata {
2204
+ id: UUID;
2205
+ settings: Settings;
2206
+ project: Project;
2207
+ }
2208
+ declare class WorkspaceStore implements Store<WorkspaceMetadata, WorkspaceMetadata> {
2209
+ private readonly collection;
2210
+ private readonly cache;
2211
+ constructor(collection: Collection<WorkspaceMetadata>, cache: LRUCache<UUID, WorkspaceMetadata>);
2212
+ get(id: UUID): Promise<WorkspaceMetadata | null>;
2213
+ add(meta: WorkspaceMetadata): Promise<void>;
2214
+ update(id: UUID, updates: Partial<WorkspaceMetadata>): Promise<WorkspaceMetadata | null>;
2215
+ delete(id: UUID): Promise<boolean>;
2216
+ list(): Promise<WorkspaceMetadata[]>;
2217
+ summarize(meta: WorkspaceMetadata): WorkspaceMetadata;
2218
+ }
2219
+
2220
+ /**
2221
+ * A function that rebuilds a portion of the workspace index from persistent storage.
2222
+ */
2223
+ type Indexer = (ctx: WorkspaceContext) => Promise<DeepPartial<Workspace>>;
2224
+ /**
2225
+ * Definition of a specific kind of context and how the system interacts with it.
2226
+ */
2227
+ interface ContextDefinition<T = any> {
2228
+ /** Unique discriminator for this context kind (e.g., 'text', 'blob', 'task'). */
2229
+ kind: string;
1853
2230
  /**
1854
- * Open the database. Registers core schemas followed by any extension
1855
- * schemas supplied by the caller (domain plugins).
1856
- *
1857
- * Idempotent — safe to call multiple times; subsequent calls are no-ops
1858
- * if the database is already open.
2231
+ * Where this context prefers to live in the prompt.
2232
+ * 'system' -> Rendered into the system instructions.
2233
+ * 'transcript' -> Rendered as a synthetic turn prefixing the transcript.
1859
2234
  */
1860
- open(extensionSchemas?: SchemaDefinition[]): Promise<void>;
2235
+ target: "system" | "transcript";
1861
2236
  /**
1862
- * Access a collection by schema name.
1863
- * Throws if the schema has not been registered.
2237
+ * Transforms the context item into one or more content blocks.
2238
+ * If these blocks contain BlobRefs, the PromptBuilder will automatically
2239
+ * catalogue them for the adapter.
1864
2240
  */
1865
- collection<T>(schemaName: string): Promise<Collection<T>>;
2241
+ render(context: Context<T>): ContentBlock | ContentBlock[];
1866
2242
  /**
1867
- * Close the database connection.
2243
+ * Returns a plain text representation for the RAG/retriever system.
1868
2244
  */
1869
- close(): void;
1870
- /** get the underlying database connection. */
1871
- database(): Database;
2245
+ toString(context: Context<T>): string;
2246
+ /**
2247
+ * Produces a condensed summary for the workspace index projection.
2248
+ */
2249
+ summarize(context: Context<T>): ContextSummary;
2250
+ /**
2251
+ * Optional factory for a custom store for this context kind.
2252
+ * If omitted, the default 'context' collection is used.
2253
+ */
2254
+ store?: (ctx: WorkspaceContext) => Store<Context<T>, ContextSummary, string>;
1872
2255
  }
1873
- declare function createWorkspaceDatabase(db: Database): WorkspaceDatabase;
1874
2256
  /**
1875
- * Collection name constants
1876
- * Defines the names of the collections used in the Workspace database.
1877
- * Use these instead of raw strings throughout the codebase so a typo is a
1878
- * compile-time error rather than a silent runtime miss.
2257
+ * A bundle of domain-specific logic that can be plugged into the workspace.
2258
+ * Allows app builders to group related schemas, reducers, stores, and blocks.
1879
2259
  */
1880
- declare const COLLECTIONS: {
1881
- readonly ROLE: "role";
1882
- readonly PREFERENCE: "preference";
1883
- readonly CONTEXT: "context";
1884
- readonly SESSION: "session";
1885
- readonly TURN: "turn";
1886
- readonly BLOB: "blob";
1887
- readonly TOPIC: "topic";
1888
- };
1889
- type Collections = typeof COLLECTIONS[keyof typeof COLLECTIONS];
1890
-
2260
+ interface WorkspaceExtension {
2261
+ /** Schema definitions for new database collections. */
2262
+ schemas?: SchemaDefinition[];
2263
+ /** Reducers for handling custom commands. */
2264
+ reducers?: Record<string, WorkspaceReducer<any>>;
2265
+ /** Middleware for intercepting or observing workspace changes. */
2266
+ middleware?: WorkspaceMiddleware[];
2267
+ /** Indexers for rebuilding custom portions of the workspace index. */
2268
+ indexers?: Indexer[];
2269
+ /** Factory for custom entity stores. */
2270
+ stores?: (ctx: Omit<WorkspaceContext, "workspace">) => Record<string, Store<any>> | Promise<Record<string, Store<any>>>;
2271
+ /** Content block definitions for the LLM adapter. */
2272
+ blocks?: ContentBlockDefinition[];
2273
+ /** Custom context kind definitions. */
2274
+ contexts?: ContextDefinition[];
2275
+ }
1891
2276
  /**
1892
2277
  * The full set of stores passed to every reducer and middleware call.
1893
2278
  * Applications extend this with their own stores (e.g., `interface AppContext extends WorkspaceContext`).
1894
2279
  */
1895
2280
  type WorkspaceContext<ProjectMetadata extends Record<string, any> = Record<string, any>, IndexExtentions extends Record<string, Record<string, any>> = Record<string, Record<string, any>>, StoreExtensions = any> = {
2281
+ /** Store for managing workspace metadata (settings, project). */
2282
+ workspaceStore: WorkspaceStore;
1896
2283
  /** Store for managing system personas and roles. */
1897
2284
  roles: RoleStore;
1898
2285
  /** Store for managing global and session-level user preferences. */
@@ -1913,6 +2300,8 @@ type WorkspaceContext<ProjectMetadata extends Record<string, any> = Record<strin
1913
2300
  workspace: Workspace<ProjectMetadata, IndexExtentions>;
1914
2301
  /** The underlying database used by the workspace */
1915
2302
  db: WorkspaceDatabase;
2303
+ /** Registry of functions to rebuild the workspace index. */
2304
+ indexers: Indexer[];
1916
2305
  } & StoreExtensions;
1917
2306
  /**
1918
2307
  * Ranks and filters context entries by relevance to the current conversation.
@@ -2171,8 +2560,18 @@ declare class Session {
2171
2560
  private _role;
2172
2561
  private _preferences;
2173
2562
  private tree;
2563
+ private unsubscribe?;
2174
2564
  private constructor();
2175
2565
  static create(sessionId: UUID, manager: WorkspaceManager, processor: TurnProcessor): Promise<Session>;
2566
+ /**
2567
+ * Synchronizes the session's in-memory state with the persistent stores.
2568
+ * Useful after a workspace-wide sync or if state becomes stale.
2569
+ */
2570
+ sync(): Promise<void>;
2571
+ /**
2572
+ * Closes the session and cleans up subscriptions.
2573
+ */
2574
+ close(): void;
2176
2575
  private _setRole;
2177
2576
  private _setPreference;
2178
2577
  id(): UUID;
@@ -2300,9 +2699,9 @@ declare function computeSHA256(data: Uint8Array): Promise<SHA256>;
2300
2699
  */
2301
2700
  declare function bufferToBase64(buffer: Uint8Array): string;
2302
2701
  /**
2303
- * Short, deterministic hash of a string (4 chars in base36).
2304
- * Suitable for AI-friendly reference tokens.
2305
- */
2702
+ * Short, deterministic hash of a string (4 chars in base36).
2703
+ * Suitable for AI-friendly reference tokens.
2704
+ */
2306
2705
  declare function shortHash(s: string, length?: number): string;
2307
2706
  declare function getExtension<K extends string, V>(index: Index, key: K): Record<string, V>;
2308
2707
 
@@ -2315,9 +2714,17 @@ interface CreateWorkspaceParams {
2315
2714
  processor: TurnProcessor;
2316
2715
  guard?: PermissionGuard;
2317
2716
  toolRegistry?: ToolRegistry;
2717
+ models?: ModelProfile[];
2718
+ extensions?: WorkspaceExtension[];
2719
+ /** @deprecated use extensions instead */
2318
2720
  extensionSchemas?: SchemaDefinition[];
2721
+ /** @deprecated use extensions instead */
2319
2722
  extensionReducers?: Record<string, WorkspaceReducer<any>>;
2723
+ /** @deprecated use extensions instead */
2320
2724
  extensionMiddleware?: WorkspaceMiddleware[];
2725
+ /** @deprecated use extensions instead */
2726
+ extensionIndexers?: Indexer[];
2727
+ /** @deprecated use extensions instead */
2321
2728
  extensionStores?: (ctx: Omit<WorkspaceContext, "workspace">) => Record<string, any>;
2322
2729
  }
2323
2730
  /**
@@ -2328,6 +2735,7 @@ declare function createWorkspace(params: CreateWorkspaceParams): Promise<{
2328
2735
  manager: WorkspaceManager;
2329
2736
  sessions: SessionManager;
2330
2737
  ctx: Omit<any, "workspace">;
2738
+ services: WorkspaceServices;
2331
2739
  }>;
2332
2740
 
2333
- export { type AddContext, type AddPreference, type AddRole, type AddSessionTopics, type AddTopic, type AddTurn, type AuthRequest, type BackendError, type BaseCommand, type BaseContentBlock, type BlobCommand, type BlobError, type BlobMediaType, type BlobRecord, type BlobRef, type BlobResolver, type BranchInfo, type BranchTurn, COLLECTIONS, type Collections, type Command, type ContentBlock, type Context, type ContextContent, type ContextRetriever, type ContextSummary, type CreateSession, type CreateWorkspace, type CreateWorkspaceParams, type DeepPartial, type DeleteContext, type DeletePreference, type DeleteRole, type DeleteSession, type DeleteTopic, type DeleteTurn, type DocumentBlock, type DocumentMediaType, type DuplicateKeyError, EMPTY_SYSTEM_ROLE, type EditTurn, type ForkSession, type ImageBlock, type ImageMediaType, type Index, type IndexExtensions, type InvalidCommandError, type LLMAdapter, type LLMAdapterStatic, LRUCache, type MergeTopics, type ModelConstraint, type ModelConstraintMap, type ModelName, type ModelProfile, type ModelRegistry, type NotFoundError, type OverrideSessionPreferences, type PermissionDeniedError, type PermissionGuard, type Preference, type PreferenceSummary, type Project, type PromptBuilder, type PromptBuilderOptions, type PurgeBlob, type RecordBlobRemoteId, type RegisterBlob, type ReleaseBlob, type ResolvedBlob, type ResolvedSession, type Result, type RetainBlob, type Role, type RoleSummary, type RoleTransitionBlock, type SHA256, Session, SessionManager, type SessionMetadata, type SessionSnapshot, type Settings, type Summarizer, type SummaryBlock, type SwitchSessionRole, type SystemActor, type TextBlock, type ThinkingBlock, type Timestamp, type ToolCall, type ToolCallCommand, type ToolRegistry, type ToolResultBlock, type ToolSummary, type ToolUseBlock, type Topic, type TopicIndex, type Turn, TurnBuilder, type TurnKey, type TurnNode, type TurnProcessor, type TurnRef, TurnTree, type URI, type UUID, type UpdateContext, type UpdatePreference, type UpdateRole, type UpdateSession, type UpdateTopic, type UpdateTurn, type Workspace, type WorkspaceBundle, type WorkspaceContext, type WorkspaceDatabase, type WorkspaceError, type WorkspaceEvents, WorkspaceManager, type WorkspaceMiddleware, type WorkspaceReducer, bufferToBase64, computeSHA256, createWorkspace, createWorkspaceDatabase, del, error, getExtension, merge, ok, omitNullUndefined, shortHash, success };
2741
+ export { type AddContext, type AddPreference, type AddRole, type AddSessionTopics, type AddTopic, type AddTurn, type AuthRequest, type BackendError, type BaseCommand, type BaseContentBlock, type BlobCommand, type BlobContextContent, type BlobError, type BlobMediaType, type BlobRecord, type BlobRef, type BlobResolver, type BranchInfo, type BranchTurn, COLLECTIONS, type Collections, type Command, type ContentBlock, type Context, type ContextContent, type ContextDefinition, type ContextRetriever, type ContextSummary, type CreateSession, type CreateWorkspace, type CreateWorkspaceParams, type DeepPartial, type DefaultContextContent, type DeleteContext, type DeletePreference, type DeleteRole, type DeleteSession, type DeleteTopic, type DeleteTurn, type DocumentBlock, type DocumentMediaType, type DuplicateKeyError, EMPTY_SYSTEM_ROLE, type EditTurn, type ForkSession, type ImageBlock, type ImageMediaType, type Index, type IndexExtensions, type Indexer, type InvalidCommandError, type JsonContextContent, type LLMAdapter, type LLMAdapterStatic, LRUCache, type MergeTopics, type ModelConstraint, type ModelConstraintMap, type ModelName, type ModelProfile, type ModelRegistry, type NotFoundError, type OverrideSessionPreferences, type PermissionDeniedError, type PermissionGuard, type Preference, type PreferenceSummary, type Project, type PromptBuilder, type PromptBuilderOptions, type PurgeBlob, type RecordBlobRemoteId, type RegisterBlob, type ReleaseBlob, type RemoteContextContent, type ResolvedBlob, type ResolvedSession, type Result, type RetainBlob, type Role, type RoleSummary, type RoleTransitionBlock, type SHA256, Session, SessionManager, type SessionMetadata, type SessionSnapshot, type Settings, type Store, type Summarizer, type SummaryBlock, type SwitchSessionRole, type SyncWorkspace, type SystemActor, type TextBlock, type TextContextContent, type ThinkingBlock, type Timestamp, type ToolCall, type ToolCallCommand, type ToolRegistry, type ToolResultBlock, type ToolSummary, type ToolUseBlock, type Topic, type TopicIndex, type Turn, TurnBuilder, type TurnKey, type TurnNode, type TurnProcessor, type TurnRef, TurnTree, type URI, type UUID, type UpdateContext, type UpdatePreference, type UpdateRole, type UpdateSession, type UpdateTopic, type UpdateTurn, type Workspace, type WorkspaceBundle, type WorkspaceContext, type WorkspaceDatabase, type WorkspaceError, type WorkspaceEvents, type WorkspaceExtension, WorkspaceManager, type WorkspaceMiddleware, type WorkspaceReducer, bufferToBase64, computeSHA256, createWorkspace, createWorkspaceDatabase, del, error, getExtension, merge, ok, omitNullUndefined, shortHash, success };