@1medium/cli 1.9.2 → 1.11.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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/src/api.js +28 -0
  3. package/src/index.js +180 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1medium/cli",
3
- "version": "1.9.2",
3
+ "version": "1.11.0",
4
4
  "description": "CLI and MCP server for 1Medium AI task management",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/api.js CHANGED
@@ -293,6 +293,31 @@ async function resumeScriptEvent(id) {
293
293
  return request("POST", `/script-events/${id}/resume`);
294
294
  }
295
295
 
296
+ // ============================================================================
297
+ // Script Secret API
298
+ // ============================================================================
299
+
300
+ /**
301
+ * List script secrets (keys only, no values)
302
+ */
303
+ async function listSecrets() {
304
+ return request("GET", "/script-secrets");
305
+ }
306
+
307
+ /**
308
+ * Create or upsert a script secret
309
+ */
310
+ async function createSecret(key, value) {
311
+ return request("POST", "/script-secrets", { key, value });
312
+ }
313
+
314
+ /**
315
+ * Delete a script secret by ID
316
+ */
317
+ async function deleteSecret(id) {
318
+ return request("DELETE", `/script-secrets/${id}`);
319
+ }
320
+
296
321
  module.exports = {
297
322
  whoami,
298
323
  createTask,
@@ -322,4 +347,7 @@ module.exports = {
322
347
  deleteScriptEvent,
323
348
  pauseScriptEvent,
324
349
  resumeScriptEvent,
350
+ listSecrets,
351
+ createSecret,
352
+ deleteSecret,
325
353
  };
package/src/index.js CHANGED
@@ -927,6 +927,14 @@ scriptCmd
927
927
  if (event.Script) {
928
928
  console.log(chalk.gray(` Script: ${event.Script.name} (${event.Script.id})`));
929
929
  }
930
+ if (event.lastRunAt) {
931
+ const runColor = event.lastRunStatus === "success" ? chalk.green : chalk.red;
932
+ const duration = event.lastRunDurationMs != null ? ` (${event.lastRunDurationMs}ms)` : "";
933
+ console.log(` Last run: ${runColor(event.lastRunStatus)}${duration} at ${event.lastRunAt}`);
934
+ if (event.lastRunStatus === "failure" && event.lastRunError) {
935
+ console.log(chalk.red(` Error: ${event.lastRunError}`));
936
+ }
937
+ }
930
938
  }
931
939
  }
932
940
  console.log("");
@@ -975,6 +983,178 @@ scriptCmd
975
983
  }
976
984
  });
977
985
 
