@ait-co/console-cli 0.1.7 → 0.1.9

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 CHANGED
@@ -204,6 +204,22 @@ 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
+ };
219
+ }
220
+ function isRecordOrNull(v) {
221
+ return v === null || typeof v === "object" && !Array.isArray(v);
222
+ }
207
223
  async function createMiniApp(workspaceId, payload, cookies, opts = {}) {
208
224
  return normalizeCreateResult(await requestConsoleApi({
209
225
  url: `${BASE$2}/workspaces/${workspaceId}/mini-app/review`,
@@ -803,21 +819,23 @@ function buildSubmitPayload(manifest, urls) {
803
819
  }))
804
820
  ];
805
821
  return {
806
- title: manifest.titleKo,
807
- titleEn: manifest.titleEn,
808
- appName: manifest.appName,
809
- iconUri: urls.logo,
810
- status: "PREPARE",
811
- csEmail: manifest.csEmail,
812
- description: manifest.subtitle,
813
- detailDescription: manifest.description,
814
- images,
822
+ miniApp: {
823
+ title: manifest.titleKo,
824
+ titleEn: manifest.titleEn,
825
+ appName: manifest.appName,
826
+ iconUri: urls.logo,
827
+ status: "PREPARE",
828
+ csEmail: manifest.csEmail,
829
+ description: manifest.subtitle,
830
+ detailDescription: manifest.description,
831
+ images,
832
+ ...urls.logoDarkMode !== void 0 ? { darkModeIconUri: urls.logoDarkMode } : {},
833
+ ...manifest.homePageUri !== void 0 ? { homePageUri: manifest.homePageUri } : {}
834
+ },
815
835
  impression: {
816
836
  keywordList: manifest.keywords,
817
- categoryList: manifest.categoryIds.map((id) => ({ id }))
818
- },
819
- ...urls.logoDarkMode !== void 0 ? { darkModeIconUri: urls.logoDarkMode } : {},
820
- ...manifest.homePageUri !== void 0 ? { homePageUri: manifest.homePageUri } : {}
837
+ categoryIds: manifest.categoryIds
838
+ }
821
839
  };
822
840
  }
823
841
  //#endregion
@@ -1026,21 +1044,112 @@ function reviewStateFor(entry) {
1026
1044
  const raw = entry.reviewState ?? entry.status;
1027
1045
  return typeof raw === "string" ? raw : void 0;
1028
1046
  }
