@ait-co/console-cli 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +300 -34
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -204,6 +204,24 @@ async function fetchReviewStatus(workspaceId, cookies, opts = {}) {
|
|
|
204
204
|
})
|
|
205
205
|
};
|
|
206
206
|
}
|
|
207
|
+
async function fetchMiniAppWithDraft(workspaceId, miniAppId, cookies, opts = {}) {
|
|
208
|
+
const raw = await requestConsoleApi({
|
|
209
|
+
url: `${BASE$2}/workspaces/${workspaceId}/mini-app/${miniAppId}/with-draft`,
|
|
210
|
+
cookies,
|
|
211
|
+
...opts.fetchImpl ? { fetchImpl: opts.fetchImpl } : {}
|
|
212
|
+
});
|
|
213
|
+
if (raw === null || typeof raw !== "object") throw new Error(`Unexpected with-draft shape for mini-app=${miniAppId}`);
|
|
214
|
+
const rec = raw;
|
|
215
|
+
return {
|
|
216
|
+
current: isRecordOrNull(rec.current) ? rec.current : null,
|
|
217
|
+
draft: isRecordOrNull(rec.draft) ? rec.draft : null,
|
|
218
|
+
approvalType: typeof rec.approvalType === "string" ? rec.approvalType : null,
|
|
219
|
+
rejectedMessage: typeof rec.rejectedMessage === "string" ? rec.rejectedMessage : null
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function isRecordOrNull(v) {
|
|
223
|
+
return v === null || typeof v === "object" && !Array.isArray(v);
|
|
224
|
+
}
|
|
207
225
|
async function createMiniApp(workspaceId, payload, cookies, opts = {}) {
|
|
208
226
|
return normalizeCreateResult(await requestConsoleApi({
|
|
209
227
|
url: `${BASE$2}/workspaces/${workspaceId}/mini-app/review`,
|
|
@@ -1028,64 +1046,312 @@ function reviewStateFor(entry) {
|
|
|
1028
1046
|
const raw = entry.reviewState ?? entry.status;
|
|
1029
1047
|
return typeof raw === "string" ? raw : void 0;
|
|
1030
1048
|
}
|
|
1049
|
+
const lsCommand$3 = defineCommand({
|
|
1050
|
+
meta: {
|
|
1051
|
+
name: "ls",
|
|
1052
|
+
description: "List mini-apps in the selected workspace."
|
|
1053
|
+
},
|
|
1054
|
+
args: {
|
|
1055
|
+
workspace: {
|
|
1056
|
+
type: "string",
|
|
1057
|
+
description: "Workspace ID. Defaults to the selected workspace (`aitcc workspace use`)."
|
|
1058
|
+
},
|
|
1059
|
+
json: {
|
|
1060
|
+
type: "boolean",
|
|
1061
|
+
description: "Emit machine-readable JSON to stdout.",
|
|
1062
|
+
default: false
|
|
1063
|
+
}
|
|
1064
|
+
},
|
|
1065
|
+
async run({ args }) {
|
|
1066
|
+
const ctx = await resolveWorkspaceContext(args);
|
|
1067
|
+
if (!ctx) return;
|
|
1068
|
+
const { session, workspaceId } = ctx;
|
|
1069
|
+
try {
|
|
1070
|
+
const [apps, review] = await Promise.all([fetchMiniApps(workspaceId, session.cookies), fetchReviewStatus(workspaceId, session.cookies)]);
|
|
1071
|
+
if (args.json) {
|
|
1072
|
+
const joined = apps.map((app) => {
|
|
1073
|
+
const reviewState = reviewStateFor(findReviewEntry(review.miniApps, app.id));
|
|
1074
|
+
return {
|
|
1075
|
+
id: app.id,
|
|
1076
|
+
name: app.name ?? null,
|
|
1077
|
+
...reviewState !== void 0 ? { reviewState } : {},
|
|
1078
|
+
extra: app.extra
|
|
1079
|
+
};
|
|
1080
|
+
});
|
|
1081
|
+
emitJson({
|
|
1082
|
+
ok: true,
|
|
1083
|
+
workspaceId,
|
|
1084
|
+
hasPolicyViolation: review.hasPolicyViolation,
|
|
1085
|
+
apps: joined
|
|
1086
|
+
});
|
|
1087
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
1088
|
+
}
|
|
1089
|
+
if (apps.length === 0) {
|
|
1090
|
+
process.stdout.write(`No apps in workspace ${workspaceId}.\n`);
|
|
1091
|
+
if (review.hasPolicyViolation) process.stderr.write("Note: workspace-wide policy violation flag is set.\n");
|
|
1092
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
1093
|
+
}
|
|
1094
|
+
for (const app of apps) {
|
|
1095
|
+
const reviewState = reviewStateFor(findReviewEntry(review.miniApps, app.id)) ?? "-";
|
|
1096
|
+
const name = app.name ?? "(unnamed)";
|
|
1097
|
+
process.stdout.write(`${app.id}\t${name}\t${reviewState}\n`);
|
|
1098
|
+
}
|
|
1099
|
+
if (review.hasPolicyViolation) process.stderr.write("Note: workspace-wide policy violation flag is set.\n");
|
|
1100
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
1101
|
+
} catch (err) {
|
|
1102
|
+
return emitFailureFromError(args.json, err);
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
});
|
|
1106
|
+
function pickMiniAppView(envelope, view) {
|
|
1107
|
+
const extract = (side) => {
|
|
1108
|
+
if (side === null) return null;
|
|
1109
|
+
const ma = side.miniApp;
|
|
1110
|
+
if (ma !== null && typeof ma === "object" && !Array.isArray(ma)) return ma;
|
|
1111
|
+
return null;
|
|
1112
|
+
};
|
|
1113
|
+
const draft = extract(envelope.draft);
|
|
1114
|
+
const current = extract(envelope.current);
|
|
1115
|
+
if (view === "draft") return draft;
|
|
1116
|
+
if (view === "current") return current;
|
|
1117
|
+
if (current !== null && draft !== null) return {
|
|
1118
|
+
...current,
|
|
1119
|
+
...draft
|
|
1120
|
+
};
|
|
1121
|
+
return draft ?? current;
|
|
1122
|
+
}
|
|
1123
|
+
function parseAppId(raw) {
|
|
1124
|
+
if (raw === void 0 || raw === "") return null;
|
|
1125
|
+
const n = Number(raw);
|
|
1126
|
+
if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) return null;
|
|
1127
|
+
return n;
|
|
1128
|
+
}
|
|
1129
|
+
const showCommand$1 = defineCommand({
|
|
1130
|
+
meta: {
|
|
1131
|
+
name: "show",
|
|
1132
|
+
description: "Show full details of a mini-app, including fields only visible in the draft view."
|
|
1133
|
+
},
|
|
1134
|
+
args: {
|
|
1135
|
+
id: {
|
|
1136
|
+
type: "positional",
|
|
1137
|
+
description: "Mini-app ID (the numeric `appId` from `app ls` or `app register`).",
|
|
1138
|
+
required: true
|
|
1139
|
+
},
|
|
1140
|
+
workspace: {
|
|
1141
|
+
type: "string",
|
|
1142
|
+
description: "Workspace ID. Defaults to the selected workspace."
|
|
1143
|
+
},
|
|
1144
|
+
view: {
|
|
1145
|
+
type: "string",
|
|
1146
|
+
description: "Which view to render: `draft` (default), `current`, or `merged`.",
|
|
1147
|
+
default: "draft"
|
|
1148
|
+
},
|
|
1149
|
+
json: {
|
|
1150
|
+
type: "boolean",
|
|
1151
|
+
description: "Emit machine-readable JSON to stdout.",
|
|
1152
|
+
default: false
|
|
1153
|
+
}
|
|
1154
|
+
},
|
|
1155
|
+
async run({ args }) {
|
|
1156
|
+
const appId = parseAppId(args.id);
|
|
1157
|
+
if (appId === null) {
|
|
1158
|
+
if (args.json) emitJson({
|
|
1159
|
+
ok: false,
|
|
1160
|
+
reason: "invalid-id",
|
|
1161
|
+
message: `app id must be a positive integer (got ${JSON.stringify(args.id)})`
|
|
1162
|
+
});
|
|
1163
|
+
else process.stderr.write(`app show: invalid id ${JSON.stringify(args.id)}\n`);
|
|
1164
|
+
return exitAfterFlush(ExitCode.Usage);
|
|
1165
|
+
}
|
|
1166
|
+
const view = args.view;
|
|
1167
|
+
if (view !== "draft" && view !== "current" && view !== "merged") {
|
|
1168
|
+
if (args.json) emitJson({
|
|
1169
|
+
ok: false,
|
|
1170
|
+
reason: "invalid-config",
|
|
1171
|
+
field: "view",
|
|
1172
|
+
message: `--view must be one of draft|current|merged (got ${JSON.stringify(view)})`
|
|
1173
|
+
});
|
|
1174
|
+
else process.stderr.write(`app show: invalid --view ${JSON.stringify(view)}\n`);
|
|
1175
|
+
return exitAfterFlush(ExitCode.Usage);
|
|
1176
|
+
}
|
|
1177
|
+
const ctx = await resolveWorkspaceContext(args);
|
|
1178
|
+
if (!ctx) return;
|
|
1179
|
+
const { session, workspaceId } = ctx;
|
|
1180
|
+
try {
|
|
1181
|
+
const envelope = await fetchMiniAppWithDraft(workspaceId, appId, session.cookies);
|
|
1182
|
+
const miniApp = pickMiniAppView(envelope, view);
|
|
1183
|
+
if (args.json) {
|
|
1184
|
+
emitJson({
|
|
1185
|
+
ok: true,
|
|
1186
|
+
workspaceId,
|
|
1187
|
+
appId,
|
|
1188
|
+
view,
|
|
1189
|
+
miniApp
|
|
1190
|
+
});
|
|
1191
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
1192
|
+
}
|
|
1193
|
+
if (miniApp === null) {
|
|
1194
|
+
if (view === "current" && envelope.draft !== null) process.stdout.write(`App ${appId} has no \`current\` view yet (not reviewed). Try --view draft.\n`);
|
|
1195
|
+
else process.stdout.write(`App ${appId} has no data for view=${view}.\n`);
|
|
1196
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
1197
|
+
}
|
|
1198
|
+
const pick = (k) => {
|
|
1199
|
+
const v = miniApp[k];
|
|
1200
|
+
return v === null || v === void 0 ? "-" : String(v);
|
|
1201
|
+
};
|
|
1202
|
+
const images = Array.isArray(miniApp.images) ? miniApp.images : [];
|
|
1203
|
+
const impression = miniApp.impression !== null && typeof miniApp.impression === "object" ? miniApp.impression : {};
|
|
1204
|
+
const keywords = Array.isArray(impression.keywordList) ? impression.keywordList : [];
|
|
1205
|
+
const categoryPaths = Array.isArray(impression.categoryPaths) ? impression.categoryPaths : [];
|
|
1206
|
+
process.stdout.write(`# App ${appId} (view=${view})\n\n`);
|
|
1207
|
+
process.stdout.write(`Name (ko) ${pick("title")}\n`);
|
|
1208
|
+
process.stdout.write(`Name (en) ${pick("titleEn")}\n`);
|
|
1209
|
+
process.stdout.write(`App slug ${pick("appName")}\n`);
|
|
1210
|
+
process.stdout.write(`Status ${pick("status")}\n`);
|
|
1211
|
+
process.stdout.write(`Home page ${pick("homePageUri")}\n`);
|
|
1212
|
+
process.stdout.write(`CS email ${pick("csEmail")}\n`);
|
|
1213
|
+
process.stdout.write(`Logo ${pick("iconUri")}\n`);
|
|
1214
|
+
process.stdout.write(`Subtitle ${pick("description")}\n`);
|
|
1215
|
+
const detail = typeof miniApp.detailDescription === "string" ? `${[...miniApp.detailDescription].length} chars` : "-";
|
|
1216
|
+
process.stdout.write(`Detail desc ${detail}\n`);
|
|
1217
|
+
process.stdout.write(`Images ${images.length}\n`);
|
|
1218
|
+
process.stdout.write(`Keywords ${keywords.length} (${keywords.join(", ")})\n`);
|
|
1219
|
+
const firstPath = categoryPaths[0];
|
|
1220
|
+
if (firstPath && typeof firstPath === "object") {
|
|
1221
|
+
const fp = firstPath;
|
|
1222
|
+
const parts = [];
|
|
1223
|
+
for (const key of [
|
|
1224
|
+
"group",
|
|
1225
|
+
"category",
|
|
1226
|
+
"subCategory"
|
|
1227
|
+
]) {
|
|
1228
|
+
const node = fp[key];
|
|
1229
|
+
if (node !== null && typeof node === "object") {
|
|
1230
|
+
const nm = node.name;
|
|
1231
|
+
if (typeof nm === "string") parts.push(nm);
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
process.stdout.write(`Category ${parts.join(" > ") || "-"}\n`);
|
|
1235
|
+
} else process.stdout.write(`Category -\n`);
|
|
1236
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
1237
|
+
} catch (err) {
|
|
1238
|
+
return emitFailureFromError(args.json, err);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
});
|
|
1242
|
+
function deriveReviewState(env) {
|
|
1243
|
+
const hasCurrent = env.current !== null;
|
|
1244
|
+
const hasDraft = env.draft !== null;
|
|
1245
|
+
const approvalType = env.approvalType;
|
|
1246
|
+
const rejectedMessage = env.rejectedMessage;
|
|
1247
|
+
let state;
|
|
1248
|
+
if (approvalType === null) state = "not-submitted";
|
|
1249
|
+
else if (rejectedMessage !== null) state = "rejected";
|
|
1250
|
+
else if (!hasCurrent) state = "under-review";
|
|
1251
|
+
else if (hasDraft) state = "approved-with-edits";
|
|
1252
|
+
else state = "approved";
|
|
1253
|
+
if (approvalType !== null && approvalType !== "REVIEW" && state === "under-review") state = "unknown";
|
|
1254
|
+
return {
|
|
1255
|
+
state,
|
|
1256
|
+
approvalType,
|
|
1257
|
+
rejectedMessage,
|
|
1258
|
+
hasCurrent,
|
|
1259
|
+
hasDraft
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
const POLL_MIN_INTERVAL_SEC = 30;
|
|
1263
|
+
const POLL_MAX_INTERVAL_SEC = 3600;
|
|
1031
1264
|
const appCommand = defineCommand({
|
|
1032
1265
|
meta: {
|
|
1033
1266
|
name: "app",
|
|
1034
1267
|
description: "Inspect mini-apps in a workspace."
|
|
1035
1268
|
},
|
|
1036
1269
|
subCommands: {
|
|
1037
|
-
ls:
|
|
1270
|
+
ls: lsCommand$3,
|
|
1271
|
+
show: showCommand$1,
|
|
1272
|
+
status: defineCommand({
|
|
1038
1273
|
meta: {
|
|
1039
|
-
name: "
|
|
1040
|
-
description: "
|
|
1274
|
+
name: "status",
|
|
1275
|
+
description: "Show the derived review state of a mini-app (under-review / rejected / approved)."
|
|
1041
1276
|
},
|
|
1042
1277
|
args: {
|
|
1278
|
+
id: {
|
|
1279
|
+
type: "positional",
|
|
1280
|
+
description: "Mini-app ID.",
|
|
1281
|
+
required: true
|
|
1282
|
+
},
|
|
1043
1283
|
workspace: {
|
|
1044
1284
|
type: "string",
|
|
1045
|
-
description: "Workspace ID. Defaults to the selected workspace
|
|
1285
|
+
description: "Workspace ID. Defaults to the selected workspace."
|
|
1286
|
+
},
|
|
1287
|
+
watch: {
|
|
1288
|
+
type: "boolean",
|
|
1289
|
+
description: "Poll until the review state flips off `under-review` (rejected or approved). Combine with `--interval <seconds>`.",
|
|
1290
|
+
default: false
|
|
1291
|
+
},
|
|
1292
|
+
interval: {
|
|
1293
|
+
type: "string",
|
|
1294
|
+
description: "Polling interval in seconds when --watch is set. Clamped to [30, 3600].",
|
|
1295
|
+
default: "60"
|
|
1046
1296
|
},
|
|
1047
1297
|
json: {
|
|
1048
1298
|
type: "boolean",
|
|
1049
|
-
description: "Emit machine-readable JSON
|
|
1299
|
+
description: "Emit machine-readable JSON.",
|
|
1050
1300
|
default: false
|
|
1051
1301
|
}
|
|
1052
1302
|
},
|
|
1053
1303
|
async run({ args }) {
|
|
1304
|
+
const appId = parseAppId(args.id);
|
|
1305
|
+
if (appId === null) {
|
|
1306
|
+
if (args.json) emitJson({
|
|
1307
|
+
ok: false,
|
|
1308
|
+
reason: "invalid-id",
|
|
1309
|
+
message: `app id must be a positive integer (got ${JSON.stringify(args.id)})`
|
|
1310
|
+
});
|
|
1311
|
+
else process.stderr.write(`app status: invalid id ${JSON.stringify(args.id)}\n`);
|
|
1312
|
+
return exitAfterFlush(ExitCode.Usage);
|
|
1313
|
+
}
|
|
1314
|
+
const intervalRaw = Number(args.interval);
|
|
1315
|
+
if (!Number.isFinite(intervalRaw) || intervalRaw <= 0) {
|
|
1316
|
+
if (args.json) emitJson({
|
|
1317
|
+
ok: false,
|
|
1318
|
+
reason: "invalid-config",
|
|
1319
|
+
field: "interval",
|
|
1320
|
+
message: `--interval must be a positive number (got ${JSON.stringify(args.interval)})`
|
|
1321
|
+
});
|
|
1322
|
+
else process.stderr.write(`app status: invalid --interval ${JSON.stringify(args.interval)}\n`);
|
|
1323
|
+
return exitAfterFlush(ExitCode.Usage);
|
|
1324
|
+
}
|
|
1325
|
+
const intervalSec = Math.max(POLL_MIN_INTERVAL_SEC, Math.min(POLL_MAX_INTERVAL_SEC, Math.floor(intervalRaw)));
|
|
1054
1326
|
const ctx = await resolveWorkspaceContext(args);
|
|
1055
1327
|
if (!ctx) return;
|
|
1056
1328
|
const { session, workspaceId } = ctx;
|
|
1329
|
+
const emit = (status) => {
|
|
1330
|
+
if (args.json) emitJson({
|
|
1331
|
+
ok: true,
|
|
1332
|
+
workspaceId,
|
|
1333
|
+
appId,
|
|
1334
|
+
...status
|
|
1335
|
+
});
|
|
1336
|
+
else process.stdout.write(`App ${appId} (ws ${workspaceId}): ${status.state}` + (status.rejectedMessage ? `\n reason: ${status.rejectedMessage}` : "") + "\n");
|
|
1337
|
+
};
|
|
1057
1338
|
try {
|
|
1058
|
-
const
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
id: app.id,
|
|
1064
|
-
name: app.name ?? null,
|
|
1065
|
-
...reviewState !== void 0 ? { reviewState } : {},
|
|
1066
|
-
extra: app.extra
|
|
1067
|
-
};
|
|
1068
|
-
});
|
|
1069
|
-
emitJson({
|
|
1070
|
-
ok: true,
|
|
1071
|
-
workspaceId,
|
|
1072
|
-
hasPolicyViolation: review.hasPolicyViolation,
|
|
1073
|
-
apps: joined
|
|
1074
|
-
});
|
|
1339
|
+
const once = async () => {
|
|
1340
|
+
return deriveReviewState(await fetchMiniAppWithDraft(workspaceId, appId, session.cookies));
|
|
1341
|
+
};
|
|
1342
|
+
if (!args.watch) {
|
|
1343
|
+
emit(await once());
|
|
1075
1344
|
return exitAfterFlush(ExitCode.Ok);
|
|
1076
1345
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
process.stdout.write(`${app.id}\t${name}\t${reviewState}\n`);
|
|
1346
|
+
let lastState = null;
|
|
1347
|
+
while (true) {
|
|
1348
|
+
const status = await once();
|
|
1349
|
+
if (args.json) emit(status);
|
|
1350
|
+
else if (status.state !== lastState) emit(status);
|
|
1351
|
+
lastState = status.state;
|
|
1352
|
+
if (status.state !== "under-review") return exitAfterFlush(ExitCode.Ok);
|
|
1353
|
+
await new Promise((resolve) => setTimeout(resolve, intervalSec * 1e3));
|
|
1086
1354
|
}
|
|
1087
|
-
if (review.hasPolicyViolation) process.stderr.write("Note: workspace-wide policy violation flag is set.\n");
|
|
1088
|
-
return exitAfterFlush(ExitCode.Ok);
|
|
1089
1355
|
} catch (err) {
|
|
1090
1356
|
return emitFailureFromError(args.json, err);
|
|
1091
1357
|
}
|
|
@@ -2082,7 +2348,7 @@ function resolveVersion() {
|
|
|
2082
2348
|
if (typeof injected === "string" && injected.length > 0) return injected;
|
|
2083
2349
|
} catch {}
|
|
2084
2350
|
try {
|
|
2085
|
-
return "0.1.
|
|
2351
|
+
return "0.1.10";
|
|
2086
2352
|
} catch {}
|
|
2087
2353
|
return "0.0.0-dev";
|
|
2088
2354
|
}
|