@eide/foir-cli 0.12.0 → 0.13.1
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/cli.js +306 -238
- package/dist/lib/config-helpers.d.ts +5 -4
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -855,7 +855,7 @@ function createIdentityMethods(client) {
|
|
|
855
855
|
fromName: params.fromName,
|
|
856
856
|
replyTo: params.replyTo,
|
|
857
857
|
supportEmail: params.supportEmail,
|
|
858
|
-
|
|
858
|
+
appBaseUrl: params.appBaseUrl,
|
|
859
859
|
customerWelcomeEmailEnabled: params.customerWelcomeEmailEnabled,
|
|
860
860
|
customerSignupEnabled: params.customerSignupEnabled
|
|
861
861
|
})
|
|
@@ -3540,17 +3540,39 @@ async function provisionApiKey(client) {
|
|
|
3540
3540
|
|
|
3541
3541
|
// src/lib/output.ts
|
|
3542
3542
|
import chalk2 from "chalk";
|
|
3543
|
+
import {
|
|
3544
|
+
toJson
|
|
3545
|
+
} from "@bufbuild/protobuf";
|
|
3546
|
+
function bigintReplacer(_key, value) {
|
|
3547
|
+
return typeof value === "bigint" ? value.toString() : value;
|
|
3548
|
+
}
|
|
3549
|
+
function safeStringify(value, indent) {
|
|
3550
|
+
return JSON.stringify(value, bigintReplacer, indent);
|
|
3551
|
+
}
|
|
3543
3552
|
function formatOutput(data, options) {
|
|
3544
3553
|
if (options?.quiet) return;
|
|
3545
3554
|
if (options?.json) {
|
|
3546
|
-
console.log(
|
|
3555
|
+
console.log(safeStringify(data, 2));
|
|
3547
3556
|
return;
|
|
3548
3557
|
}
|
|
3549
3558
|
if (options?.jsonl) {
|
|
3550
|
-
console.log(
|
|
3559
|
+
console.log(safeStringify(data));
|
|
3551
3560
|
return;
|
|
3552
3561
|
}
|
|
3553
|
-
console.log(
|
|
3562
|
+
console.log(safeStringify(data, 2));
|
|
3563
|
+
}
|
|
3564
|
+
function formatOutputProto(schema, message, options) {
|
|
3565
|
+
if (message == null) {
|
|
3566
|
+
formatOutput(null, options);
|
|
3567
|
+
return;
|
|
3568
|
+
}
|
|
3569
|
+
formatOutput(toJson(schema, message), options);
|
|
3570
|
+
}
|
|
3571
|
+
function formatListProto(schema, items, options, config2) {
|
|
3572
|
+
const converted = items.map(
|
|
3573
|
+
(item) => toJson(schema, item)
|
|
3574
|
+
);
|
|
3575
|
+
formatList(converted, options, config2);
|
|
3554
3576
|
}
|
|
3555
3577
|
function formatList(items, options, config2) {
|
|
3556
3578
|
if (options?.quiet) {
|
|
@@ -3560,12 +3582,12 @@ function formatList(items, options, config2) {
|
|
|
3560
3582
|
return;
|
|
3561
3583
|
}
|
|
3562
3584
|
if (options?.json) {
|
|
3563
|
-
console.log(
|
|
3585
|
+
console.log(safeStringify(items, 2));
|
|
3564
3586
|
return;
|
|
3565
3587
|
}
|
|
3566
3588
|
if (options?.jsonl) {
|
|
3567
3589
|
for (const item of items) {
|
|
3568
|
-
console.log(
|
|
3590
|
+
console.log(safeStringify(item));
|
|
3569
3591
|
}
|
|
3570
3592
|
return;
|
|
3571
3593
|
}
|
|
@@ -3703,7 +3725,11 @@ import { basename } from "path";
|
|
|
3703
3725
|
import chalk3 from "chalk";
|
|
3704
3726
|
import { createClient } from "@connectrpc/connect";
|
|
3705
3727
|
import { createConnectTransport as createConnectTransport2 } from "@connectrpc/connect-node";
|
|
3706
|
-
import {
|
|
3728
|
+
import {
|
|
3729
|
+
StorageService as StorageService3,
|
|
3730
|
+
FileSchema,
|
|
3731
|
+
StorageUsageSchema
|
|
3732
|
+
} from "@eide/foir-proto-ts/storage/v1/storage_pb";
|
|
3707
3733
|
|
|
3708
3734
|
// src/lib/input.ts
|
|
3709
3735
|
import inquirer2 from "inquirer";
|
|
@@ -3876,7 +3902,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
3876
3902
|
}
|
|
3877
3903
|
const file = await storage.confirmFileUpload(upload.uploadId);
|
|
3878
3904
|
if (opts.json || opts.jsonl) {
|
|
3879
|
-
|
|
3905
|
+
formatOutputProto(FileSchema, file, opts);
|
|
3880
3906
|
} else {
|
|
3881
3907
|
success(`Uploaded ${filename}`);
|
|
3882
3908
|
if (file?.url) {
|
|
@@ -3904,7 +3930,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
3904
3930
|
limit: Number(flags.limit) || 50,
|
|
3905
3931
|
offset: Number(flags.offset) || 0
|
|
3906
3932
|
});
|
|
3907
|
-
|
|
3933
|
+
formatListProto(FileSchema, result.items, opts, {
|
|
3908
3934
|
columns: [
|
|
3909
3935
|
{ key: "id", header: "ID", width: 28 },
|
|
3910
3936
|
{ key: "filename", header: "Filename", width: 24 },
|
|
@@ -3939,7 +3965,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
3939
3965
|
const { getToken } = await getStorageAuth(opts);
|
|
3940
3966
|
const storage = createStorageRpcClient(getToken);
|
|
3941
3967
|
const file = await storage.getFile(id);
|
|
3942
|
-
|
|
3968
|
+
formatOutputProto(FileSchema, file, opts);
|
|
3943
3969
|
})
|
|
3944
3970
|
);
|
|
3945
3971
|
media.command("usage").description("Get storage usage").action(
|
|
@@ -3949,7 +3975,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
3949
3975
|
const storage = createStorageRpcClient(getToken);
|
|
3950
3976
|
const usage = await storage.getStorageUsage();
|
|
3951
3977
|
if (opts.json || opts.jsonl) {
|
|
3952
|
-
|
|
3978
|
+
formatOutputProto(StorageUsageSchema, usage, opts);
|
|
3953
3979
|
} else {
|
|
3954
3980
|
const mb = (Number(usage?.totalBytes ?? 0) / (1024 * 1024)).toFixed(
|
|
3955
3981
|
1
|
|
@@ -3973,7 +3999,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
3973
3999
|
tags: flags.tags?.split(",").map((t) => t.trim())
|
|
3974
4000
|
});
|
|
3975
4001
|
if (opts.json || opts.jsonl) {
|
|
3976
|
-
|
|
4002
|
+
formatOutputProto(FileSchema, file, opts);
|
|
3977
4003
|
} else {
|
|
3978
4004
|
success("Updated file");
|
|
3979
4005
|
}
|
|
@@ -3994,7 +4020,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
3994
4020
|
description: flags.description
|
|
3995
4021
|
});
|
|
3996
4022
|
if (opts.json || opts.jsonl) {
|
|
3997
|
-
|
|
4023
|
+
formatOutputProto(FileSchema, file, opts);
|
|
3998
4024
|
} else {
|
|
3999
4025
|
success("Updated file metadata");
|
|
4000
4026
|
}
|
|
@@ -4032,7 +4058,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
4032
4058
|
const storage = createStorageRpcClient(getToken);
|
|
4033
4059
|
const file = await storage.restoreFile(id);
|
|
4034
4060
|
if (opts.json || opts.jsonl) {
|
|
4035
|
-
|
|
4061
|
+
formatOutputProto(FileSchema, file, opts);
|
|
4036
4062
|
} else {
|
|
4037
4063
|
success("Restored file");
|
|
4038
4064
|
}
|
|
@@ -4592,6 +4618,8 @@ function registerCreateConfigCommand(program2, globalOpts) {
|
|
|
4592
4618
|
}
|
|
4593
4619
|
|
|
4594
4620
|
// src/commands/search.ts
|
|
4621
|
+
import { toJson as toJson2 } from "@bufbuild/protobuf";
|
|
4622
|
+
import { SearchResultItemSchema } from "@eide/foir-proto-ts/records/v1/records_pb";
|
|
4595
4623
|
function registerSearchCommands(program2, globalOpts) {
|
|
4596
4624
|
program2.command("search <query>").description("Search across all records").option(
|
|
4597
4625
|
"--models <keys>",
|
|
@@ -4609,7 +4637,15 @@ function registerSearchCommands(program2, globalOpts) {
|
|
|
4609
4637
|
modelKeys
|
|
4610
4638
|
});
|
|
4611
4639
|
if (opts.json || opts.jsonl) {
|
|
4612
|
-
formatOutput(
|
|
4640
|
+
formatOutput(
|
|
4641
|
+
{
|
|
4642
|
+
items: result.items.map(
|
|
4643
|
+
(item) => toJson2(SearchResultItemSchema, item)
|
|
4644
|
+
),
|
|
4645
|
+
total: result.total
|
|
4646
|
+
},
|
|
4647
|
+
opts
|
|
4648
|
+
);
|
|
4613
4649
|
return;
|
|
4614
4650
|
}
|
|
4615
4651
|
if (result.items.length > 0) {
|
|
@@ -5785,7 +5821,7 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5785
5821
|
fromName: s.fromName,
|
|
5786
5822
|
replyTo: s.replyTo,
|
|
5787
5823
|
supportEmail: s.supportEmail,
|
|
5788
|
-
|
|
5824
|
+
appBaseUrl: s.appBaseUrl,
|
|
5789
5825
|
customerWelcomeEmailEnabled: s.customerWelcomeEmailEnabled,
|
|
5790
5826
|
customerSignupEnabled: s.customerSignupEnabled
|
|
5791
5827
|
});
|
|
@@ -6033,7 +6069,7 @@ function projectSettingsFromGetProject(p) {
|
|
|
6033
6069
|
if (p.fromName) out.fromName = p.fromName;
|
|
6034
6070
|
if (p.replyTo) out.replyTo = p.replyTo;
|
|
6035
6071
|
if (p.supportEmail) out.supportEmail = p.supportEmail;
|
|
6036
|
-
if (p.
|
|
6072
|
+
if (p.appBaseUrl) out.appBaseUrl = p.appBaseUrl;
|
|
6037
6073
|
if (typeof p.customerWelcomeEmailEnabled === "boolean") {
|
|
6038
6074
|
out.customerWelcomeEmailEnabled = p.customerWelcomeEmailEnabled;
|
|
6039
6075
|
}
|
|
@@ -6267,6 +6303,7 @@ function registerProfilesCommand(program2, globalOpts) {
|
|
|
6267
6303
|
}
|
|
6268
6304
|
|
|
6269
6305
|
// src/commands/context.ts
|
|
6306
|
+
import { TenantSchema } from "@eide/foir-proto-ts/identity/v1/identity_pb";
|
|
6270
6307
|
function registerContextCommands(program2, globalOpts) {
|
|
6271
6308
|
const context = program2.command("context").description("Manage project and tenant context");
|
|
6272
6309
|
context.command("projects").description("List available projects").action(
|
|
@@ -6331,7 +6368,8 @@ function registerContextCommands(program2, globalOpts) {
|
|
|
6331
6368
|
const sessionContext = await client.identity.getSessionContext();
|
|
6332
6369
|
if (!sessionContext)
|
|
6333
6370
|
throw new Error("Could not retrieve session context.");
|
|
6334
|
-
|
|
6371
|
+
formatListProto(
|
|
6372
|
+
TenantSchema,
|
|
6335
6373
|
sessionContext.availableTenants ?? [],
|
|
6336
6374
|
opts,
|
|
6337
6375
|
{
|
|
@@ -6346,6 +6384,10 @@ function registerContextCommands(program2, globalOpts) {
|
|
|
6346
6384
|
}
|
|
6347
6385
|
|
|
6348
6386
|
// src/commands/models.ts
|
|
6387
|
+
import {
|
|
6388
|
+
ModelSchema,
|
|
6389
|
+
ModelVersionSchema
|
|
6390
|
+
} from "@eide/foir-proto-ts/models/v1/models_pb";
|
|
6349
6391
|
function registerModelsCommands(program2, globalOpts) {
|
|
6350
6392
|
const models = program2.command("models").description("Manage models");
|
|
6351
6393
|
models.command("list").description("List all models").option("--category <cat>", "Filter by category").option("--search <term>", "Search by name").option("--limit <n>", "Max results", "50").option("--offset <n>", "Skip results", "0").action(
|
|
@@ -6358,24 +6400,20 @@ function registerModelsCommands(program2, globalOpts) {
|
|
|
6358
6400
|
limit: parseInt(cmdOpts.limit ?? "50", 10),
|
|
6359
6401
|
offset: parseInt(cmdOpts.offset ?? "0", 10)
|
|
6360
6402
|
});
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
],
|
|
6376
|
-
total: result.total
|
|
6377
|
-
}
|
|
6378
|
-
);
|
|
6403
|
+
formatListProto(ModelSchema, result.items, opts, {
|
|
6404
|
+
columns: [
|
|
6405
|
+
{ key: "key", header: "Key", width: 24 },
|
|
6406
|
+
{ key: "name", header: "Name", width: 24 },
|
|
6407
|
+
{ key: "category", header: "Category", width: 14 },
|
|
6408
|
+
{
|
|
6409
|
+
key: "updatedAt",
|
|
6410
|
+
header: "Updated",
|
|
6411
|
+
width: 12,
|
|
6412
|
+
format: (v) => timeAgo(v)
|
|
6413
|
+
}
|
|
6414
|
+
],
|
|
6415
|
+
total: result.total
|
|
6416
|
+
});
|
|
6379
6417
|
})
|
|
6380
6418
|
);
|
|
6381
6419
|
models.command("get <key>").description("Get a model by key").action(
|
|
@@ -6386,7 +6424,7 @@ function registerModelsCommands(program2, globalOpts) {
|
|
|
6386
6424
|
if (!model) {
|
|
6387
6425
|
throw new Error(`Model "${key}" not found.`);
|
|
6388
6426
|
}
|
|
6389
|
-
|
|
6427
|
+
formatOutputProto(ModelSchema, model, opts);
|
|
6390
6428
|
})
|
|
6391
6429
|
);
|
|
6392
6430
|
models.command("create").description("Create a new model").option("-d, --data <json>", "Model data as JSON").option("-f, --file <path>", "Read data from file").action(
|
|
@@ -6395,7 +6433,7 @@ function registerModelsCommands(program2, globalOpts) {
|
|
|
6395
6433
|
const client = await createPlatformClient(opts);
|
|
6396
6434
|
const inputData = await parseInputData(cmdOpts);
|
|
6397
6435
|
const model = await client.models.createModel(inputData);
|
|
6398
|
-
|
|
6436
|
+
formatOutputProto(ModelSchema, model, opts);
|
|
6399
6437
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6400
6438
|
success(`Created model ${model?.key}`);
|
|
6401
6439
|
}
|
|
@@ -6416,7 +6454,7 @@ function registerModelsCommands(program2, globalOpts) {
|
|
|
6416
6454
|
id: existing.id,
|
|
6417
6455
|
...inputData
|
|
6418
6456
|
});
|
|
6419
|
-
|
|
6457
|
+
formatOutputProto(ModelSchema, model, opts);
|
|
6420
6458
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6421
6459
|
success(`Updated model ${key}`);
|
|
6422
6460
|
}
|
|
@@ -6462,30 +6500,28 @@ function registerModelsCommands(program2, globalOpts) {
|
|
|
6462
6500
|
const result = await client.models.listModelVersions(existing.id, {
|
|
6463
6501
|
limit: parseInt(cmdOpts.limit ?? "20", 10)
|
|
6464
6502
|
});
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
{ key: "createdBy", header: "By", width: 18 }
|
|
6480
|
-
]
|
|
6481
|
-
}
|
|
6482
|
-
);
|
|
6503
|
+
formatListProto(ModelVersionSchema, result.items, opts, {
|
|
6504
|
+
columns: [
|
|
6505
|
+
{ key: "id", header: "Version ID", width: 28 },
|
|
6506
|
+
{ key: "versionNumber", header: "#", width: 5 },
|
|
6507
|
+
{ key: "changeDescription", header: "Description", width: 32 },
|
|
6508
|
+
{
|
|
6509
|
+
key: "createdAt",
|
|
6510
|
+
header: "Created",
|
|
6511
|
+
width: 12,
|
|
6512
|
+
format: (v) => timeAgo(v)
|
|
6513
|
+
},
|
|
6514
|
+
{ key: "createdBy", header: "By", width: 18 }
|
|
6515
|
+
]
|
|
6516
|
+
});
|
|
6483
6517
|
}
|
|
6484
6518
|
)
|
|
6485
6519
|
);
|
|
6486
6520
|
}
|
|
6487
6521
|
|
|
6488
6522
|
// src/commands/records.ts
|
|
6523
|
+
import { toJson as toJson3 } from "@bufbuild/protobuf";
|
|
6524
|
+
import { RecordSchema } from "@eide/foir-proto-ts/records/v1/records_pb";
|
|
6489
6525
|
function registerRecordsCommands(program2, globalOpts) {
|
|
6490
6526
|
const records = program2.command("records").description("Manage records");
|
|
6491
6527
|
records.command("list <modelKey>").description("List records for a model").option("--filter <expr>", "Filter expression (e.g. status=active)").option("--limit <n>", "Max results", "20").option("--offset <n>", "Skip results", "0").action(
|
|
@@ -6501,24 +6537,20 @@ function registerRecordsCommands(program2, globalOpts) {
|
|
|
6501
6537
|
};
|
|
6502
6538
|
if (cmdOpts.filter) params.filters = parseFilters(cmdOpts.filter);
|
|
6503
6539
|
const result = await client.records.listRecords(params);
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
],
|
|
6519
|
-
total: result.total
|
|
6520
|
-
}
|
|
6521
|
-
);
|
|
6540
|
+
formatListProto(RecordSchema, result.items, opts, {
|
|
6541
|
+
columns: [
|
|
6542
|
+
{ key: "id", header: "ID", width: 28 },
|
|
6543
|
+
{ key: "naturalKey", header: "Key", width: 24 },
|
|
6544
|
+
{ key: "versionNumber", header: "Version", width: 8 },
|
|
6545
|
+
{
|
|
6546
|
+
key: "updatedAt",
|
|
6547
|
+
header: "Updated",
|
|
6548
|
+
width: 12,
|
|
6549
|
+
format: (v) => timeAgo(v)
|
|
6550
|
+
}
|
|
6551
|
+
],
|
|
6552
|
+
total: result.total
|
|
6553
|
+
});
|
|
6522
6554
|
}
|
|
6523
6555
|
)
|
|
6524
6556
|
);
|
|
@@ -6528,23 +6560,13 @@ function registerRecordsCommands(program2, globalOpts) {
|
|
|
6528
6560
|
async (modelKey, idOrKey, _cmdOpts) => {
|
|
6529
6561
|
const opts = globalOpts();
|
|
6530
6562
|
const client = await createPlatformClient(opts);
|
|
6531
|
-
|
|
6532
|
-
if (
|
|
6533
|
-
const record = await client.records.getRecord(idOrKey);
|
|
6534
|
-
result = record;
|
|
6535
|
-
} else {
|
|
6536
|
-
const record = await client.records.getRecordByKey(
|
|
6537
|
-
modelKey,
|
|
6538
|
-
idOrKey
|
|
6539
|
-
);
|
|
6540
|
-
result = record;
|
|
6541
|
-
}
|
|
6542
|
-
if (!result) {
|
|
6563
|
+
const record = isUUID(idOrKey) ? await client.records.getRecord(idOrKey) : await client.records.getRecordByKey(modelKey, idOrKey);
|
|
6564
|
+
if (!record) {
|
|
6543
6565
|
throw new Error(
|
|
6544
6566
|
`Record "${idOrKey}" not found in model "${modelKey}".`
|
|
6545
6567
|
);
|
|
6546
6568
|
}
|
|
6547
|
-
|
|
6569
|
+
formatOutputProto(RecordSchema, record, opts);
|
|
6548
6570
|
}
|
|
6549
6571
|
)
|
|
6550
6572
|
);
|
|
@@ -6557,7 +6579,14 @@ function registerRecordsCommands(program2, globalOpts) {
|
|
|
6557
6579
|
const inputData = await parseInputData(cmdOpts);
|
|
6558
6580
|
const input = { modelKey, ...inputData };
|
|
6559
6581
|
const result = await client.records.createRecord(input);
|
|
6560
|
-
formatOutput(
|
|
6582
|
+
formatOutput(
|
|
6583
|
+
{
|
|
6584
|
+
record: result.record ? toJson3(RecordSchema, result.record) : null,
|
|
6585
|
+
variant: result.variant ? toJson3(RecordSchema, result.variant) : null,
|
|
6586
|
+
version: result.version ? toJson3(RecordSchema, result.version) : null
|
|
6587
|
+
},
|
|
6588
|
+
opts
|
|
6589
|
+
);
|
|
6561
6590
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6562
6591
|
success(`Created record ${result.record?.id}`);
|
|
6563
6592
|
}
|
|
@@ -6573,7 +6602,7 @@ function registerRecordsCommands(program2, globalOpts) {
|
|
|
6573
6602
|
const inputData = await parseInputData(cmdOpts);
|
|
6574
6603
|
const input = { id, ...inputData };
|
|
6575
6604
|
const record = await client.records.updateRecord(input);
|
|
6576
|
-
|
|
6605
|
+
formatOutputProto(RecordSchema, record, opts);
|
|
6577
6606
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6578
6607
|
success(`Updated record ${id}`);
|
|
6579
6608
|
}
|
|
@@ -6634,7 +6663,7 @@ function registerRecordsCommands(program2, globalOpts) {
|
|
|
6634
6663
|
const client = await createPlatformClient(opts);
|
|
6635
6664
|
const naturalKey = cmdOpts.naturalKey ?? `${id}-copy`;
|
|
6636
6665
|
const record = await client.records.duplicateRecord(id, naturalKey);
|
|
6637
|
-
|
|
6666
|
+
formatOutputProto(RecordSchema, record, opts);
|
|
6638
6667
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6639
6668
|
success(`Duplicated \u2192 ${record?.id}`);
|
|
6640
6669
|
}
|
|
@@ -6650,39 +6679,11 @@ function registerRecordsCommands(program2, globalOpts) {
|
|
|
6650
6679
|
const result = await client.records.listRecordVersions(parentId, {
|
|
6651
6680
|
limit: parseInt(cmdOpts.limit ?? "20", 10)
|
|
6652
6681
|
});
|
|
6653
|
-
|
|
6654
|
-
result.items,
|
|
6655
|
-
opts,
|
|
6656
|
-
{
|
|
6657
|
-
columns: [
|
|
6658
|
-
{ key: "id", header: "Version ID", width: 28 },
|
|
6659
|
-
{ key: "versionNumber", header: "#", width: 5 },
|
|
6660
|
-
{ key: "changeDescription", header: "Description", width: 30 },
|
|
6661
|
-
{
|
|
6662
|
-
key: "createdAt",
|
|
6663
|
-
header: "Created",
|
|
6664
|
-
width: 12,
|
|
6665
|
-
format: (v) => timeAgo(v)
|
|
6666
|
-
}
|
|
6667
|
-
]
|
|
6668
|
-
}
|
|
6669
|
-
);
|
|
6670
|
-
}
|
|
6671
|
-
)
|
|
6672
|
-
);
|
|
6673
|
-
records.command("variants <recordId>").description("List variants for a record").action(
|
|
6674
|
-
withErrorHandler(globalOpts, async (recordId) => {
|
|
6675
|
-
const opts = globalOpts();
|
|
6676
|
-
const client = await createPlatformClient(opts);
|
|
6677
|
-
const result = await client.records.listRecordVariants(recordId);
|
|
6678
|
-
formatList(
|
|
6679
|
-
result.items,
|
|
6680
|
-
opts,
|
|
6681
|
-
{
|
|
6682
|
+
formatListProto(RecordSchema, result.items, opts, {
|
|
6682
6683
|
columns: [
|
|
6683
|
-
{ key: "id", header: "
|
|
6684
|
-
{ key: "
|
|
6685
|
-
{ key: "
|
|
6684
|
+
{ key: "id", header: "Version ID", width: 28 },
|
|
6685
|
+
{ key: "versionNumber", header: "#", width: 5 },
|
|
6686
|
+
{ key: "changeDescription", header: "Description", width: 30 },
|
|
6686
6687
|
{
|
|
6687
6688
|
key: "createdAt",
|
|
6688
6689
|
header: "Created",
|
|
@@ -6690,8 +6691,28 @@ function registerRecordsCommands(program2, globalOpts) {
|
|
|
6690
6691
|
format: (v) => timeAgo(v)
|
|
6691
6692
|
}
|
|
6692
6693
|
]
|
|
6693
|
-
}
|
|
6694
|
-
|
|
6694
|
+
});
|
|
6695
|
+
}
|
|
6696
|
+
)
|
|
6697
|
+
);
|
|
6698
|
+
records.command("variants <recordId>").description("List variants for a record").action(
|
|
6699
|
+
withErrorHandler(globalOpts, async (recordId) => {
|
|
6700
|
+
const opts = globalOpts();
|
|
6701
|
+
const client = await createPlatformClient(opts);
|
|
6702
|
+
const result = await client.records.listRecordVariants(recordId);
|
|
6703
|
+
formatListProto(RecordSchema, result.items, opts, {
|
|
6704
|
+
columns: [
|
|
6705
|
+
{ key: "id", header: "Variant ID", width: 28 },
|
|
6706
|
+
{ key: "variantKey", header: "Key", width: 20 },
|
|
6707
|
+
{ key: "isDefault", header: "Default", width: 8 },
|
|
6708
|
+
{
|
|
6709
|
+
key: "createdAt",
|
|
6710
|
+
header: "Created",
|
|
6711
|
+
width: 12,
|
|
6712
|
+
format: (v) => timeAgo(v)
|
|
6713
|
+
}
|
|
6714
|
+
]
|
|
6715
|
+
});
|
|
6695
6716
|
})
|
|
6696
6717
|
);
|
|
6697
6718
|
records.command("create-version <parentId>").description(
|
|
@@ -6708,7 +6729,7 @@ function registerRecordsCommands(program2, globalOpts) {
|
|
|
6708
6729
|
inputData,
|
|
6709
6730
|
cmdOpts.message
|
|
6710
6731
|
);
|
|
6711
|
-
|
|
6732
|
+
formatOutputProto(RecordSchema, version2, opts);
|
|
6712
6733
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6713
6734
|
success(`Created version ${version2?.id}`);
|
|
6714
6735
|
}
|
|
@@ -6725,7 +6746,7 @@ function registerRecordsCommands(program2, globalOpts) {
|
|
|
6725
6746
|
recordId,
|
|
6726
6747
|
cmdOpts.key
|
|
6727
6748
|
);
|
|
6728
|
-
|
|
6749
|
+
formatOutputProto(RecordSchema, variant, opts);
|
|
6729
6750
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6730
6751
|
success(`Created variant ${variant?.id}`);
|
|
6731
6752
|
}
|
|
@@ -6735,6 +6756,7 @@ function registerRecordsCommands(program2, globalOpts) {
|
|
|
6735
6756
|
}
|
|
6736
6757
|
|
|
6737
6758
|
// src/commands/customers.ts
|
|
6759
|
+
import { CustomerSchema } from "@eide/foir-proto-ts/identity/v1/identity_pb";
|
|
6738
6760
|
var statusMap = {
|
|
6739
6761
|
ACTIVE: CustomerStatus.ACTIVE,
|
|
6740
6762
|
PENDING: CustomerStatus.PENDING,
|
|
@@ -6755,52 +6777,47 @@ function registerCustomersCommands(program2, globalOpts) {
|
|
|
6755
6777
|
limit: parseInt(cmdOpts.limit ?? "20", 10),
|
|
6756
6778
|
offset: parseInt(cmdOpts.offset ?? "0", 10)
|
|
6757
6779
|
});
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
],
|
|
6779
|
-
total: result.total
|
|
6780
|
-
}
|
|
6781
|
-
);
|
|
6780
|
+
formatListProto(CustomerSchema, result.items, opts, {
|
|
6781
|
+
columns: [
|
|
6782
|
+
{ key: "id", header: "ID", width: 28 },
|
|
6783
|
+
{ key: "email", header: "Email", width: 30 },
|
|
6784
|
+
{ key: "status", header: "Status", width: 12 },
|
|
6785
|
+
{
|
|
6786
|
+
key: "lastLoginAt",
|
|
6787
|
+
header: "Last Login",
|
|
6788
|
+
width: 12,
|
|
6789
|
+
format: (v) => timeAgo(v)
|
|
6790
|
+
},
|
|
6791
|
+
{
|
|
6792
|
+
key: "createdAt",
|
|
6793
|
+
header: "Created",
|
|
6794
|
+
width: 12,
|
|
6795
|
+
format: (v) => timeAgo(v)
|
|
6796
|
+
}
|
|
6797
|
+
],
|
|
6798
|
+
total: result.total
|
|
6799
|
+
});
|
|
6782
6800
|
})
|
|
6783
6801
|
);
|
|
6784
6802
|
customers.command("get <idOrEmail>").description("Get a customer by ID or email").action(
|
|
6785
6803
|
withErrorHandler(globalOpts, async (idOrEmail) => {
|
|
6786
6804
|
const opts = globalOpts();
|
|
6787
6805
|
const client = await createPlatformClient(opts);
|
|
6788
|
-
let
|
|
6806
|
+
let customer;
|
|
6789
6807
|
if (idOrEmail.includes("@")) {
|
|
6790
6808
|
const list = await client.identity.listCustomers({
|
|
6791
6809
|
search: idOrEmail,
|
|
6792
6810
|
limit: 1
|
|
6793
6811
|
});
|
|
6794
|
-
|
|
6795
|
-
result = match ? match : null;
|
|
6812
|
+
customer = list.items[0] ?? null;
|
|
6796
6813
|
} else {
|
|
6797
6814
|
const resp = await client.identity.getCustomer(idOrEmail);
|
|
6798
|
-
|
|
6815
|
+
customer = resp.customer ?? null;
|
|
6799
6816
|
}
|
|
6800
|
-
if (!
|
|
6817
|
+
if (!customer) {
|
|
6801
6818
|
throw new Error(`Customer "${idOrEmail}" not found.`);
|
|
6802
6819
|
}
|
|
6803
|
-
|
|
6820
|
+
formatOutputProto(CustomerSchema, customer, opts);
|
|
6804
6821
|
})
|
|
6805
6822
|
);
|
|
6806
6823
|
customers.command("create").description("Create a new customer").option("--email <email>", "Customer email (required)").option("-d, --data <json>", "Additional data as JSON").action(
|
|
@@ -6824,11 +6841,8 @@ function registerCustomersCommands(program2, globalOpts) {
|
|
|
6824
6841
|
throw new Error("--email is required.");
|
|
6825
6842
|
}
|
|
6826
6843
|
const resp = await client.identity.createCustomer(input);
|
|
6827
|
-
const customer = resp.customer;
|
|
6828
|
-
|
|
6829
|
-
customer,
|
|
6830
|
-
opts
|
|
6831
|
-
);
|
|
6844
|
+
const customer = resp.customer ?? null;
|
|
6845
|
+
formatOutputProto(CustomerSchema, customer, opts);
|
|
6832
6846
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6833
6847
|
success(`Created customer ${customer?.email}`);
|
|
6834
6848
|
}
|
|
@@ -6860,6 +6874,7 @@ function registerCustomersCommands(program2, globalOpts) {
|
|
|
6860
6874
|
}
|
|
6861
6875
|
|
|
6862
6876
|
// src/commands/customer-profiles.ts
|
|
6877
|
+
import { CustomerProfileSchemaSchema } from "@eide/foir-proto-ts/settings/v1/settings_pb";
|
|
6863
6878
|
function registerCustomerProfilesCommands(program2, globalOpts) {
|
|
6864
6879
|
const cp = program2.command("customer-profiles").alias("cp").description("Manage customer profile schema and profiles");
|
|
6865
6880
|
const schema = cp.command("schema").description("Manage the customer profile schema");
|
|
@@ -6878,7 +6893,7 @@ function registerCustomerProfilesCommands(program2, globalOpts) {
|
|
|
6878
6893
|
}
|
|
6879
6894
|
return;
|
|
6880
6895
|
}
|
|
6881
|
-
|
|
6896
|
+
formatOutputProto(CustomerProfileSchemaSchema, result, opts);
|
|
6882
6897
|
})
|
|
6883
6898
|
);
|
|
6884
6899
|
schema.command("update").description(
|
|
@@ -6897,7 +6912,7 @@ function registerCustomerProfilesCommands(program2, globalOpts) {
|
|
|
6897
6912
|
fields: inputData.fields,
|
|
6898
6913
|
publicFields: inputData.publicFields ?? []
|
|
6899
6914
|
});
|
|
6900
|
-
|
|
6915
|
+
formatOutputProto(CustomerProfileSchemaSchema, result, opts);
|
|
6901
6916
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6902
6917
|
const version2 = result?.version;
|
|
6903
6918
|
success(`Updated customer profile schema (version ${version2})`);
|
|
@@ -6938,6 +6953,11 @@ function registerCustomerProfilesCommands(program2, globalOpts) {
|
|
|
6938
6953
|
}
|
|
6939
6954
|
|
|
6940
6955
|
// src/commands/operations.ts
|
|
6956
|
+
import {
|
|
6957
|
+
OperationSchema,
|
|
6958
|
+
OperationExecutionSchema,
|
|
6959
|
+
DeadLetterEntrySchema
|
|
6960
|
+
} from "@eide/foir-proto-ts/operations/v1/operations_pb";
|
|
6941
6961
|
function registerOperationsCommands(program2, globalOpts) {
|
|
6942
6962
|
const operations = program2.command("operations").description("Manage operations");
|
|
6943
6963
|
operations.command("list").description("List operations").option("--category <cat>", "Filter by category").option("--active", "Only active operations").option("--limit <n>", "Max results", "50").action(
|
|
@@ -6949,7 +6969,7 @@ function registerOperationsCommands(program2, globalOpts) {
|
|
|
6949
6969
|
isActive: cmdOpts.active ? true : void 0,
|
|
6950
6970
|
limit: parseInt(String(cmdOpts.limit ?? "50"), 10)
|
|
6951
6971
|
});
|
|
6952
|
-
|
|
6972
|
+
formatListProto(OperationSchema, data.operations, opts, {
|
|
6953
6973
|
columns: [
|
|
6954
6974
|
{ key: "key", header: "Key", width: 24 },
|
|
6955
6975
|
{ key: "name", header: "Name", width: 24 },
|
|
@@ -6976,7 +6996,7 @@ function registerOperationsCommands(program2, globalOpts) {
|
|
|
6976
6996
|
const client = await createPlatformClient(opts);
|
|
6977
6997
|
const result = await client.operations.getOperation({ key });
|
|
6978
6998
|
if (!result) throw new Error(`Operation "${key}" not found.`);
|
|
6979
|
-
|
|
6999
|
+
formatOutputProto(OperationSchema, result, opts);
|
|
6980
7000
|
})
|
|
6981
7001
|
);
|
|
6982
7002
|
operations.command("execute <key>").description("Execute an operation").option("-d, --data <json>", "Input data as JSON").option("-f, --file <path>", "Read input from file").option("--async", "Execute asynchronously").action(
|
|
@@ -6993,7 +7013,17 @@ function registerOperationsCommands(program2, globalOpts) {
|
|
|
6993
7013
|
operationKey: key,
|
|
6994
7014
|
input: inputData
|
|
6995
7015
|
});
|
|
6996
|
-
|
|
7016
|
+
if (result.execution) {
|
|
7017
|
+
formatOutputProto(OperationExecutionSchema, result.execution, opts);
|
|
7018
|
+
} else {
|
|
7019
|
+
formatOutput(
|
|
7020
|
+
{
|
|
7021
|
+
completed: result.completed,
|
|
7022
|
+
errorMessage: result.errorMessage ?? null
|
|
7023
|
+
},
|
|
7024
|
+
opts
|
|
7025
|
+
);
|
|
7026
|
+
}
|
|
6997
7027
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6998
7028
|
if (result.completed) {
|
|
6999
7029
|
success(`Operation completed in ${result.execution?.durationMs ?? 0}ms`);
|
|
@@ -7012,7 +7042,7 @@ function registerOperationsCommands(program2, globalOpts) {
|
|
|
7012
7042
|
operationKey: cmdOpts.operation,
|
|
7013
7043
|
limit: parseInt(cmdOpts.limit ?? "20", 10)
|
|
7014
7044
|
});
|
|
7015
|
-
|
|
7045
|
+
formatListProto(DeadLetterEntrySchema, data.entries, opts, {
|
|
7016
7046
|
columns: [
|
|
7017
7047
|
{ key: "id", header: "ID", width: 28 },
|
|
7018
7048
|
{ key: "operationKey", header: "Operation", width: 20 },
|
|
@@ -7059,6 +7089,11 @@ function registerOperationsCommands(program2, globalOpts) {
|
|
|
7059
7089
|
}
|
|
7060
7090
|
|
|
7061
7091
|
// src/commands/segments.ts
|
|
7092
|
+
import {
|
|
7093
|
+
SegmentSchema,
|
|
7094
|
+
SegmentPreviewSchema,
|
|
7095
|
+
SegmentEvaluationResultSchema
|
|
7096
|
+
} from "@eide/foir-proto-ts/segments/v1/segments_pb";
|
|
7062
7097
|
function registerSegmentsCommands(program2, globalOpts) {
|
|
7063
7098
|
const segments = program2.command("segments").description("Manage segments");
|
|
7064
7099
|
segments.command("list").description("List segments").option("--active", "Only active segments").option("--limit <n>", "Max results", "50").option("--offset <n>", "Skip results", "0").action(
|
|
@@ -7070,7 +7105,7 @@ function registerSegmentsCommands(program2, globalOpts) {
|
|
|
7070
7105
|
limit: parseInt(String(cmdOpts.limit ?? "50"), 10),
|
|
7071
7106
|
offset: parseInt(String(cmdOpts.offset ?? "0"), 10)
|
|
7072
7107
|
});
|
|
7073
|
-
|
|
7108
|
+
formatListProto(SegmentSchema, data.segments, opts, {
|
|
7074
7109
|
columns: [
|
|
7075
7110
|
{ key: "id", header: "ID", width: 28 },
|
|
7076
7111
|
{ key: "key", header: "Key", width: 20 },
|
|
@@ -7103,7 +7138,7 @@ function registerSegmentsCommands(program2, globalOpts) {
|
|
|
7103
7138
|
result = await client.segments.getSegmentByKey(idOrKey);
|
|
7104
7139
|
}
|
|
7105
7140
|
if (!result) throw new Error(`Segment "${idOrKey}" not found.`);
|
|
7106
|
-
|
|
7141
|
+
formatOutputProto(SegmentSchema, result, opts);
|
|
7107
7142
|
})
|
|
7108
7143
|
);
|
|
7109
7144
|
segments.command("create").description("Create a new segment").option("-d, --data <json>", "Segment data as JSON").option("-f, --file <path>", "Read data from file").action(
|
|
@@ -7114,7 +7149,7 @@ function registerSegmentsCommands(program2, globalOpts) {
|
|
|
7114
7149
|
const result = await client.segments.createSegment(
|
|
7115
7150
|
input
|
|
7116
7151
|
);
|
|
7117
|
-
|
|
7152
|
+
formatOutputProto(SegmentSchema, result, opts);
|
|
7118
7153
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7119
7154
|
success(`Created segment ${result?.key}`);
|
|
7120
7155
|
})
|
|
@@ -7130,7 +7165,7 @@ function registerSegmentsCommands(program2, globalOpts) {
|
|
|
7130
7165
|
id,
|
|
7131
7166
|
...input
|
|
7132
7167
|
});
|
|
7133
|
-
|
|
7168
|
+
formatOutputProto(SegmentSchema, result, opts);
|
|
7134
7169
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7135
7170
|
success(`Updated segment ${id}`);
|
|
7136
7171
|
}
|
|
@@ -7166,7 +7201,7 @@ function registerSegmentsCommands(program2, globalOpts) {
|
|
|
7166
7201
|
rules,
|
|
7167
7202
|
parseInt(cmdOpts.sampleSize ?? "100", 10)
|
|
7168
7203
|
);
|
|
7169
|
-
|
|
7204
|
+
formatOutputProto(SegmentPreviewSchema, result, opts);
|
|
7170
7205
|
})
|
|
7171
7206
|
);
|
|
7172
7207
|
segments.command("test <segmentId> <customerId>").description("Test whether a customer matches a segment").action(
|
|
@@ -7179,13 +7214,17 @@ function registerSegmentsCommands(program2, globalOpts) {
|
|
|
7179
7214
|
segmentId,
|
|
7180
7215
|
customerId
|
|
7181
7216
|
);
|
|
7182
|
-
|
|
7217
|
+
formatOutputProto(SegmentEvaluationResultSchema, result, opts);
|
|
7183
7218
|
}
|
|
7184
7219
|
)
|
|
7185
7220
|
);
|
|
7186
7221
|
}
|
|
7187
7222
|
|
|
7188
7223
|
// src/commands/experiments.ts
|
|
7224
|
+
import {
|
|
7225
|
+
ExperimentSchema,
|
|
7226
|
+
ExperimentStatsSchema
|
|
7227
|
+
} from "@eide/foir-proto-ts/experiments/v1/experiments_pb";
|
|
7189
7228
|
function registerExperimentsCommands(program2, globalOpts) {
|
|
7190
7229
|
const experiments = program2.command("experiments").description("Manage experiments");
|
|
7191
7230
|
experiments.command("list").description("List experiments").option("--status <status>", "Filter by status").option("--active", "Only active experiments").option("--limit <n>", "Max results", "50").option("--offset <n>", "Skip results", "0").action(
|
|
@@ -7198,7 +7237,7 @@ function registerExperimentsCommands(program2, globalOpts) {
|
|
|
7198
7237
|
limit: parseInt(String(cmdOpts.limit ?? "50"), 10),
|
|
7199
7238
|
offset: parseInt(String(cmdOpts.offset ?? "0"), 10)
|
|
7200
7239
|
});
|
|
7201
|
-
|
|
7240
|
+
formatListProto(ExperimentSchema, data.experiments, opts, {
|
|
7202
7241
|
columns: [
|
|
7203
7242
|
{ key: "id", header: "ID", width: 28 },
|
|
7204
7243
|
{ key: "key", header: "Key", width: 20 },
|
|
@@ -7231,7 +7270,7 @@ function registerExperimentsCommands(program2, globalOpts) {
|
|
|
7231
7270
|
result = await client.experiments.getExperimentByKey(idOrKey);
|
|
7232
7271
|
}
|
|
7233
7272
|
if (!result) throw new Error(`Experiment "${idOrKey}" not found.`);
|
|
7234
|
-
|
|
7273
|
+
formatOutputProto(ExperimentSchema, result, opts);
|
|
7235
7274
|
})
|
|
7236
7275
|
);
|
|
7237
7276
|
experiments.command("create").description("Create a new experiment").option("-d, --data <json>", "Experiment data as JSON").option("-f, --file <path>", "Read data from file").action(
|
|
@@ -7242,7 +7281,7 @@ function registerExperimentsCommands(program2, globalOpts) {
|
|
|
7242
7281
|
const result = await client.experiments.createExperiment(
|
|
7243
7282
|
input
|
|
7244
7283
|
);
|
|
7245
|
-
|
|
7284
|
+
formatOutputProto(ExperimentSchema, result, opts);
|
|
7246
7285
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7247
7286
|
success(`Created experiment ${result?.key}`);
|
|
7248
7287
|
})
|
|
@@ -7258,7 +7297,7 @@ function registerExperimentsCommands(program2, globalOpts) {
|
|
|
7258
7297
|
id,
|
|
7259
7298
|
...input
|
|
7260
7299
|
});
|
|
7261
|
-
|
|
7300
|
+
formatOutputProto(ExperimentSchema, result, opts);
|
|
7262
7301
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7263
7302
|
success(`Updated experiment ${id}`);
|
|
7264
7303
|
}
|
|
@@ -7289,7 +7328,7 @@ function registerExperimentsCommands(program2, globalOpts) {
|
|
|
7289
7328
|
const opts = globalOpts();
|
|
7290
7329
|
const client = await createPlatformClient(opts);
|
|
7291
7330
|
const result = await client.experiments.startExperiment(id);
|
|
7292
|
-
|
|
7331
|
+
formatOutputProto(ExperimentSchema, result, opts);
|
|
7293
7332
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7294
7333
|
success("Experiment started");
|
|
7295
7334
|
})
|
|
@@ -7299,7 +7338,7 @@ function registerExperimentsCommands(program2, globalOpts) {
|
|
|
7299
7338
|
const opts = globalOpts();
|
|
7300
7339
|
const client = await createPlatformClient(opts);
|
|
7301
7340
|
const result = await client.experiments.pauseExperiment(id);
|
|
7302
|
-
|
|
7341
|
+
formatOutputProto(ExperimentSchema, result, opts);
|
|
7303
7342
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7304
7343
|
success("Experiment paused");
|
|
7305
7344
|
})
|
|
@@ -7309,7 +7348,7 @@ function registerExperimentsCommands(program2, globalOpts) {
|
|
|
7309
7348
|
const opts = globalOpts();
|
|
7310
7349
|
const client = await createPlatformClient(opts);
|
|
7311
7350
|
const result = await client.experiments.resumeExperiment(id);
|
|
7312
|
-
|
|
7351
|
+
formatOutputProto(ExperimentSchema, result, opts);
|
|
7313
7352
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7314
7353
|
success("Experiment resumed");
|
|
7315
7354
|
})
|
|
@@ -7319,7 +7358,7 @@ function registerExperimentsCommands(program2, globalOpts) {
|
|
|
7319
7358
|
const opts = globalOpts();
|
|
7320
7359
|
const client = await createPlatformClient(opts);
|
|
7321
7360
|
const result = await client.experiments.endExperiment(id);
|
|
7322
|
-
|
|
7361
|
+
formatOutputProto(ExperimentSchema, result, opts);
|
|
7323
7362
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7324
7363
|
success("Experiment ended");
|
|
7325
7364
|
})
|
|
@@ -7329,12 +7368,13 @@ function registerExperimentsCommands(program2, globalOpts) {
|
|
|
7329
7368
|
const opts = globalOpts();
|
|
7330
7369
|
const client = await createPlatformClient(opts);
|
|
7331
7370
|
const result = await client.experiments.getExperimentStats(id);
|
|
7332
|
-
|
|
7371
|
+
formatOutputProto(ExperimentStatsSchema, result, opts);
|
|
7333
7372
|
})
|
|
7334
7373
|
);
|
|
7335
7374
|
}
|
|
7336
7375
|
|
|
7337
7376
|
// src/commands/schedules.ts
|
|
7377
|
+
import { CronScheduleSchema } from "@eide/foir-proto-ts/schedules/v1/schedules_pb";
|
|
7338
7378
|
function registerSchedulesCommands(program2, globalOpts) {
|
|
7339
7379
|
const schedules = program2.command("schedules").description("Manage schedules");
|
|
7340
7380
|
schedules.command("list").description("List schedules").option("--active", "Only active schedules").option("--limit <n>", "Max results", "50").action(
|
|
@@ -7345,7 +7385,7 @@ function registerSchedulesCommands(program2, globalOpts) {
|
|
|
7345
7385
|
isActive: cmdOpts.active ? true : void 0,
|
|
7346
7386
|
limit: parseInt(String(cmdOpts.limit ?? "50"), 10)
|
|
7347
7387
|
});
|
|
7348
|
-
|
|
7388
|
+
formatListProto(CronScheduleSchema, data.schedules, opts, {
|
|
7349
7389
|
columns: [
|
|
7350
7390
|
{ key: "key", header: "Key", width: 20 },
|
|
7351
7391
|
{ key: "name", header: "Name", width: 24 },
|
|
@@ -7374,7 +7414,7 @@ function registerSchedulesCommands(program2, globalOpts) {
|
|
|
7374
7414
|
const client = await createPlatformClient(opts);
|
|
7375
7415
|
const result = await client.cronSchedules.getCronScheduleByKey(key);
|
|
7376
7416
|
if (!result) throw new Error(`Schedule "${key}" not found.`);
|
|
7377
|
-
|
|
7417
|
+
formatOutputProto(CronScheduleSchema, result, opts);
|
|
7378
7418
|
})
|
|
7379
7419
|
);
|
|
7380
7420
|
schedules.command("create").description("Create a new schedule").option("-d, --data <json>", "Schedule data as JSON").option("-f, --file <path>", "Read data from file").action(
|
|
@@ -7385,7 +7425,7 @@ function registerSchedulesCommands(program2, globalOpts) {
|
|
|
7385
7425
|
const result = await client.cronSchedules.createCronSchedule(
|
|
7386
7426
|
input
|
|
7387
7427
|
);
|
|
7388
|
-
|
|
7428
|
+
formatOutputProto(CronScheduleSchema, result, opts);
|
|
7389
7429
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7390
7430
|
success(`Created schedule ${result?.key}`);
|
|
7391
7431
|
})
|
|
@@ -7403,7 +7443,7 @@ function registerSchedulesCommands(program2, globalOpts) {
|
|
|
7403
7443
|
id: existing.id,
|
|
7404
7444
|
...input
|
|
7405
7445
|
});
|
|
7406
|
-
|
|
7446
|
+
formatOutputProto(CronScheduleSchema, result, opts);
|
|
7407
7447
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7408
7448
|
success(`Updated schedule "${key}"`);
|
|
7409
7449
|
}
|
|
@@ -7419,7 +7459,11 @@ function registerSchedulesCommands(program2, globalOpts) {
|
|
|
7419
7459
|
id: existing.id
|
|
7420
7460
|
});
|
|
7421
7461
|
if (opts.json || opts.jsonl) {
|
|
7422
|
-
|
|
7462
|
+
if (result) {
|
|
7463
|
+
formatOutputProto(CronScheduleSchema, result, opts);
|
|
7464
|
+
} else {
|
|
7465
|
+
formatOutput({ triggered: true }, opts);
|
|
7466
|
+
}
|
|
7423
7467
|
} else {
|
|
7424
7468
|
success(`Triggered schedule "${key}"`);
|
|
7425
7469
|
}
|
|
@@ -7434,7 +7478,7 @@ function registerSchedulesCommands(program2, globalOpts) {
|
|
|
7434
7478
|
const result = await client.cronSchedules.pauseCronSchedule({
|
|
7435
7479
|
id: existing.id
|
|
7436
7480
|
});
|
|
7437
|
-
|
|
7481
|
+
formatOutputProto(CronScheduleSchema, result, opts);
|
|
7438
7482
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7439
7483
|
success(`Paused schedule "${key}"`);
|
|
7440
7484
|
})
|
|
@@ -7448,7 +7492,7 @@ function registerSchedulesCommands(program2, globalOpts) {
|
|
|
7448
7492
|
const result = await client.cronSchedules.resumeCronSchedule({
|
|
7449
7493
|
id: existing.id
|
|
7450
7494
|
});
|
|
7451
|
-
|
|
7495
|
+
formatOutputProto(CronScheduleSchema, result, opts);
|
|
7452
7496
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7453
7497
|
success(`Resumed schedule "${key}"`);
|
|
7454
7498
|
})
|
|
@@ -7481,6 +7525,8 @@ function registerSchedulesCommands(program2, globalOpts) {
|
|
|
7481
7525
|
|
|
7482
7526
|
// src/commands/api-keys.ts
|
|
7483
7527
|
import chalk10 from "chalk";
|
|
7528
|
+
import { toJson as toJson4 } from "@bufbuild/protobuf";
|
|
7529
|
+
import { ApiKeySchema } from "@eide/foir-proto-ts/identity/v1/identity_pb";
|
|
7484
7530
|
function registerApiKeysCommands(program2, globalOpts) {
|
|
7485
7531
|
const apiKeys = program2.command("api-keys").description("Manage API keys");
|
|
7486
7532
|
apiKeys.command("list").description("List API keys").option("--include-inactive", "Include revoked/inactive keys").option("--search <term>", "Search by name").option("--limit <n>", "Max results", "50").action(
|
|
@@ -7490,7 +7536,7 @@ function registerApiKeysCommands(program2, globalOpts) {
|
|
|
7490
7536
|
const result = await client.identity.listApiKeys({
|
|
7491
7537
|
limit: parseInt(String(cmdOpts.limit ?? "50"), 10)
|
|
7492
7538
|
});
|
|
7493
|
-
|
|
7539
|
+
formatListProto(ApiKeySchema, result.items, opts, {
|
|
7494
7540
|
columns: [
|
|
7495
7541
|
{ key: "id", header: "ID", width: 28 },
|
|
7496
7542
|
{ key: "name", header: "Name", width: 24 },
|
|
@@ -7529,7 +7575,12 @@ function registerApiKeysCommands(program2, globalOpts) {
|
|
|
7529
7575
|
name: cmdOpts.name
|
|
7530
7576
|
});
|
|
7531
7577
|
if (opts.json || opts.jsonl) {
|
|
7532
|
-
formatOutput(
|
|
7578
|
+
formatOutput(
|
|
7579
|
+
{
|
|
7580
|
+
apiKey: result.apiKey ? toJson4(ApiKeySchema, result.apiKey) : null
|
|
7581
|
+
},
|
|
7582
|
+
opts
|
|
7583
|
+
);
|
|
7533
7584
|
} else {
|
|
7534
7585
|
success(`Created API key: ${result.apiKey?.name}`);
|
|
7535
7586
|
console.log("");
|
|
@@ -7556,7 +7607,12 @@ function registerApiKeysCommands(program2, globalOpts) {
|
|
|
7556
7607
|
const client = await createPlatformClient(opts);
|
|
7557
7608
|
const result = await client.identity.rotateApiKey(id);
|
|
7558
7609
|
if (opts.json || opts.jsonl) {
|
|
7559
|
-
formatOutput(
|
|
7610
|
+
formatOutput(
|
|
7611
|
+
{
|
|
7612
|
+
apiKey: result.apiKey ? toJson4(ApiKeySchema, result.apiKey) : null
|
|
7613
|
+
},
|
|
7614
|
+
opts
|
|
7615
|
+
);
|
|
7560
7616
|
} else {
|
|
7561
7617
|
success(`Rotated API key: ${result.apiKey?.name}`);
|
|
7562
7618
|
console.log("");
|
|
@@ -7597,6 +7653,7 @@ function registerApiKeysCommands(program2, globalOpts) {
|
|
|
7597
7653
|
|
|
7598
7654
|
// src/commands/auth-providers.ts
|
|
7599
7655
|
import chalk11 from "chalk";
|
|
7656
|
+
import { AuthProviderSchema } from "@eide/foir-proto-ts/identity/v1/identity_pb";
|
|
7600
7657
|
var VALID_TYPES = [
|
|
7601
7658
|
"OAUTH2",
|
|
7602
7659
|
"TOKEN_SSO",
|
|
@@ -7614,7 +7671,7 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7614
7671
|
const result = await client.identity.listAuthProviders({
|
|
7615
7672
|
enabled: cmdOpts.enabledOnly ? true : void 0
|
|
7616
7673
|
});
|
|
7617
|
-
|
|
7674
|
+
formatListProto(AuthProviderSchema, result.items, opts, {
|
|
7618
7675
|
columns: [
|
|
7619
7676
|
{ key: "id", header: "ID", width: 28 },
|
|
7620
7677
|
{ key: "key", header: "Key", width: 20 },
|
|
@@ -7646,7 +7703,7 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7646
7703
|
throw new Error(`Auth provider not found: ${id}`);
|
|
7647
7704
|
}
|
|
7648
7705
|
if (opts.json || opts.jsonl) {
|
|
7649
|
-
|
|
7706
|
+
formatOutputProto(AuthProviderSchema, provider, opts);
|
|
7650
7707
|
} else {
|
|
7651
7708
|
const p = provider;
|
|
7652
7709
|
console.log(chalk11.bold(`${p.name}`) + chalk11.gray(` (${p.key})`));
|
|
@@ -7707,7 +7764,7 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7707
7764
|
input
|
|
7708
7765
|
);
|
|
7709
7766
|
if (opts.json || opts.jsonl) {
|
|
7710
|
-
|
|
7767
|
+
formatOutputProto(AuthProviderSchema, provider, opts);
|
|
7711
7768
|
} else {
|
|
7712
7769
|
success(
|
|
7713
7770
|
`Created auth provider: ${provider?.name} (${provider?.key})`
|
|
@@ -7745,7 +7802,7 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7745
7802
|
input
|
|
7746
7803
|
);
|
|
7747
7804
|
if (opts.json || opts.jsonl) {
|
|
7748
|
-
|
|
7805
|
+
formatOutputProto(AuthProviderSchema, provider, opts);
|
|
7749
7806
|
} else {
|
|
7750
7807
|
success(
|
|
7751
7808
|
`Updated auth provider: ${provider?.name} (${provider?.key})`
|
|
@@ -7780,6 +7837,7 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7780
7837
|
}
|
|
7781
7838
|
|
|
7782
7839
|
// src/commands/locales.ts
|
|
7840
|
+
import { LocaleSchema } from "@eide/foir-proto-ts/settings/v1/settings_pb";
|
|
7783
7841
|
function registerLocalesCommands(program2, globalOpts) {
|
|
7784
7842
|
const locales = program2.command("locales").description("Manage locales");
|
|
7785
7843
|
locales.command("list").description("List locales").option("--include-inactive", "Include inactive locales").option("--limit <n>", "Max results", "50").action(
|
|
@@ -7790,7 +7848,7 @@ function registerLocalesCommands(program2, globalOpts) {
|
|
|
7790
7848
|
includeInactive: !!cmdOpts.includeInactive,
|
|
7791
7849
|
limit: parseInt(String(cmdOpts.limit ?? "50"), 10)
|
|
7792
7850
|
});
|
|
7793
|
-
|
|
7851
|
+
formatListProto(LocaleSchema, result.locales, opts, {
|
|
7794
7852
|
columns: [
|
|
7795
7853
|
{ key: "code", header: "Code", width: 8 },
|
|
7796
7854
|
{ key: "name", header: "Name", width: 20 },
|
|
@@ -7823,7 +7881,7 @@ function registerLocalesCommands(program2, globalOpts) {
|
|
|
7823
7881
|
result = await client.settings.getLocaleByCode(idOrCode);
|
|
7824
7882
|
}
|
|
7825
7883
|
if (!result) throw new Error(`Locale "${idOrCode}" not found.`);
|
|
7826
|
-
|
|
7884
|
+
formatOutputProto(LocaleSchema, result, opts);
|
|
7827
7885
|
})
|
|
7828
7886
|
);
|
|
7829
7887
|
locales.command("default").description("Get the default locale").action(
|
|
@@ -7832,7 +7890,7 @@ function registerLocalesCommands(program2, globalOpts) {
|
|
|
7832
7890
|
const client = await createPlatformClient(opts);
|
|
7833
7891
|
const result = await client.settings.getDefaultLocale();
|
|
7834
7892
|
if (!result) throw new Error("No default locale configured.");
|
|
7835
|
-
|
|
7893
|
+
formatOutputProto(LocaleSchema, result, opts);
|
|
7836
7894
|
})
|
|
7837
7895
|
);
|
|
7838
7896
|
locales.command("create").description("Create a new locale").option("-d, --data <json>", "Locale data as JSON").option("-f, --file <path>", "Read data from file").action(
|
|
@@ -7843,9 +7901,9 @@ function registerLocalesCommands(program2, globalOpts) {
|
|
|
7843
7901
|
const result = await client.settings.createLocale(
|
|
7844
7902
|
input
|
|
7845
7903
|
);
|
|
7846
|
-
|
|
7904
|
+
formatOutputProto(LocaleSchema, result, opts);
|
|
7847
7905
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7848
|
-
success(`Created locale ${result?.locale
|
|
7906
|
+
success(`Created locale ${result?.locale}`);
|
|
7849
7907
|
})
|
|
7850
7908
|
);
|
|
7851
7909
|
locales.command("update <id>").description("Update a locale").option("-d, --data <json>", "Locale data as JSON").option("-f, --file <path>", "Read data from file").action(
|
|
@@ -7859,9 +7917,9 @@ function registerLocalesCommands(program2, globalOpts) {
|
|
|
7859
7917
|
id,
|
|
7860
7918
|
...input
|
|
7861
7919
|
});
|
|
7862
|
-
|
|
7920
|
+
formatOutputProto(LocaleSchema, result, opts);
|
|
7863
7921
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7864
|
-
success(`Updated locale ${result?.locale
|
|
7922
|
+
success(`Updated locale ${result?.locale}`);
|
|
7865
7923
|
}
|
|
7866
7924
|
)
|
|
7867
7925
|
);
|
|
@@ -7888,6 +7946,7 @@ function registerLocalesCommands(program2, globalOpts) {
|
|
|
7888
7946
|
}
|
|
7889
7947
|
|
|
7890
7948
|
// src/commands/settings.ts
|
|
7949
|
+
import { SettingSchema } from "@eide/foir-proto-ts/settings/v1/settings_pb";
|
|
7891
7950
|
function inferDataType(value) {
|
|
7892
7951
|
if (value === "true" || value === "false")
|
|
7893
7952
|
return { dataType: "BOOLEAN", parsed: value === "true" };
|
|
@@ -7909,7 +7968,7 @@ function registerSettingsCommands(program2, globalOpts) {
|
|
|
7909
7968
|
const items = await client.settings.getSettings({
|
|
7910
7969
|
category: cmdOpts.category
|
|
7911
7970
|
});
|
|
7912
|
-
|
|
7971
|
+
formatListProto(SettingSchema, items, opts, {
|
|
7913
7972
|
columns: [
|
|
7914
7973
|
{ key: "key", header: "Key", width: 28 },
|
|
7915
7974
|
{
|
|
@@ -7937,7 +7996,7 @@ function registerSettingsCommands(program2, globalOpts) {
|
|
|
7937
7996
|
const items = await client.settings.getSettings({ key });
|
|
7938
7997
|
const setting = items[0] ?? null;
|
|
7939
7998
|
if (!setting) throw new Error(`Setting "${key}" not found.`);
|
|
7940
|
-
|
|
7999
|
+
formatOutputProto(SettingSchema, setting, opts);
|
|
7941
8000
|
})
|
|
7942
8001
|
);
|
|
7943
8002
|
settings.command("set <key> <value>").description("Set a setting value").option("--category <cat>", "Category (required for new settings)").option("--data-type <type>", "Data type (STRING, NUMBER, BOOLEAN, JSON)").action(
|
|
@@ -7961,7 +8020,7 @@ function registerSettingsCommands(program2, globalOpts) {
|
|
|
7961
8020
|
dataType
|
|
7962
8021
|
}
|
|
7963
8022
|
});
|
|
7964
|
-
|
|
8023
|
+
formatOutputProto(SettingSchema, result, opts);
|
|
7965
8024
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
7966
8025
|
success(`Set ${key} = ${value}`);
|
|
7967
8026
|
}
|
|
@@ -7979,6 +8038,7 @@ function registerSettingsCommands(program2, globalOpts) {
|
|
|
7979
8038
|
}
|
|
7980
8039
|
|
|
7981
8040
|
// src/commands/variant-catalog.ts
|
|
8041
|
+
import { VariantCatalogEntrySchema } from "@eide/foir-proto-ts/settings/v1/settings_pb";
|
|
7982
8042
|
function registerVariantCatalogCommands(program2, globalOpts) {
|
|
7983
8043
|
const catalog = program2.command("variant-catalog").description("Manage variant catalog entries (markets, devices, locales)");
|
|
7984
8044
|
catalog.command("list").description("List variant catalog entries").option("--active", "Only active entries").option("--limit <n>", "Max results", "50").action(
|
|
@@ -7989,7 +8049,7 @@ function registerVariantCatalogCommands(program2, globalOpts) {
|
|
|
7989
8049
|
isActive: cmdOpts.active ? true : void 0,
|
|
7990
8050
|
limit: parseInt(String(cmdOpts.limit ?? "50"), 10)
|
|
7991
8051
|
});
|
|
7992
|
-
|
|
8052
|
+
formatListProto(VariantCatalogEntrySchema, result.entries, opts, {
|
|
7993
8053
|
columns: [
|
|
7994
8054
|
{ key: "key", header: "Key", width: 20 },
|
|
7995
8055
|
{ key: "name", header: "Name", width: 24 },
|
|
@@ -8024,7 +8084,7 @@ function registerVariantCatalogCommands(program2, globalOpts) {
|
|
|
8024
8084
|
}
|
|
8025
8085
|
if (!result)
|
|
8026
8086
|
throw new Error(`Variant catalog entry "${idOrKey}" not found.`);
|
|
8027
|
-
|
|
8087
|
+
formatOutputProto(VariantCatalogEntrySchema, result, opts);
|
|
8028
8088
|
})
|
|
8029
8089
|
);
|
|
8030
8090
|
catalog.command("create").description("Create a variant catalog entry").option("-d, --data <json>", "Entry data as JSON").option("-f, --file <path>", "Read data from file").action(
|
|
@@ -8035,11 +8095,9 @@ function registerVariantCatalogCommands(program2, globalOpts) {
|
|
|
8035
8095
|
const result = await client.settings.createVariantCatalogEntry(
|
|
8036
8096
|
input
|
|
8037
8097
|
);
|
|
8038
|
-
|
|
8098
|
+
formatOutputProto(VariantCatalogEntrySchema, result, opts);
|
|
8039
8099
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
8040
|
-
success(
|
|
8041
|
-
`Created variant catalog entry ${result?.key}`
|
|
8042
|
-
);
|
|
8100
|
+
success(`Created variant catalog entry ${result?.key}`);
|
|
8043
8101
|
})
|
|
8044
8102
|
);
|
|
8045
8103
|
catalog.command("update <id>").description("Update a variant catalog entry").option("-d, --data <json>", "Entry data as JSON").option("-f, --file <path>", "Read data from file").action(
|
|
@@ -8053,11 +8111,9 @@ function registerVariantCatalogCommands(program2, globalOpts) {
|
|
|
8053
8111
|
id,
|
|
8054
8112
|
...input
|
|
8055
8113
|
});
|
|
8056
|
-
|
|
8114
|
+
formatOutputProto(VariantCatalogEntrySchema, result, opts);
|
|
8057
8115
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
8058
|
-
success(
|
|
8059
|
-
`Updated variant catalog entry ${result?.key}`
|
|
8060
|
-
);
|
|
8116
|
+
success(`Updated variant catalog entry ${result?.key}`);
|
|
8061
8117
|
}
|
|
8062
8118
|
)
|
|
8063
8119
|
);
|
|
@@ -8085,6 +8141,10 @@ function registerVariantCatalogCommands(program2, globalOpts) {
|
|
|
8085
8141
|
}
|
|
8086
8142
|
|
|
8087
8143
|
// src/commands/files.ts
|
|
8144
|
+
import {
|
|
8145
|
+
FileSchema as FileSchema2,
|
|
8146
|
+
StorageUsageSchema as StorageUsageSchema2
|
|
8147
|
+
} from "@eide/foir-proto-ts/storage/v1/storage_pb";
|
|
8088
8148
|
function registerFilesCommands(program2, globalOpts) {
|
|
8089
8149
|
const files = program2.command("files").description("Manage files (for upload, use `foir media upload`)");
|
|
8090
8150
|
files.command("list").description("List files").option("--folder <folder>", "Filter by folder").option("--mime-type <type>", "Filter by MIME type").option("--search <term>", "Search by filename").option("--limit <n>", "Max results", "50").option("--offset <n>", "Skip results", "0").action(
|
|
@@ -8098,7 +8158,7 @@ function registerFilesCommands(program2, globalOpts) {
|
|
|
8098
8158
|
limit: parseInt(cmdOpts.limit ?? "50", 10),
|
|
8099
8159
|
offset: parseInt(cmdOpts.offset ?? "0", 10)
|
|
8100
8160
|
});
|
|
8101
|
-
|
|
8161
|
+
formatListProto(FileSchema2, data.items, opts, {
|
|
8102
8162
|
columns: [
|
|
8103
8163
|
{ key: "id", header: "ID", width: 28 },
|
|
8104
8164
|
{ key: "filename", header: "Filename", width: 30 },
|
|
@@ -8127,7 +8187,7 @@ function registerFilesCommands(program2, globalOpts) {
|
|
|
8127
8187
|
const client = await createPlatformClient(opts);
|
|
8128
8188
|
const file = await client.storage.getFile(id);
|
|
8129
8189
|
if (!file) throw new Error(`File "${id}" not found.`);
|
|
8130
|
-
|
|
8190
|
+
formatOutputProto(FileSchema2, file, opts);
|
|
8131
8191
|
})
|
|
8132
8192
|
);
|
|
8133
8193
|
files.command("usage").description("Get storage usage statistics").action(
|
|
@@ -8135,7 +8195,7 @@ function registerFilesCommands(program2, globalOpts) {
|
|
|
8135
8195
|
const opts = globalOpts();
|
|
8136
8196
|
const client = await createPlatformClient(opts);
|
|
8137
8197
|
const usage = await client.storage.getStorageUsage();
|
|
8138
|
-
|
|
8198
|
+
formatOutputProto(StorageUsageSchema2, usage, opts);
|
|
8139
8199
|
})
|
|
8140
8200
|
);
|
|
8141
8201
|
files.command("update <id>").description("Update file properties").option("--filename <name>", "New filename").option("--folder <folder>", "Move to folder").option("--tags <tags>", "Comma-separated tags").action(
|
|
@@ -8150,7 +8210,7 @@ function registerFilesCommands(program2, globalOpts) {
|
|
|
8150
8210
|
if (cmdOpts.tags)
|
|
8151
8211
|
params.tags = cmdOpts.tags.split(",").map((t) => t.trim());
|
|
8152
8212
|
const file = await client.storage.updateFile(params);
|
|
8153
|
-
|
|
8213
|
+
formatOutputProto(FileSchema2, file, opts);
|
|
8154
8214
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
8155
8215
|
success(`Updated file ${id}`);
|
|
8156
8216
|
}
|
|
@@ -8168,7 +8228,7 @@ function registerFilesCommands(program2, globalOpts) {
|
|
|
8168
8228
|
caption: cmdOpts.caption,
|
|
8169
8229
|
description: cmdOpts.description
|
|
8170
8230
|
});
|
|
8171
|
-
|
|
8231
|
+
formatOutputProto(FileSchema2, file, opts);
|
|
8172
8232
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
8173
8233
|
success(`Updated metadata for file ${id}`);
|
|
8174
8234
|
}
|
|
@@ -8206,6 +8266,7 @@ function formatBytes(bytes) {
|
|
|
8206
8266
|
}
|
|
8207
8267
|
|
|
8208
8268
|
// src/commands/notes.ts
|
|
8269
|
+
import { NoteSchema } from "@eide/foir-proto-ts/settings/v1/settings_pb";
|
|
8209
8270
|
function registerNotesCommands(program2, globalOpts) {
|
|
8210
8271
|
const notes = program2.command("notes").description("Manage notes and comments");
|
|
8211
8272
|
notes.command("list").description("List notes for an entity").requiredOption("--entity-type <type>", "Entity type (e.g. record, model)").requiredOption("--entity-id <id>", "Entity ID").option("--include-resolved", "Include resolved notes").option("--limit <n>", "Max results", "20").action(
|
|
@@ -8217,7 +8278,7 @@ function registerNotesCommands(program2, globalOpts) {
|
|
|
8217
8278
|
entityId: cmdOpts.entityId,
|
|
8218
8279
|
limit: parseInt(String(cmdOpts.limit ?? "20"), 10)
|
|
8219
8280
|
});
|
|
8220
|
-
|
|
8281
|
+
formatListProto(NoteSchema, data.notes, opts, {
|
|
8221
8282
|
columns: [
|
|
8222
8283
|
{ key: "id", header: "ID", width: 28 },
|
|
8223
8284
|
{ key: "content", header: "Content", width: 40 },
|
|
@@ -8245,7 +8306,7 @@ function registerNotesCommands(program2, globalOpts) {
|
|
|
8245
8306
|
const client = await createPlatformClient(opts);
|
|
8246
8307
|
const note = await client.settings.getNote(id);
|
|
8247
8308
|
if (!note) throw new Error(`Note "${id}" not found.`);
|
|
8248
|
-
|
|
8309
|
+
formatOutputProto(NoteSchema, note, opts);
|
|
8249
8310
|
})
|
|
8250
8311
|
);
|
|
8251
8312
|
notes.command("create").description("Create a note").requiredOption("--entity-type <type>", "Entity type").requiredOption("--entity-id <id>", "Entity ID").requiredOption("--body <text>", "Note body text").option("--parent-note-id <id>", "Reply to a note").action(
|
|
@@ -8261,7 +8322,7 @@ function registerNotesCommands(program2, globalOpts) {
|
|
|
8261
8322
|
};
|
|
8262
8323
|
if (cmdOpts.parentNoteId) params.parentNoteId = cmdOpts.parentNoteId;
|
|
8263
8324
|
const note = await client.settings.createNote(params);
|
|
8264
|
-
|
|
8325
|
+
formatOutputProto(NoteSchema, note, opts);
|
|
8265
8326
|
if (!(opts.json || opts.jsonl || opts.quiet)) success("Note created");
|
|
8266
8327
|
})
|
|
8267
8328
|
);
|
|
@@ -8275,7 +8336,7 @@ function registerNotesCommands(program2, globalOpts) {
|
|
|
8275
8336
|
id,
|
|
8276
8337
|
isResolved: true
|
|
8277
8338
|
});
|
|
8278
|
-
|
|
8339
|
+
formatOutputProto(NoteSchema, note, opts);
|
|
8279
8340
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
8280
8341
|
success(`Resolved note ${id}`);
|
|
8281
8342
|
}
|
|
@@ -8304,6 +8365,7 @@ function registerNotesCommands(program2, globalOpts) {
|
|
|
8304
8365
|
}
|
|
8305
8366
|
|
|
8306
8367
|
// src/commands/notifications.ts
|
|
8368
|
+
import { NotificationSchema } from "@eide/foir-proto-ts/notifications/v1/notifications_pb";
|
|
8307
8369
|
function registerNotificationsCommands(program2, globalOpts) {
|
|
8308
8370
|
const notifications = program2.command("notifications").description("Manage notifications");
|
|
8309
8371
|
notifications.command("list").description("List notifications").option("--unread", "Only unread notifications").option("--limit <n>", "Max results", "20").action(
|
|
@@ -8318,7 +8380,7 @@ function registerNotificationsCommands(program2, globalOpts) {
|
|
|
8318
8380
|
console.log(`Unread: ${data.unreadCount}
|
|
8319
8381
|
`);
|
|
8320
8382
|
}
|
|
8321
|
-
|
|
8383
|
+
formatListProto(NotificationSchema, data.notifications, opts, {
|
|
8322
8384
|
columns: [
|
|
8323
8385
|
{ key: "id", header: "ID", width: 28 },
|
|
8324
8386
|
{ key: "type", header: "Type", width: 16 },
|
|
@@ -8367,6 +8429,7 @@ function registerNotificationsCommands(program2, globalOpts) {
|
|
|
8367
8429
|
}
|
|
8368
8430
|
|
|
8369
8431
|
// src/commands/configs.ts
|
|
8432
|
+
import { ConfigSchema } from "@eide/foir-proto-ts/configs/v1/configs_pb";
|
|
8370
8433
|
function registerConfigsCommands(program2, globalOpts) {
|
|
8371
8434
|
const configs = program2.command("configs").description("Manage configs (apps, webhooks)");
|
|
8372
8435
|
configs.command("list").description("List configs").option("--type <type>", "Filter by config type").option("--enabled", "Only enabled configs").option("--limit <n>", "Max results", "50").action(
|
|
@@ -8378,7 +8441,7 @@ function registerConfigsCommands(program2, globalOpts) {
|
|
|
8378
8441
|
enabled: cmdOpts.enabled ? true : void 0,
|
|
8379
8442
|
limit: parseInt(String(cmdOpts.limit ?? "50"), 10)
|
|
8380
8443
|
});
|
|
8381
|
-
|
|
8444
|
+
formatListProto(ConfigSchema, data.configs, opts, {
|
|
8382
8445
|
columns: [
|
|
8383
8446
|
{ key: "id", header: "ID", width: 28 },
|
|
8384
8447
|
{ key: "key", header: "Key", width: 20 },
|
|
@@ -8406,7 +8469,7 @@ function registerConfigsCommands(program2, globalOpts) {
|
|
|
8406
8469
|
result = await client.configs.getConfigByKey(idOrKey);
|
|
8407
8470
|
}
|
|
8408
8471
|
if (!result) throw new Error(`Config "${idOrKey}" not found.`);
|
|
8409
|
-
|
|
8472
|
+
formatOutputProto(ConfigSchema, result, opts);
|
|
8410
8473
|
})
|
|
8411
8474
|
);
|
|
8412
8475
|
configs.command("create").description("Create a new config").option("-d, --data <json>", "Config data as JSON").option("-f, --file <path>", "Read data from file").action(
|
|
@@ -8415,7 +8478,7 @@ function registerConfigsCommands(program2, globalOpts) {
|
|
|
8415
8478
|
const client = await createPlatformClient(opts);
|
|
8416
8479
|
const input = await parseInputData(cmdOpts);
|
|
8417
8480
|
const config2 = await client.configs.createConfig(input);
|
|
8418
|
-
|
|
8481
|
+
formatOutputProto(ConfigSchema, config2, opts);
|
|
8419
8482
|
if (!(opts.json || opts.jsonl || opts.quiet))
|
|
8420
8483
|
success(`Created config ${config2?.key}`);
|
|
8421
8484
|
})
|
|
@@ -8437,6 +8500,10 @@ function registerConfigsCommands(program2, globalOpts) {
|
|
|
8437
8500
|
}
|
|
8438
8501
|
|
|
8439
8502
|
// src/commands/apps.ts
|
|
8503
|
+
import {
|
|
8504
|
+
AppSchema,
|
|
8505
|
+
ValidateManifestResponseSchema
|
|
8506
|
+
} from "@eide/foir-proto-ts/apps/v1/apps_service_pb";
|
|
8440
8507
|
function registerAppsCommands(program2, globalOpts) {
|
|
8441
8508
|
const apps = program2.command("apps").description("Install and manage apps");
|
|
8442
8509
|
apps.command("list").description("List installed apps").action(
|
|
@@ -8448,7 +8515,7 @@ function registerAppsCommands(program2, globalOpts) {
|
|
|
8448
8515
|
resolved.project.tenantId,
|
|
8449
8516
|
resolved.project.id
|
|
8450
8517
|
);
|
|
8451
|
-
|
|
8518
|
+
formatListProto(AppSchema, apps2, opts, {
|
|
8452
8519
|
columns: [
|
|
8453
8520
|
{ key: "name", header: "Name", width: 24 },
|
|
8454
8521
|
{
|
|
@@ -8463,9 +8530,10 @@ function registerAppsCommands(program2, globalOpts) {
|
|
|
8463
8530
|
header: "Installed",
|
|
8464
8531
|
width: 12,
|
|
8465
8532
|
format: (v) => {
|
|
8466
|
-
|
|
8467
|
-
|
|
8468
|
-
|
|
8533
|
+
if (!v) return "";
|
|
8534
|
+
const date = new Date(v);
|
|
8535
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
8536
|
+
return date.toLocaleDateString();
|
|
8469
8537
|
}
|
|
8470
8538
|
}
|
|
8471
8539
|
]
|
|
@@ -8483,7 +8551,7 @@ function registerAppsCommands(program2, globalOpts) {
|
|
|
8483
8551
|
name
|
|
8484
8552
|
);
|
|
8485
8553
|
if (!app) throw new Error(`App "${name}" not installed.`);
|
|
8486
|
-
|
|
8554
|
+
formatOutputProto(AppSchema, app, opts);
|
|
8487
8555
|
})
|
|
8488
8556
|
);
|
|
8489
8557
|
apps.command("install <manifestUrl>").description("Install an app from a manifest URL").option(
|
|
@@ -8544,7 +8612,7 @@ function registerAppsCommands(program2, globalOpts) {
|
|
|
8544
8612
|
placementFieldChoices
|
|
8545
8613
|
});
|
|
8546
8614
|
if (opts.json) {
|
|
8547
|
-
|
|
8615
|
+
formatOutputProto(AppSchema, app, opts);
|
|
8548
8616
|
} else {
|
|
8549
8617
|
success(`Installed ${app?.name ?? ""}`);
|
|
8550
8618
|
}
|
|
@@ -8587,7 +8655,7 @@ function registerAppsCommands(program2, globalOpts) {
|
|
|
8587
8655
|
updateResp.newManifestHash
|
|
8588
8656
|
);
|
|
8589
8657
|
if (opts.json) {
|
|
8590
|
-
|
|
8658
|
+
formatOutputProto(AppSchema, app, opts);
|
|
8591
8659
|
} else {
|
|
8592
8660
|
success(`Updated ${name}`);
|
|
8593
8661
|
}
|
|
@@ -8645,7 +8713,7 @@ function registerAppsCommands(program2, globalOpts) {
|
|
|
8645
8713
|
const client = await createPlatformClient(opts);
|
|
8646
8714
|
const resp = await client.apps.validateManifestUrl(manifestUrl);
|
|
8647
8715
|
if (opts.json) {
|
|
8648
|
-
|
|
8716
|
+
formatOutputProto(ValidateManifestResponseSchema, resp, opts);
|
|
8649
8717
|
return;
|
|
8650
8718
|
}
|
|
8651
8719
|
if (resp.ok) {
|