@kaelen-ai/cli 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +328 -128
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import
|
|
3
|
+
import chalk12 from 'chalk';
|
|
4
4
|
import { writeFile, readFile, mkdtemp, rm, mkdir, stat, readdir } from 'fs/promises';
|
|
5
5
|
import { join, resolve, dirname, relative, basename, extname, isAbsolute } from 'path';
|
|
6
6
|
import * as acorn from 'acorn';
|
|
@@ -2387,19 +2387,26 @@ function analyzeTopLevel2(body) {
|
|
|
2387
2387
|
const imports = [];
|
|
2388
2388
|
const rootCalls = [];
|
|
2389
2389
|
for (const stmt of body) {
|
|
2390
|
-
|
|
2390
|
+
let candidate = stmt;
|
|
2391
|
+
if (stmt.type === "ExportNamedDeclaration") {
|
|
2392
|
+
const declaration = stmt.declaration;
|
|
2393
|
+
if (!declaration) {
|
|
2394
|
+
continue;
|
|
2395
|
+
}
|
|
2396
|
+
candidate = declaration;
|
|
2397
|
+
} else if (stmt.type === "ExportDefaultDeclaration" || stmt.type === "ExportAllDeclaration") {
|
|
2391
2398
|
continue;
|
|
2392
2399
|
}
|
|
2393
|
-
if (
|
|
2394
|
-
const specifiers =
|
|
2400
|
+
if (candidate.type === "ImportDeclaration") {
|
|
2401
|
+
const specifiers = candidate.specifiers;
|
|
2395
2402
|
if (specifiers.length === 0) {
|
|
2396
2403
|
continue;
|
|
2397
2404
|
}
|
|
2398
2405
|
const info = {
|
|
2399
2406
|
specifiers: [],
|
|
2400
|
-
source:
|
|
2401
|
-
start:
|
|
2402
|
-
end:
|
|
2407
|
+
source: candidate.source.value,
|
|
2408
|
+
start: candidate.start,
|
|
2409
|
+
end: candidate.end
|
|
2403
2410
|
};
|
|
2404
2411
|
for (const spec of specifiers) {
|
|
2405
2412
|
const local = spec.local.name;
|
|
@@ -2415,20 +2422,20 @@ function analyzeTopLevel2(body) {
|
|
|
2415
2422
|
imports.push(info);
|
|
2416
2423
|
continue;
|
|
2417
2424
|
}
|
|
2418
|
-
if (isRootTargetCall(
|
|
2425
|
+
if (isRootTargetCall(candidate)) {
|
|
2419
2426
|
rootCalls.push({
|
|
2420
|
-
start:
|
|
2421
|
-
end:
|
|
2427
|
+
start: candidate.start,
|
|
2428
|
+
end: candidate.end
|
|
2422
2429
|
});
|
|
2423
2430
|
continue;
|
|
2424
2431
|
}
|
|
2425
2432
|
const names = /* @__PURE__ */ new Set();
|
|
2426
|
-
if (
|
|
2427
|
-
for (const declaration of
|
|
2433
|
+
if (candidate.type === "VariableDeclaration") {
|
|
2434
|
+
for (const declaration of candidate.declarations) {
|
|
2428
2435
|
collectBindingNames2(declaration.id, names);
|
|
2429
2436
|
}
|
|
2430
|
-
} else if (
|
|
2431
|
-
const id =
|
|
2437
|
+
} else if (candidate.type === "FunctionDeclaration" || candidate.type === "ClassDeclaration") {
|
|
2438
|
+
const id = candidate.id;
|
|
2432
2439
|
if (id?.type === "Identifier") {
|
|
2433
2440
|
names.add(id.name);
|
|
2434
2441
|
}
|
|
@@ -2438,7 +2445,7 @@ function analyzeTopLevel2(body) {
|
|
|
2438
2445
|
if (names.size === 0) {
|
|
2439
2446
|
continue;
|
|
2440
2447
|
}
|
|
2441
|
-
const refs = collectRefs2(
|
|
2448
|
+
const refs = collectRefs2(candidate);
|
|
2442
2449
|
for (const name of names) {
|
|
2443
2450
|
refs.delete(name);
|
|
2444
2451
|
}
|
|
@@ -2769,7 +2776,7 @@ async function buildCommand(options) {
|
|
|
2769
2776
|
const config = await loadConfig({
|
|
2770
2777
|
dir: options.dir
|
|
2771
2778
|
});
|
|
2772
|
-
console.log(
|
|
2779
|
+
console.log(chalk12.gray("Validating deployment..."));
|
|
2773
2780
|
stagingDir = await createStagingDir();
|
|
2774
2781
|
const { manifest } = await buildPipeline(
|
|
2775
2782
|
config,
|
|
@@ -2799,10 +2806,10 @@ async function buildCommand(options) {
|
|
|
2799
2806
|
`${subscriptions.length} subscription${subscriptions.length === 1 ? "" : "s"}`,
|
|
2800
2807
|
`${secretBundles.length} secret bundle${secretBundles.length === 1 ? "" : "s"}`
|
|
2801
2808
|
];
|
|
2802
|
-
console.log(
|
|
2809
|
+
console.log(chalk12.green(`\u2713 Build succeeded (${parts.join(", ")})`));
|
|
2803
2810
|
} catch (err) {
|
|
2804
2811
|
if (err instanceof CliError) {
|
|
2805
|
-
console.error(
|
|
2812
|
+
console.error(chalk12.red(err.message));
|
|
2806
2813
|
process.exit(1);
|
|
2807
2814
|
}
|
|
2808
2815
|
throw err;
|
|
@@ -2989,9 +2996,9 @@ function diffManifests(local, remote) {
|
|
|
2989
2996
|
};
|
|
2990
2997
|
}
|
|
2991
2998
|
var SYMBOLS = {
|
|
2992
|
-
added:
|
|
2993
|
-
changed:
|
|
2994
|
-
removed:
|
|
2999
|
+
added: chalk12.green("+ "),
|
|
3000
|
+
changed: chalk12.yellow("~ "),
|
|
3001
|
+
removed: chalk12.red("- ")
|
|
2995
3002
|
};
|
|
2996
3003
|
var LABELS = {
|
|
2997
3004
|
added: "new",
|
|
@@ -3013,11 +3020,11 @@ function formatPlan(diff) {
|
|
|
3013
3020
|
const entries = diff[key];
|
|
3014
3021
|
lines.push(` ${label}:`);
|
|
3015
3022
|
if (entries.length === 0) {
|
|
3016
|
-
lines.push(
|
|
3023
|
+
lines.push(chalk12.gray(" (no changes)"));
|
|
3017
3024
|
} else {
|
|
3018
3025
|
for (const e of entries) {
|
|
3019
3026
|
lines.push(
|
|
3020
|
-
` ${SYMBOLS[e.kind]}${e.name} ${
|
|
3027
|
+
` ${SYMBOLS[e.kind]}${e.name} ${chalk12.gray(`(${LABELS[e.kind]})`)}`
|
|
3021
3028
|
);
|
|
3022
3029
|
}
|
|
3023
3030
|
}
|
|
@@ -3471,6 +3478,82 @@ function createClient(config) {
|
|
|
3471
3478
|
);
|
|
3472
3479
|
return data.createProject;
|
|
3473
3480
|
}
|
|
3481
|
+
async function principals2(projectIdValue) {
|
|
3482
|
+
const data = await graphql(
|
|
3483
|
+
`
|
|
3484
|
+
query Principals($projectId: ID!) {
|
|
3485
|
+
principals(projectId: $projectId) {
|
|
3486
|
+
id
|
|
3487
|
+
externalId
|
|
3488
|
+
state
|
|
3489
|
+
metadata
|
|
3490
|
+
projectId
|
|
3491
|
+
insertedAt
|
|
3492
|
+
updatedAt
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
`,
|
|
3496
|
+
{ projectId: projectIdValue }
|
|
3497
|
+
);
|
|
3498
|
+
return data.principals ?? [];
|
|
3499
|
+
}
|
|
3500
|
+
async function createPrincipal(projectIdValue, input) {
|
|
3501
|
+
const data = await graphql(
|
|
3502
|
+
`
|
|
3503
|
+
mutation CreatePrincipal($projectId: ID!, $input: CreatePrincipalInput!) {
|
|
3504
|
+
createPrincipal(projectId: $projectId, input: $input) {
|
|
3505
|
+
id
|
|
3506
|
+
externalId
|
|
3507
|
+
state
|
|
3508
|
+
metadata
|
|
3509
|
+
projectId
|
|
3510
|
+
insertedAt
|
|
3511
|
+
updatedAt
|
|
3512
|
+
}
|
|
3513
|
+
}
|
|
3514
|
+
`,
|
|
3515
|
+
{ projectId: projectIdValue, input }
|
|
3516
|
+
);
|
|
3517
|
+
return data.createPrincipal;
|
|
3518
|
+
}
|
|
3519
|
+
async function updatePrincipal(projectIdValue, id, input) {
|
|
3520
|
+
const data = await graphql(
|
|
3521
|
+
`
|
|
3522
|
+
mutation UpdatePrincipal($projectId: ID!, $id: ID!, $input: UpdatePrincipalInput!) {
|
|
3523
|
+
updatePrincipal(projectId: $projectId, id: $id, input: $input) {
|
|
3524
|
+
id
|
|
3525
|
+
externalId
|
|
3526
|
+
state
|
|
3527
|
+
metadata
|
|
3528
|
+
projectId
|
|
3529
|
+
insertedAt
|
|
3530
|
+
updatedAt
|
|
3531
|
+
}
|
|
3532
|
+
}
|
|
3533
|
+
`,
|
|
3534
|
+
{ projectId: projectIdValue, id, input }
|
|
3535
|
+
);
|
|
3536
|
+
return data.updatePrincipal ?? null;
|
|
3537
|
+
}
|
|
3538
|
+
async function deletePrincipal(projectIdValue, id) {
|
|
3539
|
+
const data = await graphql(
|
|
3540
|
+
`
|
|
3541
|
+
mutation DeletePrincipal($projectId: ID!, $id: ID!) {
|
|
3542
|
+
deletePrincipal(projectId: $projectId, id: $id) {
|
|
3543
|
+
id
|
|
3544
|
+
externalId
|
|
3545
|
+
state
|
|
3546
|
+
metadata
|
|
3547
|
+
projectId
|
|
3548
|
+
insertedAt
|
|
3549
|
+
updatedAt
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
`,
|
|
3553
|
+
{ projectId: projectIdValue, id }
|
|
3554
|
+
);
|
|
3555
|
+
return data.deletePrincipal ?? null;
|
|
3556
|
+
}
|
|
3474
3557
|
async function listSecrets(projectIdValue) {
|
|
3475
3558
|
const data = await graphql(
|
|
3476
3559
|
`
|
|
@@ -3591,6 +3674,9 @@ function createClient(config) {
|
|
|
3591
3674
|
}
|
|
3592
3675
|
async function emitSignal(input) {
|
|
3593
3676
|
const projectIdValue = input.projectId ?? projectId();
|
|
3677
|
+
if (!input.principalId || input.principalId.trim() === "") {
|
|
3678
|
+
throw new ConfigError("principalId is required to emit a signal");
|
|
3679
|
+
}
|
|
3594
3680
|
const eventName = normalizeRuntimeSignalName2(input.signal);
|
|
3595
3681
|
if (!eventName) {
|
|
3596
3682
|
throw new ConfigError(
|
|
@@ -3618,6 +3704,7 @@ function createClient(config) {
|
|
|
3618
3704
|
{
|
|
3619
3705
|
input: {
|
|
3620
3706
|
projectId: projectIdValue,
|
|
3707
|
+
principalId: input.principalId,
|
|
3621
3708
|
eventName,
|
|
3622
3709
|
payloadJson: JSON.stringify(input.payload ?? {}),
|
|
3623
3710
|
metadataJson: JSON.stringify(input.metadata ?? {}),
|
|
@@ -3694,6 +3781,10 @@ function createClient(config) {
|
|
|
3694
3781
|
organizations,
|
|
3695
3782
|
projects: projects2,
|
|
3696
3783
|
createProject,
|
|
3784
|
+
principals: principals2,
|
|
3785
|
+
createPrincipal,
|
|
3786
|
+
updatePrincipal,
|
|
3787
|
+
deletePrincipal,
|
|
3697
3788
|
listSecrets,
|
|
3698
3789
|
putSecret,
|
|
3699
3790
|
deleteSecret,
|
|
@@ -3712,7 +3803,7 @@ async function deployCommand(options) {
|
|
|
3712
3803
|
const config = await loadConfig({
|
|
3713
3804
|
dir: options.dir
|
|
3714
3805
|
});
|
|
3715
|
-
console.log(
|
|
3806
|
+
console.log(chalk12.gray("Planning deployment..."));
|
|
3716
3807
|
stagingDir = await createStagingDir();
|
|
3717
3808
|
const { manifest } = await buildPipeline(
|
|
3718
3809
|
config,
|
|
@@ -3722,7 +3813,7 @@ async function deployCommand(options) {
|
|
|
3722
3813
|
);
|
|
3723
3814
|
if (!config.apiUrl || !config.projectId) {
|
|
3724
3815
|
console.log(
|
|
3725
|
-
|
|
3816
|
+
chalk12.yellow(
|
|
3726
3817
|
"\nNo apiUrl or projectId configured. Skipping upload."
|
|
3727
3818
|
)
|
|
3728
3819
|
);
|
|
@@ -3732,30 +3823,30 @@ async function deployCommand(options) {
|
|
|
3732
3823
|
apiUrl: config.apiUrl,
|
|
3733
3824
|
projectId: config.projectId
|
|
3734
3825
|
});
|
|
3735
|
-
console.log(
|
|
3826
|
+
console.log(chalk12.gray("\nComparing with remote..."));
|
|
3736
3827
|
const remoteManifest = await client.fetchRemoteManifest(client.projectId());
|
|
3737
3828
|
const diff = diffManifests(manifest, remoteManifest);
|
|
3738
3829
|
if (!diff.hasChanges) {
|
|
3739
|
-
console.log(
|
|
3830
|
+
console.log(chalk12.green("\n\u2713 No changes to deploy."));
|
|
3740
3831
|
return;
|
|
3741
3832
|
}
|
|
3742
3833
|
console.log("\n" + formatPlan(diff));
|
|
3743
3834
|
const confirmed = await confirmPlan(options.yes ?? false);
|
|
3744
3835
|
if (!confirmed) {
|
|
3745
|
-
console.log(
|
|
3836
|
+
console.log(chalk12.yellow("Deploy cancelled."));
|
|
3746
3837
|
return;
|
|
3747
3838
|
}
|
|
3748
|
-
console.log(
|
|
3839
|
+
console.log(chalk12.gray("\nApplying deployment..."));
|
|
3749
3840
|
const zipPath = join(stagingDir, "deploy.zip");
|
|
3750
3841
|
await zipBuildOutput(stagingDir, zipPath);
|
|
3751
3842
|
const revision = await client.deployBundle(zipPath, manifest);
|
|
3752
3843
|
console.log(
|
|
3753
|
-
|
|
3844
|
+
chalk12.green(`
|
|
3754
3845
|
\u2713 Deployment complete (revision ${revision.revision}, ${revision.status})`)
|
|
3755
3846
|
);
|
|
3756
3847
|
} catch (err) {
|
|
3757
3848
|
if (err instanceof CliError) {
|
|
3758
|
-
console.error(
|
|
3849
|
+
console.error(chalk12.red(err.message));
|
|
3759
3850
|
process.exit(1);
|
|
3760
3851
|
}
|
|
3761
3852
|
throw err;
|
|
@@ -3866,7 +3957,7 @@ async function loginCommand(options) {
|
|
|
3866
3957
|
try {
|
|
3867
3958
|
if (options.token) {
|
|
3868
3959
|
await saveToken(options.token, true);
|
|
3869
|
-
console.log(
|
|
3960
|
+
console.log(chalk12.green("\u2713 API key saved"));
|
|
3870
3961
|
return;
|
|
3871
3962
|
}
|
|
3872
3963
|
const config = await loadConfig();
|
|
@@ -3877,7 +3968,7 @@ async function loginCommand(options) {
|
|
|
3877
3968
|
}
|
|
3878
3969
|
const existing = await loadToken();
|
|
3879
3970
|
if (existing) {
|
|
3880
|
-
console.log(
|
|
3971
|
+
console.log(chalk12.gray("Existing session found. Re-authenticating..."));
|
|
3881
3972
|
}
|
|
3882
3973
|
const callbackServer = await startCallbackServer();
|
|
3883
3974
|
const pkce = generatePkcePair();
|
|
@@ -3887,12 +3978,12 @@ async function loginCommand(options) {
|
|
|
3887
3978
|
callbackServer.state,
|
|
3888
3979
|
pkce.challenge
|
|
3889
3980
|
);
|
|
3890
|
-
console.log(
|
|
3981
|
+
console.log(chalk12.gray("Opening your browser for sign-in..."));
|
|
3891
3982
|
try {
|
|
3892
3983
|
await open(authorizationUrl);
|
|
3893
3984
|
} catch {
|
|
3894
|
-
console.log(
|
|
3895
|
-
console.log(
|
|
3985
|
+
console.log(chalk12.yellow("Could not open the browser automatically."));
|
|
3986
|
+
console.log(chalk12.gray(`Open this URL manually:
|
|
3896
3987
|
${authorizationUrl}`));
|
|
3897
3988
|
}
|
|
3898
3989
|
try {
|
|
@@ -3916,10 +4007,10 @@ ${authorizationUrl}`));
|
|
|
3916
4007
|
} finally {
|
|
3917
4008
|
callbackServer.close();
|
|
3918
4009
|
}
|
|
3919
|
-
console.log(
|
|
4010
|
+
console.log(chalk12.green("\n\u2713 Authenticated successfully"));
|
|
3920
4011
|
} catch (err) {
|
|
3921
4012
|
if (err instanceof CliError) {
|
|
3922
|
-
console.error(
|
|
4013
|
+
console.error(chalk12.red(err.message));
|
|
3923
4014
|
process.exit(1);
|
|
3924
4015
|
}
|
|
3925
4016
|
throw err;
|
|
@@ -3929,10 +4020,10 @@ async function logoutCommand() {
|
|
|
3929
4020
|
const creds = await loadCredentials();
|
|
3930
4021
|
await clearToken();
|
|
3931
4022
|
if (!creds) {
|
|
3932
|
-
console.log(
|
|
4023
|
+
console.log(chalk12.yellow("Not logged in."));
|
|
3933
4024
|
return;
|
|
3934
4025
|
}
|
|
3935
|
-
console.log(
|
|
4026
|
+
console.log(chalk12.green("\u2713 Logged out"));
|
|
3936
4027
|
}
|
|
3937
4028
|
async function hydrateIdentity() {
|
|
3938
4029
|
const creds = await loadCredentials();
|
|
@@ -3976,26 +4067,26 @@ async function hydrateIdentity() {
|
|
|
3976
4067
|
async function whoamiCommand() {
|
|
3977
4068
|
const { creds, sessionName, sessionEmail } = await hydrateIdentity();
|
|
3978
4069
|
if (!creds) {
|
|
3979
|
-
console.log(
|
|
4070
|
+
console.log(chalk12.yellow("Not logged in. Run `io login` to authenticate."));
|
|
3980
4071
|
return;
|
|
3981
4072
|
}
|
|
3982
|
-
console.log(
|
|
4073
|
+
console.log(chalk12.green("\u2713 Logged in"));
|
|
3983
4074
|
const displayUser = sessionName ?? sessionEmail ?? creds.userId;
|
|
3984
4075
|
if (displayUser) {
|
|
3985
|
-
console.log(
|
|
4076
|
+
console.log(chalk12.gray(` User: ${displayUser}`));
|
|
3986
4077
|
}
|
|
3987
4078
|
if (sessionEmail && sessionEmail !== displayUser) {
|
|
3988
|
-
console.log(
|
|
4079
|
+
console.log(chalk12.gray(` Email: ${sessionEmail}`));
|
|
3989
4080
|
}
|
|
3990
4081
|
if (creds.organizationId) {
|
|
3991
|
-
console.log(
|
|
4082
|
+
console.log(chalk12.gray(` Organization: ${creds.organizationId}`));
|
|
3992
4083
|
}
|
|
3993
4084
|
if (creds.apiKey) {
|
|
3994
|
-
console.log(
|
|
4085
|
+
console.log(chalk12.gray(" Session: API key"));
|
|
3995
4086
|
} else if (creds.refreshToken) {
|
|
3996
|
-
console.log(
|
|
4087
|
+
console.log(chalk12.gray(" Session: refresh token stored"));
|
|
3997
4088
|
} else {
|
|
3998
|
-
console.log(
|
|
4089
|
+
console.log(chalk12.gray(" Session: token only (no refresh)"));
|
|
3999
4090
|
}
|
|
4000
4091
|
}
|
|
4001
4092
|
var CONFIG_FILE = "io.config.json";
|
|
@@ -4025,13 +4116,13 @@ async function selectOrganization(organizations, preferredId) {
|
|
|
4025
4116
|
if (organizations.length === 1) {
|
|
4026
4117
|
return organizations[0];
|
|
4027
4118
|
}
|
|
4028
|
-
console.log(
|
|
4119
|
+
console.log(chalk12.gray("\nAvailable organizations:"));
|
|
4029
4120
|
organizations.forEach((organization, index2) => {
|
|
4030
4121
|
console.log(
|
|
4031
|
-
` ${
|
|
4122
|
+
` ${chalk12.green(String(index2 + 1))}. ${organization.name} ${chalk12.gray(organization.id)}`
|
|
4032
4123
|
);
|
|
4033
4124
|
});
|
|
4034
|
-
const choice = await prompt(
|
|
4125
|
+
const choice = await prompt(chalk12.gray("\nSelect an organization (number or ID): "));
|
|
4035
4126
|
const index = Number(choice);
|
|
4036
4127
|
if (index > 0 && index <= organizations.length) {
|
|
4037
4128
|
return organizations[index - 1];
|
|
@@ -4044,16 +4135,16 @@ async function initCommand(options) {
|
|
|
4044
4135
|
const existing = await readExistingConfig(cwd);
|
|
4045
4136
|
if (existing.projectId && !options.yes) {
|
|
4046
4137
|
const overwrite = await prompt(
|
|
4047
|
-
|
|
4138
|
+
chalk12.yellow(`io.config.json already has projectId "${existing.projectId}". Overwrite? (y/n) `)
|
|
4048
4139
|
);
|
|
4049
4140
|
if (overwrite.toLowerCase() !== "y") {
|
|
4050
|
-
console.log(
|
|
4141
|
+
console.log(chalk12.gray("Cancelled."));
|
|
4051
4142
|
return;
|
|
4052
4143
|
}
|
|
4053
4144
|
}
|
|
4054
4145
|
const config = { ...existing };
|
|
4055
4146
|
if (!config.apiUrl) {
|
|
4056
|
-
const apiUrl = await prompt(
|
|
4147
|
+
const apiUrl = await prompt(chalk12.gray("API URL (leave blank for default): "));
|
|
4057
4148
|
if (apiUrl) {
|
|
4058
4149
|
config.apiUrl = apiUrl;
|
|
4059
4150
|
}
|
|
@@ -4075,7 +4166,7 @@ async function initCommand(options) {
|
|
|
4075
4166
|
try {
|
|
4076
4167
|
organizations = await client.organizations();
|
|
4077
4168
|
} catch {
|
|
4078
|
-
console.log(
|
|
4169
|
+
console.log(chalk12.yellow("Could not fetch organizations. Enter project ID manually."));
|
|
4079
4170
|
}
|
|
4080
4171
|
const selectedOrganization = await selectOrganization(
|
|
4081
4172
|
organizations,
|
|
@@ -4084,14 +4175,14 @@ async function initCommand(options) {
|
|
|
4084
4175
|
if (selectedOrganization) {
|
|
4085
4176
|
const projects2 = await client.projects(selectedOrganization.id);
|
|
4086
4177
|
if (projects2.length > 0) {
|
|
4087
|
-
console.log(
|
|
4178
|
+
console.log(chalk12.gray("\nAvailable projects:"));
|
|
4088
4179
|
projects2.forEach((project, index2) => {
|
|
4089
4180
|
console.log(
|
|
4090
|
-
` ${
|
|
4181
|
+
` ${chalk12.green(String(index2 + 1))}. ${project.name} ${chalk12.gray(project.id)}`
|
|
4091
4182
|
);
|
|
4092
4183
|
});
|
|
4093
4184
|
const choice = await prompt(
|
|
4094
|
-
|
|
4185
|
+
chalk12.gray("\nSelect a project (number) or enter a project ID: ")
|
|
4095
4186
|
);
|
|
4096
4187
|
const index = Number(choice);
|
|
4097
4188
|
if (index > 0 && index <= projects2.length) {
|
|
@@ -4101,26 +4192,26 @@ async function initCommand(options) {
|
|
|
4101
4192
|
}
|
|
4102
4193
|
} else {
|
|
4103
4194
|
const createNew = await prompt(
|
|
4104
|
-
|
|
4195
|
+
chalk12.gray("No projects found. Create one? (y/n) ")
|
|
4105
4196
|
);
|
|
4106
4197
|
if (createNew.toLowerCase() === "y") {
|
|
4107
|
-
const name = await prompt(
|
|
4198
|
+
const name = await prompt(chalk12.gray("Project name: "));
|
|
4108
4199
|
if (name) {
|
|
4109
4200
|
const project = await client.createProject(selectedOrganization.id, name);
|
|
4110
4201
|
config.projectId = project.id;
|
|
4111
|
-
console.log(
|
|
4202
|
+
console.log(chalk12.green(`\u2713 Created project: ${project.name}`));
|
|
4112
4203
|
}
|
|
4113
4204
|
}
|
|
4114
4205
|
}
|
|
4115
4206
|
} else {
|
|
4116
|
-
const projectId = await prompt(
|
|
4207
|
+
const projectId = await prompt(chalk12.gray("Project ID (or leave blank): "));
|
|
4117
4208
|
if (projectId) {
|
|
4118
4209
|
config.projectId = projectId;
|
|
4119
4210
|
}
|
|
4120
4211
|
}
|
|
4121
4212
|
} else {
|
|
4122
|
-
console.log(
|
|
4123
|
-
const projectId = await prompt(
|
|
4213
|
+
console.log(chalk12.yellow("Not logged in. Run `io login` first to select a project."));
|
|
4214
|
+
const projectId = await prompt(chalk12.gray("Project ID (or leave blank): "));
|
|
4124
4215
|
if (projectId) {
|
|
4125
4216
|
config.projectId = projectId;
|
|
4126
4217
|
}
|
|
@@ -4130,14 +4221,14 @@ async function initCommand(options) {
|
|
|
4130
4221
|
JSON.stringify(config, null, 2) + "\n",
|
|
4131
4222
|
"utf-8"
|
|
4132
4223
|
);
|
|
4133
|
-
console.log(
|
|
4224
|
+
console.log(chalk12.green(`
|
|
4134
4225
|
\u2713 Wrote ${CONFIG_FILE}`));
|
|
4135
4226
|
if (config.projectId) {
|
|
4136
|
-
console.log(
|
|
4227
|
+
console.log(chalk12.gray(` Project: ${config.projectId}`));
|
|
4137
4228
|
}
|
|
4138
4229
|
} catch (err) {
|
|
4139
4230
|
if (err instanceof CliError) {
|
|
4140
|
-
console.error(
|
|
4231
|
+
console.error(chalk12.red(err.message));
|
|
4141
4232
|
process.exit(1);
|
|
4142
4233
|
}
|
|
4143
4234
|
throw err;
|
|
@@ -4165,16 +4256,16 @@ async function projectsListCommand() {
|
|
|
4165
4256
|
const organizationId = await resolveOrganizationId(client);
|
|
4166
4257
|
const projects2 = await client.projects(organizationId);
|
|
4167
4258
|
if (!projects2 || projects2.length === 0) {
|
|
4168
|
-
console.log(
|
|
4259
|
+
console.log(chalk12.gray("No projects found. Create one with `io projects create <name>`."));
|
|
4169
4260
|
return;
|
|
4170
4261
|
}
|
|
4171
4262
|
for (const p of projects2) {
|
|
4172
|
-
const current = p.id === config.projectId ?
|
|
4173
|
-
console.log(` ${p.name} ${
|
|
4263
|
+
const current = p.id === config.projectId ? chalk12.green(" (current)") : "";
|
|
4264
|
+
console.log(` ${p.name} ${chalk12.gray(p.id)}${current}`);
|
|
4174
4265
|
}
|
|
4175
4266
|
} catch (err) {
|
|
4176
4267
|
if (err instanceof CliError) {
|
|
4177
|
-
console.error(
|
|
4268
|
+
console.error(chalk12.red(err.message));
|
|
4178
4269
|
process.exit(1);
|
|
4179
4270
|
}
|
|
4180
4271
|
throw err;
|
|
@@ -4186,10 +4277,10 @@ async function projectsCreateCommand(name) {
|
|
|
4186
4277
|
const client = createClient(config);
|
|
4187
4278
|
const organizationId = await resolveOrganizationId(client);
|
|
4188
4279
|
const project = await client.createProject(organizationId, name);
|
|
4189
|
-
console.log(
|
|
4190
|
-
console.log(
|
|
4280
|
+
console.log(chalk12.green(`\u2713 Created project: ${project.name}`));
|
|
4281
|
+
console.log(chalk12.gray(` ID: ${project.id}`));
|
|
4191
4282
|
console.log(
|
|
4192
|
-
|
|
4283
|
+
chalk12.gray(
|
|
4193
4284
|
`
|
|
4194
4285
|
Add to io.config.json:
|
|
4195
4286
|
{ "projectId": "${project.id}" }`
|
|
@@ -4197,7 +4288,7 @@ async function projectsCreateCommand(name) {
|
|
|
4197
4288
|
);
|
|
4198
4289
|
} catch (err) {
|
|
4199
4290
|
if (err instanceof CliError) {
|
|
4200
|
-
console.error(
|
|
4291
|
+
console.error(chalk12.red(err.message));
|
|
4201
4292
|
process.exit(1);
|
|
4202
4293
|
}
|
|
4203
4294
|
throw err;
|
|
@@ -4209,10 +4300,10 @@ async function secretsSetCommand(name, value) {
|
|
|
4209
4300
|
const client = createClient(config);
|
|
4210
4301
|
const pid = client.projectId();
|
|
4211
4302
|
await client.putSecret(pid, { name, value });
|
|
4212
|
-
console.log(
|
|
4303
|
+
console.log(chalk12.green(`\u2713 Set secret: ${name}`));
|
|
4213
4304
|
} catch (err) {
|
|
4214
4305
|
if (err instanceof CliError) {
|
|
4215
|
-
console.error(
|
|
4306
|
+
console.error(chalk12.red(err.message));
|
|
4216
4307
|
process.exit(1);
|
|
4217
4308
|
}
|
|
4218
4309
|
throw err;
|
|
@@ -4224,16 +4315,16 @@ async function secretsListCommand() {
|
|
|
4224
4315
|
const client = createClient(config);
|
|
4225
4316
|
const secrets2 = await client.listSecrets(client.projectId());
|
|
4226
4317
|
if (!secrets2 || secrets2.length === 0) {
|
|
4227
|
-
console.log(
|
|
4318
|
+
console.log(chalk12.gray("No secrets configured."));
|
|
4228
4319
|
return;
|
|
4229
4320
|
}
|
|
4230
4321
|
for (const s of secrets2) {
|
|
4231
|
-
const value = s.hasValue ? "" :
|
|
4322
|
+
const value = s.hasValue ? "" : chalk12.gray(" (no value)");
|
|
4232
4323
|
console.log(` ${s.name}${value}`);
|
|
4233
4324
|
}
|
|
4234
4325
|
} catch (err) {
|
|
4235
4326
|
if (err instanceof CliError) {
|
|
4236
|
-
console.error(
|
|
4327
|
+
console.error(chalk12.red(err.message));
|
|
4237
4328
|
process.exit(1);
|
|
4238
4329
|
}
|
|
4239
4330
|
throw err;
|
|
@@ -4245,25 +4336,123 @@ async function secretsRemoveCommand(name) {
|
|
|
4245
4336
|
const client = createClient(config);
|
|
4246
4337
|
const removed = await client.deleteSecret(client.projectId(), name);
|
|
4247
4338
|
if (!removed) {
|
|
4248
|
-
console.log(
|
|
4339
|
+
console.log(chalk12.yellow(`Secret "${name}" not found.`));
|
|
4249
4340
|
return;
|
|
4250
4341
|
}
|
|
4251
|
-
console.log(
|
|
4342
|
+
console.log(chalk12.green(`\u2713 Removed secret: ${name}`));
|
|
4252
4343
|
} catch (err) {
|
|
4253
4344
|
if (err instanceof CliError) {
|
|
4254
|
-
console.error(
|
|
4345
|
+
console.error(chalk12.red(err.message));
|
|
4255
4346
|
process.exit(1);
|
|
4256
4347
|
}
|
|
4257
4348
|
throw err;
|
|
4258
4349
|
}
|
|
4259
4350
|
}
|
|
4351
|
+
function parseMetadata(input) {
|
|
4352
|
+
if (!input) return void 0;
|
|
4353
|
+
try {
|
|
4354
|
+
const parsed = JSON.parse(input);
|
|
4355
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4356
|
+
return parsed;
|
|
4357
|
+
}
|
|
4358
|
+
} catch {
|
|
4359
|
+
}
|
|
4360
|
+
throw new ConfigError("metadata must be a JSON object");
|
|
4361
|
+
}
|
|
4362
|
+
function validateState(state) {
|
|
4363
|
+
if (!state) return void 0;
|
|
4364
|
+
if (state === "active" || state === "inactive" || state === "archived") return state;
|
|
4365
|
+
throw new ConfigError("state must be active, inactive, or archived");
|
|
4366
|
+
}
|
|
4367
|
+
async function withClient(options) {
|
|
4368
|
+
const config = await loadConfig({ projectId: options.projectId });
|
|
4369
|
+
const client = createClient(config);
|
|
4370
|
+
return { client, projectId: client.projectId() };
|
|
4371
|
+
}
|
|
4372
|
+
function handleError(err) {
|
|
4373
|
+
if (err instanceof CliError) {
|
|
4374
|
+
console.error(chalk12.red(err.message));
|
|
4375
|
+
process.exit(1);
|
|
4376
|
+
}
|
|
4377
|
+
throw err;
|
|
4378
|
+
}
|
|
4379
|
+
async function principalsListCommand(options) {
|
|
4380
|
+
try {
|
|
4381
|
+
const { client, projectId } = await withClient(options);
|
|
4382
|
+
const principals2 = await client.principals(projectId);
|
|
4383
|
+
if (principals2.length === 0) {
|
|
4384
|
+
console.log(chalk12.gray("No principals found. Create one with `io principals create <external-id>`."));
|
|
4385
|
+
return;
|
|
4386
|
+
}
|
|
4387
|
+
for (const principal of principals2) {
|
|
4388
|
+
console.log(
|
|
4389
|
+
` ${principal.externalId} ${chalk12.gray(principal.id)} ${chalk12.gray(principal.state)}`
|
|
4390
|
+
);
|
|
4391
|
+
}
|
|
4392
|
+
} catch (err) {
|
|
4393
|
+
handleError(err);
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
async function principalsCreateCommand(externalId, options) {
|
|
4397
|
+
try {
|
|
4398
|
+
const { client, projectId } = await withClient(options);
|
|
4399
|
+
const principal = await client.createPrincipal(projectId, {
|
|
4400
|
+
externalId,
|
|
4401
|
+
state: validateState(options.state),
|
|
4402
|
+
metadata: parseMetadata(options.metadata)
|
|
4403
|
+
});
|
|
4404
|
+
console.log(chalk12.green(`\u2713 Created principal: ${principal.externalId}`));
|
|
4405
|
+
console.log(chalk12.gray(` ID: ${principal.id}`));
|
|
4406
|
+
console.log(chalk12.gray(` Project: ${principal.projectId}`));
|
|
4407
|
+
console.log(chalk12.gray(` State: ${principal.state}`));
|
|
4408
|
+
} catch (err) {
|
|
4409
|
+
handleError(err);
|
|
4410
|
+
}
|
|
4411
|
+
}
|
|
4412
|
+
async function principalsUpdateCommand(id, options) {
|
|
4413
|
+
try {
|
|
4414
|
+
const { client, projectId } = await withClient(options);
|
|
4415
|
+
const input = {
|
|
4416
|
+
externalId: options.externalId,
|
|
4417
|
+
state: validateState(options.state),
|
|
4418
|
+
metadata: parseMetadata(options.metadata)
|
|
4419
|
+
};
|
|
4420
|
+
if (!input.externalId && !input.state && !input.metadata) {
|
|
4421
|
+
throw new ConfigError("nothing to update; pass --external-id, --state, or --metadata");
|
|
4422
|
+
}
|
|
4423
|
+
const principal = await client.updatePrincipal(projectId, id, input);
|
|
4424
|
+
if (!principal) {
|
|
4425
|
+
console.log(chalk12.yellow(`Principal "${id}" not found.`));
|
|
4426
|
+
return;
|
|
4427
|
+
}
|
|
4428
|
+
console.log(chalk12.green(`\u2713 Updated principal: ${principal.externalId}`));
|
|
4429
|
+
console.log(chalk12.gray(` ID: ${principal.id}`));
|
|
4430
|
+
console.log(chalk12.gray(` Project: ${principal.projectId}`));
|
|
4431
|
+
console.log(chalk12.gray(` State: ${principal.state}`));
|
|
4432
|
+
} catch (err) {
|
|
4433
|
+
handleError(err);
|
|
4434
|
+
}
|
|
4435
|
+
}
|
|
4436
|
+
async function principalsDeleteCommand(id, options) {
|
|
4437
|
+
try {
|
|
4438
|
+
const { client, projectId } = await withClient(options);
|
|
4439
|
+
const principal = await client.deletePrincipal(projectId, id);
|
|
4440
|
+
if (!principal) {
|
|
4441
|
+
console.log(chalk12.yellow(`Principal "${id}" not found.`));
|
|
4442
|
+
return;
|
|
4443
|
+
}
|
|
4444
|
+
console.log(chalk12.green(`\u2713 Deleted principal: ${principal.externalId}`));
|
|
4445
|
+
} catch (err) {
|
|
4446
|
+
handleError(err);
|
|
4447
|
+
}
|
|
4448
|
+
}
|
|
4260
4449
|
function meterBar(used, limit, width = 20) {
|
|
4261
|
-
if (limit === 0) return
|
|
4450
|
+
if (limit === 0) return chalk12.gray("\u2591".repeat(width));
|
|
4262
4451
|
const ratio = Math.min(used / limit, 1);
|
|
4263
4452
|
const filled = Math.round(ratio * width);
|
|
4264
4453
|
const empty = width - filled;
|
|
4265
|
-
const color = ratio >= 0.9 ?
|
|
4266
|
-
return color("\u2588".repeat(filled)) +
|
|
4454
|
+
const color = ratio >= 0.9 ? chalk12.red : ratio >= 0.7 ? chalk12.yellow : chalk12.green;
|
|
4455
|
+
return color("\u2588".repeat(filled)) + chalk12.gray("\u2591".repeat(empty));
|
|
4267
4456
|
}
|
|
4268
4457
|
function formatNumber(n) {
|
|
4269
4458
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
@@ -4273,9 +4462,11 @@ function formatNumber(n) {
|
|
|
4273
4462
|
var METER_LABELS = {
|
|
4274
4463
|
events: "Events",
|
|
4275
4464
|
ingest_tokens: "Ingest Tokens",
|
|
4465
|
+
query_tokens: "Query Tokens",
|
|
4276
4466
|
voice_seconds: "Voice Seconds",
|
|
4277
4467
|
compute_gb_sec: "Compute (GB\xB7s)",
|
|
4278
|
-
storage_gb: "Storage (GB)"
|
|
4468
|
+
storage_gb: "Memory Storage (GB)",
|
|
4469
|
+
artifact_storage_gb: "Artifact Storage (GB)"
|
|
4279
4470
|
};
|
|
4280
4471
|
async function quotaCommand() {
|
|
4281
4472
|
try {
|
|
@@ -4283,22 +4474,22 @@ async function quotaCommand() {
|
|
|
4283
4474
|
const client = createClient(config);
|
|
4284
4475
|
const statuses = await client.quotaStatuses();
|
|
4285
4476
|
if (statuses.length === 0) {
|
|
4286
|
-
console.log(
|
|
4477
|
+
console.log(chalk12.gray("No quota data available."));
|
|
4287
4478
|
return;
|
|
4288
4479
|
}
|
|
4289
|
-
console.log(
|
|
4480
|
+
console.log(chalk12.bold("\nQuota Usage\n"));
|
|
4290
4481
|
for (const status of statuses) {
|
|
4291
4482
|
const label = METER_LABELS[status.meter] ?? status.meter;
|
|
4292
4483
|
const bar = meterBar(status.used, status.limit);
|
|
4293
4484
|
const pct = status.limit > 0 ? `${status.percentageUsed.toFixed(1)}%` : "\u2014";
|
|
4294
4485
|
const usage = `${formatNumber(status.used)} / ${formatNumber(status.limit)}`;
|
|
4295
|
-
const enforcement = status.enforcement === "hard_cap" ?
|
|
4296
|
-
console.log(` ${label.padEnd(
|
|
4486
|
+
const enforcement = status.enforcement === "hard_cap" ? chalk12.red("hard") : chalk12.yellow("soft");
|
|
4487
|
+
console.log(` ${label.padEnd(22)} ${bar} ${usage.padStart(16)} ${pct.padStart(6)} ${enforcement}`);
|
|
4297
4488
|
}
|
|
4298
4489
|
console.log();
|
|
4299
4490
|
} catch (err) {
|
|
4300
4491
|
if (err instanceof CliError) {
|
|
4301
|
-
console.error(
|
|
4492
|
+
console.error(chalk12.red(err.message));
|
|
4302
4493
|
process.exit(1);
|
|
4303
4494
|
}
|
|
4304
4495
|
throw err;
|
|
@@ -4694,18 +4885,18 @@ function inferActivityPrincipalLabel(event) {
|
|
|
4694
4885
|
|
|
4695
4886
|
// src/commands/logs.ts
|
|
4696
4887
|
var LEVEL_COLORS = {
|
|
4697
|
-
error:
|
|
4698
|
-
warning:
|
|
4699
|
-
info:
|
|
4700
|
-
success:
|
|
4701
|
-
scheduled:
|
|
4888
|
+
error: chalk12.red,
|
|
4889
|
+
warning: chalk12.yellow,
|
|
4890
|
+
info: chalk12.blue,
|
|
4891
|
+
success: chalk12.green,
|
|
4892
|
+
scheduled: chalk12.magenta
|
|
4702
4893
|
};
|
|
4703
4894
|
var FOLLOW_POLL_INTERVAL_MS = 2e3;
|
|
4704
4895
|
var FOLLOW_SEEN_ID_LIMIT = 1e3;
|
|
4705
4896
|
var FOLLOW_BATCH_LIMIT = 200;
|
|
4706
4897
|
function colorLevel(level) {
|
|
4707
|
-
if (!level) return
|
|
4708
|
-
const colorFn = LEVEL_COLORS[level] ??
|
|
4898
|
+
if (!level) return chalk12.gray("\u2014");
|
|
4899
|
+
const colorFn = LEVEL_COLORS[level] ?? chalk12.gray;
|
|
4709
4900
|
return colorFn(level.padEnd(7));
|
|
4710
4901
|
}
|
|
4711
4902
|
function pad(value, width) {
|
|
@@ -4718,8 +4909,8 @@ function formatTime(isoString) {
|
|
|
4718
4909
|
}
|
|
4719
4910
|
function formatDuration(ms) {
|
|
4720
4911
|
if (ms == null) return "";
|
|
4721
|
-
if (ms < 1e3) return
|
|
4722
|
-
return
|
|
4912
|
+
if (ms < 1e3) return chalk12.gray(`${ms}ms`);
|
|
4913
|
+
return chalk12.gray(`${(ms / 1e3).toFixed(1)}s`);
|
|
4723
4914
|
}
|
|
4724
4915
|
function truncate(value, width) {
|
|
4725
4916
|
if (value.length <= width) return value;
|
|
@@ -4727,19 +4918,19 @@ function truncate(value, width) {
|
|
|
4727
4918
|
}
|
|
4728
4919
|
function formatHeader() {
|
|
4729
4920
|
return [
|
|
4730
|
-
` ${
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4921
|
+
` ${chalk12.gray(pad("TIME", 10))}`,
|
|
4922
|
+
chalk12.gray(pad("STATUS", 9)),
|
|
4923
|
+
chalk12.gray(pad("CATEGORY", 14)),
|
|
4924
|
+
chalk12.gray(pad("NAME", 24)),
|
|
4925
|
+
chalk12.gray(pad("DURATION", 10)),
|
|
4926
|
+
chalk12.gray("DETAIL")
|
|
4736
4927
|
].join(" ");
|
|
4737
4928
|
}
|
|
4738
4929
|
function formatEvent(event) {
|
|
4739
|
-
const time =
|
|
4930
|
+
const time = chalk12.gray(formatTime(event.occurredAt));
|
|
4740
4931
|
const statusKey = inferActivityEventStatus(event);
|
|
4741
4932
|
const status = colorLevel(statusKey);
|
|
4742
|
-
const category =
|
|
4933
|
+
const category = chalk12.cyan(pad(inferActivityEventCategory(event), 14));
|
|
4743
4934
|
const name = pad(truncate(inferActivityEventName(event), 24), 24);
|
|
4744
4935
|
const duration = formatDuration(event.durationMs);
|
|
4745
4936
|
const detail = inferActivityEventDetail(event) || inferActivityPrincipalLabel(event) || "";
|
|
@@ -4749,7 +4940,7 @@ function formatEvent(event) {
|
|
|
4749
4940
|
category,
|
|
4750
4941
|
name,
|
|
4751
4942
|
pad(duration || "", 10),
|
|
4752
|
-
detail ?
|
|
4943
|
+
detail ? chalk12.gray(detail) : ""
|
|
4753
4944
|
].join(" ").trimEnd();
|
|
4754
4945
|
}
|
|
4755
4946
|
function latestOccurredAt(events, fallback) {
|
|
@@ -4811,7 +5002,7 @@ async function drainFollowEvents(client, projectId, input, since, seenIds, seenO
|
|
|
4811
5002
|
}
|
|
4812
5003
|
function installSigintHandler(onExit) {
|
|
4813
5004
|
const handleSigint = () => {
|
|
4814
|
-
console.log(
|
|
5005
|
+
console.log(chalk12.gray("\n Disconnected."));
|
|
4815
5006
|
onExit();
|
|
4816
5007
|
process.exit(0);
|
|
4817
5008
|
};
|
|
@@ -4837,15 +5028,15 @@ async function logsCommand(options) {
|
|
|
4837
5028
|
}
|
|
4838
5029
|
const events = await client.projectEvents(pid, input);
|
|
4839
5030
|
if (events.length === 0 && !options.follow) {
|
|
4840
|
-
console.log(
|
|
5031
|
+
console.log(chalk12.gray("No events found."));
|
|
4841
5032
|
return;
|
|
4842
5033
|
}
|
|
4843
5034
|
if (events.length > 0) {
|
|
4844
|
-
console.log(
|
|
5035
|
+
console.log(chalk12.bold(`
|
|
4845
5036
|
Activity Log \u2014 ${events.length} events
|
|
4846
5037
|
`));
|
|
4847
5038
|
console.log(formatHeader());
|
|
4848
|
-
console.log(
|
|
5039
|
+
console.log(chalk12.gray(` ${"\u2500".repeat(92)}`));
|
|
4849
5040
|
for (const event of events) {
|
|
4850
5041
|
console.log(formatEvent(event));
|
|
4851
5042
|
}
|
|
@@ -4864,7 +5055,7 @@ Activity Log \u2014 ${events.length} events
|
|
|
4864
5055
|
}
|
|
4865
5056
|
} catch (err) {
|
|
4866
5057
|
if (err instanceof CliError) {
|
|
4867
|
-
console.error(
|
|
5058
|
+
console.error(chalk12.red(err.message));
|
|
4868
5059
|
process.exit(1);
|
|
4869
5060
|
}
|
|
4870
5061
|
throw err;
|
|
@@ -4875,7 +5066,7 @@ async function tailEvents(apiUrl, client, projectId, input, initialEvents, follo
|
|
|
4875
5066
|
if (!creds || !creds.token) {
|
|
4876
5067
|
throw new ConfigError("Not authenticated. Run `io login` first.");
|
|
4877
5068
|
}
|
|
4878
|
-
console.log(
|
|
5069
|
+
console.log(chalk12.gray("\n Waiting for events... (Ctrl+C to stop)\n"));
|
|
4879
5070
|
if (creds.apiKey) {
|
|
4880
5071
|
return new Promise((_resolve, reject) => {
|
|
4881
5072
|
let disconnect;
|
|
@@ -4899,7 +5090,7 @@ async function tailEvents(apiUrl, client, projectId, input, initialEvents, follo
|
|
|
4899
5090
|
trimSeenIds(seenIds2, seenOrder2);
|
|
4900
5091
|
},
|
|
4901
5092
|
onConnected: () => {
|
|
4902
|
-
console.log(
|
|
5093
|
+
console.log(chalk12.green(" \u25CF Connected \u2014 tailing live events\n"));
|
|
4903
5094
|
void drainFollowEvents(
|
|
4904
5095
|
client,
|
|
4905
5096
|
projectId,
|
|
@@ -4912,7 +5103,7 @@ async function tailEvents(apiUrl, client, projectId, input, initialEvents, follo
|
|
|
4912
5103
|
console.log(formatEvent(event));
|
|
4913
5104
|
}
|
|
4914
5105
|
}).catch((error) => {
|
|
4915
|
-
console.error(
|
|
5106
|
+
console.error(chalk12.red(`
|
|
4916
5107
|
Connection error: ${error.message}`));
|
|
4917
5108
|
removeSigintHandler2();
|
|
4918
5109
|
disconnect?.();
|
|
@@ -4920,7 +5111,7 @@ async function tailEvents(apiUrl, client, projectId, input, initialEvents, follo
|
|
|
4920
5111
|
});
|
|
4921
5112
|
},
|
|
4922
5113
|
onError: (error) => {
|
|
4923
|
-
console.error(
|
|
5114
|
+
console.error(chalk12.red(`
|
|
4924
5115
|
Connection error: ${error.message}`));
|
|
4925
5116
|
removeSigintHandler2();
|
|
4926
5117
|
disconnect?.();
|
|
@@ -4930,7 +5121,7 @@ async function tailEvents(apiUrl, client, projectId, input, initialEvents, follo
|
|
|
4930
5121
|
});
|
|
4931
5122
|
}
|
|
4932
5123
|
console.log(
|
|
4933
|
-
|
|
5124
|
+
chalk12.green(" \u25CF Connected \u2014 polling for live events with your authenticated session\n")
|
|
4934
5125
|
);
|
|
4935
5126
|
const seenIds = new Set(initialEvents.map((event) => event.id));
|
|
4936
5127
|
const seenOrder = initialEvents.map((event) => event.id);
|
|
@@ -4996,10 +5187,14 @@ async function signalEmitCommand(name, options) {
|
|
|
4996
5187
|
"signal name must be a bare event name like smoke.start or use the signal: namespace"
|
|
4997
5188
|
);
|
|
4998
5189
|
}
|
|
5190
|
+
if (!options.principalId || options.principalId.trim() === "") {
|
|
5191
|
+
throw new ConfigError("signals emit requires --principal-id <id>");
|
|
5192
|
+
}
|
|
4999
5193
|
const payload = parseJsonObject(options.payload, "payload");
|
|
5000
5194
|
const metadata = parseJsonObject(options.metadata, "metadata");
|
|
5001
5195
|
const event = await client.emitSignal({
|
|
5002
5196
|
signal,
|
|
5197
|
+
principalId: options.principalId,
|
|
5003
5198
|
payload,
|
|
5004
5199
|
metadata,
|
|
5005
5200
|
correlationId: options.correlationId,
|
|
@@ -5011,18 +5206,18 @@ async function signalEmitCommand(name, options) {
|
|
|
5011
5206
|
console.log(JSON.stringify(event, null, 2));
|
|
5012
5207
|
return;
|
|
5013
5208
|
}
|
|
5014
|
-
console.log(
|
|
5015
|
-
console.log(
|
|
5016
|
-
console.log(
|
|
5209
|
+
console.log(chalk12.green(`\u2713 Emitted ${event.name}`));
|
|
5210
|
+
console.log(chalk12.gray(` Event: ${event.id}`));
|
|
5211
|
+
console.log(chalk12.gray(` Project: ${event.projectId}`));
|
|
5017
5212
|
if (event.dispatchStatus) {
|
|
5018
|
-
console.log(
|
|
5213
|
+
console.log(chalk12.gray(` Dispatch: ${event.dispatchStatus}`));
|
|
5019
5214
|
}
|
|
5020
5215
|
if (event.occurredAt) {
|
|
5021
|
-
console.log(
|
|
5216
|
+
console.log(chalk12.gray(` At: ${event.occurredAt}`));
|
|
5022
5217
|
}
|
|
5023
5218
|
} catch (err) {
|
|
5024
5219
|
if (err instanceof CliError) {
|
|
5025
|
-
console.error(
|
|
5220
|
+
console.error(chalk12.red(err.message));
|
|
5026
5221
|
process.exit(1);
|
|
5027
5222
|
}
|
|
5028
5223
|
throw err;
|
|
@@ -5031,7 +5226,7 @@ async function signalEmitCommand(name, options) {
|
|
|
5031
5226
|
|
|
5032
5227
|
// src/index.ts
|
|
5033
5228
|
var program = new Command();
|
|
5034
|
-
program.name("io").description("IO CLI \u2014 build and deploy behaviors").version("0.1.
|
|
5229
|
+
program.name("io").description("IO CLI \u2014 build and deploy behaviors").version("0.1.15");
|
|
5035
5230
|
program.command("init").description("Initialize io.config.json for the current project").option("--yes", "Overwrite existing config without prompting").action(initCommand);
|
|
5036
5231
|
program.command("build").description("Build behaviors from the io/ directory").option("--dir <path>", "Source directory", "io").option("--minify", "Minify bundles", false).action(buildCommand);
|
|
5037
5232
|
program.command("deploy").description("Build and package for deployment").option("--dir <path>", "Source directory", "io").option("--no-minify", "Skip minification").option("--yes", "Skip confirmation prompt").action(deployCommand);
|
|
@@ -5045,8 +5240,13 @@ var secrets = program.command("secrets").description("Manage project secrets");
|
|
|
5045
5240
|
secrets.command("set <name> <value>").description("Set a secret value").option("--target <targets...>", "Restrict to specific targets").action(secretsSetCommand);
|
|
5046
5241
|
secrets.command("list").description("List all secrets").action(secretsListCommand);
|
|
5047
5242
|
secrets.command("remove <name>").description("Remove a secret").action(secretsRemoveCommand);
|
|
5243
|
+
var principals = program.command("principals").description("Manage project principals");
|
|
5244
|
+
principals.command("list").description("List principals in the active project").option("--project-id <id>", "Override the configured project ID").action(principalsListCommand);
|
|
5245
|
+
principals.command("create <external-id>").description("Create a principal in the active project").option("--project-id <id>", "Override the configured project ID").option("--state <state>", "Principal state: active, inactive, or archived").option("--metadata <json>", "Principal metadata as a JSON object").action(principalsCreateCommand);
|
|
5246
|
+
principals.command("update <id>").description("Update a principal").option("--project-id <id>", "Override the configured project ID").option("--external-id <external-id>", "Replace the external ID").option("--state <state>", "Principal state: active, inactive, or archived").option("--metadata <json>", "Replace principal metadata with a JSON object").action(principalsUpdateCommand);
|
|
5247
|
+
principals.command("delete <id>").description("Delete a principal").option("--project-id <id>", "Override the configured project ID").action(principalsDeleteCommand);
|
|
5048
5248
|
var signals = program.command("signals").description("Emit runtime signals");
|
|
5049
|
-
signals.command("emit <name>").description("Emit a signal into the active project's event stream").option("--payload <json>", "Signal payload as a JSON object", "{}").option("--metadata <json>", "Signal metadata as a JSON object", "{}").option("--project-id <id>", "Override the configured project ID").option("--correlation-id <id>", "Correlation ID to attach to the signal").option("--causation-id <id>", "Causation ID to attach to the signal").option("--idempotency-key <key>", "Optional idempotency key").option("--source-name <name>", "Optional source name for the emitted signal").option("--json", "Print the raw emitted event as JSON", false).action(signalEmitCommand);
|
|
5249
|
+
signals.command("emit <name>").description("Emit a signal into the active project's event stream").option("--payload <json>", "Signal payload as a JSON object", "{}").option("--metadata <json>", "Signal metadata as a JSON object", "{}").option("--project-id <id>", "Override the configured project ID").requiredOption("--principal-id <id>", "Project principal ID for the emitted signal").option("--correlation-id <id>", "Correlation ID to attach to the signal").option("--causation-id <id>", "Causation ID to attach to the signal").option("--idempotency-key <key>", "Optional idempotency key").option("--source-name <name>", "Optional source name for the emitted signal").option("--json", "Print the raw emitted event as JSON", false).action(signalEmitCommand);
|
|
5050
5250
|
program.command("quota").description("Show current quota usage for the active organization").action(quotaCommand);
|
|
5051
5251
|
program.command("logs").description("Show recent activity events").option("--limit <count>", "Number of events to show", "50").option("--type <types...>", "Filter by event types").option("--since <duration>", "Show events since (e.g. 15m, 1h, 7d)").option("--follow", "Tail events in real-time").action(logsCommand);
|
|
5052
5252
|
program.parse();
|