maoda-commander-tt 0.0.7 → 0.0.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/main.js CHANGED
@@ -72,6 +72,36 @@ var HelloCommand = class extends BaseSubcommandHost {
72
72
  // src/commands/pippit/pippit-get-thread-command.ts
73
73
  import { Option } from "commander";
74
74
 
75
+ // src/commands/pippit/modules/request-json.ts
76
+ async function readJsonBody(response, url, responseParseFailed2) {
77
+ const bodyText = await response.text();
78
+ try {
79
+ return makeOkWith(JSON.parse(bodyText));
80
+ } catch (error) {
81
+ const cause = error instanceof Error ? ` (${error.message})` : "";
82
+ return responseParseFailed2(`\u63A5\u53E3\u8FD4\u56DE\u975E JSON \u54CD\u5E94: ${url}${cause}`);
83
+ }
84
+ }
85
+ async function requestJson(url, init, handlers) {
86
+ let response;
87
+ try {
88
+ response = await fetch(url, init);
89
+ } catch (error) {
90
+ const cause = error instanceof Error ? ` (${error.message})` : "";
91
+ return handlers.networkRequestFailed(`\u8BF7\u6C42\u63A5\u53E3\u5931\u8D25: ${url}${cause}`);
92
+ }
93
+ if (handlers.unauthorizedError && (response.status === 401 || response.status === 403)) {
94
+ return handlers.unauthorizedError();
95
+ }
96
+ if (handlers.httpError && !response.ok) {
97
+ return handlers.httpError(
98
+ `\u63A5\u53E3\u8FD4\u56DE HTTP ${response.status} ${response.statusText}: ${url}`,
99
+ response
100
+ );
101
+ }
102
+ return readJsonBody(response, url, handlers.responseParseFailed);
103
+ }
104
+
75
105
  // src/commands/pippit/modules/get-thread/errors.ts
76
106
  var BASE = 1e4;
77
107
  var GetThreadError = ((GetThreadError2) => {
@@ -110,32 +140,27 @@ var REGION_REFERER_MAP = {
110
140
  async function fetchThread(threadId, region) {
111
141
  const url = REGION_URL_MAP[region];
112
142
  const referer = REGION_REFERER_MAP[region];
113
- let res;
114
- try {
115
- res = await fetch(url, {
116
- method: "POST",
117
- headers: {
118
- accept: "*/*",
119
- "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
120
- appvr: "1.1.4",
121
- "content-type": "application/json",
122
- Referer: referer
123
- },
124
- body: JSON.stringify({
125
- scopes: ["run_list.entry_list"],
126
- thread_id: threadId
127
- })
128
- });
129
- } catch (err) {
130
- return networkRequestFailedError(err instanceof Error ? err : void 0);
131
- }
132
- let data;
133
- try {
134
- data = await res.json();
135
- } catch (err) {
136
- return responseParseFailed(err instanceof Error ? err : void 0);
143
+ const result = await requestJson(url, {
144
+ method: "POST",
145
+ headers: {
146
+ accept: "*/*",
147
+ "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
148
+ appvr: "1.1.4",
149
+ "content-type": "application/json",
150
+ Referer: referer
151
+ },
152
+ body: JSON.stringify({
153
+ scopes: ["run_list.entry_list"],
154
+ thread_id: threadId
155
+ })
156
+ }, {
157
+ networkRequestFailed: (message) => networkRequestFailedError(message),
158
+ responseParseFailed: (message) => responseParseFailed(message)
159
+ });
160
+ if (!result.ok) {
161
+ return result;
137
162
  }
138
- const thread = data?.data?.thread;
163
+ const thread = result.value?.data?.thread;
139
164
  if (!thread?.run_list) {
140
165
  return threadNotFoundError();
141
166
  }
@@ -625,28 +650,19 @@ function createHeaders(token, referer) {
625
650
  Referer: referer
626
651
  };
627
652
  }
628
- async function requestJson(url, options) {
629
- let res;
630
- try {
631
- res = await fetch(url, options);
632
- } catch (error) {
633
- return networkRequestFailedError2(
634
- error instanceof Error ? error : void 0
635
- );
636
- }
637
- if (res.status === 401 || res.status === 403) {
638
- return (options.unauthorizedError ?? expiredFornaxTokenError)();
639
- }
640
- if (!res.ok) {
641
- return networkRequestFailedError2(
642
- new Error(`HTTP ${res.status} ${res.statusText}`)
643
- );
644
- }
645
- try {
646
- return makeOkWith(await res.json());
647
- } catch (error) {
648
- return responseParseFailedError(error instanceof Error ? error : void 0);
649
- }
653
+ async function requestJson2(url, options) {
654
+ return requestJson(url, options, {
655
+ networkRequestFailed: (message) => {
656
+ return networkRequestFailedError2(message);
657
+ },
658
+ responseParseFailed: (message) => {
659
+ return responseParseFailedError(message);
660
+ },
661
+ unauthorizedError: options.unauthorizedError ?? expiredFornaxTokenError,
662
+ httpError: (message) => {
663
+ return networkRequestFailedError2(message);
664
+ }
665
+ });
650
666
  }
651
667
  function resolveTimeWindow(baseOffsetInDays, daysLater) {
652
668
  const currentTime = Date.now();
@@ -766,7 +782,7 @@ async function searchLogCn(options) {
766
782
  if (!token) {
767
783
  return missingFornaxTokenError();
768
784
  }
769
- const searchResult = await requestJson(getSearchUrl(), {
785
+ const searchResult = await requestJson2(getSearchUrl(), {
770
786
  method: "POST",
771
787
  headers: createHeaders(token, getSearchReferer()),
772
788
  body: getSearchBody(logId),
@@ -783,7 +799,7 @@ async function searchLogCn(options) {
783
799
  if (!rootSpan?.trace_id) {
784
800
  return detailSpanNotFoundError();
785
801
  }
786
- const treeResult = await requestJson(getTreeUrl(), {
802
+ const treeResult = await requestJson2(getTreeUrl(), {
787
803
  method: "POST",
788
804
  headers: createHeaders(token, getSearchReferer()),
789
805
  body: JSON.stringify({
@@ -802,7 +818,7 @@ async function searchLogCn(options) {
802
818
  if (!detailSpan?.trace_id || !detailSpan.span_id) {
803
819
  return detailSpanNotFoundError();
804
820
  }
805
- const detailResult = await requestJson(
821
+ const detailResult = await requestJson2(
806
822
  getDetailUrl(detailSpan.trace_id, detailSpan.span_id),
807
823
  {
808
824
  method: "GET",
@@ -862,7 +878,7 @@ async function searchLogI18n(options) {
862
878
  if (!token) {
863
879
  return missingFornaxTokenError();
864
880
  }
865
- const searchResult = await requestJson(getSearchUrl2(), {
881
+ const searchResult = await requestJson2(getSearchUrl2(), {
866
882
  method: "POST",
867
883
  headers: createHeaders(token, getSearchReferer2(logId)),
868
884
  body: JSON.stringify({
@@ -880,7 +896,7 @@ async function searchLogI18n(options) {
880
896
  if (!searchSpan?.trace_id || !searchSpan.span_id) {
881
897
  return searchResultNotFoundError();
882
898
  }
883
- const detailResult = await requestJson(
899
+ const detailResult = await requestJson2(
884
900
  getDetailUrl2(searchSpan.trace_id, searchSpan.span_id),
885
901
  {
886
902
  method: "GET",
@@ -1079,6 +1095,710 @@ var PippitSaveThreadFornaxCommand = class extends BaseCommand {
1079
1095
  }
1080
1096
  };
1081
1097
 
1098
+ // src/commands/pippit/pippit-asset-upload-command.ts
1099
+ import * as path5 from "path";
1100
+ import { Option as Option5 } from "commander";
1101
+
1102
+ // src/commands/pippit/modules/asset-upload/cn-asset-upload.ts
1103
+ import * as fs4 from "fs/promises";
1104
+ import * as path4 from "path";
1105
+
1106
+ // src/commands/pippit/modules/web-token/web-token.ts
1107
+ function getWebTokenConfigPath(region) {
1108
+ return region === "cn" /* CN */ ? ["xyqweb", "sessionid_pippitcn_web"] : ["pippitweb", "sid_tt"];
1109
+ }
1110
+ function getWebTokenNamespace(region) {
1111
+ return region === "cn" /* CN */ ? ["xyqweb"] : ["pippitweb"];
1112
+ }
1113
+ async function writeWebToken(region, token) {
1114
+ const namespace = getWebTokenNamespace(region);
1115
+ const namespaceResult = await readConfigValue(
1116
+ namespace,
1117
+ void 0
1118
+ );
1119
+ if (!namespaceResult.ok) {
1120
+ return namespaceResult;
1121
+ }
1122
+ const nextConfig = {
1123
+ [getWebTokenConfigPath(region)[1]]: token
1124
+ };
1125
+ return writeConfigValue(namespace, nextConfig);
1126
+ }
1127
+ async function readWebToken(region) {
1128
+ return readConfigValue(getWebTokenConfigPath(region));
1129
+ }
1130
+
1131
+ // src/commands/pippit/modules/web-token/errors.ts
1132
+ var BASE3 = 13e3;
1133
+ var WebTokenError = ((WebTokenError2) => {
1134
+ WebTokenError2[WebTokenError2["MissingWebToken"] = BASE3 + 1] = "MissingWebToken";
1135
+ WebTokenError2[WebTokenError2["NetworkRequestFailed"] = BASE3 + 2] = "NetworkRequestFailed";
1136
+ WebTokenError2[WebTokenError2["ResponseParseFailed"] = BASE3 + 3] = "ResponseParseFailed";
1137
+ WebTokenError2[WebTokenError2["UserInfoRequestFailed"] = BASE3 + 4] = "UserInfoRequestFailed";
1138
+ WebTokenError2[WebTokenError2["UserInfoNotFound"] = BASE3 + 5] = "UserInfoNotFound";
1139
+ WebTokenError2[WebTokenError2["WorkspaceRequestFailed"] = BASE3 + 6] = "WorkspaceRequestFailed";
1140
+ WebTokenError2[WebTokenError2["WorkspaceNotFound"] = BASE3 + 7] = "WorkspaceNotFound";
1141
+ WebTokenError2[WebTokenError2["RefreshNotSupported"] = BASE3 + 8] = "RefreshNotSupported";
1142
+ WebTokenError2[WebTokenError2["MissingWebContext"] = BASE3 + 9] = "MissingWebContext";
1143
+ return WebTokenError2;
1144
+ })(WebTokenError || {});
1145
+ var missingWebTokenError = lvErrorConst(
1146
+ WebTokenError.MissingWebToken,
1147
+ "\u7F3A\u5C11\u53EF\u7528\u7684 sessionid_pippitcn_web token\uFF0C\u8BF7\u5148\u4F7F\u7528 `tt pippit web-token --region=cn <token>` \u914D\u7F6E\u3002"
1148
+ );
1149
+ var networkRequestFailedError3 = lvErrorConst(
1150
+ WebTokenError.NetworkRequestFailed,
1151
+ "\u8BF7\u6C42 pippit web \u76F8\u5173\u63A5\u53E3\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u548C\u767B\u5F55\u6001\u3002"
1152
+ );
1153
+ var responseParseFailedError2 = lvErrorConst(
1154
+ WebTokenError.ResponseParseFailed,
1155
+ "\u89E3\u6790 pippit web \u63A5\u53E3\u54CD\u5E94\u5931\u8D25\u3002"
1156
+ );
1157
+ var userInfoRequestFailedError = lvErrorConst(
1158
+ WebTokenError.UserInfoRequestFailed,
1159
+ "\u83B7\u53D6 pippit \u7528\u6237\u4FE1\u606F\u5931\u8D25\u3002"
1160
+ );
1161
+ var userInfoNotFoundError = lvErrorConst(
1162
+ WebTokenError.UserInfoNotFound,
1163
+ "\u83B7\u53D6 pippit \u7528\u6237\u4FE1\u606F\u5931\u8D25\uFF0C\u672A\u8FD4\u56DE uid\u3002"
1164
+ );
1165
+ var workspaceRequestFailedError = lvErrorConst(
1166
+ WebTokenError.WorkspaceRequestFailed,
1167
+ "\u83B7\u53D6 pippit workspace \u4FE1\u606F\u5931\u8D25\u3002"
1168
+ );
1169
+ var workspaceNotFoundError = lvErrorConst(
1170
+ WebTokenError.WorkspaceNotFound,
1171
+ "\u83B7\u53D6 pippit workspace \u4FE1\u606F\u5931\u8D25\uFF0C\u672A\u8FD4\u56DE workspace_id \u6216 space_id\u3002"
1172
+ );
1173
+ var refreshNotSupportedError = lvErrorConst(
1174
+ WebTokenError.RefreshNotSupported,
1175
+ "\u5F53\u524D\u4EC5\u652F\u6301\u56FD\u5185\u573A\u666F\u5237\u65B0 pippit web \u5173\u8054\u4FE1\u606F\u3002"
1176
+ );
1177
+ var missingWebContextError = lvErrorConst(
1178
+ WebTokenError.MissingWebContext,
1179
+ "\u8BF7\u5148\u914D\u7F6E web-token"
1180
+ );
1181
+
1182
+ // src/commands/pippit/modules/web-token/web-context.ts
1183
+ var USER_INFO_URL = "https://xyq.jianying.com/commerce/v1/subscription/user_info";
1184
+ var WORKSPACE_URL = "https://xyq.jianying.com/api/web/v1/workspace/get_user_workspace";
1185
+ var WEB_NAMESPACE_PATH = ["xyqweb", "pippitweb"];
1186
+ function normalizeToken2(token) {
1187
+ const trimmed = token.trim();
1188
+ const prefix = "sessionid_pippitcn_web=";
1189
+ if (trimmed.startsWith(prefix)) {
1190
+ return trimmed.slice(prefix.length).trim();
1191
+ }
1192
+ return trimmed;
1193
+ }
1194
+ function createCookieHeader(token) {
1195
+ return `sessionid_pippitcn_web=${normalizeToken2(token)}`;
1196
+ }
1197
+ function normalizeId(value) {
1198
+ if (typeof value === "number") {
1199
+ return Number.isFinite(value) ? String(value) : void 0;
1200
+ }
1201
+ if (typeof value !== "string") {
1202
+ return void 0;
1203
+ }
1204
+ const trimmed = value.trim();
1205
+ return trimmed.length > 0 ? trimmed : void 0;
1206
+ }
1207
+ function parseWebContext(value) {
1208
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
1209
+ return void 0;
1210
+ }
1211
+ const record = value;
1212
+ const uid = normalizeId(record.uid);
1213
+ const workspaceId = normalizeId(
1214
+ record.workspace_id
1215
+ );
1216
+ const spaceId = normalizeId(record.space_id);
1217
+ if (!uid || !workspaceId || !spaceId) {
1218
+ return void 0;
1219
+ }
1220
+ return {
1221
+ uid,
1222
+ workspaceId,
1223
+ spaceId
1224
+ };
1225
+ }
1226
+ async function requestJson3(url, init) {
1227
+ return requestJson(url, init, {
1228
+ networkRequestFailed: (message) => {
1229
+ return networkRequestFailedError3(message);
1230
+ },
1231
+ responseParseFailed: (message) => {
1232
+ return responseParseFailedError2(message);
1233
+ }
1234
+ });
1235
+ }
1236
+ async function fetchUserId(token) {
1237
+ const responseResult = await requestJson3(USER_INFO_URL, {
1238
+ method: "POST",
1239
+ headers: {
1240
+ accept: "application/json, text/plain, */*",
1241
+ "content-type": "application/json",
1242
+ cookie: createCookieHeader(token),
1243
+ Referer: "https://xyq.jianying.com/"
1244
+ },
1245
+ body: JSON.stringify({
1246
+ aid: 795647
1247
+ })
1248
+ });
1249
+ if (!responseResult.ok) {
1250
+ return responseResult;
1251
+ }
1252
+ const data = responseResult.value;
1253
+ if (String(data?.ret) !== "0") {
1254
+ return userInfoRequestFailedError(data?.errmsg);
1255
+ }
1256
+ const uid = normalizeId(data?.data?.uid);
1257
+ if (!uid) {
1258
+ return userInfoNotFoundError();
1259
+ }
1260
+ return makeOkWith(uid);
1261
+ }
1262
+ async function fetchWorkspace(token, uid) {
1263
+ const responseResult = await requestJson3(WORKSPACE_URL, {
1264
+ method: "POST",
1265
+ headers: {
1266
+ accept: "application/json, text/plain, */*",
1267
+ "content-type": "application/json",
1268
+ cookie: createCookieHeader(token),
1269
+ Referer: "https://xyq.jianying.com/"
1270
+ },
1271
+ body: JSON.stringify({
1272
+ uid
1273
+ })
1274
+ });
1275
+ if (!responseResult.ok) {
1276
+ return responseResult;
1277
+ }
1278
+ const data = responseResult.value;
1279
+ if (String(data?.ret) !== "0") {
1280
+ return workspaceRequestFailedError(data?.errmsg);
1281
+ }
1282
+ const workspaceId = normalizeId(data?.data?.workspace_id);
1283
+ const spaceId = normalizeId(data?.data?.space_id);
1284
+ if (!workspaceId || !spaceId) {
1285
+ return workspaceNotFoundError();
1286
+ }
1287
+ return makeOkWith({
1288
+ uid,
1289
+ workspaceId,
1290
+ spaceId
1291
+ });
1292
+ }
1293
+ async function refreshWebContext(region, token) {
1294
+ if (region !== "cn" /* CN */) {
1295
+ return refreshNotSupportedError();
1296
+ }
1297
+ const normalizedToken = normalizeToken2(token);
1298
+ if (!normalizedToken) {
1299
+ return missingWebTokenError();
1300
+ }
1301
+ const uidResult = await fetchUserId(normalizedToken);
1302
+ if (!uidResult.ok) {
1303
+ return uidResult;
1304
+ }
1305
+ const workspaceResult = await fetchWorkspace(
1306
+ normalizedToken,
1307
+ uidResult.value
1308
+ );
1309
+ if (!workspaceResult.ok) {
1310
+ return workspaceResult;
1311
+ }
1312
+ const writeResult = await writeConfigValue(WEB_NAMESPACE_PATH, {
1313
+ uid: workspaceResult.value.uid,
1314
+ workspace_id: workspaceResult.value.workspaceId,
1315
+ space_id: workspaceResult.value.spaceId
1316
+ });
1317
+ if (!writeResult.ok) {
1318
+ return writeResult;
1319
+ }
1320
+ return workspaceResult;
1321
+ }
1322
+ async function readWebContext(region) {
1323
+ if (region !== "cn" /* CN */) {
1324
+ return refreshNotSupportedError();
1325
+ }
1326
+ const configResult = await readConfigValue(
1327
+ WEB_NAMESPACE_PATH,
1328
+ void 0
1329
+ );
1330
+ if (!configResult.ok) {
1331
+ return configResult;
1332
+ }
1333
+ const webContext = parseWebContext(configResult.value);
1334
+ if (!webContext) {
1335
+ return missingWebContextError();
1336
+ }
1337
+ return makeOkWith(webContext);
1338
+ }
1339
+
1340
+ // src/commands/pippit/modules/asset-upload/errors.ts
1341
+ var BASE4 = 12e3;
1342
+ var AssetUploadError = ((AssetUploadError2) => {
1343
+ AssetUploadError2[AssetUploadError2["MissingFilePath"] = BASE4 + 1] = "MissingFilePath";
1344
+ AssetUploadError2[AssetUploadError2["MissingUploadToken"] = BASE4 + 2] = "MissingUploadToken";
1345
+ AssetUploadError2[AssetUploadError2["UnsupportedAssetType"] = BASE4 + 3] = "UnsupportedAssetType";
1346
+ AssetUploadError2[AssetUploadError2["NetworkRequestFailed"] = BASE4 + 4] = "NetworkRequestFailed";
1347
+ AssetUploadError2[AssetUploadError2["ResponseParseFailed"] = BASE4 + 5] = "ResponseParseFailed";
1348
+ AssetUploadError2[AssetUploadError2["I18nNotSupported"] = BASE4 + 6] = "I18nNotSupported";
1349
+ AssetUploadError2[AssetUploadError2["FileReadFailed"] = BASE4 + 7] = "FileReadFailed";
1350
+ return AssetUploadError2;
1351
+ })(AssetUploadError || {});
1352
+ var missingFilePathError = lvErrorConst(
1353
+ AssetUploadError.MissingFilePath,
1354
+ "\u7F3A\u5C11 file_path \u53C2\u6570\u3002"
1355
+ );
1356
+ var missingUploadTokenError = lvErrorConst(
1357
+ AssetUploadError.MissingUploadToken,
1358
+ "\u7F3A\u5C11\u53EF\u7528\u7684 sessionid_pippitcn_web token\uFF0C\u8BF7\u5148\u4F7F\u7528 `tt pippit web-token --region=cn <token>` \u914D\u7F6E token\u3002\u83B7\u53D6 token \u7684\u56FE\u6587\u8BE6\u60C5\u53C2\u8003 https://cdna-1253404032.cos.ap-beijing.myqcloud.com/img/copy-cookie.png"
1359
+ );
1360
+ var unsupportedAssetTypeError = lvErrorConst(
1361
+ AssetUploadError.UnsupportedAssetType,
1362
+ "\u76EE\u524D\u53EA\u652F\u6301\u56FE\u7247\u3001\u89C6\u9891\u6587\u4EF6\u7C7B\u578B\u3002"
1363
+ );
1364
+ var networkRequestFailedError4 = lvErrorConst(
1365
+ AssetUploadError.NetworkRequestFailed,
1366
+ "\u8BF7\u6C42 pippit \u8D44\u6E90\u4E0A\u4F20 API \u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u548C\u767B\u5F55\u6001\u3002"
1367
+ );
1368
+ var responseParseFailedError3 = lvErrorConst(
1369
+ AssetUploadError.ResponseParseFailed,
1370
+ "\u89E3\u6790 pippit \u8D44\u6E90\u4E0A\u4F20 API \u54CD\u5E94\u5931\u8D25\u3002"
1371
+ );
1372
+ var i18nNotSupportedError = lvErrorConst(
1373
+ AssetUploadError.I18nNotSupported,
1374
+ "i18n \u533A\u57DF\u6682\u4E0D\u652F\u6301 pippit \u8D44\u6E90\u4E0A\u4F20\u3002"
1375
+ );
1376
+ var fileReadFailedError = lvErrorConst(
1377
+ AssetUploadError.FileReadFailed,
1378
+ "\u8BFB\u53D6\u5F85\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25\u3002"
1379
+ );
1380
+
1381
+ // src/commands/pippit/modules/asset-upload/cn-asset-upload.ts
1382
+ var UPLOAD_URL = "https://xyq.jianying.com/api/web/v1/common/upload_file";
1383
+ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
1384
+ ".png",
1385
+ ".jpg",
1386
+ ".jpeg",
1387
+ ".gif",
1388
+ ".webp",
1389
+ ".bmp",
1390
+ ".tif",
1391
+ ".tiff",
1392
+ ".heic",
1393
+ ".heif",
1394
+ ".avif"
1395
+ ]);
1396
+ var VIDEO_EXTENSIONS = /* @__PURE__ */ new Set([
1397
+ ".mp4",
1398
+ ".mov",
1399
+ ".m4v",
1400
+ ".webm",
1401
+ ".avi",
1402
+ ".mkv",
1403
+ ".flv",
1404
+ ".ts",
1405
+ ".wmv",
1406
+ ".mpg",
1407
+ ".mpeg"
1408
+ ]);
1409
+ function normalizeSessionToken(token) {
1410
+ const trimmed = token.trim();
1411
+ const prefix = "sessionid_pippitcn_web=";
1412
+ if (trimmed.startsWith(prefix)) {
1413
+ return trimmed.slice(prefix.length).trim();
1414
+ }
1415
+ return trimmed;
1416
+ }
1417
+ function getCookieHeader(token) {
1418
+ return `sessionid_pippitcn_web=${normalizeSessionToken(token)}`;
1419
+ }
1420
+ function resolveFileInfo(filePath) {
1421
+ const resolvedPath = path4.resolve(process.cwd(), filePath);
1422
+ const fileName = path4.basename(resolvedPath);
1423
+ const ext = path4.extname(fileName).toLowerCase();
1424
+ let assetType;
1425
+ if (IMAGE_EXTENSIONS.has(ext)) {
1426
+ assetType = 2;
1427
+ } else if (VIDEO_EXTENSIONS.has(ext)) {
1428
+ assetType = 1;
1429
+ }
1430
+ if (!assetType) {
1431
+ return void 0;
1432
+ }
1433
+ return {
1434
+ resolvedPath,
1435
+ fileName,
1436
+ assetType
1437
+ };
1438
+ }
1439
+ function makeUploadFailedError(ret, errmsg) {
1440
+ const parsedCode = typeof ret === "number" ? ret : typeof ret === "string" ? Number.parseInt(ret, 10) : Number.NaN;
1441
+ const code = Number.isFinite(parsedCode) ? parsedCode : 1;
1442
+ const message = errmsg?.trim();
1443
+ return makeError(
1444
+ code,
1445
+ message && message.length > 0 ? message : `\u4E0A\u4F20\u5931\u8D25\uFF0C\u8FD4\u56DE\u7801: ${String(ret ?? "unknown")}`
1446
+ );
1447
+ }
1448
+ async function uploadAssetCn(options) {
1449
+ const tokenResult = await readWebToken("cn" /* CN */);
1450
+ if (!tokenResult.ok) {
1451
+ return tokenResult;
1452
+ }
1453
+ const token = tokenResult.value?.trim();
1454
+ if (!token) {
1455
+ return missingUploadTokenError();
1456
+ }
1457
+ const fileInfo = resolveFileInfo(options.filePath);
1458
+ if (!fileInfo) {
1459
+ return unsupportedAssetTypeError();
1460
+ }
1461
+ let fileBytes;
1462
+ try {
1463
+ fileBytes = await fs4.readFile(fileInfo.resolvedPath);
1464
+ } catch (error) {
1465
+ const message = error instanceof Error ? error.message : String(error);
1466
+ return fileReadFailedError(message);
1467
+ }
1468
+ const formData = new FormData();
1469
+ formData.append("file", new Blob([fileBytes]), fileInfo.fileName);
1470
+ formData.append("asset_type", String(fileInfo.assetType));
1471
+ const result = await requestJson(UPLOAD_URL, {
1472
+ method: "POST",
1473
+ headers: {
1474
+ accept: "application/json, text/plain, */*",
1475
+ cookie: getCookieHeader(token),
1476
+ Referer: "https://xyq.jianying.com/"
1477
+ },
1478
+ body: formData
1479
+ }, {
1480
+ networkRequestFailed: (message) => networkRequestFailedError4(message),
1481
+ responseParseFailed: (message) => responseParseFailedError3(message)
1482
+ });
1483
+ if (!result.ok) {
1484
+ return result;
1485
+ }
1486
+ const payload = result.value;
1487
+ const ret = payload?.ret;
1488
+ if (String(ret) !== "0") {
1489
+ return makeUploadFailedError(ret, payload?.errmsg);
1490
+ }
1491
+ const assetId = payload?.data?.asset_id?.trim();
1492
+ if (!assetId) {
1493
+ return makeError(1, "\u4E0A\u4F20\u6210\u529F\uFF0C\u4F46\u672A\u8FD4\u56DE asset_id\u3002");
1494
+ }
1495
+ return makeOkWith({
1496
+ assetId,
1497
+ fileInfo,
1498
+ region: "cn" /* CN */
1499
+ });
1500
+ }
1501
+
1502
+ // src/commands/pippit/modules/asset-upload/i18n-asset-upload.ts
1503
+ async function uploadAssetI18n(_options) {
1504
+ return i18nNotSupportedError();
1505
+ }
1506
+
1507
+ // src/commands/pippit/modules/asset-upload/upload-asset.ts
1508
+ async function uploadAsset(options) {
1509
+ if (options.region === "cn" /* CN */) {
1510
+ return uploadAssetCn(options);
1511
+ }
1512
+ return uploadAssetI18n(options);
1513
+ }
1514
+
1515
+ // src/commands/pippit/pippit-asset-upload-command.ts
1516
+ var PippitAssetUploadCommand = class extends BaseCommand {
1517
+ _meta() {
1518
+ return {
1519
+ name: "asset-upload",
1520
+ description: "\u4E0A\u4F20 pippit \u56FE\u7247\u6216\u89C6\u9891\u8D44\u6E90"
1521
+ };
1522
+ }
1523
+ _configureArguments(cmd) {
1524
+ cmd.argument("<file_path>", "\u8981\u4E0A\u4F20\u7684\u56FE\u7247\u6216\u89C6\u9891\u6587\u4EF6\u8DEF\u5F84");
1525
+ }
1526
+ _configureOptions(cmd) {
1527
+ cmd.addOption(
1528
+ new Option5("-r, --region <region>", "\u6307\u5B9A\u533A\u57DF").choices(["cn" /* CN */, "i18n" /* I18N */]).makeOptionMandatory()
1529
+ );
1530
+ }
1531
+ async _execute(ctx) {
1532
+ const filePath = ctx.args[0];
1533
+ const region = ctx.options.region;
1534
+ if (!filePath) {
1535
+ const error = missingFilePathError();
1536
+ this._outputJsonError(error.code, error.msg);
1537
+ return this._makeOk();
1538
+ }
1539
+ const result = await uploadAsset({ filePath, region });
1540
+ if (!result.ok) {
1541
+ this._outputJsonError(result.code, result.msg);
1542
+ return this._makeOk();
1543
+ }
1544
+ this._outputJsonOk({
1545
+ asset_id: result.value.assetId,
1546
+ file_path: path5.resolve(process.cwd(), filePath),
1547
+ region: result.value.region,
1548
+ asset_type: result.value.fileInfo.assetType
1549
+ });
1550
+ return this._makeOk();
1551
+ }
1552
+ };
1553
+
1554
+ // src/commands/pippit/pippit-web-token-command.ts
1555
+ import { Option as Option6 } from "commander";
1556
+ var PippitWebTokenCommand = class extends BaseCommand {
1557
+ _meta() {
1558
+ return {
1559
+ name: "web-token",
1560
+ description: "\u8BBE\u7F6E pippit web \u7684 token"
1561
+ };
1562
+ }
1563
+ _configureArguments(cmd) {
1564
+ cmd.argument("<token>", "\u8981\u5199\u5165\u7684 pippit web token");
1565
+ }
1566
+ _configureOptions(cmd) {
1567
+ cmd.addOption(
1568
+ new Option6("-r, --region <region>", "token \u6240\u5C5E\u533A\u57DF").choices(["cn", "i18n"]).makeOptionMandatory()
1569
+ );
1570
+ }
1571
+ async _execute(ctx) {
1572
+ const token = ctx.args[0];
1573
+ const { region } = ctx.options;
1574
+ const result = await writeWebToken(region, token);
1575
+ if (!result.ok) {
1576
+ return this._makeError(result.code, result.msg);
1577
+ }
1578
+ if (region === "cn" /* CN */) {
1579
+ const refreshResult = await refreshWebContext(region, token);
1580
+ if (!refreshResult.ok) {
1581
+ return this._makeError(refreshResult.code, refreshResult.msg);
1582
+ }
1583
+ this._outputJsonOk({
1584
+ region,
1585
+ stored: true,
1586
+ refreshed: true,
1587
+ web: {
1588
+ uid: refreshResult.value.uid,
1589
+ workspace_id: refreshResult.value.workspaceId,
1590
+ space_id: refreshResult.value.spaceId
1591
+ }
1592
+ });
1593
+ return this._makeOk();
1594
+ }
1595
+ this._outputJsonOk({
1596
+ region,
1597
+ stored: true,
1598
+ refreshed: false
1599
+ });
1600
+ return this._makeOk();
1601
+ }
1602
+ };
1603
+
1604
+ // src/commands/pippit/pippit-asset-get-command.ts
1605
+ import { Option as Option7 } from "commander";
1606
+
1607
+ // src/commands/pippit/modules/asset-get/errors.ts
1608
+ var BASE5 = 14e3;
1609
+ var AssetGetError = ((AssetGetError2) => {
1610
+ AssetGetError2[AssetGetError2["MissingAssetIds"] = BASE5 + 1] = "MissingAssetIds";
1611
+ AssetGetError2[AssetGetError2["MissingWebContext"] = BASE5 + 2] = "MissingWebContext";
1612
+ AssetGetError2[AssetGetError2["NetworkRequestFailed"] = BASE5 + 3] = "NetworkRequestFailed";
1613
+ AssetGetError2[AssetGetError2["ResponseParseFailed"] = BASE5 + 4] = "ResponseParseFailed";
1614
+ AssetGetError2[AssetGetError2["RequestFailed"] = BASE5 + 5] = "RequestFailed";
1615
+ AssetGetError2[AssetGetError2["I18nNotSupported"] = BASE5 + 6] = "I18nNotSupported";
1616
+ return AssetGetError2;
1617
+ })(AssetGetError || {});
1618
+ var missingAssetIdsError = lvErrorConst(
1619
+ AssetGetError.MissingAssetIds,
1620
+ "\u7F3A\u5C11 asset_id \u53C2\u6570\u3002"
1621
+ );
1622
+ var missingWebContextError2 = lvErrorConst(
1623
+ AssetGetError.MissingWebContext,
1624
+ "\u8BF7\u5148\u914D\u7F6E web-token"
1625
+ );
1626
+ var networkRequestFailedError5 = lvErrorConst(
1627
+ AssetGetError.NetworkRequestFailed,
1628
+ "\u8BF7\u6C42 pippit asset \u63A5\u53E3\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u548C\u767B\u5F55\u6001\u3002"
1629
+ );
1630
+ var responseParseFailedError4 = lvErrorConst(
1631
+ AssetGetError.ResponseParseFailed,
1632
+ "\u89E3\u6790 pippit asset \u63A5\u53E3\u54CD\u5E94\u5931\u8D25\u3002"
1633
+ );
1634
+ var requestFailedError = lvErrorConst(
1635
+ AssetGetError.RequestFailed,
1636
+ "\u83B7\u53D6 asset \u4FE1\u606F\u5931\u8D25\u3002"
1637
+ );
1638
+ var i18nNotSupportedError2 = lvErrorConst(
1639
+ AssetGetError.I18nNotSupported,
1640
+ "i18n \u533A\u57DF\u6682\u4E0D\u652F\u6301 pippit asset \u67E5\u8BE2\u3002"
1641
+ );
1642
+
1643
+ // src/commands/pippit/modules/asset-get/cn-asset-get.ts
1644
+ var QUERY_URL = "https://xyq.jianying.com/api/web/v1/common/mget_asset_info";
1645
+ var ALLOWED_KEYS = /* @__PURE__ */ new Set([
1646
+ "asset_id",
1647
+ "download_url",
1648
+ "duration_ms",
1649
+ "format",
1650
+ "height",
1651
+ "md5",
1652
+ "mime"
1653
+ ]);
1654
+ function normalizeToken3(token) {
1655
+ const trimmed = token.trim();
1656
+ const prefix = "sessionid_pippitcn_web=";
1657
+ if (trimmed.startsWith(prefix)) {
1658
+ return trimmed.slice(prefix.length).trim();
1659
+ }
1660
+ return trimmed;
1661
+ }
1662
+ function createCookieHeader2(token) {
1663
+ return `sessionid_pippitcn_web=${normalizeToken3(token)}`;
1664
+ }
1665
+ function sanitizeAssetItem(item) {
1666
+ if (typeof item !== "object" || item === null || Array.isArray(item)) {
1667
+ return void 0;
1668
+ }
1669
+ const record = item;
1670
+ const assetId = record.asset_id;
1671
+ if (typeof assetId !== "string" || assetId.trim().length === 0) {
1672
+ return void 0;
1673
+ }
1674
+ for (const key of Object.keys(record)) {
1675
+ if (!ALLOWED_KEYS.has(key)) {
1676
+ void Reflect.deleteProperty(record, key);
1677
+ }
1678
+ }
1679
+ record.asset_id = assetId.trim();
1680
+ return record;
1681
+ }
1682
+ function parseAssetList(data) {
1683
+ if (!Array.isArray(data)) {
1684
+ return void 0;
1685
+ }
1686
+ const result = [];
1687
+ for (const item of data) {
1688
+ const sanitized = sanitizeAssetItem(item);
1689
+ if (sanitized) {
1690
+ result.push(sanitized);
1691
+ }
1692
+ }
1693
+ return result;
1694
+ }
1695
+ function parseErrorCode(ret) {
1696
+ const parsed = typeof ret === "number" ? ret : typeof ret === "string" ? Number.parseInt(ret, 10) : Number.NaN;
1697
+ return Number.isFinite(parsed) ? parsed : 1;
1698
+ }
1699
+ async function getAssetInfoCn(options) {
1700
+ const webContextResult = await readWebContext("cn" /* CN */);
1701
+ if (!webContextResult.ok) {
1702
+ return webContextResult;
1703
+ }
1704
+ const tokenResult = await readWebToken("cn" /* CN */);
1705
+ if (!tokenResult.ok) {
1706
+ return tokenResult;
1707
+ }
1708
+ const token = tokenResult.value?.trim();
1709
+ if (!token) {
1710
+ return missingWebContextError2();
1711
+ }
1712
+ const responseResult = await requestJson(
1713
+ QUERY_URL,
1714
+ {
1715
+ method: "POST",
1716
+ headers: {
1717
+ accept: "application/json, text/plain, */*",
1718
+ "content-type": "application/json",
1719
+ cookie: createCookieHeader2(token),
1720
+ Referer: "https://xyq.jianying.com/"
1721
+ },
1722
+ body: JSON.stringify({
1723
+ workspace_id: webContextResult.value.workspaceId,
1724
+ asset_ids: options.assetIds,
1725
+ uid: webContextResult.value.uid,
1726
+ need_transcode: true
1727
+ })
1728
+ },
1729
+ {
1730
+ networkRequestFailed: (message) => networkRequestFailedError5(message),
1731
+ responseParseFailed: (message) => responseParseFailedError4(message)
1732
+ }
1733
+ );
1734
+ if (!responseResult.ok) {
1735
+ return responseResult;
1736
+ }
1737
+ const response = responseResult.value;
1738
+ if (String(response.ret) !== "0") {
1739
+ return makeError(
1740
+ parseErrorCode(response.ret),
1741
+ response.errmsg?.trim() || "\u83B7\u53D6 asset \u4FE1\u606F\u5931\u8D25\u3002"
1742
+ );
1743
+ }
1744
+ const assets = parseAssetList(response.data);
1745
+ if (!assets) {
1746
+ return requestFailedError("\u8FD4\u56DE\u7684 data \u4E0D\u662F\u6570\u7EC4\u3002");
1747
+ }
1748
+ return makeOkWith(assets);
1749
+ }
1750
+
1751
+ // src/commands/pippit/modules/asset-get/i18n-asset-get.ts
1752
+ async function getAssetInfoI18n(_options) {
1753
+ return i18nNotSupportedError2();
1754
+ }
1755
+
1756
+ // src/commands/pippit/modules/asset-get/get-asset.ts
1757
+ async function getAssetInfo(options) {
1758
+ if (options.region === "cn" /* CN */) {
1759
+ return getAssetInfoCn(options);
1760
+ }
1761
+ return getAssetInfoI18n(options);
1762
+ }
1763
+
1764
+ // src/commands/pippit/pippit-asset-get-command.ts
1765
+ var PippitAssetGetCommand = class extends BaseCommand {
1766
+ _meta() {
1767
+ return {
1768
+ name: "asset-get",
1769
+ description: "\u83B7\u53D6 pippit asset \u8BE6\u60C5"
1770
+ };
1771
+ }
1772
+ _configureArguments(cmd) {
1773
+ cmd.argument("<asset_id...>", "\u8981\u67E5\u8BE2\u7684 asset id\uFF0C\u53EF\u4F20\u591A\u4E2A");
1774
+ }
1775
+ _configureOptions(cmd) {
1776
+ cmd.addOption(
1777
+ new Option7("-r, --region <region>", "\u6307\u5B9A\u533A\u57DF").choices(["cn" /* CN */, "i18n" /* I18N */]).makeOptionMandatory()
1778
+ );
1779
+ }
1780
+ async _execute(ctx) {
1781
+ const assetIds = ctx.args[0] ?? [];
1782
+ const region = ctx.options.region;
1783
+ const normalizedAssetIds = assetIds.map((assetId) => assetId.trim()).filter((assetId) => assetId.length > 0);
1784
+ if (normalizedAssetIds.length === 0) {
1785
+ const error = missingAssetIdsError();
1786
+ this._outputJsonError(error.code, error.msg);
1787
+ return this._makeOk();
1788
+ }
1789
+ const result = await getAssetInfo({
1790
+ region,
1791
+ assetIds: normalizedAssetIds
1792
+ });
1793
+ if (!result.ok) {
1794
+ this._outputJsonError(result.code, result.msg);
1795
+ return this._makeOk();
1796
+ }
1797
+ this._outputJsonOk(result.value);
1798
+ return this._makeOk();
1799
+ }
1800
+ };
1801
+
1082
1802
  // src/commands/pippit/pippit-command.ts
1083
1803
  var PippitCommand = class extends BaseSubcommandHost {
1084
1804
  _meta() {
@@ -1093,6 +1813,9 @@ var PippitCommand = class extends BaseSubcommandHost {
1093
1813
  this._addSubcommand(new PippitFornaxTokenCommand());
1094
1814
  this._addSubcommand(new PippitSearchFornaxLogCommand());
1095
1815
  this._addSubcommand(new PippitSaveThreadFornaxCommand());
1816
+ this._addSubcommand(new PippitAssetUploadCommand());
1817
+ this._addSubcommand(new PippitWebTokenCommand());
1818
+ this._addSubcommand(new PippitAssetGetCommand());
1096
1819
  }
1097
1820
  };
1098
1821
 
@@ -1355,9 +2078,9 @@ var ShortcutBaseCommand = class extends BaseCommand {
1355
2078
  stdio: "inherit",
1356
2079
  shell: true
1357
2080
  });
1358
- return new Promise((resolve2) => {
2081
+ return new Promise((resolve4) => {
1359
2082
  child.on("error", (error) => {
1360
- resolve2(
2083
+ resolve4(
1361
2084
  this._makeError(
1362
2085
  1,
1363
2086
  `\u6267\u884C ${cmdLine} \u5931\u8D25: ${error.message}`
@@ -1366,11 +2089,11 @@ var ShortcutBaseCommand = class extends BaseCommand {
1366
2089
  });
1367
2090
  child.on("close", (code, signal) => {
1368
2091
  if (code === 0) {
1369
- resolve2(this._makeOk());
2092
+ resolve4(this._makeOk());
1370
2093
  return;
1371
2094
  }
1372
2095
  const signalText = signal ? `, signal: ${signal}` : "";
1373
- resolve2(
2096
+ resolve4(
1374
2097
  this._makeError(
1375
2098
  code ?? 1,
1376
2099
  `\u6267\u884C ${cmdLine} \u5931\u8D25${signalText}`
@@ -1429,7 +2152,7 @@ var ShortcutCommand = class extends BaseSubcommandHost {
1429
2152
  };
1430
2153
 
1431
2154
  // src/commands/ai/ai-base-command.ts
1432
- import { spawnSync as spawnSync2 } from "child_process";
2155
+ import { spawn as spawn2 } from "child_process";
1433
2156
  var AiBaseCommand = class extends BaseCommand {
1434
2157
  _readPrompt(ctx) {
1435
2158
  const parts = [];
@@ -1443,24 +2166,33 @@ var AiBaseCommand = class extends BaseCommand {
1443
2166
  return parts.join(" ").trim();
1444
2167
  }
1445
2168
  _runCommand(command, args) {
1446
- const result = spawnSync2(command, args, {
2169
+ const child = spawn2(command, args, {
1447
2170
  cwd: process.cwd(),
1448
2171
  stdio: "inherit"
1449
2172
  });
1450
- if (result.error) {
1451
- return this._makeError(
1452
- 1,
1453
- `\u6267\u884C ${command} ${args.join(" ")} \u5931\u8D25: ${result.error.message}`
1454
- );
1455
- }
1456
- if (result.status !== 0) {
1457
- const signalText = result.signal ? `, signal: ${result.signal}` : "";
1458
- return this._makeError(
1459
- result.status ?? 1,
1460
- `\u6267\u884C ${command} ${args.join(" ")} \u5931\u8D25${signalText}`
1461
- );
1462
- }
1463
- return this._makeOk();
2173
+ return new Promise((resolve4) => {
2174
+ child.on("error", (error) => {
2175
+ resolve4(
2176
+ this._makeError(
2177
+ 1,
2178
+ `\u6267\u884C ${command} ${args.join(" ")} \u5931\u8D25: ${error.message}`
2179
+ )
2180
+ );
2181
+ });
2182
+ child.on("close", (code, signal) => {
2183
+ if (code === 0) {
2184
+ resolve4(this._makeOk());
2185
+ return;
2186
+ }
2187
+ const signalText = signal ? `, signal: ${signal}` : "";
2188
+ resolve4(
2189
+ this._makeError(
2190
+ code ?? 1,
2191
+ `\u6267\u884C ${command} ${args.join(" ")} \u5931\u8D25${signalText}`
2192
+ )
2193
+ );
2194
+ });
2195
+ });
1464
2196
  }
1465
2197
  };
1466
2198
 
@@ -1563,6 +2295,9 @@ var AiCodexCommand = class extends AiBaseCommand {
1563
2295
  description: "\u901A\u8FC7 codex exec \u6267\u884C\u63D0\u793A\u8BCD"
1564
2296
  };
1565
2297
  }
2298
+ _configureOptions(cmd) {
2299
+ cmd.option("--mini", "\u4F7F\u7528 gpt-5.4-mini\uFF0C\u5426\u5219\u4F7F\u7528 gpt-5.4", false);
2300
+ }
1566
2301
  _configureArguments(cmd) {
1567
2302
  cmd.argument("[content...]", "\u8981\u4F20\u7ED9 codex \u7684\u5185\u5BB9");
1568
2303
  }
@@ -1571,16 +2306,131 @@ var AiCodexCommand = class extends AiBaseCommand {
1571
2306
  if (!prompt) {
1572
2307
  return this._makeError(1, "\u8BF7\u8F93\u5165\u5185\u5BB9");
1573
2308
  }
2309
+ const model = ctx.options.mini ? "gpt-5.4-mini" : "gpt-5.4";
1574
2310
  return this._runCommand("codex", [
1575
2311
  "exec",
1576
2312
  "-m",
1577
- "gpt-5.4-mini",
2313
+ model,
1578
2314
  "--full-auto",
1579
2315
  prompt
1580
2316
  ]);
1581
2317
  }
1582
2318
  };
1583
2319
 
2320
+ // src/commands/ai/ai-run-command.ts
2321
+ import { homedir as homedir5 } from "os";
2322
+ import { join as join7 } from "path";
2323
+
2324
+ // src/commands/ai/ai-context-path.ts
2325
+ import { existsSync as existsSync2 } from "fs";
2326
+ import { homedir as homedir4 } from "os";
2327
+ import { join as join6 } from "path";
2328
+ function getCurrentCloudRootPath() {
2329
+ if (process.platform !== "darwin") {
2330
+ return makeError(1, "`--my` \u4EC5\u652F\u6301\u5728 macOS \u4E0A\u4F7F\u7528");
2331
+ }
2332
+ const cloudRootPath = join6(
2333
+ homedir4(),
2334
+ "Library",
2335
+ "Mobile Documents",
2336
+ "com~apple~CloudDocs"
2337
+ );
2338
+ if (!existsSync2(cloudRootPath)) {
2339
+ return makeError(1, `\u672A\u627E\u5230 iCloud \u76EE\u5F55: ${cloudRootPath}`);
2340
+ }
2341
+ return makeOkWith(cloudRootPath);
2342
+ }
2343
+ function ensureDirectoryExists(dirPath) {
2344
+ if (!existsSync2(dirPath)) {
2345
+ return makeError(1, `\u672A\u627E\u5230\u76EE\u5F55: ${dirPath}`);
2346
+ }
2347
+ return makeOkWith(dirPath);
2348
+ }
2349
+
2350
+ // src/commands/ai/ai-run-command.ts
2351
+ var AI_RUN_CONTEXT_ALIASES = [
2352
+ {
2353
+ optionName: "my",
2354
+ optionDescription: "\u53C2\u8003 iCloud \u77E5\u8BC6\u5E93\u4E0A\u4E0B\u6587\uFF0C\u4E86\u89E3\u6211\u7684\u4E2A\u4EBA\u4FE1\u606F\u548C\u5DE5\u4F5C\u65E5\u5FD7\u4FE1\u606F",
2355
+ resolveReferenceDir: () => {
2356
+ const cloudRoot = getCurrentCloudRootPath();
2357
+ if (!cloudRoot.ok) {
2358
+ return cloudRoot;
2359
+ }
2360
+ return ensureDirectoryExists(
2361
+ join7(cloudRoot.value, "icloud-hub", "local-knowlege-base")
2362
+ );
2363
+ }
2364
+ },
2365
+ {
2366
+ optionName: "sk",
2367
+ optionDescription: "\u53C2\u8003 ~/work/smart-agent/dymamic-skills \u5B66\u4E60 skill",
2368
+ resolveReferenceDir: () => {
2369
+ return ensureDirectoryExists(
2370
+ join7(homedir5(), "work", "smart-agent", "dynamic-skills")
2371
+ );
2372
+ }
2373
+ }
2374
+ ];
2375
+ var AiRunCommand = class extends AiBaseCommand {
2376
+ _meta() {
2377
+ return {
2378
+ name: "run",
2379
+ description: "\u901A\u8FC7 codex exec \u6267\u884C prompt\uFF0C\u5E76\u53EF\u9644\u5E26\u76EE\u5F55\u4E0A\u4E0B\u6587"
2380
+ };
2381
+ }
2382
+ _configureOptions(cmd) {
2383
+ for (const alias of AI_RUN_CONTEXT_ALIASES) {
2384
+ cmd.option(`--${alias.optionName}`, alias.optionDescription, false);
2385
+ }
2386
+ }
2387
+ _configureArguments(cmd) {
2388
+ cmd.argument("[content...]", "\u8981\u4F20\u7ED9 codex \u7684\u5185\u5BB9");
2389
+ }
2390
+ async _execute(ctx) {
2391
+ const prompt = this._readPrompt(ctx);
2392
+ if (!prompt) {
2393
+ return this._makeError(1, "\u8BF7\u8F93\u5165\u5185\u5BB9");
2394
+ }
2395
+ const enhancedPrompt = this._buildPromptWithContext(ctx.options, prompt);
2396
+ if (!enhancedPrompt.ok) {
2397
+ return enhancedPrompt;
2398
+ }
2399
+ return this._runCommand("codex", [
2400
+ "exec",
2401
+ "-m",
2402
+ "gpt-5.4",
2403
+ "--full-auto",
2404
+ enhancedPrompt.value
2405
+ ]);
2406
+ }
2407
+ _buildPromptWithContext(options, prompt) {
2408
+ const reminders = [];
2409
+ for (const alias of AI_RUN_CONTEXT_ALIASES) {
2410
+ if (!options[alias.optionName]) {
2411
+ continue;
2412
+ }
2413
+ const referenceDir = alias.resolveReferenceDir();
2414
+ if (!referenceDir.ok) {
2415
+ return referenceDir;
2416
+ }
2417
+ reminders.push(this._createSystemReminder(referenceDir.value));
2418
+ }
2419
+ if (reminders.length === 0) {
2420
+ return makeOkWith(prompt);
2421
+ }
2422
+ return makeOkWith([...reminders, prompt].join("\n"));
2423
+ }
2424
+ _createSystemReminder(referenceDir) {
2425
+ return `<system-reminder>
2426
+ \u53C2\u8003 ${referenceDir} \u6587\u4EF6\u5939\u7684\u5185\u5BB9\uFF0C\u6267\u884C\u7528\u6237\u7684\u8981\u6C42\uFF0C\u82E5\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\uFF0C\u4E0D\u8981\u5BF9\u8BE5\u6587\u4EF6\u5939\u7684\u5185\u5BB9\u8FDB\u884C\u4FEE\u6539\uFF0C\u800C\u662F\u67E5\u9605\u91CC\u9762\u7684\u5185\u5BB9\u4F5C\u4E3A\u4E0A\u4E0B\u6587\u8865\u5145\u6BD4\u5982\u4F5C\u4E3A\u4FE1\u606F\u53C2\u8003\uFF0C\u6216\u8005\u6267\u884C\u6307\u5F15\uFF1B
2427
+ \u5982\u679C user_prompt \u91CC\uFF0C\u7ED9\u51FA\u4E00\u4E9B\u6587\u4EF6\u5730\u5740\uFF0C\u9ED8\u8BA4\u662F\u5F53\u524D\u6267\u884C\u547D\u4EE4\u8DEF\u5F84 (cwd) \u4E0B\u7684\u6587\u4EF6\uFF0C\u63D0\u4F9B\u7684\u662F\u672C\u6B21\u8981\u6C42\u7684\u8BE6\u7EC6\u6307\u4EE4\u6216\u8005\u91CD\u8981\u7684\u53C2\u8003\u4FE1\u606F
2428
+ </system-reminder>
2429
+ user_prompt:
2430
+ `;
2431
+ }
2432
+ };
2433
+
1584
2434
  // src/commands/ai/ai-command.ts
1585
2435
  var AiCommand = class extends BaseSubcommandHost {
1586
2436
  _meta() {
@@ -1593,6 +2443,7 @@ var AiCommand = class extends BaseSubcommandHost {
1593
2443
  this._addSubcommand(new AiWebSearchCommand());
1594
2444
  this._addSubcommand(new AiCursorCommand());
1595
2445
  this._addSubcommand(new AiCodexCommand());
2446
+ this._addSubcommand(new AiRunCommand());
1596
2447
  }
1597
2448
  };
1598
2449