@eide/foir-cli 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +884 -23
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -469,7 +469,7 @@ import { StorageService as StorageService2 } from "@eide/foir-proto-ts/storage/v
|
|
|
469
469
|
import { OperationsService as OperationsService2 } from "@eide/foir-proto-ts/operations/v1/operations_pb";
|
|
470
470
|
import { HooksService as HooksService2 } from "@eide/foir-proto-ts/hooks/v1/hooks_pb";
|
|
471
471
|
import { NotificationsService as NotificationsService2 } from "@eide/foir-proto-ts/notifications/v1/notifications_pb";
|
|
472
|
-
import { SchedulesService as
|
|
472
|
+
import { SchedulesService as SchedulesService3 } from "@eide/foir-proto-ts/schedules/v1/schedules_pb";
|
|
473
473
|
import { AppsService as AppsService2 } from "@eide/foir-proto-ts/apps/v1/apps_service_pb";
|
|
474
474
|
import { SecretsService as SecretsService2 } from "@eide/foir-proto-ts/secrets/v1/secrets_pb";
|
|
475
475
|
|
|
@@ -1464,7 +1464,10 @@ import {
|
|
|
1464
1464
|
GlobalSearchRequestSchema,
|
|
1465
1465
|
GetEmbeddingStatsRequestSchema,
|
|
1466
1466
|
GetRecordEmbeddingsRequestSchema,
|
|
1467
|
-
FindSimilarRecordsRequestSchema
|
|
1467
|
+
FindSimilarRecordsRequestSchema,
|
|
1468
|
+
WriteEmbeddingsRequestSchema,
|
|
1469
|
+
DeleteEmbeddingsRequestSchema,
|
|
1470
|
+
SearchEmbeddingsRequestSchema
|
|
1468
1471
|
} from "@eide/foir-proto-ts/records/v1/records_pb";
|
|
1469
1472
|
import { RecordType } from "@eide/foir-proto-ts/records/v1/records_pb";
|
|
1470
1473
|
function sanitizeData(obj) {
|
|
@@ -1812,6 +1815,34 @@ function createRecordsMethods(client) {
|
|
|
1812
1815
|
})
|
|
1813
1816
|
);
|
|
1814
1817
|
return resp.records ?? [];
|
|
1818
|
+
},
|
|
1819
|
+
async writeEmbeddings(params) {
|
|
1820
|
+
const resp = await client.writeEmbeddings(
|
|
1821
|
+
create4(WriteEmbeddingsRequestSchema, {
|
|
1822
|
+
recordId: params.recordId,
|
|
1823
|
+
vector: params.vector,
|
|
1824
|
+
dimensions: params.dimensions,
|
|
1825
|
+
provider: params.provider,
|
|
1826
|
+
modelName: params.modelName
|
|
1827
|
+
})
|
|
1828
|
+
);
|
|
1829
|
+
return resp.success;
|
|
1830
|
+
},
|
|
1831
|
+
async deleteEmbeddings(recordId) {
|
|
1832
|
+
const resp = await client.deleteEmbeddings(
|
|
1833
|
+
create4(DeleteEmbeddingsRequestSchema, { recordId })
|
|
1834
|
+
);
|
|
1835
|
+
return resp.success;
|
|
1836
|
+
},
|
|
1837
|
+
async searchEmbeddings(params) {
|
|
1838
|
+
const resp = await client.searchEmbeddings(
|
|
1839
|
+
create4(SearchEmbeddingsRequestSchema, {
|
|
1840
|
+
queryVector: params.queryVector,
|
|
1841
|
+
modelKey: params.modelKey,
|
|
1842
|
+
limit: params.limit ?? 10
|
|
1843
|
+
})
|
|
1844
|
+
);
|
|
1845
|
+
return resp.results ?? [];
|
|
1815
1846
|
}
|
|
1816
1847
|
};
|
|
1817
1848
|
}
|
|
@@ -3032,8 +3063,144 @@ function createCronSchedulesMethods(client) {
|
|
|
3032
3063
|
};
|
|
3033
3064
|
}
|
|
3034
3065
|
|
|
3035
|
-
// src/lib/rpc/
|
|
3066
|
+
// src/lib/rpc/publish-batches.ts
|
|
3036
3067
|
import { create as create13 } from "@bufbuild/protobuf";
|
|
3068
|
+
import { timestampFromDate } from "@bufbuild/protobuf/wkt";
|
|
3069
|
+
import {
|
|
3070
|
+
ListPublishBatchesRequestSchema,
|
|
3071
|
+
GetPublishBatchRequestSchema,
|
|
3072
|
+
CreatePublishBatchRequestSchema,
|
|
3073
|
+
UpdatePublishBatchRequestSchema,
|
|
3074
|
+
DeletePublishBatchRequestSchema,
|
|
3075
|
+
TriggerPublishBatchRequestSchema,
|
|
3076
|
+
PausePublishBatchRequestSchema,
|
|
3077
|
+
ResumePublishBatchRequestSchema,
|
|
3078
|
+
PreviewRollbackBatchRequestSchema,
|
|
3079
|
+
RollbackPublishBatchRequestSchema,
|
|
3080
|
+
RetryFailedBatchItemsRequestSchema,
|
|
3081
|
+
AddItemsToPublishBatchRequestSchema,
|
|
3082
|
+
RemoveItemsFromPublishBatchRequestSchema
|
|
3083
|
+
} from "@eide/foir-proto-ts/schedules/v1/schedules_pb";
|
|
3084
|
+
function createPublishBatchesMethods(client) {
|
|
3085
|
+
return {
|
|
3086
|
+
async listPublishBatches(params = {}) {
|
|
3087
|
+
const resp = await client.listPublishBatches(
|
|
3088
|
+
create13(ListPublishBatchesRequestSchema, {
|
|
3089
|
+
status: params.status,
|
|
3090
|
+
limit: params.limit ?? 50,
|
|
3091
|
+
offset: params.offset ?? 0
|
|
3092
|
+
})
|
|
3093
|
+
);
|
|
3094
|
+
return { batches: resp.batches ?? [], total: resp.total };
|
|
3095
|
+
},
|
|
3096
|
+
async getPublishBatch(id) {
|
|
3097
|
+
const resp = await client.getPublishBatch(
|
|
3098
|
+
create13(GetPublishBatchRequestSchema, { id })
|
|
3099
|
+
);
|
|
3100
|
+
return { batch: resp.batch ?? null, items: resp.items ?? [] };
|
|
3101
|
+
},
|
|
3102
|
+
async createPublishBatch(input) {
|
|
3103
|
+
const resp = await client.createPublishBatch(
|
|
3104
|
+
create13(CreatePublishBatchRequestSchema, {
|
|
3105
|
+
name: input.name,
|
|
3106
|
+
description: input.description,
|
|
3107
|
+
scheduledAt: timestampFromDate(input.scheduledAt),
|
|
3108
|
+
versionIds: input.versionIds ?? [],
|
|
3109
|
+
modelIds: input.modelIds ?? [],
|
|
3110
|
+
operationIds: input.operationIds ?? [],
|
|
3111
|
+
contextDimensionIds: input.contextDimensionIds ?? [],
|
|
3112
|
+
authProviderIds: input.authProviderIds ?? [],
|
|
3113
|
+
includeProfileSchema: input.includeProfileSchema ?? false
|
|
3114
|
+
})
|
|
3115
|
+
);
|
|
3116
|
+
return resp.batch ?? null;
|
|
3117
|
+
},
|
|
3118
|
+
async updatePublishBatch(input) {
|
|
3119
|
+
const resp = await client.updatePublishBatch(
|
|
3120
|
+
create13(UpdatePublishBatchRequestSchema, {
|
|
3121
|
+
id: input.id,
|
|
3122
|
+
name: input.name,
|
|
3123
|
+
description: input.description,
|
|
3124
|
+
scheduledAt: input.scheduledAt ? timestampFromDate(input.scheduledAt) : void 0
|
|
3125
|
+
})
|
|
3126
|
+
);
|
|
3127
|
+
return resp.batch ?? null;
|
|
3128
|
+
},
|
|
3129
|
+
async deletePublishBatch(id) {
|
|
3130
|
+
const resp = await client.deletePublishBatch(
|
|
3131
|
+
create13(DeletePublishBatchRequestSchema, { id })
|
|
3132
|
+
);
|
|
3133
|
+
return resp.success;
|
|
3134
|
+
},
|
|
3135
|
+
async triggerPublishBatch(id) {
|
|
3136
|
+
const resp = await client.triggerPublishBatch(
|
|
3137
|
+
create13(TriggerPublishBatchRequestSchema, { id })
|
|
3138
|
+
);
|
|
3139
|
+
return resp.batch ?? null;
|
|
3140
|
+
},
|
|
3141
|
+
async pausePublishBatch(id) {
|
|
3142
|
+
const resp = await client.pausePublishBatch(
|
|
3143
|
+
create13(PausePublishBatchRequestSchema, { id })
|
|
3144
|
+
);
|
|
3145
|
+
return resp.batch ?? null;
|
|
3146
|
+
},
|
|
3147
|
+
async resumePublishBatch(id) {
|
|
3148
|
+
const resp = await client.resumePublishBatch(
|
|
3149
|
+
create13(ResumePublishBatchRequestSchema, { id })
|
|
3150
|
+
);
|
|
3151
|
+
return resp.batch ?? null;
|
|
3152
|
+
},
|
|
3153
|
+
async previewRollback(batchId) {
|
|
3154
|
+
const resp = await client.previewRollbackBatch(
|
|
3155
|
+
create13(PreviewRollbackBatchRequestSchema, { batchId })
|
|
3156
|
+
);
|
|
3157
|
+
return resp;
|
|
3158
|
+
},
|
|
3159
|
+
async rollbackPublishBatch(batchId) {
|
|
3160
|
+
const resp = await client.rollbackPublishBatch(
|
|
3161
|
+
create13(RollbackPublishBatchRequestSchema, { batchId })
|
|
3162
|
+
);
|
|
3163
|
+
return resp.batch ?? null;
|
|
3164
|
+
},
|
|
3165
|
+
async retryFailedItems(batchId) {
|
|
3166
|
+
const resp = await client.retryFailedBatchItems(
|
|
3167
|
+
create13(RetryFailedBatchItemsRequestSchema, { batchId })
|
|
3168
|
+
);
|
|
3169
|
+
return resp.batch ?? null;
|
|
3170
|
+
},
|
|
3171
|
+
async addItems(input) {
|
|
3172
|
+
const resp = await client.addItemsToPublishBatch(
|
|
3173
|
+
create13(AddItemsToPublishBatchRequestSchema, {
|
|
3174
|
+
batchId: input.batchId,
|
|
3175
|
+
versionIds: input.versionIds ?? [],
|
|
3176
|
+
modelIds: input.modelIds ?? [],
|
|
3177
|
+
operationIds: input.operationIds ?? [],
|
|
3178
|
+
contextDimensionIds: input.contextDimensionIds ?? [],
|
|
3179
|
+
authProviderIds: input.authProviderIds ?? [],
|
|
3180
|
+
includeProfileSchema: input.includeProfileSchema ?? false
|
|
3181
|
+
})
|
|
3182
|
+
);
|
|
3183
|
+
return resp.batch ?? null;
|
|
3184
|
+
},
|
|
3185
|
+
async removeItems(input) {
|
|
3186
|
+
const resp = await client.removeItemsFromPublishBatch(
|
|
3187
|
+
create13(RemoveItemsFromPublishBatchRequestSchema, {
|
|
3188
|
+
batchId: input.batchId,
|
|
3189
|
+
versionIds: input.versionIds ?? [],
|
|
3190
|
+
modelIds: input.modelIds ?? [],
|
|
3191
|
+
operationIds: input.operationIds ?? [],
|
|
3192
|
+
contextDimensionIds: input.contextDimensionIds ?? [],
|
|
3193
|
+
authProviderIds: input.authProviderIds ?? [],
|
|
3194
|
+
excludeProfileSchema: input.excludeProfileSchema ?? false
|
|
3195
|
+
})
|
|
3196
|
+
);
|
|
3197
|
+
return resp.batch ?? null;
|
|
3198
|
+
}
|
|
3199
|
+
};
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3202
|
+
// src/lib/rpc/secrets.ts
|
|
3203
|
+
import { create as create14 } from "@bufbuild/protobuf";
|
|
3037
3204
|
import {
|
|
3038
3205
|
PutSecretRequestSchema,
|
|
3039
3206
|
GetSecretRequestSchema,
|
|
@@ -3048,7 +3215,7 @@ function createSecretsMethods(client) {
|
|
|
3048
3215
|
return {
|
|
3049
3216
|
async put(args) {
|
|
3050
3217
|
const resp = await client.putSecret(
|
|
3051
|
-
|
|
3218
|
+
create14(PutSecretRequestSchema, {
|
|
3052
3219
|
tenantId: args.tenantId,
|
|
3053
3220
|
projectId: args.projectId,
|
|
3054
3221
|
ownerKind: args.ownerKind,
|
|
@@ -3061,12 +3228,12 @@ function createSecretsMethods(client) {
|
|
|
3061
3228
|
},
|
|
3062
3229
|
async get(ref, purpose) {
|
|
3063
3230
|
return client.getSecret(
|
|
3064
|
-
|
|
3231
|
+
create14(GetSecretRequestSchema, { ref, purpose: purpose ?? "" })
|
|
3065
3232
|
);
|
|
3066
3233
|
},
|
|
3067
3234
|
async list(args) {
|
|
3068
3235
|
const resp = await client.listSecrets(
|
|
3069
|
-
|
|
3236
|
+
create14(ListSecretsRequestSchema, {
|
|
3070
3237
|
tenantId: args.tenantId,
|
|
3071
3238
|
projectId: args.projectId,
|
|
3072
3239
|
ownerKind: args.ownerKind ?? OwnerKind.UNSPECIFIED,
|
|
@@ -3078,19 +3245,19 @@ function createSecretsMethods(client) {
|
|
|
3078
3245
|
},
|
|
3079
3246
|
async rotate(ref, plaintext) {
|
|
3080
3247
|
const resp = await client.rotateSecret(
|
|
3081
|
-
|
|
3248
|
+
create14(RotateSecretRequestSchema, { ref, plaintext })
|
|
3082
3249
|
);
|
|
3083
3250
|
return resp.newRef;
|
|
3084
3251
|
},
|
|
3085
3252
|
async delete(ref) {
|
|
3086
|
-
await client.deleteSecret(
|
|
3253
|
+
await client.deleteSecret(create14(DeleteSecretRequestSchema, { ref }));
|
|
3087
3254
|
},
|
|
3088
3255
|
async restore(ref) {
|
|
3089
|
-
await client.restoreSecret(
|
|
3256
|
+
await client.restoreSecret(create14(RestoreSecretRequestSchema, { ref }));
|
|
3090
3257
|
},
|
|
3091
3258
|
async purge(args = {}) {
|
|
3092
3259
|
const resp = await client.purgeSoftDeleted(
|
|
3093
|
-
|
|
3260
|
+
create14(PurgeSoftDeletedRequestSchema, {
|
|
3094
3261
|
tenantId: args.tenantId ?? "",
|
|
3095
3262
|
projectId: args.projectId ?? ""
|
|
3096
3263
|
})
|
|
@@ -3154,7 +3321,10 @@ async function createPlatformClient(options) {
|
|
|
3154
3321
|
createRpcClient(NotificationsService2, transport)
|
|
3155
3322
|
),
|
|
3156
3323
|
cronSchedules: createCronSchedulesMethods(
|
|
3157
|
-
createRpcClient(
|
|
3324
|
+
createRpcClient(SchedulesService3, transport)
|
|
3325
|
+
),
|
|
3326
|
+
publishBatches: createPublishBatchesMethods(
|
|
3327
|
+
createRpcClient(SchedulesService3, transport)
|
|
3158
3328
|
),
|
|
3159
3329
|
apps: createAppsMethods(createRpcClient(AppsService2, transport)),
|
|
3160
3330
|
secrets: createSecretsMethods(createRpcClient(SecretsService2, transport))
|
|
@@ -3188,7 +3358,10 @@ function createPlatformClientWithHeaders(apiUrl, headers) {
|
|
|
3188
3358
|
createRpcClient(NotificationsService2, transport)
|
|
3189
3359
|
),
|
|
3190
3360
|
cronSchedules: createCronSchedulesMethods(
|
|
3191
|
-
createRpcClient(
|
|
3361
|
+
createRpcClient(SchedulesService3, transport)
|
|
3362
|
+
),
|
|
3363
|
+
publishBatches: createPublishBatchesMethods(
|
|
3364
|
+
createRpcClient(SchedulesService3, transport)
|
|
3192
3365
|
),
|
|
3193
3366
|
apps: createAppsMethods(createRpcClient(AppsService2, transport)),
|
|
3194
3367
|
secrets: createSecretsMethods(createRpcClient(SecretsService2, transport))
|
|
@@ -7501,8 +7674,61 @@ function registerApiKeysCommands(program2, globalOpts) {
|
|
|
7501
7674
|
);
|
|
7502
7675
|
}
|
|
7503
7676
|
|
|
7504
|
-
// src/commands/auth
|
|
7677
|
+
// src/commands/auth.ts
|
|
7505
7678
|
import chalk11 from "chalk";
|
|
7679
|
+
import { CustomerAuthConfigSchema } from "@eide/foir-proto-ts/identity/v1/identity_pb";
|
|
7680
|
+
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
7681
|
+
function registerAuthCommands(program2, globalOpts) {
|
|
7682
|
+
const auth = program2.command("auth").description("Inspect customer auth configuration and verify customer tokens");
|
|
7683
|
+
auth.command("config").description("Print the project's customer-auth configuration").action(
|
|
7684
|
+
withErrorHandler(globalOpts, async () => {
|
|
7685
|
+
const opts = globalOpts();
|
|
7686
|
+
const client = await createPlatformClient(opts);
|
|
7687
|
+
const config2 = await client.identity.getCustomerAuthConfig();
|
|
7688
|
+
if (!config2) {
|
|
7689
|
+
throw new Error("No customer auth configuration found for this project.");
|
|
7690
|
+
}
|
|
7691
|
+
formatOutputProto(CustomerAuthConfigSchema, config2, opts);
|
|
7692
|
+
})
|
|
7693
|
+
);
|
|
7694
|
+
auth.command("verify-token <token>").description("Verify a customer JWT and print its claims").action(
|
|
7695
|
+
withErrorHandler(globalOpts, async (token) => {
|
|
7696
|
+
const opts = globalOpts();
|
|
7697
|
+
const client = await createPlatformClient(opts);
|
|
7698
|
+
const resp = await client.identity.verifyCustomerToken(token);
|
|
7699
|
+
const expiresAtIso = resp.expiresAt ? timestampDate(resp.expiresAt).toISOString() : null;
|
|
7700
|
+
if (opts.json || opts.jsonl) {
|
|
7701
|
+
formatOutput(
|
|
7702
|
+
{
|
|
7703
|
+
valid: resp.valid,
|
|
7704
|
+
customerId: resp.customerId ?? null,
|
|
7705
|
+
email: resp.email ?? null,
|
|
7706
|
+
roles: resp.roles ?? [],
|
|
7707
|
+
expiresAt: expiresAtIso,
|
|
7708
|
+
error: resp.error ?? null
|
|
7709
|
+
},
|
|
7710
|
+
opts
|
|
7711
|
+
);
|
|
7712
|
+
return;
|
|
7713
|
+
}
|
|
7714
|
+
if (!resp.valid) {
|
|
7715
|
+
throw new Error(
|
|
7716
|
+
`Token invalid: ${resp.error ?? "no further detail"}`
|
|
7717
|
+
);
|
|
7718
|
+
}
|
|
7719
|
+
console.log(chalk11.green("\u25CF Valid"));
|
|
7720
|
+
if (resp.customerId)
|
|
7721
|
+
console.log(` Customer: ${chalk11.cyan(resp.customerId)}`);
|
|
7722
|
+
if (resp.email) console.log(` Email: ${resp.email}`);
|
|
7723
|
+
if (resp.roles && resp.roles.length > 0)
|
|
7724
|
+
console.log(` Roles: ${resp.roles.join(", ")}`);
|
|
7725
|
+
if (expiresAtIso) console.log(` Expires: ${expiresAtIso}`);
|
|
7726
|
+
})
|
|
7727
|
+
);
|
|
7728
|
+
}
|
|
7729
|
+
|
|
7730
|
+
// src/commands/auth-providers.ts
|
|
7731
|
+
import chalk12 from "chalk";
|
|
7506
7732
|
import { AuthProviderSchema } from "@eide/foir-proto-ts/identity/v1/identity_pb";
|
|
7507
7733
|
var VALID_TYPES = [
|
|
7508
7734
|
"OAUTH2",
|
|
@@ -7556,7 +7782,7 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7556
7782
|
formatOutputProto(AuthProviderSchema, provider, opts);
|
|
7557
7783
|
} else {
|
|
7558
7784
|
const p = provider;
|
|
7559
|
-
console.log(
|
|
7785
|
+
console.log(chalk12.bold(`${p.name}`) + chalk12.gray(` (${p.key})`));
|
|
7560
7786
|
console.log(` Type: ${p.type}`);
|
|
7561
7787
|
console.log(` Enabled: ${p.enabled ? "yes" : "no"}`);
|
|
7562
7788
|
console.log(` Default: ${p.isDefault ? "yes" : "no"}`);
|
|
@@ -7570,13 +7796,13 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7570
7796
|
if (p.configDisplay) {
|
|
7571
7797
|
console.log(` Config:`);
|
|
7572
7798
|
console.log(
|
|
7573
|
-
|
|
7799
|
+
chalk12.gray(
|
|
7574
7800
|
JSON.stringify(p.configDisplay, null, 2).replace(/^/gm, " ")
|
|
7575
7801
|
)
|
|
7576
7802
|
);
|
|
7577
7803
|
}
|
|
7578
|
-
console.log(
|
|
7579
|
-
console.log(
|
|
7804
|
+
console.log(chalk12.gray(` Created: ${p.createdAt}`));
|
|
7805
|
+
console.log(chalk12.gray(` Updated: ${p.updatedAt}`));
|
|
7580
7806
|
}
|
|
7581
7807
|
})
|
|
7582
7808
|
);
|
|
@@ -7686,6 +7912,637 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7686
7912
|
);
|
|
7687
7913
|
}
|
|
7688
7914
|
|
|
7915
|
+
// src/commands/embeddings.ts
|
|
7916
|
+
import chalk13 from "chalk";
|
|
7917
|
+
function registerEmbeddingsCommands(program2, globalOpts) {
|
|
7918
|
+
const embeddings = program2.command("embeddings").description("Manage vector embeddings for semantic search");
|
|
7919
|
+
embeddings.command("write").description("Write an embedding vector for a record").option("-d, --data <json>", "Embedding input as JSON string").option("--file <path>", "Embedding input from JSON file").action(
|
|
7920
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
7921
|
+
const opts = globalOpts();
|
|
7922
|
+
const input = await parseInputData({
|
|
7923
|
+
data: cmdOpts.data,
|
|
7924
|
+
file: cmdOpts.file
|
|
7925
|
+
});
|
|
7926
|
+
if (!input?.recordId) {
|
|
7927
|
+
throw new Error("Embedding input missing required field: recordId");
|
|
7928
|
+
}
|
|
7929
|
+
if (!Array.isArray(input.vector) || input.vector.length === 0) {
|
|
7930
|
+
throw new Error(
|
|
7931
|
+
"Embedding input missing required field: vector (non-empty number[])"
|
|
7932
|
+
);
|
|
7933
|
+
}
|
|
7934
|
+
const dimensions = input.dimensions ?? input.vector.length;
|
|
7935
|
+
const client = await createPlatformClient(opts);
|
|
7936
|
+
const ok = await client.records.writeEmbeddings({
|
|
7937
|
+
recordId: input.recordId,
|
|
7938
|
+
vector: input.vector,
|
|
7939
|
+
dimensions,
|
|
7940
|
+
provider: input.provider,
|
|
7941
|
+
modelName: input.modelName
|
|
7942
|
+
});
|
|
7943
|
+
if (opts.json || opts.jsonl) {
|
|
7944
|
+
formatOutput({ written: ok, recordId: input.recordId, dimensions }, opts);
|
|
7945
|
+
} else if (ok) {
|
|
7946
|
+
success(
|
|
7947
|
+
`Wrote ${dimensions}-dim embedding for ${input.recordId}`
|
|
7948
|
+
);
|
|
7949
|
+
} else {
|
|
7950
|
+
throw new Error(`Write failed for ${input.recordId}`);
|
|
7951
|
+
}
|
|
7952
|
+
})
|
|
7953
|
+
);
|
|
7954
|
+
embeddings.command("delete <recordId>").description("Delete the embedding for a record").option("--confirm", "Skip confirmation prompt").action(
|
|
7955
|
+
withErrorHandler(
|
|
7956
|
+
globalOpts,
|
|
7957
|
+
async (recordId, cmdOpts) => {
|
|
7958
|
+
const opts = globalOpts();
|
|
7959
|
+
const confirmed = await confirmAction(
|
|
7960
|
+
`Delete embedding for ${recordId}?`,
|
|
7961
|
+
{ confirm: !!cmdOpts.confirm }
|
|
7962
|
+
);
|
|
7963
|
+
if (!confirmed) {
|
|
7964
|
+
console.log("Aborted.");
|
|
7965
|
+
return;
|
|
7966
|
+
}
|
|
7967
|
+
const client = await createPlatformClient(opts);
|
|
7968
|
+
const ok = await client.records.deleteEmbeddings(recordId);
|
|
7969
|
+
if (opts.json || opts.jsonl) {
|
|
7970
|
+
formatOutput({ deleted: ok, recordId }, opts);
|
|
7971
|
+
} else {
|
|
7972
|
+
success(`Deleted embedding for ${recordId}`);
|
|
7973
|
+
}
|
|
7974
|
+
}
|
|
7975
|
+
)
|
|
7976
|
+
);
|
|
7977
|
+
embeddings.command("search").description("Search by vector similarity").requiredOption(
|
|
7978
|
+
"-d, --data <json>",
|
|
7979
|
+
'Search input as JSON: {"queryVector":[\u2026],"modelKey":"\u2026","limit":10}'
|
|
7980
|
+
).action(
|
|
7981
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
7982
|
+
const opts = globalOpts();
|
|
7983
|
+
const input = await parseInputData({
|
|
7984
|
+
data: cmdOpts.data
|
|
7985
|
+
});
|
|
7986
|
+
if (!Array.isArray(input.queryVector) || input.queryVector.length === 0) {
|
|
7987
|
+
throw new Error(
|
|
7988
|
+
"Search input missing required field: queryVector (non-empty number[])"
|
|
7989
|
+
);
|
|
7990
|
+
}
|
|
7991
|
+
const client = await createPlatformClient(opts);
|
|
7992
|
+
const results = await client.records.searchEmbeddings({
|
|
7993
|
+
queryVector: input.queryVector,
|
|
7994
|
+
modelKey: input.modelKey,
|
|
7995
|
+
limit: input.limit
|
|
7996
|
+
});
|
|
7997
|
+
if (opts.json || opts.jsonl) {
|
|
7998
|
+
formatOutput(results, opts);
|
|
7999
|
+
return;
|
|
8000
|
+
}
|
|
8001
|
+
if (results.length === 0) {
|
|
8002
|
+
console.log(chalk13.dim("No matches."));
|
|
8003
|
+
return;
|
|
8004
|
+
}
|
|
8005
|
+
for (const r of results) {
|
|
8006
|
+
const score = typeof r.similarity === "number" ? r.similarity.toFixed(4) : "\u2014";
|
|
8007
|
+
console.log(
|
|
8008
|
+
` ${chalk13.cyan(r.id)} ${chalk13.dim(r.modelKey ?? "")} ${chalk13.gray(`sim=${score}`)}`
|
|
8009
|
+
);
|
|
8010
|
+
}
|
|
8011
|
+
})
|
|
8012
|
+
);
|
|
8013
|
+
embeddings.command("list <recordId>").description("List embeddings stored for a record").action(
|
|
8014
|
+
withErrorHandler(globalOpts, async (recordId) => {
|
|
8015
|
+
const opts = globalOpts();
|
|
8016
|
+
const client = await createPlatformClient(opts);
|
|
8017
|
+
const items = await client.records.getRecordEmbeddings(recordId);
|
|
8018
|
+
formatOutput(items, opts);
|
|
8019
|
+
})
|
|
8020
|
+
);
|
|
8021
|
+
embeddings.command("stats [modelKey]").description("Embedding statistics, optionally scoped to a model").action(
|
|
8022
|
+
withErrorHandler(globalOpts, async (modelKey) => {
|
|
8023
|
+
const opts = globalOpts();
|
|
8024
|
+
const client = await createPlatformClient(opts);
|
|
8025
|
+
const stats = await client.records.getEmbeddingStats(modelKey);
|
|
8026
|
+
if (opts.json || opts.jsonl) {
|
|
8027
|
+
formatOutput(stats, opts);
|
|
8028
|
+
return;
|
|
8029
|
+
}
|
|
8030
|
+
if (stats.length === 0) {
|
|
8031
|
+
console.log(chalk13.dim("No embeddings yet."));
|
|
8032
|
+
return;
|
|
8033
|
+
}
|
|
8034
|
+
for (const s of stats) {
|
|
8035
|
+
console.log(
|
|
8036
|
+
` ${chalk13.cyan(s.modelKey)} ${chalk13.dim(`embedded=${s.embeddedRecords}/${s.totalRecords} pending=${s.pendingRecords}`)}`
|
|
8037
|
+
);
|
|
8038
|
+
}
|
|
8039
|
+
})
|
|
8040
|
+
);
|
|
8041
|
+
embeddings.command("similar <recordId>").description("Find records similar to the given record").option("--model-key <key>", "Limit matches to a specific model").option("--limit <n>", "Maximum results (default: 10)").action(
|
|
8042
|
+
withErrorHandler(
|
|
8043
|
+
globalOpts,
|
|
8044
|
+
async (recordId, cmdOpts) => {
|
|
8045
|
+
const opts = globalOpts();
|
|
8046
|
+
const client = await createPlatformClient(opts);
|
|
8047
|
+
const results = await client.records.findSimilarRecords({
|
|
8048
|
+
recordId,
|
|
8049
|
+
modelKey: cmdOpts.modelKey,
|
|
8050
|
+
limit: cmdOpts.limit ? parseInt(String(cmdOpts.limit), 10) : void 0
|
|
8051
|
+
});
|
|
8052
|
+
if (opts.json || opts.jsonl) {
|
|
8053
|
+
formatOutput(results, opts);
|
|
8054
|
+
return;
|
|
8055
|
+
}
|
|
8056
|
+
if (results.length === 0) {
|
|
8057
|
+
console.log(chalk13.dim("No similar records."));
|
|
8058
|
+
return;
|
|
8059
|
+
}
|
|
8060
|
+
for (const r of results) {
|
|
8061
|
+
const score = typeof r.similarity === "number" ? r.similarity.toFixed(4) : "\u2014";
|
|
8062
|
+
console.log(
|
|
8063
|
+
` ${chalk13.cyan(r.id)} ${chalk13.dim(r.modelKey ?? "")} ${chalk13.gray(`sim=${score}`)}`
|
|
8064
|
+
);
|
|
8065
|
+
}
|
|
8066
|
+
}
|
|
8067
|
+
)
|
|
8068
|
+
);
|
|
8069
|
+
}
|
|
8070
|
+
|
|
8071
|
+
// src/commands/hooks.ts
|
|
8072
|
+
import {
|
|
8073
|
+
HookSchema,
|
|
8074
|
+
HookDeliverySchema
|
|
8075
|
+
} from "@eide/foir-proto-ts/hooks/v1/hooks_pb";
|
|
8076
|
+
function registerHooksCommands(program2, globalOpts) {
|
|
8077
|
+
const hooks = program2.command("hooks").description("Manage lifecycle hooks (event-driven webhooks)");
|
|
8078
|
+
hooks.command("list").description("List hooks").option("--event <event>", "Filter by event name").option("--active", "Show only active hooks").option("--inactive", "Show only inactive hooks").option("--limit <n>", "Maximum results (default: 50)").option("--offset <n>", "Pagination offset").action(
|
|
8079
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
8080
|
+
const opts = globalOpts();
|
|
8081
|
+
const client = await createPlatformClient(opts);
|
|
8082
|
+
let isActive;
|
|
8083
|
+
if (cmdOpts.active) isActive = true;
|
|
8084
|
+
else if (cmdOpts.inactive) isActive = false;
|
|
8085
|
+
const resp = await client.hooks.listHooks({
|
|
8086
|
+
event: cmdOpts.event,
|
|
8087
|
+
isActive,
|
|
8088
|
+
limit: cmdOpts.limit ? parseInt(String(cmdOpts.limit), 10) : void 0,
|
|
8089
|
+
offset: cmdOpts.offset ? parseInt(String(cmdOpts.offset), 10) : void 0
|
|
8090
|
+
});
|
|
8091
|
+
formatListProto(HookSchema, resp.hooks ?? [], opts, {
|
|
8092
|
+
columns: [
|
|
8093
|
+
{ key: "id", header: "ID", width: 28 },
|
|
8094
|
+
{ key: "key", header: "Key", width: 24 },
|
|
8095
|
+
{ key: "name", header: "Name", width: 24 },
|
|
8096
|
+
{ key: "event", header: "Event", width: 22 },
|
|
8097
|
+
{ key: "targetType", header: "Target", width: 14 },
|
|
8098
|
+
{
|
|
8099
|
+
key: "isActive",
|
|
8100
|
+
header: "Active",
|
|
8101
|
+
width: 7,
|
|
8102
|
+
format: (v) => v ? "yes" : "no"
|
|
8103
|
+
}
|
|
8104
|
+
]
|
|
8105
|
+
});
|
|
8106
|
+
})
|
|
8107
|
+
);
|
|
8108
|
+
hooks.command("get <keyOrId>").description("Get a hook by key or ID").action(
|
|
8109
|
+
withErrorHandler(globalOpts, async (keyOrId) => {
|
|
8110
|
+
const opts = globalOpts();
|
|
8111
|
+
const client = await createPlatformClient(opts);
|
|
8112
|
+
const hook = keyOrId.includes("-") || keyOrId.length > 20 ? await client.hooks.getHook(keyOrId) : await client.hooks.getHookByKey(keyOrId);
|
|
8113
|
+
if (!hook) {
|
|
8114
|
+
throw new Error(`Hook not found: ${keyOrId}`);
|
|
8115
|
+
}
|
|
8116
|
+
formatOutputProto(HookSchema, hook, opts);
|
|
8117
|
+
})
|
|
8118
|
+
);
|
|
8119
|
+
hooks.command("create").description("Create a hook").option("-d, --data <json>", "Hook definition as JSON string").option("--file <path>", "Hook definition from JSON file").action(
|
|
8120
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
8121
|
+
const opts = globalOpts();
|
|
8122
|
+
const input = await parseInputData({
|
|
8123
|
+
data: cmdOpts.data,
|
|
8124
|
+
file: cmdOpts.file
|
|
8125
|
+
});
|
|
8126
|
+
for (const required of ["key", "name", "event", "targetType"]) {
|
|
8127
|
+
if (!input[required]) {
|
|
8128
|
+
throw new Error(`Hook input missing required field: ${required}`);
|
|
8129
|
+
}
|
|
8130
|
+
}
|
|
8131
|
+
const client = await createPlatformClient(opts);
|
|
8132
|
+
const hook = await client.hooks.createHook({
|
|
8133
|
+
key: input.key,
|
|
8134
|
+
name: input.name,
|
|
8135
|
+
event: input.event,
|
|
8136
|
+
targetType: input.targetType,
|
|
8137
|
+
description: input.description,
|
|
8138
|
+
operationKey: input.operationKey,
|
|
8139
|
+
notificationConfig: input.notificationConfig,
|
|
8140
|
+
filter: input.filter,
|
|
8141
|
+
configId: input.configId
|
|
8142
|
+
});
|
|
8143
|
+
if (opts.json || opts.jsonl) {
|
|
8144
|
+
formatOutputProto(HookSchema, hook, opts);
|
|
8145
|
+
} else {
|
|
8146
|
+
success(`Created hook ${hook?.key} (${hook?.id})`);
|
|
8147
|
+
}
|
|
8148
|
+
})
|
|
8149
|
+
);
|
|
8150
|
+
hooks.command("update <id>").description("Update a hook").option("-d, --data <json>", "Patch fields as JSON string").option("--file <path>", "Patch fields from JSON file").option("--active", "Activate the hook").option("--no-active", "Deactivate the hook").action(
|
|
8151
|
+
withErrorHandler(
|
|
8152
|
+
globalOpts,
|
|
8153
|
+
async (id, cmdOpts) => {
|
|
8154
|
+
const opts = globalOpts();
|
|
8155
|
+
const patch = cmdOpts.data || cmdOpts.file ? await parseInputData({
|
|
8156
|
+
data: cmdOpts.data,
|
|
8157
|
+
file: cmdOpts.file
|
|
8158
|
+
}) : {};
|
|
8159
|
+
const update = {
|
|
8160
|
+
id,
|
|
8161
|
+
name: patch.name,
|
|
8162
|
+
description: patch.description,
|
|
8163
|
+
operationKey: patch.operationKey,
|
|
8164
|
+
notificationConfig: patch.notificationConfig,
|
|
8165
|
+
filter: patch.filter
|
|
8166
|
+
};
|
|
8167
|
+
if (cmdOpts.active !== void 0) {
|
|
8168
|
+
update.isActive = !!cmdOpts.active;
|
|
8169
|
+
}
|
|
8170
|
+
const client = await createPlatformClient(opts);
|
|
8171
|
+
const hook = await client.hooks.updateHook(update);
|
|
8172
|
+
if (opts.json || opts.jsonl) {
|
|
8173
|
+
formatOutputProto(HookSchema, hook, opts);
|
|
8174
|
+
} else {
|
|
8175
|
+
success(`Updated hook ${hook?.key} (${hook?.id})`);
|
|
8176
|
+
}
|
|
8177
|
+
}
|
|
8178
|
+
)
|
|
8179
|
+
);
|
|
8180
|
+
hooks.command("delete <id>").description("Delete a hook").option("--confirm", "Skip confirmation prompt").action(
|
|
8181
|
+
withErrorHandler(
|
|
8182
|
+
globalOpts,
|
|
8183
|
+
async (id, cmdOpts) => {
|
|
8184
|
+
const opts = globalOpts();
|
|
8185
|
+
const confirmed = await confirmAction(
|
|
8186
|
+
`Delete hook ${id}? This also removes its delivery history.`,
|
|
8187
|
+
{ confirm: !!cmdOpts.confirm }
|
|
8188
|
+
);
|
|
8189
|
+
if (!confirmed) {
|
|
8190
|
+
console.log("Aborted.");
|
|
8191
|
+
return;
|
|
8192
|
+
}
|
|
8193
|
+
const client = await createPlatformClient(opts);
|
|
8194
|
+
const deleted = await client.hooks.deleteHook(id);
|
|
8195
|
+
if (opts.json || opts.jsonl) {
|
|
8196
|
+
formatOutput({ deleted, id }, opts);
|
|
8197
|
+
} else {
|
|
8198
|
+
success(`Deleted hook ${id}`);
|
|
8199
|
+
}
|
|
8200
|
+
}
|
|
8201
|
+
)
|
|
8202
|
+
);
|
|
8203
|
+
hooks.command("deliveries <hookId>").description("List recent deliveries for a hook").option("--status <status>", "Filter by status (success / failed / pending)").option("--limit <n>", "Maximum results (default: 50)").option("--offset <n>", "Pagination offset").action(
|
|
8204
|
+
withErrorHandler(
|
|
8205
|
+
globalOpts,
|
|
8206
|
+
async (hookId, cmdOpts) => {
|
|
8207
|
+
const opts = globalOpts();
|
|
8208
|
+
const client = await createPlatformClient(opts);
|
|
8209
|
+
const resp = await client.hooks.listHookDeliveries({
|
|
8210
|
+
hookId,
|
|
8211
|
+
status: cmdOpts.status,
|
|
8212
|
+
limit: cmdOpts.limit ? parseInt(String(cmdOpts.limit), 10) : void 0,
|
|
8213
|
+
offset: cmdOpts.offset ? parseInt(String(cmdOpts.offset), 10) : void 0
|
|
8214
|
+
});
|
|
8215
|
+
formatListProto(HookDeliverySchema, resp.deliveries ?? [], opts, {
|
|
8216
|
+
columns: [
|
|
8217
|
+
{ key: "id", header: "ID", width: 28 },
|
|
8218
|
+
{ key: "event", header: "Event", width: 22 },
|
|
8219
|
+
{ key: "status", header: "Status", width: 10 },
|
|
8220
|
+
{ key: "attempts", header: "Tries", width: 6 },
|
|
8221
|
+
{
|
|
8222
|
+
key: "durationMs",
|
|
8223
|
+
header: "Duration",
|
|
8224
|
+
width: 10,
|
|
8225
|
+
format: (v) => typeof v === "number" ? `${v}ms` : "\u2014"
|
|
8226
|
+
},
|
|
8227
|
+
{ key: "deliveredAt", header: "Delivered", width: 24 }
|
|
8228
|
+
]
|
|
8229
|
+
});
|
|
8230
|
+
}
|
|
8231
|
+
)
|
|
8232
|
+
);
|
|
8233
|
+
hooks.command("retry-delivery <deliveryId>").description("Retry a failed delivery").action(
|
|
8234
|
+
withErrorHandler(globalOpts, async (deliveryId) => {
|
|
8235
|
+
const opts = globalOpts();
|
|
8236
|
+
const client = await createPlatformClient(opts);
|
|
8237
|
+
const ok = await client.hooks.retryHookDelivery(deliveryId);
|
|
8238
|
+
if (opts.json || opts.jsonl) {
|
|
8239
|
+
formatOutput({ retried: ok, deliveryId }, opts);
|
|
8240
|
+
} else if (ok) {
|
|
8241
|
+
success(`Re-queued delivery ${deliveryId}`);
|
|
8242
|
+
} else {
|
|
8243
|
+
throw new Error(`Retry failed for delivery ${deliveryId}`);
|
|
8244
|
+
}
|
|
8245
|
+
})
|
|
8246
|
+
);
|
|
8247
|
+
hooks.command("test <hookId>").description("Send a test delivery against the hook").option("-d, --data <json>", "Test payload as JSON string").option("--file <path>", "Test payload from JSON file").action(
|
|
8248
|
+
withErrorHandler(
|
|
8249
|
+
globalOpts,
|
|
8250
|
+
async (hookId, cmdOpts) => {
|
|
8251
|
+
const opts = globalOpts();
|
|
8252
|
+
const testPayload = cmdOpts.data || cmdOpts.file ? await parseInputData({
|
|
8253
|
+
data: cmdOpts.data,
|
|
8254
|
+
file: cmdOpts.file
|
|
8255
|
+
}) : void 0;
|
|
8256
|
+
const client = await createPlatformClient(opts);
|
|
8257
|
+
const result = await client.hooks.testHook({ hookId, testPayload });
|
|
8258
|
+
if (opts.json || opts.jsonl) {
|
|
8259
|
+
formatOutput(result, opts);
|
|
8260
|
+
} else if (result.success) {
|
|
8261
|
+
success(`Test delivery succeeded for hook ${hookId}`);
|
|
8262
|
+
} else {
|
|
8263
|
+
throw new Error(
|
|
8264
|
+
`Test delivery failed: ${result.error ?? "unknown error"}`
|
|
8265
|
+
);
|
|
8266
|
+
}
|
|
8267
|
+
}
|
|
8268
|
+
)
|
|
8269
|
+
);
|
|
8270
|
+
}
|
|
8271
|
+
|
|
8272
|
+
// src/commands/rollouts.ts
|
|
8273
|
+
import chalk14 from "chalk";
|
|
8274
|
+
import { PublishBatchSchema } from "@eide/foir-proto-ts/schedules/v1/schedules_pb";
|
|
8275
|
+
function parseScheduledAt(value) {
|
|
8276
|
+
const date = new Date(value);
|
|
8277
|
+
if (Number.isNaN(date.getTime())) {
|
|
8278
|
+
throw new Error(
|
|
8279
|
+
`Invalid scheduledAt "${value}". Expected an ISO-8601 timestamp.`
|
|
8280
|
+
);
|
|
8281
|
+
}
|
|
8282
|
+
return date;
|
|
8283
|
+
}
|
|
8284
|
+
function registerRolloutsCommands(program2, globalOpts) {
|
|
8285
|
+
const rollouts = program2.command("rollouts").description("Manage bulk scheduled publishing rollouts");
|
|
8286
|
+
rollouts.command("list").description("List rollouts").option("--status <status>", "Filter by status").option("--limit <n>", "Maximum results (default: 50)").option("--offset <n>", "Pagination offset").action(
|
|
8287
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
8288
|
+
const opts = globalOpts();
|
|
8289
|
+
const client = await createPlatformClient(opts);
|
|
8290
|
+
const { batches } = await client.publishBatches.listPublishBatches({
|
|
8291
|
+
status: cmdOpts.status,
|
|
8292
|
+
limit: cmdOpts.limit ? parseInt(String(cmdOpts.limit), 10) : void 0,
|
|
8293
|
+
offset: cmdOpts.offset ? parseInt(String(cmdOpts.offset), 10) : void 0
|
|
8294
|
+
});
|
|
8295
|
+
formatListProto(PublishBatchSchema, batches, opts, {
|
|
8296
|
+
columns: [
|
|
8297
|
+
{ key: "id", header: "ID", width: 28 },
|
|
8298
|
+
{ key: "name", header: "Name", width: 28 },
|
|
8299
|
+
{ key: "status", header: "Status", width: 12 },
|
|
8300
|
+
{ key: "itemCount", header: "Items", width: 6 },
|
|
8301
|
+
{ key: "completedCount", header: "Done", width: 6 },
|
|
8302
|
+
{ key: "failedCount", header: "Failed", width: 7 },
|
|
8303
|
+
{ key: "scheduledAt", header: "Scheduled", width: 24 }
|
|
8304
|
+
]
|
|
8305
|
+
});
|
|
8306
|
+
})
|
|
8307
|
+
);
|
|
8308
|
+
rollouts.command("get <id>").description("Get a rollout (with its items)").action(
|
|
8309
|
+
withErrorHandler(globalOpts, async (id) => {
|
|
8310
|
+
const opts = globalOpts();
|
|
8311
|
+
const client = await createPlatformClient(opts);
|
|
8312
|
+
const { batch, items } = await client.publishBatches.getPublishBatch(id);
|
|
8313
|
+
if (!batch) throw new Error(`Rollout not found: ${id}`);
|
|
8314
|
+
if (opts.json || opts.jsonl) {
|
|
8315
|
+
formatOutput({ rollout: batch, items }, opts);
|
|
8316
|
+
return;
|
|
8317
|
+
}
|
|
8318
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8319
|
+
if (items.length > 0) {
|
|
8320
|
+
console.log();
|
|
8321
|
+
console.log(chalk14.bold(`Items (${items.length}):`));
|
|
8322
|
+
for (const it of items) {
|
|
8323
|
+
console.log(
|
|
8324
|
+
` ${chalk14.cyan(it.id)} ${chalk14.dim(it.targetKind)} ${chalk14.gray(it.status ?? "")}`
|
|
8325
|
+
);
|
|
8326
|
+
}
|
|
8327
|
+
}
|
|
8328
|
+
})
|
|
8329
|
+
);
|
|
8330
|
+
rollouts.command("create").description("Create a rollout").option("-d, --data <json>", "Rollout definition as JSON string").option("--file <path>", "Rollout definition from JSON file").action(
|
|
8331
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
8332
|
+
const opts = globalOpts();
|
|
8333
|
+
const input = await parseInputData({
|
|
8334
|
+
data: cmdOpts.data,
|
|
8335
|
+
file: cmdOpts.file
|
|
8336
|
+
});
|
|
8337
|
+
if (!input?.name) {
|
|
8338
|
+
throw new Error("Rollout input missing required field: name");
|
|
8339
|
+
}
|
|
8340
|
+
if (!input.scheduledAt) {
|
|
8341
|
+
throw new Error("Rollout input missing required field: scheduledAt");
|
|
8342
|
+
}
|
|
8343
|
+
const scheduledAt = parseScheduledAt(input.scheduledAt);
|
|
8344
|
+
const client = await createPlatformClient(opts);
|
|
8345
|
+
const batch = await client.publishBatches.createPublishBatch({
|
|
8346
|
+
name: input.name,
|
|
8347
|
+
description: input.description,
|
|
8348
|
+
scheduledAt,
|
|
8349
|
+
versionIds: input.versionIds,
|
|
8350
|
+
modelIds: input.modelIds,
|
|
8351
|
+
operationIds: input.operationIds,
|
|
8352
|
+
contextDimensionIds: input.contextDimensionIds,
|
|
8353
|
+
authProviderIds: input.authProviderIds,
|
|
8354
|
+
includeProfileSchema: input.includeProfileSchema
|
|
8355
|
+
});
|
|
8356
|
+
if (opts.json || opts.jsonl) {
|
|
8357
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8358
|
+
} else {
|
|
8359
|
+
success(`Created rollout ${batch?.name} (${batch?.id})`);
|
|
8360
|
+
}
|
|
8361
|
+
})
|
|
8362
|
+
);
|
|
8363
|
+
rollouts.command("update <id>").description("Update a rollout (name, description, scheduledAt)").option("-d, --data <json>", "Patch fields as JSON string").option("--file <path>", "Patch fields from JSON file").action(
|
|
8364
|
+
withErrorHandler(
|
|
8365
|
+
globalOpts,
|
|
8366
|
+
async (id, cmdOpts) => {
|
|
8367
|
+
const opts = globalOpts();
|
|
8368
|
+
const patch = await parseInputData({
|
|
8369
|
+
data: cmdOpts.data,
|
|
8370
|
+
file: cmdOpts.file
|
|
8371
|
+
});
|
|
8372
|
+
const client = await createPlatformClient(opts);
|
|
8373
|
+
const batch = await client.publishBatches.updatePublishBatch({
|
|
8374
|
+
id,
|
|
8375
|
+
name: patch.name,
|
|
8376
|
+
description: patch.description,
|
|
8377
|
+
scheduledAt: patch.scheduledAt ? parseScheduledAt(patch.scheduledAt) : void 0
|
|
8378
|
+
});
|
|
8379
|
+
if (opts.json || opts.jsonl) {
|
|
8380
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8381
|
+
} else {
|
|
8382
|
+
success(`Updated rollout ${batch?.name} (${batch?.id})`);
|
|
8383
|
+
}
|
|
8384
|
+
}
|
|
8385
|
+
)
|
|
8386
|
+
);
|
|
8387
|
+
rollouts.command("delete <id>").description("Delete a rollout before it runs").option("--confirm", "Skip confirmation prompt").action(
|
|
8388
|
+
withErrorHandler(
|
|
8389
|
+
globalOpts,
|
|
8390
|
+
async (id, cmdOpts) => {
|
|
8391
|
+
const opts = globalOpts();
|
|
8392
|
+
const confirmed = await confirmAction(
|
|
8393
|
+
`Delete rollout ${id}? This cannot be undone.`,
|
|
8394
|
+
{ confirm: !!cmdOpts.confirm }
|
|
8395
|
+
);
|
|
8396
|
+
if (!confirmed) {
|
|
8397
|
+
console.log("Aborted.");
|
|
8398
|
+
return;
|
|
8399
|
+
}
|
|
8400
|
+
const client = await createPlatformClient(opts);
|
|
8401
|
+
const ok = await client.publishBatches.deletePublishBatch(id);
|
|
8402
|
+
if (opts.json || opts.jsonl) {
|
|
8403
|
+
formatOutput({ deleted: ok, id }, opts);
|
|
8404
|
+
} else {
|
|
8405
|
+
success(`Deleted rollout ${id}`);
|
|
8406
|
+
}
|
|
8407
|
+
}
|
|
8408
|
+
)
|
|
8409
|
+
);
|
|
8410
|
+
rollouts.command("trigger <id>").description("Trigger a rollout immediately (ignore its scheduled time)").action(
|
|
8411
|
+
withErrorHandler(globalOpts, async (id) => {
|
|
8412
|
+
const opts = globalOpts();
|
|
8413
|
+
const client = await createPlatformClient(opts);
|
|
8414
|
+
const batch = await client.publishBatches.triggerPublishBatch(id);
|
|
8415
|
+
if (opts.json || opts.jsonl) {
|
|
8416
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8417
|
+
} else {
|
|
8418
|
+
success(`Triggered rollout ${batch?.name} (${batch?.id})`);
|
|
8419
|
+
}
|
|
8420
|
+
})
|
|
8421
|
+
);
|
|
8422
|
+
rollouts.command("pause <id>").description("Pause an in-flight rollout").action(
|
|
8423
|
+
withErrorHandler(globalOpts, async (id) => {
|
|
8424
|
+
const opts = globalOpts();
|
|
8425
|
+
const client = await createPlatformClient(opts);
|
|
8426
|
+
const batch = await client.publishBatches.pausePublishBatch(id);
|
|
8427
|
+
if (opts.json || opts.jsonl) {
|
|
8428
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8429
|
+
} else {
|
|
8430
|
+
success(`Paused rollout ${batch?.id}`);
|
|
8431
|
+
}
|
|
8432
|
+
})
|
|
8433
|
+
);
|
|
8434
|
+
rollouts.command("resume <id>").description("Resume a paused rollout").action(
|
|
8435
|
+
withErrorHandler(globalOpts, async (id) => {
|
|
8436
|
+
const opts = globalOpts();
|
|
8437
|
+
const client = await createPlatformClient(opts);
|
|
8438
|
+
const batch = await client.publishBatches.resumePublishBatch(id);
|
|
8439
|
+
if (opts.json || opts.jsonl) {
|
|
8440
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8441
|
+
} else {
|
|
8442
|
+
success(`Resumed rollout ${batch?.id}`);
|
|
8443
|
+
}
|
|
8444
|
+
})
|
|
8445
|
+
);
|
|
8446
|
+
rollouts.command("retry <id>").description("Retry failed items in a rollout").action(
|
|
8447
|
+
withErrorHandler(globalOpts, async (id) => {
|
|
8448
|
+
const opts = globalOpts();
|
|
8449
|
+
const client = await createPlatformClient(opts);
|
|
8450
|
+
const batch = await client.publishBatches.retryFailedItems(id);
|
|
8451
|
+
if (opts.json || opts.jsonl) {
|
|
8452
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8453
|
+
} else {
|
|
8454
|
+
success(`Re-queued failed items for rollout ${batch?.id}`);
|
|
8455
|
+
}
|
|
8456
|
+
})
|
|
8457
|
+
);
|
|
8458
|
+
rollouts.command("rollback <id>").description(
|
|
8459
|
+
"Roll back a completed rollout (use --preview to dry-run first)"
|
|
8460
|
+
).option("--preview", "Preview the rollback without executing").option("--confirm", "Skip confirmation prompt").action(
|
|
8461
|
+
withErrorHandler(
|
|
8462
|
+
globalOpts,
|
|
8463
|
+
async (id, cmdOpts) => {
|
|
8464
|
+
const opts = globalOpts();
|
|
8465
|
+
const client = await createPlatformClient(opts);
|
|
8466
|
+
if (cmdOpts.preview) {
|
|
8467
|
+
const preview = await client.publishBatches.previewRollback(id);
|
|
8468
|
+
formatOutput(preview, opts);
|
|
8469
|
+
return;
|
|
8470
|
+
}
|
|
8471
|
+
const confirmed = await confirmAction(
|
|
8472
|
+
`Roll back rollout ${id}? This creates a new inverse rollout that reverts published changes.`,
|
|
8473
|
+
{ confirm: !!cmdOpts.confirm }
|
|
8474
|
+
);
|
|
8475
|
+
if (!confirmed) {
|
|
8476
|
+
console.log("Aborted.");
|
|
8477
|
+
return;
|
|
8478
|
+
}
|
|
8479
|
+
const rollback = await client.publishBatches.rollbackPublishBatch(id);
|
|
8480
|
+
if (opts.json || opts.jsonl) {
|
|
8481
|
+
formatOutputProto(PublishBatchSchema, rollback, opts);
|
|
8482
|
+
} else {
|
|
8483
|
+
success(
|
|
8484
|
+
`Rollback rollout ${rollback?.id} created for ${id}`
|
|
8485
|
+
);
|
|
8486
|
+
}
|
|
8487
|
+
}
|
|
8488
|
+
)
|
|
8489
|
+
);
|
|
8490
|
+
rollouts.command("add-items <id>").description("Add items (records / models / operations / etc.) to a rollout").option("-d, --data <json>", "Items as JSON string").option("--file <path>", "Items from JSON file").action(
|
|
8491
|
+
withErrorHandler(
|
|
8492
|
+
globalOpts,
|
|
8493
|
+
async (id, cmdOpts) => {
|
|
8494
|
+
const opts = globalOpts();
|
|
8495
|
+
const items = await parseInputData({
|
|
8496
|
+
data: cmdOpts.data,
|
|
8497
|
+
file: cmdOpts.file
|
|
8498
|
+
});
|
|
8499
|
+
const client = await createPlatformClient(opts);
|
|
8500
|
+
const batch = await client.publishBatches.addItems({
|
|
8501
|
+
batchId: id,
|
|
8502
|
+
versionIds: items.versionIds,
|
|
8503
|
+
modelIds: items.modelIds,
|
|
8504
|
+
operationIds: items.operationIds,
|
|
8505
|
+
contextDimensionIds: items.contextDimensionIds,
|
|
8506
|
+
authProviderIds: items.authProviderIds,
|
|
8507
|
+
includeProfileSchema: items.includeProfileSchema
|
|
8508
|
+
});
|
|
8509
|
+
if (opts.json || opts.jsonl) {
|
|
8510
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8511
|
+
} else {
|
|
8512
|
+
success(`Added items to rollout ${batch?.id}`);
|
|
8513
|
+
}
|
|
8514
|
+
}
|
|
8515
|
+
)
|
|
8516
|
+
);
|
|
8517
|
+
rollouts.command("remove-items <id>").description("Remove items from a rollout").option("-d, --data <json>", "Items to remove as JSON string").option("--file <path>", "Items to remove from JSON file").action(
|
|
8518
|
+
withErrorHandler(
|
|
8519
|
+
globalOpts,
|
|
8520
|
+
async (id, cmdOpts) => {
|
|
8521
|
+
const opts = globalOpts();
|
|
8522
|
+
const items = await parseInputData({
|
|
8523
|
+
data: cmdOpts.data,
|
|
8524
|
+
file: cmdOpts.file
|
|
8525
|
+
});
|
|
8526
|
+
const client = await createPlatformClient(opts);
|
|
8527
|
+
const batch = await client.publishBatches.removeItems({
|
|
8528
|
+
batchId: id,
|
|
8529
|
+
versionIds: items.versionIds,
|
|
8530
|
+
modelIds: items.modelIds,
|
|
8531
|
+
operationIds: items.operationIds,
|
|
8532
|
+
contextDimensionIds: items.contextDimensionIds,
|
|
8533
|
+
authProviderIds: items.authProviderIds,
|
|
8534
|
+
excludeProfileSchema: items.excludeProfileSchema
|
|
8535
|
+
});
|
|
8536
|
+
if (opts.json || opts.jsonl) {
|
|
8537
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8538
|
+
} else {
|
|
8539
|
+
success(`Removed items from rollout ${batch?.id}`);
|
|
8540
|
+
}
|
|
8541
|
+
}
|
|
8542
|
+
)
|
|
8543
|
+
);
|
|
8544
|
+
}
|
|
8545
|
+
|
|
7689
8546
|
// src/commands/locales.ts
|
|
7690
8547
|
import { LocaleSchema } from "@eide/foir-proto-ts/settings/v1/settings_pb";
|
|
7691
8548
|
function registerLocalesCommands(program2, globalOpts) {
|
|
@@ -7890,7 +8747,7 @@ function registerSettingsCommands(program2, globalOpts) {
|
|
|
7890
8747
|
// src/commands/design-tokens.ts
|
|
7891
8748
|
import { existsSync as existsSync6, readFileSync as readFileSync2 } from "fs";
|
|
7892
8749
|
import { resolve as resolve6 } from "path";
|
|
7893
|
-
import
|
|
8750
|
+
import chalk15 from "chalk";
|
|
7894
8751
|
function registerDesignTokensCommands(program2, globalOpts) {
|
|
7895
8752
|
const tokens = program2.command("design-tokens").description("Manage project design tokens (W3C-formatted)");
|
|
7896
8753
|
tokens.command("get").description("Print the current design tokens document").option("--channel <channel>", "draft | published", "draft").option(
|
|
@@ -7938,7 +8795,7 @@ function registerDesignTokensCommands(program2, globalOpts) {
|
|
|
7938
8795
|
const resp = await client.settings.publishDesignTokens();
|
|
7939
8796
|
success("Design tokens published");
|
|
7940
8797
|
if (resp.breakingChanges && resp.breakingChanges.length > 0) {
|
|
7941
|
-
console.log(
|
|
8798
|
+
console.log(chalk15.yellow("\nBreaking changes:"));
|
|
7942
8799
|
for (const c of resp.breakingChanges) {
|
|
7943
8800
|
console.log(` ${c.severity} ${c.path}: ${c.description}`);
|
|
7944
8801
|
}
|
|
@@ -7954,7 +8811,7 @@ function registerDesignTokensCommands(program2, globalOpts) {
|
|
|
7954
8811
|
const resp = await client.settings.publishDesignTokens();
|
|
7955
8812
|
success("Design tokens published");
|
|
7956
8813
|
if (resp.breakingChanges && resp.breakingChanges.length > 0) {
|
|
7957
|
-
console.log(
|
|
8814
|
+
console.log(chalk15.yellow("\nBreaking changes:"));
|
|
7958
8815
|
for (const c of resp.breakingChanges) {
|
|
7959
8816
|
console.log(` ${c.severity} ${c.path}: ${c.description}`);
|
|
7960
8817
|
}
|
|
@@ -7979,12 +8836,12 @@ function registerDesignTokensCommands(program2, globalOpts) {
|
|
|
7979
8836
|
return;
|
|
7980
8837
|
}
|
|
7981
8838
|
if (status.hasPendingChanges) {
|
|
7982
|
-
console.log(
|
|
8839
|
+
console.log(chalk15.yellow("\u25CF Pending changes"));
|
|
7983
8840
|
} else {
|
|
7984
|
-
console.log(
|
|
8841
|
+
console.log(chalk15.green("\u25CF Up to date"));
|
|
7985
8842
|
}
|
|
7986
8843
|
if (status.breakingChanges && status.breakingChanges.length > 0) {
|
|
7987
|
-
console.log(
|
|
8844
|
+
console.log(chalk15.yellow("\nPending changes:"));
|
|
7988
8845
|
for (const c of status.breakingChanges) {
|
|
7989
8846
|
console.log(` ${c.severity} ${c.path}: ${c.description}`);
|
|
7990
8847
|
}
|
|
@@ -9156,7 +10013,11 @@ registerOperationsCommands(program, getGlobalOpts);
|
|
|
9156
10013
|
registerSegmentsCommands(program, getGlobalOpts);
|
|
9157
10014
|
registerSchedulesCommands(program, getGlobalOpts);
|
|
9158
10015
|
registerApiKeysCommands(program, getGlobalOpts);
|
|
10016
|
+
registerAuthCommands(program, getGlobalOpts);
|
|
9159
10017
|
registerAuthProvidersCommands(program, getGlobalOpts);
|
|
10018
|
+
registerEmbeddingsCommands(program, getGlobalOpts);
|
|
10019
|
+
registerHooksCommands(program, getGlobalOpts);
|
|
10020
|
+
registerRolloutsCommands(program, getGlobalOpts);
|
|
9160
10021
|
registerLocalesCommands(program, getGlobalOpts);
|
|
9161
10022
|
registerSettingsCommands(program, getGlobalOpts);
|
|
9162
10023
|
registerDesignTokensCommands(program, getGlobalOpts);
|