@freelog-cli/cli2 0.5.1 → 0.5.2

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/bin/index.js CHANGED
@@ -9168,11 +9168,11 @@ var require_mime_types = __commonJS({
9168
9168
  }
9169
9169
  return exts[0];
9170
9170
  }
9171
- function lookup(path17) {
9172
- if (!path17 || typeof path17 !== "string") {
9171
+ function lookup(path16) {
9172
+ if (!path16 || typeof path16 !== "string") {
9173
9173
  return false;
9174
9174
  }
9175
- var extension2 = extname("x." + path17).toLowerCase().substr(1);
9175
+ var extension2 = extname("x." + path16).toLowerCase().substr(1);
9176
9176
  if (!extension2) {
9177
9177
  return false;
9178
9178
  }
@@ -10287,7 +10287,7 @@ var require_form_data = __commonJS({
10287
10287
  "use strict";
10288
10288
  var CombinedStream = require_combined_stream();
10289
10289
  var util4 = __require("util");
10290
- var path17 = __require("path");
10290
+ var path16 = __require("path");
10291
10291
  var http3 = __require("http");
10292
10292
  var https2 = __require("https");
10293
10293
  var parseUrl2 = __require("url").parse;
@@ -10418,11 +10418,11 @@ var require_form_data = __commonJS({
10418
10418
  FormData3.prototype._getContentDisposition = function(value, options) {
10419
10419
  var filename;
10420
10420
  if (typeof options.filepath === "string") {
10421
- filename = path17.normalize(options.filepath).replace(/\\/g, "/");
10421
+ filename = path16.normalize(options.filepath).replace(/\\/g, "/");
10422
10422
  } else if (options.filename || value && (value.name || value.path)) {
10423
- filename = path17.basename(options.filename || value && (value.name || value.path));
10423
+ filename = path16.basename(options.filename || value && (value.name || value.path));
10424
10424
  } else if (value && value.readable && hasOwn(value, "httpVersion")) {
10425
- filename = path17.basename(value.client._httpMessage.path || "");
10425
+ filename = path16.basename(value.client._httpMessage.path || "");
10426
10426
  }
10427
10427
  if (filename) {
10428
10428
  return 'filename="' + escapeHeaderParam(filename) + '"';
@@ -12550,10 +12550,10 @@ var forEachEntry = (obj, fn) => {
12550
12550
  }
12551
12551
  };
12552
12552
  var matchAll = (regExp, str) => {
12553
- let matches;
12553
+ let matches2;
12554
12554
  const arr = [];
12555
- while ((matches = regExp.exec(str)) !== null) {
12556
- arr.push(matches);
12555
+ while ((matches2 = regExp.exec(str)) !== null) {
12556
+ arr.push(matches2);
12557
12557
  }
12558
12558
  return arr;
12559
12559
  };
@@ -13339,9 +13339,9 @@ function isVisitable(thing) {
13339
13339
  function removeBrackets(key) {
13340
13340
  return utils_default.endsWith(key, "[]") ? key.slice(0, -2) : key;
13341
13341
  }
13342
- function renderKey(path17, key, dots) {
13343
- if (!path17) return key;
13344
- return path17.concat(key).map(function each(token, i) {
13342
+ function renderKey(path16, key, dots) {
13343
+ if (!path16) return key;
13344
+ return path16.concat(key).map(function each(token, i) {
13345
13345
  token = removeBrackets(token);
13346
13346
  return !dots && i ? "[" + token + "]" : token;
13347
13347
  }).join(dots ? "." : "");
@@ -13427,13 +13427,13 @@ function toFormData(obj, formData, options) {
13427
13427
  return currentValue;
13428
13428
  });
13429
13429
  }
13430
- function defaultVisitor(value, key, path17) {
13430
+ function defaultVisitor(value, key, path16) {
13431
13431
  let arr = value;
13432
13432
  if (utils_default.isReactNative(formData) && utils_default.isReactNativeBlob(value)) {
13433
- formData.append(renderKey(path17, key, dots), convertValue(value));
13433
+ formData.append(renderKey(path16, key, dots), convertValue(value));
13434
13434
  return false;
13435
13435
  }
13436
- if (value && !path17 && typeof value === "object") {
13436
+ if (value && !path16 && typeof value === "object") {
13437
13437
  if (utils_default.endsWith(key, "{}")) {
13438
13438
  key = metaTokens ? key : key.slice(0, -2);
13439
13439
  value = stringifyWithDepthLimit(value, 1);
@@ -13452,7 +13452,7 @@ function toFormData(obj, formData, options) {
13452
13452
  if (isVisitable(value)) {
13453
13453
  return true;
13454
13454
  }
13455
- formData.append(renderKey(path17, key, dots), convertValue(value));
13455
+ formData.append(renderKey(path16, key, dots), convertValue(value));
13456
13456
  return false;
13457
13457
  }
13458
13458
  const exposedHelpers = Object.assign(predicates, {
@@ -13460,17 +13460,17 @@ function toFormData(obj, formData, options) {
13460
13460
  convertValue,
13461
13461
  isVisitable
13462
13462
  });
13463
- function build(value, path17, depth = 0) {
13463
+ function build(value, path16, depth = 0) {
13464
13464
  if (utils_default.isUndefined(value)) return;
13465
13465
  throwIfMaxDepthExceeded(depth);
13466
13466
  if (stack.indexOf(value) !== -1) {
13467
- throw new Error("Circular reference detected in " + path17.join("."));
13467
+ throw new Error("Circular reference detected in " + path16.join("."));
13468
13468
  }
13469
13469
  stack.push(value);
13470
13470
  utils_default.forEach(value, function each(el, key) {
13471
- const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key) ? key.trim() : key, path17, exposedHelpers);
13471
+ const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key) ? key.trim() : key, path16, exposedHelpers);
13472
13472
  if (result === true) {
13473
- build(el, path17 ? path17.concat(key) : [key], depth + 1);
13473
+ build(el, path16 ? path16.concat(key) : [key], depth + 1);
13474
13474
  }
13475
13475
  });
13476
13476
  stack.pop();
@@ -13682,7 +13682,7 @@ var platform_default = {
13682
13682
  // ../../node_modules/.pnpm/axios@1.19.0/node_modules/axios/lib/helpers/toURLEncodedForm.js
13683
13683
  function toURLEncodedForm(data, options) {
13684
13684
  return toFormData_default(data, new platform_default.classes.URLSearchParams(), {
13685
- visitor: function(value, key, path17, helpers) {
13685
+ visitor: function(value, key, path16, helpers) {
13686
13686
  if (platform_default.isNode && utils_default.isBuffer(value)) {
13687
13687
  this.append(key, value.toString("base64"));
13688
13688
  return false;
@@ -13704,14 +13704,14 @@ function throwIfDepthExceeded(index) {
13704
13704
  }
13705
13705
  }
13706
13706
  function parsePropPath(name) {
13707
- const path17 = [];
13707
+ const path16 = [];
13708
13708
  const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
13709
13709
  let match;
13710
13710
  while ((match = pattern.exec(name)) !== null) {
13711
- throwIfDepthExceeded(path17.length);
13712
- path17.push(match[0] === "[]" ? "" : match[1] || match[0]);
13711
+ throwIfDepthExceeded(path16.length);
13712
+ path16.push(match[0] === "[]" ? "" : match[1] || match[0]);
13713
13713
  }
13714
- return path17;
13714
+ return path16;
13715
13715
  }
13716
13716
  function arrayToObject(arr) {
13717
13717
  const obj = {};
@@ -13726,12 +13726,12 @@ function arrayToObject(arr) {
13726
13726
  return obj;
13727
13727
  }
13728
13728
  function formDataToJSON(formData) {
13729
- function buildPath(path17, value, target, index) {
13729
+ function buildPath(path16, value, target, index) {
13730
13730
  throwIfDepthExceeded(index);
13731
- let name = path17[index++];
13731
+ let name = path16[index++];
13732
13732
  if (name === "__proto__") return true;
13733
13733
  const isNumericKey = Number.isFinite(+name);
13734
- const isLast = index >= path17.length;
13734
+ const isLast = index >= path16.length;
13735
13735
  name = !name && utils_default.isArray(target) ? target.length : name;
13736
13736
  if (isLast) {
13737
13737
  if (utils_default.hasOwnProp(target, name)) {
@@ -13744,7 +13744,7 @@ function formDataToJSON(formData) {
13744
13744
  if (!utils_default.hasOwnProp(target, name) || !utils_default.isObject(target[name])) {
13745
13745
  target[name] = [];
13746
13746
  }
13747
- const result = buildPath(path17, value, target[name], index);
13747
+ const result = buildPath(path16, value, target[name], index);
13748
13748
  if (result && utils_default.isArray(target[name])) {
13749
13749
  target[name] = arrayToObject(target[name]);
13750
13750
  }
@@ -15462,9 +15462,9 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
15462
15462
  auth = urlUsername + ":" + urlPassword;
15463
15463
  }
15464
15464
  auth && headers.delete("authorization");
15465
- let path17;
15465
+ let path16;
15466
15466
  try {
15467
- path17 = buildURL(
15467
+ path16 = buildURL(
15468
15468
  parsed.pathname + parsed.search,
15469
15469
  own2("params"),
15470
15470
  own2("paramsSerializer")
@@ -15483,7 +15483,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
15483
15483
  false
15484
15484
  );
15485
15485
  const options = Object.assign(/* @__PURE__ */ Object.create(null), {
15486
- path: path17,
15486
+ path: path16,
15487
15487
  method,
15488
15488
  headers: toByteStringHeaderObject(headers),
15489
15489
  agents: { http: httpAgent, https: httpsAgent },
@@ -15885,14 +15885,14 @@ var isURLSameOrigin_default = platform_default.hasStandardBrowserEnv ? /* @__PUR
15885
15885
  var cookies_default = platform_default.hasStandardBrowserEnv ? (
15886
15886
  // Standard browser envs support document.cookie
15887
15887
  {
15888
- write(name, value, expires, path17, domain, secure, sameSite) {
15888
+ write(name, value, expires, path16, domain, secure, sameSite) {
15889
15889
  if (typeof document === "undefined") return;
15890
15890
  const cookie = [`${name}=${encodeURIComponent(value)}`];
15891
15891
  if (utils_default.isNumber(expires)) {
15892
15892
  cookie.push(`expires=${new Date(expires).toUTCString()}`);
15893
15893
  }
15894
- if (utils_default.isString(path17)) {
15895
- cookie.push(`path=${path17}`);
15894
+ if (utils_default.isString(path16)) {
15895
+ cookie.push(`path=${path16}`);
15896
15896
  }
15897
15897
  if (utils_default.isString(domain)) {
15898
15898
  cookie.push(`domain=${domain}`);
@@ -17786,14 +17786,14 @@ function copy(a, s, t2) {
17786
17786
  if (s[m]) t2[m] = s[m];
17787
17787
  });
17788
17788
  }
17789
- function getLastOfPath(object, path17, Empty) {
17789
+ function getLastOfPath(object, path16, Empty) {
17790
17790
  function cleanKey(key2) {
17791
17791
  return key2 && key2.indexOf("###") > -1 ? key2.replace(/###/g, ".") : key2;
17792
17792
  }
17793
17793
  function canNotTraverseDeeper() {
17794
17794
  return !object || typeof object === "string";
17795
17795
  }
17796
- var stack = typeof path17 !== "string" ? [].concat(path17) : path17.split(".");
17796
+ var stack = typeof path16 !== "string" ? [].concat(path16) : path16.split(".");
17797
17797
  while (stack.length > 1) {
17798
17798
  if (canNotTraverseDeeper()) return {};
17799
17799
  var key = cleanKey(stack.shift());
@@ -17810,18 +17810,18 @@ function getLastOfPath(object, path17, Empty) {
17810
17810
  k: cleanKey(stack.shift())
17811
17811
  };
17812
17812
  }
17813
- function setPath(object, path17, newValue) {
17814
- var _getLastOfPath = getLastOfPath(object, path17, Object), obj = _getLastOfPath.obj, k = _getLastOfPath.k;
17813
+ function setPath(object, path16, newValue) {
17814
+ var _getLastOfPath = getLastOfPath(object, path16, Object), obj = _getLastOfPath.obj, k = _getLastOfPath.k;
17815
17815
  obj[k] = newValue;
17816
17816
  }
17817
- function pushPath(object, path17, newValue, concat) {
17818
- var _getLastOfPath2 = getLastOfPath(object, path17, Object), obj = _getLastOfPath2.obj, k = _getLastOfPath2.k;
17817
+ function pushPath(object, path16, newValue, concat) {
17818
+ var _getLastOfPath2 = getLastOfPath(object, path16, Object), obj = _getLastOfPath2.obj, k = _getLastOfPath2.k;
17819
17819
  obj[k] = obj[k] || [];
17820
17820
  if (concat) obj[k] = obj[k].concat(newValue);
17821
17821
  if (!concat) obj[k].push(newValue);
17822
17822
  }
17823
- function getPath(object, path17) {
17824
- var _getLastOfPath3 = getLastOfPath(object, path17), obj = _getLastOfPath3.obj, k = _getLastOfPath3.k;
17823
+ function getPath(object, path16) {
17824
+ var _getLastOfPath3 = getLastOfPath(object, path16), obj = _getLastOfPath3.obj, k = _getLastOfPath3.k;
17825
17825
  if (!obj) return void 0;
17826
17826
  return obj[k];
17827
17827
  }
@@ -17943,11 +17943,11 @@ function _isNativeReflectConstruct() {
17943
17943
  return false;
17944
17944
  }
17945
17945
  }
17946
- function deepFind(obj, path17) {
17946
+ function deepFind(obj, path16) {
17947
17947
  var keySeparator = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : ".";
17948
17948
  if (!obj) return void 0;
17949
- if (obj[path17]) return obj[path17];
17950
- var paths = path17.split(keySeparator);
17949
+ if (obj[path16]) return obj[path16];
17950
+ var paths = path16.split(keySeparator);
17951
17951
  var current = obj;
17952
17952
  for (var i = 0; i < paths.length; ++i) {
17953
17953
  if (!current) return void 0;
@@ -17965,7 +17965,7 @@ function deepFind(obj, path17) {
17965
17965
  }
17966
17966
  if (mix === void 0) return void 0;
17967
17967
  if (mix === null) return null;
17968
- if (path17.endsWith(p)) {
17968
+ if (path16.endsWith(p)) {
17969
17969
  if (typeof mix === "string") return mix;
17970
17970
  if (p && typeof mix[p] === "string") return mix[p];
17971
17971
  }
@@ -18022,13 +18022,13 @@ var ResourceStore = (function(_EventEmitter) {
18022
18022
  var options = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : {};
18023
18023
  var keySeparator = options.keySeparator !== void 0 ? options.keySeparator : this.options.keySeparator;
18024
18024
  var ignoreJSONStructure = options.ignoreJSONStructure !== void 0 ? options.ignoreJSONStructure : this.options.ignoreJSONStructure;
18025
- var path17 = [lng, ns];
18026
- if (key && typeof key !== "string") path17 = path17.concat(key);
18027
- if (key && typeof key === "string") path17 = path17.concat(keySeparator ? key.split(keySeparator) : key);
18025
+ var path16 = [lng, ns];
18026
+ if (key && typeof key !== "string") path16 = path16.concat(key);
18027
+ if (key && typeof key === "string") path16 = path16.concat(keySeparator ? key.split(keySeparator) : key);
18028
18028
  if (lng.indexOf(".") > -1) {
18029
- path17 = lng.split(".");
18029
+ path16 = lng.split(".");
18030
18030
  }
18031
- var result = getPath(this.data, path17);
18031
+ var result = getPath(this.data, path16);
18032
18032
  if (result || !ignoreJSONStructure || typeof key !== "string") return result;
18033
18033
  return deepFind(this.data && this.data[lng] && this.data[lng][ns], key, keySeparator);
18034
18034
  }
@@ -18040,15 +18040,15 @@ var ResourceStore = (function(_EventEmitter) {
18040
18040
  };
18041
18041
  var keySeparator = this.options.keySeparator;
18042
18042
  if (keySeparator === void 0) keySeparator = ".";
18043
- var path17 = [lng, ns];
18044
- if (key) path17 = path17.concat(keySeparator ? key.split(keySeparator) : key);
18043
+ var path16 = [lng, ns];
18044
+ if (key) path16 = path16.concat(keySeparator ? key.split(keySeparator) : key);
18045
18045
  if (lng.indexOf(".") > -1) {
18046
- path17 = lng.split(".");
18046
+ path16 = lng.split(".");
18047
18047
  value = ns;
18048
- ns = path17[1];
18048
+ ns = path16[1];
18049
18049
  }
18050
18050
  this.addNamespaces(ns);
18051
- setPath(this.data, path17, value);
18051
+ setPath(this.data, path16, value);
18052
18052
  if (!options.silent) this.emit("added", lng, ns, key, value);
18053
18053
  }
18054
18054
  }, {
@@ -18070,21 +18070,21 @@ var ResourceStore = (function(_EventEmitter) {
18070
18070
  var options = arguments.length > 5 && arguments[5] !== void 0 ? arguments[5] : {
18071
18071
  silent: false
18072
18072
  };
18073
- var path17 = [lng, ns];
18073
+ var path16 = [lng, ns];
18074
18074
  if (lng.indexOf(".") > -1) {
18075
- path17 = lng.split(".");
18075
+ path16 = lng.split(".");
18076
18076
  deep = resources;
18077
18077
  resources = ns;
18078
- ns = path17[1];
18078
+ ns = path16[1];
18079
18079
  }
18080
18080
  this.addNamespaces(ns);
18081
- var pack = getPath(this.data, path17) || {};
18081
+ var pack = getPath(this.data, path16) || {};
18082
18082
  if (deep) {
18083
18083
  deepExtend(pack, resources, overwrite);
18084
18084
  } else {
18085
18085
  pack = _objectSpread$1(_objectSpread$1({}, pack), resources);
18086
18086
  }
18087
- setPath(this.data, path17, pack);
18087
+ setPath(this.data, path16, pack);
18088
18088
  if (!options.silent) this.emit("added", lng, ns, resources);
18089
18089
  }
18090
18090
  }, {
@@ -19078,10 +19078,10 @@ var Interpolator = (function() {
19078
19078
  }
19079
19079
  var handleFormat = function handleFormat2(key) {
19080
19080
  if (key.indexOf(_this.formatSeparator) < 0) {
19081
- var path17 = getPathWithDefaults(data, defaultData, key);
19082
- return _this.alwaysFormat ? _this.format(path17, void 0, lng, _objectSpread$3(_objectSpread$3(_objectSpread$3({}, options), data), {}, {
19081
+ var path16 = getPathWithDefaults(data, defaultData, key);
19082
+ return _this.alwaysFormat ? _this.format(path16, void 0, lng, _objectSpread$3(_objectSpread$3(_objectSpread$3({}, options), data), {}, {
19083
19083
  interpolationkey: key
19084
- })) : path17;
19084
+ })) : path16;
19085
19085
  }
19086
19086
  var p = key.split(_this.formatSeparator);
19087
19087
  var k = p.shift().trim();
@@ -23954,10 +23954,10 @@ function bootstrapPlatform() {
23954
23954
  }
23955
23955
 
23956
23956
  // src/bin/program.ts
23957
- import { Command as Command28, CommanderError } from "commander";
23957
+ import { Command as Command29, CommanderError } from "commander";
23958
23958
 
23959
23959
  // src/commands/index.ts
23960
- import { Command as Command27 } from "commander";
23960
+ import { Command as Command28 } from "commander";
23961
23961
 
23962
23962
  // src/core/cliArgs.ts
23963
23963
  import { Command } from "commander";
@@ -23985,7 +23985,7 @@ function addSharedOptions(command) {
23985
23985
  "--json",
23986
23986
  // i18n: cli.flag.json
23987
23987
  "\u4EE5 JSON \u8F93\u51FA"
23988
- );
23988
+ ).option("--resource <selector>", "\u9009\u62E9\u672C\u5730\u8D44\u6E90\u72B6\u6001\uFF08N.json\u3001\u8D44\u6E90 ID\u3001\u6807\u8BC6\u7B26\u6216\u6807\u9898\uFF09");
23989
23989
  }
23990
23990
  function readSharedOptions(command) {
23991
23991
  const raw = command.optsWithGlobals();
@@ -23993,7 +23993,8 @@ function readSharedOptions(command) {
23993
23993
  ...typeof raw.env === "string" ? { env: raw.env } : {},
23994
23994
  ...typeof raw.yes === "boolean" ? { yes: raw.yes } : {},
23995
23995
  ...typeof raw.cwd === "string" ? { cwd: raw.cwd } : {},
23996
- ...typeof raw.json === "boolean" ? { json: raw.json } : {}
23996
+ ...typeof raw.json === "boolean" ? { json: raw.json } : {},
23997
+ ...typeof raw.resource === "string" ? { file: raw.resource } : {}
23997
23998
  };
23998
23999
  }
23999
24000
  function addLeafSubcommand(parent, name, description) {
@@ -24246,9 +24247,6 @@ function createLogoutCommand() {
24246
24247
  // src/commands/create/create.ts
24247
24248
  import { Command as Command4 } from "commander";
24248
24249
 
24249
- // src/domain/create/create.ts
24250
- import path8 from "path";
24251
-
24252
24250
  // src/local/identity.ts
24253
24251
  import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync4 } from "fs";
24254
24252
  import path6 from "path";
@@ -24456,6 +24454,7 @@ var inputFields = {
24456
24454
  subject: z2.literal("resource"),
24457
24455
  resourceId: z2.string().min(1).optional(),
24458
24456
  name: z2.string().min(1).optional(),
24457
+ title: z2.string().min(1).optional(),
24459
24458
  typeCode: z2.string().min(1),
24460
24459
  filePath: z2.string().min(1).optional(),
24461
24460
  env: z2.enum(["prod", "test", "dev"]).optional()
@@ -24468,7 +24467,8 @@ var storedSchema = z2.object({
24468
24467
  }).strict().superRefine((identity, ctx) => {
24469
24468
  const hasResourceId = identity.resourceId !== void 0;
24470
24469
  const hasName = identity.name !== void 0;
24471
- const bound = hasResourceId || hasName;
24470
+ const hasTitle = identity.title !== void 0;
24471
+ const bound = hasResourceId || hasName || hasTitle;
24472
24472
  if (hasResourceId !== hasName) {
24473
24473
  ctx.addIssue({
24474
24474
  code: ZodIssueCode.custom,
@@ -24476,6 +24476,9 @@ var storedSchema = z2.object({
24476
24476
  message: "\u7ED1\u5B9A\u8EAB\u4EFD\u5FC5\u987B\u540C\u65F6\u5305\u542B resourceId \u548C name"
24477
24477
  });
24478
24478
  }
24479
+ if (!hasResourceId && !hasName && hasTitle) {
24480
+ ctx.addIssue({ code: ZodIssueCode.custom, path: ["title"], message: "\u672A\u7ED1\u5B9A\u8EAB\u4EFD\u4E0D\u80FD\u5199\u5165 title" });
24481
+ }
24479
24482
  if (!bound && identity.env !== void 0) {
24480
24483
  ctx.addIssue({
24481
24484
  code: ZodIssueCode.custom,
@@ -24510,8 +24513,8 @@ function throwZodAsCliError(error2) {
24510
24513
  if (field === "subject") {
24511
24514
  throw new CliError("\u672C\u671F\u53EA\u652F\u6301\u5355\u8D44\u6E90", "IDENTITY_SUBJECT_UNSUPPORTED");
24512
24515
  }
24513
- if (field === "name" || field === "resourceId") {
24514
- throw new CliError("\u7ED1\u5B9A\u8EAB\u4EFD\u5FC5\u987B\u540C\u65F6\u5305\u542B resourceId \u548C name", "IDENTITY_BINDING_INVALID");
24516
+ if (field === "name" || field === "resourceId" || field === "title") {
24517
+ throw new CliError("\u7ED1\u5B9A\u8EAB\u4EFD\u5B57\u6BB5\u4E0D\u5B8C\u6574", "IDENTITY_BINDING_INVALID");
24515
24518
  }
24516
24519
  throw new CliError("\u8EAB\u4EFD\u5B57\u6BB5\u65E0\u6548", "IDENTITY_INVALID");
24517
24520
  }
@@ -24521,6 +24524,7 @@ function toStored(data) {
24521
24524
  subject: data.subject,
24522
24525
  ...data.resourceId ? { resourceId: data.resourceId } : {},
24523
24526
  ...data.name ? { name: data.name } : {},
24527
+ ...data.title ? { title: data.title } : {},
24524
24528
  typeCode: data.typeCode,
24525
24529
  ...data.filePath ? { filePath: data.filePath } : {},
24526
24530
  ...data.env === "test" || data.env === "dev" ? { env: data.env } : {}
@@ -24539,6 +24543,7 @@ function toDiskObject(identity) {
24539
24543
  subject: identity.subject,
24540
24544
  ...identity.resourceId ? { resourceId: identity.resourceId } : {},
24541
24545
  ...identity.name ? { name: identity.name } : {},
24546
+ ...identity.title ? { title: identity.title } : {},
24542
24547
  typeCode: identity.typeCode,
24543
24548
  ...identity.filePath ? { filePath: identity.filePath } : {},
24544
24549
  ...identity.env ? { env: identity.env } : {}
@@ -24565,6 +24570,7 @@ function prepareIdentityUpdate(cwd, n, patch) {
24565
24570
  subject: parsed.subject ?? current.subject,
24566
24571
  resourceId: parsed.resourceId ?? current.resourceId,
24567
24572
  name: parsed.name ?? current.name,
24573
+ title: parsed.title ?? current.title,
24568
24574
  typeCode: parsed.typeCode ?? current.typeCode,
24569
24575
  filePath: parsed.filePath ?? current.filePath,
24570
24576
  env: parsed.env ?? current.env
@@ -24572,10 +24578,8 @@ function prepareIdentityUpdate(cwd, n, patch) {
24572
24578
  return { n, ...identity };
24573
24579
  }
24574
24580
  function prepareIdentityCreate(cwd, input2) {
24575
- if (listIdentityNumbers(cwd).length > 0) {
24576
- throw new CliError("\u4E00\u4E2A\u5DE5\u7A0B\u53EA\u80FD\u7BA1\u7406\u4E00\u4E2A\u8D44\u6E90\uFF1B\u8BF7\u4F7F\u7528\u72EC\u7ACB\u5DE5\u7A0B\u76EE\u5F55", "IDENTITY_SINGLE_RESOURCE");
24577
- }
24578
- return { n: 1, ...parseCreateInput(input2) };
24581
+ const numbers = listIdentityNumbers(cwd);
24582
+ return { n: numbers.length === 0 ? 1 : Math.max(...numbers) + 1, ...parseCreateInput(input2) };
24579
24583
  }
24580
24584
  function parsePatchInput(input2) {
24581
24585
  const parsed = patchSchema.safeParse(input2);
@@ -24633,6 +24637,186 @@ function updateIdentity(cwd, n, patch) {
24633
24637
  }, "update-identity");
24634
24638
  }
24635
24639
 
24640
+ // src/local/resolve.ts
24641
+ import { existsSync as existsSync7, readdirSync as readdirSync2 } from "fs";
24642
+
24643
+ // src/local/draft.ts
24644
+ import { existsSync as existsSync6, readFileSync as readFileSync5, unlinkSync as unlinkSync4 } from "fs";
24645
+ import path7 from "path";
24646
+ import { z as z3 } from "zod";
24647
+ var itemList = z3.array(z3.record(z3.unknown()));
24648
+ var draftSchema = z3.object({
24649
+ schemaVersion: z3.literal(1),
24650
+ draftKind: z3.enum(["initial", "update"]),
24651
+ resourceId: z3.string().min(1),
24652
+ resourceTypeCode: z3.string().min(1),
24653
+ fromVersion: z3.string().min(1).optional(),
24654
+ fileSha1: z3.string().min(1).nullable(),
24655
+ filename: z3.string().min(1).nullable(),
24656
+ analyzedSha1: z3.string().min(1).nullable(),
24657
+ description: z3.string(),
24658
+ inputAttrs: itemList,
24659
+ orphanedInputAttrs: itemList,
24660
+ customPropertyDescriptors: itemList,
24661
+ dependencies: itemList,
24662
+ baseUpcastResources: z3.array(z3.never()),
24663
+ authExcludedItems: z3.array(z3.never())
24664
+ }).strict().superRefine((draft, ctx) => {
24665
+ if (draft.draftKind === "initial" && (draft.fromVersion || draft.description !== "")) {
24666
+ ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "initial \u5DE5\u4F5C\u7A3F\u4E0D\u80FD\u6709\u6765\u6E90\u7248\u672C\u6216\u63CF\u8FF0" });
24667
+ }
24668
+ if (draft.draftKind === "update" && !draft.fromVersion) {
24669
+ ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "update \u5DE5\u4F5C\u7A3F\u5FC5\u987B\u6709\u6765\u6E90\u7248\u672C" });
24670
+ }
24671
+ if (draft.analyzedSha1 !== null && draft.analyzedSha1 !== draft.fileSha1) {
24672
+ ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "analyzedSha1 \u5FC5\u987B\u7B49\u4E8E fileSha1" });
24673
+ }
24674
+ if (draft.fileSha1 === null && (draft.filename !== null || draft.analyzedSha1 !== null)) {
24675
+ ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "\u65E0\u6587\u4EF6\u65F6\u4E0D\u80FD\u4FDD\u7559\u6587\u4EF6\u540D\u6216\u5206\u6790 SHA" });
24676
+ }
24677
+ });
24678
+ function draftFilePath(cwd, n) {
24679
+ return path7.join(freelogDir(cwd), `${n}.version.json`);
24680
+ }
24681
+ function emptyDraft() {
24682
+ return { baseUpcastResources: [], authExcludedItems: [] };
24683
+ }
24684
+ function prepareDraft(cwd, n, input2) {
24685
+ const identity = readIdentity(cwd, n);
24686
+ if (!identity.resourceId) {
24687
+ throw new CliError("\u8BF7\u5148 create \u6216 bind\uFF0C\u518D\u7F16\u8F91\u7248\u672C\u5DE5\u4F5C\u7A3F", "DRAFT_IDENTITY_UNBOUND");
24688
+ }
24689
+ if (input2.resourceId !== void 0 && input2.resourceId !== identity.resourceId) {
24690
+ throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u4E0E\u8EAB\u4EFD\u4E0D\u4E00\u81F4`, "DRAFT_IDENTITY_MISMATCH");
24691
+ }
24692
+ if (input2.resourceTypeCode !== void 0 && input2.resourceTypeCode !== identity.typeCode) {
24693
+ throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u4E0E\u8EAB\u4EFD\u4E0D\u4E00\u81F4`, "DRAFT_IDENTITY_MISMATCH");
24694
+ }
24695
+ const draftKind = input2.draftKind ?? (input2.fromVersion ? "update" : "initial");
24696
+ const fileSha1 = input2.fileSha1 ?? null;
24697
+ const value = {
24698
+ schemaVersion: 1,
24699
+ draftKind,
24700
+ resourceId: identity.resourceId,
24701
+ resourceTypeCode: input2.resourceTypeCode ?? identity.typeCode,
24702
+ ...draftKind === "update" ? { fromVersion: input2.fromVersion } : {},
24703
+ fileSha1,
24704
+ filename: fileSha1 ? input2.filename ?? null : null,
24705
+ analyzedSha1: fileSha1 ? input2.analyzedSha1 ?? null : null,
24706
+ description: draftKind === "initial" ? "" : input2.description ?? "",
24707
+ inputAttrs: input2.inputAttrs ?? [],
24708
+ orphanedInputAttrs: input2.orphanedInputAttrs ?? [],
24709
+ customPropertyDescriptors: input2.customPropertyDescriptors ?? [],
24710
+ dependencies: input2.dependencies ?? [],
24711
+ baseUpcastResources: [],
24712
+ authExcludedItems: []
24713
+ };
24714
+ const parsed = draftSchema.safeParse(value);
24715
+ if (!parsed.success) throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u65E0\u6548`, "DRAFT_INVALID");
24716
+ return parsed.data;
24717
+ }
24718
+ function serializeDraft(draft) {
24719
+ return `${JSON.stringify(draft, null, 2)}
24720
+ `;
24721
+ }
24722
+ function readDraft(cwd, n) {
24723
+ const filePath = draftFilePath(cwd, n);
24724
+ if (!existsSync6(filePath)) return void 0;
24725
+ let raw;
24726
+ try {
24727
+ raw = JSON.parse(readFileSync5(filePath, "utf8"));
24728
+ } catch {
24729
+ throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u65E0\u6CD5\u89E3\u6790`, "DRAFT_INVALID");
24730
+ }
24731
+ const parsed = draftSchema.safeParse(raw);
24732
+ if (!parsed.success) throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u65E0\u6548\uFF1B\u4EC5\u652F\u6301 schemaVersion=1`, "DRAFT_INVALID");
24733
+ const identity = readIdentity(cwd, n);
24734
+ if (!identity.resourceId || parsed.data.resourceId !== identity.resourceId || parsed.data.resourceTypeCode !== identity.typeCode) {
24735
+ throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u4E0E\u8EAB\u4EFD\u4E0D\u4E00\u81F4`, "DRAFT_IDENTITY_MISMATCH");
24736
+ }
24737
+ return parsed.data;
24738
+ }
24739
+ function writeDraft(cwd, n, draft) {
24740
+ return withProjectLock(cwd, () => {
24741
+ const normalized = prepareDraft(cwd, n, draft);
24742
+ atomicWriteFile(draftFilePath(cwd, n), serializeDraft(normalized));
24743
+ return normalized;
24744
+ }, "write-version-draft");
24745
+ }
24746
+ function deleteDraft(cwd, n) {
24747
+ return withProjectLock(cwd, () => {
24748
+ const filePath = draftFilePath(cwd, n);
24749
+ if (!existsSync6(filePath)) return false;
24750
+ unlinkSync4(filePath);
24751
+ return true;
24752
+ }, "delete-version-draft");
24753
+ }
24754
+ function draftSummary(draft) {
24755
+ const source = draft.draftKind === "update" ? draft.fromVersion ?? "\u66F4\u65B0" : "\u9996\u7248";
24756
+ const sha1 = draft.fileSha1 ? `${draft.fileSha1.slice(0, 8)}\u2026` : "\u65E0";
24757
+ return ["\u5C06\u8986\u76D6\u672C\u5730\u5DE5\u4F5C\u7A3F\uFF1A", ` \u6765\u6E90\uFF1A${source}`, ` \u6587\u4EF6\uFF1A${draft.filename ?? "\u65E0"} sha1=${sha1}`, ` \u5C5E\u6027 ${(draft.customPropertyDescriptors ?? []).length} / \u4F9D\u8D56 ${(draft.dependencies ?? []).length}`].join("\n");
24758
+ }
24759
+
24760
+ // src/local/resolve.ts
24761
+ function assertNoDuplicate(identities, key) {
24762
+ const seen = /* @__PURE__ */ new Map();
24763
+ for (const identity of identities) {
24764
+ const value = identity[key];
24765
+ if (!value) continue;
24766
+ const previous = seen.get(value);
24767
+ if (previous !== void 0) {
24768
+ throw new CliError(`\u672C\u5730\u72B6\u6001\u51B2\u7A81\uFF1A${previous}.json \u4E0E ${identity.n}.json \u4F7F\u7528\u540C\u4E00 ${key}`, "IDENTITY_CONFLICT");
24769
+ }
24770
+ seen.set(value, identity.n);
24771
+ }
24772
+ }
24773
+ function matches(identity, selector) {
24774
+ if (selector.startsWith("file:")) return `${identity.n}.json` === selector.slice(5);
24775
+ if (selector.startsWith("id:")) return identity.resourceId === selector.slice(3);
24776
+ if (selector.startsWith("name:")) return identity.name === selector.slice(5) || identity.name === selector.slice(5).split("/").pop();
24777
+ if (selector.startsWith("title:")) return identity.title === selector.slice(6);
24778
+ return `${identity.n}.json` === selector || identity.resourceId === selector || identity.name === selector || identity.title === selector;
24779
+ }
24780
+ var DRAFT_FILE_RE = /^([1-9]\d*)\.version\.json$/;
24781
+ function validateLocalState(cwd) {
24782
+ const identities = listIdentities(cwd);
24783
+ assertNoDuplicate(identities, "resourceId");
24784
+ assertNoDuplicate(identities, "name");
24785
+ assertNoDuplicate(identities, "filePath");
24786
+ const numbers = new Set(identities.map((identity) => identity.n));
24787
+ const dir = freelogDir(cwd);
24788
+ if (!existsSync7(dir)) return identities;
24789
+ for (const fileName of readdirSync2(dir)) {
24790
+ const match = DRAFT_FILE_RE.exec(fileName);
24791
+ if (!match) continue;
24792
+ const n = Number(match[1]);
24793
+ if (!numbers.has(n)) {
24794
+ throw new CliError(`\u5DE5\u4F5C\u7A3F ${fileName} \u6CA1\u6709\u540C\u53F7\u8EAB\u4EFD\u6587\u4EF6`, "DRAFT_ORPHAN");
24795
+ }
24796
+ readDraft(cwd, n);
24797
+ }
24798
+ return identities;
24799
+ }
24800
+ function resolveIdentity(cwd, selector) {
24801
+ const identities = validateLocalState(cwd);
24802
+ if (identities.length === 0) {
24803
+ throw new CliError(
24804
+ "\u5F53\u524D\u76EE\u5F55\u6CA1\u6709\u8D44\u6E90\u72B6\u6001\u3002\u65B0\u8D44\u6E90\u8BF7\u5148 init \u540E create\uFF1B\u5DF2\u6709\u8D44\u6E90\u8BF7 bind <\u8D44\u6E90 ID|\u6807\u8BC6\u7B26> --artifact <\u8DEF\u5F84>\u3002",
24805
+ "IDENTITY_NOT_FOUND"
24806
+ );
24807
+ }
24808
+ if (!selector) {
24809
+ if (identities.length === 1) return identities[0];
24810
+ throw new CliError("\u5F53\u524D\u5DE5\u7A0B\u6709\u591A\u4EFD\u8D44\u6E90\u72B6\u6001\uFF1B\u8BF7\u4F7F\u7528 --resource \u6307\u5B9A\u8D44\u6E90", "IDENTITY_RESOURCE_REQUIRED");
24811
+ }
24812
+ const matched = identities.filter((identity) => matches(identity, selector));
24813
+ if (matched.length === 1) return matched[0];
24814
+ if (matched.length === 0) {
24815
+ throw new CliError(`\u627E\u4E0D\u5230\u8D44\u6E90\u9009\u62E9\u5668 ${selector}`, "IDENTITY_RESOURCE_NOT_FOUND");
24816
+ }
24817
+ throw new CliError(`\u8D44\u6E90\u9009\u62E9\u5668 ${selector} \u5339\u914D\u591A\u4EFD\u72B6\u6001\uFF1B\u8BF7\u4F7F\u7528 file:\u3001id: \u6216 name:`, "IDENTITY_RESOURCE_AMBIGUOUS");
24818
+ }
24819
+
24636
24820
  // src/core/tty.ts
24637
24821
  import { confirm as inquirerConfirm, input as inquirerInput, select as inquirerSelect } from "@inquirer/prompts";
24638
24822
  function isInteractive() {
@@ -24646,7 +24830,7 @@ async function confirmQuestion(message, defaultYes = true) {
24646
24830
  }
24647
24831
  async function askInput2(message) {
24648
24832
  if (!isInteractive()) {
24649
- throw new CliError("\u8BF7\u63D0\u4F9B --file \u6216 --yes", "TTY_REQUIRED");
24833
+ throw new CliError("\u975E\u4EA4\u4E92\u6A21\u5F0F\u8BF7\u663E\u5F0F\u63D0\u4F9B\u5FC5\u9700\u53C2\u6570", "TTY_REQUIRED");
24650
24834
  }
24651
24835
  return inquirerInput({ message });
24652
24836
  }
@@ -24806,19 +24990,19 @@ function formatTypeList(items) {
24806
24990
  }
24807
24991
 
24808
24992
  // src/local/projectPath.ts
24809
- import path7 from "path";
24993
+ import path8 from "path";
24810
24994
  var defaultError = {
24811
24995
  code: "FILE_PATH_OUTSIDE_PROJECT",
24812
24996
  message: "\u8DEF\u5F84\u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
24813
24997
  };
24814
24998
  function normalizeProjectPath(cwd, rawPath, error2 = defaultError) {
24815
- if (!rawPath.trim() || path7.isAbsolute(rawPath) || path7.win32.isAbsolute(rawPath) || path7.posix.isAbsolute(rawPath)) {
24999
+ if (!rawPath.trim() || path8.isAbsolute(rawPath) || path8.win32.isAbsolute(rawPath) || path8.posix.isAbsolute(rawPath)) {
24816
25000
  throw new CliError(error2.message, error2.code);
24817
25001
  }
24818
- const root = path7.resolve(cwd);
24819
- const resolved = path7.resolve(root, rawPath);
24820
- const relative = path7.relative(root, resolved);
24821
- if (!relative || relative.startsWith("..") || path7.isAbsolute(relative)) {
25002
+ const root = path8.resolve(cwd);
25003
+ const resolved = path8.resolve(root, rawPath);
25004
+ const relative = path8.relative(root, resolved);
25005
+ if (!relative || relative.startsWith("..") || path8.isAbsolute(relative)) {
24822
25006
  throw new CliError(error2.message, error2.code);
24823
25007
  }
24824
25008
  return relative.replaceAll("\\", "/");
@@ -24881,48 +25065,11 @@ function validateCreateFlags(input2) {
24881
25065
  }
24882
25066
  return { title, name };
24883
25067
  }
24884
- async function resolveTargetByFile(input2) {
24885
- const resolvedFile = path8.resolve(input2.cwd, input2.file);
24886
- const occupant = input2.identities.find(
24887
- (item) => item.filePath !== void 0 && path8.resolve(input2.cwd, item.filePath) === resolvedFile
24888
- );
24889
- if (!occupant || !occupant.resourceId) {
24890
- return occupant;
24891
- }
24892
- const infoApi2 = input2.infoApi ?? ((params) => service_API_default.Resource.info(params));
24893
- const existing = await lookupResource(infoApi2, {
24894
- resourceIdOrName: occupant.resourceId,
24895
- isLoadLatestVersionInfo: 1
24896
- });
24897
- if (existing.latestVersion) {
24898
- throw new CliError(
24899
- `\u6587\u4EF6 ${input2.file} \u5DF2\u5BF9\u5E94 ${occupant.name}\u3002\u4E0D\u8981\u518D create\u3002`,
24900
- "CREATE_FILE_OCCUPIED"
24901
- );
24902
- }
24903
- throw new CliError(
24904
- `\u6587\u4EF6 ${input2.file} \u5DF2\u5BF9\u5E94 ${occupant.name}\uFF0C\u4E14\u8FD8\u6CA1\u6709\u53D1\u884C\u7248\u672C\u3002\u8BF7\u5BF9\u8BE5\u8D44\u6E90 create-version\u3002`,
24905
- "CREATE_FILE_OCCUPIED"
24906
- );
24907
- }
24908
- async function resolveTargetIdentity(input2) {
24909
- if (input2.file) {
24910
- const byFile = await resolveTargetByFile({
24911
- cwd: input2.cwd,
24912
- file: input2.file,
24913
- identities: input2.identities,
24914
- infoApi: input2.infoApi
24915
- });
24916
- if (byFile) {
24917
- return byFile;
24918
- }
24919
- if (input2.identities.length > 1) {
24920
- throw new CliError("\u4E00\u5939\u591A\u6761\u5FC5\u987B\u6307\u5B9A\u5DF2\u767B\u8BB0\u7684 --file", "IDENTITY_FILE_REQUIRED");
24921
- }
24922
- }
24923
- if (input2.identities.length === 1) {
24924
- return input2.identities[0];
24925
- }
25068
+ function resolveTargetIdentity(input2) {
25069
+ if (input2.selector) return resolveIdentity(input2.cwd, input2.selector);
25070
+ const unbound = input2.identities.filter((identity) => !identity.resourceId);
25071
+ if (unbound.length === 1) return unbound[0];
25072
+ if (unbound.length > 1) throw new CliError("\u5F53\u524D\u5DE5\u7A0B\u6709\u591A\u4EFD\u672A\u7ED1\u5B9A\u8D44\u6E90\u72B6\u6001\uFF1B\u8BF7\u4F7F\u7528 --resource \u6307\u5B9A\u8D44\u6E90", "IDENTITY_RESOURCE_REQUIRED");
24926
25073
  return void 0;
24927
25074
  }
24928
25075
  async function assertOwnShellAvailable(input2) {
@@ -24950,6 +25097,7 @@ function writeCreatedIdentity(input2) {
24950
25097
  const patch = {
24951
25098
  resourceId: input2.resourceId,
24952
25099
  name: input2.name,
25100
+ title: input2.title,
24953
25101
  typeCode: input2.typeCode,
24954
25102
  ...filePath ? { filePath } : {},
24955
25103
  env: input2.env
@@ -24958,6 +25106,7 @@ function writeCreatedIdentity(input2) {
24958
25106
  subject: "resource",
24959
25107
  resourceId: input2.resourceId,
24960
25108
  name: input2.name,
25109
+ title: input2.title,
24961
25110
  typeCode: input2.typeCode,
24962
25111
  ...filePath ? { filePath } : {},
24963
25112
  env: input2.env
@@ -24966,19 +25115,23 @@ function writeCreatedIdentity(input2) {
24966
25115
  async function createResource(input2) {
24967
25116
  assertPlatformAllowed();
24968
25117
  const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
25118
+ validateLocalState(input2.cwd);
24969
25119
  const { title, name } = validateCreateFlags(input2);
24970
25120
  const file = input2.file !== void 0 ? normalizeProjectPath(input2.cwd, input2.file, {
24971
25121
  code: "CREATE_FILE_OUTSIDE",
24972
25122
  message: "--artifact \u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
24973
25123
  }) : void 0;
24974
25124
  return withProjectLock(input2.cwd, async () => {
24975
- const identities = listIdentities(input2.cwd);
24976
- const target = await resolveTargetIdentity({
25125
+ const identities = validateLocalState(input2.cwd);
25126
+ const target = resolveTargetIdentity({
24977
25127
  cwd: input2.cwd,
24978
- file,
24979
- identities,
24980
- infoApi: input2.apis?.info
25128
+ selector: input2.selector,
25129
+ identities
24981
25130
  });
25131
+ const occupant = file ? identities.find((identity) => identity.filePath === file && identity.n !== target?.n) : void 0;
25132
+ if (occupant) {
25133
+ throw new CliError(`\u4EA7\u7269\u8DEF\u5F84 ${file} \u5DF2\u88AB ${occupant.n}.json \u5360\u7528`, "CREATE_FILE_OCCUPIED");
25134
+ }
24982
25135
  if (target?.resourceId) {
24983
25136
  throw new CliError(
24984
25137
  "\u8FD9\u4E2A\u8D44\u6E90\u5DF2\u7ECF\u521B\u5EFA\u8FC7\u6388\u6743\u6761\u76EE\uFF0C\u8FD8\u6CA1\u6709\u53D1\u884C\u7248\u672C\u3002",
@@ -25024,6 +25177,7 @@ async function createResource(input2) {
25024
25177
  name,
25025
25178
  typeCode,
25026
25179
  resourceId,
25180
+ title,
25027
25181
  file,
25028
25182
  target
25029
25183
  });
@@ -25057,6 +25211,7 @@ function createCreateCommand() {
25057
25211
  type: options.type,
25058
25212
  name: options.name,
25059
25213
  file: options.artifact,
25214
+ selector: shared.file,
25060
25215
  yes: shared.yes
25061
25216
  });
25062
25217
  console.log(record.resourceId ?? "");
@@ -25067,135 +25222,6 @@ function createCreateCommand() {
25067
25222
  // src/commands/listing/update.ts
25068
25223
  import { Command as Command5 } from "commander";
25069
25224
 
25070
- // src/local/draft.ts
25071
- import { existsSync as existsSync6, readFileSync as readFileSync5, unlinkSync as unlinkSync4 } from "fs";
25072
- import path9 from "path";
25073
- import { z as z3 } from "zod";
25074
- var itemList = z3.array(z3.record(z3.unknown()));
25075
- var draftSchema = z3.object({
25076
- schemaVersion: z3.literal(1),
25077
- draftKind: z3.enum(["initial", "update"]),
25078
- resourceId: z3.string().min(1),
25079
- resourceTypeCode: z3.string().min(1),
25080
- fromVersion: z3.string().min(1).optional(),
25081
- fileSha1: z3.string().min(1).nullable(),
25082
- filename: z3.string().min(1).nullable(),
25083
- analyzedSha1: z3.string().min(1).nullable(),
25084
- description: z3.string(),
25085
- inputAttrs: itemList,
25086
- orphanedInputAttrs: itemList,
25087
- customPropertyDescriptors: itemList,
25088
- dependencies: itemList,
25089
- baseUpcastResources: z3.array(z3.never()),
25090
- authExcludedItems: z3.array(z3.never())
25091
- }).strict().superRefine((draft, ctx) => {
25092
- if (draft.draftKind === "initial" && (draft.fromVersion || draft.description !== "")) {
25093
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "initial \u5DE5\u4F5C\u7A3F\u4E0D\u80FD\u6709\u6765\u6E90\u7248\u672C\u6216\u63CF\u8FF0" });
25094
- }
25095
- if (draft.draftKind === "update" && !draft.fromVersion) {
25096
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "update \u5DE5\u4F5C\u7A3F\u5FC5\u987B\u6709\u6765\u6E90\u7248\u672C" });
25097
- }
25098
- if (draft.analyzedSha1 !== null && draft.analyzedSha1 !== draft.fileSha1) {
25099
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "analyzedSha1 \u5FC5\u987B\u7B49\u4E8E fileSha1" });
25100
- }
25101
- if (draft.fileSha1 === null && (draft.filename !== null || draft.analyzedSha1 !== null)) {
25102
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "\u65E0\u6587\u4EF6\u65F6\u4E0D\u80FD\u4FDD\u7559\u6587\u4EF6\u540D\u6216\u5206\u6790 SHA" });
25103
- }
25104
- });
25105
- function draftFilePath(cwd, n) {
25106
- return path9.join(freelogDir(cwd), `${n}.version.json`);
25107
- }
25108
- function emptyDraft() {
25109
- return { baseUpcastResources: [], authExcludedItems: [] };
25110
- }
25111
- function prepareDraft(cwd, n, input2) {
25112
- const identity = readIdentity(cwd, n);
25113
- if (!identity.resourceId) {
25114
- throw new CliError("\u8BF7\u5148 create \u6216 bind\uFF0C\u518D\u7F16\u8F91\u7248\u672C\u5DE5\u4F5C\u7A3F", "DRAFT_IDENTITY_UNBOUND");
25115
- }
25116
- if (input2.resourceId !== void 0 && input2.resourceId !== identity.resourceId) {
25117
- throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u4E0E\u8EAB\u4EFD\u4E0D\u4E00\u81F4`, "DRAFT_IDENTITY_MISMATCH");
25118
- }
25119
- if (input2.resourceTypeCode !== void 0 && input2.resourceTypeCode !== identity.typeCode) {
25120
- throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u4E0E\u8EAB\u4EFD\u4E0D\u4E00\u81F4`, "DRAFT_IDENTITY_MISMATCH");
25121
- }
25122
- const draftKind = input2.draftKind ?? (input2.fromVersion ? "update" : "initial");
25123
- const fileSha1 = input2.fileSha1 ?? null;
25124
- const value = {
25125
- schemaVersion: 1,
25126
- draftKind,
25127
- resourceId: identity.resourceId,
25128
- resourceTypeCode: input2.resourceTypeCode ?? identity.typeCode,
25129
- ...draftKind === "update" ? { fromVersion: input2.fromVersion } : {},
25130
- fileSha1,
25131
- filename: fileSha1 ? input2.filename ?? null : null,
25132
- analyzedSha1: fileSha1 ? input2.analyzedSha1 ?? null : null,
25133
- description: draftKind === "initial" ? "" : input2.description ?? "",
25134
- inputAttrs: input2.inputAttrs ?? [],
25135
- orphanedInputAttrs: input2.orphanedInputAttrs ?? [],
25136
- customPropertyDescriptors: input2.customPropertyDescriptors ?? [],
25137
- dependencies: input2.dependencies ?? [],
25138
- baseUpcastResources: [],
25139
- authExcludedItems: []
25140
- };
25141
- const parsed = draftSchema.safeParse(value);
25142
- if (!parsed.success) throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u65E0\u6548`, "DRAFT_INVALID");
25143
- return parsed.data;
25144
- }
25145
- function serializeDraft(draft) {
25146
- return `${JSON.stringify(draft, null, 2)}
25147
- `;
25148
- }
25149
- function readDraft(cwd, n) {
25150
- const filePath = draftFilePath(cwd, n);
25151
- if (!existsSync6(filePath)) return void 0;
25152
- let raw;
25153
- try {
25154
- raw = JSON.parse(readFileSync5(filePath, "utf8"));
25155
- } catch {
25156
- throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u65E0\u6CD5\u89E3\u6790`, "DRAFT_INVALID");
25157
- }
25158
- const parsed = draftSchema.safeParse(raw);
25159
- if (!parsed.success) throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u65E0\u6548\uFF1B\u4EC5\u652F\u6301 schemaVersion=1`, "DRAFT_INVALID");
25160
- const identity = readIdentity(cwd, n);
25161
- if (!identity.resourceId || parsed.data.resourceId !== identity.resourceId || parsed.data.resourceTypeCode !== identity.typeCode) {
25162
- throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u4E0E\u8EAB\u4EFD\u4E0D\u4E00\u81F4`, "DRAFT_IDENTITY_MISMATCH");
25163
- }
25164
- return parsed.data;
25165
- }
25166
- function writeDraft(cwd, n, draft) {
25167
- return withProjectLock(cwd, () => {
25168
- const normalized = prepareDraft(cwd, n, draft);
25169
- atomicWriteFile(draftFilePath(cwd, n), serializeDraft(normalized));
25170
- return normalized;
25171
- }, "write-version-draft");
25172
- }
25173
- function deleteDraft(cwd, n) {
25174
- return withProjectLock(cwd, () => {
25175
- const filePath = draftFilePath(cwd, n);
25176
- if (!existsSync6(filePath)) return false;
25177
- unlinkSync4(filePath);
25178
- return true;
25179
- }, "delete-version-draft");
25180
- }
25181
- function draftSummary(draft) {
25182
- const source = draft.draftKind === "update" ? draft.fromVersion ?? "\u66F4\u65B0" : "\u9996\u7248";
25183
- const sha1 = draft.fileSha1 ? `${draft.fileSha1.slice(0, 8)}\u2026` : "\u65E0";
25184
- return ["\u5C06\u8986\u76D6\u672C\u5730\u5DE5\u4F5C\u7A3F\uFF1A", ` \u6765\u6E90\uFF1A${source}`, ` \u6587\u4EF6\uFF1A${draft.filename ?? "\u65E0"} sha1=${sha1}`, ` \u5C5E\u6027 ${(draft.customPropertyDescriptors ?? []).length} / \u4F9D\u8D56 ${(draft.dependencies ?? []).length}`].join("\n");
25185
- }
25186
-
25187
- // src/local/resolve.ts
25188
- function resolveIdentity(cwd, _legacyFile) {
25189
- const identities = listIdentities(cwd);
25190
- if (identities.length === 0) {
25191
- throw new CliError("\u5F53\u524D\u76EE\u5F55\u6CA1\u6709\u8EAB\u4EFD\u6587\u4EF6", "IDENTITY_NOT_FOUND");
25192
- }
25193
- if (identities.length !== 1 || identities[0].n !== 1) {
25194
- throw new CliError("\u53D1\u73B0\u65E7\u7684\u591A\u8D44\u6E90\u672C\u5730\u72B6\u6001\uFF1B\u8BF7\u5C06\u6BCF\u4EFD\u8D44\u6E90\u8FC1\u79FB\u5230\u72EC\u7ACB\u5DE5\u7A0B\u540E\u518D\u7EE7\u7EED", "IDENTITY_MIGRATION_REQUIRED");
25195
- }
25196
- return identities[0];
25197
- }
25198
-
25199
25225
  // src/domain/version/gates.ts
25200
25226
  function evaluateGates(input2, intent) {
25201
25227
  const latest = input2.latestVersion;
@@ -25300,6 +25326,7 @@ async function updateListing(input2) {
25300
25326
  }
25301
25327
  const update2 = input2.apis?.update ?? ((params) => service_API_default.Resource.update(params));
25302
25328
  await update2(payload);
25329
+ if (input2.title) updateIdentity(input2.cwd, identity.n, { title: input2.title });
25303
25330
  return payload;
25304
25331
  }
25305
25332
 
@@ -25326,7 +25353,7 @@ function createUpdateCommand() {
25326
25353
 
25327
25354
  // src/commands/policy/apply.ts
25328
25355
  import { readFileSync as readFileSync6 } from "fs";
25329
- import path10 from "path";
25356
+ import path9 from "path";
25330
25357
  import { confirm, input } from "@inquirer/prompts";
25331
25358
  import { Command as Command6 } from "commander";
25332
25359
 
@@ -25505,7 +25532,7 @@ async function setPolicy(input2) {
25505
25532
  // src/commands/policy/apply.ts
25506
25533
  function parsePolicy(file) {
25507
25534
  const text = readFileSync6(file, "utf8");
25508
- if (path10.extname(file).toLowerCase() !== ".json") return { policyText: text };
25535
+ if (path9.extname(file).toLowerCase() !== ".json") return { policyText: text };
25509
25536
  let parsed;
25510
25537
  try {
25511
25538
  parsed = JSON.parse(text);
@@ -25520,10 +25547,10 @@ function parsePolicy(file) {
25520
25547
  function createPolicyApplyCommand() {
25521
25548
  const command = addSharedOptions(new Command6("apply"));
25522
25549
  command.description("\u4ECE\u672C\u5730\u6587\u4EF6\u8FFD\u52A0\u7B56\u7565").option("--from-file <path>", "\u7B56\u7565\u6587\u672C\u6216 JSON \u8DEF\u5F84").option("--name <name>", "\u7B56\u7565\u540D\uFF0C\u8986\u76D6 JSON \u5185\u540D\u79F0").action(async function(options) {
25523
- const shared = this.optsWithGlobals();
25524
- const cwd = resolveCwd(options.cwd ?? shared.cwd);
25525
- const file = options.file ?? shared.file;
25526
- const yes = (options.yes ?? shared.yes) === true;
25550
+ const shared = readSharedOptions(this);
25551
+ const cwd = resolveCwd(shared.cwd);
25552
+ const file = shared.file;
25553
+ const yes = shared.yes === true;
25527
25554
  if (!options.fromFile) throw new CliError("\u8BF7\u63D0\u4F9B --from-file", "POLICY_FROM_FILE");
25528
25555
  const source = parsePolicy(options.fromFile);
25529
25556
  let policyName = options.name ?? source.policyName;
@@ -25561,11 +25588,11 @@ import { Command as Command8 } from "commander";
25561
25588
  function createPolicySetCommand() {
25562
25589
  const command = addSharedOptions(new Command8("set"));
25563
25590
  command.description("\u542F\u7528\u6216\u505C\u7528\u7B56\u7565").requiredOption("--id <policyId>", "\u7B56\u7565\u7F16\u53F7").option("--on", "\u542F\u7528").option("--off", "\u505C\u7528").action(async function(options) {
25564
- const shared = this.optsWithGlobals();
25565
- const yes = (options.yes ?? shared.yes) === true;
25591
+ const shared = readSharedOptions(this);
25592
+ const yes = shared.yes === true;
25566
25593
  if (options.on === options.off) throw new CliError("\u5FC5\u987B\u4E14\u53EA\u80FD\u63D0\u4F9B --on \u6216 --off", "POLICY_SET_DIRECTION");
25567
25594
  if (!yes && !await confirm2({ message: `${options.on ? "\u542F\u7528" : "\u505C\u7528"}\u7B56\u7565 ${options.id}\uFF1F`, default: true })) return;
25568
- await setPolicy({ cwd: resolveCwd(options.cwd ?? shared.cwd), file: options.file ?? shared.file, policyId: options.id, on: options.on === true });
25595
+ await setPolicy({ cwd: resolveCwd(shared.cwd), file: shared.file, policyId: options.id, on: options.on === true });
25569
25596
  console.log(`\u5DF2${options.on ? "\u542F\u7528" : "\u505C\u7528"}\u6388\u6743\u7B56\u7565`);
25570
25597
  });
25571
25598
  return command;
@@ -25630,8 +25657,8 @@ function createPolicyTemplateCommand() {
25630
25657
  import { Command as Command10 } from "commander";
25631
25658
 
25632
25659
  // src/local/indexFile.ts
25633
- import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
25634
- import path11 from "path";
25660
+ import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
25661
+ import path10 from "path";
25635
25662
  function normalizeFileKey(filePath) {
25636
25663
  return filePath.replaceAll("\\", "/").replace(/^\.\//, "");
25637
25664
  }
@@ -25640,6 +25667,7 @@ function normalizeFileKey(filePath) {
25640
25667
  async function bindResource(input2) {
25641
25668
  assertPlatformAllowed();
25642
25669
  const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
25670
+ validateLocalState(input2.cwd);
25643
25671
  const filePath = input2.file !== void 0 ? normalizeProjectPath(input2.cwd, input2.file, {
25644
25672
  code: "BIND_FILE_OUTSIDE",
25645
25673
  message: "--artifact \u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
@@ -25662,14 +25690,15 @@ async function bindResource(input2) {
25662
25690
  }
25663
25691
  const resourceId = String(info2.resourceId ?? "");
25664
25692
  const name = String(info2.resourceName ?? info2.name ?? "").split("/").pop() ?? "";
25693
+ const title = String(info2.resourceTitle ?? info2.title ?? name);
25665
25694
  const resourceType = info2.resourceType;
25666
25695
  const typeFromArray = Array.isArray(resourceType) ? String(resourceType[0] ?? "") : "";
25667
25696
  const typeCode = String(info2.resourceTypeCode ?? typeFromArray);
25668
- if (!resourceId || !name || !typeCode) {
25697
+ if (!resourceId || !name || !typeCode || !title) {
25669
25698
  throw new CliError("\u5E73\u53F0\u8BE6\u60C5\u7F3A\u5C11\u8EAB\u4EFD\u5B57\u6BB5", "BIND_INFO_INVALID");
25670
25699
  }
25671
25700
  return withProjectLock(input2.cwd, () => {
25672
- const identities = listIdentities(input2.cwd);
25701
+ const identities = validateLocalState(input2.cwd);
25673
25702
  const byId = identities.find((item) => item.resourceId === resourceId);
25674
25703
  const byFile = filePath ? identities.find(
25675
25704
  (item) => item.filePath !== void 0 && normalizeFileKey(item.filePath) === filePath
@@ -25678,12 +25707,16 @@ async function bindResource(input2) {
25678
25707
  if (byFile && byId && byFile.n !== byId.n) {
25679
25708
  throw new CliError("\u8DEF\u5F84\u5DF2\u88AB\u5360\u7528", "BIND_PATH_TAKEN");
25680
25709
  }
25681
- let target = byId ?? byFile;
25710
+ let target = input2.selector ? resolveIdentity(input2.cwd, input2.selector) : byId;
25711
+ if (input2.selector && byId && target && target.n !== byId.n) {
25712
+ throw new CliError(`\u8D44\u6E90\u5DF2\u7ED1\u5B9A\u5230 ${byId.n}.json`, "BIND_ID_TAKEN");
25713
+ }
25682
25714
  if (!target && unbound.length === 1) {
25683
25715
  target = unbound[0];
25684
25716
  }
25685
- if (!target && identities.length > 1 && !filePath) {
25686
- throw new CliError("\u4E00\u5939\u591A\u6761\u5FC5\u987B\u6307\u5B9A --file", "IDENTITY_FILE_REQUIRED");
25717
+ if (!target && unbound.length > 1) throw new CliError("\u5F53\u524D\u5DE5\u7A0B\u6709\u591A\u4EFD\u672A\u7ED1\u5B9A\u8D44\u6E90\u72B6\u6001\uFF1B\u8BF7\u4F7F\u7528 --resource \u6307\u5B9A\u8D44\u6E90", "IDENTITY_RESOURCE_REQUIRED");
25718
+ if (byFile && target?.n !== byFile.n) {
25719
+ throw new CliError("\u8DEF\u5F84\u5DF2\u88AB\u5360\u7528", "BIND_PATH_TAKEN");
25687
25720
  }
25688
25721
  if (isThemeOrWidget(typeCode) && !filePath && !target?.filePath) {
25689
25722
  throw new CliError("\u4E3B\u9898/\u63D2\u4EF6 bind \u65F6\u8BF7\u901A\u8FC7 --artifact \u6307\u5B9A\u6784\u5EFA\u76EE\u5F55", "BIND_FIXED_TYPE_FILE_REQUIRED");
@@ -25701,6 +25734,7 @@ async function bindResource(input2) {
25701
25734
  const updated = prepareIdentityUpdate(input2.cwd, target.n, {
25702
25735
  resourceId,
25703
25736
  name,
25737
+ title,
25704
25738
  typeCode,
25705
25739
  filePath: filePath ?? target.filePath,
25706
25740
  env
@@ -25715,6 +25749,7 @@ async function bindResource(input2) {
25715
25749
  subject: "resource",
25716
25750
  resourceId,
25717
25751
  name,
25752
+ title,
25718
25753
  typeCode,
25719
25754
  filePath,
25720
25755
  env
@@ -25757,6 +25792,7 @@ function createBindCommand() {
25757
25792
  cwd: resolveCwd(shared.cwd),
25758
25793
  target,
25759
25794
  file: options.artifact,
25795
+ selector: shared.file,
25760
25796
  force: options.force,
25761
25797
  yes: shared.yes
25762
25798
  });
@@ -25770,9 +25806,9 @@ import { Command as Command11 } from "commander";
25770
25806
 
25771
25807
  // src/domain/init/scaffold.ts
25772
25808
  import { execFile as execFileCallback } from "child_process";
25773
- import { cpSync, existsSync as existsSync8, lstatSync, mkdirSync as mkdirSync2, mkdtempSync, readdirSync as readdirSync2, readFileSync as readFileSync8, renameSync, rmSync } from "fs";
25809
+ import { cpSync, existsSync as existsSync9, lstatSync, mkdirSync as mkdirSync2, mkdtempSync, readdirSync as readdirSync3, readFileSync as readFileSync8, renameSync, rmSync } from "fs";
25774
25810
  import os4 from "os";
25775
- import path12 from "path";
25811
+ import path11 from "path";
25776
25812
  import { promisify } from "util";
25777
25813
 
25778
25814
  // src/domain/init/templates.ts
@@ -25802,28 +25838,28 @@ function isFixedTemplateType2(typeCode) {
25802
25838
  return typeCode === "RT001" || typeCode === "RT002";
25803
25839
  }
25804
25840
  function resolveTargetDir(input2) {
25805
- return input2.dir ? path12.isAbsolute(input2.dir) ? input2.dir : path12.resolve(input2.cwd, input2.dir) : path12.resolve(input2.cwd);
25841
+ return input2.dir ? path11.isAbsolute(input2.dir) ? input2.dir : path11.resolve(input2.cwd, input2.dir) : path11.resolve(input2.cwd);
25806
25842
  }
25807
25843
  function targetHasOnlyAuthSelector(targetDir) {
25808
- if (!existsSync8(targetDir)) return false;
25844
+ if (!existsSync9(targetDir)) return false;
25809
25845
  let entries;
25810
25846
  try {
25811
- entries = readdirSync2(targetDir);
25847
+ entries = readdirSync3(targetDir);
25812
25848
  } catch {
25813
25849
  throw new CliError("\u76EE\u6807\u76EE\u5F55\u4E0D\u53EF\u8BFB\u53D6\uFF0C\u62D2\u7EDD\u8986\u76D6", "INIT_TARGET_NOT_EMPTY");
25814
25850
  }
25815
25851
  if (entries.length === 0) return false;
25816
25852
  if (entries.length !== 1 || entries[0] !== ".freelog") return false;
25817
- const stateDir = path12.join(targetDir, ".freelog");
25853
+ const stateDir = path11.join(targetDir, ".freelog");
25818
25854
  if (!lstatSync(stateDir).isDirectory() || lstatSync(stateDir).isSymbolicLink()) return false;
25819
- const stateEntries = readdirSync2(stateDir);
25855
+ const stateEntries = readdirSync3(stateDir);
25820
25856
  if (stateEntries.length !== 1 || stateEntries[0] !== "auth") return false;
25821
- const auth = lstatSync(path12.join(stateDir, "auth"));
25857
+ const auth = lstatSync(path11.join(stateDir, "auth"));
25822
25858
  return auth.isFile() && !auth.isSymbolicLink();
25823
25859
  }
25824
25860
  function assertInitialTarget(targetDir) {
25825
- if (!existsSync8(targetDir)) return { targetExisted: false, preserveAuth: false };
25826
- const entries = readdirSync2(targetDir);
25861
+ if (!existsSync9(targetDir)) return { targetExisted: false, preserveAuth: false };
25862
+ const entries = readdirSync3(targetDir);
25827
25863
  if (entries.length === 0) return { targetExisted: true, preserveAuth: false };
25828
25864
  if (targetHasOnlyAuthSelector(targetDir)) return { targetExisted: true, preserveAuth: true };
25829
25865
  throw new CliError("\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u7A7A\u76EE\u5F55\uFF0C\u62D2\u7EDD\u8986\u76D6", "INIT_TARGET_NOT_EMPTY");
@@ -25834,8 +25870,8 @@ function assertOnlyAuthSelectorStillThere(targetDir) {
25834
25870
  }
25835
25871
  }
25836
25872
  function copyDirectoryContents(sourceDir, targetDir) {
25837
- for (const entry2 of readdirSync2(sourceDir)) {
25838
- cpSync(path12.join(sourceDir, entry2), path12.join(targetDir, entry2), { recursive: true, errorOnExist: true, force: false });
25873
+ for (const entry2 of readdirSync3(sourceDir)) {
25874
+ cpSync(path11.join(sourceDir, entry2), path11.join(targetDir, entry2), { recursive: true, errorOnExist: true, force: false });
25839
25875
  }
25840
25876
  }
25841
25877
  function parsePackFilename(stdout) {
@@ -25847,8 +25883,8 @@ function parsePackFilename(stdout) {
25847
25883
  throw new CliError("\u6A21\u677F\u4E0B\u8F7D\u5931\u8D25\uFF1Anpm \u672A\u8FD4\u56DE\u5B89\u88C5\u5305", "TEMPLATE_DOWNLOAD_FAILED");
25848
25884
  }
25849
25885
  function validateRemoteTemplate(packageDir, template) {
25850
- const manifestPath = path12.join(packageDir, "template.manifest.json");
25851
- const templateDir = path12.join(packageDir, "template");
25886
+ const manifestPath = path11.join(packageDir, "template.manifest.json");
25887
+ const templateDir = path11.join(packageDir, "template");
25852
25888
  let manifest;
25853
25889
  try {
25854
25890
  manifest = JSON.parse(readFileSync8(manifestPath, "utf8"));
@@ -25856,15 +25892,15 @@ function validateRemoteTemplate(packageDir, template) {
25856
25892
  throw new CliError("\u6A21\u677F\u6821\u9A8C\u5931\u8D25\uFF1A\u7F3A\u5C11\u6216\u65E0\u6CD5\u8BFB\u53D6 template.manifest.json", "TEMPLATE_INVALID");
25857
25893
  }
25858
25894
  const tags = Array.isArray(manifest.tags) ? manifest.tags : [];
25859
- if (manifest.id !== template.id || manifest.npmName !== template.npmName || manifest.version !== template.version || !tags.includes("runtime") || !template.targets.every((target) => tags.includes(target)) || !existsSync8(templateDir)) {
25895
+ if (manifest.id !== template.id || manifest.npmName !== template.npmName || manifest.version !== template.version || !tags.includes("runtime") || !template.targets.every((target) => tags.includes(target)) || !existsSync9(templateDir)) {
25860
25896
  throw new CliError("\u6A21\u677F\u6821\u9A8C\u5931\u8D25\uFF1A\u7EBF\u4E0A\u6A21\u677F\u4E0E\u53D7\u63A7\u6E05\u5355\u4E0D\u4E00\u81F4", "TEMPLATE_INVALID");
25861
25897
  }
25862
25898
  return templateDir;
25863
25899
  }
25864
25900
  async function installRemoteTemplate(input2) {
25865
- const tempDir = mkdtempSync(path12.join(os4.tmpdir(), "freelog-template-"));
25866
- const downloadDir = path12.join(tempDir, "download");
25867
- const extractDir = path12.join(tempDir, "extract");
25901
+ const tempDir = mkdtempSync(path11.join(os4.tmpdir(), "freelog-template-"));
25902
+ const downloadDir = path11.join(tempDir, "download");
25903
+ const extractDir = path11.join(tempDir, "extract");
25868
25904
  mkdirSync2(downloadDir);
25869
25905
  mkdirSync2(extractDir);
25870
25906
  const npm = process.platform === "win32" ? "npm.cmd" : "npm";
@@ -25875,13 +25911,13 @@ async function installRemoteTemplate(input2) {
25875
25911
  } catch {
25876
25912
  throw new CliError(`\u6A21\u677F\u4E0B\u8F7D\u5931\u8D25\uFF1A${input2.template.id}`, "TEMPLATE_DOWNLOAD_FAILED");
25877
25913
  }
25878
- const archivePath = path12.join(downloadDir, parsePackFilename(stdout));
25914
+ const archivePath = path11.join(downloadDir, parsePackFilename(stdout));
25879
25915
  try {
25880
25916
  await execFile("tar", ["-xzf", archivePath, "-C", extractDir]);
25881
25917
  } catch {
25882
25918
  throw new CliError(`\u6A21\u677F\u89E3\u5305\u5931\u8D25\uFF1A${input2.template.id}`, "TEMPLATE_EXTRACT_FAILED");
25883
25919
  }
25884
- copyDirectoryContents(validateRemoteTemplate(path12.join(extractDir, "package"), input2.template), input2.targetDir);
25920
+ copyDirectoryContents(validateRemoteTemplate(path11.join(extractDir, "package"), input2.template), input2.targetDir);
25885
25921
  } finally {
25886
25922
  rmSync(tempDir, { recursive: true, force: true });
25887
25923
  }
@@ -25896,23 +25932,23 @@ function commitStaging(stagingDir, targetDir, targetExisted, preserveAuth) {
25896
25932
  } else {
25897
25933
  assertInitialTarget(targetDir);
25898
25934
  }
25899
- for (const entry2 of readdirSync2(stagingDir)) {
25900
- const destination = path12.join(targetDir, entry2);
25935
+ for (const entry2 of readdirSync3(stagingDir)) {
25936
+ const destination = path11.join(targetDir, entry2);
25901
25937
  if (preserveAuth && entry2 === ".freelog") {
25902
- for (const stateEntry of readdirSync2(path12.join(stagingDir, entry2))) {
25903
- const stateDestination = path12.join(destination, stateEntry);
25904
- if (existsSync8(stateDestination)) {
25938
+ for (const stateEntry of readdirSync3(path11.join(stagingDir, entry2))) {
25939
+ const stateDestination = path11.join(destination, stateEntry);
25940
+ if (existsSync9(stateDestination)) {
25905
25941
  throw new CliError("\u76EE\u6807\u76EE\u5F55\u5728\u521D\u59CB\u5316\u671F\u95F4\u88AB\u4FEE\u6539\uFF0C\u672A\u8986\u76D6\u672A\u77E5\u6587\u4EF6", "INIT_TARGET_CHANGED");
25906
25942
  }
25907
- renameSync(path12.join(stagingDir, entry2, stateEntry), stateDestination);
25943
+ renameSync(path11.join(stagingDir, entry2, stateEntry), stateDestination);
25908
25944
  }
25909
- rmSync(path12.join(stagingDir, entry2), { recursive: true, force: true });
25945
+ rmSync(path11.join(stagingDir, entry2), { recursive: true, force: true });
25910
25946
  continue;
25911
25947
  }
25912
- if (existsSync8(destination)) {
25948
+ if (existsSync9(destination)) {
25913
25949
  throw new CliError("\u76EE\u6807\u76EE\u5F55\u5728\u521D\u59CB\u5316\u671F\u95F4\u88AB\u4FEE\u6539\uFF0C\u672A\u8986\u76D6\u672A\u77E5\u6587\u4EF6", "INIT_TARGET_CHANGED");
25914
25950
  }
25915
- renameSync(path12.join(stagingDir, entry2), destination);
25951
+ renameSync(path11.join(stagingDir, entry2), destination);
25916
25952
  }
25917
25953
  rmSync(stagingDir, { recursive: true, force: true });
25918
25954
  }
@@ -25936,9 +25972,9 @@ async function initProject(input2) {
25936
25972
  }
25937
25973
  const template = shortcut && input2.template ? getTemplate(input2.template, shortcut) : void 0;
25938
25974
  if (shortcut && !template) throw new CliError("\u8BF7\u9009\u62E9\u6A21\u677F", "INIT_TEMPLATE_REQUIRED");
25939
- const parent = path12.dirname(targetDir);
25975
+ const parent = path11.dirname(targetDir);
25940
25976
  mkdirSync2(parent, { recursive: true });
25941
- const stagingDir = mkdtempSync(path12.join(parent, `.${path12.basename(targetDir)}.freelog-init-`));
25977
+ const stagingDir = mkdtempSync(path11.join(parent, `.${path11.basename(targetDir)}.freelog-init-`));
25942
25978
  try {
25943
25979
  if (template) await (input2.templateSource ?? installRemoteTemplate)({ template, targetDir: stagingDir });
25944
25980
  const created = createIdentity(stagingDir, {
@@ -26012,9 +26048,8 @@ import { Command as Command12 } from "commander";
26012
26048
 
26013
26049
  // src/domain/status.ts
26014
26050
  async function statusProject(input2) {
26015
- const identities = listIdentities(input2.cwd);
26016
- const local = identities.length ? resolveIdentity(input2.cwd, input2.file) : void 0;
26017
- const draft = local ? readDraft(input2.cwd, local.n) : void 0;
26051
+ const local = resolveIdentity(input2.cwd, input2.file);
26052
+ const draft = readDraft(input2.cwd, local.n);
26018
26053
  let online = "\u672A\u67E5\u8BE2";
26019
26054
  if (local?.resourceId) {
26020
26055
  assertPlatformAllowed();
@@ -26149,9 +26184,64 @@ function createTypeCommand() {
26149
26184
  return type;
26150
26185
  }
26151
26186
 
26152
- // src/commands/shelf/offline.ts
26187
+ // src/commands/project/resource.ts
26153
26188
  import { Command as Command15 } from "commander";
26154
26189
 
26190
+ // src/domain/resource/sync.ts
26191
+ async function syncResourceTitles(input2) {
26192
+ assertPlatformAllowed();
26193
+ requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
26194
+ return withProjectLock(input2.cwd, async () => {
26195
+ const env = getEnv2();
26196
+ const all3 = validateLocalState(input2.cwd);
26197
+ const targets = input2.selector ? [resolveIdentity(input2.cwd, input2.selector)] : all3.filter((identity) => identity.resourceId && (identity.env ?? "prod") === env);
26198
+ if (targets.length === 0) {
26199
+ throw new CliError("\u5F53\u524D\u73AF\u5883\u6CA1\u6709\u53EF\u540C\u6B65\u6807\u9898\u7684\u5DF2\u7ED1\u5B9A\u8D44\u6E90", "RESOURCE_SYNC_EMPTY");
26200
+ }
26201
+ if (input2.selector && (targets[0].env ?? "prod") !== env) {
26202
+ throw new CliError("\u6240\u9009\u8D44\u6E90\u4E0D\u5C5E\u4E8E\u5F53\u524D\u73AF\u5883\uFF0C\u4E0D\u80FD\u540C\u6B65\u6807\u9898", "RESOURCE_SYNC_ENV_MISMATCH");
26203
+ }
26204
+ const info2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
26205
+ const results = await Promise.all(targets.map(async (identity) => {
26206
+ if (!identity.resourceId) return { identity, error: "\u8D44\u6E90\u5C1A\u672A\u7ED1\u5B9A" };
26207
+ try {
26208
+ const data = unwrapData2(await info2({ resourceIdOrName: identity.resourceId, isLoadLatestVersionInfo: 1 }));
26209
+ const title = String(data.resourceTitle ?? data.title ?? "");
26210
+ if (!title) return { identity, error: "\u5E73\u53F0\u8BE6\u60C5\u7F3A\u5C11\u6807\u9898" };
26211
+ return { identity, title };
26212
+ } catch (error2) {
26213
+ return { identity, error: error2 instanceof Error ? error2.message : "\u8BF7\u6C42\u5931\u8D25" };
26214
+ }
26215
+ }));
26216
+ const successful = results.filter((item) => "title" in item);
26217
+ if (successful.length > 0) {
26218
+ const changes = successful.map(({ identity, title }) => {
26219
+ const updated = prepareIdentityUpdate(input2.cwd, identity.n, { title });
26220
+ return { path: identityFilePath(input2.cwd, identity.n), content: serializeIdentity(updated) };
26221
+ });
26222
+ commitLocalTransaction(input2.cwd, changes);
26223
+ }
26224
+ const failed = results.filter((item) => "error" in item);
26225
+ if (failed.length > 0) {
26226
+ throw new CliError(`\u6807\u9898\u5DF2\u540C\u6B65 ${successful.length} \u4EFD\uFF1B\u5931\u8D25\uFF1A${failed.map((item) => `${item.identity.n}.json\uFF08${item.error}\uFF09`).join("\u3001")}`, "RESOURCE_SYNC_PARTIAL");
26227
+ }
26228
+ return `\u5DF2\u540C\u6B65 ${successful.length} \u4EFD\u8D44\u6E90\u6807\u9898`;
26229
+ }, "sync-resource-titles");
26230
+ }
26231
+
26232
+ // src/commands/project/resource.ts
26233
+ function createResourceCommand() {
26234
+ const resource = addSharedOptions(new Command15("resource")).description("\u8D44\u6E90\u672C\u5730\u72B6\u6001\u7EF4\u62A4");
26235
+ resource.command("sync").description("\u4ECE\u5E73\u53F0\u540C\u6B65\u672C\u5730\u8D44\u6E90\u6807\u9898").action(async function() {
26236
+ const shared = readSharedOptions(this);
26237
+ console.log(await syncResourceTitles({ cwd: resolveCwd(shared.cwd), selector: shared.file }));
26238
+ });
26239
+ return resource;
26240
+ }
26241
+
26242
+ // src/commands/shelf/offline.ts
26243
+ import { Command as Command16 } from "commander";
26244
+
26155
26245
  // src/domain/online/online.ts
26156
26246
  async function loadInfo(resourceId, apis) {
26157
26247
  const infoApi2 = apis?.info ?? ((params) => service_API_default.Resource.info(params));
@@ -26197,7 +26287,7 @@ async function offlineResource(input2) {
26197
26287
 
26198
26288
  // src/commands/shelf/offline.ts
26199
26289
  function createOfflineCommand() {
26200
- const command = addSharedOptions(new Command15("offline"));
26290
+ const command = addSharedOptions(new Command16("offline"));
26201
26291
  command.description(
26202
26292
  // i18n: cli.command.offline.description
26203
26293
  "\u4E0B\u67B6"
@@ -26212,9 +26302,9 @@ function createOfflineCommand() {
26212
26302
  }
26213
26303
 
26214
26304
  // src/commands/shelf/online.ts
26215
- import { Command as Command16 } from "commander";
26305
+ import { Command as Command17 } from "commander";
26216
26306
  function createOnlineCommand() {
26217
- const command = addSharedOptions(new Command16("online"));
26307
+ const command = addSharedOptions(new Command17("online"));
26218
26308
  command.description(
26219
26309
  // i18n: cli.command.online.description
26220
26310
  "\u4E0A\u67B6"
@@ -26229,7 +26319,7 @@ function createOnlineCommand() {
26229
26319
  }
26230
26320
 
26231
26321
  // src/commands/shelf/validate.ts
26232
- import { Command as Command17 } from "commander";
26322
+ import { Command as Command18 } from "commander";
26233
26323
 
26234
26324
  // src/domain/online/validate.ts
26235
26325
  async function validateOnline(input2) {
@@ -26252,7 +26342,7 @@ async function validateOnline(input2) {
26252
26342
 
26253
26343
  // src/commands/shelf/validate.ts
26254
26344
  function createValidateCommand() {
26255
- const command = addSharedOptions(new Command17("validate"));
26345
+ const command = addSharedOptions(new Command18("validate"));
26256
26346
  command.description(
26257
26347
  // i18n: cli.command.validate.description
26258
26348
  "\u53EA\u9884\u68C0"
@@ -26274,7 +26364,7 @@ function createValidateCommand() {
26274
26364
  }
26275
26365
 
26276
26366
  // src/commands/version/attr.ts
26277
- import { Command as Command18 } from "commander";
26367
+ import { Command as Command19 } from "commander";
26278
26368
 
26279
26369
  // src/domain/version/form/parseLine.ts
26280
26370
  var KEY_RE = /^[A-Za-z][A-Za-z0-9_]{0,29}$/;
@@ -26532,7 +26622,7 @@ function attrList(cwd, file) {
26532
26622
 
26533
26623
  // src/commands/version/attr.ts
26534
26624
  function createVersionAttrCommand() {
26535
- const attr = addSharedOptions(new Command18("attr"));
26625
+ const attr = addSharedOptions(new Command19("attr"));
26536
26626
  attr.description("\u6539\u7A3F\u4E0A\u7684\u5C5E\u6027");
26537
26627
  addSharedOptions(attr.command("add")).description("\u52A0\u81EA\u5B9A\u4E49\u5C5E\u6027").argument("[line]", "\u4E00\u884C\u5F0F").action(async function(line) {
26538
26628
  const shared = readSharedOptions(this);
@@ -26554,7 +26644,7 @@ function createVersionAttrCommand() {
26554
26644
  }
26555
26645
 
26556
26646
  // src/commands/version/create-version.ts
26557
- import { Command as Command19 } from "commander";
26647
+ import { Command as Command20 } from "commander";
26558
26648
 
26559
26649
  // src/domain/version/submit.ts
26560
26650
  function fieldName(error2) {
@@ -26615,20 +26705,20 @@ async function submitVersion(input2) {
26615
26705
 
26616
26706
  // src/domain/version/file.ts
26617
26707
  import { createHash as createHash3 } from "crypto";
26618
- import { existsSync as existsSync10, readFileSync as readFileSync9, statSync as statSync2, unlinkSync as unlinkSync6 } from "fs";
26619
- import path14 from "path";
26708
+ import { existsSync as existsSync11, readFileSync as readFileSync9, statSync as statSync2, unlinkSync as unlinkSync6 } from "fs";
26709
+ import path13 from "path";
26620
26710
 
26621
26711
  // src/domain/version/zip.ts
26622
- import { createWriteStream, existsSync as existsSync9, readdirSync as readdirSync3, statSync, unlinkSync as unlinkSync5 } from "fs";
26712
+ import { createWriteStream, existsSync as existsSync10, readdirSync as readdirSync4, statSync, unlinkSync as unlinkSync5 } from "fs";
26623
26713
  import { tmpdir } from "os";
26624
- import path13 from "path";
26714
+ import path12 from "path";
26625
26715
  import { finished } from "stream/promises";
26626
26716
  import archiver from "archiver";
26627
26717
  function isThemeOrWidget2(typeCode) {
26628
26718
  return typeCode === "RT001" || typeCode === "RT002";
26629
26719
  }
26630
26720
  function assertArtifactPath(typeCode, filePath) {
26631
- const stats = existsSync9(filePath) ? statSync(filePath) : void 0;
26721
+ const stats = existsSync10(filePath) ? statSync(filePath) : void 0;
26632
26722
  const themeOrWidget = isThemeOrWidget2(typeCode);
26633
26723
  if (stats?.isDirectory() && !themeOrWidget) {
26634
26724
  throw new CliError("\u4E0D\u652F\u6301\u6587\u4EF6\u5939\uFF0C\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6587\u4EF6\u3002", "FILE_DIRECTORY_UNSUPPORTED");
@@ -26641,17 +26731,17 @@ function assertArtifactPath(typeCode, filePath) {
26641
26731
  }
26642
26732
  }
26643
26733
  async function zipDirectoryContents(dir) {
26644
- if (!existsSync9(dir) || !statSync(dir).isDirectory()) {
26734
+ if (!existsSync10(dir) || !statSync(dir).isDirectory()) {
26645
26735
  throw new CliError(`\u6CA1\u6709\u6784\u5EFA\u4EA7\u7269 ${dir}\uFF0C\u8BF7\u5148\u6784\u5EFA`, "ZIP_MISSING");
26646
26736
  }
26647
- if (existsSync9(path13.join(dir, ".freelog"))) {
26737
+ if (existsSync10(path12.join(dir, ".freelog"))) {
26648
26738
  throw new CliError("\u4E0D\u8981\u628A\u5DE5\u7A0B\u6839\u5F53\u4EA7\u7269\u76EE\u5F55\uFF0C\u8BF7\u6307\u5B9A dist \u6216 build\u3002", "ZIP_PROJECT_ROOT");
26649
26739
  }
26650
- const entries = readdirSync3(dir);
26740
+ const entries = readdirSync4(dir);
26651
26741
  if (entries.length === 0) {
26652
26742
  throw new CliError("\u6784\u5EFA\u4EA7\u7269\u662F\u7A7A\u7684\uFF0C\u8BF7\u5148\u6784\u5EFA", "ZIP_EMPTY");
26653
26743
  }
26654
- const outPath = path13.join(
26744
+ const outPath = path12.join(
26655
26745
  tmpdir(),
26656
26746
  `freelog-zip-${process.pid}-${Date.now()}.zip`
26657
26747
  );
@@ -26661,7 +26751,7 @@ async function zipDirectoryContents(dir) {
26661
26751
  archive.on("error", (error2) => output2.destroy(error2));
26662
26752
  archive.pipe(output2);
26663
26753
  for (const entry2 of entries) {
26664
- const full = path13.join(dir, entry2);
26754
+ const full = path12.join(dir, entry2);
26665
26755
  const stats = statSync(full);
26666
26756
  if (stats.isDirectory()) {
26667
26757
  archive.directory(full, entry2);
@@ -26673,7 +26763,7 @@ async function zipDirectoryContents(dir) {
26673
26763
  await finished(output2);
26674
26764
  return outPath;
26675
26765
  } catch (error2) {
26676
- if (existsSync9(outPath)) {
26766
+ if (existsSync10(outPath)) {
26677
26767
  try {
26678
26768
  unlinkSync5(outPath);
26679
26769
  } catch {
@@ -26684,7 +26774,7 @@ async function zipDirectoryContents(dir) {
26684
26774
  }
26685
26775
  async function prepareUploadPath(typeCode, filePath) {
26686
26776
  assertArtifactPath(typeCode, filePath);
26687
- if (isThemeOrWidget2(typeCode) && existsSync9(filePath) && statSync(filePath).isDirectory()) {
26777
+ if (isThemeOrWidget2(typeCode) && existsSync10(filePath) && statSync(filePath).isDirectory()) {
26688
26778
  return zipDirectoryContents(filePath);
26689
26779
  }
26690
26780
  return filePath;
@@ -26694,11 +26784,11 @@ async function prepareUploadPath(typeCode, filePath) {
26694
26784
  var ANALYZE_TIMEOUT_MS = 12e4;
26695
26785
  var ANALYZE_POLL_INTERVAL_MS = 200;
26696
26786
  function resolveExistingPath(cwd, raw) {
26697
- if (existsSync10(raw)) {
26698
- return path14.resolve(raw);
26787
+ if (existsSync11(raw)) {
26788
+ return path13.resolve(raw);
26699
26789
  }
26700
- const joined = path14.resolve(cwd, raw);
26701
- if (existsSync10(joined)) {
26790
+ const joined = path13.resolve(cwd, raw);
26791
+ if (existsSync11(joined)) {
26702
26792
  return joined;
26703
26793
  }
26704
26794
  return void 0;
@@ -26757,7 +26847,7 @@ async function uploadIfNew(uploadPath, sha1, typeCode, apis) {
26757
26847
  await upload({ file: readFileSync9(uploadPath), resourceType: typeCode });
26758
26848
  }
26759
26849
  function removeTempZip(uploadPath, localPath) {
26760
- if (uploadPath === localPath || !existsSync10(uploadPath)) {
26850
+ if (uploadPath === localPath || !existsSync11(uploadPath)) {
26761
26851
  return;
26762
26852
  }
26763
26853
  try {
@@ -26811,7 +26901,7 @@ async function uploadAndAnalyzeLocked(input2) {
26811
26901
  const localPath = confirmLocalPath(identity, file, input2.yes, input2.cwd);
26812
26902
  const uploadPath = await prepareUploadPath(identity.typeCode, localPath);
26813
26903
  try {
26814
- const uploaded = { fileSha1: sha1OfFile(uploadPath), filename: path14.basename(uploadPath) };
26904
+ const uploaded = { fileSha1: sha1OfFile(uploadPath), filename: path13.basename(uploadPath) };
26815
26905
  await uploadIfNew(uploadPath, uploaded.fileSha1, identity.typeCode, input2.apis ?? {});
26816
26906
  const analysis = await waitAnalyze(
26817
26907
  uploaded.fileSha1,
@@ -26837,16 +26927,11 @@ async function uploadAndAnalyzeLocked(input2) {
26837
26927
  }
26838
26928
 
26839
26929
  // src/domain/version/artifact.ts
26840
- function resolveArtifactPath(cwd, identity, file, artifact) {
26930
+ function resolveArtifactPath(cwd, _identity, _selector, artifact) {
26841
26931
  if (artifact !== void 0) {
26842
26932
  return normalizeProjectPath(cwd, artifact);
26843
26933
  }
26844
- if (file === void 0) {
26845
- return void 0;
26846
- }
26847
- const selector = normalizeProjectPath(cwd, file);
26848
- const recorded = identity.filePath ? normalizeProjectPath(cwd, identity.filePath) : void 0;
26849
- return selector === recorded ? void 0 : selector;
26934
+ return void 0;
26850
26935
  }
26851
26936
 
26852
26937
  // src/domain/version/createVersion.ts
@@ -26921,7 +27006,7 @@ async function runCreateVersionLocked(input2) {
26921
27006
 
26922
27007
  // src/commands/version/create-version.ts
26923
27008
  function createCreateVersionCommand() {
26924
- const command = addSharedOptions(new Command19("create-version"));
27009
+ const command = addSharedOptions(new Command20("create-version"));
26925
27010
  command.description(
26926
27011
  // i18n: cli.command.create_version.description
26927
27012
  "\u63D0\u4EA4\u9996\u7248"
@@ -26953,7 +27038,7 @@ function createCreateVersionCommand() {
26953
27038
  }
26954
27039
 
26955
27040
  // src/commands/version/dep.ts
26956
- import { Command as Command20 } from "commander";
27041
+ import { Command as Command21 } from "commander";
26957
27042
 
26958
27043
  // src/domain/version/form/dep.ts
26959
27044
  import semver from "semver";
@@ -27223,7 +27308,7 @@ async function depRangeLocked(cwd, resourceId, versionRange, file, apis, options
27223
27308
 
27224
27309
  // src/commands/version/dep.ts
27225
27310
  function createVersionDepCommand() {
27226
- const dep = addSharedOptions(new Command20("dep"));
27311
+ const dep = addSharedOptions(new Command21("dep"));
27227
27312
  dep.description("\u6539\u7A3F\u4E0A\u7684\u4F9D\u8D56");
27228
27313
  addSharedOptions(dep.command("add")).description("\u52A0\u4F9D\u8D56").argument("<resourceId>", "\u4F9D\u8D56\u8D44\u6E90 id").option("--range <range>", "\u7248\u672C\u8303\u56F4").option("--policy-id <policyId>", "\u672A\u6388\u6743\u65F6\u8981\u7B7E\u7EA6\u7684\u7B56\u7565\u7F16\u53F7").action(async function(resourceId, options) {
27229
27314
  const shared = readSharedOptions(this);
@@ -27256,7 +27341,7 @@ function createVersionDepCommand() {
27256
27341
  }
27257
27342
 
27258
27343
  // src/commands/version/description.ts
27259
- import { Command as Command21 } from "commander";
27344
+ import { Command as Command22 } from "commander";
27260
27345
 
27261
27346
  // src/domain/version/description.ts
27262
27347
  async function updateOnlineDescription(input2) {
@@ -27289,7 +27374,7 @@ async function updateOnlineDescription(input2) {
27289
27374
 
27290
27375
  // src/commands/version/description.ts
27291
27376
  function createVersionDescriptionCommand() {
27292
- const command = addSharedOptions(new Command21("description"));
27377
+ const command = addSharedOptions(new Command22("description"));
27293
27378
  command.description(
27294
27379
  // i18n: cli.command.version.description.description
27295
27380
  "\u6539\u7EBF\u4E0A\u5DF2\u53D1\u53F7\u63CF\u8FF0"
@@ -27354,7 +27439,7 @@ function registerDraftDescription(draft) {
27354
27439
  }
27355
27440
 
27356
27441
  // src/commands/version/draft.ts
27357
- import { Command as Command22 } from "commander";
27442
+ import { Command as Command23 } from "commander";
27358
27443
 
27359
27444
  // src/domain/version/draftDiscard.ts
27360
27445
  function draftDiscard(cwd, file) {
@@ -27434,7 +27519,7 @@ async function draftPullLocked(input2) {
27434
27519
 
27435
27520
  // src/commands/version/draft.ts
27436
27521
  function createVersionDraftCommand() {
27437
- const draft = addSharedOptions(new Command22("draft"));
27522
+ const draft = addSharedOptions(new Command23("draft"));
27438
27523
  draft.description(
27439
27524
  // i18n: cli.command.version.draft.description
27440
27525
  "\u7BA1\u672C\u5730\u5DE5\u4F5C\u7A3F"
@@ -27467,7 +27552,7 @@ function createVersionDraftCommand() {
27467
27552
  }
27468
27553
 
27469
27554
  // src/commands/version/option.ts
27470
- import { Command as Command23 } from "commander";
27555
+ import { Command as Command24 } from "commander";
27471
27556
 
27472
27557
  // src/domain/version/form/option.ts
27473
27558
  var MAX_OPTION = 30;
@@ -27673,7 +27758,7 @@ function optionList(cwd, file) {
27673
27758
 
27674
27759
  // src/commands/version/option.ts
27675
27760
  function createVersionOptionCommand() {
27676
- const option = addSharedOptions(new Command23("option"));
27761
+ const option = addSharedOptions(new Command24("option"));
27677
27762
  option.description("\u6539\u7A3F\u4E0A\u7684\u53EF\u9009\u914D\u7F6E");
27678
27763
  addSharedOptions(option.command("add")).description("\u52A0\u53EF\u9009\u914D\u7F6E").argument("[line]", "\u4E00\u884C\u5F0F").action(async function(line) {
27679
27764
  const shared = readSharedOptions(this);
@@ -27703,7 +27788,7 @@ function createVersionOptionCommand() {
27703
27788
  }
27704
27789
 
27705
27790
  // src/commands/version/set.ts
27706
- import { Command as Command24 } from "commander";
27791
+ import { Command as Command25 } from "commander";
27707
27792
 
27708
27793
  // src/domain/version/setPath.ts
27709
27794
  function setIdentityFilePath(cwd, input2) {
@@ -27712,7 +27797,7 @@ function setIdentityFilePath(cwd, input2) {
27712
27797
  if (!artifact) {
27713
27798
  throw new CliError("\u8BF7\u63D0\u4F9B --artifact", "SET_ARTIFACT_REQUIRED");
27714
27799
  }
27715
- const identity = resolveIdentity(cwd);
27800
+ const identity = resolveIdentity(cwd, input2.file);
27716
27801
  const updated = prepareIdentityUpdate(cwd, identity.n, { filePath: artifact });
27717
27802
  commitLocalTransaction(cwd, [
27718
27803
  { path: identityFilePath(cwd, updated.n), content: serializeIdentity(updated) }
@@ -27723,7 +27808,7 @@ function setIdentityFilePath(cwd, input2) {
27723
27808
 
27724
27809
  // src/commands/version/set.ts
27725
27810
  function createVersionSetCommand() {
27726
- const command = addSharedOptions(new Command24("set"));
27811
+ const command = addSharedOptions(new Command25("set"));
27727
27812
  command.description(
27728
27813
  // i18n: cli.command.version.set.description
27729
27814
  "\u53EA\u6539\u8BB0\u5F55\u7684\u672C\u5730\u8DEF\u5F84"
@@ -27743,7 +27828,7 @@ function createVersionSetCommand() {
27743
27828
  }
27744
27829
 
27745
27830
  // src/commands/version/show.ts
27746
- import { Command as Command25 } from "commander";
27831
+ import { Command as Command26 } from "commander";
27747
27832
 
27748
27833
  // src/domain/version/show.ts
27749
27834
  function showLocal(cwd, file) {
@@ -27790,7 +27875,7 @@ async function showOnline(input2) {
27790
27875
 
27791
27876
  // src/commands/version/show.ts
27792
27877
  function createVersionShowCommand() {
27793
- const command = addSharedOptions(new Command25("show"));
27878
+ const command = addSharedOptions(new Command26("show"));
27794
27879
  command.description(
27795
27880
  // i18n: cli.command.version.show.description
27796
27881
  "\u53EA\u8BFB\u67E5\u770B"
@@ -27824,7 +27909,7 @@ function createVersionShowCommand() {
27824
27909
  }
27825
27910
 
27826
27911
  // src/commands/version/update-version.ts
27827
- import { Command as Command26 } from "commander";
27912
+ import { Command as Command27 } from "commander";
27828
27913
 
27829
27914
  // src/domain/version/updateVersion.ts
27830
27915
  import semver2 from "semver";
@@ -27933,7 +28018,7 @@ function resolveNextVersion(latest, version, bump) {
27933
28018
 
27934
28019
  // src/commands/version/update-version.ts
27935
28020
  function createUpdateVersionCommand() {
27936
- const command = addSharedOptions(new Command26("update-version"));
28021
+ const command = addSharedOptions(new Command27("update-version"));
27937
28022
  command.description(
27938
28023
  // i18n: cli.command.update_version.description
27939
28024
  "\u5B9A\u65B0\u53F7\u5E76\u63D0\u4EA4"
@@ -27976,7 +28061,7 @@ function createUpdateVersionCommand() {
27976
28061
 
27977
28062
  // src/commands/index.ts
27978
28063
  function createVersionCommand() {
27979
- const version = addSharedOptions(new Command27("version"));
28064
+ const version = addSharedOptions(new Command28("version"));
27980
28065
  version.description(
27981
28066
  // i18n: cli.command.version.description
27982
28067
  "\u770B\u7EBF\u4E0A\u3001\u7BA1\u5DE5\u4F5C\u7A3F\u3001\u6539\u7A3F"
@@ -27993,7 +28078,7 @@ function createVersionCommand() {
27993
28078
  return version;
27994
28079
  }
27995
28080
  function createPolicyCommand() {
27996
- const policy = addSharedOptions(new Command27("policy"));
28081
+ const policy = addSharedOptions(new Command28("policy"));
27997
28082
  policy.description(
27998
28083
  // i18n: cli.command.policy.description
27999
28084
  "\u6388\u6743\u7B56\u7565"
@@ -28011,6 +28096,7 @@ function createSubCommands() {
28011
28096
  init: createInitCommand(),
28012
28097
  template: createTemplateCommand(),
28013
28098
  type: createTypeCommand(),
28099
+ resource: createResourceCommand(),
28014
28100
  bind: createBindCommand(),
28015
28101
  status: createStatusCommand(),
28016
28102
  create: createCreateCommand(),
@@ -28026,32 +28112,32 @@ function createSubCommands() {
28026
28112
  }
28027
28113
 
28028
28114
  // src/core/usageDocs.ts
28029
- import { existsSync as existsSync11 } from "fs";
28030
- import path15 from "path";
28115
+ import { existsSync as existsSync12 } from "fs";
28116
+ import path14 from "path";
28031
28117
  import { fileURLToPath } from "url";
28032
28118
  function usageDocsPath() {
28033
- const moduleDir = path15.dirname(fileURLToPath(import.meta.url));
28034
- const bundledPath = path15.resolve(moduleDir, "../docs/README.md");
28035
- if (existsSync11(bundledPath)) {
28119
+ const moduleDir = path14.dirname(fileURLToPath(import.meta.url));
28120
+ const bundledPath = path14.resolve(moduleDir, "../docs/README.md");
28121
+ if (existsSync12(bundledPath)) {
28036
28122
  return bundledPath;
28037
28123
  }
28038
- return path15.resolve(moduleDir, "../../../../docs/\u4E00\u671F/\u4EA7\u54C1\u65B9\u6848/\u4F7F\u7528/README.md");
28124
+ return path14.resolve(moduleDir, "../../../../docs/\u4E00\u671F/\u4EA7\u54C1\u65B9\u6848/\u4F7F\u7528/README.md");
28039
28125
  }
28040
28126
 
28041
28127
  // src/core/packageVersion.ts
28042
28128
  import { readFileSync as readFileSync10 } from "fs";
28043
- import path16 from "path";
28129
+ import path15 from "path";
28044
28130
  import { fileURLToPath as fileURLToPath2 } from "url";
28045
28131
  function packageVersion() {
28046
- const moduleDir = path16.dirname(fileURLToPath2(import.meta.url));
28047
- const packageJson = path16.resolve(moduleDir, "../..", "package.json");
28132
+ const moduleDir = path15.dirname(fileURLToPath2(import.meta.url));
28133
+ const packageJson = path15.resolve(moduleDir, "../..", "package.json");
28048
28134
  const value = JSON.parse(readFileSync10(packageJson, "utf8"));
28049
28135
  return typeof value.version === "string" ? value.version : "unknown";
28050
28136
  }
28051
28137
 
28052
28138
  // src/bin/program.ts
28053
28139
  function createProgram() {
28054
- const program = new Command28();
28140
+ const program = new Command29();
28055
28141
  program.name("freelog-cli").description(
28056
28142
  // i18n: cli.program.description
28057
28143
  "Freelog \u547D\u4EE4\u884C"
@@ -28064,17 +28150,68 @@ function createProgram() {
28064
28150
  \u4F7F\u7528\u6587\u6863\uFF1A${usageDocsPath()}
28065
28151
  `);
28066
28152
  addSharedOptions(program);
28067
- program.hook("preAction", (thisCommand) => {
28068
- const envFlag = findOptionValue(thisCommand, "env");
28153
+ program.hook("preAction", async (thisCommand, actionCommand) => {
28154
+ const envFlag = findOptionValue(actionCommand ?? thisCommand, "env");
28069
28155
  applyCliEnv({ flag: typeof envFlag === "string" ? envFlag : void 0 });
28070
- const cwdFlag = findOptionValue(thisCommand, "cwd");
28071
- setAuthSearchCwd(resolveCwd(typeof cwdFlag === "string" ? cwdFlag : void 0));
28156
+ const cwdFlag = findOptionValue(actionCommand ?? thisCommand, "cwd");
28157
+ const cwd = resolveCwd(typeof cwdFlag === "string" ? cwdFlag : void 0);
28158
+ setAuthSearchCwd(cwd);
28159
+ await chooseResourceWhenNeeded(actionCommand ?? thisCommand, cwd);
28072
28160
  });
28073
28161
  for (const command of Object.values(createSubCommands())) {
28074
28162
  program.addCommand(command);
28075
28163
  }
28076
28164
  return program;
28077
28165
  }
28166
+ var RESOURCE_FREE_COMMANDS = /* @__PURE__ */ new Set(["login", "logout", "init", "template", "type", "resource", "create", "bind"]);
28167
+ async function chooseResourceWhenNeeded(command, cwd) {
28168
+ if (isResourceFreeCommand(command)) return;
28169
+ const selector = findOptionValue(command, "resource");
28170
+ if (typeof selector === "string") return;
28171
+ const identities = validateLocalState(cwd);
28172
+ if (identities.length <= 1) return;
28173
+ const yes = findOptionValue(command, "yes") === true;
28174
+ if (yes || !isInteractive()) {
28175
+ throw new CliError(
28176
+ `\u5F53\u524D\u5DE5\u7A0B\u6709\u591A\u4EFD\u8D44\u6E90\u72B6\u6001\uFF1B\u975E\u4EA4\u4E92\u8C03\u7528\u8BF7\u4F7F\u7528 --resource \u6307\u5B9A\u8D44\u6E90\u3002\u4F8B\u5982\uFF1A${resourceSelectorExamples(identities)}`,
28177
+ "IDENTITY_RESOURCE_REQUIRED"
28178
+ );
28179
+ }
28180
+ const selected = await selectQuestion("\u8BF7\u9009\u62E9\u8D44\u6E90", [
28181
+ ...identities.map((identity) => ({
28182
+ name: resourceChoiceLabel(cwd, identity),
28183
+ value: `file:${identity.n}.json`
28184
+ })),
28185
+ { name: "\u9000\u51FA", value: "__cancel__" }
28186
+ ]);
28187
+ if (selected === "__cancel__") {
28188
+ throw new CliError("\u5DF2\u53D6\u6D88", "RESOURCE_SELECTION_CANCELLED");
28189
+ }
28190
+ command.setOptionValue("resource", selected);
28191
+ }
28192
+ function resourceChoiceLabel(cwd, identity) {
28193
+ const draft = readDraft(cwd, identity.n) ? "\u6709\u5DE5\u4F5C\u7A3F" : "\u65E0\u5DE5\u4F5C\u7A3F";
28194
+ return [
28195
+ `${identity.n}.json`,
28196
+ `\u6807\u9898=${identity.title ?? "\uFF08\u672A\u540C\u6B65\u6807\u9898\uFF09"}`,
28197
+ `\u6807\u8BC6=${identity.name ?? "\u672A\u7ED1\u5B9A"}`,
28198
+ `ID=${identity.resourceId ?? "\u672A\u7ED1\u5B9A"}`,
28199
+ `\u7C7B\u578B=${identity.typeCode}`,
28200
+ `\u4EA7\u7269=${identity.filePath ?? "\u672A\u8BBE\u7F6E"}`,
28201
+ draft
28202
+ ].join(" ");
28203
+ }
28204
+ function resourceSelectorExamples(identities) {
28205
+ return identities.map((identity) => `file:${identity.n}.json\uFF08${identity.title ?? "\u672A\u540C\u6B65\u6807\u9898"}\uFF1B${identity.name ?? "\u672A\u7ED1\u5B9A"}\uFF1B${identity.resourceId ?? "\u672A\u7ED1\u5B9A"}\uFF09`).join("\u3001");
28206
+ }
28207
+ function isResourceFreeCommand(command) {
28208
+ let current = command;
28209
+ while (current) {
28210
+ if (RESOURCE_FREE_COMMANDS.has(current.name())) return true;
28211
+ current = current.parent;
28212
+ }
28213
+ return false;
28214
+ }
28078
28215
  async function runCli(argv, options = {}) {
28079
28216
  const writeOut = options.writeOut ?? ((text) => {
28080
28217
  process.stdout.write(text);