@freelog-cli/cli2 0.5.1 → 0.5.3

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(path19) {
9172
+ if (!path19 || typeof path19 !== "string") {
9173
9173
  return false;
9174
9174
  }
9175
- var extension2 = extname("x." + path17).toLowerCase().substr(1);
9175
+ var extension2 = extname("x." + path19).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 path19 = __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 = path19.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 = path19.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 = path19.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(path19, key, dots) {
13343
+ if (!path19) return key;
13344
+ return path19.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, path19) {
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(path19, key, dots), convertValue(value));
13434
13434
  return false;
13435
13435
  }
13436
- if (value && !path17 && typeof value === "object") {
13436
+ if (value && !path19 && 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(path19, 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, path19, 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 " + path19.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, path19, exposedHelpers);
13472
13472
  if (result === true) {
13473
- build(el, path17 ? path17.concat(key) : [key], depth + 1);
13473
+ build(el, path19 ? path19.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, path19, 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 path19 = [];
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(path19.length);
13712
+ path19.push(match[0] === "[]" ? "" : match[1] || match[0]);
13713
13713
  }
13714
- return path17;
13714
+ return path19;
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(path19, value, target, index) {
13730
13730
  throwIfDepthExceeded(index);
13731
- let name = path17[index++];
13731
+ let name = path19[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 >= path19.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(path19, 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 path19;
15466
15466
  try {
15467
- path17 = buildURL(
15467
+ path19 = 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: path19,
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, path19, 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(path19)) {
15895
+ cookie.push(`path=${path19}`);
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, path19, 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 path19 !== "string" ? [].concat(path19) : path19.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, path19, newValue) {
17814
+ var _getLastOfPath = getLastOfPath(object, path19, 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, path19, newValue, concat) {
17818
+ var _getLastOfPath2 = getLastOfPath(object, path19, 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, path19) {
17824
+ var _getLastOfPath3 = getLastOfPath(object, path19), 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, path19) {
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[path19]) return obj[path19];
17950
+ var paths = path19.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 (path19.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 path19 = [lng, ns];
18026
+ if (key && typeof key !== "string") path19 = path19.concat(key);
18027
+ if (key && typeof key === "string") path19 = path19.concat(keySeparator ? key.split(keySeparator) : key);
18028
18028
  if (lng.indexOf(".") > -1) {
18029
- path17 = lng.split(".");
18029
+ path19 = lng.split(".");
18030
18030
  }
18031
- var result = getPath(this.data, path17);
18031
+ var result = getPath(this.data, path19);
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 path19 = [lng, ns];
18044
+ if (key) path19 = path19.concat(keySeparator ? key.split(keySeparator) : key);
18045
18045
  if (lng.indexOf(".") > -1) {
18046
- path17 = lng.split(".");
18046
+ path19 = lng.split(".");
18047
18047
  value = ns;
18048
- ns = path17[1];
18048
+ ns = path19[1];
18049
18049
  }
18050
18050
  this.addNamespaces(ns);
18051
- setPath(this.data, path17, value);
18051
+ setPath(this.data, path19, 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 path19 = [lng, ns];
18074
18074
  if (lng.indexOf(".") > -1) {
18075
- path17 = lng.split(".");
18075
+ path19 = lng.split(".");
18076
18076
  deep = resources;
18077
18077
  resources = ns;
18078
- ns = path17[1];
18078
+ ns = path19[1];
18079
18079
  }
18080
18080
  this.addNamespaces(ns);
18081
- var pack = getPath(this.data, path17) || {};
18081
+ var pack = getPath(this.data, path19) || {};
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, path19, 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 path19 = getPathWithDefaults(data, defaultData, key);
19082
+ return _this.alwaysFormat ? _this.format(path19, void 0, lng, _objectSpread$3(_objectSpread$3(_objectSpread$3({}, options), data), {}, {
19083
19083
  interpolationkey: key
19084
- })) : path17;
19084
+ })) : path19;
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\uFF08id:\u3001name:\u3001title:\u3001artifact: \u6216 file:N.json\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) {
@@ -24247,7 +24248,7 @@ function createLogoutCommand() {
24247
24248
  import { Command as Command4 } from "commander";
24248
24249
 
24249
24250
  // src/domain/create/create.ts
24250
- import path8 from "path";
24251
+ import path10 from "path";
24251
24252
 
24252
24253
  // src/local/identity.ts
24253
24254
  import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync4 } from "fs";
@@ -24456,8 +24457,9 @@ var inputFields = {
24456
24457
  subject: z2.literal("resource"),
24457
24458
  resourceId: z2.string().min(1).optional(),
24458
24459
  name: z2.string().min(1).optional(),
24460
+ title: z2.string().min(1).optional(),
24459
24461
  typeCode: z2.string().min(1),
24460
- filePath: z2.string().min(1).optional(),
24462
+ filePath: z2.string().min(1),
24461
24463
  env: z2.enum(["prod", "test", "dev"]).optional()
24462
24464
  };
24463
24465
  var createSchema = z2.object(inputFields).strict();
@@ -24468,7 +24470,8 @@ var storedSchema = z2.object({
24468
24470
  }).strict().superRefine((identity, ctx) => {
24469
24471
  const hasResourceId = identity.resourceId !== void 0;
24470
24472
  const hasName = identity.name !== void 0;
24471
- const bound = hasResourceId || hasName;
24473
+ const hasTitle = identity.title !== void 0;
24474
+ const bound = hasResourceId || hasName || hasTitle;
24472
24475
  if (hasResourceId !== hasName) {
24473
24476
  ctx.addIssue({
24474
24477
  code: ZodIssueCode.custom,
@@ -24476,6 +24479,9 @@ var storedSchema = z2.object({
24476
24479
  message: "\u7ED1\u5B9A\u8EAB\u4EFD\u5FC5\u987B\u540C\u65F6\u5305\u542B resourceId \u548C name"
24477
24480
  });
24478
24481
  }
24482
+ if (!hasResourceId && !hasName && hasTitle) {
24483
+ ctx.addIssue({ code: ZodIssueCode.custom, path: ["title"], message: "\u672A\u7ED1\u5B9A\u8EAB\u4EFD\u4E0D\u80FD\u5199\u5165 title" });
24484
+ }
24479
24485
  if (!bound && identity.env !== void 0) {
24480
24486
  ctx.addIssue({
24481
24487
  code: ZodIssueCode.custom,
@@ -24510,8 +24516,11 @@ function throwZodAsCliError(error2) {
24510
24516
  if (field === "subject") {
24511
24517
  throw new CliError("\u672C\u671F\u53EA\u652F\u6301\u5355\u8D44\u6E90", "IDENTITY_SUBJECT_UNSUPPORTED");
24512
24518
  }
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");
24519
+ if (field === "name" || field === "resourceId" || field === "title") {
24520
+ throw new CliError("\u7ED1\u5B9A\u8EAB\u4EFD\u5B57\u6BB5\u4E0D\u5B8C\u6574", "IDENTITY_BINDING_INVALID");
24521
+ }
24522
+ if (field === "filePath") {
24523
+ throw new CliError("\u6BCF\u4EFD\u8D44\u6E90\u72B6\u6001\u5FC5\u987B\u5173\u8054\u672C\u5730\u4EA7\u7269\u8DEF\u5F84", "IDENTITY_ARTIFACT_REQUIRED");
24515
24524
  }
24516
24525
  throw new CliError("\u8EAB\u4EFD\u5B57\u6BB5\u65E0\u6548", "IDENTITY_INVALID");
24517
24526
  }
@@ -24521,8 +24530,9 @@ function toStored(data) {
24521
24530
  subject: data.subject,
24522
24531
  ...data.resourceId ? { resourceId: data.resourceId } : {},
24523
24532
  ...data.name ? { name: data.name } : {},
24533
+ ...data.title ? { title: data.title } : {},
24524
24534
  typeCode: data.typeCode,
24525
- ...data.filePath ? { filePath: data.filePath } : {},
24535
+ filePath: data.filePath,
24526
24536
  ...data.env === "test" || data.env === "dev" ? { env: data.env } : {}
24527
24537
  };
24528
24538
  }
@@ -24539,8 +24549,9 @@ function toDiskObject(identity) {
24539
24549
  subject: identity.subject,
24540
24550
  ...identity.resourceId ? { resourceId: identity.resourceId } : {},
24541
24551
  ...identity.name ? { name: identity.name } : {},
24552
+ ...identity.title ? { title: identity.title } : {},
24542
24553
  typeCode: identity.typeCode,
24543
- ...identity.filePath ? { filePath: identity.filePath } : {},
24554
+ filePath: identity.filePath,
24544
24555
  ...identity.env ? { env: identity.env } : {}
24545
24556
  };
24546
24557
  }
@@ -24565,6 +24576,7 @@ function prepareIdentityUpdate(cwd, n, patch) {
24565
24576
  subject: parsed.subject ?? current.subject,
24566
24577
  resourceId: parsed.resourceId ?? current.resourceId,
24567
24578
  name: parsed.name ?? current.name,
24579
+ title: parsed.title ?? current.title,
24568
24580
  typeCode: parsed.typeCode ?? current.typeCode,
24569
24581
  filePath: parsed.filePath ?? current.filePath,
24570
24582
  env: parsed.env ?? current.env
@@ -24572,10 +24584,8 @@ function prepareIdentityUpdate(cwd, n, patch) {
24572
24584
  return { n, ...identity };
24573
24585
  }
24574
24586
  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) };
24587
+ const numbers = listIdentityNumbers(cwd);
24588
+ return { n: numbers.length === 0 ? 1 : Math.max(...numbers) + 1, ...parseCreateInput(input2) };
24579
24589
  }
24580
24590
  function parsePatchInput(input2) {
24581
24591
  const parsed = patchSchema.safeParse(input2);
@@ -24633,6 +24643,212 @@ function updateIdentity(cwd, n, patch) {
24633
24643
  }, "update-identity");
24634
24644
  }
24635
24645
 
24646
+ // src/local/resolve.ts
24647
+ import { existsSync as existsSync7, readdirSync as readdirSync2 } from "fs";
24648
+
24649
+ // src/local/draft.ts
24650
+ import { existsSync as existsSync6, readFileSync as readFileSync5, unlinkSync as unlinkSync4 } from "fs";
24651
+ import path7 from "path";
24652
+ import { z as z3 } from "zod";
24653
+ var itemList = z3.array(z3.record(z3.unknown()));
24654
+ var draftSchema = z3.object({
24655
+ schemaVersion: z3.literal(1),
24656
+ draftKind: z3.enum(["initial", "update"]),
24657
+ resourceId: z3.string().min(1),
24658
+ resourceTypeCode: z3.string().min(1),
24659
+ fromVersion: z3.string().min(1).optional(),
24660
+ fileSha1: z3.string().min(1).nullable(),
24661
+ filename: z3.string().min(1).nullable(),
24662
+ analyzedSha1: z3.string().min(1).nullable(),
24663
+ description: z3.string(),
24664
+ inputAttrs: itemList,
24665
+ orphanedInputAttrs: itemList,
24666
+ customPropertyDescriptors: itemList,
24667
+ dependencies: itemList,
24668
+ baseUpcastResources: z3.array(z3.never()),
24669
+ authExcludedItems: z3.array(z3.never())
24670
+ }).strict().superRefine((draft, ctx) => {
24671
+ if (draft.draftKind === "initial" && (draft.fromVersion || draft.description !== "")) {
24672
+ ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "initial \u5DE5\u4F5C\u7A3F\u4E0D\u80FD\u6709\u6765\u6E90\u7248\u672C\u6216\u63CF\u8FF0" });
24673
+ }
24674
+ if (draft.draftKind === "update" && !draft.fromVersion) {
24675
+ ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "update \u5DE5\u4F5C\u7A3F\u5FC5\u987B\u6709\u6765\u6E90\u7248\u672C" });
24676
+ }
24677
+ if (draft.analyzedSha1 !== null && draft.analyzedSha1 !== draft.fileSha1) {
24678
+ ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "analyzedSha1 \u5FC5\u987B\u7B49\u4E8E fileSha1" });
24679
+ }
24680
+ if (draft.fileSha1 === null && (draft.filename !== null || draft.analyzedSha1 !== null)) {
24681
+ ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "\u65E0\u6587\u4EF6\u65F6\u4E0D\u80FD\u4FDD\u7559\u6587\u4EF6\u540D\u6216\u5206\u6790 SHA" });
24682
+ }
24683
+ });
24684
+ function draftFilePath(cwd, n) {
24685
+ return path7.join(freelogDir(cwd), `${n}.version.json`);
24686
+ }
24687
+ function emptyDraft() {
24688
+ return { baseUpcastResources: [], authExcludedItems: [] };
24689
+ }
24690
+ function prepareDraft(cwd, n, input2) {
24691
+ const identity = readIdentity(cwd, n);
24692
+ if (!identity.resourceId) {
24693
+ throw new CliError("\u8BF7\u5148 create \u6216 bind\uFF0C\u518D\u7F16\u8F91\u7248\u672C\u5DE5\u4F5C\u7A3F", "DRAFT_IDENTITY_UNBOUND");
24694
+ }
24695
+ if (input2.resourceId !== void 0 && input2.resourceId !== identity.resourceId) {
24696
+ throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u4E0E\u8EAB\u4EFD\u4E0D\u4E00\u81F4`, "DRAFT_IDENTITY_MISMATCH");
24697
+ }
24698
+ if (input2.resourceTypeCode !== void 0 && input2.resourceTypeCode !== identity.typeCode) {
24699
+ throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u4E0E\u8EAB\u4EFD\u4E0D\u4E00\u81F4`, "DRAFT_IDENTITY_MISMATCH");
24700
+ }
24701
+ const draftKind = input2.draftKind ?? (input2.fromVersion ? "update" : "initial");
24702
+ const fileSha1 = input2.fileSha1 ?? null;
24703
+ const value = {
24704
+ schemaVersion: 1,
24705
+ draftKind,
24706
+ resourceId: identity.resourceId,
24707
+ resourceTypeCode: input2.resourceTypeCode ?? identity.typeCode,
24708
+ ...draftKind === "update" ? { fromVersion: input2.fromVersion } : {},
24709
+ fileSha1,
24710
+ filename: fileSha1 ? input2.filename ?? null : null,
24711
+ analyzedSha1: fileSha1 ? input2.analyzedSha1 ?? null : null,
24712
+ description: draftKind === "initial" ? "" : input2.description ?? "",
24713
+ inputAttrs: input2.inputAttrs ?? [],
24714
+ orphanedInputAttrs: input2.orphanedInputAttrs ?? [],
24715
+ customPropertyDescriptors: input2.customPropertyDescriptors ?? [],
24716
+ dependencies: input2.dependencies ?? [],
24717
+ baseUpcastResources: [],
24718
+ authExcludedItems: []
24719
+ };
24720
+ const parsed = draftSchema.safeParse(value);
24721
+ if (!parsed.success) throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u65E0\u6548`, "DRAFT_INVALID");
24722
+ return parsed.data;
24723
+ }
24724
+ function serializeDraft(draft) {
24725
+ return `${JSON.stringify(draft, null, 2)}
24726
+ `;
24727
+ }
24728
+ function readDraft(cwd, n) {
24729
+ const filePath = draftFilePath(cwd, n);
24730
+ if (!existsSync6(filePath)) return void 0;
24731
+ let raw;
24732
+ try {
24733
+ raw = JSON.parse(readFileSync5(filePath, "utf8"));
24734
+ } catch {
24735
+ throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u65E0\u6CD5\u89E3\u6790`, "DRAFT_INVALID");
24736
+ }
24737
+ const parsed = draftSchema.safeParse(raw);
24738
+ if (!parsed.success) throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u65E0\u6548\uFF1B\u4EC5\u652F\u6301 schemaVersion=1`, "DRAFT_INVALID");
24739
+ const identity = readIdentity(cwd, n);
24740
+ if (!identity.resourceId || parsed.data.resourceId !== identity.resourceId || parsed.data.resourceTypeCode !== identity.typeCode) {
24741
+ throw new CliError(`\u5DE5\u4F5C\u7A3F ${n}.version.json \u4E0E\u8EAB\u4EFD\u4E0D\u4E00\u81F4`, "DRAFT_IDENTITY_MISMATCH");
24742
+ }
24743
+ return parsed.data;
24744
+ }
24745
+ function writeDraft(cwd, n, draft) {
24746
+ return withProjectLock(cwd, () => {
24747
+ const normalized = prepareDraft(cwd, n, draft);
24748
+ atomicWriteFile(draftFilePath(cwd, n), serializeDraft(normalized));
24749
+ return normalized;
24750
+ }, "write-version-draft");
24751
+ }
24752
+ function deleteDraft(cwd, n) {
24753
+ return withProjectLock(cwd, () => {
24754
+ const filePath = draftFilePath(cwd, n);
24755
+ if (!existsSync6(filePath)) return false;
24756
+ unlinkSync4(filePath);
24757
+ return true;
24758
+ }, "delete-version-draft");
24759
+ }
24760
+ function draftSummary(draft) {
24761
+ const source = draft.draftKind === "update" ? draft.fromVersion ?? "\u66F4\u65B0" : "\u9996\u7248";
24762
+ const sha1 = draft.fileSha1 ? `${draft.fileSha1.slice(0, 8)}\u2026` : "\u65E0";
24763
+ 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");
24764
+ }
24765
+
24766
+ // src/local/projectPath.ts
24767
+ import path8 from "path";
24768
+ var defaultError = {
24769
+ code: "FILE_PATH_OUTSIDE_PROJECT",
24770
+ message: "\u8DEF\u5F84\u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
24771
+ };
24772
+ function normalizeProjectPath(cwd, rawPath, error2 = defaultError) {
24773
+ if (!rawPath.trim() || path8.isAbsolute(rawPath) || path8.win32.isAbsolute(rawPath) || path8.posix.isAbsolute(rawPath)) {
24774
+ throw new CliError(error2.message, error2.code);
24775
+ }
24776
+ const root = path8.resolve(cwd);
24777
+ const resolved = path8.resolve(root, rawPath);
24778
+ const relative = path8.relative(root, resolved);
24779
+ if (!relative || relative.startsWith("..") || path8.isAbsolute(relative)) {
24780
+ throw new CliError(error2.message, error2.code);
24781
+ }
24782
+ return relative.replaceAll("\\", "/");
24783
+ }
24784
+
24785
+ // src/local/resolve.ts
24786
+ function assertNoDuplicate(cwd, identities, key) {
24787
+ const seen = /* @__PURE__ */ new Map();
24788
+ for (const identity of identities) {
24789
+ const value = identity[key];
24790
+ if (!value) continue;
24791
+ const comparable = key === "filePath" ? normalizeProjectPath(cwd, value) : value;
24792
+ const previous = seen.get(comparable);
24793
+ if (previous !== void 0) {
24794
+ throw new CliError(`\u672C\u5730\u72B6\u6001\u51B2\u7A81\uFF1A${previous}.json \u4E0E ${identity.n}.json \u4F7F\u7528\u540C\u4E00 ${key}`, "IDENTITY_CONFLICT");
24795
+ }
24796
+ seen.set(comparable, identity.n);
24797
+ }
24798
+ }
24799
+ function matches(cwd, identity, selector) {
24800
+ if (selector.startsWith("file:")) return `${identity.n}.json` === selector.slice(5);
24801
+ if (selector.startsWith("id:")) return identity.resourceId === selector.slice(3);
24802
+ if (selector.startsWith("name:")) return identity.name === selector.slice(5) || identity.name === selector.slice(5).split("/").pop();
24803
+ if (selector.startsWith("title:")) return identity.title === selector.slice(6);
24804
+ if (selector.startsWith("artifact:")) {
24805
+ return normalizeProjectPath(cwd, identity.filePath) === normalizeProjectPath(
24806
+ cwd,
24807
+ selector.slice("artifact:".length)
24808
+ );
24809
+ }
24810
+ return `${identity.n}.json` === selector || identity.resourceId === selector || identity.name === selector || identity.title === selector;
24811
+ }
24812
+ var DRAFT_FILE_RE = /^([1-9]\d*)\.version\.json$/;
24813
+ function validateLocalState(cwd) {
24814
+ const identities = listIdentities(cwd);
24815
+ assertNoDuplicate(cwd, identities, "resourceId");
24816
+ assertNoDuplicate(cwd, identities, "name");
24817
+ assertNoDuplicate(cwd, identities, "filePath");
24818
+ const numbers = new Set(identities.map((identity) => identity.n));
24819
+ const dir = freelogDir(cwd);
24820
+ if (!existsSync7(dir)) return identities;
24821
+ for (const fileName of readdirSync2(dir)) {
24822
+ const match = DRAFT_FILE_RE.exec(fileName);
24823
+ if (!match) continue;
24824
+ const n = Number(match[1]);
24825
+ if (!numbers.has(n)) {
24826
+ throw new CliError(`\u5DE5\u4F5C\u7A3F ${fileName} \u6CA1\u6709\u540C\u53F7\u8EAB\u4EFD\u6587\u4EF6`, "DRAFT_ORPHAN");
24827
+ }
24828
+ readDraft(cwd, n);
24829
+ }
24830
+ return identities;
24831
+ }
24832
+ function resolveIdentity(cwd, selector) {
24833
+ const identities = validateLocalState(cwd);
24834
+ if (identities.length === 0) {
24835
+ throw new CliError(
24836
+ "\u5F53\u524D\u76EE\u5F55\u6CA1\u6709\u8D44\u6E90\u72B6\u6001\u3002\u65B0\u8D44\u6E90\u53EF\u76F4\u63A5 create --type <\u53F6\u5B50\u7C7B\u578B> --artifact <\u8DEF\u5F84>\uFF0C\u4E5F\u53EF\u5148 init \u518D create\uFF1B\u5DF2\u6709\u8D44\u6E90\u8BF7 bind <\u8D44\u6E90 ID|\u6807\u8BC6\u7B26> --artifact <\u8DEF\u5F84>\u3002",
24837
+ "IDENTITY_NOT_FOUND"
24838
+ );
24839
+ }
24840
+ if (!selector) {
24841
+ if (identities.length === 1) return identities[0];
24842
+ 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");
24843
+ }
24844
+ const matched = identities.filter((identity) => matches(cwd, identity, selector));
24845
+ if (matched.length === 1) return matched[0];
24846
+ if (matched.length === 0) {
24847
+ throw new CliError(`\u627E\u4E0D\u5230\u8D44\u6E90\u9009\u62E9\u5668 ${selector}`, "IDENTITY_RESOURCE_NOT_FOUND");
24848
+ }
24849
+ throw new CliError(`\u8D44\u6E90\u9009\u62E9\u5668 ${selector} \u5339\u914D\u591A\u4EFD\u72B6\u6001\uFF1B\u8BF7\u4F7F\u7528 id:\u3001name:\u3001artifact: \u6216 file:`, "IDENTITY_RESOURCE_AMBIGUOUS");
24850
+ }
24851
+
24636
24852
  // src/core/tty.ts
24637
24853
  import { confirm as inquirerConfirm, input as inquirerInput, select as inquirerSelect } from "@inquirer/prompts";
24638
24854
  function isInteractive() {
@@ -24646,7 +24862,7 @@ async function confirmQuestion(message, defaultYes = true) {
24646
24862
  }
24647
24863
  async function askInput2(message) {
24648
24864
  if (!isInteractive()) {
24649
- throw new CliError("\u8BF7\u63D0\u4F9B --file \u6216 --yes", "TTY_REQUIRED");
24865
+ throw new CliError("\u975E\u4EA4\u4E92\u6A21\u5F0F\u8BF7\u663E\u5F0F\u63D0\u4F9B\u5FC5\u9700\u53C2\u6570", "TTY_REQUIRED");
24650
24866
  }
24651
24867
  return inquirerInput({ message });
24652
24868
  }
@@ -24670,6 +24886,16 @@ async function confirmWrite(preview, yes) {
24670
24886
  }
24671
24887
  return preview;
24672
24888
  }
24889
+ async function confirmDestructive(preview, action, yes, interactive = isInteractive(), ask = confirmQuestion) {
24890
+ if (yes) {
24891
+ return true;
24892
+ }
24893
+ if (!interactive) {
24894
+ throw new CliError(`\u6709\u672A\u63D0\u4EA4\u5DE5\u4F5C\u7A3F\uFF1B\u8BF7\u52A0 --yes \u786E\u8BA4${action}`, "DRAFT_DESTRUCTIVE_NEED_YES");
24895
+ }
24896
+ return ask(`${preview}
24897
+ \u786E\u8BA4${action}\uFF1F`, false);
24898
+ }
24673
24899
 
24674
24900
  // src/domain/create/typePick.ts
24675
24901
  function unwrapList(result) {
@@ -24805,29 +25031,83 @@ function formatTypeList(items) {
24805
25031
  return items.map((item) => `${item.code} ${item.nameChain ?? item.name}`).join("\n");
24806
25032
  }
24807
25033
 
24808
- // src/local/projectPath.ts
24809
- import path7 from "path";
24810
- var defaultError = {
24811
- code: "FILE_PATH_OUTSIDE_PROJECT",
24812
- message: "\u8DEF\u5F84\u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
24813
- };
24814
- function normalizeProjectPath(cwd, rawPath, error2 = defaultError) {
24815
- if (!rawPath.trim() || path7.isAbsolute(rawPath) || path7.win32.isAbsolute(rawPath) || path7.posix.isAbsolute(rawPath)) {
24816
- throw new CliError(error2.message, error2.code);
25034
+ // src/domain/version/zip.ts
25035
+ import { createWriteStream, existsSync as existsSync8, readdirSync as readdirSync3, statSync, unlinkSync as unlinkSync5 } from "fs";
25036
+ import { tmpdir } from "os";
25037
+ import path9 from "path";
25038
+ import { finished } from "stream/promises";
25039
+ import archiver from "archiver";
25040
+ function isThemeOrWidget(typeCode) {
25041
+ return typeCode === "RT001" || typeCode === "RT002";
25042
+ }
25043
+ function assertArtifactPath(typeCode, filePath) {
25044
+ const stats = existsSync8(filePath) ? statSync(filePath) : void 0;
25045
+ const themeOrWidget = isThemeOrWidget(typeCode);
25046
+ if (stats?.isDirectory() && !themeOrWidget) {
25047
+ throw new CliError("\u4E0D\u652F\u6301\u6587\u4EF6\u5939\uFF0C\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6587\u4EF6\u3002", "FILE_DIRECTORY_UNSUPPORTED");
24817
25048
  }
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)) {
24822
- throw new CliError(error2.message, error2.code);
25049
+ }
25050
+ function assertArtifactAnchor(typeCode, filePath) {
25051
+ if (!existsSync8(filePath)) {
25052
+ throw new CliError(`\u672C\u5730\u4EA7\u7269\u4E0D\u5B58\u5728\uFF1A${filePath}`, "ARTIFACT_ANCHOR_MISSING");
24823
25053
  }
24824
- return relative.replaceAll("\\", "/");
25054
+ const stats = statSync(filePath);
25055
+ assertArtifactPath(typeCode, filePath);
25056
+ if (!isThemeOrWidget(typeCode) && !stats.isFile()) {
25057
+ throw new CliError("\u4E0D\u652F\u6301\u6587\u4EF6\u5939\uFF0C\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6587\u4EF6\u3002", "FILE_DIRECTORY_UNSUPPORTED");
25058
+ }
25059
+ }
25060
+ async function zipDirectoryContents(dir) {
25061
+ if (!existsSync8(dir) || !statSync(dir).isDirectory()) {
25062
+ throw new CliError(`\u6CA1\u6709\u6784\u5EFA\u4EA7\u7269 ${dir}\uFF0C\u8BF7\u5148\u6784\u5EFA`, "ZIP_MISSING");
25063
+ }
25064
+ if (existsSync8(path9.join(dir, ".freelog"))) {
25065
+ 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");
25066
+ }
25067
+ const entries = readdirSync3(dir);
25068
+ if (entries.length === 0) {
25069
+ throw new CliError("\u6784\u5EFA\u4EA7\u7269\u662F\u7A7A\u7684\uFF0C\u8BF7\u5148\u6784\u5EFA", "ZIP_EMPTY");
25070
+ }
25071
+ const outPath = path9.join(
25072
+ tmpdir(),
25073
+ `freelog-zip-${process.pid}-${Date.now()}.zip`
25074
+ );
25075
+ const output2 = createWriteStream(outPath);
25076
+ const archive = archiver("zip", { zlib: { level: 9 } });
25077
+ try {
25078
+ archive.on("error", (error2) => output2.destroy(error2));
25079
+ archive.pipe(output2);
25080
+ for (const entry2 of entries) {
25081
+ const full = path9.join(dir, entry2);
25082
+ const stats = statSync(full);
25083
+ if (stats.isDirectory()) {
25084
+ archive.directory(full, entry2);
25085
+ } else {
25086
+ archive.file(full, { name: entry2 });
25087
+ }
25088
+ }
25089
+ await archive.finalize();
25090
+ await finished(output2);
25091
+ return outPath;
25092
+ } catch (error2) {
25093
+ if (existsSync8(outPath)) {
25094
+ try {
25095
+ unlinkSync5(outPath);
25096
+ } catch {
25097
+ }
25098
+ }
25099
+ throw error2;
25100
+ }
25101
+ }
25102
+ async function prepareUploadPath(typeCode, filePath) {
25103
+ assertArtifactPath(typeCode, filePath);
25104
+ if (isThemeOrWidget(typeCode) && existsSync8(filePath) && statSync(filePath).isDirectory()) {
25105
+ return zipDirectoryContents(filePath);
25106
+ }
25107
+ return filePath;
24825
25108
  }
24826
25109
 
24827
25110
  // src/domain/create/create.ts
24828
- function isFixedTemplateType(typeCode) {
24829
- return typeCode === "RT001" || typeCode === "RT002";
24830
- }
24831
25111
  function unwrapData(result) {
24832
25112
  const envelope = result;
24833
25113
  return envelope.data ?? result;
@@ -24881,48 +25161,11 @@ function validateCreateFlags(input2) {
24881
25161
  }
24882
25162
  return { title, name };
24883
25163
  }
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
- }
25164
+ function resolveTargetIdentity(input2) {
25165
+ if (input2.selector) return resolveIdentity(input2.cwd, input2.selector);
25166
+ const unbound = input2.identities.filter((identity) => !identity.resourceId);
25167
+ if (unbound.length === 1) return unbound[0];
25168
+ 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
25169
  return void 0;
24927
25170
  }
24928
25171
  async function assertOwnShellAvailable(input2) {
@@ -24946,39 +25189,46 @@ async function assertOwnShellAvailable(input2) {
24946
25189
  );
24947
25190
  }
24948
25191
  function writeCreatedIdentity(input2) {
24949
- const filePath = input2.file;
25192
+ const filePath = input2.file ?? input2.target?.filePath;
25193
+ if (!filePath) throw new CliError("\u65B0\u8D44\u6E90\u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "CREATE_ARTIFACT_REQUIRED");
24950
25194
  const patch = {
24951
25195
  resourceId: input2.resourceId,
24952
25196
  name: input2.name,
25197
+ title: input2.title,
24953
25198
  typeCode: input2.typeCode,
24954
- ...filePath ? { filePath } : {},
25199
+ filePath,
24955
25200
  env: input2.env
24956
25201
  };
24957
25202
  return input2.target ? updateIdentity(input2.cwd, input2.target.n, patch) : createIdentity(input2.cwd, {
24958
25203
  subject: "resource",
24959
25204
  resourceId: input2.resourceId,
24960
25205
  name: input2.name,
25206
+ title: input2.title,
24961
25207
  typeCode: input2.typeCode,
24962
- ...filePath ? { filePath } : {},
25208
+ filePath,
24963
25209
  env: input2.env
24964
25210
  });
24965
25211
  }
24966
25212
  async function createResource(input2) {
24967
25213
  assertPlatformAllowed();
24968
25214
  const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
25215
+ validateLocalState(input2.cwd);
24969
25216
  const { title, name } = validateCreateFlags(input2);
24970
25217
  const file = input2.file !== void 0 ? normalizeProjectPath(input2.cwd, input2.file, {
24971
25218
  code: "CREATE_FILE_OUTSIDE",
24972
25219
  message: "--artifact \u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
24973
25220
  }) : void 0;
24974
25221
  return withProjectLock(input2.cwd, async () => {
24975
- const identities = listIdentities(input2.cwd);
24976
- const target = await resolveTargetIdentity({
25222
+ const identities = validateLocalState(input2.cwd);
25223
+ const target = resolveTargetIdentity({
24977
25224
  cwd: input2.cwd,
24978
- file,
24979
- identities,
24980
- infoApi: input2.apis?.info
25225
+ selector: input2.selector,
25226
+ identities
24981
25227
  });
25228
+ const occupant = file ? identities.find((identity) => identity.filePath === file && identity.n !== target?.n) : void 0;
25229
+ if (occupant) {
25230
+ throw new CliError(`\u4EA7\u7269\u8DEF\u5F84 ${file} \u5DF2\u88AB ${occupant.n}.json \u5360\u7528`, "CREATE_FILE_OCCUPIED");
25231
+ }
24982
25232
  if (target?.resourceId) {
24983
25233
  throw new CliError(
24984
25234
  "\u8FD9\u4E2A\u8D44\u6E90\u5DF2\u7ECF\u521B\u5EFA\u8FC7\u6388\u6743\u6761\u76EE\uFF0C\u8FD8\u6CA1\u6709\u53D1\u884C\u7248\u672C\u3002",
@@ -24988,18 +25238,17 @@ async function createResource(input2) {
24988
25238
  if (input2.yes && !input2.type && !target?.typeCode) {
24989
25239
  throw new CliError("--yes \u5728\u6CA1\u6709\u5DE5\u7A0B\u7C7B\u578B\u65F6\u5FC5\u987B\u63D0\u4F9B --type", "CREATE_YES_FLAGS");
24990
25240
  }
24991
- const targetTypeCode = target?.typeCode;
24992
- if (!target && isFixedTemplateType(input2.type) && !file) {
24993
- throw new CliError(
24994
- input2.type === "RT001" ? "\u5DF2\u6709\u4E3B\u9898\u5DE5\u7A0B\u8BF7\u901A\u8FC7 --artifact \u6307\u5B9A\u6784\u5EFA\u76EE\u5F55" : "\u5DF2\u6709\u63D2\u4EF6\u5DE5\u7A0B\u8BF7\u901A\u8FC7 --artifact \u6307\u5B9A\u6784\u5EFA\u76EE\u5F55",
24995
- "CREATE_FIXED_TYPE_FILE_REQUIRED"
24996
- );
25241
+ const artifact = file ?? target?.filePath;
25242
+ if (!artifact) {
25243
+ throw new CliError("\u65B0\u8D44\u6E90\u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "CREATE_ARTIFACT_REQUIRED");
24997
25244
  }
24998
- if (isFixedTemplateType(targetTypeCode) && input2.type && input2.type !== targetTypeCode) {
25245
+ const targetTypeCode = target?.typeCode;
25246
+ if ((targetTypeCode === "RT001" || targetTypeCode === "RT002") && input2.type && input2.type !== targetTypeCode) {
24999
25247
  throw new CliError("\u4E3B\u9898/\u63D2\u4EF6\u5DE5\u7A0B\u7684\u8D44\u6E90\u7C7B\u578B\u56FA\u5B9A\uFF0C\u4E0D\u80FD\u7528 --type \u6539\u5199", "CREATE_FIXED_TYPE");
25000
25248
  }
25001
25249
  const typeCode = resolveTypeCode(input2.type, target);
25002
25250
  await getTypeInfo(typeCode, input2.apis);
25251
+ assertArtifactAnchor(typeCode, path10.resolve(input2.cwd, artifact));
25003
25252
  await assertOwnShellAvailable({
25004
25253
  authLoginName: auth.loginName,
25005
25254
  authUserId: auth.userId,
@@ -25024,6 +25273,7 @@ async function createResource(input2) {
25024
25273
  name,
25025
25274
  typeCode,
25026
25275
  resourceId,
25276
+ title,
25027
25277
  file,
25028
25278
  target
25029
25279
  });
@@ -25055,146 +25305,18 @@ function createCreateCommand() {
25055
25305
  cwd: resolveCwd(shared.cwd),
25056
25306
  title: options.title,
25057
25307
  type: options.type,
25058
- name: options.name,
25059
- file: options.artifact,
25060
- yes: shared.yes
25061
- });
25062
- console.log(record.resourceId ?? "");
25063
- });
25064
- return command;
25065
- }
25066
-
25067
- // src/commands/listing/update.ts
25068
- import { Command as Command5 } from "commander";
25069
-
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");
25308
+ name: options.name,
25309
+ file: options.artifact,
25310
+ selector: shared.file,
25311
+ yes: shared.yes
25312
+ });
25313
+ console.log(record.resourceId ?? "");
25314
+ });
25315
+ return command;
25185
25316
  }
25186
25317
 
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
- }
25318
+ // src/commands/listing/update.ts
25319
+ import { Command as Command5 } from "commander";
25198
25320
 
25199
25321
  // src/domain/version/gates.ts
25200
25322
  function evaluateGates(input2, intent) {
@@ -25300,6 +25422,7 @@ async function updateListing(input2) {
25300
25422
  }
25301
25423
  const update2 = input2.apis?.update ?? ((params) => service_API_default.Resource.update(params));
25302
25424
  await update2(payload);
25425
+ if (input2.title) updateIdentity(input2.cwd, identity.n, { title: input2.title });
25303
25426
  return payload;
25304
25427
  }
25305
25428
 
@@ -25326,7 +25449,7 @@ function createUpdateCommand() {
25326
25449
 
25327
25450
  // src/commands/policy/apply.ts
25328
25451
  import { readFileSync as readFileSync6 } from "fs";
25329
- import path10 from "path";
25452
+ import path11 from "path";
25330
25453
  import { confirm, input } from "@inquirer/prompts";
25331
25454
  import { Command as Command6 } from "commander";
25332
25455
 
@@ -25505,7 +25628,7 @@ async function setPolicy(input2) {
25505
25628
  // src/commands/policy/apply.ts
25506
25629
  function parsePolicy(file) {
25507
25630
  const text = readFileSync6(file, "utf8");
25508
- if (path10.extname(file).toLowerCase() !== ".json") return { policyText: text };
25631
+ if (path11.extname(file).toLowerCase() !== ".json") return { policyText: text };
25509
25632
  let parsed;
25510
25633
  try {
25511
25634
  parsed = JSON.parse(text);
@@ -25520,10 +25643,10 @@ function parsePolicy(file) {
25520
25643
  function createPolicyApplyCommand() {
25521
25644
  const command = addSharedOptions(new Command6("apply"));
25522
25645
  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;
25646
+ const shared = readSharedOptions(this);
25647
+ const cwd = resolveCwd(shared.cwd);
25648
+ const file = shared.file;
25649
+ const yes = shared.yes === true;
25527
25650
  if (!options.fromFile) throw new CliError("\u8BF7\u63D0\u4F9B --from-file", "POLICY_FROM_FILE");
25528
25651
  const source = parsePolicy(options.fromFile);
25529
25652
  let policyName = options.name ?? source.policyName;
@@ -25561,11 +25684,11 @@ import { Command as Command8 } from "commander";
25561
25684
  function createPolicySetCommand() {
25562
25685
  const command = addSharedOptions(new Command8("set"));
25563
25686
  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;
25687
+ const shared = readSharedOptions(this);
25688
+ const yes = shared.yes === true;
25566
25689
  if (options.on === options.off) throw new CliError("\u5FC5\u987B\u4E14\u53EA\u80FD\u63D0\u4F9B --on \u6216 --off", "POLICY_SET_DIRECTION");
25567
25690
  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 });
25691
+ await setPolicy({ cwd: resolveCwd(shared.cwd), file: shared.file, policyId: options.id, on: options.on === true });
25569
25692
  console.log(`\u5DF2${options.on ? "\u542F\u7528" : "\u505C\u7528"}\u6388\u6743\u7B56\u7565`);
25570
25693
  });
25571
25694
  return command;
@@ -25629,21 +25752,32 @@ function createPolicyTemplateCommand() {
25629
25752
  // src/commands/project/bind.ts
25630
25753
  import { Command as Command10 } from "commander";
25631
25754
 
25755
+ // src/domain/bind/bind.ts
25756
+ import { existsSync as existsSync10 } from "fs";
25757
+
25632
25758
  // src/local/indexFile.ts
25633
- import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
25634
- import path11 from "path";
25759
+ import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
25760
+ import path12 from "path";
25635
25761
  function normalizeFileKey(filePath) {
25636
- return filePath.replaceAll("\\", "/").replace(/^\.\//, "");
25762
+ return path12.posix.normalize(filePath.replaceAll("\\", "/")).replace(/^\.\//, "");
25637
25763
  }
25638
25764
 
25639
25765
  // src/domain/bind/bind.ts
25766
+ import path13 from "path";
25640
25767
  async function bindResource(input2) {
25641
25768
  assertPlatformAllowed();
25642
25769
  const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
25770
+ validateLocalState(input2.cwd);
25643
25771
  const filePath = input2.file !== void 0 ? normalizeProjectPath(input2.cwd, input2.file, {
25644
25772
  code: "BIND_FILE_OUTSIDE",
25645
25773
  message: "--artifact \u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
25646
25774
  }) : void 0;
25775
+ if (filePath) {
25776
+ const absolute = path13.resolve(input2.cwd, filePath);
25777
+ if (!existsSync10(absolute)) {
25778
+ throw new CliError(`\u672C\u5730\u4EA7\u7269\u4E0D\u5B58\u5728\uFF1A${absolute}`, "ARTIFACT_ANCHOR_MISSING");
25779
+ }
25780
+ }
25647
25781
  const infoApi2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
25648
25782
  const info2 = unwrapData2(
25649
25783
  await infoApi2({
@@ -25662,14 +25796,15 @@ async function bindResource(input2) {
25662
25796
  }
25663
25797
  const resourceId = String(info2.resourceId ?? "");
25664
25798
  const name = String(info2.resourceName ?? info2.name ?? "").split("/").pop() ?? "";
25799
+ const title = String(info2.resourceTitle ?? info2.title ?? name);
25665
25800
  const resourceType = info2.resourceType;
25666
25801
  const typeFromArray = Array.isArray(resourceType) ? String(resourceType[0] ?? "") : "";
25667
25802
  const typeCode = String(info2.resourceTypeCode ?? typeFromArray);
25668
- if (!resourceId || !name || !typeCode) {
25803
+ if (!resourceId || !name || !typeCode || !title) {
25669
25804
  throw new CliError("\u5E73\u53F0\u8BE6\u60C5\u7F3A\u5C11\u8EAB\u4EFD\u5B57\u6BB5", "BIND_INFO_INVALID");
25670
25805
  }
25671
25806
  return withProjectLock(input2.cwd, () => {
25672
- const identities = listIdentities(input2.cwd);
25807
+ const identities = validateLocalState(input2.cwd);
25673
25808
  const byId = identities.find((item) => item.resourceId === resourceId);
25674
25809
  const byFile = filePath ? identities.find(
25675
25810
  (item) => item.filePath !== void 0 && normalizeFileKey(item.filePath) === filePath
@@ -25678,16 +25813,22 @@ async function bindResource(input2) {
25678
25813
  if (byFile && byId && byFile.n !== byId.n) {
25679
25814
  throw new CliError("\u8DEF\u5F84\u5DF2\u88AB\u5360\u7528", "BIND_PATH_TAKEN");
25680
25815
  }
25681
- let target = byId ?? byFile;
25816
+ let target = input2.selector ? resolveIdentity(input2.cwd, input2.selector) : byId;
25817
+ if (input2.selector && byId && target && target.n !== byId.n) {
25818
+ throw new CliError(`\u8D44\u6E90\u5DF2\u7ED1\u5B9A\u5230 ${byId.n}.json`, "BIND_ID_TAKEN");
25819
+ }
25682
25820
  if (!target && unbound.length === 1) {
25683
25821
  target = unbound[0];
25684
25822
  }
25685
- if (!target && identities.length > 1 && !filePath) {
25686
- throw new CliError("\u4E00\u5939\u591A\u6761\u5FC5\u987B\u6307\u5B9A --file", "IDENTITY_FILE_REQUIRED");
25823
+ 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");
25824
+ if (byFile && target?.n !== byFile.n) {
25825
+ throw new CliError("\u8DEF\u5F84\u5DF2\u88AB\u5360\u7528", "BIND_PATH_TAKEN");
25687
25826
  }
25688
- if (isThemeOrWidget(typeCode) && !filePath && !target?.filePath) {
25689
- throw new CliError("\u4E3B\u9898/\u63D2\u4EF6 bind \u65F6\u8BF7\u901A\u8FC7 --artifact \u6307\u5B9A\u6784\u5EFA\u76EE\u5F55", "BIND_FIXED_TYPE_FILE_REQUIRED");
25827
+ const resolvedFilePath = filePath ?? target?.filePath;
25828
+ if (!resolvedFilePath) {
25829
+ throw new CliError("\u65B0\u589E\u672C\u5730\u72B6\u6001\u65F6\u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "BIND_ARTIFACT_REQUIRED");
25690
25830
  }
25831
+ assertArtifactAnchor(typeCode, path13.resolve(input2.cwd, resolvedFilePath));
25691
25832
  const env = getEnv2();
25692
25833
  if (target) {
25693
25834
  const resourceChanged = target.resourceId !== resourceId;
@@ -25701,8 +25842,9 @@ async function bindResource(input2) {
25701
25842
  const updated = prepareIdentityUpdate(input2.cwd, target.n, {
25702
25843
  resourceId,
25703
25844
  name,
25845
+ title,
25704
25846
  typeCode,
25705
- filePath: filePath ?? target.filePath,
25847
+ filePath: resolvedFilePath,
25706
25848
  env
25707
25849
  });
25708
25850
  commitLocalTransaction(input2.cwd, [
@@ -25715,8 +25857,9 @@ async function bindResource(input2) {
25715
25857
  subject: "resource",
25716
25858
  resourceId,
25717
25859
  name,
25860
+ title,
25718
25861
  typeCode,
25719
- filePath,
25862
+ filePath: resolvedFilePath,
25720
25863
  env
25721
25864
  });
25722
25865
  commitLocalTransaction(input2.cwd, [
@@ -25733,9 +25876,6 @@ function isCollectionSubject(subjectType) {
25733
25876
  const values = Array.isArray(subjectType) ? subjectType : [subjectType];
25734
25877
  return values.some((value) => Number(value) === 4);
25735
25878
  }
25736
- function isThemeOrWidget(typeCode) {
25737
- return typeCode === "RT001" || typeCode === "RT002";
25738
- }
25739
25879
 
25740
25880
  // src/commands/project/bind.ts
25741
25881
  function createBindCommand() {
@@ -25757,6 +25897,7 @@ function createBindCommand() {
25757
25897
  cwd: resolveCwd(shared.cwd),
25758
25898
  target,
25759
25899
  file: options.artifact,
25900
+ selector: shared.file,
25760
25901
  force: options.force,
25761
25902
  yes: shared.yes
25762
25903
  });
@@ -25770,9 +25911,9 @@ import { Command as Command11 } from "commander";
25770
25911
 
25771
25912
  // src/domain/init/scaffold.ts
25772
25913
  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";
25914
+ import { cpSync, existsSync as existsSync11, lstatSync, mkdirSync as mkdirSync2, mkdtempSync, readdirSync as readdirSync4, readFileSync as readFileSync8, renameSync, rmSync } from "fs";
25774
25915
  import os4 from "os";
25775
- import path12 from "path";
25916
+ import path14 from "path";
25776
25917
  import { promisify } from "util";
25777
25918
 
25778
25919
  // src/domain/init/templates.ts
@@ -25798,44 +25939,49 @@ function formatTemplateList(items) {
25798
25939
 
25799
25940
  // src/domain/init/scaffold.ts
25800
25941
  var execFile = promisify(execFileCallback);
25801
- function isFixedTemplateType2(typeCode) {
25802
- return typeCode === "RT001" || typeCode === "RT002";
25803
- }
25804
25942
  function resolveTargetDir(input2) {
25805
- return input2.dir ? path12.isAbsolute(input2.dir) ? input2.dir : path12.resolve(input2.cwd, input2.dir) : path12.resolve(input2.cwd);
25943
+ return input2.dir ? path14.isAbsolute(input2.dir) ? input2.dir : path14.resolve(input2.cwd, input2.dir) : path14.resolve(input2.cwd);
25806
25944
  }
25807
25945
  function targetHasOnlyAuthSelector(targetDir) {
25808
- if (!existsSync8(targetDir)) return false;
25946
+ if (!existsSync11(targetDir)) return false;
25809
25947
  let entries;
25810
25948
  try {
25811
- entries = readdirSync2(targetDir);
25949
+ entries = readdirSync4(targetDir);
25812
25950
  } catch {
25813
25951
  throw new CliError("\u76EE\u6807\u76EE\u5F55\u4E0D\u53EF\u8BFB\u53D6\uFF0C\u62D2\u7EDD\u8986\u76D6", "INIT_TARGET_NOT_EMPTY");
25814
25952
  }
25815
25953
  if (entries.length === 0) return false;
25816
25954
  if (entries.length !== 1 || entries[0] !== ".freelog") return false;
25817
- const stateDir = path12.join(targetDir, ".freelog");
25818
- if (!lstatSync(stateDir).isDirectory() || lstatSync(stateDir).isSymbolicLink()) return false;
25819
- const stateEntries = readdirSync2(stateDir);
25955
+ const stateDir = path14.join(targetDir, ".freelog");
25956
+ return stateDirHasOnlyAuthSelector(stateDir);
25957
+ }
25958
+ function stateDirHasOnlyAuthSelector(stateDir) {
25959
+ if (!existsSync11(stateDir) || !lstatSync(stateDir).isDirectory() || lstatSync(stateDir).isSymbolicLink()) return false;
25960
+ const stateEntries = readdirSync4(stateDir);
25820
25961
  if (stateEntries.length !== 1 || stateEntries[0] !== "auth") return false;
25821
- const auth = lstatSync(path12.join(stateDir, "auth"));
25962
+ const auth = lstatSync(path14.join(stateDir, "auth"));
25822
25963
  return auth.isFile() && !auth.isSymbolicLink();
25823
25964
  }
25824
- function assertInitialTarget(targetDir) {
25825
- if (!existsSync8(targetDir)) return { targetExisted: false, preserveAuth: false };
25826
- const entries = readdirSync2(targetDir);
25827
- if (entries.length === 0) return { targetExisted: true, preserveAuth: false };
25828
- if (targetHasOnlyAuthSelector(targetDir)) return { targetExisted: true, preserveAuth: true };
25965
+ function assertInitialTarget(targetDir, adoptExistingProject) {
25966
+ if (!existsSync11(targetDir)) return { targetExisted: false, preserveAuth: false, adoptExistingProject };
25967
+ const entries = readdirSync4(targetDir);
25968
+ if (entries.length === 0) return { targetExisted: true, preserveAuth: false, adoptExistingProject };
25969
+ if (targetHasOnlyAuthSelector(targetDir)) return { targetExisted: true, preserveAuth: true, adoptExistingProject };
25970
+ if (adoptExistingProject) {
25971
+ const stateDir = path14.join(targetDir, ".freelog");
25972
+ if (!existsSync11(stateDir)) return { targetExisted: true, preserveAuth: false, adoptExistingProject: true };
25973
+ if (stateDirHasOnlyAuthSelector(stateDir)) return { targetExisted: true, preserveAuth: true, adoptExistingProject: true };
25974
+ }
25829
25975
  throw new CliError("\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u7A7A\u76EE\u5F55\uFF0C\u62D2\u7EDD\u8986\u76D6", "INIT_TARGET_NOT_EMPTY");
25830
25976
  }
25831
25977
  function assertOnlyAuthSelectorStillThere(targetDir) {
25832
- if (!targetHasOnlyAuthSelector(targetDir)) {
25978
+ if (!stateDirHasOnlyAuthSelector(path14.join(targetDir, ".freelog"))) {
25833
25979
  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");
25834
25980
  }
25835
25981
  }
25836
25982
  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 });
25983
+ for (const entry2 of readdirSync4(sourceDir)) {
25984
+ cpSync(path14.join(sourceDir, entry2), path14.join(targetDir, entry2), { recursive: true, errorOnExist: true, force: false });
25839
25985
  }
25840
25986
  }
25841
25987
  function parsePackFilename(stdout) {
@@ -25847,8 +25993,8 @@ function parsePackFilename(stdout) {
25847
25993
  throw new CliError("\u6A21\u677F\u4E0B\u8F7D\u5931\u8D25\uFF1Anpm \u672A\u8FD4\u56DE\u5B89\u88C5\u5305", "TEMPLATE_DOWNLOAD_FAILED");
25848
25994
  }
25849
25995
  function validateRemoteTemplate(packageDir, template) {
25850
- const manifestPath = path12.join(packageDir, "template.manifest.json");
25851
- const templateDir = path12.join(packageDir, "template");
25996
+ const manifestPath = path14.join(packageDir, "template.manifest.json");
25997
+ const templateDir = path14.join(packageDir, "template");
25852
25998
  let manifest;
25853
25999
  try {
25854
26000
  manifest = JSON.parse(readFileSync8(manifestPath, "utf8"));
@@ -25856,15 +26002,15 @@ function validateRemoteTemplate(packageDir, template) {
25856
26002
  throw new CliError("\u6A21\u677F\u6821\u9A8C\u5931\u8D25\uFF1A\u7F3A\u5C11\u6216\u65E0\u6CD5\u8BFB\u53D6 template.manifest.json", "TEMPLATE_INVALID");
25857
26003
  }
25858
26004
  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)) {
26005
+ if (manifest.id !== template.id || manifest.npmName !== template.npmName || manifest.version !== template.version || !tags.includes("runtime") || !template.targets.every((target) => tags.includes(target)) || !existsSync11(templateDir)) {
25860
26006
  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
26007
  }
25862
26008
  return templateDir;
25863
26009
  }
25864
26010
  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");
26011
+ const tempDir = mkdtempSync(path14.join(os4.tmpdir(), "freelog-template-"));
26012
+ const downloadDir = path14.join(tempDir, "download");
26013
+ const extractDir = path14.join(tempDir, "extract");
25868
26014
  mkdirSync2(downloadDir);
25869
26015
  mkdirSync2(extractDir);
25870
26016
  const npm = process.platform === "win32" ? "npm.cmd" : "npm";
@@ -25875,78 +26021,86 @@ async function installRemoteTemplate(input2) {
25875
26021
  } catch {
25876
26022
  throw new CliError(`\u6A21\u677F\u4E0B\u8F7D\u5931\u8D25\uFF1A${input2.template.id}`, "TEMPLATE_DOWNLOAD_FAILED");
25877
26023
  }
25878
- const archivePath = path12.join(downloadDir, parsePackFilename(stdout));
26024
+ const archivePath = path14.join(downloadDir, parsePackFilename(stdout));
25879
26025
  try {
25880
26026
  await execFile("tar", ["-xzf", archivePath, "-C", extractDir]);
25881
26027
  } catch {
25882
26028
  throw new CliError(`\u6A21\u677F\u89E3\u5305\u5931\u8D25\uFF1A${input2.template.id}`, "TEMPLATE_EXTRACT_FAILED");
25883
26029
  }
25884
- copyDirectoryContents(validateRemoteTemplate(path12.join(extractDir, "package"), input2.template), input2.targetDir);
26030
+ copyDirectoryContents(validateRemoteTemplate(path14.join(extractDir, "package"), input2.template), input2.targetDir);
25885
26031
  } finally {
25886
26032
  rmSync(tempDir, { recursive: true, force: true });
25887
26033
  }
25888
26034
  }
25889
- function commitStaging(stagingDir, targetDir, targetExisted, preserveAuth) {
26035
+ function commitStaging(stagingDir, targetDir, targetExisted, preserveAuth, adoptExistingProject) {
25890
26036
  if (!targetExisted) {
25891
26037
  renameSync(stagingDir, targetDir);
25892
26038
  return;
25893
26039
  }
25894
26040
  if (preserveAuth) {
25895
26041
  assertOnlyAuthSelectorStillThere(targetDir);
26042
+ } else if (adoptExistingProject) {
26043
+ if (existsSync11(path14.join(targetDir, ".freelog"))) {
26044
+ 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");
26045
+ }
26046
+ renameSync(path14.join(stagingDir, ".freelog"), path14.join(targetDir, ".freelog"));
26047
+ rmSync(stagingDir, { recursive: true, force: true });
26048
+ return;
25896
26049
  } else {
25897
- assertInitialTarget(targetDir);
26050
+ assertInitialTarget(targetDir, false);
25898
26051
  }
25899
- for (const entry2 of readdirSync2(stagingDir)) {
25900
- const destination = path12.join(targetDir, entry2);
26052
+ for (const entry2 of readdirSync4(stagingDir)) {
26053
+ const destination = path14.join(targetDir, entry2);
25901
26054
  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)) {
26055
+ for (const stateEntry of readdirSync4(path14.join(stagingDir, entry2))) {
26056
+ const stateDestination = path14.join(destination, stateEntry);
26057
+ if (existsSync11(stateDestination)) {
25905
26058
  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
26059
  }
25907
- renameSync(path12.join(stagingDir, entry2, stateEntry), stateDestination);
26060
+ renameSync(path14.join(stagingDir, entry2, stateEntry), stateDestination);
25908
26061
  }
25909
- rmSync(path12.join(stagingDir, entry2), { recursive: true, force: true });
26062
+ rmSync(path14.join(stagingDir, entry2), { recursive: true, force: true });
25910
26063
  continue;
25911
26064
  }
25912
- if (existsSync8(destination)) {
26065
+ if (existsSync11(destination)) {
25913
26066
  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
26067
  }
25915
- renameSync(path12.join(stagingDir, entry2), destination);
26068
+ renameSync(path14.join(stagingDir, entry2), destination);
25916
26069
  }
25917
26070
  rmSync(stagingDir, { recursive: true, force: true });
25918
26071
  }
25919
26072
  async function initProject(input2) {
25920
26073
  const targetDir = resolveTargetDir(input2);
25921
26074
  return withInitLock(targetDir, async () => {
25922
- const initialTarget = assertInitialTarget(targetDir);
25923
26075
  const shortcut = input2.shortcut;
26076
+ const adoptExistingProject = !shortcut;
26077
+ const initialTarget = assertInitialTarget(targetDir, adoptExistingProject);
25924
26078
  if (shortcut && input2.yes && !input2.template) {
25925
26079
  throw new CliError("init theme / widget \u4F7F\u7528 --yes \u65F6\u5FC5\u987B\u5E26 --template", "INIT_TEMPLATE_REQUIRED");
25926
26080
  }
25927
26081
  if (!shortcut && !input2.typeCode?.trim()) {
25928
26082
  throw new CliError("\u8BF7\u9009\u62E9\u8D44\u6E90\u7C7B\u578B", "INIT_TYPE_REQUIRED");
25929
26083
  }
25930
- const typeCode = shortcut === "theme" ? "RT001" : shortcut === "widget" ? "RT002" : (await (input2.typeValidator ?? ((code) => getTypeInfo(code, input2.typeApis)))(input2.typeCode)).code;
25931
- if (!shortcut && isFixedTemplateType2(typeCode)) {
25932
- throw new CliError(
25933
- typeCode === "RT001" ? "\u4E3B\u9898\u8BF7\u4F7F\u7528 init theme \u521B\u5EFA\u6A21\u677F\u5DE5\u7A0B" : "\u63D2\u4EF6\u8BF7\u4F7F\u7528 init widget \u521B\u5EFA\u6A21\u677F\u5DE5\u7A0B",
25934
- "INIT_TEMPLATE_SHORTCUT_REQUIRED"
25935
- );
26084
+ if (!shortcut && !input2.artifact?.trim()) {
26085
+ throw new CliError("init \u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "INIT_ARTIFACT_REQUIRED");
25936
26086
  }
26087
+ const typeCode = shortcut === "theme" ? "RT001" : shortcut === "widget" ? "RT002" : (await (input2.typeValidator ?? ((code) => getTypeInfo(code, input2.typeApis)))(input2.typeCode)).code;
26088
+ const artifact = shortcut ? "dist" : normalizeProjectPath(targetDir, input2.artifact);
26089
+ if (!shortcut) assertArtifactAnchor(typeCode, path14.resolve(targetDir, artifact));
25937
26090
  const template = shortcut && input2.template ? getTemplate(input2.template, shortcut) : void 0;
25938
26091
  if (shortcut && !template) throw new CliError("\u8BF7\u9009\u62E9\u6A21\u677F", "INIT_TEMPLATE_REQUIRED");
25939
- const parent = path12.dirname(targetDir);
26092
+ const parent = path14.dirname(targetDir);
25940
26093
  mkdirSync2(parent, { recursive: true });
25941
- const stagingDir = mkdtempSync(path12.join(parent, `.${path12.basename(targetDir)}.freelog-init-`));
26094
+ const stagingDir = mkdtempSync(path14.join(parent, `.${path14.basename(targetDir)}.freelog-init-`));
25942
26095
  try {
25943
26096
  if (template) await (input2.templateSource ?? installRemoteTemplate)({ template, targetDir: stagingDir });
26097
+ if (shortcut) mkdirSync2(path14.join(stagingDir, artifact), { recursive: true });
25944
26098
  const created = createIdentity(stagingDir, {
25945
26099
  subject: "resource",
25946
26100
  typeCode,
25947
- ...shortcut ? { filePath: "dist" } : {}
26101
+ filePath: artifact
25948
26102
  });
25949
- commitStaging(stagingDir, targetDir, initialTarget.targetExisted, initialTarget.preserveAuth);
26103
+ commitStaging(stagingDir, targetDir, initialTarget.targetExisted, initialTarget.preserveAuth, adoptExistingProject);
25950
26104
  return { ...created, n: created.n };
25951
26105
  } catch (error2) {
25952
26106
  rmSync(stagingDir, { recursive: true, force: true });
@@ -25976,9 +26130,18 @@ async function chooseProjectDir(dir) {
25976
26130
  }
25977
26131
  return selected;
25978
26132
  }
26133
+ async function chooseArtifact(artifact, yes) {
26134
+ if (artifact?.trim()) return artifact;
26135
+ if (yes || !isInteractive()) {
26136
+ throw new CliError("init \u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "INIT_ARTIFACT_REQUIRED");
26137
+ }
26138
+ const selected = (await askInput2("\u672C\u5730\u4EA7\u7269\u6587\u4EF6\u6216\u6784\u5EFA\u76EE\u5F55")).trim();
26139
+ if (!selected) throw new CliError("init \u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "INIT_ARTIFACT_REQUIRED");
26140
+ return selected;
26141
+ }
25979
26142
  function createInitCommand() {
25980
26143
  const init2 = addSharedOptions(new Command11("init"));
25981
- init2.description("\u53EA\u5EFA\u672C\u5730\u5355\u8D44\u6E90\u5DE5\u7A0B").argument("[dir]", "\u76EE\u6807\u76EE\u5F55").option("--type <leaf-code>", "\u666E\u901A\u8D44\u6E90\u6700\u7EC8\u53F6\u5B50\u7C7B\u578B").option("--resource-type <leaf-code>", "\u5DF2\u5F03\u7528\uFF1A\u8BF7\u6539\u7528 --type").action(async function(dir, options) {
26144
+ init2.description("\u5EFA\u7ACB\u9996\u4EFD\u672C\u5730\u8D44\u6E90\u72B6\u6001").argument("[dir]", "\u76EE\u6807\u76EE\u5F55").option("--type <leaf-code>", "\u666E\u901A\u8D44\u6E90\u6700\u7EC8\u53F6\u5B50\u7C7B\u578B").option("--artifact <path>", "\u8981\u5173\u8054\u7684\u672C\u5730\u4EA7\u7269\u6587\u4EF6\u6216\u6784\u5EFA\u76EE\u5F55").option("--resource-type <leaf-code>", "\u5DF2\u5F03\u7528\uFF1A\u8BF7\u6539\u7528 --type").action(async function(dir, options) {
25982
26145
  if (options.type && options.resourceType) throw new CliError("--type \u4E0E --resource-type \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528", "INIT_TYPE_CONFLICT");
25983
26146
  if (options.resourceType) console.warn("\u8B66\u544A\uFF1A--resource-type \u5DF2\u5F03\u7528\uFF0C\u8BF7\u6539\u7528 --type");
25984
26147
  const shared = sharedOptions(this);
@@ -25987,7 +26150,14 @@ function createInitCommand() {
25987
26150
  requireAuth({ cwd });
25988
26151
  const selected = options.type ?? options.resourceType;
25989
26152
  const type = selected ? await getTypeInfo(selected) : await chooseLeafType();
25990
- const created = await initProject({ cwd, dir: targetDir, typeCode: type.code, typeValidator: async () => type, yes: shared.yes });
26153
+ const created = await initProject({
26154
+ cwd,
26155
+ dir: targetDir,
26156
+ typeCode: type.code,
26157
+ typeValidator: async () => type,
26158
+ artifact: await chooseArtifact(options.artifact, shared.yes),
26159
+ yes: shared.yes
26160
+ });
25991
26161
  console.log(`\u5DF2\u521B\u5EFA\u672C\u5730\u8EAB\u4EFD ${created.n}.json`);
25992
26162
  });
25993
26163
  for (const shortcut of ["theme", "widget"]) {
@@ -26012,9 +26182,8 @@ import { Command as Command12 } from "commander";
26012
26182
 
26013
26183
  // src/domain/status.ts
26014
26184
  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;
26185
+ const local = resolveIdentity(input2.cwd, input2.file);
26186
+ const draft = readDraft(input2.cwd, local.n);
26018
26187
  let online = "\u672A\u67E5\u8BE2";
26019
26188
  if (local?.resourceId) {
26020
26189
  assertPlatformAllowed();
@@ -26149,9 +26318,64 @@ function createTypeCommand() {
26149
26318
  return type;
26150
26319
  }
26151
26320
 
26152
- // src/commands/shelf/offline.ts
26321
+ // src/commands/project/resource.ts
26153
26322
  import { Command as Command15 } from "commander";
26154
26323
 
26324
+ // src/domain/resource/sync.ts
26325
+ async function syncResourceTitles(input2) {
26326
+ assertPlatformAllowed();
26327
+ requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
26328
+ return withProjectLock(input2.cwd, async () => {
26329
+ const env = getEnv2();
26330
+ const all3 = validateLocalState(input2.cwd);
26331
+ const targets = input2.selector ? [resolveIdentity(input2.cwd, input2.selector)] : all3.filter((identity) => identity.resourceId && (identity.env ?? "prod") === env);
26332
+ if (targets.length === 0) {
26333
+ throw new CliError("\u5F53\u524D\u73AF\u5883\u6CA1\u6709\u53EF\u540C\u6B65\u6807\u9898\u7684\u5DF2\u7ED1\u5B9A\u8D44\u6E90", "RESOURCE_SYNC_EMPTY");
26334
+ }
26335
+ if (input2.selector && (targets[0].env ?? "prod") !== env) {
26336
+ 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");
26337
+ }
26338
+ const info2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
26339
+ const results = await Promise.all(targets.map(async (identity) => {
26340
+ if (!identity.resourceId) return { identity, error: "\u8D44\u6E90\u5C1A\u672A\u7ED1\u5B9A" };
26341
+ try {
26342
+ const data = unwrapData2(await info2({ resourceIdOrName: identity.resourceId, isLoadLatestVersionInfo: 1 }));
26343
+ const title = String(data.resourceTitle ?? data.title ?? "");
26344
+ if (!title) return { identity, error: "\u5E73\u53F0\u8BE6\u60C5\u7F3A\u5C11\u6807\u9898" };
26345
+ return { identity, title };
26346
+ } catch (error2) {
26347
+ return { identity, error: error2 instanceof Error ? error2.message : "\u8BF7\u6C42\u5931\u8D25" };
26348
+ }
26349
+ }));
26350
+ const successful = results.filter((item) => "title" in item);
26351
+ if (successful.length > 0) {
26352
+ const changes = successful.map(({ identity, title }) => {
26353
+ const updated = prepareIdentityUpdate(input2.cwd, identity.n, { title });
26354
+ return { path: identityFilePath(input2.cwd, identity.n), content: serializeIdentity(updated) };
26355
+ });
26356
+ commitLocalTransaction(input2.cwd, changes);
26357
+ }
26358
+ const failed = results.filter((item) => "error" in item);
26359
+ if (failed.length > 0) {
26360
+ 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");
26361
+ }
26362
+ return `\u5DF2\u540C\u6B65 ${successful.length} \u4EFD\u8D44\u6E90\u6807\u9898`;
26363
+ }, "sync-resource-titles");
26364
+ }
26365
+
26366
+ // src/commands/project/resource.ts
26367
+ function createResourceCommand() {
26368
+ const resource = addSharedOptions(new Command15("resource")).description("\u8D44\u6E90\u672C\u5730\u72B6\u6001\u7EF4\u62A4");
26369
+ resource.command("sync").description("\u4ECE\u5E73\u53F0\u540C\u6B65\u672C\u5730\u8D44\u6E90\u6807\u9898").action(async function() {
26370
+ const shared = readSharedOptions(this);
26371
+ console.log(await syncResourceTitles({ cwd: resolveCwd(shared.cwd), selector: shared.file }));
26372
+ });
26373
+ return resource;
26374
+ }
26375
+
26376
+ // src/commands/shelf/offline.ts
26377
+ import { Command as Command16 } from "commander";
26378
+
26155
26379
  // src/domain/online/online.ts
26156
26380
  async function loadInfo(resourceId, apis) {
26157
26381
  const infoApi2 = apis?.info ?? ((params) => service_API_default.Resource.info(params));
@@ -26197,7 +26421,7 @@ async function offlineResource(input2) {
26197
26421
 
26198
26422
  // src/commands/shelf/offline.ts
26199
26423
  function createOfflineCommand() {
26200
- const command = addSharedOptions(new Command15("offline"));
26424
+ const command = addSharedOptions(new Command16("offline"));
26201
26425
  command.description(
26202
26426
  // i18n: cli.command.offline.description
26203
26427
  "\u4E0B\u67B6"
@@ -26212,9 +26436,9 @@ function createOfflineCommand() {
26212
26436
  }
26213
26437
 
26214
26438
  // src/commands/shelf/online.ts
26215
- import { Command as Command16 } from "commander";
26439
+ import { Command as Command17 } from "commander";
26216
26440
  function createOnlineCommand() {
26217
- const command = addSharedOptions(new Command16("online"));
26441
+ const command = addSharedOptions(new Command17("online"));
26218
26442
  command.description(
26219
26443
  // i18n: cli.command.online.description
26220
26444
  "\u4E0A\u67B6"
@@ -26229,7 +26453,7 @@ function createOnlineCommand() {
26229
26453
  }
26230
26454
 
26231
26455
  // src/commands/shelf/validate.ts
26232
- import { Command as Command17 } from "commander";
26456
+ import { Command as Command18 } from "commander";
26233
26457
 
26234
26458
  // src/domain/online/validate.ts
26235
26459
  async function validateOnline(input2) {
@@ -26252,7 +26476,7 @@ async function validateOnline(input2) {
26252
26476
 
26253
26477
  // src/commands/shelf/validate.ts
26254
26478
  function createValidateCommand() {
26255
- const command = addSharedOptions(new Command17("validate"));
26479
+ const command = addSharedOptions(new Command18("validate"));
26256
26480
  command.description(
26257
26481
  // i18n: cli.command.validate.description
26258
26482
  "\u53EA\u9884\u68C0"
@@ -26274,7 +26498,7 @@ function createValidateCommand() {
26274
26498
  }
26275
26499
 
26276
26500
  // src/commands/version/attr.ts
26277
- import { Command as Command18 } from "commander";
26501
+ import { Command as Command19 } from "commander";
26278
26502
 
26279
26503
  // src/domain/version/form/parseLine.ts
26280
26504
  var KEY_RE = /^[A-Za-z][A-Za-z0-9_]{0,29}$/;
@@ -26532,7 +26756,7 @@ function attrList(cwd, file) {
26532
26756
 
26533
26757
  // src/commands/version/attr.ts
26534
26758
  function createVersionAttrCommand() {
26535
- const attr = addSharedOptions(new Command18("attr"));
26759
+ const attr = addSharedOptions(new Command19("attr"));
26536
26760
  attr.description("\u6539\u7A3F\u4E0A\u7684\u5C5E\u6027");
26537
26761
  addSharedOptions(attr.command("add")).description("\u52A0\u81EA\u5B9A\u4E49\u5C5E\u6027").argument("[line]", "\u4E00\u884C\u5F0F").action(async function(line) {
26538
26762
  const shared = readSharedOptions(this);
@@ -26554,7 +26778,7 @@ function createVersionAttrCommand() {
26554
26778
  }
26555
26779
 
26556
26780
  // src/commands/version/create-version.ts
26557
- import { Command as Command19 } from "commander";
26781
+ import { Command as Command20 } from "commander";
26558
26782
 
26559
26783
  // src/domain/version/submit.ts
26560
26784
  function fieldName(error2) {
@@ -26615,90 +26839,16 @@ async function submitVersion(input2) {
26615
26839
 
26616
26840
  // src/domain/version/file.ts
26617
26841
  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";
26620
-
26621
- // src/domain/version/zip.ts
26622
- import { createWriteStream, existsSync as existsSync9, readdirSync as readdirSync3, statSync, unlinkSync as unlinkSync5 } from "fs";
26623
- import { tmpdir } from "os";
26624
- import path13 from "path";
26625
- import { finished } from "stream/promises";
26626
- import archiver from "archiver";
26627
- function isThemeOrWidget2(typeCode) {
26628
- return typeCode === "RT001" || typeCode === "RT002";
26629
- }
26630
- function assertArtifactPath(typeCode, filePath) {
26631
- const stats = existsSync9(filePath) ? statSync(filePath) : void 0;
26632
- const themeOrWidget = isThemeOrWidget2(typeCode);
26633
- if (stats?.isDirectory() && !themeOrWidget) {
26634
- throw new CliError("\u4E0D\u652F\u6301\u6587\u4EF6\u5939\uFF0C\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6587\u4EF6\u3002", "FILE_DIRECTORY_UNSUPPORTED");
26635
- }
26636
- if (themeOrWidget && stats?.isFile() && filePath.toLowerCase().endsWith(".zip")) {
26637
- throw new CliError("\u4E3B\u9898/\u63D2\u4EF6\u8BF7\u6307\u5B9A\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\uFF0C\u4E0D\u8981\u81EA\u5DF1\u6253 zip\u3002", "FILE_THEME_ZIP");
26638
- }
26639
- if (themeOrWidget && stats?.isFile()) {
26640
- throw new CliError("\u4E3B\u9898/\u63D2\u4EF6\u8BF7\u6307\u5B9A\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\uFF0C\u4E0D\u8981\u81EA\u5DF1\u6253 zip\u3002", "FILE_THEME_ZIP");
26641
- }
26642
- }
26643
- async function zipDirectoryContents(dir) {
26644
- if (!existsSync9(dir) || !statSync(dir).isDirectory()) {
26645
- throw new CliError(`\u6CA1\u6709\u6784\u5EFA\u4EA7\u7269 ${dir}\uFF0C\u8BF7\u5148\u6784\u5EFA`, "ZIP_MISSING");
26646
- }
26647
- if (existsSync9(path13.join(dir, ".freelog"))) {
26648
- 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
- }
26650
- const entries = readdirSync3(dir);
26651
- if (entries.length === 0) {
26652
- throw new CliError("\u6784\u5EFA\u4EA7\u7269\u662F\u7A7A\u7684\uFF0C\u8BF7\u5148\u6784\u5EFA", "ZIP_EMPTY");
26653
- }
26654
- const outPath = path13.join(
26655
- tmpdir(),
26656
- `freelog-zip-${process.pid}-${Date.now()}.zip`
26657
- );
26658
- const output2 = createWriteStream(outPath);
26659
- const archive = archiver("zip", { zlib: { level: 9 } });
26660
- try {
26661
- archive.on("error", (error2) => output2.destroy(error2));
26662
- archive.pipe(output2);
26663
- for (const entry2 of entries) {
26664
- const full = path13.join(dir, entry2);
26665
- const stats = statSync(full);
26666
- if (stats.isDirectory()) {
26667
- archive.directory(full, entry2);
26668
- } else {
26669
- archive.file(full, { name: entry2 });
26670
- }
26671
- }
26672
- await archive.finalize();
26673
- await finished(output2);
26674
- return outPath;
26675
- } catch (error2) {
26676
- if (existsSync9(outPath)) {
26677
- try {
26678
- unlinkSync5(outPath);
26679
- } catch {
26680
- }
26681
- }
26682
- throw error2;
26683
- }
26684
- }
26685
- async function prepareUploadPath(typeCode, filePath) {
26686
- assertArtifactPath(typeCode, filePath);
26687
- if (isThemeOrWidget2(typeCode) && existsSync9(filePath) && statSync(filePath).isDirectory()) {
26688
- return zipDirectoryContents(filePath);
26689
- }
26690
- return filePath;
26691
- }
26692
-
26693
- // src/domain/version/file.ts
26842
+ import { existsSync as existsSync12, readFileSync as readFileSync9, statSync as statSync2, unlinkSync as unlinkSync6 } from "fs";
26843
+ import path15 from "path";
26694
26844
  var ANALYZE_TIMEOUT_MS = 12e4;
26695
26845
  var ANALYZE_POLL_INTERVAL_MS = 200;
26696
26846
  function resolveExistingPath(cwd, raw) {
26697
- if (existsSync10(raw)) {
26698
- return path14.resolve(raw);
26847
+ if (existsSync12(raw)) {
26848
+ return path15.resolve(raw);
26699
26849
  }
26700
- const joined = path14.resolve(cwd, raw);
26701
- if (existsSync10(joined)) {
26850
+ const joined = path15.resolve(cwd, raw);
26851
+ if (existsSync12(joined)) {
26702
26852
  return joined;
26703
26853
  }
26704
26854
  return void 0;
@@ -26757,7 +26907,7 @@ async function uploadIfNew(uploadPath, sha1, typeCode, apis) {
26757
26907
  await upload({ file: readFileSync9(uploadPath), resourceType: typeCode });
26758
26908
  }
26759
26909
  function removeTempZip(uploadPath, localPath) {
26760
- if (uploadPath === localPath || !existsSync10(uploadPath)) {
26910
+ if (uploadPath === localPath || !existsSync12(uploadPath)) {
26761
26911
  return;
26762
26912
  }
26763
26913
  try {
@@ -26806,12 +26956,12 @@ async function uploadAndAnalyze(input2) {
26806
26956
  async function uploadAndAnalyzeLocked(input2) {
26807
26957
  assertPlatformAllowed();
26808
26958
  const file = input2.file !== void 0 ? normalizeProjectPath(input2.cwd, input2.file) : void 0;
26809
- const recordedFile = input2.identity.filePath ? normalizeProjectPath(input2.cwd, input2.identity.filePath) : void 0;
26959
+ const recordedFile = normalizeProjectPath(input2.cwd, input2.identity.filePath);
26810
26960
  const identity = recordedFile === input2.identity.filePath ? input2.identity : { ...input2.identity, filePath: recordedFile };
26811
26961
  const localPath = confirmLocalPath(identity, file, input2.yes, input2.cwd);
26812
26962
  const uploadPath = await prepareUploadPath(identity.typeCode, localPath);
26813
26963
  try {
26814
- const uploaded = { fileSha1: sha1OfFile(uploadPath), filename: path14.basename(uploadPath) };
26964
+ const uploaded = { fileSha1: sha1OfFile(uploadPath), filename: path15.basename(uploadPath) };
26815
26965
  await uploadIfNew(uploadPath, uploaded.fileSha1, identity.typeCode, input2.apis ?? {});
26816
26966
  const analysis = await waitAnalyze(
26817
26967
  uploaded.fileSha1,
@@ -26837,16 +26987,11 @@ async function uploadAndAnalyzeLocked(input2) {
26837
26987
  }
26838
26988
 
26839
26989
  // src/domain/version/artifact.ts
26840
- function resolveArtifactPath(cwd, identity, file, artifact) {
26990
+ function resolveArtifactPath(cwd, _identity, _selector, artifact) {
26841
26991
  if (artifact !== void 0) {
26842
26992
  return normalizeProjectPath(cwd, artifact);
26843
26993
  }
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;
26994
+ return void 0;
26850
26995
  }
26851
26996
 
26852
26997
  // src/domain/version/createVersion.ts
@@ -26869,12 +27014,26 @@ async function runCreateVersionLocked(input2) {
26869
27014
  })
26870
27015
  );
26871
27016
  const latestVersion = info2.latestVersion ? String(info2.latestVersion) : void 0;
27017
+ const existingDraft = readDraft(input2.cwd, identity.n);
27018
+ evaluateGates({ latestVersion, draft: input2.reset ? void 0 : existingDraft }, "create-version");
27019
+ const artifact = resolveArtifactPath(input2.cwd, identity, input2.file, input2.artifact);
27020
+ if (!input2.prepare && !input2.yes) {
27021
+ throw new CliError("\u63D0\u4EA4\u8BF7\u52A0 --yes", "CREATE_VERSION_NEED_YES");
27022
+ }
26872
27023
  if (input2.reset) {
27024
+ confirmLocalPath(identity, artifact, input2.yes, input2.cwd);
27025
+ }
27026
+ let draft = existingDraft;
27027
+ if (input2.reset && existingDraft) {
27028
+ if (!input2.confirmReset) {
27029
+ throw new CliError("\u8BF7\u5148\u786E\u8BA4\u4E22\u5F03\u5DE5\u4F5C\u7A3F", "RESET_CONFIRMATION_REQUIRED");
27030
+ }
27031
+ if (!await input2.confirmReset(draftSummary(existingDraft))) {
27032
+ return "\u5DF2\u53D6\u6D88";
27033
+ }
26873
27034
  deleteDraft(input2.cwd, identity.n);
27035
+ draft = void 0;
26874
27036
  }
26875
- const draft = readDraft(input2.cwd, identity.n);
26876
- evaluateGates({ latestVersion, draft }, "create-version");
26877
- const artifact = resolveArtifactPath(input2.cwd, identity, input2.file, input2.artifact);
26878
27037
  if (!draft || input2.prepare || artifact) {
26879
27038
  writeDraft(input2.cwd, identity.n, draft ?? emptyDraft());
26880
27039
  }
@@ -26888,9 +27047,6 @@ async function runCreateVersionLocked(input2) {
26888
27047
  });
26889
27048
  return "\u5DF2\u5907\u7A3F\uFF0C\u672A\u63D0\u4EA4";
26890
27049
  }
26891
- if (!input2.yes) {
26892
- throw new CliError("\u63D0\u4EA4\u8BF7\u52A0 --yes", "CREATE_VERSION_NEED_YES");
26893
- }
26894
27050
  await uploadAndAnalyze({
26895
27051
  cwd: input2.cwd,
26896
27052
  identity,
@@ -26919,9 +27075,14 @@ async function runCreateVersionLocked(input2) {
26919
27075
  return "1.0.0";
26920
27076
  }
26921
27077
 
27078
+ // src/commands/version/draftConfirmation.ts
27079
+ async function confirmDraftDestruction(input2) {
27080
+ return confirmDestructive(input2.summary, input2.action, input2.yes, isInteractive(), confirmQuestion);
27081
+ }
27082
+
26922
27083
  // src/commands/version/create-version.ts
26923
27084
  function createCreateVersionCommand() {
26924
- const command = addSharedOptions(new Command19("create-version"));
27085
+ const command = addSharedOptions(new Command20("create-version"));
26925
27086
  command.description(
26926
27087
  // i18n: cli.command.create_version.description
26927
27088
  "\u63D0\u4EA4\u9996\u7248"
@@ -26939,12 +27100,14 @@ function createCreateVersionCommand() {
26939
27100
  "\u672C\u6B21\u4E0A\u4F20\u5E76\u8BB0\u5F55\u7684\u672C\u5730\u6587\u4EF6\u6216\u76EE\u5F55"
26940
27101
  ).action(async function(options) {
26941
27102
  const shared = readSharedOptions(this);
27103
+ const cwd = resolveCwd(shared.cwd);
26942
27104
  const result = await runCreateVersion({
26943
- cwd: resolveCwd(shared.cwd),
27105
+ cwd,
26944
27106
  file: shared.file,
26945
27107
  artifact: options.artifact,
26946
27108
  prepare: options.prepare,
26947
27109
  reset: options.reset,
27110
+ confirmReset: options.reset ? (summary) => confirmDraftDestruction({ summary, yes: shared.yes, action: "\u4E22\u5F03\u5DE5\u4F5C\u7A3F\u5E76\u91CD\u7F6E\u9996\u7248" }) : void 0,
26948
27111
  yes: shared.yes
26949
27112
  });
26950
27113
  console.log(result);
@@ -26953,7 +27116,7 @@ function createCreateVersionCommand() {
26953
27116
  }
26954
27117
 
26955
27118
  // src/commands/version/dep.ts
26956
- import { Command as Command20 } from "commander";
27119
+ import { Command as Command21 } from "commander";
26957
27120
 
26958
27121
  // src/domain/version/form/dep.ts
26959
27122
  import semver from "semver";
@@ -27223,7 +27386,7 @@ async function depRangeLocked(cwd, resourceId, versionRange, file, apis, options
27223
27386
 
27224
27387
  // src/commands/version/dep.ts
27225
27388
  function createVersionDepCommand() {
27226
- const dep = addSharedOptions(new Command20("dep"));
27389
+ const dep = addSharedOptions(new Command21("dep"));
27227
27390
  dep.description("\u6539\u7A3F\u4E0A\u7684\u4F9D\u8D56");
27228
27391
  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
27392
  const shared = readSharedOptions(this);
@@ -27256,7 +27419,7 @@ function createVersionDepCommand() {
27256
27419
  }
27257
27420
 
27258
27421
  // src/commands/version/description.ts
27259
- import { Command as Command21 } from "commander";
27422
+ import { Command as Command22 } from "commander";
27260
27423
 
27261
27424
  // src/domain/version/description.ts
27262
27425
  async function updateOnlineDescription(input2) {
@@ -27289,7 +27452,7 @@ async function updateOnlineDescription(input2) {
27289
27452
 
27290
27453
  // src/commands/version/description.ts
27291
27454
  function createVersionDescriptionCommand() {
27292
- const command = addSharedOptions(new Command21("description"));
27455
+ const command = addSharedOptions(new Command22("description"));
27293
27456
  command.description(
27294
27457
  // i18n: cli.command.version.description.description
27295
27458
  "\u6539\u7EBF\u4E0A\u5DF2\u53D1\u53F7\u63CF\u8FF0"
@@ -27354,18 +27517,26 @@ function registerDraftDescription(draft) {
27354
27517
  }
27355
27518
 
27356
27519
  // src/commands/version/draft.ts
27357
- import { Command as Command22 } from "commander";
27520
+ import { Command as Command23 } from "commander";
27358
27521
 
27359
27522
  // src/domain/version/draftDiscard.ts
27360
- function draftDiscard(cwd, file) {
27361
- return withProjectLock(cwd, () => draftDiscardLocked(cwd, file), "version-draft-discard");
27523
+ async function draftDiscard(cwd, file, confirmed = false, confirm4) {
27524
+ return withProjectLock(cwd, () => draftDiscardLocked(cwd, file, confirmed, confirm4), "version-draft-discard");
27362
27525
  }
27363
- function draftDiscardLocked(cwd, file) {
27526
+ async function draftDiscardLocked(cwd, file, confirmed, confirm4) {
27364
27527
  const identity = resolveIdentity(cwd, file);
27365
27528
  const draft = readDraft(cwd, identity.n);
27366
27529
  if (!draft) {
27367
27530
  return "\u6CA1\u6709\u5DE5\u4F5C\u7A3F";
27368
27531
  }
27532
+ if (!confirmed) {
27533
+ if (!confirm4) {
27534
+ throw new CliError("\u8BF7\u5148\u786E\u8BA4\u4E22\u5F03\u5DE5\u4F5C\u7A3F", "DRAFT_DISCARD_CONFIRMATION_REQUIRED");
27535
+ }
27536
+ if (!await confirm4(draftSummary(draft))) {
27537
+ return "\u5DF2\u53D6\u6D88";
27538
+ }
27539
+ }
27369
27540
  deleteDraft(cwd, identity.n);
27370
27541
  return "\u5DF2\u4E22\u6389\u5DE5\u4F5C\u7A3F";
27371
27542
  }
@@ -27392,17 +27563,6 @@ async function draftPullLocked(input2) {
27392
27563
  if (!want) {
27393
27564
  throw new CliError("\u8FD8\u6CA1\u6709\u53D1\u884C\u7248\u672C\uFF0C\u8BF7\u5148 create-version", "GATE_USE_CREATE");
27394
27565
  }
27395
- if (existing) {
27396
- const summary = draftSummary(existing);
27397
- if (!input2.yes && existing.fromVersion === want) {
27398
- return `${summary}
27399
- \u7A3F\u5DF2\u6765\u81EA ${want}\uFF0C\u672A\u8986\u76D6`;
27400
- }
27401
- if (!input2.yes) {
27402
- return `${summary}
27403
- \u672A\u8986\u76D6`;
27404
- }
27405
- }
27406
27566
  const versionInfoApi = input2.apis?.resourceVersionInfo1 ?? ((params) => service_API_default.Resource.resourceVersionInfo1(params));
27407
27567
  const versionInfo = unwrapData2(
27408
27568
  await versionInfoApi({
@@ -27414,6 +27574,17 @@ async function draftPullLocked(input2) {
27414
27574
  if (!pulledSha) {
27415
27575
  throw new CliError("\u6CA1\u6709\u8FD9\u4E2A\u7248\u672C", "DRAFT_VERSION_MISSING");
27416
27576
  }
27577
+ if (existing && !input2.yes) {
27578
+ const summary = draftSummary(existing);
27579
+ if (!input2.confirmOverwrite) {
27580
+ return existing.fromVersion === want ? `${summary}
27581
+ \u7A3F\u5DF2\u6765\u81EA ${want}\uFF0C\u672A\u8986\u76D6` : `${summary}
27582
+ \u672A\u8986\u76D6`;
27583
+ }
27584
+ if (!await input2.confirmOverwrite(summary, want)) {
27585
+ return "\u5DF2\u53D6\u6D88";
27586
+ }
27587
+ }
27417
27588
  writeDraft(input2.cwd, identity.n, {
27418
27589
  fromVersion: want,
27419
27590
  fileSha1: pulledSha,
@@ -27434,7 +27605,7 @@ async function draftPullLocked(input2) {
27434
27605
 
27435
27606
  // src/commands/version/draft.ts
27436
27607
  function createVersionDraftCommand() {
27437
- const draft = addSharedOptions(new Command22("draft"));
27608
+ const draft = addSharedOptions(new Command23("draft"));
27438
27609
  draft.description(
27439
27610
  // i18n: cli.command.version.draft.description
27440
27611
  "\u7BA1\u672C\u5730\u5DE5\u4F5C\u7A3F"
@@ -27448,26 +27619,42 @@ function createVersionDraftCommand() {
27448
27619
  "\u5DF2\u53D1\u53F7"
27449
27620
  ).action(async function(options) {
27450
27621
  const shared = readSharedOptions(this);
27622
+ const cwd = resolveCwd(shared.cwd);
27451
27623
  const text = await draftPull({
27452
- cwd: resolveCwd(shared.cwd),
27624
+ cwd,
27453
27625
  file: shared.file,
27454
27626
  version: options.version,
27455
- yes: shared.yes
27627
+ yes: shared.yes,
27628
+ confirmOverwrite: (summary, version) => confirmDraftDestruction({
27629
+ summary,
27630
+ yes: shared.yes,
27631
+ action: `\u7528\u7EBF\u4E0A\u7248\u672C ${version} \u8986\u76D6\u672C\u5730\u5DE5\u4F5C\u7A3F`
27632
+ })
27456
27633
  });
27457
27634
  console.log(text);
27458
27635
  });
27459
27636
  addSharedOptions(draft.command("discard")).description(
27460
27637
  // i18n: cli.command.version.draft.discard.description
27461
27638
  "\u4E22\u6389\u5DE5\u4F5C\u7A3F"
27462
- ).action(function() {
27639
+ ).action(async function() {
27463
27640
  const shared = readSharedOptions(this);
27464
- console.log(draftDiscard(resolveCwd(shared.cwd), shared.file));
27641
+ const cwd = resolveCwd(shared.cwd);
27642
+ console.log(await draftDiscard(
27643
+ cwd,
27644
+ shared.file,
27645
+ shared.yes,
27646
+ (summary) => confirmDraftDestruction({
27647
+ summary,
27648
+ yes: shared.yes,
27649
+ action: "\u4E22\u5F03\u5DE5\u4F5C\u7A3F"
27650
+ })
27651
+ ));
27465
27652
  });
27466
27653
  return draft;
27467
27654
  }
27468
27655
 
27469
27656
  // src/commands/version/option.ts
27470
- import { Command as Command23 } from "commander";
27657
+ import { Command as Command24 } from "commander";
27471
27658
 
27472
27659
  // src/domain/version/form/option.ts
27473
27660
  var MAX_OPTION = 30;
@@ -27673,7 +27860,7 @@ function optionList(cwd, file) {
27673
27860
 
27674
27861
  // src/commands/version/option.ts
27675
27862
  function createVersionOptionCommand() {
27676
- const option = addSharedOptions(new Command23("option"));
27863
+ const option = addSharedOptions(new Command24("option"));
27677
27864
  option.description("\u6539\u7A3F\u4E0A\u7684\u53EF\u9009\u914D\u7F6E");
27678
27865
  addSharedOptions(option.command("add")).description("\u52A0\u53EF\u9009\u914D\u7F6E").argument("[line]", "\u4E00\u884C\u5F0F").action(async function(line) {
27679
27866
  const shared = readSharedOptions(this);
@@ -27703,16 +27890,18 @@ function createVersionOptionCommand() {
27703
27890
  }
27704
27891
 
27705
27892
  // src/commands/version/set.ts
27706
- import { Command as Command24 } from "commander";
27893
+ import { Command as Command25 } from "commander";
27707
27894
 
27708
27895
  // src/domain/version/setPath.ts
27896
+ import path16 from "path";
27709
27897
  function setIdentityFilePath(cwd, input2) {
27710
27898
  return withProjectLock(cwd, () => {
27711
27899
  const artifact = input2.artifact !== void 0 ? normalizeProjectPath(cwd, input2.artifact) : void 0;
27712
27900
  if (!artifact) {
27713
27901
  throw new CliError("\u8BF7\u63D0\u4F9B --artifact", "SET_ARTIFACT_REQUIRED");
27714
27902
  }
27715
- const identity = resolveIdentity(cwd);
27903
+ const identity = resolveIdentity(cwd, input2.file);
27904
+ assertArtifactAnchor(identity.typeCode, path16.resolve(cwd, artifact));
27716
27905
  const updated = prepareIdentityUpdate(cwd, identity.n, { filePath: artifact });
27717
27906
  commitLocalTransaction(cwd, [
27718
27907
  { path: identityFilePath(cwd, updated.n), content: serializeIdentity(updated) }
@@ -27723,7 +27912,7 @@ function setIdentityFilePath(cwd, input2) {
27723
27912
 
27724
27913
  // src/commands/version/set.ts
27725
27914
  function createVersionSetCommand() {
27726
- const command = addSharedOptions(new Command24("set"));
27915
+ const command = addSharedOptions(new Command25("set"));
27727
27916
  command.description(
27728
27917
  // i18n: cli.command.version.set.description
27729
27918
  "\u53EA\u6539\u8BB0\u5F55\u7684\u672C\u5730\u8DEF\u5F84"
@@ -27743,7 +27932,7 @@ function createVersionSetCommand() {
27743
27932
  }
27744
27933
 
27745
27934
  // src/commands/version/show.ts
27746
- import { Command as Command25 } from "commander";
27935
+ import { Command as Command26 } from "commander";
27747
27936
 
27748
27937
  // src/domain/version/show.ts
27749
27938
  function showLocal(cwd, file) {
@@ -27790,7 +27979,7 @@ async function showOnline(input2) {
27790
27979
 
27791
27980
  // src/commands/version/show.ts
27792
27981
  function createVersionShowCommand() {
27793
- const command = addSharedOptions(new Command25("show"));
27982
+ const command = addSharedOptions(new Command26("show"));
27794
27983
  command.description(
27795
27984
  // i18n: cli.command.version.show.description
27796
27985
  "\u53EA\u8BFB\u67E5\u770B"
@@ -27824,7 +28013,7 @@ function createVersionShowCommand() {
27824
28013
  }
27825
28014
 
27826
28015
  // src/commands/version/update-version.ts
27827
- import { Command as Command26 } from "commander";
28016
+ import { Command as Command27 } from "commander";
27828
28017
 
27829
28018
  // src/domain/version/updateVersion.ts
27830
28019
  import semver2 from "semver";
@@ -27847,13 +28036,40 @@ async function runUpdateVersionLocked(input2) {
27847
28036
  })
27848
28037
  );
27849
28038
  const latestVersion = info2.latestVersion ? String(info2.latestVersion) : void 0;
28039
+ const existingDraft = readDraft(input2.cwd, identity.n);
28040
+ const source = input2.reuseVersion ?? latestVersion;
28041
+ evaluateGates({ latestVersion, draft: input2.reset ? void 0 : existingDraft, reuseVersion: input2.reuseVersion }, "update-version");
28042
+ const artifact = resolveArtifactPath(input2.cwd, identity, input2.file, input2.artifact);
28043
+ if (!input2.reset && input2.yes && existingDraft?.fromVersion && source && existingDraft.fromVersion !== source) {
28044
+ throw new CliError(
28045
+ `\u7A3F\u6765\u81EA ${existingDraft.fromVersion}\u3001\u5E95\u662F ${source}\u3002\u8BF7 version draft pull \u6216 --reuse-version`,
28046
+ "UPDATE_VERSION_MISMATCH"
28047
+ );
28048
+ }
28049
+ const next = resolveNextVersion(latestVersion, input2.version, input2.bump);
28050
+ if (!semver2.gt(next, latestVersion)) {
28051
+ throw new CliError(
28052
+ `\u7EBF\u4E0A\u5DF2\u7ECF\u662F ${latestVersion}\uFF0C\u4E0D\u80FD\u53D1 ${next}`,
28053
+ "UPDATE_VERSION_NOT_GREATER"
28054
+ );
28055
+ }
28056
+ if (!input2.yes) {
28057
+ throw new CliError("\u63D0\u4EA4\u8BF7\u52A0 --yes", "UPDATE_VERSION_NEED_YES");
28058
+ }
27850
28059
  if (input2.reset) {
28060
+ confirmLocalPath(identity, artifact, input2.yes, input2.cwd);
28061
+ }
28062
+ let draft = existingDraft;
28063
+ if (input2.reset && existingDraft) {
28064
+ if (!input2.confirmReset) {
28065
+ throw new CliError("\u8BF7\u5148\u786E\u8BA4\u4E22\u5F03\u5DE5\u4F5C\u7A3F", "RESET_CONFIRMATION_REQUIRED");
28066
+ }
28067
+ if (!await input2.confirmReset(draftSummary(existingDraft))) {
28068
+ return "\u5DF2\u53D6\u6D88";
28069
+ }
27851
28070
  deleteDraft(input2.cwd, identity.n);
28071
+ draft = void 0;
27852
28072
  }
27853
- let draft = readDraft(input2.cwd, identity.n);
27854
- const source = input2.reuseVersion ?? latestVersion;
27855
- evaluateGates({ latestVersion, draft, reuseVersion: input2.reuseVersion }, "update-version");
27856
- const artifact = resolveArtifactPath(input2.cwd, identity, input2.file, input2.artifact);
27857
28073
  if (input2.yes && draft && !draft.fromVersion && input2.reuseVersion === void 0) {
27858
28074
  throw new CliError("\u8BF7\u5148 version draft pull --yes", "UPDATE_VERSION_FIRST_DRAFT");
27859
28075
  }
@@ -27873,16 +28089,6 @@ async function runUpdateVersionLocked(input2) {
27873
28089
  "UPDATE_VERSION_MISMATCH"
27874
28090
  );
27875
28091
  }
27876
- const next = resolveNextVersion(latestVersion, input2.version, input2.bump);
27877
- if (!semver2.gt(next, latestVersion)) {
27878
- throw new CliError(
27879
- `\u7EBF\u4E0A\u5DF2\u7ECF\u662F ${latestVersion}\uFF0C\u4E0D\u80FD\u53D1 ${next}`,
27880
- "UPDATE_VERSION_NOT_GREATER"
27881
- );
27882
- }
27883
- if (!input2.yes) {
27884
- throw new CliError("\u63D0\u4EA4\u8BF7\u52A0 --yes", "UPDATE_VERSION_NEED_YES");
27885
- }
27886
28092
  await uploadAndAnalyze({
27887
28093
  cwd: input2.cwd,
27888
28094
  identity,
@@ -27933,7 +28139,7 @@ function resolveNextVersion(latest, version, bump) {
27933
28139
 
27934
28140
  // src/commands/version/update-version.ts
27935
28141
  function createUpdateVersionCommand() {
27936
- const command = addSharedOptions(new Command26("update-version"));
28142
+ const command = addSharedOptions(new Command27("update-version"));
27937
28143
  command.description(
27938
28144
  // i18n: cli.command.update_version.description
27939
28145
  "\u5B9A\u65B0\u53F7\u5E76\u63D0\u4EA4"
@@ -27959,14 +28165,16 @@ function createUpdateVersionCommand() {
27959
28165
  "\u672C\u6B21\u4E0A\u4F20\u5E76\u8BB0\u5F55\u7684\u672C\u5730\u6587\u4EF6\u6216\u76EE\u5F55"
27960
28166
  ).action(async function(options) {
27961
28167
  const shared = readSharedOptions(this);
28168
+ const cwd = resolveCwd(shared.cwd);
27962
28169
  const result = await runUpdateVersion({
27963
- cwd: resolveCwd(shared.cwd),
28170
+ cwd,
27964
28171
  file: shared.file,
27965
28172
  artifact: options.artifact,
27966
28173
  version: options.version,
27967
28174
  bump: options.bump,
27968
28175
  reuseVersion: options.reuseVersion,
27969
28176
  reset: options.reset,
28177
+ confirmReset: options.reset ? (summary) => confirmDraftDestruction({ summary, yes: shared.yes, action: "\u4E22\u5F03\u5DE5\u4F5C\u7A3F\u5E76\u91CD\u7F6E\u66F4\u65B0\u7248\u672C" }) : void 0,
27970
28178
  yes: shared.yes
27971
28179
  });
27972
28180
  console.log(result);
@@ -27976,7 +28184,7 @@ function createUpdateVersionCommand() {
27976
28184
 
27977
28185
  // src/commands/index.ts
27978
28186
  function createVersionCommand() {
27979
- const version = addSharedOptions(new Command27("version"));
28187
+ const version = addSharedOptions(new Command28("version"));
27980
28188
  version.description(
27981
28189
  // i18n: cli.command.version.description
27982
28190
  "\u770B\u7EBF\u4E0A\u3001\u7BA1\u5DE5\u4F5C\u7A3F\u3001\u6539\u7A3F"
@@ -27993,7 +28201,7 @@ function createVersionCommand() {
27993
28201
  return version;
27994
28202
  }
27995
28203
  function createPolicyCommand() {
27996
- const policy = addSharedOptions(new Command27("policy"));
28204
+ const policy = addSharedOptions(new Command28("policy"));
27997
28205
  policy.description(
27998
28206
  // i18n: cli.command.policy.description
27999
28207
  "\u6388\u6743\u7B56\u7565"
@@ -28011,6 +28219,7 @@ function createSubCommands() {
28011
28219
  init: createInitCommand(),
28012
28220
  template: createTemplateCommand(),
28013
28221
  type: createTypeCommand(),
28222
+ resource: createResourceCommand(),
28014
28223
  bind: createBindCommand(),
28015
28224
  status: createStatusCommand(),
28016
28225
  create: createCreateCommand(),
@@ -28026,32 +28235,32 @@ function createSubCommands() {
28026
28235
  }
28027
28236
 
28028
28237
  // src/core/usageDocs.ts
28029
- import { existsSync as existsSync11 } from "fs";
28030
- import path15 from "path";
28238
+ import { existsSync as existsSync13 } from "fs";
28239
+ import path17 from "path";
28031
28240
  import { fileURLToPath } from "url";
28032
28241
  function usageDocsPath() {
28033
- const moduleDir = path15.dirname(fileURLToPath(import.meta.url));
28034
- const bundledPath = path15.resolve(moduleDir, "../docs/README.md");
28035
- if (existsSync11(bundledPath)) {
28242
+ const moduleDir = path17.dirname(fileURLToPath(import.meta.url));
28243
+ const bundledPath = path17.resolve(moduleDir, "../docs/README.md");
28244
+ if (existsSync13(bundledPath)) {
28036
28245
  return bundledPath;
28037
28246
  }
28038
- return path15.resolve(moduleDir, "../../../../docs/\u4E00\u671F/\u4EA7\u54C1\u65B9\u6848/\u4F7F\u7528/README.md");
28247
+ return path17.resolve(moduleDir, "../../../../docs/\u4E00\u671F/\u4EA7\u54C1\u65B9\u6848/\u4F7F\u7528/README.md");
28039
28248
  }
28040
28249
 
28041
28250
  // src/core/packageVersion.ts
28042
28251
  import { readFileSync as readFileSync10 } from "fs";
28043
- import path16 from "path";
28252
+ import path18 from "path";
28044
28253
  import { fileURLToPath as fileURLToPath2 } from "url";
28045
28254
  function packageVersion() {
28046
- const moduleDir = path16.dirname(fileURLToPath2(import.meta.url));
28047
- const packageJson = path16.resolve(moduleDir, "../..", "package.json");
28255
+ const moduleDir = path18.dirname(fileURLToPath2(import.meta.url));
28256
+ const packageJson = path18.resolve(moduleDir, "../..", "package.json");
28048
28257
  const value = JSON.parse(readFileSync10(packageJson, "utf8"));
28049
28258
  return typeof value.version === "string" ? value.version : "unknown";
28050
28259
  }
28051
28260
 
28052
28261
  // src/bin/program.ts
28053
28262
  function createProgram() {
28054
- const program = new Command28();
28263
+ const program = new Command29();
28055
28264
  program.name("freelog-cli").description(
28056
28265
  // i18n: cli.program.description
28057
28266
  "Freelog \u547D\u4EE4\u884C"
@@ -28064,17 +28273,81 @@ function createProgram() {
28064
28273
  \u4F7F\u7528\u6587\u6863\uFF1A${usageDocsPath()}
28065
28274
  `);