1047
+ const lsCommand$3 = defineCommand({
1048
+ meta: {
1049
+ name: "ls",
1050
+ description: "List mini-apps in the selected workspace."
1051
+ },
1052
+ args: {
1053
+ workspace: {
1054
+ type: "string",
1055
+ description: "Workspace ID. Defaults to the selected workspace (`aitcc workspace use`)."
1056
+ },
1057
+ json: {
1058
+ type: "boolean",
1059
+ description: "Emit machine-readable JSON to stdout.",
1060
+ default: false
1061
+ }
1062
+ },
1063
+ async run({ args }) {
1064
+ const ctx = await resolveWorkspaceContext(args);
1065
+ if (!ctx) return;
1066
+ const { session, workspaceId } = ctx;
1067
+ try {
1068
+ const [apps, review] = await Promise.all([fetchMiniApps(workspaceId, session.cookies), fetchReviewStatus(workspaceId, session.cookies)]);
1069
+ if (args.json) {
1070
+ const joined = apps.map((app) => {
1071
+ const reviewState = reviewStateFor(findReviewEntry(review.miniApps, app.id));
1072
+ return {
1073
+ id: app.id,
1074
+ name: app.name ?? null,
1075
+ ...reviewState !== void 0 ? { reviewState } : {},
1076
+ extra: app.extra
1077
+ };
1078
+ });
1079
+ emitJson({
1080
+ ok: true,
1081
+ workspaceId,
1082
+ hasPolicyViolation: review.hasPolicyViolation,
1083
+ apps: joined
1084
+ });
1085
+ return exitAfterFlush(ExitCode.Ok);
1086
+ }
1087
+ if (apps.length === 0) {
1088
+ process.stdout.write(`No apps in workspace ${workspaceId}.\n`);
1089
+ if (review.hasPolicyViolation) process.stderr.write("Note: workspace-wide policy violation flag is set.\n");
1090
+ return exitAfterFlush(ExitCode.Ok);
1091
+ }
1092
+ for (const app of apps) {
1093
+ const reviewState = reviewStateFor(findReviewEntry(review.miniApps, app.id)) ?? "-";
1094
+ const name = app.name ?? "(unnamed)";
1095
+ process.stdout.write(`${app.id}\t${name}\t${reviewState}\n`);
1096
+ }
1097
+ if (review.hasPolicyViolation) process.stderr.write("Note: workspace-wide policy violation flag is set.\n");
1098
+ return exitAfterFlush(ExitCode.Ok);
1099
+ } catch (err) {
1100
+ return emitFailureFromError(args.json, err);
1101
+ }
1102
+ }
1103
+ });
1104
+ function pickMiniAppView(envelope, view) {
1105
+ const extract = (side) => {
1106
+ if (side === null) return null;
1107
+ const ma = side.miniApp;
1108
+ if (ma !== null && typeof ma === "object" && !Array.isArray(ma)) return ma;
1109
+ return null;
1110
+ };
1111
+ const draft = extract(envelope.draft);
1112
+ const current = extract(envelope.current);
1113
+ if (view === "draft") return draft;
1114
+ if (view === "current") return current;
1115
+ if (current !== null && draft !== null) return {
1116
+ ...current,
1117
+ ...draft
1118
+ };
1119
+ return draft ?? current;
1120
+ }
1121
+ function parseAppId(raw) {
1122
+ if (raw === void 0 || raw === "") return null;
1123
+ const n = Number(raw);
1124
+ if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) return null;
1125
+ return n;
1126
+ }
1029
1127
  const appCommand = defineCommand({
1030
1128
  meta: {
1031
1129
  name: "app",
1032
1130
  description: "Inspect mini-apps in a workspace."
1033
1131
  },
1034
1132
  subCommands: {
1035
- ls: defineCommand({
1133
+ ls: lsCommand$3,
1134
+ show: defineCommand({
1036
1135
  meta: {
1037
- name: "ls",
1038
- description: "List mini-apps in the selected workspace."
1136
+ name: "show",
1137
+ description: "Show full details of a mini-app, including fields only visible in the draft view."
1039
1138
  },
1040
1139
  args: {
1140
+ id: {
1141
+ type: "positional",
1142
+ description: "Mini-app ID (the numeric `appId` from `app ls` or `app register`).",
1143
+ required: true
1144
+ },
1041
1145
  workspace: {
1042
1146
  type: "string",
1043
- description: "Workspace ID. Defaults to the selected workspace (`aitcc workspace use`)."
1147
+ description: "Workspace ID. Defaults to the selected workspace."
1148
+ },
1149
+ view: {
1150
+ type: "string",
1151
+ description: "Which view to render: `draft` (default), `current`, or `merged`.",
1152
+ default: "draft"
1044
1153
  },
1045
1154
  json: {
1046
1155
  type: "boolean",
@@ -1049,40 +1158,86 @@ const appCommand = defineCommand({
1049
1158
  }
1050
1159
  },
1051
1160
  async run({ args }) {
1161
+ const appId = parseAppId(args.id);
1162
+ if (appId === null) {
1163
+ if (args.json) emitJson({
1164
+ ok: false,
1165
+ reason: "invalid-id",
1166
+ message: `app id must be a positive integer (got ${JSON.stringify(args.id)})`
1167
+ });
1168
+ else process.stderr.write(`app show: invalid id ${JSON.stringify(args.id)}\n`);
1169
+ return exitAfterFlush(ExitCode.Usage);
1170
+ }
1171
+ const view = args.view;
1172
+ if (view !== "draft" && view !== "current" && view !== "merged") {
1173
+ if (args.json) emitJson({
1174
+ ok: false,
1175
+ reason: "invalid-config",
1176
+ field: "view",
1177
+ message: `--view must be one of draft|current|merged (got ${JSON.stringify(view)})`
1178
+ });
1179
+ else process.stderr.write(`app show: invalid --view ${JSON.stringify(view)}\n`);
1180
+ return exitAfterFlush(ExitCode.Usage);
1181
+ }
1052
1182
  const ctx = await resolveWorkspaceContext(args);
1053
1183
  if (!ctx) return;
1054
1184
  const { session, workspaceId } = ctx;
1055
1185
  try {
1056
- const [apps, review] = await Promise.all([fetchMiniApps(workspaceId, session.cookies), fetchReviewStatus(workspaceId, session.cookies)]);
1186
+ const envelope = await fetchMiniAppWithDraft(workspaceId, appId, session.cookies);
1187
+ const miniApp = pickMiniAppView(envelope, view);
1057
1188
  if (args.json) {
1058
- const joined = apps.map((app) => {
1059
- const reviewState = reviewStateFor(findReviewEntry(review.miniApps, app.id));
1060
- return {
1061
- id: app.id,
1062
- name: app.name ?? null,
1063
- ...reviewState !== void 0 ? { reviewState } : {},
1064
- extra: app.extra
1065
- };
1066
- });
1067
1189
  emitJson({
1068
1190
  ok: true,
1069
1191
  workspaceId,
1070
- hasPolicyViolation: review.hasPolicyViolation,
1071
- apps: joined
1192
+ appId,
1193
+ view,
1194
+ miniApp
1072
1195
  });
1073
1196
  return exitAfterFlush(ExitCode.Ok);
1074
1197
  }
1075
- if (apps.length === 0) {
1076
- process.stdout.write(`No apps in workspace ${workspaceId}.\n`);
1077
- if (review.hasPolicyViolation) process.stderr.write("Note: workspace-wide policy violation flag is set.\n");
1198
+ if (miniApp === null) {
1199
+ if (view === "current" && envelope.draft !== null) process.stdout.write(`App ${appId} has no \`current\` view yet (not reviewed). Try --view draft.\n`);
1200
+ else process.stdout.write(`App ${appId} has no data for view=${view}.\n`);
1078
1201
  return exitAfterFlush(ExitCode.Ok);
1079
1202
  }
1080
- for (const app of apps) {
1081
- const reviewState = reviewStateFor(findReviewEntry(review.miniApps, app.id)) ?? "-";
1082
- const name = app.name ?? "(unnamed)";
1083
- process.stdout.write(`${app.id}\t${name}\t${reviewState}\n`);
1084
- }
1085
- if (review.hasPolicyViolation) process.stderr.write("Note: workspace-wide policy violation flag is set.\n");
1203
+ const pick = (k) => {
1204
+ const v = miniApp[k];
1205
+ return v === null || v === void 0 ? "-" : String(v);
1206
+ };
1207
+ const images = Array.isArray(miniApp.images) ? miniApp.images : [];
1208
+ const impression = miniApp.impression !== null && typeof miniApp.impression === "object" ? miniApp.impression : {};
1209
+ const keywords = Array.isArray(impression.keywordList) ? impression.keywordList : [];
1210
+ const categoryPaths = Array.isArray(impression.categoryPaths) ? impression.categoryPaths : [];
1211
+ process.stdout.write(`# App ${appId} (view=${view})\n\n`);
1212
+ process.stdout.write(`Name (ko) ${pick("title")}\n`);
1213
+ process.stdout.write(`Name (en) ${pick("titleEn")}\n`);
1214
+ process.stdout.write(`App slug ${pick("appName")}\n`);
1215
+ process.stdout.write(`Status ${pick("status")}\n`);
1216
+ process.stdout.write(`Home page ${pick("homePageUri")}\n`);
1217
+ process.stdout.write(`CS email ${pick("csEmail")}\n`);
1218
+ process.stdout.write(`Logo ${pick("iconUri")}\n`);
1219
+ process.stdout.write(`Subtitle ${pick("description")}\n`);
1220
+ const detail = typeof miniApp.detailDescription === "string" ? `${[...miniApp.detailDescription].length} chars` : "-";
1221
+ process.stdout.write(`Detail desc ${detail}\n`);
1222
+ process.stdout.write(`Images ${images.length}\n`);
1223
+ process.stdout.write(`Keywords ${keywords.length} (${keywords.join(", ")})\n`);
1224
+ const firstPath = categoryPaths[0];
1225
+ if (firstPath && typeof firstPath === "object") {
1226
+ const fp = firstPath;
1227
+ const parts = [];
1228
+ for (const key of [
1229
+ "group",
1230
+ "category",
1231
+ "subCategory"
1232
+ ]) {
1233
+ const node = fp[key];
1234
+ if (node !== null && typeof node === "object") {
1235
+ const nm = node.name;
1236
+ if (typeof nm === "string") parts.push(nm);
1237
+ }
1238
+ }
1239
+ process.stdout.write(`Category ${parts.join(" > ") || "-"}\n`);
1240
+ } else process.stdout.write(`Category -\n`);
1086
1241
  return exitAfterFlush(ExitCode.Ok);
1087
1242
  } catch (err) {
1088
1243
  return emitFailureFromError(args.json, err);
@@ -2080,7 +2235,7 @@ function resolveVersion() {
2080
2235
  if (typeof injected === "string" && injected.length > 0) return injected;
2081
2236
  } catch {}
2082
2237
  try {
2083
- return "0.1.7";
2238
+ return "0.1.9";
2084
2239
  } catch {}
2085
2240
  return "0.0.0-dev";
2086
2241
  }