busabase-sdk 0.9.8 → 0.9.10

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/dist/index.d.ts CHANGED
@@ -251,7 +251,7 @@ interface NodeOutput {
251
251
  slug: string;
252
252
  name: string;
253
253
  description: string;
254
- metadata: {
254
+ metadata: Record<string, unknown> & {
255
255
  entryFile?: string;
256
256
  visibility?: "private" | "workspace" | "public";
257
257
  version?: string;
@@ -393,6 +393,8 @@ declare const cloudContract: {
393
393
  slug: z.ZodNullable<z.ZodString>;
394
394
  plan: z.ZodNullable<z.ZodString>;
395
395
  }, z.core.$strip>>;
396
+ createdSpace: z.ZodOptional<z.ZodBoolean>;
397
+ bootstrapRequired: z.ZodOptional<z.ZodBoolean>;
396
398
  }, z.core.$strip>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
397
399
  };
398
400
  search: _orpc_contract.ContractProcedure<z.ZodObject<{
@@ -512,6 +514,19 @@ declare const cloudContract: {
512
514
  parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
513
515
  depth: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
514
516
  }, z.core.$strip>>, z.ZodArray<z.ZodType<NodeOutput, unknown, z.core.$ZodTypeInternals<NodeOutput, unknown>>>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
517
+ searchByName: _orpc_contract.ContractProcedure<z.ZodObject<{
518
+ query: z.ZodString;
519
+ limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
520
+ }, z.core.$strip>, z.ZodArray<z.ZodObject<{
521
+ id: z.ZodString;
522
+ type: z.ZodEnum<{
523
+ [x: string]: string;
524
+ }>;
525
+ name: z.ZodString;
526
+ slug: z.ZodString;
527
+ path: z.ZodString;
528
+ updatedAt: z.ZodString;
529
+ }, z.core.$strip>>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
515
530
  isDescendant: _orpc_contract.ContractProcedure<z.ZodObject<{
516
531
  nodeId: z.ZodString;
517
532
  potentialAncestorId: z.ZodString;
@@ -1400,6 +1415,10 @@ declare const cloudContract: {
1400
1415
  createdAt: z.ZodString;
1401
1416
  }, z.core.$strip>>;
1402
1417
  }, z.core.$strip>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
1418
+ updateMetadata: _orpc_contract.ContractProcedure<z.ZodObject<{
1419
+ nodeId: z.ZodString;
1420
+ metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
1421
+ }, z.core.$strip>, z.ZodType<NodeOutput, unknown, z.core.$ZodTypeInternals<NodeOutput, unknown>>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
1403
1422
  purge: _orpc_contract.ContractProcedure<z.ZodObject<{
1404
1423
  nodeId: z.ZodString;
1405
1424
  }, z.core.$strip>, z.ZodObject<{
@@ -1495,6 +1514,7 @@ declare const cloudContract: {
1495
1514
  "asset.metadata_updated": "asset.metadata_updated";
1496
1515
  "asset.text_written": "asset.text_written";
1497
1516
  "asset.text_marked_none": "asset.text_marked_none";
1517
+ "node.metadata_updated": "node.metadata_updated";
1498
1518
  "node.purged": "node.purged";
1499
1519
  }>;
1500
1520
  actorId: z.ZodString;
@@ -1533,6 +1553,7 @@ declare const cloudContract: {
1533
1553
  "asset.metadata_updated": "asset.metadata_updated";
1534
1554
  "asset.text_written": "asset.text_written";
1535
1555
  "asset.text_marked_none": "asset.text_marked_none";
1556
+ "node.metadata_updated": "node.metadata_updated";
1536
1557
  "node.purged": "node.purged";
1537
1558
  }>;
1538
1559
  actorId: z.ZodDefault<z.ZodOptional<z.ZodString>>;
@@ -1563,6 +1584,7 @@ declare const cloudContract: {
1563
1584
  "asset.metadata_updated": "asset.metadata_updated";
1564
1585
  "asset.text_written": "asset.text_written";
1565
1586
  "asset.text_marked_none": "asset.text_marked_none";
1587
+ "node.metadata_updated": "node.metadata_updated";
1566
1588
  "node.purged": "node.purged";
1567
1589
  }>;
1568
1590
  actorId: z.ZodString;
@@ -2549,6 +2571,7 @@ declare const cloudContract: {
2549
2571
  "asset.metadata_updated": "asset.metadata_updated";
2550
2572
  "asset.text_written": "asset.text_written";
2551
2573
  "asset.text_marked_none": "asset.text_marked_none";
2574
+ "node.metadata_updated": "node.metadata_updated";
2552
2575
  "node.purged": "node.purged";
2553
2576
  }>;
2554
2577
  actorId: z.ZodString;
@@ -14729,6 +14752,15 @@ declare const cloudContract: {
14729
14752
  rows: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
14730
14753
  nextCursor: z.ZodNullable<z.ZodString>;
14731
14754
  }, z.core.$strip>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
14755
+ exportAssetText: _orpc_contract.ContractProcedure<z.ZodObject<{
14756
+ assetId: z.ZodString;
14757
+ }, z.core.$strip>, z.ZodObject<{
14758
+ assetId: z.ZodString;
14759
+ textStorageKey: z.ZodString;
14760
+ downloadUrl: z.ZodNullable<z.ZodString>;
14761
+ textContentHash: z.ZodNullable<z.ZodString>;
14762
+ byteCount: z.ZodNumber;
14763
+ }, z.core.$strip>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
14732
14764
  importBegin: _orpc_contract.ContractProcedure<_orpc_contract.Schema<unknown, unknown>, z.ZodObject<{
14733
14765
  sessionId: z.ZodString;
14734
14766
  }, z.core.$strip>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
@@ -14753,7 +14785,7 @@ declare const cloudContract: {
14753
14785
  commits: "commits";
14754
14786
  changeRequests: "changeRequests";
14755
14787
  auditEvents: "auditEvents";
14756
- }>, z.ZodLiteral<"docBodies">, z.ZodLiteral<"attachmentBlobs">]>;
14788
+ }>, z.ZodLiteral<"docBodies">, z.ZodLiteral<"attachmentBlobs">, z.ZodLiteral<"assetTextBlobs">]>;
14757
14789
  rows: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