986
+ scriptCmd
987
+ .command("logs <event-id>")
988
+ .description("View execution logs for a script event")
989
+ .option("-j, --json", "Output as JSON")
990
+ .action(async (eventId, options) => {
991
+ try {
992
+ const data = await api.getScriptEvent(eventId);
993
+ const event = data.scriptEvent || data;
994
+
995
+ if (options.json) {
996
+ console.log(JSON.stringify({
997
+ id: event.id,
998
+ title: event.title,
999
+ status: event.status,
1000
+ lastRunAt: event.lastRunAt,
1001
+ lastRunStatus: event.lastRunStatus,
1002
+ lastRunDurationMs: event.lastRunDurationMs,
1003
+ lastRunError: event.lastRunError,
1004
+ lastRunLogs: event.lastRunLogs,
1005
+ }, null, 2));
1006
+ } else {
1007
+ console.log(chalk.bold(`\nScript Event: ${event.title}`));
1008
+ console.log(chalk.gray(` ID: ${event.id} Status: ${event.status}`));
1009
+
1010
+ if (!event.lastRunAt) {
1011
+ console.log(chalk.gray("\n No execution history yet.\n"));
1012
+ } else {
1013
+ const runColor = event.lastRunStatus === "success" ? chalk.green : chalk.red;
1014
+ const duration = event.lastRunDurationMs != null ? ` in ${event.lastRunDurationMs}ms` : "";
1015
+ console.log(`\n Last run: ${runColor(event.lastRunStatus)}${duration}`);
1016
+ console.log(chalk.gray(` Ran at: ${event.lastRunAt}`));
1017
+
1018
+ if (event.lastRunError) {
1019
+ console.log(chalk.red(`\n Error:\n ${event.lastRunError}`));
1020
+ }
1021
+
1022
+ if (event.lastRunLogs) {
1023
+ console.log(chalk.bold("\n Logs:"));
1024
+ console.log(
1025
+ event.lastRunLogs
1026
+ .split("\n")
1027
+ .map((line) => ` ${line}`)
1028
+ .join("\n")
1029
+ );
1030
+ } else {
1031
+ console.log(chalk.gray("\n No log output."));
1032
+ }
1033
+ console.log("");
1034
+ }
1035
+ }
1036
+ } catch (error) {
1037
+ console.error(chalk.red(`Error: ${error.message}`));
1038
+ process.exit(1);
1039
+ }
1040
+ });
1041
+
1042
+ // ============================================================================
1043
+ // Secret Commands
1044
+ // ============================================================================
1045
+
1046
+ const secretCmd = program.command("secret").description("Manage script secrets");
1047
+
1048
+ secretCmd
1049
+ .command("set <key> <value>")
1050
+ .description("Create or update a script secret")
1051
+ .option("-j, --json", "Output as JSON")
1052
+ .action(async (key, value, options) => {
1053
+ try {
1054
+ const data = await api.createSecret(key.toUpperCase(), value);
1055
+ const secret = data.secret || data;
1056
+
1057
+ if (options.json) {
1058
+ console.log(JSON.stringify(data, null, 2));
1059
+ } else {
1060
+ console.log(chalk.green("Secret saved:"));
1061
+ console.log(` Key: ${secret.key}`);
1062
+ console.log(` ID: ${secret.id}`);
1063
+ }
1064
+ } catch (error) {
1065
+ console.error(chalk.red(`Error: ${error.message}`));
1066
+ process.exit(1);
1067
+ }
1068
+ });
1069
+
1070
+ secretCmd
1071
+ .command("list")
1072
+ .description("List script secret keys (values are never shown)")
1073
+ .option("-j, --json", "Output as JSON")
1074
+ .action(async (options) => {
1075
+ try {
1076
+ const data = await api.listSecrets();
1077
+ const secrets = data.secrets || data;
1078
+
1079
+ if (options.json) {
1080
+ console.log(JSON.stringify(data, null, 2));
1081
+ } else {
1082
+ console.log(chalk.bold("\nScript Secrets:\n"));
1083
+ if (!secrets.length) {
1084
+ console.log(" No secrets stored.");
1085
+ } else {
1086
+ for (const secret of secrets) {
1087
+ console.log(` ${chalk.cyan(secret.key)}`);
1088
+ console.log(chalk.gray(` ID: ${secret.id} Added: ${new Date(secret.createdAt).toLocaleDateString()}`));
1089
+ }
1090
+ }
1091
+ console.log("");
1092
+ }
1093
+ } catch (error) {
1094
+ console.error(chalk.red(`Error: ${error.message}`));
1095
+ process.exit(1);
1096
+ }
1097
+ });
1098
+
1099
+ secretCmd
1100
+ .command("delete <key>")
1101
+ .description("Delete a script secret by key name")
1102
+ .option("-j, --json", "Output as JSON")
1103
+ .action(async (key, options) => {
1104
+ try {
1105
+ // Look up secret by key name to get its ID
1106
+ const data = await api.listSecrets();
1107
+ const secrets = data.secrets || data;
1108
+ const match = secrets.find((s) => s.key === key.toUpperCase());
1109
+
1110
+ if (!match) {
1111
+ console.error(chalk.red(`Error: Secret "${key.toUpperCase()}" not found`));
1112
+ process.exit(1);
1113
+ }
1114
+
1115
+ const deleteData = await api.deleteSecret(match.id);
1116
+
1117
+ if (options.json) {
1118
+ console.log(JSON.stringify(deleteData, null, 2));
1119
+ } else {
1120
+ console.log(chalk.green(`Secret deleted: ${key.toUpperCase()}`));
1121
+ }
1122
+ } catch (error) {
1123
+ console.error(chalk.red(`Error: ${error.message}`));
1124
+ process.exit(1);
1125
+ }
1126
+ });
1127
+
1128
+ // Alias: `1m secrets` -> `1m secret list`
1129
+ program
1130
+ .command("secrets")
1131
+ .description("List script secrets (alias for 'secret list')")
1132
+ .option("-j, --json", "Output as JSON")
1133
+ .action(async (options) => {
1134
+ try {
1135
+ const data = await api.listSecrets();
1136
+ const secrets = data.secrets || data;
1137
+
1138
+ if (options.json) {
1139
+ console.log(JSON.stringify(data, null, 2));
1140
+ } else {
1141
+ console.log(chalk.bold("\nScript Secrets:\n"));
1142
+ if (!secrets.length) {
1143
+ console.log(" No secrets stored.");
1144
+ } else {
1145
+ for (const secret of secrets) {
1146
+ console.log(` ${chalk.cyan(secret.key)}`);
1147
+ console.log(chalk.gray(` ID: ${secret.id} Added: ${new Date(secret.createdAt).toLocaleDateString()}`));
1148
+ }
1149
+ }
1150
+ console.log("");
1151
+ }
1152
+ } catch (error) {
1153
+ console.error(chalk.red(`Error: ${error.message}`));
1154
+ process.exit(1);
1155
+ }
1156
+ });
1157
+
978
1158
  // ============================================================================
979
1159
  // Config Commands
980
1160
  // ============================================================================