busa-cli 0.9.3 → 0.9.5
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/{chunk-C5BGRNMU.js → chunk-N6NMNVQT.js} +133 -7
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
|
@@ -792,6 +792,34 @@ async function uploadAsset(config, opts) {
|
|
|
792
792
|
size: file.byteLength
|
|
793
793
|
};
|
|
794
794
|
}
|
|
795
|
+
var INLINE_TEXT_MAX_BYTES = 1024 * 1024;
|
|
796
|
+
async function putTextCommand(client, opts) {
|
|
797
|
+
const assetId = opts.assetId;
|
|
798
|
+
const text = opts.file ? readFileSync2(opts.file, "utf8") : opts.text;
|
|
799
|
+
if (opts.none) {
|
|
800
|
+
return client.assets.putText({ assetId, none: true });
|
|
801
|
+
}
|
|
802
|
+
if (text === void 0) {
|
|
803
|
+
throw new Error("Provide --text <string>, --file <path>, or --none.");
|
|
804
|
+
}
|
|
805
|
+
const sizeBytes = Buffer.byteLength(text, "utf8");
|
|
806
|
+
if (sizeBytes <= INLINE_TEXT_MAX_BYTES) {
|
|
807
|
+
return client.assets.putText({ assetId, text });
|
|
808
|
+
}
|
|
809
|
+
const upload = await client.assets.createTextUploadUrl({ assetId, sizeBytes });
|
|
810
|
+
const uploadResponse = await fetch(upload.uploadUrl, {
|
|
811
|
+
method: "PUT",
|
|
812
|
+
headers: { "content-type": "text/plain; charset=utf-8" },
|
|
813
|
+
body: text
|
|
814
|
+
});
|
|
815
|
+
if (!uploadResponse.ok) {
|
|
816
|
+
const body = await uploadResponse.text();
|
|
817
|
+
throw new Error(
|
|
818
|
+
`Text byte upload failed (${uploadResponse.status} ${uploadResponse.statusText})${body ? `: ${body}` : ""}`
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
return client.assets.putText({ assetId, storageKey: upload.storageKey });
|
|
822
|
+
}
|
|
795
823
|
function runAction(state, handler) {
|
|
796
824
|
return async (_opts, cmd) => {
|
|
797
825
|
const opts = cmd.optsWithGlobals();
|
|
@@ -840,9 +868,12 @@ function classifyKind(inner) {
|
|
|
840
868
|
return { kind: "json" };
|
|
841
869
|
}
|
|
842
870
|
function inputFields(inputSchema) {
|
|
871
|
+
if (inputSchema === void 0) return [];
|
|
843
872
|
const { inner } = unwrapSchema(inputSchema);
|
|
844
873
|
const shape = inner?.shape ?? (inner?.def?.type === "object" ? inner.def.shape : void 0);
|
|
845
|
-
if (!shape || typeof shape !== "object")
|
|
874
|
+
if (!shape || typeof shape !== "object") {
|
|
875
|
+
return [{ key: "input", kind: "json", required: true, root: true }];
|
|
876
|
+
}
|
|
846
877
|
const fields = [];
|
|
847
878
|
for (const [key, sub] of Object.entries(shape)) {
|
|
848
879
|
const { inner: unwrapped, optional } = unwrapSchema(sub);
|
|
@@ -900,13 +931,15 @@ function registerGeneratedCommands(program, state) {
|
|
|
900
931
|
OpenAPI: ${route.method} ${route.path}`);
|
|
901
932
|
leaf.action(
|
|
902
933
|
runAction(state, (client, opts) => {
|
|
903
|
-
|
|
934
|
+
let input = {};
|
|
904
935
|
for (const f of fields) {
|
|
905
936
|
if (GLOBAL_LONG_FLAGS.has(`--${kebab(f.key)}`)) continue;
|
|
906
937
|
const optKey = f.kind === "json" ? `${f.key}Json` : f.key;
|
|
907
938
|
const value = opts[optKey];
|
|
908
939
|
if (value === void 0) continue;
|
|
909
|
-
|
|
940
|
+
const parsed = f.kind === "json" ? parseJsonValue(value, `${kebab(f.key)}-json`) : value;
|
|
941
|
+
if (f.root) input = parsed;
|
|
942
|
+
else input[f.key] = parsed;
|
|
910
943
|
}
|
|
911
944
|
let target = client;
|
|
912
945
|
for (const segment of navPath) target = target[segment];
|
|
@@ -1056,6 +1089,28 @@ Examples:
|
|
|
1056
1089
|
});
|
|
1057
1090
|
})
|
|
1058
1091
|
);
|
|
1092
|
+
addGlobalFlags(nodes.command("move")).description("Move or reorder a node (applied immediately, no review needed)").requiredOption("--node-id <id>", "node id to move").option("--parent-node-id <id>", "new parent folder node id; omit to keep the current parent").option(
|
|
1093
|
+
"--position <n>",
|
|
1094
|
+
"new position among the target parent's children",
|
|
1095
|
+
(v) => Number.parseInt(v, 10)
|
|
1096
|
+
).option("--message <text>", "Change Request message").option("--submitted-by <name>", "producer label").addHelpText(
|
|
1097
|
+
"after",
|
|
1098
|
+
`
|
|
1099
|
+
Examples:
|
|
1100
|
+
busabase-cli nodes move --node-id nod_123 --position 0
|
|
1101
|
+
busabase-cli nodes move --node-id nod_123 --parent-node-id nod_456 --position 2`
|
|
1102
|
+
).action(
|
|
1103
|
+
runAction(
|
|
1104
|
+
state,
|
|
1105
|
+
(client, opts) => client.nodes.move({
|
|
1106
|
+
nodeId: opts.nodeId,
|
|
1107
|
+
parentNodeId: opts.parentNodeId,
|
|
1108
|
+
position: opts.position,
|
|
1109
|
+
message: opts.message,
|
|
1110
|
+
submittedBy: opts.submittedBy
|
|
1111
|
+
})
|
|
1112
|
+
)
|
|
1113
|
+
);
|
|
1059
1114
|
const bases = program.command("bases").description("Bases (structured tables)");
|
|
1060
1115
|
addGlobalFlags(bases.command("list")).description("List Bases in the active space").action(runAction(state, (client) => client.bases.list()));
|
|
1061
1116
|
addGlobalFlags(bases.command("get")).description("Get one Base by slug").requiredOption("--slug <slug>", "Base slug").action(
|
|
@@ -1066,12 +1121,16 @@ Examples:
|
|
|
1066
1121
|
return found;
|
|
1067
1122
|
})
|
|
1068
1123
|
);
|
|
1069
|
-
addGlobalFlags(bases.command("create")).description("Create a Base").requiredOption("--slug <slug>", "Base slug").requiredOption("--name <name>", "Base name").option("--field <slug:name:type...>", "field definition, repeatable").option("--fields-json <json|@file>", "field definitions as JSON array").option("--description <text>", "optional description").option("--parent-node-id <id>", "parent folder node id; omit for root").
|
|
1124
|
+
addGlobalFlags(bases.command("create")).description("Create a Base \u2014 review-first by default: returns a pending Change Request").requiredOption("--slug <slug>", "Base slug").requiredOption("--name <name>", "Base name").option("--field <slug:name:type...>", "field definition, repeatable").option("--fields-json <json|@file>", "field definitions as JSON array").option("--description <text>", "optional description").option("--parent-node-id <id>", "parent folder node id; omit for root").option(
|
|
1125
|
+
"--auto-merge",
|
|
1126
|
+
"skip review and create the Base immediately (default: propose a pending Change Request)"
|
|
1127
|
+
).addHelpText(
|
|
1070
1128
|
"after",
|
|
1071
1129
|
`
|
|
1072
1130
|
Examples:
|
|
1073
1131
|
busabase-cli bases create --slug products --name "\u4EA7\u54C1\u76EE\u5F55 Products" --field product_name:"Product Name":text
|
|
1074
|
-
busabase-cli bases create --slug products --name "\u4EA7\u54C1\u76EE\u5F55 Products" --fields-json @fields.json
|
|
1132
|
+
busabase-cli bases create --slug products --name "\u4EA7\u54C1\u76EE\u5F55 Products" --fields-json @fields.json
|
|
1133
|
+
busabase-cli bases create --slug products --name "Products" --auto-merge # skip review, create immediately`
|
|
1075
1134
|
).action(
|
|
1076
1135
|
runAction(
|
|
1077
1136
|
state,
|
|
@@ -1080,7 +1139,8 @@ Examples:
|
|
|
1080
1139
|
name: opts.name,
|
|
1081
1140
|
description: opts.description,
|
|
1082
1141
|
parentNodeId: opts.parentNodeId,
|
|
1083
|
-
fields: parseFieldDefinitions(opts)
|
|
1142
|
+
fields: parseFieldDefinitions(opts),
|
|
1143
|
+
...opts.autoMerge ? { autoMerge: true } : {}
|
|
1084
1144
|
})
|
|
1085
1145
|
)
|
|
1086
1146
|
);
|
|
@@ -1233,6 +1293,37 @@ Examples:
|
|
|
1233
1293
|
})
|
|
1234
1294
|
)
|
|
1235
1295
|
);
|
|
1296
|
+
addGlobalFlags(program.command("grep")).description(
|
|
1297
|
+
"Search files, Docs, and Base records with one pattern (unified grep; use `assets grep` for files-only)"
|
|
1298
|
+
).requiredOption("--pattern <regex>", "literal or regex pattern").option("--flags <flags>", 'RegExp flags, e.g. "i" for case-insensitive').option(
|
|
1299
|
+
"--sources <sources...>",
|
|
1300
|
+
'sources to scan: "files", "docs", and/or "records" (default: all three)'
|
|
1301
|
+
).option("--asset-ids <ids...>", "files scope: specific asset ids").option("--drive-path <path>", "files scope: Drive/Skill mounted path prefix").option("--mime-types <types...>", "files scope: MIME types").option("--node-ids <ids...>", "docs scope: specific Doc node ids").option("--base-ids <ids...>", "records scope: specific Base ids").option("--base-slugs <slugs...>", "records scope: specific Base slugs").option(
|
|
1302
|
+
"--max-matches <n>",
|
|
1303
|
+
"max matches, shared across sources (default 100, cap 1000)",
|
|
1304
|
+
parsePositiveInt
|
|
1305
|
+
).option("--context-lines <n>", "lines of before/after context (default 0, cap 10)", parseNum).action(
|
|
1306
|
+
runAction(state, (client, opts) => {
|
|
1307
|
+
const filesScope = opts.assetIds || opts.drivePath || opts.mimeTypes ? {
|
|
1308
|
+
assetIds: opts.assetIds,
|
|
1309
|
+
drivePath: opts.drivePath,
|
|
1310
|
+
mimeTypes: opts.mimeTypes
|
|
1311
|
+
} : void 0;
|
|
1312
|
+
const docsScope = opts.nodeIds ? { nodeIds: opts.nodeIds } : void 0;
|
|
1313
|
+
const recordsScope = opts.baseIds || opts.baseSlugs ? {
|
|
1314
|
+
baseIds: opts.baseIds,
|
|
1315
|
+
baseSlugs: opts.baseSlugs
|
|
1316
|
+
} : void 0;
|
|
1317
|
+
return client.grep({
|
|
1318
|
+
pattern: opts.pattern,
|
|
1319
|
+
flags: opts.flags,
|
|
1320
|
+
sources: opts.sources,
|
|
1321
|
+
scope: filesScope || docsScope || recordsScope ? { files: filesScope, docs: docsScope, records: recordsScope } : void 0,
|
|
1322
|
+
maxMatches: opts.maxMatches,
|
|
1323
|
+
contextLines: opts.contextLines
|
|
1324
|
+
});
|
|
1325
|
+
})
|
|
1326
|
+
);
|
|
1236
1327
|
const addUploadCommand = (parent, hidden = false) => addGlobalFlags(parent.command("upload", { noHelp: hidden })).description("Upload a file and print an asset ref for record fields").requiredOption("--file <path>", "local file to upload").option("--file-name <name>", "stored file name (default: basename of --file)").option("--mime-type <mime>", "MIME type (default: inferred from extension)").option("--context <value>", "upload context (default record-field)").addHelpText(
|
|
1237
1328
|
"after",
|
|
1238
1329
|
`
|
|
@@ -1241,7 +1332,42 @@ Example:
|
|
|
1241
1332
|
|
|
1242
1333
|
Use the JSON output directly in an attachment field value, e.g. {"cover_image":[<output>]}.`
|
|
1243
1334
|
).action(runAction(state, (_client, opts, config) => uploadAsset(config, opts)));
|
|
1244
|
-
|
|
1335
|
+
const assetsCommand = program.command("assets").description("Assets");
|
|
1336
|
+
addUploadCommand(assetsCommand);
|
|
1337
|
+
addGlobalFlags(assetsCommand.command("put-text")).description("Write (or mark none) an asset's Drive Grep Retrieval text slot").requiredOption("--asset-id <id>", "asset id").option("--text <string>", "inline text (\u22641MB)").option("--file <path>", "read text from a local file instead of --text").option("--none", "mark as having no extractable text (e.g. a scanned, image-only PDF)").addHelpText(
|
|
1338
|
+
"after",
|
|
1339
|
+
`
|
|
1340
|
+
Examples:
|
|
1341
|
+
busabase-cli assets put-text --asset-id ast_123 --file ./extracted.txt
|
|
1342
|
+
busabase-cli assets put-text --asset-id ast_123 --text "plain text"
|
|
1343
|
+
busabase-cli assets put-text --asset-id ast_123 --none`
|
|
1344
|
+
).action(runAction(state, (client, opts) => putTextCommand(client, opts)));
|
|
1345
|
+
addGlobalFlags(assetsCommand.command("grep")).description("Search every text-bearing asset in scope").requiredOption("--pattern <regex>", "literal or regex pattern").option("--flags <flags>", 'RegExp flags, e.g. "i" for case-insensitive').option("--asset-ids <ids...>", "scope: specific asset ids").option("--drive-path <path>", "scope: Drive/Skill mounted path prefix").option("--mime-types <types...>", "scope: MIME types").option("--max-matches <n>", "max matches (default 100, cap 1000)", parsePositiveInt).option("--context-lines <n>", "lines of before/after context (default 0, cap 10)", parseNum).action(
|
|
1346
|
+
runAction(
|
|
1347
|
+
state,
|
|
1348
|
+
(client, opts) => client.assets.grep({
|
|
1349
|
+
pattern: opts.pattern,
|
|
1350
|
+
flags: opts.flags,
|
|
1351
|
+
scope: opts.assetIds || opts.drivePath || opts.mimeTypes ? {
|
|
1352
|
+
assetIds: opts.assetIds,
|
|
1353
|
+
drivePath: opts.drivePath,
|
|
1354
|
+
mimeTypes: opts.mimeTypes
|
|
1355
|
+
} : void 0,
|
|
1356
|
+
maxMatches: opts.maxMatches,
|
|
1357
|
+
contextLines: opts.contextLines
|
|
1358
|
+
})
|
|
1359
|
+
)
|
|
1360
|
+
);
|
|
1361
|
+
addGlobalFlags(assetsCommand.command("read-lines")).description("Read an exact line range from an asset's text (range capped at 2000 lines)").requiredOption("--asset-id <id>", "asset id").requiredOption("--start-line <n>", "first line (1-based)", parsePositiveInt).requiredOption("--end-line <n>", "last line (1-based)", parsePositiveInt).action(
|
|
1362
|
+
runAction(
|
|
1363
|
+
state,
|
|
1364
|
+
(client, opts) => client.assets.readTextLines({
|
|
1365
|
+
assetId: opts.assetId,
|
|
1366
|
+
startLine: opts.startLine,
|
|
1367
|
+
endLine: opts.endLine
|
|
1368
|
+
})
|
|
1369
|
+
)
|
|
1370
|
+
);
|
|
1245
1371
|
addGlobalFlags(program.command("api")).description("Raw request to any /api/v1 endpoint").addOption(
|
|
1246
1372
|
new Option("--method <get|post|put|delete>", "HTTP method").choices(["get", "post", "put", "delete"]).makeOptionMandatory()
|
|
1247
1373
|
).requiredOption("--path <p>", "path under /api/v1, e.g. /bases").option("--query <k=v...>", "query-string param, repeatable").option("--body-json <json>", "JSON request body").action(
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "busa-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"description": "Command-line client for the Busabase OpenAPI REST API. Talks to a local or remote `busabase server`. Short-name alias for busabase-cli.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/busabase/busabase/tree/main/apps/busabase-cli",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"README.md"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"busabase-sdk": "0.9.
|
|
34
|
+
"busabase-sdk": "0.9.5",
|
|
35
35
|
"commander": "^14.0.0"
|
|
36
36
|
},
|
|
37
37
|
"engines": {
|