busa-sdk 0.30.1 → 0.40.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/dist/airapp.d.ts +1 -1
- package/dist/{client-DJmL8Jl_.d.ts → client-CWlHll4H.d.ts} +212 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +312 -16
- package/package.json +1 -1
package/dist/airapp.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as BusabaseClient } from "./client-
|
|
1
|
+
import { t as BusabaseClient } from "./client-CWlHll4H.js";
|
|
2
2
|
//#region src/airapp.d.ts
|
|
3
3
|
type NodeChangeRequestInput = Parameters<BusabaseClient["nodes"]["createChangeRequest"]>[0];
|
|
4
4
|
type NodeOperationInput = NodeChangeRequestInput["operations"][number];
|
|
@@ -319,6 +319,10 @@ declare const NodeIconSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
319
319
|
type NodeIcon = z.infer<typeof NodeIconSchema>;
|
|
320
320
|
//#endregion
|
|
321
321
|
//#region ../../packages/busabase-contract/src/contract/schemas.d.ts
|
|
322
|
+
/** @see nodeSettingsSchema — declared here so `NodeOutput` can reference it. */
|
|
323
|
+
type NodeSettings = {
|
|
324
|
+
airappEngine?: "browser" | "local" | "remote" | null;
|
|
325
|
+
};
|
|
322
326
|
interface NodeOutput {
|
|
323
327
|
id: string;
|
|
324
328
|
parentId: string | null;
|
|
@@ -338,6 +342,15 @@ interface NodeOutput {
|
|
|
338
342
|
metadata: Record<string, unknown> & {
|
|
339
343
|
version?: string;
|
|
340
344
|
};
|
|
345
|
+
/**
|
|
346
|
+
* System settings the product DOES read and act on — the opposite of
|
|
347
|
+
* `metadata` above, and separate for that reason.
|
|
348
|
+
*
|
|
349
|
+
* Written only by `PATCH /nodes/{nodeId}/settings`, whose input is a closed
|
|
350
|
+
* schema; the generic metadata endpoint cannot address it. See
|
|
351
|
+
* `nodeSettingsSchema`.
|
|
352
|
+
*/
|
|
353
|
+
settings?: NodeSettings;
|
|
341
354
|
/**
|
|
342
355
|
* This node's OWN declared visibility, or null when it simply inherits from
|
|
343
356
|
* its ancestors. Access control, so it is a real column rather than a
|
|
@@ -1628,6 +1641,113 @@ declare const cloudContract: {
|
|
|
1628
1641
|
nodeId: z.ZodString;
|
|
1629
1642
|
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
1630
1643
|
}, z.core.$strip>, z.ZodType<NodeOutput, unknown, z.core.$ZodTypeInternals<NodeOutput, unknown>>, import("@orpc/contract").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
1644
|
+
updateSettings: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
1645
|
+
nodeId: z.ZodString;
|
|
1646
|
+
settings: z.ZodObject<{
|
|
1647
|
+
airappEngine: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
1648
|
+
browser: "browser";
|
|
1649
|
+
local: "local";
|
|
1650
|
+
remote: "remote";
|
|
1651
|
+
}>>>;
|
|
1652
|
+
}, z.core.$strict>;
|
|
1653
|
+
}, z.core.$strip>, z.ZodType<NodeOutput, unknown, z.core.$ZodTypeInternals<NodeOutput, unknown>>, import("@orpc/contract").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
1654
|
+
getAgentPrompts: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
1655
|
+
nodeId: z.ZodString;
|
|
1656
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1657
|
+
nodeId: z.ZodString;
|
|
1658
|
+
agentPrompts: z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
1659
|
+
key: z.ZodString;
|
|
1660
|
+
intent: z.ZodOptional<z.ZodEnum<{
|
|
1661
|
+
change: "change";
|
|
1662
|
+
"read-only": "read-only";
|
|
1663
|
+
}>>;
|
|
1664
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodEnum<{
|
|
1665
|
+
de: "de";
|
|
1666
|
+
en: "en";
|
|
1667
|
+
es: "es";
|
|
1668
|
+
fr: "fr";
|
|
1669
|
+
ja: "ja";
|
|
1670
|
+
ko: "ko";
|
|
1671
|
+
pt: "pt";
|
|
1672
|
+
"zh-CN": "zh-CN";
|
|
1673
|
+
"zh-TW": "zh-TW";
|
|
1674
|
+
}> & z.core.$partial, z.ZodString>]>;
|
|
1675
|
+
body: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodEnum<{
|
|
1676
|
+
de: "de";
|
|
1677
|
+
en: "en";
|
|
1678
|
+
es: "es";
|
|
1679
|
+
fr: "fr";
|
|
1680
|
+
ja: "ja";
|
|
1681
|
+
ko: "ko";
|
|
1682
|
+
pt: "pt";
|
|
1683
|
+
"zh-CN": "zh-CN";
|
|
1684
|
+
"zh-TW": "zh-TW";
|
|
1685
|
+
}> & z.core.$partial, z.ZodString>]>;
|
|
1686
|
+
}, z.core.$strip>>>;
|
|
1687
|
+
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
1688
|
+
updateAgentPrompts: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
1689
|
+
nodeId: z.ZodString;
|
|
1690
|
+
agentPrompts: z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
1691
|
+
key: z.ZodString;
|
|
1692
|
+
intent: z.ZodOptional<z.ZodEnum<{
|
|
1693
|
+
change: "change";
|
|
1694
|
+
"read-only": "read-only";
|
|
1695
|
+
}>>;
|
|
1696
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodEnum<{
|
|
1697
|
+
de: "de";
|
|
1698
|
+
en: "en";
|
|
1699
|
+
es: "es";
|
|
1700
|
+
fr: "fr";
|
|
1701
|
+
ja: "ja";
|
|
1702
|
+
ko: "ko";
|
|
1703
|
+
pt: "pt";
|
|
1704
|
+
"zh-CN": "zh-CN";
|
|
1705
|
+
"zh-TW": "zh-TW";
|
|
1706
|
+
}> & z.core.$partial, z.ZodString>]>;
|
|
1707
|
+
body: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodEnum<{
|
|
1708
|
+
de: "de";
|
|
1709
|
+
en: "en";
|
|
1710
|
+
es: "es";
|
|
1711
|
+
fr: "fr";
|
|
1712
|
+
ja: "ja";
|
|
1713
|
+
ko: "ko";
|
|
1714
|
+
pt: "pt";
|
|
1715
|
+
"zh-CN": "zh-CN";
|
|
1716
|
+
"zh-TW": "zh-TW";
|
|
1717
|
+
}> & z.core.$partial, z.ZodString>]>;
|
|
1718
|
+
}, z.core.$strip>>>;
|
|
1719
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1720
|
+
nodeId: z.ZodString;
|
|
1721
|
+
agentPrompts: z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
1722
|
+
key: z.ZodString;
|
|
1723
|
+
intent: z.ZodOptional<z.ZodEnum<{
|
|
1724
|
+
change: "change";
|
|
1725
|
+
"read-only": "read-only";
|
|
1726
|
+
}>>;
|
|
1727
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodEnum<{
|
|
1728
|
+
de: "de";
|
|
1729
|
+
en: "en";
|
|
1730
|
+
es: "es";
|
|
1731
|
+
fr: "fr";
|
|
1732
|
+
ja: "ja";
|
|
1733
|
+
ko: "ko";
|
|
1734
|
+
pt: "pt";
|
|
1735
|
+
"zh-CN": "zh-CN";
|
|
1736
|
+
"zh-TW": "zh-TW";
|
|
1737
|
+
}> & z.core.$partial, z.ZodString>]>;
|
|
1738
|
+
body: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodEnum<{
|
|
1739
|
+
de: "de";
|
|
1740
|
+
en: "en";
|
|
1741
|
+
es: "es";
|
|
1742
|
+
fr: "fr";
|
|
1743
|
+
ja: "ja";
|
|
1744
|
+
ko: "ko";
|
|
1745
|
+
pt: "pt";
|
|
1746
|
+
"zh-CN": "zh-CN";
|
|
1747
|
+
"zh-TW": "zh-TW";
|
|
1748
|
+
}> & z.core.$partial, z.ZodString>]>;
|
|
1749
|
+
}, z.core.$strip>>>;
|
|
1750
|
+
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
1631
1751
|
updateContent: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
1632
1752
|
nodeId: z.ZodString;
|
|
1633
1753
|
content: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -2729,8 +2849,10 @@ declare const cloudContract: {
|
|
|
2729
2849
|
"drive.created": "drive.created";
|
|
2730
2850
|
"field.created": "field.created";
|
|
2731
2851
|
"file.created": "file.created";
|
|
2852
|
+
"node.agent_prompts_updated": "node.agent_prompts_updated";
|
|
2732
2853
|
"node.metadata_updated": "node.metadata_updated";
|
|
2733
2854
|
"node.purged": "node.purged";
|
|
2855
|
+
"node.settings_updated": "node.settings_updated";
|
|
2734
2856
|
"record.viewed": "record.viewed";
|
|
2735
2857
|
"skill.created": "skill.created";
|
|
2736
2858
|
}>;
|
|
@@ -2784,8 +2906,10 @@ declare const cloudContract: {
|
|
|
2784
2906
|
"drive.created": "drive.created";
|
|
2785
2907
|
"field.created": "field.created";
|
|
2786
2908
|
"file.created": "file.created";
|
|
2909
|
+
"node.agent_prompts_updated": "node.agent_prompts_updated";
|
|
2787
2910
|
"node.metadata_updated": "node.metadata_updated";
|
|
2788
2911
|
"node.purged": "node.purged";
|
|
2912
|
+
"node.settings_updated": "node.settings_updated";
|
|
2789
2913
|
"record.viewed": "record.viewed";
|
|
2790
2914
|
"skill.created": "skill.created";
|
|
2791
2915
|
}>;
|
|
@@ -2815,8 +2939,10 @@ declare const cloudContract: {
|
|
|
2815
2939
|
"drive.created": "drive.created";
|
|
2816
2940
|
"field.created": "field.created";
|
|
2817
2941
|
"file.created": "file.created";
|
|
2942
|
+
"node.agent_prompts_updated": "node.agent_prompts_updated";
|
|
2818
2943
|
"node.metadata_updated": "node.metadata_updated";
|
|
2819
2944
|
"node.purged": "node.purged";
|
|
2945
|
+
"node.settings_updated": "node.settings_updated";
|
|
2820
2946
|
"record.viewed": "record.viewed";
|
|
2821
2947
|
"skill.created": "skill.created";
|
|
2822
2948
|
}>;
|
|
@@ -3949,8 +4075,10 @@ declare const cloudContract: {
|
|
|
3949
4075
|
"drive.created": "drive.created";
|
|
3950
4076
|
"field.created": "field.created";
|
|
3951
4077
|
"file.created": "file.created";
|
|
4078
|
+
"node.agent_prompts_updated": "node.agent_prompts_updated";
|
|
3952
4079
|
"node.metadata_updated": "node.metadata_updated";
|
|
3953
4080
|
"node.purged": "node.purged";
|
|
4081
|
+
"node.settings_updated": "node.settings_updated";
|
|
3954
4082
|
"record.viewed": "record.viewed";
|
|
3955
4083
|
"skill.created": "skill.created";
|
|
3956
4084
|
}>;
|
|
@@ -5282,8 +5410,10 @@ declare const cloudContract: {
|
|
|
5282
5410
|
"drive.created": "drive.created";
|
|
5283
5411
|
"field.created": "field.created";
|
|
5284
5412
|
"file.created": "file.created";
|
|
5413
|
+
"node.agent_prompts_updated": "node.agent_prompts_updated";
|
|
5285
5414
|
"node.metadata_updated": "node.metadata_updated";
|
|
5286
5415
|
"node.purged": "node.purged";
|
|
5416
|
+
"node.settings_updated": "node.settings_updated";
|
|
5287
5417
|
"record.viewed": "record.viewed";
|
|
5288
5418
|
"skill.created": "skill.created";
|
|
5289
5419
|
}>;
|
|
@@ -6613,8 +6743,10 @@ declare const cloudContract: {
|
|
|
6613
6743
|
"drive.created": "drive.created";
|
|
6614
6744
|
"field.created": "field.created";
|
|
6615
6745
|
"file.created": "file.created";
|
|
6746
|
+
"node.agent_prompts_updated": "node.agent_prompts_updated";
|
|
6616
6747
|
"node.metadata_updated": "node.metadata_updated";
|
|
6617
6748
|
"node.purged": "node.purged";
|
|
6749
|
+
"node.settings_updated": "node.settings_updated";
|
|
6618
6750
|
"record.viewed": "record.viewed";
|
|
6619
6751
|
"skill.created": "skill.created";
|
|
6620
6752
|
}>;
|
|
@@ -7391,7 +7523,7 @@ declare const cloudContract: {
|
|
|
7391
7523
|
};
|
|
7392
7524
|
live: {
|
|
7393
7525
|
subscribe: import("@orpc/contract").ContractProcedure<import("@orpc/contract").Schema<unknown, unknown>, import("@orpc/contract").Schema<AsyncIteratorObject<{
|
|
7394
|
-
kind: "change_request.created" | "change_request.deleted" | "change_request.merged" | "change_request.pending_review" | "change_request.reviewed" | "change_request.updated" | "node.metadata_updated";
|
|
7526
|
+
kind: "change_request.created" | "change_request.deleted" | "change_request.merged" | "change_request.pending_review" | "change_request.reviewed" | "change_request.updated" | "node.metadata_updated" | "node.settings_updated";
|
|
7395
7527
|
spaceId: string;
|
|
7396
7528
|
actorId: string;
|
|
7397
7529
|
changeRequestId: string | null;
|
|
@@ -7401,7 +7533,7 @@ declare const cloudContract: {
|
|
|
7401
7533
|
viewIds: string[];
|
|
7402
7534
|
operationCount: number;
|
|
7403
7535
|
}, unknown, void>, AsyncIteratorClass<{
|
|
7404
|
-
kind: "change_request.created" | "change_request.deleted" | "change_request.merged" | "change_request.pending_review" | "change_request.reviewed" | "change_request.updated" | "node.metadata_updated";
|
|
7536
|
+
kind: "change_request.created" | "change_request.deleted" | "change_request.merged" | "change_request.pending_review" | "change_request.reviewed" | "change_request.updated" | "node.metadata_updated" | "node.settings_updated";
|
|
7405
7537
|
spaceId: string;
|
|
7406
7538
|
actorId: string;
|
|
7407
7539
|
changeRequestId: string | null;
|
|
@@ -12444,10 +12576,10 @@ declare const cloudContract: {
|
|
|
12444
12576
|
nodeId: z.ZodString;
|
|
12445
12577
|
files: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
12446
12578
|
binaryFiles: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
12447
|
-
engine: z.
|
|
12579
|
+
engine: z.ZodEnum<{
|
|
12448
12580
|
local: "local";
|
|
12449
12581
|
remote: "remote";
|
|
12450
|
-
}
|
|
12582
|
+
}>;
|
|
12451
12583
|
}, z.core.$strip>, import("@orpc/contract").Schema<AsyncIteratorObject<{
|
|
12452
12584
|
type: "log";
|
|
12453
12585
|
line: string;
|
|
@@ -15156,8 +15288,17 @@ declare const cloudContract: {
|
|
|
15156
15288
|
textContentHash: z.ZodNullable<z.ZodString>;
|
|
15157
15289
|
byteCount: z.ZodNumber;
|
|
15158
15290
|
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
15291
|
+
exportDocBodies: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
15292
|
+
nodeIds: z.ZodArray<z.ZodString>;
|
|
15293
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
15294
|
+
bodies: z.ZodArray<z.ZodObject<{
|
|
15295
|
+
nodeId: z.ZodString;
|
|
15296
|
+
markdown: z.ZodString;
|
|
15297
|
+
}, z.core.$strip>>;
|
|
15298
|
+
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
15159
15299
|
importBegin: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
15160
15300
|
sourceSpaceId: z.ZodString;
|
|
15301
|
+
resume: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
15161
15302
|
}, z.core.$strip>, z.ZodObject<{
|
|
15162
15303
|
sessionId: z.ZodString;
|
|
15163
15304
|
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
@@ -19411,6 +19552,24 @@ declare const cloudContract: {
|
|
|
19411
19552
|
listPage: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
19412
19553
|
baseId: z.ZodString;
|
|
19413
19554
|
viewId: z.ZodOptional<z.ZodString>;
|
|
19555
|
+
filters: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
19556
|
+
fieldSlug: z.ZodString;
|
|
19557
|
+
fieldType: z.ZodOptional<z.ZodString>;
|
|
19558
|
+
operator: z.ZodEnum<{
|
|
19559
|
+
contains: "contains";
|
|
19560
|
+
equals: "equals";
|
|
19561
|
+
is_empty: "is_empty";
|
|
19562
|
+
is_false: "is_false";
|
|
19563
|
+
is_true: "is_true";
|
|
19564
|
+
not_empty: "not_empty";
|
|
19565
|
+
}>;
|
|
19566
|
+
value: z.ZodOptional<z.ZodUnknown>;
|
|
19567
|
+
}, z.core.$strip>>>;
|
|
19568
|
+
dateRange: z.ZodOptional<z.ZodObject<{
|
|
19569
|
+
fieldSlug: z.ZodString;
|
|
19570
|
+
gte: z.ZodString;
|
|
19571
|
+
lt: z.ZodString;
|
|
19572
|
+
}, z.core.$strip>>;
|
|
19414
19573
|
page: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
19415
19574
|
pageSize: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
19416
19575
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -19637,6 +19796,39 @@ declare const cloudContract: {
|
|
|
19637
19796
|
}, z.core.$strip>>>, z.ZodObject<{
|
|
19638
19797
|
total: z.ZodNumber;
|
|
19639
19798
|
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
19799
|
+
groupBy: import("@orpc/contract").ContractProcedure<z.ZodObject<{
|
|
19800
|
+
baseId: z.ZodString;
|
|
19801
|
+
fieldSlug: z.ZodString;
|
|
19802
|
+
viewId: z.ZodOptional<z.ZodString>;
|
|
19803
|
+
filters: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
19804
|
+
fieldSlug: z.ZodString;
|
|
19805
|
+
fieldType: z.ZodOptional<z.ZodString>;
|
|
19806
|
+
operator: z.ZodEnum<{
|
|
19807
|
+
contains: "contains";
|
|
19808
|
+
equals: "equals";
|
|
19809
|
+
is_empty: "is_empty";
|
|
19810
|
+
is_false: "is_false";
|
|
19811
|
+
is_true: "is_true";
|
|
19812
|
+
not_empty: "not_empty";
|
|
19813
|
+
}>;
|
|
19814
|
+
value: z.ZodOptional<z.ZodUnknown>;
|
|
19815
|
+
}, z.core.$strip>>>;
|
|
19816
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
19817
|
+
groups: z.ZodArray<z.ZodObject<{
|
|
19818
|
+
value: z.ZodNullable<z.ZodString>;
|
|
19819
|
+
count: z.ZodNumber;
|
|
19820
|
+
}, z.core.$strip>>;
|
|
19821
|
+
total: z.ZodNumber;
|
|
19822
|
+
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, import("@orpc/contract").MergedErrorMap<Record<never, never>, {
|
|
19823
|
+
BAD_REQUEST: {
|
|
19824
|
+
status: number;
|
|
19825
|
+
message: string;
|
|
19826
|
+
};
|
|
19827
|
+
NOT_FOUND: {
|
|
19828
|
+
status: number;
|
|
19829
|
+
message: string;
|
|
19830
|
+
};
|
|
19831
|
+
}>>, Record<never, never>>;
|
|
19640
19832
|
get: import("@orpc/contract").ContractProcedure<z.ZodUnion<readonly [z.ZodObject<{
|
|
19641
19833
|
recordId: z.ZodString;
|
|
19642
19834
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -23731,8 +23923,10 @@ declare const activityItemSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
23731
23923
|
"drive.created": "drive.created";
|
|
23732
23924
|
"field.created": "field.created";
|
|
23733
23925
|
"file.created": "file.created";
|
|
23926
|
+
"node.agent_prompts_updated": "node.agent_prompts_updated";
|
|
23734
23927
|
"node.metadata_updated": "node.metadata_updated";
|
|
23735
23928
|
"node.purged": "node.purged";
|
|
23929
|
+
"node.settings_updated": "node.settings_updated";
|
|
23736
23930
|
"record.viewed": "record.viewed";
|
|
23737
23931
|
"skill.created": "skill.created";
|
|
23738
23932
|
}>;
|
|
@@ -24686,7 +24880,7 @@ type BusabaseSourceChannel = "web_ui" | "browser" | "openapi" | "sdk" | "cli" |
|
|
|
24686
24880
|
type ReviewVerdict = "approved" | "rejected";
|
|
24687
24881
|
type SearchResultKind = "record" | "change_request" | "base" | "file" | "node";
|
|
24688
24882
|
type CommentSubjectType = "record" | "change_request" | "operation" | "commit";
|
|
24689
|
-
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";
|
|
24883
|
+
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.settings_updated" | "node.agent_prompts_updated" | "node.purged";
|
|
24690
24884
|
interface UserRefVO {
|
|
24691
24885
|
id: string;
|
|
24692
24886
|
name: string | null;
|
|
@@ -24731,6 +24925,19 @@ interface NodeVO {
|
|
|
24731
24925
|
metadata: Record<string, unknown> & {
|
|
24732
24926
|
version?: string;
|
|
24733
24927
|
};
|
|
24928
|
+
/**
|
|
24929
|
+
* System settings the product DOES read and act on — the opposite of
|
|
24930
|
+
* `metadata` above, which is why they are separate fields with separate
|
|
24931
|
+
* endpoints. Written only by `PATCH /nodes/{nodeId}/settings`, whose input is
|
|
24932
|
+
* a closed schema; the generic metadata endpoint cannot address it.
|
|
24933
|
+
*
|
|
24934
|
+
* Absent (or an absent key) means "unset". For an AirApp's engine that means
|
|
24935
|
+
* "follow the app" — `airapp.json` decides — which is why absence has to stay
|
|
24936
|
+
* distinguishable from any particular value.
|
|
24937
|
+
*/
|
|
24938
|
+
settings?: {
|
|
24939
|
+
airappEngine?: "browser" | "local" | "remote" | null;
|
|
24940
|
+
};
|
|
24734
24941
|
/**
|
|
24735
24942
|
* This node's OWN declared visibility, or null when it inherits from its
|
|
24736
24943
|
* ancestors. A real column rather than a metadata key, because it is the node
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as FileTreeReadFileVO, A as SearchResultKind, At as AttachmentRef, B as VaultRuntimeEnv, C as NodeSearchResultVO, Ct as VIEW_FIELD_MIN_WIDTH, D as ReviewVO, Dt as ViewSortVO, E as OperationVO, Et as ViewFilterVO, F as VaultAccessPolicy, Ft as CREATABLE_NODE_TYPES, G as AssetDetailVO, H as VaultSettingsVO, I as VaultEnvironment, It as CreatableNodeType, J as AssetVO, K as AssetTextStatus, L as VaultItemInput, Lt as NodeType, M as SourceAttributionVO, Mt as cloudContract, N as UserRefVO, Nt as NodeIcon, O as ReviewVerdict, Ot as ViewType, P as UpdateVaultSettingsDTO, Pt as NodeIconSchema, Q as FileTreeNodeVO, R as VaultItemKind, Rt as OperationKind, S as LookupRollup, St as VIEW_FIELD_MAX_WIDTH, T as OperationStatus, Tt as ViewFilterOperator, U as FileNodeMetadata, V as VaultScopeType, W as FileNodeVO, X as GrepResultVO, Y as GrepInputDTO, Z as FileTreeFileVO, _ as ChangeRequestVO, _t as GalleryCardSize, a as createBusabaseClient, at as FormPageSourceVO, b as CommitVO, bt as RecordLinkVO, c as AuditAction, ct as FormThemeVO, d as ChangeRequestBatchFailureVO, dt as ListFormsVO, et as NodeDetailVO, f as ChangeRequestCountsVO, ft as SubmitFormDTO, g as ChangeRequestTargetType, gt as BaseVO, h as ChangeRequestStatus, ht as BaseFieldVO, i as ResolvedConfig, it as FormFieldBindingVO, j as SearchResultVO, jt as CloudContract, k as SearchResponseVO, kt as ViewVO, l as AuditEventVO, lt as FormVO, m as ChangeRequestReviewBatchResultVO, mt as AssetAttachmentRef, n as BusabaseConfig, nt as CreateFormDTO, o as resolveConfig, ot as FormShareVO, p as ChangeRequestMergeBatchResultVO, pt as UpdateFormDTO, q as AssetUsageVO, r as DEFAULT_BASE_URL, rt as FormBoundFieldVO, s as AgentTaskVO, st as FormSubmitResultVO, t as BusabaseClient, tt as ActivityItemVO, u as BusabaseSourceChannel, ut as ListFormsDTO, v as CommentSubjectType, vt as GalleryCoverFit, w as NodeVO, wt as ViewConfigVO, x as FieldType, xt as RecordVO, y as CommentVO, yt as GanttScale, z as VaultItemVO } from "./client-
|
|
1
|
+
import { $ as FileTreeReadFileVO, A as SearchResultKind, At as AttachmentRef, B as VaultRuntimeEnv, C as NodeSearchResultVO, Ct as VIEW_FIELD_MIN_WIDTH, D as ReviewVO, Dt as ViewSortVO, E as OperationVO, Et as ViewFilterVO, F as VaultAccessPolicy, Ft as CREATABLE_NODE_TYPES, G as AssetDetailVO, H as VaultSettingsVO, I as VaultEnvironment, It as CreatableNodeType, J as AssetVO, K as AssetTextStatus, L as VaultItemInput, Lt as NodeType, M as SourceAttributionVO, Mt as cloudContract, N as UserRefVO, Nt as NodeIcon, O as ReviewVerdict, Ot as ViewType, P as UpdateVaultSettingsDTO, Pt as NodeIconSchema, Q as FileTreeNodeVO, R as VaultItemKind, Rt as OperationKind, S as LookupRollup, St as VIEW_FIELD_MAX_WIDTH, T as OperationStatus, Tt as ViewFilterOperator, U as FileNodeMetadata, V as VaultScopeType, W as FileNodeVO, X as GrepResultVO, Y as GrepInputDTO, Z as FileTreeFileVO, _ as ChangeRequestVO, _t as GalleryCardSize, a as createBusabaseClient, at as FormPageSourceVO, b as CommitVO, bt as RecordLinkVO, c as AuditAction, ct as FormThemeVO, d as ChangeRequestBatchFailureVO, dt as ListFormsVO, et as NodeDetailVO, f as ChangeRequestCountsVO, ft as SubmitFormDTO, g as ChangeRequestTargetType, gt as BaseVO, h as ChangeRequestStatus, ht as BaseFieldVO, i as ResolvedConfig, it as FormFieldBindingVO, j as SearchResultVO, jt as CloudContract, k as SearchResponseVO, kt as ViewVO, l as AuditEventVO, lt as FormVO, m as ChangeRequestReviewBatchResultVO, mt as AssetAttachmentRef, n as BusabaseConfig, nt as CreateFormDTO, o as resolveConfig, ot as FormShareVO, p as ChangeRequestMergeBatchResultVO, pt as UpdateFormDTO, q as AssetUsageVO, r as DEFAULT_BASE_URL, rt as FormBoundFieldVO, s as AgentTaskVO, st as FormSubmitResultVO, t as BusabaseClient, tt as ActivityItemVO, u as BusabaseSourceChannel, ut as ListFormsDTO, v as CommentSubjectType, vt as GalleryCoverFit, w as NodeVO, wt as ViewConfigVO, x as FieldType, xt as RecordVO, y as CommentVO, yt as GanttScale, z as VaultItemVO } from "./client-CWlHll4H.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
//#region src/url.d.ts
|
|
4
4
|
/**
|
package/dist/index.js
CHANGED
|
@@ -354,7 +354,7 @@ const LocaleSchema = z.enum({
|
|
|
354
354
|
* - ZH: isIString 接受 JSON 字符串并尝试解析为按语言分布的对象;纯字符串将返回 false。
|
|
355
355
|
*/
|
|
356
356
|
const iStringRecordSchema = z.partialRecord(LocaleSchema, z.string());
|
|
357
|
-
z.union([z.string(), iStringRecordSchema]).describe("i18n string");
|
|
357
|
+
const iStringSchema = z.union([z.string(), iStringRecordSchema]).describe("i18n string");
|
|
358
358
|
//#endregion
|
|
359
359
|
//#region ../../packages/busabase-contract/src/contract/auto-merge.ts
|
|
360
360
|
/**
|
|
@@ -1082,6 +1082,81 @@ const NodeIconSchema = z.discriminatedUnion("type", [z.object({
|
|
|
1082
1082
|
}).optional()
|
|
1083
1083
|
})]);
|
|
1084
1084
|
//#endregion
|
|
1085
|
+
//#region ../../packages/busabase-contract/src/contract/node-agent-prompt-schemas.ts
|
|
1086
|
+
/**
|
|
1087
|
+
* Per-node custom scenario prompts (`node.metadata.agentPrompts`) — the single
|
|
1088
|
+
* schema shared by BOTH write and read paths, per
|
|
1089
|
+
* `apps/busabase-cloud/content/spec/node-agent-prompts-v2.md` §7.3:
|
|
1090
|
+
*
|
|
1091
|
+
* - Write: `busabase-cli nodes set-agent-prompts` validates a file against this
|
|
1092
|
+
* schema client-side, before calling `nodes.updateMetadata` — a malformed file
|
|
1093
|
+
* never reaches the network.
|
|
1094
|
+
* - Read: `buildNodeAgentPrompts` (`packages/busabase-core/.../node-agent-prompts.ts`)
|
|
1095
|
+
* `.safeParse`s whatever is stored in `metadata.agentPrompts` and falls back to
|
|
1096
|
+
* the node type's default scenarios on failure, so a bad write (or a manual
|
|
1097
|
+
* jsonb edit) can never crash the Agent Prompts dialog.
|
|
1098
|
+
*
|
|
1099
|
+
* One schema, one place to edit the limits — do not duplicate this validation on
|
|
1100
|
+
* either side.
|
|
1101
|
+
*/
|
|
1102
|
+
/** Recommended limits from the spec (§7.3) — kept as named constants so a limit
|
|
1103
|
+
* change has exactly one place to edit, and so error messages can cite them. */
|
|
1104
|
+
const CUSTOM_AGENT_PROMPT_LIMITS = {
|
|
1105
|
+
/** Max custom prompts per node. */
|
|
1106
|
+
maxPrompts: 50,
|
|
1107
|
+
/** Max characters per localized `label` value. */
|
|
1108
|
+
maxLabelChars: 80,
|
|
1109
|
+
/** Max bytes (UTF-8) per localized `body` value. */
|
|
1110
|
+
maxBodyBytes: 8192
|
|
1111
|
+
};
|
|
1112
|
+
/** Same intent vocabulary `PromptDef.intent` uses — `change` is the router-side
|
|
1113
|
+
* default when omitted, matching the existing curated-prompt behavior. */
|
|
1114
|
+
const customPromptIntentSchema = z.enum(["read-only", "change"]);
|
|
1115
|
+
const iStringLocaleValues = (value) => typeof value === "string" ? [value] : Object.values(value);
|
|
1116
|
+
/** UTF-8 byte length — `body` includes CJK/JA text, whose per-character byte
|
|
1117
|
+
* cost is not 1, so a character-count limit alone would under-enforce §7.3's
|
|
1118
|
+
* "8 KiB per localized body" budget. */
|
|
1119
|
+
const utf8ByteLength = (value) => new TextEncoder().encode(value).length;
|
|
1120
|
+
const customPromptLabelSchema = iStringSchema.refine((value) => iStringLocaleValues(value).every((v) => v.length <= CUSTOM_AGENT_PROMPT_LIMITS.maxLabelChars), { message: `label must be at most ${CUSTOM_AGENT_PROMPT_LIMITS.maxLabelChars} characters per locale` });
|
|
1121
|
+
const customPromptBodySchema = iStringSchema.refine((value) => iStringLocaleValues(value).every((v) => utf8ByteLength(v) <= CUSTOM_AGENT_PROMPT_LIMITS.maxBodyBytes), { message: `body must be at most ${CUSTOM_AGENT_PROMPT_LIMITS.maxBodyBytes} bytes (UTF-8) per locale` });
|
|
1122
|
+
/**
|
|
1123
|
+
* One custom scenario prompt. `body`'s `{target}` placeholder is substituted at
|
|
1124
|
+
* render time with the same target string `PromptDef.body(target)` receives
|
|
1125
|
+
* today (see `node-agent-prompts.ts`) — this schema does not interpolate it.
|
|
1126
|
+
*/
|
|
1127
|
+
const customPromptDefSchema = z.object({
|
|
1128
|
+
/** Stable id, unique within this node's custom list. */
|
|
1129
|
+
key: z.string().trim().min(1, { message: "key must not be empty" }),
|
|
1130
|
+
/** Defaults to `change` (same default the curated prompts use) so a prompt
|
|
1131
|
+
* cannot silently bypass the approval-first policy by omission. */
|
|
1132
|
+
intent: customPromptIntentSchema.optional(),
|
|
1133
|
+
/** Short title shown in the dialog's left list. */
|
|
1134
|
+
label: customPromptLabelSchema,
|
|
1135
|
+
/** Template text; "{target}" is substituted with the rendered target line. */
|
|
1136
|
+
body: customPromptBodySchema
|
|
1137
|
+
});
|
|
1138
|
+
/**
|
|
1139
|
+
* The full `metadata.agentPrompts` array. `.max` bounds the list; the
|
|
1140
|
+
* `superRefine` catches duplicate keys with an issue path pointing at the
|
|
1141
|
+
* offending entry, so a CLI/server validation error names which entry and
|
|
1142
|
+
* which key collided instead of a bare "keys must be unique".
|
|
1143
|
+
*/
|
|
1144
|
+
const customAgentPromptsSchema = z.array(customPromptDefSchema).max(CUSTOM_AGENT_PROMPT_LIMITS.maxPrompts, { message: `at most ${CUSTOM_AGENT_PROMPT_LIMITS.maxPrompts} custom prompts per node` }).superRefine((prompts, ctx) => {
|
|
1145
|
+
const firstIndexByKey = /* @__PURE__ */ new Map();
|
|
1146
|
+
prompts.forEach((prompt, index) => {
|
|
1147
|
+
const firstIndex = firstIndexByKey.get(prompt.key);
|
|
1148
|
+
if (firstIndex === void 0) {
|
|
1149
|
+
firstIndexByKey.set(prompt.key, index);
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
ctx.addIssue({
|
|
1153
|
+
code: "custom",
|
|
1154
|
+
path: [index, "key"],
|
|
1155
|
+
message: `duplicate key "${prompt.key}" — already used at entry ${firstIndex + 1}`
|
|
1156
|
+
});
|
|
1157
|
+
});
|
|
1158
|
+
});
|
|
1159
|
+
//#endregion
|
|
1085
1160
|
//#region ../../packages/busabase-contract/src/contract/schemas.ts
|
|
1086
1161
|
const nodeSchema = z.lazy(() => z.object({
|
|
1087
1162
|
id: z.string(),
|
|
@@ -1091,6 +1166,7 @@ const nodeSchema = z.lazy(() => z.object({
|
|
|
1091
1166
|
name: z.string(),
|
|
1092
1167
|
description: z.string(),
|
|
1093
1168
|
metadata: z.object({ version: z.string().optional() }).catchall(z.unknown()).default({}),
|
|
1169
|
+
settings: nodeSettingsSchema.default({}),
|
|
1094
1170
|
explicitVisibility: z.enum([
|
|
1095
1171
|
"private",
|
|
1096
1172
|
"workspace",
|
|
@@ -1174,6 +1250,65 @@ const updateNodeMetadataInputSchema = z.object({
|
|
|
1174
1250
|
nodeId: z.string(),
|
|
1175
1251
|
metadata: z.record(z.string(), z.unknown())
|
|
1176
1252
|
});
|
|
1253
|
+
/**
|
|
1254
|
+
* System settings Busabase itself acts on, per node.
|
|
1255
|
+
*
|
|
1256
|
+
* A CLOSED object, unlike `metadata`'s `z.record(z.string(), z.unknown())`.
|
|
1257
|
+
* That difference is the point: `metadata` is the open bag callers put their
|
|
1258
|
+
* own keys in, and its endpoint merges whatever it is handed. Anything the
|
|
1259
|
+
* product *reads and acts on* must not live there — `metadata.visibility` had
|
|
1260
|
+
* to be pulled out into its own column precisely because the generic endpoint
|
|
1261
|
+
* handed a `write`-level actor a door into an ACL input.
|
|
1262
|
+
*
|
|
1263
|
+
* Adding a key here is a deliberate change to this schema, which is what keeps
|
|
1264
|
+
* `PATCH /nodes/{nodeId}/settings` from becoming a second free-form bag.
|
|
1265
|
+
*
|
|
1266
|
+
* `strictObject`, not `object`: zod's default is to STRIP an unknown key, which
|
|
1267
|
+
* would hand a client that misspelled `airappEngine` a 200 and no effect —
|
|
1268
|
+
* exactly the silent failure a closed schema exists to prevent. Verified
|
|
1269
|
+
* against a running server, where the permissive version returned 200.
|
|
1270
|
+
*/
|
|
1271
|
+
const nodeSettingsSchema = z.strictObject({
|
|
1272
|
+
/**
|
|
1273
|
+
* Which engine an AirApp runs on, when a human has chosen.
|
|
1274
|
+
*
|
|
1275
|
+
* `undefined` means "follow the app" — `airapp.json`'s `preferredEngine`
|
|
1276
|
+
* decides, or the default does. A value means somebody overrode it in the
|
|
1277
|
+
* node settings dialog, and it outranks the manifest from then on. So absence
|
|
1278
|
+
* must stay distinguishable from any particular value; `null` clears an
|
|
1279
|
+
* override and returns the node to following the app.
|
|
1280
|
+
*/
|
|
1281
|
+
airappEngine: z.enum([
|
|
1282
|
+
"browser",
|
|
1283
|
+
"local",
|
|
1284
|
+
"remote"
|
|
1285
|
+
]).nullish() });
|
|
1286
|
+
const updateNodeSettingsInputSchema = z.object({
|
|
1287
|
+
nodeId: z.string(),
|
|
1288
|
+
settings: nodeSettingsSchema
|
|
1289
|
+
});
|
|
1290
|
+
/**
|
|
1291
|
+
* This node's custom scenario prompts.
|
|
1292
|
+
*
|
|
1293
|
+
* A separate read from `nodes.get`/`nodes.list` on purpose: the list is capped
|
|
1294
|
+
* at 50 prompts x 8 KiB of body per locale, so carrying it on every node of
|
|
1295
|
+
* every sidebar load is exactly what its own column exists to avoid. The dialog
|
|
1296
|
+
* asks for it when it opens.
|
|
1297
|
+
*
|
|
1298
|
+
* `agentPrompts: null` means "this node has never set any" — distinct from `[]`,
|
|
1299
|
+
* which means "set, and deliberately empty". Both fall back to the node type's
|
|
1300
|
+
* default scenarios in the UI, but only the first is a node nobody has touched.
|
|
1301
|
+
*/
|
|
1302
|
+
const getNodeAgentPromptsInputSchema = z.object({ nodeId: z.string() });
|
|
1303
|
+
const nodeAgentPromptsSchema = z.object({
|
|
1304
|
+
nodeId: z.string(),
|
|
1305
|
+
agentPrompts: customAgentPromptsSchema.nullable()
|
|
1306
|
+
});
|
|
1307
|
+
const updateNodeAgentPromptsInputSchema = z.object({
|
|
1308
|
+
nodeId: z.string(),
|
|
1309
|
+
/** Replaces the whole list — this is not a merge. Send `null` to clear. */
|
|
1310
|
+
agentPrompts: customAgentPromptsSchema.nullable()
|
|
1311
|
+
});
|
|
1177
1312
|
const searchNodesByNameInputSchema = z.object({
|
|
1178
1313
|
query: z.string().min(1),
|
|
1179
1314
|
limit: z.coerce.number().int().min(1).max(50).optional().default(20)
|
|
@@ -1369,7 +1504,8 @@ const liveEventSchema = z.object({
|
|
|
1369
1504
|
"change_request.reviewed",
|
|
1370
1505
|
"change_request.merged",
|
|
1371
1506
|
"change_request.pending_review",
|
|
1372
|
-
"node.metadata_updated"
|
|
1507
|
+
"node.metadata_updated",
|
|
1508
|
+
"node.settings_updated"
|
|
1373
1509
|
]),
|
|
1374
1510
|
spaceId: z.string(),
|
|
1375
1511
|
actorId: z.string(),
|
|
@@ -1400,6 +1536,8 @@ const auditActionSchema = z.enum([
|
|
|
1400
1536
|
"asset.text_written",
|
|
1401
1537
|
"asset.text_marked_none",
|
|
1402
1538
|
"node.metadata_updated",
|
|
1539
|
+
"node.settings_updated",
|
|
1540
|
+
"node.agent_prompts_updated",
|
|
1403
1541
|
"node.purged"
|
|
1404
1542
|
]);
|
|
1405
1543
|
const auditEventSchema = z.object({
|
|
@@ -1818,8 +1956,14 @@ const airAppRunLocalInputSchema = z.object({
|
|
|
1818
1956
|
/** Where the server should run it. `"local"` spawns a bare process on the
|
|
1819
1957
|
* Busabase host (previewable, data bridge via reverse proxy, NOT isolated);
|
|
1820
1958
|
* `"remote"` runs the same lifecycle on a provisioned machine elsewhere.
|
|
1821
|
-
* `"browser"` never reaches this endpoint — it runs entirely in the tab.
|
|
1822
|
-
|
|
1959
|
+
* `"browser"` never reaches this endpoint — it runs entirely in the tab.
|
|
1960
|
+
*
|
|
1961
|
+
* Required, deliberately. This used to default to `"local"`, so a call that
|
|
1962
|
+
* simply omitted the field asked the server to spawn a host process — the
|
|
1963
|
+
* most privileged of the two options, reached by saying nothing. Naming the
|
|
1964
|
+
* engine is now the caller's job, and the handler independently refuses one
|
|
1965
|
+
* this deployment does not offer. */
|
|
1966
|
+
engine: z.enum(["local", "remote"])
|
|
1823
1967
|
});
|
|
1824
1968
|
const airAppRuntimeEventSchema = z.discriminatedUnion("type", [
|
|
1825
1969
|
z.object({
|
|
@@ -2410,6 +2554,41 @@ const listRecordsResponseSchema = z.object({
|
|
|
2410
2554
|
const listRecordsPageInputSchema = z.object({
|
|
2411
2555
|
baseId: z.string().min(1),
|
|
2412
2556
|
viewId: z.string().min(1).optional(),
|
|
2557
|
+
/**
|
|
2558
|
+
* Extra conditions ANDed with the View's own filters — "this View, further
|
|
2559
|
+
* narrowed". The motivating case is one board column: the saved View's
|
|
2560
|
+
* filters plus `stackField equals <choice>`, paged independently of the
|
|
2561
|
+
* other columns.
|
|
2562
|
+
*
|
|
2563
|
+
* Unlike `records.list`'s `filters` (a SUPERSET push-down the client then
|
|
2564
|
+
* narrows), these are applied with the same authority as a saved View's:
|
|
2565
|
+
* every returned page is exactly what the client's own matcher would keep.
|
|
2566
|
+
* That distinction is the whole point — a *superset* page can be missing
|
|
2567
|
+
* records, and a board column that silently drops cards reads as data loss.
|
|
2568
|
+
*/
|
|
2569
|
+
filters: z.array(listRecordsFilterSchema).optional(),
|
|
2570
|
+
/**
|
|
2571
|
+
* Scope the page to records whose `date`/`created_time`/`updated_time` field
|
|
2572
|
+
* falls in `[gte, lt)` — an absolute UTC instant range, not a `filters`
|
|
2573
|
+
* condition. It is deliberately NOT an operator on `listRecordsFilterSchema`:
|
|
2574
|
+
* that model mirrors the client's label-based view-filter matching (see
|
|
2575
|
+
* `recordMatchesViewFilter`), which for a date renders via
|
|
2576
|
+
* `toLocaleDateString()` — meaningless without knowing the viewer's
|
|
2577
|
+
* timezone, which the server never has. A UTC instant range has no such
|
|
2578
|
+
* ambiguity, so it is resolved once here, by the caller (who DOES know the
|
|
2579
|
+
* viewer's timezone), and applied as a real timestamp comparison.
|
|
2580
|
+
*
|
|
2581
|
+
* The motivating case is a Calendar month grid: the client computes the UTC
|
|
2582
|
+
* bounds of its own local 42-day grid and asks for only that slice, instead
|
|
2583
|
+
* of every record in the Base.
|
|
2584
|
+
*/
|
|
2585
|
+
dateRange: z.object({
|
|
2586
|
+
fieldSlug: z.string().min(1),
|
|
2587
|
+
/** Inclusive lower bound, ISO 8601 UTC instant. */
|
|
2588
|
+
gte: z.string(),
|
|
2589
|
+
/** Exclusive upper bound, ISO 8601 UTC instant. */
|
|
2590
|
+
lt: z.string()
|
|
2591
|
+
}).optional(),
|
|
2413
2592
|
page: z.coerce.number().int().min(1).optional().default(1),
|
|
2414
2593
|
pageSize: z.coerce.number().int().min(1).max(100).optional().default(50)
|
|
2415
2594
|
});
|
|
@@ -2454,6 +2633,42 @@ const countRecordsInputSchema = z.object({
|
|
|
2454
2633
|
const countRecordsResponseSchema = z.object({
|
|
2455
2634
|
/** Total active records in the space (optionally scoped to a base). */
|
|
2456
2635
|
total: z.number().int().nonnegative() });
|
|
2636
|
+
const groupRecordsInputSchema = z.object({
|
|
2637
|
+
/** Group within exactly one Base — a field slug is only unambiguous there. */
|
|
2638
|
+
baseId: z.string().min(1),
|
|
2639
|
+
/**
|
|
2640
|
+
* The field to group by. Restricted to `select` and `checkbox`: their stored
|
|
2641
|
+
* value IS the grouping key (a choice id / a boolean), so a SQL GROUP BY
|
|
2642
|
+
* returns exactly the buckets a client would build. Text/number keys would
|
|
2643
|
+
* be truncated at the projection limit, and date keys would bucket by the
|
|
2644
|
+
* server's timezone rather than the viewer's — both would report a
|
|
2645
|
+
* confidently wrong split, so they're rejected instead of approximated.
|
|
2646
|
+
*/
|
|
2647
|
+
fieldSlug: z.string().min(1),
|
|
2648
|
+
/** Group only the rows a saved View would display (its filters; sort ignored). */
|
|
2649
|
+
viewId: z.string().min(1).optional(),
|
|
2650
|
+
/** Ad-hoc filters, ANDed with the View's own when both are given. */
|
|
2651
|
+
filters: z.array(listRecordsFilterSchema).optional()
|
|
2652
|
+
});
|
|
2653
|
+
const groupRecordsResponseSchema = z.object({
|
|
2654
|
+
groups: z.array(z.object({
|
|
2655
|
+
/**
|
|
2656
|
+
* The raw stored key: a `select` choice id, or `"true"`/`"false"` for a
|
|
2657
|
+
* checkbox. For a select, `null` is the bucket of records with no value
|
|
2658
|
+
* (what a Kanban board shows as its "Uncategorized" column). A checkbox
|
|
2659
|
+
* never reports `null` — an unset checkbox counts as `"false"`, matching
|
|
2660
|
+
* how view filters already treat it (`is_false` covers null/undefined).
|
|
2661
|
+
*
|
|
2662
|
+
* Choice LABELS are deliberately not resolved here — the client already
|
|
2663
|
+
* holds the Base's field definitions and renders labels itself, and
|
|
2664
|
+
* returning ids keeps this response stable across a choice rename.
|
|
2665
|
+
*/
|
|
2666
|
+
value: z.string().nullable(),
|
|
2667
|
+
count: z.number().int().nonnegative()
|
|
2668
|
+
})),
|
|
2669
|
+
/** Sum of every group's count — the same number `records.count` would return. */
|
|
2670
|
+
total: z.number().int().nonnegative()
|
|
2671
|
+
});
|
|
2457
2672
|
const createChangeRequestInputSchema = z.object({
|
|
2458
2673
|
fields: z.record(z.string(), z.unknown()).describe("Record field values keyed by field slug. The base's PRIMARY field (its first field) becomes the record's display name and the change request title everywhere — always give it a short, human-readable value, never an id or placeholder."),
|
|
2459
2674
|
message: z.string().optional().default("Initial change request").describe("Explanation shown to the human reviewer. Write a conventional-commit style subject — imperative verb + what + why, e.g. \"Add Acme Corp — qualified lead from the June webinar\"."),
|
|
@@ -2653,7 +2868,7 @@ const recordContract = {
|
|
|
2653
2868
|
path: "/records/page",
|
|
2654
2869
|
tags: ["Records"],
|
|
2655
2870
|
summary: "List a numbered record page",
|
|
2656
|
-
successDescription: "A random-access page of active records. When viewId is supplied, the saved view is authoritatively filtered and sorted before total and page slicing are calculated."
|
|
2871
|
+
successDescription: "A random-access page of active records. When viewId is supplied, the saved view is authoritatively filtered and sorted before total and page slicing are calculated. `dateRange` additionally scopes to a `[gte, lt)` UTC instant window on a date/created_time/updated_time field."
|
|
2657
2872
|
}).input(listRecordsPageInputSchema).output(listRecordsPageResponseSchema),
|
|
2658
2873
|
count: oc.route({
|
|
2659
2874
|
method: "GET",
|
|
@@ -2663,6 +2878,23 @@ const recordContract = {
|
|
|
2663
2878
|
description: "A real SQL COUNT — always the exact total, never a partial or capped number, so it's safe to render as a canonical figure (e.g. a dashboard summary tile). Plain `baseId` scoping is always cheap. Adding `viewId` and/or `filters` is exact too — provably-exact conditions (e.g. text equals/contains, not_empty/is_empty, checkbox is_true/is_false) stay a cheap SQL COUNT; everything else falls back to evaluating every matching row server-side, which is exact but not free on a large Base. Both `viewId` and `filters` require `baseId`.",
|
|
2664
2879
|
successDescription: "Total active records matching the scope: the whole space, one Base, a saved View, an ad-hoc filter set, or a combination."
|
|
2665
2880
|
}).input(countRecordsInputSchema).output(countRecordsResponseSchema),
|
|
2881
|
+
groupBy: oc.route({
|
|
2882
|
+
method: "GET",
|
|
2883
|
+
path: "/records/group-by",
|
|
2884
|
+
tags: ["Records"],
|
|
2885
|
+
summary: "Count records per group",
|
|
2886
|
+
description: "One SQL GROUP BY returning every bucket's exact count — the split a board column header or a summary tile needs, without reading the records themselves. `fieldSlug` must name a `select` or `checkbox` field: their stored value IS the grouping key, so the buckets are exactly the ones a client would build. Grouping by a text, number or date field is rejected rather than approximated (text keys are truncated at the projection limit; date keys would bucket by the server's timezone, not the viewer's). `viewId` and `filters` narrow the set first, with the same exactness rules as `records.count`: provably-exact conditions stay a cheap SQL aggregate, anything else falls back to evaluating every matching row server-side — exact, but not free on a large Base. Groups come back keyed by raw choice id (or `\"true\"`/`\"false\"`), with `null` for records that have no value; labels are the client's to render.",
|
|
2887
|
+
successDescription: "Every group's exact count, plus the total across all groups. Groups with zero records are omitted — a Base's full choice list lives in its field definition, so the client already knows which buckets to render empty."
|
|
2888
|
+
}).errors({
|
|
2889
|
+
BAD_REQUEST: {
|
|
2890
|
+
status: 400,
|
|
2891
|
+
message: "Field is not groupable"
|
|
2892
|
+
},
|
|
2893
|
+
NOT_FOUND: {
|
|
2894
|
+
status: 404,
|
|
2895
|
+
message: "Base or field not found"
|
|
2896
|
+
}
|
|
2897
|
+
}).input(groupRecordsInputSchema).output(groupRecordsResponseSchema),
|
|
2666
2898
|
get: oc.route({
|
|
2667
2899
|
method: "GET",
|
|
2668
2900
|
path: "/records/get",
|
|
@@ -2836,19 +3068,55 @@ const ExportAssetTextVOSchema = z.object({
|
|
|
2836
3068
|
textContentHash: z.string().nullable(),
|
|
2837
3069
|
byteCount: z.number().int().nonnegative()
|
|
2838
3070
|
});
|
|
2839
|
-
const
|
|
3071
|
+
const ExportDocBodiesInputSchema = z.object({ nodeIds: z.array(z.string()).min(1).max(25) });
|
|
3072
|
+
const ExportDocBodiesVOSchema = z.object({
|
|
2840
3073
|
/**
|
|
2841
|
-
*
|
|
2842
|
-
*
|
|
2843
|
-
*
|
|
2844
|
-
*
|
|
2845
|
-
*
|
|
2846
|
-
* works when that row happens to land in the SAME batch as its children,
|
|
2847
|
-
* which cursor pagination (id-ordered, not tree-ordered) does not
|
|
2848
|
-
* guarantee once a space has more nodes than one page. See the matching
|
|
2849
|
-
* comment in `import-logic.ts`.
|
|
3074
|
+
* One entry per requested node that is a Doc in this space. A node id that
|
|
3075
|
+
* does not resolve is simply absent (not an error): the caller asked for a
|
|
3076
|
+
* batch, and one bad id must not cost it the other 24. A Doc that exists but
|
|
3077
|
+
* has no body object yet yields `markdown: ""`, matching what a read through
|
|
3078
|
+
* the Doc domain would return.
|
|
2850
3079
|
*/
|
|
2851
|
-
|
|
3080
|
+
bodies: z.array(z.object({
|
|
3081
|
+
nodeId: z.string(),
|
|
3082
|
+
markdown: z.string()
|
|
3083
|
+
})) });
|
|
3084
|
+
const ImportBeginInputSchema = z.object({
|
|
3085
|
+
/**
|
|
3086
|
+
* The space id the archive was ORIGINALLY exported from (`manifest.spaceId`
|
|
3087
|
+
* in the `.bbdump`, already integrity-verified before this is called).
|
|
3088
|
+
* `importTableRows`'s "nodes" handling needs this to recognize the
|
|
3089
|
+
* archive's own root-node row deterministically (`rootNodeIdForSpace`) —
|
|
3090
|
+
* scanning each batch's rows for "the one with a null `parentId`" only
|
|
3091
|
+
* works when that row happens to land in the SAME batch as its children,
|
|
3092
|
+
* which cursor pagination (id-ordered, not tree-ordered) does not
|
|
3093
|
+
* guarantee once a space has more nodes than one page. See the matching
|
|
3094
|
+
* comment in `import-logic.ts`.
|
|
3095
|
+
*/
|
|
3096
|
+
sourceSpaceId: z.string(),
|
|
3097
|
+
/**
|
|
3098
|
+
* Continue a restore that was interrupted partway through, instead of
|
|
3099
|
+
* requiring an empty space.
|
|
3100
|
+
*
|
|
3101
|
+
* A restore that FAILS rolls itself back (`importAbort`), so the target is
|
|
3102
|
+
* left clean and a plain re-run works. What cannot roll itself back is a
|
|
3103
|
+
* restore whose process died — Ctrl-C, OOM, a dropped connection, the
|
|
3104
|
+
* machine rebooting. That leaves the space holding however many of the
|
|
3105
|
+
* archive's rows had landed, and every subsequent attempt is refused
|
|
3106
|
+
* ("requires an empty target space") with no way forward except wiping it.
|
|
3107
|
+
*
|
|
3108
|
+
* In this mode the empty-space guard is skipped and inserts become
|
|
3109
|
+
* `ON CONFLICT DO NOTHING`, so replaying the same archive re-lands only what
|
|
3110
|
+
* is missing. Blobs and doc bodies are content-addressed writes to object
|
|
3111
|
+
* storage and were already idempotent.
|
|
3112
|
+
*
|
|
3113
|
+
* DANGEROUS if pointed at the wrong space: rows that collide are silently
|
|
3114
|
+
* skipped rather than reported, so restoring archive A into a space holding
|
|
3115
|
+
* archive B's data would interleave the two instead of refusing. Only pass
|
|
3116
|
+
* it to continue the SAME archive into the SAME space.
|
|
3117
|
+
*/
|
|
3118
|
+
resume: z.boolean().optional().default(false)
|
|
3119
|
+
});
|
|
2852
3120
|
const ImportBeginVOSchema = z.object({ sessionId: z.string() });
|
|
2853
3121
|
/**
|
|
2854
3122
|
* `docBodies`, `attachmentBlobs` and `assetTextBlobs` are pseudo-tables: doc
|
|
@@ -2906,6 +3174,13 @@ const dumpContract = {
|
|
|
2906
3174
|
summary: "Resolve the download URL for one asset's extracted-text object",
|
|
2907
3175
|
successDescription: "A resolved download URL for the asset's DERIVED text blob (`asset-texts/blobs/sha256/…`) 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)."
|
|
2908
3176
|
}).input(ExportAssetTextInputSchema).output(ExportAssetTextVOSchema),
|
|
3177
|
+
exportDocBodies: oc.route({
|
|
3178
|
+
method: "POST",
|
|
3179
|
+
path: "/dump/export/doc-bodies",
|
|
3180
|
+
tags: ["Dump"],
|
|
3181
|
+
summary: "Read the raw markdown for a batch of Doc nodes",
|
|
3182
|
+
successDescription: "The raw body behind each requested Doc, read straight from object storage — archived Docs included, which the ordinary `nodes.get` deliberately refuses. Ids that do not resolve to a Doc in this space are omitted rather than failing the batch."
|
|
3183
|
+
}).input(ExportDocBodiesInputSchema).output(ExportDocBodiesVOSchema),
|
|
2909
3184
|
importBegin: oc.route({
|
|
2910
3185
|
method: "POST",
|
|
2911
3186
|
path: "/dump/import/begin",
|
|
@@ -4458,6 +4733,27 @@ const busabaseContractRoutes = {
|
|
|
4458
4733
|
summary: "Update node metadata",
|
|
4459
4734
|
successDescription: "Shallow-merged the supplied top-level keys into the active node's existing metadata. Requires write access on the node. Node CONTENT (a Doc body, or a whiteboard/workflow/html document) does not go through here — use PUT /nodes/{nodeId}/content instead."
|
|
4460
4735
|
}).input(updateNodeMetadataInputSchema).output(nodeSchema),
|
|
4736
|
+
updateSettings: oc.route({
|
|
4737
|
+
method: "PATCH",
|
|
4738
|
+
path: "/nodes/{nodeId}/settings",
|
|
4739
|
+
tags: ["Nodes"],
|
|
4740
|
+
summary: "Update node system settings",
|
|
4741
|
+
successDescription: "Replaced the node's system settings. Unlike metadata this is a closed set of keys Busabase itself acts on, so an unknown key is rejected rather than stored. Send a key as null to clear it — for an AirApp's engine that returns the node to following its airapp.json. Requires write access on the node."
|
|
4742
|
+
}).input(updateNodeSettingsInputSchema).output(nodeSchema),
|
|
4743
|
+
getAgentPrompts: oc.route({
|
|
4744
|
+
method: "GET",
|
|
4745
|
+
path: "/nodes/{nodeId}/agent-prompts",
|
|
4746
|
+
tags: ["Nodes"],
|
|
4747
|
+
summary: "Get node custom agent prompts",
|
|
4748
|
+
successDescription: "This node's custom scenario prompts, which replace the node type's default prompts in the Ask-agent dialog. `null` means the node has never had any set, which is not the same as an empty list. Read separately from the node itself because the list is large enough (50 prompts x 8 KiB per locale) that carrying it on every node listing would be its own problem. Requires read access on the node."
|
|
4749
|
+
}).input(getNodeAgentPromptsInputSchema).output(nodeAgentPromptsSchema),
|
|
4750
|
+
updateAgentPrompts: oc.route({
|
|
4751
|
+
method: "PUT",
|
|
4752
|
+
path: "/nodes/{nodeId}/agent-prompts",
|
|
4753
|
+
tags: ["Nodes"],
|
|
4754
|
+
summary: "Replace node custom agent prompts",
|
|
4755
|
+
successDescription: "Replaced this node's custom scenario prompts — the whole list, not a merge. Send `null` to clear them and return the node to its type's default prompts. Requires write access on the node."
|
|
4756
|
+
}).input(updateNodeAgentPromptsInputSchema).output(nodeAgentPromptsSchema),
|
|
4461
4757
|
updateContent: oc.route({
|
|
4462
4758
|
method: "PUT",
|
|
4463
4759
|
path: "/nodes/{nodeId}/content",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "busa-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.0",
|
|
4
4
|
"description": "Typed TypeScript/JavaScript SDK for the Busabase OpenAPI REST API. Talks to a local or remote `busabase server` (or Busabase Cloud). Short-name alias for busabase-sdk.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/busabase/busabase/tree/main/apps/busabase-sdk",
|