@kaelen-ai/cli 0.1.14 → 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 +307 -114
- 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';
|
|
@@ -2776,7 +2776,7 @@ async function buildCommand(options) {
|
|
|
2776
2776
|
const config = await loadConfig({
|
|
2777
2777
|
dir: options.dir
|
|
2778
2778
|
});
|
|
2779
|
-
console.log(
|
|
2779
|
+
console.log(chalk12.gray("Validating deployment..."));
|
|
2780
2780
|
stagingDir = await createStagingDir();
|
|
2781
2781
|
const { manifest } = await buildPipeline(
|
|
2782
2782
|
config,
|
|
@@ -2806,10 +2806,10 @@ async function buildCommand(options) {
|
|
|
2806
2806
|
`${subscriptions.length} subscription${subscriptions.length === 1 ? "" : "s"}`,
|
|
2807
2807
|
`${secretBundles.length} secret bundle${secretBundles.length === 1 ? "" : "s"}`
|
|
2808
2808
|
];
|
|
2809
|
-
console.log(
|
|
2809
|
+
console.log(chalk12.green(`\u2713 Build succeeded (${parts.join(", ")})`));
|
|
2810
2810
|
} catch (err) {
|
|
2811
2811
|
if (err instanceof CliError) {
|
|
2812
|
-
console.error(
|
|
2812
|
+
console.error(chalk12.red(err.message));
|
|
2813
2813
|
process.exit(1);
|
|
2814
2814
|
}
|
|
2815
2815
|
throw err;
|
|
@@ -2996,9 +2996,9 @@ function diffManifests(local, remote) {
|
|
|
2996
2996
|
};
|
|
2997
2997
|
}
|
|
2998
2998
|
var SYMBOLS = {
|
|
2999
|
-
added:
|
|
3000
|
-
changed:
|
|
3001
|
-
removed:
|
|
2999
|
+
added: chalk12.green("+ "),
|
|
3000
|
+
changed: chalk12.yellow("~ "),
|
|
3001
|
+
removed: chalk12.red("- ")
|
|
3002
3002
|
};
|
|
3003
3003
|
var LABELS = {
|
|
3004
3004
|
added: "new",
|
|
@@ -3020,11 +3020,11 @@ function formatPlan(diff) {
|
|
|
3020
3020
|
const entries = diff[key];
|
|
3021
3021
|
lines.push(` ${label}:`);
|
|
3022
3022
|
if (entries.length === 0) {
|
|
3023
|
-
lines.push(
|
|
3023
|
+
lines.push(chalk12.gray(" (no changes)"));
|
|
3024
3024
|
} else {
|
|
3025
3025
|
for (const e of entries) {
|
|
3026
3026
|
lines.push(
|
|
3027
|
-
` ${SYMBOLS[e.kind]}${e.name} ${
|
|
3027
|
+
` ${SYMBOLS[e.kind]}${e.name} ${chalk12.gray(`(${LABELS[e.kind]})`)}`
|
|
3028
3028
|
);
|
|
3029
3029
|
}
|
|
3030
3030
|
}
|
|
@@ -3478,6 +3478,82 @@ function createClient(config) {
|
|
|
3478
3478
|
);
|
|
3479
3479
|
return data.createProject;
|
|
3480
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
|
+
}
|
|
3481
3557
|
async function listSecrets(projectIdValue) {
|
|
3482
3558
|
const data = await graphql(
|
|
3483
3559
|
`
|
|
@@ -3598,6 +3674,9 @@ function createClient(config) {
|
|
|
3598
3674
|
}
|
|
3599
3675
|
async function emitSignal(input) {
|
|
3600
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
|
+
}
|
|
3601
3680
|
const eventName = normalizeRuntimeSignalName2(input.signal);
|
|
3602
3681
|
if (!eventName) {
|
|
3603
3682
|
throw new ConfigError(
|
|
@@ -3625,6 +3704,7 @@ function createClient(config) {
|
|
|
3625
3704
|
{
|
|
3626
3705
|
input: {
|
|
3627
3706
|
projectId: projectIdValue,
|
|
3707
|
+
principalId: input.principalId,
|
|
3628
3708
|
eventName,
|
|
3629
3709
|
payloadJson: JSON.stringify(input.payload ?? {}),
|
|
3630
3710
|
metadataJson: JSON.stringify(input.metadata ?? {}),
|
|
@@ -3701,6 +3781,10 @@ function createClient(config) {
|
|
|
3701
3781
|
organizations,
|
|
3702
3782
|
projects: projects2,
|
|
3703
3783
|
createProject,
|
|
3784
|
+
principals: principals2,
|
|
3785
|
+
createPrincipal,
|
|
3786
|
+
updatePrincipal,
|
|
3787
|
+
deletePrincipal,
|
|
3704
3788
|
listSecrets,
|
|
3705
3789
|
putSecret,
|
|
3706
3790
|
deleteSecret,
|
|
@@ -3719,7 +3803,7 @@ async function deployCommand(options) {
|
|
|
3719
3803
|
const config = await loadConfig({
|
|
3720
3804
|
dir: options.dir
|
|
3721
3805
|
});
|
|
3722
|
-
console.log(
|
|
3806
|
+
console.log(chalk12.gray("Planning deployment..."));
|
|
3723
3807
|
stagingDir = await createStagingDir();
|
|
3724
3808
|
const { manifest } = await buildPipeline(
|
|
3725
3809
|
config,
|
|
@@ -3729,7 +3813,7 @@ async function deployCommand(options) {
|
|
|
3729
3813
|
);
|
|
3730
3814
|
if (!config.apiUrl || !config.projectId) {
|
|
3731
3815
|
console.log(
|
|
3732
|
-
|
|
3816
|
+
chalk12.yellow(
|
|
3733
3817
|
"\nNo apiUrl or projectId configured. Skipping upload."
|
|
3734
3818
|
)
|
|
3735
3819
|
);
|
|
@@ -3739,30 +3823,30 @@ async function deployCommand(options) {
|
|
|
3739
3823
|
apiUrl: config.apiUrl,
|
|
3740
3824
|
projectId: config.projectId
|
|
3741
3825
|
});
|
|
3742
|
-
console.log(
|
|
3826
|
+
console.log(chalk12.gray("\nComparing with remote..."));
|
|
3743
3827
|
const remoteManifest = await client.fetchRemoteManifest(client.projectId());
|
|
3744
3828
|
const diff = diffManifests(manifest, remoteManifest);
|
|
3745
3829
|
if (!diff.hasChanges) {
|
|
3746
|
-
console.log(
|
|
3830
|
+
console.log(chalk12.green("\n\u2713 No changes to deploy."));
|
|
3747
3831
|
return;
|
|
3748
3832
|
}
|
|
3749
3833
|
console.log("\n" + formatPlan(diff));
|
|
3750
3834
|
const confirmed = await confirmPlan(options.yes ?? false);
|
|
3751
3835
|
if (!confirmed) {
|
|
3752
|
-
console.log(
|
|
3836
|
+
console.log(chalk12.yellow("Deploy cancelled."));
|
|
3753
3837
|
return;
|
|
3754
3838
|
}
|
|
3755
|
-
console.log(
|
|
3839
|
+
console.log(chalk12.gray("\nApplying deployment..."));
|
|
3756
3840
|
const zipPath = join(stagingDir, "deploy.zip");
|
|
3757
3841
|
await zipBuildOutput(stagingDir, zipPath);
|
|
3758
3842
|
const revision = await client.deployBundle(zipPath, manifest);
|
|
3759
3843
|
console.log(
|
|
3760
|
-
|
|
3844
|
+
chalk12.green(`
|
|
3761
3845
|
\u2713 Deployment complete (revision ${revision.revision}, ${revision.status})`)
|
|
3762
3846
|
);
|
|
3763
3847
|
} catch (err) {
|
|
3764
3848
|
if (err instanceof CliError) {
|
|
3765
|
-
console.error(
|
|
3849
|
+
console.error(chalk12.red(err.message));
|
|
3766
3850
|
process.exit(1);
|
|
3767
3851
|
}
|
|
3768
3852
|
throw err;
|
|
@@ -3873,7 +3957,7 @@ async function loginCommand(options) {
|
|
|
3873
3957
|
try {
|
|
3874
3958
|
if (options.token) {
|
|
3875
3959
|
await saveToken(options.token, true);
|
|
3876
|
-
console.log(
|
|
3960
|
+
console.log(chalk12.green("\u2713 API key saved"));
|
|
3877
3961
|
return;
|
|
3878
3962
|
}
|
|
3879
3963
|
const config = await loadConfig();
|
|
@@ -3884,7 +3968,7 @@ async function loginCommand(options) {
|
|
|
3884
3968
|
}
|
|
3885
3969
|
const existing = await loadToken();
|
|
3886
3970
|
if (existing) {
|
|
3887
|
-
console.log(
|
|
3971
|
+
console.log(chalk12.gray("Existing session found. Re-authenticating..."));
|
|
3888
3972
|
}
|
|
3889
3973
|
const callbackServer = await startCallbackServer();
|
|
3890
3974
|
const pkce = generatePkcePair();
|
|
@@ -3894,12 +3978,12 @@ async function loginCommand(options) {
|
|
|
3894
3978
|
callbackServer.state,
|
|
3895
3979
|
pkce.challenge
|
|
3896
3980
|
);
|
|
3897
|
-
console.log(
|
|
3981
|
+
console.log(chalk12.gray("Opening your browser for sign-in..."));
|
|
3898
3982
|
try {
|
|
3899
3983
|
await open(authorizationUrl);
|
|
3900
3984
|
} catch {
|
|
3901
|
-
console.log(
|
|
3902
|
-
console.log(
|
|
3985
|
+
console.log(chalk12.yellow("Could not open the browser automatically."));
|
|
3986
|
+
console.log(chalk12.gray(`Open this URL manually:
|
|
3903
3987
|
${authorizationUrl}`));
|
|
3904
3988
|
}
|
|
3905
3989
|
try {
|
|
@@ -3923,10 +4007,10 @@ ${authorizationUrl}`));
|
|
|
3923
4007
|
} finally {
|
|
3924
4008
|
callbackServer.close();
|
|
3925
4009
|
}
|
|
3926
|
-
console.log(
|
|
4010
|
+
console.log(chalk12.green("\n\u2713 Authenticated successfully"));
|
|
3927
4011
|
} catch (err) {
|
|
3928
4012
|
if (err instanceof CliError) {
|
|
3929
|
-
console.error(
|
|
4013
|
+
console.error(chalk12.red(err.message));
|
|
3930
4014
|
process.exit(1);
|
|
3931
4015
|
}
|
|
3932
4016
|
throw err;
|
|
@@ -3936,10 +4020,10 @@ async function logoutCommand() {
|
|
|
3936
4020
|
const creds = await loadCredentials();
|
|
3937
4021
|
await clearToken();
|
|
3938
4022
|
if (!creds) {
|
|
3939
|
-
console.log(
|
|
4023
|
+
console.log(chalk12.yellow("Not logged in."));
|
|
3940
4024
|
return;
|
|
3941
4025
|
}
|
|
3942
|
-
console.log(
|
|
4026
|
+
console.log(chalk12.green("\u2713 Logged out"));
|
|
3943
4027
|
}
|
|
3944
4028
|
async function hydrateIdentity() {
|
|
3945
4029
|
const creds = await loadCredentials();
|
|
@@ -3983,26 +4067,26 @@ async function hydrateIdentity() {
|
|
|
3983
4067
|
async function whoamiCommand() {
|
|
3984
4068
|
const { creds, sessionName, sessionEmail } = await hydrateIdentity();
|
|
3985
4069
|
if (!creds) {
|
|
3986
|
-
console.log(
|
|
4070
|
+
console.log(chalk12.yellow("Not logged in. Run `io login` to authenticate."));
|
|
3987
4071
|
return;
|
|
3988
4072
|
}
|
|
3989
|
-
console.log(
|
|
4073
|
+
console.log(chalk12.green("\u2713 Logged in"));
|
|
3990
4074
|
const displayUser = sessionName ?? sessionEmail ?? creds.userId;
|
|
3991
4075
|
if (displayUser) {
|
|
3992
|
-
console.log(
|
|
4076
|
+
console.log(chalk12.gray(` User: ${displayUser}`));
|
|
3993
4077
|
}
|
|
3994
4078
|
if (sessionEmail && sessionEmail !== displayUser) {
|
|
3995
|
-
console.log(
|
|
4079
|
+
console.log(chalk12.gray(` Email: ${sessionEmail}`));
|
|
3996
4080
|
}
|
|
3997
4081
|
if (creds.organizationId) {
|
|
3998
|
-
console.log(
|
|
4082
|
+
console.log(chalk12.gray(` Organization: ${creds.organizationId}`));
|
|
3999
4083
|
}
|
|
4000
4084
|
if (creds.apiKey) {
|
|
4001
|
-
console.log(
|
|
4085
|
+
console.log(chalk12.gray(" Session: API key"));
|
|
4002
4086
|
} else if (creds.refreshToken) {
|
|
4003
|
-
console.log(
|
|
4087
|
+
console.log(chalk12.gray(" Session: refresh token stored"));
|
|
4004
4088
|
} else {
|
|
4005
|
-
console.log(
|
|
4089
|
+
console.log(chalk12.gray(" Session: token only (no refresh)"));
|
|
4006
4090
|
}
|
|
4007
4091
|
}
|
|
4008
4092
|
var CONFIG_FILE = "io.config.json";
|
|
@@ -4032,13 +4116,13 @@ async function selectOrganization(organizations, preferredId) {
|
|
|
4032
4116
|
if (organizations.length === 1) {
|
|
4033
4117
|
return organizations[0];
|
|
4034
4118
|
}
|
|
4035
|
-
console.log(
|
|
4119
|
+
console.log(chalk12.gray("\nAvailable organizations:"));
|
|
4036
4120
|
organizations.forEach((organization, index2) => {
|
|
4037
4121
|
console.log(
|
|
4038
|
-
` ${
|
|
4122
|
+
` ${chalk12.green(String(index2 + 1))}. ${organization.name} ${chalk12.gray(organization.id)}`
|
|
4039
4123
|
);
|
|
4040
4124
|
});
|
|
4041
|
-
const choice = await prompt(
|
|
4125
|
+
const choice = await prompt(chalk12.gray("\nSelect an organization (number or ID): "));
|
|
4042
4126
|
const index = Number(choice);
|
|
4043
4127
|
if (index > 0 && index <= organizations.length) {
|
|
4044
4128
|
return organizations[index - 1];
|
|
@@ -4051,16 +4135,16 @@ async function initCommand(options) {
|
|
|
4051
4135
|
const existing = await readExistingConfig(cwd);
|
|
4052
4136
|
if (existing.projectId && !options.yes) {
|
|
4053
4137
|
const overwrite = await prompt(
|
|
4054
|
-
|
|
4138
|
+
chalk12.yellow(`io.config.json already has projectId "${existing.projectId}". Overwrite? (y/n) `)
|
|
4055
4139
|
);
|
|
4056
4140
|
if (overwrite.toLowerCase() !== "y") {
|
|
4057
|
-
console.log(
|
|
4141
|
+
console.log(chalk12.gray("Cancelled."));
|
|
4058
4142
|
return;
|
|
4059
4143
|
}
|
|
4060
4144
|
}
|
|
4061
4145
|
const config = { ...existing };
|
|
4062
4146
|
if (!config.apiUrl) {
|
|
4063
|
-
const apiUrl = await prompt(
|
|
4147
|
+
const apiUrl = await prompt(chalk12.gray("API URL (leave blank for default): "));
|
|
4064
4148
|
if (apiUrl) {
|
|
4065
4149
|
config.apiUrl = apiUrl;
|
|
4066
4150
|
}
|
|
@@ -4082,7 +4166,7 @@ async function initCommand(options) {
|
|
|
4082
4166
|
try {
|
|
4083
4167
|
organizations = await client.organizations();
|
|
4084
4168
|
} catch {
|
|
4085
|
-
console.log(
|
|
4169
|
+
console.log(chalk12.yellow("Could not fetch organizations. Enter project ID manually."));
|
|
4086
4170
|
}
|
|
4087
4171
|
const selectedOrganization = await selectOrganization(
|
|
4088
4172
|
organizations,
|
|
@@ -4091,14 +4175,14 @@ async function initCommand(options) {
|
|
|
4091
4175
|
if (selectedOrganization) {
|
|
4092
4176
|
const projects2 = await client.projects(selectedOrganization.id);
|
|
4093
4177
|
if (projects2.length > 0) {
|
|
4094
|
-
console.log(
|
|
4178
|
+
console.log(chalk12.gray("\nAvailable projects:"));
|
|
4095
4179
|
projects2.forEach((project, index2) => {
|
|
4096
4180
|
console.log(
|
|
4097
|
-
` ${
|
|
4181
|
+
` ${chalk12.green(String(index2 + 1))}. ${project.name} ${chalk12.gray(project.id)}`
|
|
4098
4182
|
);
|
|
4099
4183
|
});
|
|
4100
4184
|
const choice = await prompt(
|
|
4101
|
-
|
|
4185
|
+
chalk12.gray("\nSelect a project (number) or enter a project ID: ")
|
|
4102
4186
|
);
|
|
4103
4187
|
const index = Number(choice);
|
|
4104
4188
|
if (index > 0 && index <= projects2.length) {
|
|
@@ -4108,26 +4192,26 @@ async function initCommand(options) {
|
|
|
4108
4192
|
}
|
|
4109
4193
|
} else {
|
|
4110
4194
|
const createNew = await prompt(
|
|
4111
|
-
|
|
4195
|
+
chalk12.gray("No projects found. Create one? (y/n) ")
|
|
4112
4196
|
);
|
|
4113
4197
|
if (createNew.toLowerCase() === "y") {
|
|
4114
|
-
const name = await prompt(
|
|
4198
|
+
const name = await prompt(chalk12.gray("Project name: "));
|
|
4115
4199
|
if (name) {
|
|
4116
4200
|
const project = await client.createProject(selectedOrganization.id, name);
|
|
4117
4201
|
config.projectId = project.id;
|
|
4118
|
-
console.log(
|
|
4202
|
+
console.log(chalk12.green(`\u2713 Created project: ${project.name}`));
|
|
4119
4203
|
}
|
|
4120
4204
|
}
|
|
4121
4205
|
}
|
|
4122
4206
|
} else {
|
|
4123
|
-
const projectId = await prompt(
|
|
4207
|
+
const projectId = await prompt(chalk12.gray("Project ID (or leave blank): "));
|
|
4124
4208
|
if (projectId) {
|
|
4125
4209
|
config.projectId = projectId;
|
|
4126
4210
|
}
|
|
4127
4211
|
}
|
|
4128
4212
|
} else {
|
|
4129
|
-
console.log(
|
|
4130
|
-
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): "));
|
|
4131
4215
|
if (projectId) {
|
|
4132
4216
|
config.projectId = projectId;
|
|
4133
4217
|
}
|
|
@@ -4137,14 +4221,14 @@ async function initCommand(options) {
|
|
|
4137
4221
|
JSON.stringify(config, null, 2) + "\n",
|
|
4138
4222
|
"utf-8"
|
|
4139
4223
|
);
|
|
4140
|
-
console.log(
|
|
4224
|
+
console.log(chalk12.green(`
|
|
4141
4225
|
\u2713 Wrote ${CONFIG_FILE}`));
|
|
4142
4226
|
if (config.projectId) {
|
|
4143
|
-
console.log(
|
|
4227
|
+
console.log(chalk12.gray(` Project: ${config.projectId}`));
|
|
4144
4228
|
}
|
|
4145
4229
|
} catch (err) {
|
|
4146
4230
|
if (err instanceof CliError) {
|
|
4147
|
-
console.error(
|
|
4231
|
+
console.error(chalk12.red(err.message));
|
|
4148
4232
|
process.exit(1);
|
|
4149
4233
|
}
|
|
4150
4234
|
throw err;
|
|
@@ -4172,16 +4256,16 @@ async function projectsListCommand() {
|
|
|
4172
4256
|
const organizationId = await resolveOrganizationId(client);
|
|
4173
4257
|
const projects2 = await client.projects(organizationId);
|
|
4174
4258
|
if (!projects2 || projects2.length === 0) {
|
|
4175
|
-
console.log(
|
|
4259
|
+
console.log(chalk12.gray("No projects found. Create one with `io projects create <name>`."));
|
|
4176
4260
|
return;
|
|
4177
4261
|
}
|
|
4178
4262
|
for (const p of projects2) {
|
|
4179
|
-
const current = p.id === config.projectId ?
|
|
4180
|
-
console.log(` ${p.name} ${
|
|
4263
|
+
const current = p.id === config.projectId ? chalk12.green(" (current)") : "";
|
|
4264
|
+
console.log(` ${p.name} ${chalk12.gray(p.id)}${current}`);
|
|
4181
4265
|
}
|
|
4182
4266
|
} catch (err) {
|
|
4183
4267
|
if (err instanceof CliError) {
|
|
4184
|
-
console.error(
|
|
4268
|
+
console.error(chalk12.red(err.message));
|
|
4185
4269
|
process.exit(1);
|
|
4186
4270
|
}
|
|
4187
4271
|
throw err;
|
|
@@ -4193,10 +4277,10 @@ async function projectsCreateCommand(name) {
|
|
|
4193
4277
|
const client = createClient(config);
|
|
4194
4278
|
const organizationId = await resolveOrganizationId(client);
|
|
4195
4279
|
const project = await client.createProject(organizationId, name);
|
|
4196
|
-
console.log(
|
|
4197
|
-
console.log(
|
|
4280
|
+
console.log(chalk12.green(`\u2713 Created project: ${project.name}`));
|
|
4281
|
+
console.log(chalk12.gray(` ID: ${project.id}`));
|
|
4198
4282
|
console.log(
|
|
4199
|
-
|
|
4283
|
+
chalk12.gray(
|
|
4200
4284
|
`
|
|
4201
4285
|
Add to io.config.json:
|
|
4202
4286
|
{ "projectId": "${project.id}" }`
|
|
@@ -4204,7 +4288,7 @@ async function projectsCreateCommand(name) {
|
|
|
4204
4288
|
);
|
|
4205
4289
|
} catch (err) {
|
|
4206
4290
|
if (err instanceof CliError) {
|
|
4207
|
-
console.error(
|
|
4291
|
+
console.error(chalk12.red(err.message));
|
|
4208
4292
|
process.exit(1);
|
|
4209
4293
|
}
|
|
4210
4294
|
throw err;
|
|
@@ -4216,10 +4300,10 @@ async function secretsSetCommand(name, value) {
|
|
|
4216
4300
|
const client = createClient(config);
|
|
4217
4301
|
const pid = client.projectId();
|
|
4218
4302
|
await client.putSecret(pid, { name, value });
|
|
4219
|
-
console.log(
|
|
4303
|
+
console.log(chalk12.green(`\u2713 Set secret: ${name}`));
|
|
4220
4304
|
} catch (err) {
|
|
4221
4305
|
if (err instanceof CliError) {
|
|
4222
|
-
console.error(
|
|
4306
|
+
console.error(chalk12.red(err.message));
|
|
4223
4307
|
process.exit(1);
|
|
4224
4308
|
}
|
|
4225
4309
|
throw err;
|
|
@@ -4231,16 +4315,16 @@ async function secretsListCommand() {
|
|
|
4231
4315
|
const client = createClient(config);
|
|
4232
4316
|
const secrets2 = await client.listSecrets(client.projectId());
|
|
4233
4317
|
if (!secrets2 || secrets2.length === 0) {
|
|
4234
|
-
console.log(
|
|
4318
|
+
console.log(chalk12.gray("No secrets configured."));
|
|
4235
4319
|
return;
|
|
4236
4320
|
}
|
|
4237
4321
|
for (const s of secrets2) {
|
|
4238
|
-
const value = s.hasValue ? "" :
|
|
4322
|
+
const value = s.hasValue ? "" : chalk12.gray(" (no value)");
|
|
4239
4323
|
console.log(` ${s.name}${value}`);
|
|
4240
4324
|
}
|
|
4241
4325
|
} catch (err) {
|
|
4242
4326
|
if (err instanceof CliError) {
|
|
4243
|
-
console.error(
|
|
4327
|
+
console.error(chalk12.red(err.message));
|
|
4244
4328
|
process.exit(1);
|
|
4245
4329
|
}
|
|
4246
4330
|
throw err;
|
|
@@ -4252,25 +4336,123 @@ async function secretsRemoveCommand(name) {
|
|
|
4252
4336
|
const client = createClient(config);
|
|
4253
4337
|
const removed = await client.deleteSecret(client.projectId(), name);
|
|
4254
4338
|
if (!removed) {
|
|
4255
|
-
console.log(
|
|
4339
|
+
console.log(chalk12.yellow(`Secret "${name}" not found.`));
|
|
4256
4340
|
return;
|
|
4257
4341
|
}
|
|
4258
|
-
console.log(
|
|
4342
|
+
console.log(chalk12.green(`\u2713 Removed secret: ${name}`));
|
|
4259
4343
|
} catch (err) {
|
|
4260
4344
|
if (err instanceof CliError) {
|
|
4261
|
-
console.error(
|
|
4345
|
+
console.error(chalk12.red(err.message));
|
|
4262
4346
|
process.exit(1);
|
|
4263
4347
|
}
|
|
4264
4348
|
throw err;
|
|
4265
4349
|
}
|
|
4266
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
|
+
}
|
|
4267
4449
|
function meterBar(used, limit, width = 20) {
|
|
4268
|
-
if (limit === 0) return
|
|
4450
|
+
if (limit === 0) return chalk12.gray("\u2591".repeat(width));
|
|
4269
4451
|
const ratio = Math.min(used / limit, 1);
|
|
4270
4452
|
const filled = Math.round(ratio * width);
|
|
4271
4453
|
const empty = width - filled;
|
|
4272
|
-
const color = ratio >= 0.9 ?
|
|
4273
|
-
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));
|
|
4274
4456
|
}
|
|
4275
4457
|
function formatNumber(n) {
|
|
4276
4458
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
@@ -4280,9 +4462,11 @@ function formatNumber(n) {
|
|
|
4280
4462
|
var METER_LABELS = {
|
|
4281
4463
|
events: "Events",
|
|
4282
4464
|
ingest_tokens: "Ingest Tokens",
|
|
4465
|
+
query_tokens: "Query Tokens",
|
|
4283
4466
|
voice_seconds: "Voice Seconds",
|
|
4284
4467
|
compute_gb_sec: "Compute (GB\xB7s)",
|
|
4285
|
-
storage_gb: "Storage (GB)"
|
|
4468
|
+
storage_gb: "Memory Storage (GB)",
|
|
4469
|
+
artifact_storage_gb: "Artifact Storage (GB)"
|
|
4286
4470
|
};
|
|
4287
4471
|
async function quotaCommand() {
|
|
4288
4472
|
try {
|
|
@@ -4290,22 +4474,22 @@ async function quotaCommand() {
|
|
|
4290
4474
|
const client = createClient(config);
|
|
4291
4475
|
const statuses = await client.quotaStatuses();
|
|
4292
4476
|
if (statuses.length === 0) {
|
|
4293
|
-
console.log(
|
|
4477
|
+
console.log(chalk12.gray("No quota data available."));
|
|
4294
4478
|
return;
|
|
4295
4479
|
}
|
|
4296
|
-
console.log(
|
|
4480
|
+
console.log(chalk12.bold("\nQuota Usage\n"));
|
|
4297
4481
|
for (const status of statuses) {
|
|
4298
4482
|
const label = METER_LABELS[status.meter] ?? status.meter;
|
|
4299
4483
|
const bar = meterBar(status.used, status.limit);
|
|
4300
4484
|
const pct = status.limit > 0 ? `${status.percentageUsed.toFixed(1)}%` : "\u2014";
|
|
4301
4485
|
const usage = `${formatNumber(status.used)} / ${formatNumber(status.limit)}`;
|
|
4302
|
-
const enforcement = status.enforcement === "hard_cap" ?
|
|
4303
|
-
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}`);
|
|
4304
4488
|
}
|
|
4305
4489
|
console.log();
|
|
4306
4490
|
} catch (err) {
|
|
4307
4491
|
if (err instanceof CliError) {
|
|
4308
|
-
console.error(
|
|
4492
|
+
console.error(chalk12.red(err.message));
|
|
4309
4493
|
process.exit(1);
|
|
4310
4494
|
}
|
|
4311
4495
|
throw err;
|
|
@@ -4701,18 +4885,18 @@ function inferActivityPrincipalLabel(event) {
|
|
|
4701
4885
|
|
|
4702
4886
|
// src/commands/logs.ts
|
|
4703
4887
|
var LEVEL_COLORS = {
|
|
4704
|
-
error:
|
|
4705
|
-
warning:
|
|
4706
|
-
info:
|
|
4707
|
-
success:
|
|
4708
|
-
scheduled:
|
|
4888
|
+
error: chalk12.red,
|
|
4889
|
+
warning: chalk12.yellow,
|
|
4890
|
+
info: chalk12.blue,
|
|
4891
|
+
success: chalk12.green,
|
|
4892
|
+
scheduled: chalk12.magenta
|
|
4709
4893
|
};
|
|
4710
4894
|
var FOLLOW_POLL_INTERVAL_MS = 2e3;
|
|
4711
4895
|
var FOLLOW_SEEN_ID_LIMIT = 1e3;
|
|
4712
4896
|
var FOLLOW_BATCH_LIMIT = 200;
|
|
4713
4897
|
function colorLevel(level) {
|
|
4714
|
-
if (!level) return
|
|
4715
|
-
const colorFn = LEVEL_COLORS[level] ??
|
|
4898
|
+
if (!level) return chalk12.gray("\u2014");
|
|
4899
|
+
const colorFn = LEVEL_COLORS[level] ?? chalk12.gray;
|
|
4716
4900
|
return colorFn(level.padEnd(7));
|
|
4717
4901
|
}
|
|
4718
4902
|
function pad(value, width) {
|
|
@@ -4725,8 +4909,8 @@ function formatTime(isoString) {
|
|
|
4725
4909
|
}
|
|
4726
4910
|
function formatDuration(ms) {
|
|
4727
4911
|
if (ms == null) return "";
|
|
4728
|
-
if (ms < 1e3) return
|
|
4729
|
-
return
|
|
4912
|
+
if (ms < 1e3) return chalk12.gray(`${ms}ms`);
|
|
4913
|
+
return chalk12.gray(`${(ms / 1e3).toFixed(1)}s`);
|
|
4730
4914
|
}
|
|
4731
4915
|
function truncate(value, width) {
|
|
4732
4916
|
if (value.length <= width) return value;
|
|
@@ -4734,19 +4918,19 @@ function truncate(value, width) {
|
|
|
4734
4918
|
}
|
|
4735
4919
|
function formatHeader() {
|
|
4736
4920
|
return [
|
|
4737
|
-
` ${
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
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")
|
|
4743
4927
|
].join(" ");
|
|
4744
4928
|
}
|
|
4745
4929
|
function formatEvent(event) {
|
|
4746
|
-
const time =
|
|
4930
|
+
const time = chalk12.gray(formatTime(event.occurredAt));
|
|
4747
4931
|
const statusKey = inferActivityEventStatus(event);
|
|
4748
4932
|
const status = colorLevel(statusKey);
|
|
4749
|
-
const category =
|
|
4933
|
+
const category = chalk12.cyan(pad(inferActivityEventCategory(event), 14));
|
|
4750
4934
|
const name = pad(truncate(inferActivityEventName(event), 24), 24);
|
|
4751
4935
|
const duration = formatDuration(event.durationMs);
|
|
4752
4936
|
const detail = inferActivityEventDetail(event) || inferActivityPrincipalLabel(event) || "";
|
|
@@ -4756,7 +4940,7 @@ function formatEvent(event) {
|
|
|
4756
4940
|
category,
|
|
4757
4941
|
name,
|
|
4758
4942
|
pad(duration || "", 10),
|
|
4759
|
-
detail ?
|
|
4943
|
+
detail ? chalk12.gray(detail) : ""
|
|
4760
4944
|
].join(" ").trimEnd();
|
|
4761
4945
|
}
|
|
4762
4946
|
function latestOccurredAt(events, fallback) {
|
|
@@ -4818,7 +5002,7 @@ async function drainFollowEvents(client, projectId, input, since, seenIds, seenO
|
|
|
4818
5002
|
}
|
|
4819
5003
|
function installSigintHandler(onExit) {
|
|
4820
5004
|
const handleSigint = () => {
|
|
4821
|
-
console.log(
|
|
5005
|
+
console.log(chalk12.gray("\n Disconnected."));
|
|
4822
5006
|
onExit();
|
|
4823
5007
|
process.exit(0);
|
|
4824
5008
|
};
|
|
@@ -4844,15 +5028,15 @@ async function logsCommand(options) {
|
|
|
4844
5028
|
}
|
|
4845
5029
|
const events = await client.projectEvents(pid, input);
|
|
4846
5030
|
if (events.length === 0 && !options.follow) {
|
|
4847
|
-
console.log(
|
|
5031
|
+
console.log(chalk12.gray("No events found."));
|
|
4848
5032
|
return;
|
|
4849
5033
|
}
|
|
4850
5034
|
if (events.length > 0) {
|
|
4851
|
-
console.log(
|
|
5035
|
+
console.log(chalk12.bold(`
|
|
4852
5036
|
Activity Log \u2014 ${events.length} events
|
|
4853
5037
|
`));
|
|
4854
5038
|
console.log(formatHeader());
|
|
4855
|
-
console.log(
|
|
5039
|
+
console.log(chalk12.gray(` ${"\u2500".repeat(92)}`));
|
|
4856
5040
|
for (const event of events) {
|
|
4857
5041
|
console.log(formatEvent(event));
|
|
4858
5042
|
}
|
|
@@ -4871,7 +5055,7 @@ Activity Log \u2014 ${events.length} events
|
|
|
4871
5055
|
}
|
|
4872
5056
|
} catch (err) {
|
|
4873
5057
|
if (err instanceof CliError) {
|
|
4874
|
-
console.error(
|
|
5058
|
+
console.error(chalk12.red(err.message));
|
|
4875
5059
|
process.exit(1);
|
|
4876
5060
|
}
|
|
4877
5061
|
throw err;
|
|
@@ -4882,7 +5066,7 @@ async function tailEvents(apiUrl, client, projectId, input, initialEvents, follo
|
|
|
4882
5066
|
if (!creds || !creds.token) {
|
|
4883
5067
|
throw new ConfigError("Not authenticated. Run `io login` first.");
|
|
4884
5068
|
}
|
|
4885
|
-
console.log(
|
|
5069
|
+
console.log(chalk12.gray("\n Waiting for events... (Ctrl+C to stop)\n"));
|
|
4886
5070
|
if (creds.apiKey) {
|
|
4887
5071
|
return new Promise((_resolve, reject) => {
|
|
4888
5072
|
let disconnect;
|
|
@@ -4906,7 +5090,7 @@ async function tailEvents(apiUrl, client, projectId, input, initialEvents, follo
|
|
|
4906
5090
|
trimSeenIds(seenIds2, seenOrder2);
|
|
4907
5091
|
},
|
|
4908
5092
|
onConnected: () => {
|
|
4909
|
-
console.log(
|
|
5093
|
+
console.log(chalk12.green(" \u25CF Connected \u2014 tailing live events\n"));
|
|
4910
5094
|
void drainFollowEvents(
|
|
4911
5095
|
client,
|
|
4912
5096
|
projectId,
|
|
@@ -4919,7 +5103,7 @@ async function tailEvents(apiUrl, client, projectId, input, initialEvents, follo
|
|
|
4919
5103
|
console.log(formatEvent(event));
|
|
4920
5104
|
}
|
|
4921
5105
|
}).catch((error) => {
|
|
4922
|
-
console.error(
|
|
5106
|
+
console.error(chalk12.red(`
|
|
4923
5107
|
Connection error: ${error.message}`));
|
|
4924
5108
|
removeSigintHandler2();
|
|
4925
5109
|
disconnect?.();
|
|
@@ -4927,7 +5111,7 @@ async function tailEvents(apiUrl, client, projectId, input, initialEvents, follo
|
|
|
4927
5111
|
});
|
|
4928
5112
|
},
|
|
4929
5113
|
onError: (error) => {
|
|
4930
|
-
console.error(
|
|
5114
|
+
console.error(chalk12.red(`
|
|
4931
5115
|
Connection error: ${error.message}`));
|
|
4932
5116
|
removeSigintHandler2();
|
|
4933
5117
|
disconnect?.();
|
|
@@ -4937,7 +5121,7 @@ async function tailEvents(apiUrl, client, projectId, input, initialEvents, follo
|
|
|
4937
5121
|
});
|
|
4938
5122
|
}
|
|
4939
5123
|
console.log(
|
|
4940
|
-
|
|
5124
|
+
chalk12.green(" \u25CF Connected \u2014 polling for live events with your authenticated session\n")
|
|
4941
5125
|
);
|
|
4942
5126
|
const seenIds = new Set(initialEvents.map((event) => event.id));
|
|
4943
5127
|
const seenOrder = initialEvents.map((event) => event.id);
|
|
@@ -5003,10 +5187,14 @@ async function signalEmitCommand(name, options) {
|
|
|
5003
5187
|
"signal name must be a bare event name like smoke.start or use the signal: namespace"
|
|
5004
5188
|
);
|
|
5005
5189
|
}
|
|
5190
|
+
if (!options.principalId || options.principalId.trim() === "") {
|
|
5191
|
+
throw new ConfigError("signals emit requires --principal-id <id>");
|
|
5192
|
+
}
|
|
5006
5193
|
const payload = parseJsonObject(options.payload, "payload");
|
|
5007
5194
|
const metadata = parseJsonObject(options.metadata, "metadata");
|
|
5008
5195
|
const event = await client.emitSignal({
|
|
5009
5196
|
signal,
|
|
5197
|
+
principalId: options.principalId,
|
|
5010
5198
|
payload,
|
|
5011
5199
|
metadata,
|
|
5012
5200
|
correlationId: options.correlationId,
|
|
@@ -5018,18 +5206,18 @@ async function signalEmitCommand(name, options) {
|
|
|
5018
5206
|
console.log(JSON.stringify(event, null, 2));
|
|
5019
5207
|
return;
|
|
5020
5208
|
}
|
|
5021
|
-
console.log(
|
|
5022
|
-
console.log(
|
|
5023
|
-
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}`));
|
|
5024
5212
|
if (event.dispatchStatus) {
|
|
5025
|
-
console.log(
|
|
5213
|
+
console.log(chalk12.gray(` Dispatch: ${event.dispatchStatus}`));
|
|
5026
5214
|
}
|
|
5027
5215
|
if (event.occurredAt) {
|
|
5028
|
-
console.log(
|
|
5216
|
+
console.log(chalk12.gray(` At: ${event.occurredAt}`));
|
|
5029
5217
|
}
|
|
5030
5218
|
} catch (err) {
|
|
5031
5219
|
if (err instanceof CliError) {
|
|
5032
|
-
console.error(
|
|
5220
|
+
console.error(chalk12.red(err.message));
|
|
5033
5221
|
process.exit(1);
|
|
5034
5222
|
}
|
|
5035
5223
|
throw err;
|
|
@@ -5038,7 +5226,7 @@ async function signalEmitCommand(name, options) {
|
|
|
5038
5226
|
|
|
5039
5227
|
// src/index.ts
|
|
5040
5228
|
var program = new Command();
|
|
5041
|
-
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");
|
|
5042
5230
|
program.command("init").description("Initialize io.config.json for the current project").option("--yes", "Overwrite existing config without prompting").action(initCommand);
|
|
5043
5231
|
program.command("build").description("Build behaviors from the io/ directory").option("--dir <path>", "Source directory", "io").option("--minify", "Minify bundles", false).action(buildCommand);
|
|
5044
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);
|
|
@@ -5052,8 +5240,13 @@ var secrets = program.command("secrets").description("Manage project secrets");
|
|
|
5052
5240
|
secrets.command("set <name> <value>").description("Set a secret value").option("--target <targets...>", "Restrict to specific targets").action(secretsSetCommand);
|
|
5053
5241
|
secrets.command("list").description("List all secrets").action(secretsListCommand);
|
|
5054
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);
|
|
5055
5248
|
var signals = program.command("signals").description("Emit runtime signals");
|
|
5056
|
-
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);
|
|
5057
5250
|
program.command("quota").description("Show current quota usage for the active organization").action(quotaCommand);
|
|
5058
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);
|
|
5059
5252
|
program.parse();
|