14758
14790
  }, z.core.$strip>, z.ZodObject<{
14759
14791
  inserted: z.ZodNumber;
@@ -14770,6 +14802,91 @@ declare const cloudContract: {
14770
14802
  ok: z.ZodBoolean;
14771
14803
  }, z.core.$strip>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
14772
14804
  };
14805
+ install: {
14806
+ planFromGithub: _orpc_contract.ContractProcedure<z.ZodObject<{
14807
+ repoUrl: z.ZodString;
14808
+ intoFolder: z.ZodOptional<z.ZodString>;
14809
+ rename: z.ZodOptional<z.ZodBoolean>;
14810
+ autoMerge: z.ZodOptional<z.ZodBoolean>;
14811
+ }, z.core.$strip>, z.ZodObject<{
14812
+ package: z.ZodObject<{
14813
+ name: z.ZodString;
14814
+ description: z.ZodDefault<z.ZodString>;
14815
+ version: z.ZodOptional<z.ZodString>;
14816
+ author: z.ZodOptional<z.ZodString>;
14817
+ license: z.ZodOptional<z.ZodString>;
14818
+ homepage: z.ZodOptional<z.ZodString>;
14819
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
14820
+ }, z.core.$strip>;
14821
+ source: z.ZodObject<{
14822
+ owner: z.ZodString;
14823
+ repo: z.ZodString;
14824
+ ref: z.ZodOptional<z.ZodString>;
14825
+ subdir: z.ZodOptional<z.ZodString>;
14826
+ }, z.core.$strip>;
14827
+ targetFolderSlug: z.ZodString;
14828
+ nodes: z.ZodDefault<z.ZodArray<z.ZodObject<{
14829
+ path: z.ZodString;
14830
+ slug: z.ZodString;
14831
+ name: z.ZodString;
14832
+ type: z.ZodEnum<{
14833
+ file: "file";
14834
+ base: "base";
14835
+ folder: "folder";
14836
+ skill: "skill";
14837
+ drive: "drive";
14838
+ airapp: "airapp";
14839
+ doc: "doc";
14840
+ }>;
14841
+ depth: z.ZodNumber;
14842
+ fieldCount: z.ZodOptional<z.ZodNumber>;
14843
+ recordCount: z.ZodOptional<z.ZodNumber>;
14844
+ fileCount: z.ZodOptional<z.ZodNumber>;
14845
+ }, z.core.$strip>>>;
14846
+ counts: z.ZodObject<{
14847
+ folders: z.ZodNumber;
14848
+ docs: z.ZodNumber;
14849
+ bases: z.ZodNumber;
14850
+ records: z.ZodNumber;
14851
+ skills: z.ZodNumber;
14852
+ airapps: z.ZodNumber;
14853
+ drives: z.ZodNumber;
14854
+ files: z.ZodNumber;
14855
+ }, z.core.$strip>;
14856
+ collisions: z.ZodDefault<z.ZodArray<z.ZodObject<{
14857
+ kind: z.ZodEnum<{
14858
+ base: "base";
14859
+ node: "node";
14860
+ }>;
14861
+ slug: z.ZodString;
14862
+ path: z.ZodString;
14863
+ renamedTo: z.ZodOptional<z.ZodString>;
14864
+ }, z.core.$strip>>>;
14865
+ warnings: z.ZodDefault<z.ZodArray<z.ZodString>>;
14866
+ requiresAutoMerge: z.ZodBoolean;
14867
+ applicable: z.ZodBoolean;
14868
+ }, z.core.$strip>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
14869
+ fromGithub: _orpc_contract.ContractProcedure<z.ZodObject<{
14870
+ repoUrl: z.ZodString;
14871
+ intoFolder: z.ZodOptional<z.ZodString>;
14872
+ rename: z.ZodOptional<z.ZodBoolean>;
14873
+ autoMerge: z.ZodOptional<z.ZodBoolean>;
14874
+ }, z.core.$strip>, z.ZodObject<{
14875
+ targetFolderSlug: z.ZodString;
14876
+ targetFolderNodeId: z.ZodString;
14877
+ created: z.ZodObject<{
14878
+ folders: z.ZodNumber;
14879
+ docs: z.ZodNumber;
14880
+ bases: z.ZodNumber;
14881
+ views: z.ZodNumber;
14882
+ records: z.ZodNumber;
14883
+ fileTreeNodes: z.ZodNumber;
14884
+ files: z.ZodNumber;
14885
+ }, z.core.$strip>;
14886
+ pendingChangeRequests: z.ZodNumber;
14887
+ warnings: z.ZodDefault<z.ZodArray<z.ZodString>>;
14888
+ }, z.core.$strip>, _orpc_contract.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
14889
+ };
14773
14890
  changeRequests: {
14774
14891
  list: _orpc_contract.ContractProcedure<z.ZodDefault<z.ZodOptional<z.ZodObject<{
14775
14892
  limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
@@ -22472,6 +22589,7 @@ declare const activityItemSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
22472
22589
  "asset.metadata_updated": "asset.metadata_updated";
22473
22590
  "asset.text_written": "asset.text_written";
22474
22591
  "asset.text_marked_none": "asset.text_marked_none";
22592
+ "node.metadata_updated": "node.metadata_updated";
22475
22593
  "node.purged": "node.purged";
22476
22594
  }>;
22477
22595
  actorId: z.ZodString;
@@ -23017,7 +23135,7 @@ type ChangeRequestTargetType = "base" | "node";
23017
23135
  type ReviewVerdict = "approved" | "rejected";
23018
23136
  type SearchResultKind = "record" | "change_request" | "base" | "file";
23019
23137
  type CommentSubjectType = "record" | "change_request" | "operation" | "commit";
23020
- type AuditAction = "record.viewed" | "change_request.created" | "change_request.updated" | "change_request.deleted" | "change_request.reviewed" | "change_request.merged" | "base.created" | "field.created" | "doc.created" | "doc.updated" | "file.created" | "skill.created" | "drive.created" | "airapp.created" | "asset.deleted" | "asset.metadata_updated" | "asset.text_written" | "asset.text_marked_none" | "node.purged";
23138
+ type AuditAction = "record.viewed" | "change_request.created" | "change_request.updated" | "change_request.deleted" | "change_request.reviewed" | "change_request.merged" | "base.created" | "field.created" | "doc.created" | "doc.updated" | "file.created" | "skill.created" | "drive.created" | "airapp.created" | "asset.deleted" | "asset.metadata_updated" | "asset.text_written" | "asset.text_marked_none" | "node.metadata_updated" | "node.purged";
23021
23139
  interface UserRefVO {
23022
23140
  id: string;
23023
23141
  name: string | null;
@@ -23025,6 +23143,22 @@ interface UserRefVO {
23025
23143
  image: string | null;
23026
23144
  role?: string | null;
23027
23145
  }
23146
+ /**
23147
+ * Cheap, name/slug-only match from `nodes.searchByName` (see
23148
+ * `apps/busabase/content/spec/search-quick-jump.md`) — deliberately a much
23149
+ * smaller projection than `NodeVO` (no `description`/`metadata`/tree shape):
23150
+ * this backs the dashboard's instant quick-jump palette, not the sidebar tree
23151
+ * or a node's own detail view. `path` is the route this node navigates to
23152
+ * (e.g. `/base/{slug}`), not a filesystem/breadcrumb tree path.
23153
+ */
23154
+ interface NodeSearchResultVO {
23155
+ id: string;
23156
+ type: NodeType;
23157
+ name: string;
23158
+ slug: string;
23159
+ path: string;
23160
+ updatedAt: string;
23161
+ }
23028
23162
  interface NodeVO {
23029
23163
  id: string;
23030
23164
  parentId: string | null;
@@ -23032,7 +23166,7 @@ interface NodeVO {
23032
23166
  slug: string;
23033
23167
  name: string;
23034
23168
  description: string;
23035
- metadata: {
23169
+ metadata: Record<string, unknown> & {
23036
23170
  entryFile?: string;
23037
23171
  visibility?: "private" | "workspace" | "public";
23038
23172
  version?: string;
@@ -23351,4 +23485,4 @@ declare class Busabase {
23351
23485
  }>>>>;
23352
23486
  }
23353
23487
 
23354
- export { type ActivityItemVO, type AgentTaskVO, type FileTreeFileVO as AirAppFileVO, type FileTreeReadFileVO as AirAppReadFileVO, type FileTreeNodeVO as AirAppVO, type AssetAttachmentRef, type AssetDetailVO, type AssetTextStatus, type AssetUsageVO, type AssetVO, type AttachmentRef, type AuditAction, type AuditEventVO, type BaseFieldVO, type BaseVO, Busabase, type BusabaseClient, type BusabaseConfig, type BusabaseRpcConfig, CREATABLE_NODE_TYPES, type ChangeRequestBatchResultVO, type ChangeRequestCountsVO, type ChangeRequestStatus, type ChangeRequestTargetType, type ChangeRequestVO, type CloudContract, type CommentSubjectType, type CommentVO, type CommitVO, type CreatableNodeType, DEFAULT_BASE_URL, type FileTreeFileVO as DriveFileVO, type FileTreeReadFileVO as DriveReadFileVO, type FileTreeNodeVO as DriveVO, type FieldType, type FileNodeMetadata, type FileNodeVO, type FileTreeFileVO, type FileTreeNodeVO, type FileTreeReadFileVO, type GalleryCardSize, type GalleryCoverFit, type GanttScale, type NodeType, type NodeVO, type OperationKind, type OperationStatus, type OperationVO, type RecordLinkVO, type RecordVO, type ResolvedConfig, type ReviewVO, type ReviewVerdict, type SearchResponseVO, type SearchResultKind, type SearchResultVO, type FileTreeFileVO as SkillFileVO, type FileTreeReadFileVO as SkillReadFileVO, type FileTreeNodeVO as SkillVO, type UpdateVaultSettingsDTO, type UserRefVO, type VaultAccessPolicy, type VaultEnvironment, type VaultItemInput, type VaultItemKind, type VaultItemVO, type VaultRuntimeEnv, type VaultScopeType, type VaultSettingsVO, type ViewConfigVO, type ViewFilterOperator, type ViewFilterVO, type ViewSortVO, type ViewType, type ViewVO, cloudContract, createBusabaseClient, createBusabaseRpcClient, normalizeBaseUrl, resolveConfig };
23488
+ export { type ActivityItemVO, type AgentTaskVO, type FileTreeFileVO as AirAppFileVO, type FileTreeReadFileVO as AirAppReadFileVO, type FileTreeNodeVO as AirAppVO, type AssetAttachmentRef, type AssetDetailVO, type AssetTextStatus, type AssetUsageVO, type AssetVO, type AttachmentRef, type AuditAction, type AuditEventVO, type BaseFieldVO, type BaseVO, Busabase, type BusabaseClient, type BusabaseConfig, type BusabaseRpcConfig, CREATABLE_NODE_TYPES, type ChangeRequestBatchResultVO, type ChangeRequestCountsVO, type ChangeRequestStatus, type ChangeRequestTargetType, type ChangeRequestVO, type CloudContract, type CommentSubjectType, type CommentVO, type CommitVO, type CreatableNodeType, DEFAULT_BASE_URL, type FileTreeFileVO as DriveFileVO, type FileTreeReadFileVO as DriveReadFileVO, type FileTreeNodeVO as DriveVO, type FieldType, type FileNodeMetadata, type FileNodeVO, type FileTreeFileVO, type FileTreeNodeVO, type FileTreeReadFileVO, type GalleryCardSize, type GalleryCoverFit, type GanttScale, type NodeSearchResultVO, type NodeType, type NodeVO, type OperationKind, type OperationStatus, type OperationVO, type RecordLinkVO, type RecordVO, type ResolvedConfig, type ReviewVO, type ReviewVerdict, type SearchResponseVO, type SearchResultKind, type SearchResultVO, type FileTreeFileVO as SkillFileVO, type FileTreeReadFileVO as SkillReadFileVO, type FileTreeNodeVO as SkillVO, type UpdateVaultSettingsDTO, type UserRefVO, type VaultAccessPolicy, type VaultEnvironment, type VaultItemInput, type VaultItemKind, type VaultItemVO, type VaultRuntimeEnv, type VaultScopeType, type VaultSettingsVO, type ViewConfigVO, type ViewFilterOperator, type ViewFilterVO, type ViewSortVO, type ViewType, type ViewVO, cloudContract, createBusabaseClient, createBusabaseRpcClient, normalizeBaseUrl, resolveConfig };
package/dist/index.js CHANGED
@@ -427,7 +427,7 @@ var nodeSchema = z.lazy(
427
427
  visibility: z.enum(["private", "workspace", "public"]).optional(),
428
428
  version: z.string().optional(),
429
429
  assetId: z.string().optional()
430
- }).default({}),
430
+ }).catchall(z.unknown()).default({}),
431
431
  position: z.number(),
432
432
  createdAt: z.string(),
433
433
  updatedAt: z.string(),
@@ -459,6 +459,22 @@ var isDescendantInputSchema = z.object({
459
459
  var isDescendantOutputSchema = z.object({
460
460
  isDescendant: z.boolean()
461
461
  });
462
+ var updateNodeMetadataInputSchema = z.object({
463
+ nodeId: z.string(),
464
+ metadata: z.record(z.string(), z.unknown())
465
+ });
466
+ var searchNodesByNameInputSchema = z.object({
467
+ query: z.string().min(1),
468
+ limit: z.number().int().min(1).max(50).optional().default(20)
469
+ });
470
+ var nodeSearchResultSchema = z.object({
471
+ id: z.string(),
472
+ type: z.enum(NODE_TYPES),
473
+ name: z.string(),
474
+ slug: z.string(),
475
+ path: z.string(),
476
+ updatedAt: z.string()
477
+ });
462
478
  var userRefSchema = z.object({
463
479
  id: z.string(),
464
480
  name: z.string().nullable(),
@@ -635,6 +651,7 @@ var auditActionSchema = z.enum([
635
651
  "asset.metadata_updated",
636
652
  "asset.text_written",
637
653
  "asset.text_marked_none",
654
+ "node.metadata_updated",
638
655
  "node.purged"
639
656
  ]);
640
657
  var auditEventSchema = z.object({
@@ -824,7 +841,11 @@ var authInfoSchema = z.object({
824
841
  * space-scoped — when this has more than one entry, callers should confirm the
825
842
  * intended space and target it explicitly via the `x-busabase-space` header.
826
843
  */
827
- spaces: z.array(authSpaceSchema)
844
+ spaces: z.array(authSpaceSchema),
845
+ /** Cloud only: the server created this user's first Space during this exact request. */
846
+ createdSpace: z.boolean().optional(),
847
+ /** Cloud only: this auto-created Space still needs its idempotent starter initialization. */
848
+ bootstrapRequired: z.boolean().optional()
828
849
  });
829
850
 
830
851
  // ../../packages/busabase-contract/src/domains/filetree/contract.ts
@@ -1907,12 +1928,36 @@ var ExportTablesVOSchema = z.object({
1907
1928
  rows: z.array(z.record(z.string(), z.unknown())),
1908
1929
  nextCursor: z.string().nullable()
1909
1930
  });
1931
+ var ExportAssetTextInputSchema = z.object({ assetId: z.string() });
1932
+ var ExportAssetTextVOSchema = z.object({
1933
+ assetId: z.string(),
1934
+ /** The row's `text_storage_key` — the exact key a restore must write back to. */
1935
+ textStorageKey: z.string(),
1936
+ /**
1937
+ * `null` when this row owns no separate text object and therefore needs no
1938
+ * blob in the archive:
1939
+ * - auto-registered text-kind rows (`writtenBy: "auto"`), whose
1940
+ * `textStorageKey` IS the owning attachment's own key — those bytes are
1941
+ * already archived by the attachment-blob pass, and re-archiving them
1942
+ * would duplicate bytes and collide on restore;
1943
+ * - `status: "none"` rows (no extractable text), whose key is `""`.
1944
+ */
1945
+ downloadUrl: z.string().nullable(),
1946
+ /** `sha256:<hex>` of the text bytes, so a backup can verify what it downloaded. */
1947
+ textContentHash: z.string().nullable(),
1948
+ byteCount: z.number().int().nonnegative()
1949
+ });
1910
1950
  var ImportBeginVOSchema = z.object({
1911
1951
  sessionId: z.string()
1912
1952
  });
1913
1953
  var ImportTablesInputSchema = z.object({
1914
1954
  sessionId: z.string(),
1915
- table: z.union([DumpTableSchema, z.literal("docBodies"), z.literal("attachmentBlobs")]),
1955
+ table: z.union([
1956
+ DumpTableSchema,
1957
+ z.literal("docBodies"),
1958
+ z.literal("attachmentBlobs"),
1959
+ z.literal("assetTextBlobs")
1960
+ ]),
1916
1961
  rows: z.array(z.record(z.string(), z.unknown()))
1917
1962
  });
1918
1963
  var ImportTablesVOSchema = z.object({
@@ -1938,6 +1983,13 @@ var dumpContract = {
1938
1983
  summary: "Export raw rows for one table (cursor-paginated)",
1939
1984
  successDescription: "A page of raw rows for the requested table (id-ordered), plus an opaque nextCursor (null at the end). Vault items and webhook secrets are never exportable through this endpoint."
1940
1985
  }).input(ExportTablesInputSchema).output(ExportTablesVOSchema),
1986
+ exportAssetText: oc.route({
1987
+ method: "GET",
1988
+ path: "/dump/export/asset-texts/{assetId}/content",
1989
+ tags: ["Dump"],
1990
+ summary: "Resolve the download URL for one asset's extracted-text object",
1991
+ successDescription: "A resolved download URL for the asset's DERIVED text blob (`asset-texts/blobs/sha256/\u2026`) plus its `textStorageKey` and `textContentHash`, so a backup can archive the exact bytes and verify them. `downloadUrl` is null when the row owns no separate object (auto-registered text-kind rows point at their attachment's own key, already covered by the attachment blobs; `status: \"none\"` rows have no text at all)."
1992
+ }).input(ExportAssetTextInputSchema).output(ExportAssetTextVOSchema),
1941
1993
  importBegin: oc.route({
1942
1994
  method: "POST",
1943
1995
  path: "/dump/import/begin",
@@ -1950,7 +2002,7 @@ var dumpContract = {
1950
2002
  path: "/dump/import/tables",
1951
2003
  tags: ["Dump"],
1952
2004
  summary: "Import a batch of raw rows into an open session",
1953
- successDescription: "Inserted rows preserving their original ids. `docBodies` is a pseudo-table ({nodeId, markdown}[]) written directly to object storage (doc bodies are not a DB row)."
2005
+ successDescription: "Inserted rows preserving their original ids. `docBodies` ({nodeId, markdown}[]), `attachmentBlobs` ({storageKey, mimeType, base64}[]) and `assetTextBlobs` ({textStorageKey, base64}[]) are pseudo-tables written directly to object storage (none of them are DB rows)."
1954
2006
  }).input(ImportTablesInputSchema).output(ImportTablesVOSchema),
1955
2007
  importCommit: oc.route({
1956
2008
  method: "POST",
@@ -2038,6 +2090,168 @@ var folderContract = {
2038
2090
  successDescription: "Folder node and its direct children."
2039
2091
  }).input(z.object({ nodeId: z.string() })).output(folderSchema)
2040
2092
  };
2093
+ var InstallPlanNodeTypeSchema = z.enum([
2094
+ "folder",
2095
+ "doc",
2096
+ "base",
2097
+ "skill",
2098
+ "airapp",
2099
+ "drive",
2100
+ "file"
2101
+ ]);
2102
+ var InstallPlanNodeVOSchema = z.object({
2103
+ /** Package-relative path, e.g. `guides/faq`. Unique within a plan. */
2104
+ path: z.string(),
2105
+ slug: z.string(),
2106
+ name: z.string(),
2107
+ type: InstallPlanNodeTypeSchema,
2108
+ /** 0 for a top-level node under the target folder. */
2109
+ depth: z.number().int().min(0),
2110
+ /** Bases only. */
2111
+ fieldCount: z.number().int().min(0).optional(),
2112
+ /** Bases only — the per-base record count §15.4 asks the plan to surface. */
2113
+ recordCount: z.number().int().min(0).optional(),
2114
+ /** skill / airapp / drive only — files carried verbatim inside the node. */
2115
+ fileCount: z.number().int().min(0).optional()
2116
+ });
2117
+ var InstallCollisionVOSchema = z.object({
2118
+ kind: z.enum(["node", "base"]),
2119
+ slug: z.string(),
2120
+ /** Human-readable location, e.g. `my-package/product-catalog`. */
2121
+ path: z.string(),
2122
+ /** Set when `rename` resolved it — the slug that would actually be created. */
2123
+ renamedTo: z.string().optional()
2124
+ });
2125
+ var InstallPlanCountsVOSchema = z.object({
2126
+ folders: z.number().int().min(0),
2127
+ docs: z.number().int().min(0),
2128
+ bases: z.number().int().min(0),
2129
+ records: z.number().int().min(0),
2130
+ skills: z.number().int().min(0),
2131
+ airapps: z.number().int().min(0),
2132
+ drives: z.number().int().min(0),
2133
+ files: z.number().int().min(0)
2134
+ });
2135
+ var InstallPackageInfoVOSchema = z.object({
2136
+ name: z.string(),
2137
+ description: z.string().default(""),
2138
+ version: z.string().optional(),
2139
+ author: z.string().optional(),
2140
+ license: z.string().optional(),
2141
+ homepage: z.string().optional(),
2142
+ tags: z.array(z.string()).default([])
2143
+ });
2144
+ var InstallPlanVOSchema = z.object({
2145
+ package: InstallPackageInfoVOSchema,
2146
+ /** Resolved GitHub source, echoed back so the UI can show what it actually fetched. */
2147
+ source: z.object({
2148
+ owner: z.string(),
2149
+ repo: z.string(),
2150
+ ref: z.string().optional(),
2151
+ subdir: z.string().optional()
2152
+ }),
2153
+ targetFolderSlug: z.string(),
2154
+ nodes: z.array(InstallPlanNodeVOSchema).default([]),
2155
+ counts: InstallPlanCountsVOSchema,
2156
+ collisions: z.array(InstallCollisionVOSchema).default([]),
2157
+ warnings: z.array(z.string()).default([]),
2158
+ /**
2159
+ * True when a record carries a relation VALUE. A relation stores the ids of the
2160
+ * records it points at, and those exist only once the records are merged — so a
2161
+ * review-first install would land every relation empty. `autoMerge` is required
2162
+ * in that case, and the UI must say why.
2163
+ */
2164
+ requiresAutoMerge: z.boolean(),
2165
+ /**
2166
+ * Whether installing with **the options this plan was asked for** would work:
2167
+ * false when a collision is unresolved, or when `requiresAutoMerge` is unmet
2168
+ * for the `autoMerge` the caller passed.
2169
+ *
2170
+ * It is therefore an answer to "what happens if I install like this", not a
2171
+ * property of the package — a package whose records carry relation values
2172
+ * reports `applicable: false` when planned WITHOUT `autoMerge` and true WITH
2173
+ * it. A client that offers an auto-merge toggle must re-plan when it changes
2174
+ * (the same way it re-plans when `rename` or `intoFolder` change), rather than
2175
+ * treating one plan's `applicable` as final.
2176
+ *
2177
+ * There is deliberately no `blockedReason` string here: the reason is already
2178
+ * carried structurally by `collisions[]` (with `renamedTo`) and
2179
+ * `requiresAutoMerge`, and each client words it for its own surface — a CLI
2180
+ * says "re-run with --auto-merge", a dialog points at its own checkbox.
2181
+ */
2182
+ applicable: z.boolean()
2183
+ });
2184
+ var InstallCreatedCountsVOSchema = z.object({
2185
+ folders: z.number().int().min(0),
2186
+ docs: z.number().int().min(0),
2187
+ bases: z.number().int().min(0),
2188
+ views: z.number().int().min(0),
2189
+ records: z.number().int().min(0),
2190
+ fileTreeNodes: z.number().int().min(0),
2191
+ files: z.number().int().min(0)
2192
+ });
2193
+ var InstallResultVOSchema = z.object({
2194
+ targetFolderSlug: z.string(),
2195
+ targetFolderNodeId: z.string(),
2196
+ created: InstallCreatedCountsVOSchema,
2197
+ /**
2198
+ * Change requests left for a human to review. Structure (folders, Bases, their
2199
+ * fields and views) is always created immediately — a pending Base has no id, so
2200
+ * there would be nowhere to attach a view or a record. Content (records, docs,
2201
+ * skills, AirApps) is what lands here for review.
2202
+ */
2203
+ pendingChangeRequests: z.number().int().min(0),
2204
+ warnings: z.array(z.string()).default([])
2205
+ });
2206
+ var repoUrlField = z.string().min(1).describe(
2207
+ "GitHub repo URL: https://github.com/<owner>/<repo>[/tree/<ref>[/<subdir>]]. Only GitHub hosts are accepted."
2208
+ );
2209
+ var intoFolderField = z.string().optional().describe("Slug of the folder to install into. Defaults to the package manifest's name.");
2210
+ var renameField = z.boolean().optional().describe(
2211
+ "Resolve slug collisions by suffixing (-2, -3, \u2026) instead of refusing. Never overwrites anything."
2212
+ );
2213
+ var InstallPlanFromGithubDTOSchema = z.object({
2214
+ repoUrl: repoUrlField,
2215
+ intoFolder: intoFolderField,
2216
+ rename: renameField,
2217
+ /**
2218
+ * Plan as if installing with auto-merge. Only affects the returned
2219
+ * `applicable` (see `InstallPlanVOSchema`) — a dry run never writes either
2220
+ * way. A client with an auto-merge toggle passes the toggle's current value so
2221
+ * the preview answers the question the user is actually about to ask.
2222
+ *
2223
+ * `.optional()` with no `.default()`, matching `rename` above: `z.infer` gives
2224
+ * the OUTPUT type, so a default would make this REQUIRED for every caller.
2225
+ * Omitted means "plan without auto-merge" (applied in the logic layer).
2226
+ */
2227
+ autoMerge: z.boolean().optional()
2228
+ });
2229
+ var InstallFromGithubDTOSchema = z.object({
2230
+ repoUrl: repoUrlField,
2231
+ intoFolder: intoFolderField,
2232
+ rename: renameField,
2233
+ autoMerge: z.boolean().optional().describe(
2234
+ "Merge the content change requests on the spot instead of leaving them for review. This trusts the package author: a package can carry skills and AirApps, i.e. code this space's agents will execute."
2235
+ )
2236
+ });
2237
+
2238
+ // ../../packages/busabase-contract/src/domains/install/contract.ts
2239
+ var installContract = {
2240
+ planFromGithub: oc.route({
2241
+ method: "POST",
2242
+ path: "/install/github/plan",
2243
+ tags: ["Install"],
2244
+ summary: "Dry-run a GitHub package install",
2245
+ successDescription: "What installing this package would create: the node outline, per-base record counts, slug collisions, warnings, and whether autoMerge is required. Creates nothing."
2246
+ }).input(InstallPlanFromGithubDTOSchema).output(InstallPlanVOSchema),
2247
+ fromGithub: oc.route({
2248
+ method: "POST",
2249
+ path: "/install/github",
2250
+ tags: ["Install"],
2251
+ summary: "Install a package from a GitHub repo",
2252
+ successDescription: "Created counts plus the number of change requests left for review. Structure (folders, Bases, fields, views) is created immediately \u2014 a pending Base has no id to attach a view or record to; content (records, docs, skills, AirApps) lands as change requests unless `autoMerge` is set."
2253
+ }).input(InstallFromGithubDTOSchema).output(InstallResultVOSchema)
2254
+ };
2041
2255
 
2042
2256
  // ../../packages/busabase-contract/src/domains/skill/contract.ts
2043
2257
  var skillContract = makeFileTreeContract("skills", "Skills");
@@ -2463,6 +2677,13 @@ var busabaseContractRoutes = {
2463
2677
  summary: "List node tree",
2464
2678
  successDescription: "Workspace node tree including folders, Bases, files, and agents. With no `parentId`/`depth`, returns the FULL tree (legacy behavior, still what every non-sidebar caller gets). Passing `parentId` and/or `depth` switches to a depth-bounded fetch: `parentId` omitted/null starts from the space root and returns it wrapped exactly like the legacy call (just depth-limited); an explicit `parentId` returns that node's children directly, ready to merge into its `NodeVO.children` for a sidebar's lazy per-folder expand. See `NodeVO.hasChildren` for how a depth boundary is surfaced."
2465
2679
  }).input(listNodesInputSchema).output(z.array(nodeSchema)),
2680
+ searchByName: oc.route({
2681
+ method: "GET",
2682
+ path: "/nodes/search",
2683
+ tags: ["Nodes", "Search"],
2684
+ summary: "Search nodes by name/slug (cheap, name-only quick-jump)",
2685
+ successDescription: "Plain ilike match on name/slug across every node type (folder/base/skill/drive/airapp/file/doc), scoped by the same node-visibility ACL as `nodes.list`. No content scan and no full-text ranking \u2014 ordered exact-slug-match first, then by name. Backs the dashboard search dialog's 'Recent' tab cache-miss path (see apps/busabase/content/spec/search-quick-jump.md); the heavier `search` endpoint remains the dedicated full-text content search."
2686
+ }).input(searchNodesByNameInputSchema).output(z.array(nodeSearchResultSchema)),
2466
2687
  isDescendant: oc.route({
2467
2688
  method: "GET",
2468
2689
  path: "/nodes/{nodeId}/is-descendant",
@@ -2491,6 +2712,13 @@ var busabaseContractRoutes = {
2491
2712
  summary: "Move or reorder a node",
2492
2713
  successDescription: "Merged change request that repositioned the node under its (optionally new) parent. Applied immediately (auto-merged) since reordering is a low-risk structural tweak, not a review-worthy content change."
2493
2714
  }).input(moveNodeInputSchema).output(changeRequestSchema),
2715
+ updateMetadata: oc.route({
2716
+ method: "PATCH",
2717
+ path: "/nodes/{nodeId}/metadata",
2718
+ tags: ["Nodes"],
2719
+ summary: "Update node metadata",
2720
+ successDescription: "Shallow-merged the supplied top-level keys into the active node's existing metadata. Requires write access on the node."
2721
+ }).input(updateNodeMetadataInputSchema).output(nodeSchema),
2494
2722
  purge: oc.route({
2495
2723
  method: "DELETE",
2496
2724
  path: "/nodes/{nodeId}",
@@ -2627,6 +2855,7 @@ var busabaseContractRoutes = {
2627
2855
  vault: vaultContract,
2628
2856
  webhooks: webhookContract,
2629
2857
  dump: dumpContract,
2858
+ install: installContract,
2630
2859
  changeRequests: {
2631
2860
  list: oc.route({
2632
2861
  method: "GET",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "busabase-sdk",
3
- "version": "0.9.8",
3
+ "version": "0.9.10",
4
4
  "description": "Typed TypeScript/JavaScript SDK for the Busabase OpenAPI REST API. Talks to a local or remote `busabase server` (or Busabase Cloud).",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/busabase/busabase/tree/main/apps/busabase-sdk",
@@ -41,9 +41,9 @@
41
41
  "tsx": "^4.20.5",
42
42
  "typescript": "^5.9.3",
43
43
  "vitest": "^2.1.8",
44
- "busabase-contract": "0.9.8",
45
- "openlib": "0.1.1",
46
- "open-domains": "0.0.2"
44
+ "busabase-contract": "0.9.10",
45
+ "open-domains": "0.0.2",
46
+ "openlib": "0.1.1"
47
47
  },
48
48
  "engines": {
49
49
  "node": ">=24.18.0"