mano-coding 0.1.22 → 0.1.24

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.js CHANGED
@@ -23947,7 +23947,7 @@ var init_errors3 = __esm({
23947
23947
 
23948
23948
  // packages/core/src/resolvers/registry-client.ts
23949
23949
  function selectRelease(entry, versionRange) {
23950
- const stableVersion = entry.channels?.stable;
23950
+ const packageId = entry.id ?? entry.metadata?.id ?? "unknown";
23951
23951
  const normalizedRange = normalizeRange(versionRange);
23952
23952
  const candidates = entry.releases.filter((r) => {
23953
23953
  if (import_semver2.default.prerelease(r.version) && !rangeAllowsPrerelease(normalizedRange)) {
@@ -23957,12 +23957,13 @@ function selectRelease(entry, versionRange) {
23957
23957
  });
23958
23958
  if (candidates.length === 0) {
23959
23959
  throw new RegistryError(
23960
- `Package ${entry.metadata.id} \u6CA1\u6709\u6EE1\u8DB3\u7248\u672C\u8303\u56F4 '${versionRange}' \u7684 Release`,
23960
+ `Package ${packageId} \u6CA1\u6709\u6EE1\u8DB3\u7248\u672C\u8303\u56F4 '${versionRange}' \u7684 Release`,
23961
23961
  "REGISTRY_NO_MATCHING_RELEASE",
23962
- entry.metadata.id
23962
+ packageId
23963
23963
  );
23964
23964
  }
23965
23965
  candidates.sort((a, b2) => import_semver2.default.rcompare(a.version, b2.version));
23966
+ const stableVersion = entry.channels?.stable ?? candidates.find((r) => !import_semver2.default.prerelease(r.version))?.version;
23966
23967
  if (stableVersion) {
23967
23968
  const stableMatch = candidates.find((r) => r.version === stableVersion);
23968
23969
  if (stableMatch) return stableMatch;
@@ -28159,9 +28160,18 @@ var init_gitlab_registry_client = __esm({
28159
28160
  );
28160
28161
  }
28161
28162
  const entry = value;
28162
- if (entry.metadata.id !== packageId) {
28163
+ const entryId = entry.id ?? entry.metadata?.id;
28164
+ if (entryId && entryId !== packageId) {
28163
28165
  throw new RegistryError(`Registry Entry \u6807\u8BC6\u4E0D\u5339\u914D: \u671F\u671B ${packageId}`, "REGISTRY_ENTRY_INVALID", packageId);
28164
28166
  }
28167
+ if (!entry.metadata) {
28168
+ entry.metadata = {
28169
+ id: entry.id ?? packageId,
28170
+ name: entry.name,
28171
+ displayName: entry.displayName ?? entry.name,
28172
+ description: entry.description
28173
+ };
28174
+ }
28165
28175
  const { isGitLabShorthand: isGitLabShorthand2, parseGitLabShorthand: parseGitLabShorthand2 } = await Promise.resolve().then(() => (init_gitlab_shorthand(), gitlab_shorthand_exports));
28166
28176
  for (const release of entry.releases) {
28167
28177
  if (typeof release.source === "string" && isGitLabShorthand2(release.source)) {
@@ -31978,10 +31988,11 @@ function interpolateString(template, ctx) {
31978
31988
  }
31979
31989
  function generateTaskSummary(tasks, ctx) {
31980
31990
  return tasks.map((task, idx) => {
31991
+ const taskLabel = task.name ? `${task.name} (${task.id})` : task.id;
31981
31992
  const command = interpolateString(task.command, ctx);
31982
31993
  const args = (task.args ?? []).map((arg) => interpolateString(arg, ctx));
31983
31994
  const fullCmd = [command, ...args].join(" ");
31984
- return `[${idx + 1}/${tasks.length}] ${task.id}: ${fullCmd}`;
31995
+ return `[${idx + 1}/${tasks.length}] ${taskLabel}: ${fullCmd}`;
31985
31996
  });
31986
31997
  }
31987
31998
  function resolveTaskExecutable(command, platform = process.platform, envPath) {
@@ -32040,8 +32051,9 @@ async function executeTasks(tasks, ctx, options = {}) {
32040
32051
  env[k2] = interpolateString(v2, ctx);
32041
32052
  }
32042
32053
  }
32054
+ const taskLabel = task.name ? `${task.name} (${task.id})` : task.id;
32043
32055
  if (options.onProgress) {
32044
- options.onProgress(`\u6B63\u5728\u6267\u884C\u4EFB\u52A1 [${i + 1}/${tasks.length}] (${task.id}): ${command} ${effectiveArgs.join(" ")}`);
32056
+ options.onProgress(`\u6B63\u5728\u6267\u884C\u4EFB\u52A1 [${i + 1}/${tasks.length}] (${taskLabel}): ${command} ${effectiveArgs.join(" ")}`);
32045
32057
  }
32046
32058
  const executable = resolveTaskExecutable(command, process.platform, env.PATH);
32047
32059
  await new Promise((resolve22, reject) => {
@@ -38886,6 +38898,101 @@ var init_searchable_select = __esm({
38886
38898
  }
38887
38899
  });
38888
38900
 
38901
+ // packages/cli/src/commands/spinner.ts
38902
+ async function withSpinner(text, action, options) {
38903
+ const spinner = new Spinner(text, { enabled: options?.enabled });
38904
+ spinner.start();
38905
+ try {
38906
+ const result = await action(spinner);
38907
+ const successMsg = typeof options?.successText === "function" ? options.successText(result) : options?.successText ?? text;
38908
+ spinner.succeed(successMsg);
38909
+ return result;
38910
+ } catch (error) {
38911
+ spinner.fail(options?.failText);
38912
+ throw error;
38913
+ }
38914
+ }
38915
+ var Spinner;
38916
+ var init_spinner = __esm({
38917
+ "packages/cli/src/commands/spinner.ts"() {
38918
+ "use strict";
38919
+ init_src2();
38920
+ Spinner = class {
38921
+ text;
38922
+ timer = null;
38923
+ frameIndex = 0;
38924
+ isSpinning = false;
38925
+ enabled;
38926
+ frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
38927
+ interval = 80;
38928
+ constructor(text = "", options = {}) {
38929
+ this.text = text;
38930
+ this.enabled = options.enabled ?? (Boolean(process.stdout.isTTY) && process.env.NODE_ENV !== "test" && !process.env.CI);
38931
+ }
38932
+ start(text) {
38933
+ if (text !== void 0) this.text = text;
38934
+ if (!this.enabled || this.isSpinning) return this;
38935
+ this.isSpinning = true;
38936
+ this.frameIndex = 0;
38937
+ process.stdout.write("\x1B[?25l");
38938
+ this.render();
38939
+ this.timer = setInterval(() => {
38940
+ this.frameIndex = (this.frameIndex + 1) % this.frames.length;
38941
+ this.render();
38942
+ }, this.interval);
38943
+ return this;
38944
+ }
38945
+ update(text) {
38946
+ this.text = text;
38947
+ if (this.isSpinning && this.enabled) {
38948
+ this.render();
38949
+ }
38950
+ return this;
38951
+ }
38952
+ succeed(text) {
38953
+ return this.stopAndPersist("\u2714", text ?? this.text, "\x1B[32m");
38954
+ }
38955
+ fail(text) {
38956
+ return this.stopAndPersist("\u2716", text ?? this.text, "\x1B[31m");
38957
+ }
38958
+ warn(text) {
38959
+ return this.stopAndPersist("\u26A0", text ?? this.text, "\x1B[33m");
38960
+ }
38961
+ info(text) {
38962
+ return this.stopAndPersist("\u2139", text ?? this.text, "\x1B[34m");
38963
+ }
38964
+ stop() {
38965
+ if (!this.isSpinning) return this;
38966
+ if (this.timer) {
38967
+ clearInterval(this.timer);
38968
+ this.timer = null;
38969
+ }
38970
+ this.isSpinning = false;
38971
+ if (this.enabled) {
38972
+ process.stdout.write("\r\x1B[2K\x1B[?25h");
38973
+ }
38974
+ return this;
38975
+ }
38976
+ stopAndPersist(symbol, text, color = "") {
38977
+ this.stop();
38978
+ if (this.enabled) {
38979
+ const reset = "\x1B[0m";
38980
+ const output = `${color}${symbol}${reset} ${redactString(text)}
38981
+ `;
38982
+ process.stdout.write(output);
38983
+ }
38984
+ return this;
38985
+ }
38986
+ render() {
38987
+ const frame = this.frames[this.frameIndex];
38988
+ const cyan = "\x1B[36m";
38989
+ const reset = "\x1B[0m";
38990
+ process.stdout.write(`\r\x1B[2K${cyan}${frame}${reset} ${redactString(this.text)}`);
38991
+ }
38992
+ };
38993
+ }
38994
+ });
38995
+
38889
38996
  // packages/cli/src/commands/tty-confirm.ts
38890
38997
  var tty_confirm_exports = {};
38891
38998
  __export(tty_confirm_exports, {
@@ -39097,19 +39204,36 @@ async function executeCreate(templateSpec, directory, options, cliVersion, event
39097
39204
  throw error;
39098
39205
  }
39099
39206
  }
39100
- const templateResolution = await events.measure("resolve", () => resolvePackageWith(
39101
- service,
39102
- templateSpec,
39103
- options,
39104
- cliVersion
39105
- ), { packageId: templateSpec });
39106
- const addonResolutions = [];
39107
- for (const addonSpec of options.addons ?? []) {
39108
- const addonResolution = await events.measure("resolve", () => resolvePackageWith(
39207
+ const spinnerEnabled = !output.json && Boolean(process.stdout.isTTY) && process.env.NODE_ENV !== "test";
39208
+ const templateResolution = await events.measure("resolve", () => withSpinner(
39209
+ `\u6B63\u5728\u62C9\u53D6\u5E76\u89E3\u6790\u6A21\u677F (${templateSpec})...`,
39210
+ () => resolvePackageWith(
39109
39211
  service,
39110
- addonSpec,
39212
+ templateSpec,
39111
39213
  options,
39112
39214
  cliVersion
39215
+ ),
39216
+ {
39217
+ enabled: spinnerEnabled,
39218
+ successText: (res) => `\u2714 \u6A21\u677F\u89E3\u6790\u5B8C\u6210: ${res.manifest.displayName ?? res.manifest.name ?? res.manifest.id ?? templateSpec} (v${res.manifest.version ?? "0.0.0"})`,
39219
+ failText: `\u2716 \u6A21\u677F\u89E3\u6790\u5931\u8D25: ${templateSpec}`
39220
+ }
39221
+ ), { packageId: templateSpec });
39222
+ const addonResolutions = [];
39223
+ for (const addonSpec of options.addons ?? []) {
39224
+ const addonResolution = await events.measure("resolve", () => withSpinner(
39225
+ `\u6B63\u5728\u62C9\u53D6\u5E76\u89E3\u6790\u6269\u5C55 (${addonSpec})...`,
39226
+ () => resolvePackageWith(
39227
+ service,
39228
+ addonSpec,
39229
+ options,
39230
+ cliVersion
39231
+ ),
39232
+ {
39233
+ enabled: spinnerEnabled,
39234
+ successText: (res) => `\u2714 \u6269\u5C55\u89E3\u6790\u5B8C\u6210: ${res.manifest.displayName ?? res.manifest.name ?? res.manifest.id ?? addonSpec} (v${res.manifest.version ?? "0.0.0"})`,
39235
+ failText: `\u2716 \u6269\u5C55\u89E3\u6790\u5931\u8D25: ${addonSpec}`
39236
+ }
39113
39237
  ), { packageId: addonSpec });
39114
39238
  addonResolutions.push(addonResolution);
39115
39239
  }
@@ -39185,7 +39309,15 @@ ${taskValidation.missingInputs.map((k2) => `--set ${k2}=<value>`).join("\n")}`,
39185
39309
  projectTargets
39186
39310
  );
39187
39311
  const userInstallationKeys = /* @__PURE__ */ new Set();
39188
- const intents = await buildIntentsFromPlan(planResult.plan, allResolutions, service, projectTargets, userInstallationKeys);
39312
+ const intents = await withSpinner(
39313
+ "\u6B63\u5728\u8BA1\u7B97\u53D7\u7BA1\u8D44\u6E90\u5E76\u751F\u6210\u6267\u884C\u8BA1\u5212...",
39314
+ () => buildIntentsFromPlan(planResult.plan, allResolutions, service, projectTargets, userInstallationKeys),
39315
+ {
39316
+ enabled: spinnerEnabled,
39317
+ successText: (res) => `\u2714 \u6267\u884C\u8BA1\u5212\u5DF2\u5C31\u7EEA (\u5171 ${res.length} \u9879\u8D44\u6E90\u53D8\u66F4)`,
39318
+ failText: "\u2716 \u6267\u884C\u8BA1\u5212\u751F\u6210\u5931\u8D25"
39319
+ }
39320
+ );
39189
39321
  planResult = materializePlan(planResult.plan, intents);
39190
39322
  events.report("plan", "success", Date.now() - planStartedAt, { planDigest: planResult.plan.planDigest, details: { intentCount: intents.length } });
39191
39323
  if (planResult.conflicts.length > 0) {
@@ -39499,6 +39631,7 @@ var init_create = __esm({
39499
39631
  init_service_locator();
39500
39632
  init_plan_execution();
39501
39633
  init_searchable_select();
39634
+ init_spinner();
39502
39635
  init_i18n();
39503
39636
  }
39504
39637
  });
@@ -39561,17 +39694,33 @@ async function executeApply(packageSpec, options, cliVersion, events) {
39561
39694
  }
39562
39695
  let templateResolution;
39563
39696
  let addonResolutions = [];
39697
+ const spinnerEnabled = !output.json && Boolean(process.stdout.isTTY) && process.env.NODE_ENV !== "test";
39564
39698
  if (existingLock) {
39565
- const existing = await resolveLockedPackages(existingLock, service);
39699
+ const existing = await withSpinner(
39700
+ "\u6B63\u5728\u4ECE\u9501\u5B9A\u6587\u4EF6\u89E3\u6790\u5DF2\u5B89\u88C5\u5305...",
39701
+ () => resolveLockedPackages(existingLock, service),
39702
+ {
39703
+ enabled: spinnerEnabled,
39704
+ successText: "\u2714 \u5DF2\u52A0\u8F7D\u9501\u5B9A\u914D\u7F6E"
39705
+ }
39706
+ );
39566
39707
  templateResolution = existing.template;
39567
39708
  addonResolutions = existing.addons;
39568
39709
  }
39569
39710
  if (packageSpec) {
39570
- const newAddonResolution = await resolvePackageWith2(
39571
- service,
39572
- packageSpec,
39573
- options,
39574
- cliVersion
39711
+ const newAddonResolution = await withSpinner(
39712
+ `\u6B63\u5728\u62C9\u53D6\u5E76\u89E3\u6790\u6269\u5C55 (${packageSpec})...`,
39713
+ () => resolvePackageWith2(
39714
+ service,
39715
+ packageSpec,
39716
+ options,
39717
+ cliVersion
39718
+ ),
39719
+ {
39720
+ enabled: spinnerEnabled,
39721
+ successText: (res) => `\u2714 \u6269\u5C55\u89E3\u6790\u5B8C\u6210: ${res.manifest.displayName ?? res.manifest.name ?? res.manifest.id ?? packageSpec} (v${res.manifest.version ?? "0.0.0"})`,
39722
+ failText: `\u2716 \u6269\u5C55\u89E3\u6790\u5931\u8D25: ${packageSpec}`
39723
+ }
39575
39724
  );
39576
39725
  addonResolutions = [...addonResolutions.filter((resolution) => resolution.packageId !== newAddonResolution.packageId), newAddonResolution];
39577
39726
  }
@@ -39612,7 +39761,15 @@ async function executeApply(packageSpec, options, cliVersion, events) {
39612
39761
  projectTargets
39613
39762
  );
39614
39763
  const userInstallationKeys = /* @__PURE__ */ new Set();
39615
- const intents = await buildIntentsFromPlan(planResult.plan, allResolutions, service, projectTargets, userInstallationKeys);
39764
+ const intents = await withSpinner(
39765
+ "\u6B63\u5728\u8BA1\u7B97\u53D7\u7BA1\u8D44\u6E90\u5E76\u751F\u6210\u6267\u884C\u8BA1\u5212...",
39766
+ () => buildIntentsFromPlan(planResult.plan, allResolutions, service, projectTargets, userInstallationKeys),
39767
+ {
39768
+ enabled: spinnerEnabled,
39769
+ successText: (res) => `\u2714 \u6267\u884C\u8BA1\u5212\u5DF2\u5C31\u7EEA (\u5171 ${res.length} \u9879\u8D44\u6E90\u53D8\u66F4)`,
39770
+ failText: "\u2716 \u6267\u884C\u8BA1\u5212\u751F\u6210\u5931\u8D25"
39771
+ }
39772
+ );
39616
39773
  planResult = materializePlan(planResult.plan, intents);
39617
39774
  events.report("plan", "success", Date.now() - planStartedAt, { planDigest: planResult.plan.planDigest, details: { intentCount: intents.length } });
39618
39775
  if (planResult.conflicts.length > 0) {
@@ -39874,6 +40031,7 @@ var init_apply = __esm({
39874
40031
  init_shared_options();
39875
40032
  init_cli_output();
39876
40033
  init_service_locator();
40034
+ init_spinner();
39877
40035
  init_i18n();
39878
40036
  init_plan_execution();
39879
40037
  }
@@ -42101,7 +42259,7 @@ import { createRequire as createRequire2 } from "node:module";
42101
42259
  import { readFileSync as readFileSync4 } from "node:fs";
42102
42260
  import { fileURLToPath as fileURLToPath5 } from "node:url";
42103
42261
  function resolveVersion() {
42104
- if (true) return "0.1.22";
42262
+ if (true) return "0.1.24";
42105
42263
  const candidates = [
42106
42264
  new URL("../package.json", import.meta.url),
42107
42265
  new URL("../../package.json", import.meta.url),
@@ -4,10 +4,16 @@
4
4
  "title": "Mano Coding Registry Entry",
5
5
  "type": "object",
6
6
  "additionalProperties": true,
7
- "required": ["metadata", "releases"],
7
+ "required": ["releases"],
8
8
  "properties": {
9
+ "apiVersion": { "type": "string" },
9
10
  "kind": { "type": "string" },
11
+ "id": { "$ref": "#/$defs/packageName" },
12
+ "name": { "type": "string", "minLength": 1, "maxLength": 80 },
13
+ "displayName": { "type": "string", "minLength": 1, "maxLength": 80 },
14
+ "description": { "type": "string", "maxLength": 500 },
10
15
  "metadata": { "$ref": "#/$defs/metadata" },
16
+ "channels": { "type": "object" },
11
17
  "releases": {
12
18
  "type": "array",
13
19
  "minItems": 1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mano-coding",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Mano Coding CLI and toolchain",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -4,10 +4,16 @@
4
4
  "title": "Mano Coding Registry Entry",
5
5
  "type": "object",
6
6
  "additionalProperties": true,
7
- "required": ["metadata", "releases"],
7
+ "required": ["releases"],
8
8
  "properties": {
9
+ "apiVersion": { "type": "string" },
9
10
  "kind": { "type": "string" },
11
+ "id": { "$ref": "#/$defs/packageName" },
12
+ "name": { "type": "string", "minLength": 1, "maxLength": 80 },
13
+ "displayName": { "type": "string", "minLength": 1, "maxLength": 80 },
14
+ "description": { "type": "string", "maxLength": 500 },
10
15
  "metadata": { "$ref": "#/$defs/metadata" },
16
+ "channels": { "type": "object" },
11
17
  "releases": {
12
18
  "type": "array",
13
19
  "minItems": 1,