orizu 0.0.6 → 0.0.7
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.js +87 -3
- package/package.json +1 -1
- package/src/index.ts +115 -3
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { parseDatasetReference } from './dataset-download.js';
|
|
|
12
12
|
import { parseGlobalFlags } from './global-flags.js';
|
|
13
13
|
import { authedFetch, getBaseUrl, setGlobalFlags } from './http.js';
|
|
14
14
|
function printUsage() {
|
|
15
|
-
console.log(`orizu global options:\n\n --local Use http://localhost:3000\n --server <url> Use a specific server origin (for example: https://preview.example.com)\n\norizu commands:\n\n orizu login\n orizu logout\n orizu whoami\n orizu teams list\n orizu teams create [--name <name>]\n orizu teams members list [--team <teamSlug>]\n orizu teams members add --email <email> [--team <teamSlug>]\n orizu teams members remove --email <email> [--team <teamSlug>]\n orizu teams members role --team <teamSlug> --email <email> --role <admin|member>\n orizu projects list [--team <teamSlug>]\n orizu projects create --name <name> [--team <teamSlug>]\n orizu apps list [--project <team/project>]\n orizu apps create --project <team/project> --name <name> --dataset <datasetId> --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps update [--app <appId>] [--project <team/project>] --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps link-dataset --dataset <datasetId> [--app <appId>] [--project <team/project>] [--version <n>]\n orizu tasks list [--project <team/project>]\n orizu tasks create --project <team/project> --dataset <datasetId> --app <appId> --title <title> --assignees <userId1,userId2> [--instructions <text>] [--labels-per-item <n>]\n orizu tasks assign --task <taskId> --assignees <userId1,userId2>\n orizu tasks status --task <taskId> [--json]\n orizu datasets upload --file <path> [--project <team/project>] [--name <name>]\n orizu datasets download [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--format <csv|json|jsonl>] [--out <path>]\n orizu tasks export [--task <taskId>] [--format <csv|json|jsonl>] [--out <path>]`);
|
|
15
|
+
console.log(`orizu global options:\n\n --local Use http://localhost:3000\n --server <url> Use a specific server origin (for example: https://preview.example.com)\n\norizu commands:\n\n orizu login\n orizu logout\n orizu whoami\n orizu teams list\n orizu teams create [--name <name>]\n orizu teams members list [--team <teamSlug>]\n orizu teams members add --email <email> [--team <teamSlug>]\n orizu teams members remove --email <email> [--team <teamSlug>]\n orizu teams members role --team <teamSlug> --email <email> --role <admin|member>\n orizu projects list [--team <teamSlug>]\n orizu projects create --name <name> [--team <teamSlug>]\n orizu apps list [--project <team/project>]\n orizu apps create --project <team/project> --name <name> --dataset <datasetId> --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps update [--app <appId>] [--project <team/project>] --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps link-dataset --dataset <datasetId> [--app <appId>] [--project <team/project>] [--version <n>]\n orizu tasks list [--project <team/project>]\n orizu tasks create --project <team/project> --dataset <datasetId> --app <appId> --title <title> --assignees <userId1,userId2> [--instructions <text>] [--labels-per-item <n>]\n orizu tasks assign --task <taskId> --assignees <userId1,userId2>\n orizu tasks status --task <taskId> [--json]\n orizu datasets upload --file <path> [--project <team/project>] [--name <name>]\n orizu datasets download [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--format <csv|json|jsonl>] [--out <path>]\n orizu datasets append [--dataset <datasetId|datasetUrl>] [--project <team/project>] --file <path>\n orizu datasets delete-rows [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--row-ids <id1,id2>] [--row-indices <n1,n2>]\n orizu tasks export [--task <taskId>] [--format <csv|json|jsonl>] [--out <path>]`);
|
|
16
16
|
}
|
|
17
17
|
let cliArgs = process.argv.slice(2);
|
|
18
18
|
function getArg(name) {
|
|
@@ -792,7 +792,7 @@ async function uploadDataset() {
|
|
|
792
792
|
console.log(`View dataset: ${formatTerminalLink(data.dataset.url)}`);
|
|
793
793
|
}
|
|
794
794
|
}
|
|
795
|
-
function
|
|
795
|
+
function getDatasetReferenceInput() {
|
|
796
796
|
const fromFlag = getArg('--dataset');
|
|
797
797
|
if (fromFlag) {
|
|
798
798
|
return fromFlag;
|
|
@@ -805,7 +805,7 @@ function getDatasetDownloadInput() {
|
|
|
805
805
|
}
|
|
806
806
|
async function downloadDataset() {
|
|
807
807
|
const projectArg = getArg('--project');
|
|
808
|
-
const datasetInput =
|
|
808
|
+
const datasetInput = getDatasetReferenceInput();
|
|
809
809
|
const format = (getArg('--format') || 'jsonl');
|
|
810
810
|
const outPathArg = getArg('--out');
|
|
811
811
|
if (!['csv', 'json', 'jsonl'].includes(format)) {
|
|
@@ -830,6 +830,82 @@ async function downloadDataset() {
|
|
|
830
830
|
writeFileSync(filename, bytes);
|
|
831
831
|
console.log(`Saved dataset ${datasetId} (${format.toUpperCase()}) to ${filename}`);
|
|
832
832
|
}
|
|
833
|
+
async function appendDatasetRows() {
|
|
834
|
+
const projectArg = getArg('--project');
|
|
835
|
+
const datasetInput = getDatasetReferenceInput();
|
|
836
|
+
const fileArg = getArg('--file');
|
|
837
|
+
if (!fileArg) {
|
|
838
|
+
throw new Error('Usage: orizu datasets append [--dataset <datasetId|datasetUrl>] [--project <team/project>] --file <path>');
|
|
839
|
+
}
|
|
840
|
+
let datasetId;
|
|
841
|
+
if (datasetInput) {
|
|
842
|
+
datasetId = parseDatasetReference(datasetInput).datasetId;
|
|
843
|
+
}
|
|
844
|
+
else {
|
|
845
|
+
const selected = await selectDatasetInteractively(projectArg);
|
|
846
|
+
datasetId = selected.datasetId;
|
|
847
|
+
}
|
|
848
|
+
const file = expandHomePath(fileArg);
|
|
849
|
+
const { rows } = parseDatasetFile(file);
|
|
850
|
+
if (!Array.isArray(rows) || rows.length === 0) {
|
|
851
|
+
throw new Error('Dataset append file must contain at least one row');
|
|
852
|
+
}
|
|
853
|
+
const response = await authedFetch(`/api/cli/datasets/${encodeURIComponent(datasetId)}/rows`, {
|
|
854
|
+
method: 'POST',
|
|
855
|
+
headers: { 'Content-Type': 'application/json' },
|
|
856
|
+
body: JSON.stringify({ rows }),
|
|
857
|
+
});
|
|
858
|
+
if (!response.ok) {
|
|
859
|
+
throw new Error(`Append failed: ${await response.text()}`);
|
|
860
|
+
}
|
|
861
|
+
const data = await parseJsonResponse(response, 'Dataset append');
|
|
862
|
+
console.log(`Appended ${data.appendedCount} rows to dataset ${data.dataset.name} (${data.dataset.id}). New row count: ${data.dataset.rowCount}`);
|
|
863
|
+
}
|
|
864
|
+
function parseCommaSeparatedIntegers(value) {
|
|
865
|
+
if (!value) {
|
|
866
|
+
return [];
|
|
867
|
+
}
|
|
868
|
+
const rawItems = value
|
|
869
|
+
.split(',')
|
|
870
|
+
.map(item => item.trim())
|
|
871
|
+
.filter(Boolean);
|
|
872
|
+
const parsed = rawItems.map(item => Number(item));
|
|
873
|
+
const invalid = parsed.some(item => !Number.isInteger(item) || item < 0);
|
|
874
|
+
if (invalid) {
|
|
875
|
+
throw new Error('row-indices must be comma-separated non-negative integers');
|
|
876
|
+
}
|
|
877
|
+
return parsed;
|
|
878
|
+
}
|
|
879
|
+
async function deleteDatasetRows() {
|
|
880
|
+
const projectArg = getArg('--project');
|
|
881
|
+
const datasetInput = getDatasetReferenceInput();
|
|
882
|
+
const rowIds = parseCommaSeparated(getArg('--row-ids'));
|
|
883
|
+
const rowIndices = parseCommaSeparatedIntegers(getArg('--row-indices'));
|
|
884
|
+
if (rowIds.length === 0 && rowIndices.length === 0) {
|
|
885
|
+
throw new Error('Usage: orizu datasets delete-rows [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--row-ids <id1,id2>] [--row-indices <n1,n2>]');
|
|
886
|
+
}
|
|
887
|
+
let datasetId;
|
|
888
|
+
if (datasetInput) {
|
|
889
|
+
datasetId = parseDatasetReference(datasetInput).datasetId;
|
|
890
|
+
}
|
|
891
|
+
else {
|
|
892
|
+
const selected = await selectDatasetInteractively(projectArg);
|
|
893
|
+
datasetId = selected.datasetId;
|
|
894
|
+
}
|
|
895
|
+
const response = await authedFetch(`/api/cli/datasets/${encodeURIComponent(datasetId)}/rows`, {
|
|
896
|
+
method: 'DELETE',
|
|
897
|
+
headers: { 'Content-Type': 'application/json' },
|
|
898
|
+
body: JSON.stringify({
|
|
899
|
+
rowIds,
|
|
900
|
+
rowIndices,
|
|
901
|
+
}),
|
|
902
|
+
});
|
|
903
|
+
if (!response.ok) {
|
|
904
|
+
throw new Error(`Delete rows failed: ${await response.text()}`);
|
|
905
|
+
}
|
|
906
|
+
const data = await parseJsonResponse(response, 'Dataset delete rows');
|
|
907
|
+
console.log(`Deleted ${data.deletedCount} rows from dataset ${data.dataset.name} (${data.dataset.id}). New row count: ${data.dataset.rowCount}`);
|
|
908
|
+
}
|
|
833
909
|
async function downloadAnnotations() {
|
|
834
910
|
let taskId = getArg('--task');
|
|
835
911
|
const format = (getArg('--format') || 'jsonl');
|
|
@@ -947,6 +1023,14 @@ async function main() {
|
|
|
947
1023
|
await downloadDataset();
|
|
948
1024
|
return;
|
|
949
1025
|
}
|
|
1026
|
+
if (command === 'datasets' && subcommand === 'append') {
|
|
1027
|
+
await appendDatasetRows();
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
if (command === 'datasets' && subcommand === 'delete-rows') {
|
|
1031
|
+
await deleteDatasetRows();
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
950
1034
|
if (command === 'tasks' && subcommand === 'export') {
|
|
951
1035
|
await downloadAnnotations();
|
|
952
1036
|
return;
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -106,7 +106,7 @@ interface TaskStatusPayload {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
function printUsage() {
|
|
109
|
-
console.log(`orizu global options:\n\n --local Use http://localhost:3000\n --server <url> Use a specific server origin (for example: https://preview.example.com)\n\norizu commands:\n\n orizu login\n orizu logout\n orizu whoami\n orizu teams list\n orizu teams create [--name <name>]\n orizu teams members list [--team <teamSlug>]\n orizu teams members add --email <email> [--team <teamSlug>]\n orizu teams members remove --email <email> [--team <teamSlug>]\n orizu teams members role --team <teamSlug> --email <email> --role <admin|member>\n orizu projects list [--team <teamSlug>]\n orizu projects create --name <name> [--team <teamSlug>]\n orizu apps list [--project <team/project>]\n orizu apps create --project <team/project> --name <name> --dataset <datasetId> --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps update [--app <appId>] [--project <team/project>] --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps link-dataset --dataset <datasetId> [--app <appId>] [--project <team/project>] [--version <n>]\n orizu tasks list [--project <team/project>]\n orizu tasks create --project <team/project> --dataset <datasetId> --app <appId> --title <title> --assignees <userId1,userId2> [--instructions <text>] [--labels-per-item <n>]\n orizu tasks assign --task <taskId> --assignees <userId1,userId2>\n orizu tasks status --task <taskId> [--json]\n orizu datasets upload --file <path> [--project <team/project>] [--name <name>]\n orizu datasets download [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--format <csv|json|jsonl>] [--out <path>]\n orizu tasks export [--task <taskId>] [--format <csv|json|jsonl>] [--out <path>]`)
|
|
109
|
+
console.log(`orizu global options:\n\n --local Use http://localhost:3000\n --server <url> Use a specific server origin (for example: https://preview.example.com)\n\norizu commands:\n\n orizu login\n orizu logout\n orizu whoami\n orizu teams list\n orizu teams create [--name <name>]\n orizu teams members list [--team <teamSlug>]\n orizu teams members add --email <email> [--team <teamSlug>]\n orizu teams members remove --email <email> [--team <teamSlug>]\n orizu teams members role --team <teamSlug> --email <email> --role <admin|member>\n orizu projects list [--team <teamSlug>]\n orizu projects create --name <name> [--team <teamSlug>]\n orizu apps list [--project <team/project>]\n orizu apps create --project <team/project> --name <name> --dataset <datasetId> --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps update [--app <appId>] [--project <team/project>] --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps link-dataset --dataset <datasetId> [--app <appId>] [--project <team/project>] [--version <n>]\n orizu tasks list [--project <team/project>]\n orizu tasks create --project <team/project> --dataset <datasetId> --app <appId> --title <title> --assignees <userId1,userId2> [--instructions <text>] [--labels-per-item <n>]\n orizu tasks assign --task <taskId> --assignees <userId1,userId2>\n orizu tasks status --task <taskId> [--json]\n orizu datasets upload --file <path> [--project <team/project>] [--name <name>]\n orizu datasets download [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--format <csv|json|jsonl>] [--out <path>]\n orizu datasets append [--dataset <datasetId|datasetUrl>] [--project <team/project>] --file <path>\n orizu datasets delete-rows [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--row-ids <id1,id2>] [--row-indices <n1,n2>]\n orizu tasks export [--task <taskId>] [--format <csv|json|jsonl>] [--out <path>]`)
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
let cliArgs = process.argv.slice(2)
|
|
@@ -1173,7 +1173,7 @@ async function uploadDataset() {
|
|
|
1173
1173
|
}
|
|
1174
1174
|
}
|
|
1175
1175
|
|
|
1176
|
-
function
|
|
1176
|
+
function getDatasetReferenceInput(): string | null {
|
|
1177
1177
|
const fromFlag = getArg('--dataset')
|
|
1178
1178
|
if (fromFlag) {
|
|
1179
1179
|
return fromFlag
|
|
@@ -1189,7 +1189,7 @@ function getDatasetDownloadInput(): string | null {
|
|
|
1189
1189
|
|
|
1190
1190
|
async function downloadDataset() {
|
|
1191
1191
|
const projectArg = getArg('--project')
|
|
1192
|
-
const datasetInput =
|
|
1192
|
+
const datasetInput = getDatasetReferenceInput()
|
|
1193
1193
|
const format = (getArg('--format') || 'jsonl') as 'csv' | 'json' | 'jsonl'
|
|
1194
1194
|
const outPathArg = getArg('--out')
|
|
1195
1195
|
|
|
@@ -1222,6 +1222,108 @@ async function downloadDataset() {
|
|
|
1222
1222
|
console.log(`Saved dataset ${datasetId} (${format.toUpperCase()}) to ${filename}`)
|
|
1223
1223
|
}
|
|
1224
1224
|
|
|
1225
|
+
async function appendDatasetRows() {
|
|
1226
|
+
const projectArg = getArg('--project')
|
|
1227
|
+
const datasetInput = getDatasetReferenceInput()
|
|
1228
|
+
const fileArg = getArg('--file')
|
|
1229
|
+
|
|
1230
|
+
if (!fileArg) {
|
|
1231
|
+
throw new Error('Usage: orizu datasets append [--dataset <datasetId|datasetUrl>] [--project <team/project>] --file <path>')
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
let datasetId: string
|
|
1235
|
+
if (datasetInput) {
|
|
1236
|
+
datasetId = parseDatasetReference(datasetInput).datasetId
|
|
1237
|
+
} else {
|
|
1238
|
+
const selected = await selectDatasetInteractively(projectArg)
|
|
1239
|
+
datasetId = selected.datasetId
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
const file = expandHomePath(fileArg)
|
|
1243
|
+
const { rows } = parseDatasetFile(file)
|
|
1244
|
+
if (!Array.isArray(rows) || rows.length === 0) {
|
|
1245
|
+
throw new Error('Dataset append file must contain at least one row')
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
const response = await authedFetch(`/api/cli/datasets/${encodeURIComponent(datasetId)}/rows`, {
|
|
1249
|
+
method: 'POST',
|
|
1250
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1251
|
+
body: JSON.stringify({ rows }),
|
|
1252
|
+
})
|
|
1253
|
+
|
|
1254
|
+
if (!response.ok) {
|
|
1255
|
+
throw new Error(`Append failed: ${await response.text()}`)
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
const data = await parseJsonResponse<{
|
|
1259
|
+
dataset: { id: string; name: string; rowCount: number }
|
|
1260
|
+
appendedCount: number
|
|
1261
|
+
}>(response, 'Dataset append')
|
|
1262
|
+
|
|
1263
|
+
console.log(
|
|
1264
|
+
`Appended ${data.appendedCount} rows to dataset ${data.dataset.name} (${data.dataset.id}). New row count: ${data.dataset.rowCount}`
|
|
1265
|
+
)
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
function parseCommaSeparatedIntegers(value: string | null): number[] {
|
|
1269
|
+
if (!value) {
|
|
1270
|
+
return []
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
const rawItems = value
|
|
1274
|
+
.split(',')
|
|
1275
|
+
.map(item => item.trim())
|
|
1276
|
+
.filter(Boolean)
|
|
1277
|
+
const parsed = rawItems.map(item => Number(item))
|
|
1278
|
+
const invalid = parsed.some(item => !Number.isInteger(item) || item < 0)
|
|
1279
|
+
if (invalid) {
|
|
1280
|
+
throw new Error('row-indices must be comma-separated non-negative integers')
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
return parsed
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
async function deleteDatasetRows() {
|
|
1287
|
+
const projectArg = getArg('--project')
|
|
1288
|
+
const datasetInput = getDatasetReferenceInput()
|
|
1289
|
+
const rowIds = parseCommaSeparated(getArg('--row-ids'))
|
|
1290
|
+
const rowIndices = parseCommaSeparatedIntegers(getArg('--row-indices'))
|
|
1291
|
+
|
|
1292
|
+
if (rowIds.length === 0 && rowIndices.length === 0) {
|
|
1293
|
+
throw new Error('Usage: orizu datasets delete-rows [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--row-ids <id1,id2>] [--row-indices <n1,n2>]')
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
let datasetId: string
|
|
1297
|
+
if (datasetInput) {
|
|
1298
|
+
datasetId = parseDatasetReference(datasetInput).datasetId
|
|
1299
|
+
} else {
|
|
1300
|
+
const selected = await selectDatasetInteractively(projectArg)
|
|
1301
|
+
datasetId = selected.datasetId
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
const response = await authedFetch(`/api/cli/datasets/${encodeURIComponent(datasetId)}/rows`, {
|
|
1305
|
+
method: 'DELETE',
|
|
1306
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1307
|
+
body: JSON.stringify({
|
|
1308
|
+
rowIds,
|
|
1309
|
+
rowIndices,
|
|
1310
|
+
}),
|
|
1311
|
+
})
|
|
1312
|
+
|
|
1313
|
+
if (!response.ok) {
|
|
1314
|
+
throw new Error(`Delete rows failed: ${await response.text()}`)
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
const data = await parseJsonResponse<{
|
|
1318
|
+
dataset: { id: string; name: string; rowCount: number }
|
|
1319
|
+
deletedCount: number
|
|
1320
|
+
}>(response, 'Dataset delete rows')
|
|
1321
|
+
|
|
1322
|
+
console.log(
|
|
1323
|
+
`Deleted ${data.deletedCount} rows from dataset ${data.dataset.name} (${data.dataset.id}). New row count: ${data.dataset.rowCount}`
|
|
1324
|
+
)
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1225
1327
|
async function downloadAnnotations() {
|
|
1226
1328
|
let taskId = getArg('--task')
|
|
1227
1329
|
const format = (getArg('--format') || 'jsonl') as 'csv' | 'json' | 'jsonl'
|
|
@@ -1367,6 +1469,16 @@ async function main() {
|
|
|
1367
1469
|
return
|
|
1368
1470
|
}
|
|
1369
1471
|
|
|
1472
|
+
if (command === 'datasets' && subcommand === 'append') {
|
|
1473
|
+
await appendDatasetRows()
|
|
1474
|
+
return
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
if (command === 'datasets' && subcommand === 'delete-rows') {
|
|
1478
|
+
await deleteDatasetRows()
|
|
1479
|
+
return
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1370
1482
|
if (command === 'tasks' && subcommand === 'export') {
|
|
1371
1483
|
await downloadAnnotations()
|
|
1372
1484
|
return
|