28066
28275
  addSharedOptions(program);
28067
- program.hook("preAction", (thisCommand) => {
28068
- const envFlag = findOptionValue(thisCommand, "env");
28276
+ program.hook("preAction", async (thisCommand, actionCommand) => {
28277
+ const envFlag = findOptionValue(actionCommand ?? thisCommand, "env");
28069
28278
  applyCliEnv({ flag: typeof envFlag === "string" ? envFlag : void 0 });
28070
- const cwdFlag = findOptionValue(thisCommand, "cwd");
28071
- setAuthSearchCwd(resolveCwd(typeof cwdFlag === "string" ? cwdFlag : void 0));
28279
+ const cwdFlag = findOptionValue(actionCommand ?? thisCommand, "cwd");
28280
+ const cwd = resolveCwd(typeof cwdFlag === "string" ? cwdFlag : void 0);
28281
+ setAuthSearchCwd(cwd);
28282
+ await chooseResourceWhenNeeded(actionCommand ?? thisCommand, cwd);
28072
28283
  });
28073
28284
  for (const command of Object.values(createSubCommands())) {
28074
28285
  program.addCommand(command);
28075
28286
  }
28076
28287
  return program;
28077
28288
  }
28289
+ var RESOURCE_FREE_COMMANDS = /* @__PURE__ */ new Set(["login", "logout", "init", "template", "type", "resource", "create", "bind"]);
28290
+ async function chooseResourceWhenNeeded(command, cwd) {
28291
+ if (isResourceFreeCommand(command)) return;
28292
+ const selector = findOptionValue(command, "resource");
28293
+ if (typeof selector === "string") return;
28294
+ const identities = validateLocalState(cwd);
28295
+ if (identities.length <= 1) return;
28296
+ const yes = findOptionValue(command, "yes") === true;
28297
+ if (yes || !isInteractive()) {
28298
+ throw new CliError(
28299
+ `\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)}`,
28300
+ "IDENTITY_RESOURCE_REQUIRED"
28301
+ );
28302
+ }
28303
+ const selected = await selectQuestion("\u8BF7\u9009\u62E9\u8D44\u6E90", [
28304
+ ...identities.map((identity) => ({
28305
+ name: resourceChoiceLabel(cwd, identity),
28306
+ value: `file:${identity.n}.json`
28307
+ })),
28308
+ { name: "\u9000\u51FA", value: "__cancel__" }
28309
+ ]);
28310
+ if (selected === "__cancel__") {
28311
+ throw new CliError("\u5DF2\u53D6\u6D88", "RESOURCE_SELECTION_CANCELLED");
28312
+ }
28313
+ command.setOptionValue("resource", selected);
28314
+ }
28315
+ function resourceChoiceLabel(cwd, identity) {
28316
+ const draft = readDraft(cwd, identity.n) ? "\u6709\u5DE5\u4F5C\u7A3F" : "\u65E0\u5DE5\u4F5C\u7A3F";
28317
+ return [
28318
+ `${identity.n}.json`,
28319
+ `\u6807\u9898=${identity.title ?? "\uFF08\u672A\u540C\u6B65\u6807\u9898\uFF09"}`,
28320
+ `\u6807\u8BC6=${identity.name ?? "\u672A\u7ED1\u5B9A"}`,
28321
+ `ID=${identity.resourceId ?? "\u672A\u7ED1\u5B9A"}`,
28322
+ `\u7C7B\u578B=${identity.typeCode}`,
28323
+ `\u4EA7\u7269=${identity.filePath ?? "\u672A\u8BBE\u7F6E"}`,
28324
+ draft
28325
+ ].join(" ");
28326
+ }
28327
+ function resourceSelectorExamples(identities) {
28328
+ const titleCounts = /* @__PURE__ */ new Map();
28329
+ for (const identity of identities) {
28330
+ if (identity.title) titleCounts.set(identity.title, (titleCounts.get(identity.title) ?? 0) + 1);
28331
+ }
28332
+ return identities.map((identity) => {
28333
+ const selectors = [
28334
+ ...identity.resourceId ? [`id:${identity.resourceId}`] : [],
28335
+ ...identity.name ? [`name:${identity.name}`] : [],
28336
+ ...identity.title && titleCounts.get(identity.title) === 1 ? [`title:${identity.title}`] : [],
28337
+ `artifact:${identity.filePath}`,
28338
+ `file:${identity.n}.json`
28339
+ ];
28340
+ return selectors.join(" | ");
28341
+ }).join("\uFF1B");
28342
+ }
28343
+ function isResourceFreeCommand(command) {
28344
+ let current = command;
28345
+ while (current) {
28346
+ if (RESOURCE_FREE_COMMANDS.has(current.name())) return true;
28347
+ current = current.parent;
28348
+ }
28349
+ return false;
28350
+ }
28078
28351
  async function runCli(argv, options = {}) {
28079
28352
  const writeOut = options.writeOut ?? ((text) => {
28080
28353
  process.stdout.write(text);