mano-coding 0.1.19 → 0.1.21

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
@@ -31879,6 +31879,8 @@ var init_execute = __esm({
31879
31879
 
31880
31880
  // packages/core/src/execute/task-runner.ts
31881
31881
  import { spawn } from "node:child_process";
31882
+ import { existsSync as existsSync4 } from "node:fs";
31883
+ import { delimiter, join as join11 } from "node:path";
31882
31884
  function filterTasksByHook(items, hook) {
31883
31885
  return items.filter((item) => {
31884
31886
  const task = "task" in item ? item.task : item;
@@ -31980,6 +31982,33 @@ function generateTaskSummary(tasks, ctx) {
31980
31982
  return `[${idx + 1}/${tasks.length}] ${task.id}: ${fullCmd}`;
31981
31983
  });
31982
31984
  }
31985
+ function resolveTaskExecutable(command, platform = process.platform, envPath) {
31986
+ if (platform !== "win32") {
31987
+ return command;
31988
+ }
31989
+ if (/\.(exe|cmd|bat|com)$/i.test(command)) {
31990
+ return command;
31991
+ }
31992
+ const knownCmds = /* @__PURE__ */ new Set(["npx", "npm", "pnpm", "yarn", "corepack", "bun", "deno"]);
31993
+ if (knownCmds.has(command.toLowerCase())) {
31994
+ return `${command}.cmd`;
31995
+ }
31996
+ const pathValue = envPath ?? process.env.PATH ?? "";
31997
+ const pathext = (process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").map((ext) => ext.toLowerCase());
31998
+ const dirs = pathValue.split(delimiter).filter(Boolean);
31999
+ for (const dir of dirs) {
32000
+ for (const ext of pathext) {
32001
+ const target = join11(dir, `${command}${ext}`);
32002
+ try {
32003
+ if (existsSync4(target)) {
32004
+ return `${command}${ext}`;
32005
+ }
32006
+ } catch {
32007
+ }
32008
+ }
32009
+ }
32010
+ return command;
32011
+ }
31983
32012
  async function executeTasks(tasks, ctx, options = {}) {
31984
32013
  if (tasks.length === 0) return;
31985
32014
  const stdio = options.stdio ?? "inherit";
@@ -31997,8 +32026,9 @@ async function executeTasks(tasks, ctx, options = {}) {
31997
32026
  if (options.onProgress) {
31998
32027
  options.onProgress(`\u6B63\u5728\u6267\u884C\u4EFB\u52A1 [${i + 1}/${tasks.length}] (${task.id}): ${command} ${args.join(" ")}`);
31999
32028
  }
32029
+ const executable = resolveTaskExecutable(command, process.platform, env.PATH);
32000
32030
  await new Promise((resolve22, reject) => {
32001
- const child = spawn(command, args, {
32031
+ const child = spawn(executable, args, {
32002
32032
  cwd,
32003
32033
  env,
32004
32034
  stdio,
@@ -32050,7 +32080,7 @@ var init_task_runner = __esm({
32050
32080
 
32051
32081
  // packages/core/src/execute/template-contract.ts
32052
32082
  import { readFile as readFile17, readdir as readdir4 } from "node:fs/promises";
32053
- import { join as join11, relative as relative4 } from "node:path";
32083
+ import { join as join12, relative as relative4 } from "node:path";
32054
32084
  function validateMcpConfig(rawConfig) {
32055
32085
  if (typeof rawConfig !== "object" || rawConfig === null) {
32056
32086
  throw new TemplateContractError("mcp/mcp.json \u5FC5\u987B\u662F JSON \u5BF9\u8C61", "MCP_CONFIG_INVALID");
@@ -32083,10 +32113,89 @@ function validateMcpConfig(rawConfig) {
32083
32113
  }
32084
32114
  return validatedServers;
32085
32115
  }
32116
+ function getTargetSkillPath(target, skillId, relFile) {
32117
+ const normalizedRel = relFile.replaceAll("\\", "/");
32118
+ switch (target) {
32119
+ case "cursor":
32120
+ return `.cursor/skills/${skillId}/${normalizedRel}`;
32121
+ case "codebuddy":
32122
+ return `.codebuddy/skills/${skillId}/${normalizedRel}`;
32123
+ case "claude-code":
32124
+ return `.claude/skills/${skillId}/${normalizedRel}`;
32125
+ case "trae":
32126
+ return `.trae/skills/${skillId}/${normalizedRel}`;
32127
+ case "opencode":
32128
+ return `.opencode/skills/${skillId}/${normalizedRel}`;
32129
+ case "codex":
32130
+ return `.agents/skills/${skillId}/${normalizedRel}`;
32131
+ case "deepseek-harness":
32132
+ return `.dsh/skills/${skillId}/${normalizedRel}`;
32133
+ default:
32134
+ return `.${target}/skills/${skillId}/${normalizedRel}`;
32135
+ }
32136
+ }
32137
+ function getTargetRulePath(target, relFile) {
32138
+ const normalizedRel = relFile.replaceAll("\\", "/");
32139
+ switch (target) {
32140
+ case "cursor":
32141
+ return `.cursor/rules/${normalizedRel}`;
32142
+ case "claude-code":
32143
+ return `.claude/rules/${normalizedRel}`;
32144
+ case "trae":
32145
+ return `.trae/rules/${normalizedRel}`;
32146
+ case "codebuddy":
32147
+ return `.codebuddy/rules/${normalizedRel}`;
32148
+ case "opencode":
32149
+ return `.opencode/rules/${normalizedRel}`;
32150
+ case "deepseek-harness":
32151
+ return `.dsh/rules/${normalizedRel}`;
32152
+ default:
32153
+ return `.${target}/rules/${normalizedRel}`;
32154
+ }
32155
+ }
32156
+ function getTargetSubagentPath(target, relFile) {
32157
+ const normalizedRel = relFile.replaceAll("\\", "/");
32158
+ switch (target) {
32159
+ case "cursor":
32160
+ return `.cursor/agents/${normalizedRel}`;
32161
+ case "claude-code":
32162
+ return `.claude/agents/${normalizedRel}`;
32163
+ case "codex":
32164
+ return `.codex/agents/${normalizedRel}`;
32165
+ case "opencode":
32166
+ return `.opencode/agents/${normalizedRel}`;
32167
+ case "codebuddy":
32168
+ return `.codebuddy/agents/${normalizedRel}`;
32169
+ case "trae":
32170
+ return `.trae/agents/${normalizedRel}`;
32171
+ case "deepseek-harness":
32172
+ return `.dsh/agents/${normalizedRel}`;
32173
+ default:
32174
+ return `.${target}/agents/${normalizedRel}`;
32175
+ }
32176
+ }
32177
+ function getTargetMcpPath(target) {
32178
+ switch (target) {
32179
+ case "cursor":
32180
+ return ".cursor/mcp.json";
32181
+ case "trae":
32182
+ return ".trae/mcp.json";
32183
+ case "codebuddy":
32184
+ return ".codebuddy/mcp.json";
32185
+ case "claude-code":
32186
+ return ".claude/mcp.json";
32187
+ case "opencode":
32188
+ return ".opencode/mcp.json";
32189
+ case "deepseek-harness":
32190
+ return ".dsh/mcp.json";
32191
+ default:
32192
+ return `.${target}/mcp.json`;
32193
+ }
32194
+ }
32086
32195
  async function scanTemplateDirectoryContract(options) {
32087
32196
  const { templateDir, targets } = options;
32088
32197
  const intents = [];
32089
- const agentsPath = join11(templateDir, "AGENTS.md");
32198
+ const agentsPath = join12(templateDir, "AGENTS.md");
32090
32199
  try {
32091
32200
  const agentsContent = await readFile17(agentsPath);
32092
32201
  intents.push({
@@ -32097,70 +32206,46 @@ async function scanTemplateDirectoryContract(options) {
32097
32206
  });
32098
32207
  } catch {
32099
32208
  }
32100
- const skillsDir = join11(templateDir, "skills");
32209
+ const skillsDir = join12(templateDir, "skills");
32101
32210
  try {
32102
32211
  const skillEntries = await readdir4(skillsDir, { withFileTypes: true });
32103
32212
  for (const skillEntry of skillEntries) {
32104
32213
  if (!skillEntry.isDirectory()) continue;
32105
32214
  const skillId = skillEntry.name;
32106
- const singleSkillDir = join11(skillsDir, skillId);
32215
+ const singleSkillDir = join12(skillsDir, skillId);
32107
32216
  const allSkillFiles = await listAllFilesRecursive(singleSkillDir);
32108
32217
  for (const relFile of allSkillFiles) {
32109
- const fileContent = await readFile17(join11(singleSkillDir, relFile));
32110
- intents.push({
32111
- action: "upsert",
32112
- type: "file",
32113
- path: `.agents/skills/${skillId}/${relFile.replaceAll("\\", "/")}`,
32114
- content: fileContent
32115
- });
32218
+ const fileContent = await readFile17(join12(singleSkillDir, relFile));
32219
+ const normalizedRel = relFile.replaceAll("\\", "/");
32116
32220
  for (const target of targets) {
32117
- if (target === "cursor") {
32118
- intents.push({
32119
- action: "upsert",
32120
- type: "file",
32121
- path: `.cursor/skills/${skillId}/${relFile.replaceAll("\\", "/")}`,
32122
- content: fileContent
32123
- });
32124
- }
32221
+ intents.push({
32222
+ action: "upsert",
32223
+ type: "file",
32224
+ path: getTargetSkillPath(target, skillId, normalizedRel),
32225
+ content: fileContent,
32226
+ target
32227
+ });
32125
32228
  }
32126
32229
  }
32127
32230
  }
32128
32231
  } catch {
32129
32232
  }
32130
- const rulesDir = join11(templateDir, "rules");
32233
+ const rulesDir = join12(templateDir, "rules");
32131
32234
  try {
32132
32235
  const ruleIdeEntries = await readdir4(rulesDir, { withFileTypes: true });
32133
32236
  for (const ideEntry of ruleIdeEntries) {
32134
32237
  if (!ideEntry.isDirectory()) continue;
32135
32238
  const ide = ideEntry.name;
32136
32239
  if (!targets.includes(ide)) continue;
32137
- const singleRuleDir = join11(rulesDir, ide);
32240
+ const singleRuleDir = join12(rulesDir, ide);
32138
32241
  const allRuleFiles = await listAllFilesRecursive(singleRuleDir);
32139
32242
  for (const relFile of allRuleFiles) {
32140
- const fileContent = await readFile17(join11(singleRuleDir, relFile));
32243
+ const fileContent = await readFile17(join12(singleRuleDir, relFile));
32141
32244
  const normalizedRel = relFile.replaceAll("\\", "/");
32142
- let targetDestPath;
32143
- switch (ide) {
32144
- case "cursor":
32145
- targetDestPath = `.cursor/rules/${normalizedRel}`;
32146
- break;
32147
- case "claude-code":
32148
- targetDestPath = `.claude/rules/${normalizedRel}`;
32149
- break;
32150
- case "trae":
32151
- targetDestPath = `.trae/rules/${normalizedRel}`;
32152
- break;
32153
- case "codebuddy":
32154
- targetDestPath = `.codebuddy/rules/${normalizedRel}`;
32155
- break;
32156
- default:
32157
- targetDestPath = `.${ide}/rules/${normalizedRel}`;
32158
- break;
32159
- }
32160
32245
  intents.push({
32161
32246
  action: "upsert",
32162
32247
  type: "file",
32163
- path: targetDestPath,
32248
+ path: getTargetRulePath(ide, normalizedRel),
32164
32249
  content: fileContent,
32165
32250
  target: ide
32166
32251
  });
@@ -32168,31 +32253,39 @@ async function scanTemplateDirectoryContract(options) {
32168
32253
  }
32169
32254
  } catch {
32170
32255
  }
32171
- const mcpPath = join11(templateDir, "mcp", "mcp.json");
32256
+ const subagentsDir = join12(templateDir, "subagents");
32257
+ try {
32258
+ const agentIdeEntries = await readdir4(subagentsDir, { withFileTypes: true });
32259
+ for (const ideEntry of agentIdeEntries) {
32260
+ if (!ideEntry.isDirectory()) continue;
32261
+ const ide = ideEntry.name;
32262
+ if (!targets.includes(ide)) continue;
32263
+ const singleAgentDir = join12(subagentsDir, ide);
32264
+ const allAgentFiles = await listAllFilesRecursive(singleAgentDir);
32265
+ for (const relFile of allAgentFiles) {
32266
+ const fileContent = await readFile17(join12(singleAgentDir, relFile));
32267
+ const normalizedRel = relFile.replaceAll("\\", "/");
32268
+ intents.push({
32269
+ action: "upsert",
32270
+ type: "file",
32271
+ path: getTargetSubagentPath(ide, normalizedRel),
32272
+ content: fileContent,
32273
+ target: ide
32274
+ });
32275
+ }
32276
+ }
32277
+ } catch {
32278
+ }
32279
+ const mcpPath = join12(templateDir, "mcp", "mcp.json");
32172
32280
  try {
32173
32281
  const mcpRaw = await readFile17(mcpPath, "utf-8");
32174
32282
  const mcpServers = validateMcpConfig(JSON.parse(mcpRaw));
32175
32283
  for (const [serverName, serverConfig] of Object.entries(mcpServers)) {
32176
32284
  for (const target of targets) {
32177
- let mcpConfigPath;
32178
- switch (target) {
32179
- case "cursor":
32180
- mcpConfigPath = ".cursor/mcp.json";
32181
- break;
32182
- case "trae":
32183
- mcpConfigPath = ".trae/mcp.json";
32184
- break;
32185
- case "codebuddy":
32186
- mcpConfigPath = ".codebuddy/mcp.json";
32187
- break;
32188
- default:
32189
- mcpConfigPath = `.${target}/mcp.json`;
32190
- break;
32191
- }
32192
32285
  intents.push({
32193
32286
  action: "upsert",
32194
32287
  type: "config-entry",
32195
- path: mcpConfigPath,
32288
+ path: getTargetMcpPath(target),
32196
32289
  selector: `/mcpServers/${serverName}`,
32197
32290
  value: serverConfig,
32198
32291
  format: "json",
@@ -32212,7 +32305,7 @@ async function listAllFilesRecursive(dir, baseDir = dir) {
32212
32305
  try {
32213
32306
  const entries = await readdir4(dir, { withFileTypes: true });
32214
32307
  for (const entry of entries) {
32215
- const full = join11(dir, entry.name);
32308
+ const full = join12(dir, entry.name);
32216
32309
  if (entry.isDirectory()) {
32217
32310
  const subFiles = await listAllFilesRecursive(full, baseDir);
32218
32311
  files.push(...subFiles);
@@ -32240,7 +32333,7 @@ var init_template_contract = __esm({
32240
32333
 
32241
32334
  // packages/core/src/plugin/plugin-delivery.ts
32242
32335
  import { readFile as readFile18, stat as stat4, readdir as readdir5 } from "node:fs/promises";
32243
- import { join as join12, resolve as resolve8 } from "node:path";
32336
+ import { join as join13, resolve as resolve8 } from "node:path";
32244
32337
  import { createHash as createHash8 } from "node:crypto";
32245
32338
  function isPluginTargetSupported(target) {
32246
32339
  return target in PLUGIN_SUPPORT_MATRIX;
@@ -32294,7 +32387,7 @@ async function validatePlugin(request) {
32294
32387
  return diagnostics;
32295
32388
  }
32296
32389
  const entryFile = getPluginEntryFile(plugin.target);
32297
- const entryPath = join12(pluginPath, entryFile);
32390
+ const entryPath = join13(pluginPath, entryFile);
32298
32391
  try {
32299
32392
  await stat4(entryPath);
32300
32393
  } catch {
@@ -32555,7 +32648,7 @@ function getHostVersionCommand(target) {
32555
32648
  }
32556
32649
  async function readNativePluginMeta(pluginDir, target) {
32557
32650
  const entryFile = getPluginEntryFile(target);
32558
- const entryPath = join12(pluginDir, entryFile);
32651
+ const entryPath = join13(pluginDir, entryFile);
32559
32652
  try {
32560
32653
  const raw = await readFile18(entryPath, "utf-8");
32561
32654
  const parsed = JSON.parse(raw);
@@ -32599,7 +32692,7 @@ async function collectDirectoryCopyIntents(sourceDir, sourceRelPath, destDir, pa
32599
32692
  const intents = [];
32600
32693
  const entries = await readdir5(sourceDir, { withFileTypes: true });
32601
32694
  for (const entry of entries) {
32602
- const entrySourcePath = join12(sourceDir, entry.name);
32695
+ const entrySourcePath = join13(sourceDir, entry.name);
32603
32696
  const entryDestPath = `${destDir}/${entry.name}`;
32604
32697
  if (!isPathInside(packageRoot, entrySourcePath)) {
32605
32698
  continue;
@@ -32607,7 +32700,7 @@ async function collectDirectoryCopyIntents(sourceDir, sourceRelPath, destDir, pa
32607
32700
  if (entry.isDirectory()) {
32608
32701
  const subIntents = await collectDirectoryCopyIntents(
32609
32702
  entrySourcePath,
32610
- join12(sourceRelPath, entry.name),
32703
+ join13(sourceRelPath, entry.name),
32611
32704
  entryDestPath,
32612
32705
  packageRoot,
32613
32706
  metadata
@@ -32717,7 +32810,7 @@ var init_plugin = __esm({
32717
32810
  // packages/core/src/journal.ts
32718
32811
  import { createHash as createHash9, randomUUID as randomUUID3 } from "node:crypto";
32719
32812
  import { chmod as chmod2, cp, mkdir as mkdir11, open as open3, readdir as readdir6, readFile as readFile19, rename as rename5, rm as rm4, stat as stat5, writeFile as writeFile7 } from "node:fs/promises";
32720
- import { dirname as dirname11, join as join13, resolve as resolve9 } from "node:path";
32813
+ import { dirname as dirname11, join as join14, resolve as resolve9 } from "node:path";
32721
32814
  function projectHash(projectRoot) {
32722
32815
  return createHash9("sha256").update(resolve9(projectRoot)).digest("hex").slice(0, 32);
32723
32816
  }
@@ -32728,15 +32821,15 @@ function isUuid(value) {
32728
32821
  return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
32729
32822
  }
32730
32823
  function transactionPathOf(userDataDir, projectRoot, operationId) {
32731
- return join13(resolve9(userDataDir), "transactions", projectHash(projectRoot), operationId);
32824
+ return join14(resolve9(userDataDir), "transactions", projectHash(projectRoot), operationId);
32732
32825
  }
32733
32826
  function pathsFor(userDataDir, projectRoot, operationId) {
32734
32827
  const directory = transactionPathOf(userDataDir, projectRoot, operationId);
32735
32828
  return {
32736
- journalPath: join13(directory, "journal.json"),
32829
+ journalPath: join14(directory, "journal.json"),
32737
32830
  transactionPath: directory,
32738
- backupPath: join13(directory, "backup"),
32739
- recoveryPath: join13(directory, "recovery.json")
32831
+ backupPath: join14(directory, "backup"),
32832
+ recoveryPath: join14(directory, "recovery.json")
32740
32833
  };
32741
32834
  }
32742
32835
  function documentOf(journal) {
@@ -32861,7 +32954,7 @@ async function updateJournal(journal, state) {
32861
32954
  return updated;
32862
32955
  }
32863
32956
  async function scanJournals(userDataDir, projectRoot) {
32864
- const directory = join13(resolve9(userDataDir), "transactions", projectHash(projectRoot));
32957
+ const directory = join14(resolve9(userDataDir), "transactions", projectHash(projectRoot));
32865
32958
  let entries;
32866
32959
  try {
32867
32960
  entries = await readdir6(directory, { withFileTypes: true });
@@ -32872,7 +32965,7 @@ async function scanJournals(userDataDir, projectRoot) {
32872
32965
  const journals = [];
32873
32966
  for (const entry of entries) {
32874
32967
  if (!entry.isDirectory() || !isUuid(entry.name)) continue;
32875
- const path2 = join13(directory, entry.name, "journal.json");
32968
+ const path2 = join14(directory, entry.name, "journal.json");
32876
32969
  try {
32877
32970
  journals.push(await readJournal(path2, userDataDir, projectRoot));
32878
32971
  } catch (error) {
@@ -32910,12 +33003,12 @@ async function prepareRecoverySnapshots(journal, scope, root, paths) {
32910
33003
  try {
32911
33004
  const info = await stat5(absolutePath);
32912
33005
  if (info.isDirectory()) {
32913
- await cp(absolutePath, join13(journal.backupPath, backupName), { recursive: true, force: false });
33006
+ await cp(absolutePath, join14(journal.backupPath, backupName), { recursive: true, force: false });
32914
33007
  snapshots.push({ scope, path: path2, existed: true, backup: backupName, kind: "directory", mode: info.mode & 4095 });
32915
33008
  continue;
32916
33009
  }
32917
33010
  if (!info.isFile()) throw new JournalError(`Recovery \u76EE\u6807\u4E0D\u662F\u6587\u4EF6\u6216\u76EE\u5F55: ${path2}`, "JOURNAL_INVALID");
32918
- await writeFile7(join13(journal.backupPath, backupName), await readFile19(absolutePath));
33011
+ await writeFile7(join14(journal.backupPath, backupName), await readFile19(absolutePath));
32919
33012
  snapshots.push({ scope, path: path2, existed: true, backup: backupName, mode: info.mode & 4095, kind: "file" });
32920
33013
  } catch (error) {
32921
33014
  if (error.code === "ENOENT") {
@@ -32941,12 +33034,12 @@ async function restoreRecovery(journal, projectRoot, recovery) {
32941
33034
  }
32942
33035
  if (snapshot2.kind === "directory") {
32943
33036
  await rm4(absolutePath, { recursive: true, force: true });
32944
- await cp(join13(journal.backupPath, snapshot2.backup), absolutePath, { recursive: true, force: false });
33037
+ await cp(join14(journal.backupPath, snapshot2.backup), absolutePath, { recursive: true, force: false });
32945
33038
  if (snapshot2.mode !== void 0 && process.platform !== "win32") await chmod2(absolutePath, snapshot2.mode);
32946
33039
  continue;
32947
33040
  }
32948
33041
  await mkdir11(dirname11(absolutePath), { recursive: true });
32949
- await writeFile7(absolutePath, await readFile19(join13(journal.backupPath, snapshot2.backup)));
33042
+ await writeFile7(absolutePath, await readFile19(join14(journal.backupPath, snapshot2.backup)));
32950
33043
  if (snapshot2.mode !== void 0 && process.platform !== "win32") await chmod2(absolutePath, snapshot2.mode);
32951
33044
  }
32952
33045
  }
@@ -33495,6 +33588,10 @@ __export(src_exports, {
33495
33588
  getOfficialTargets: () => getOfficialTargets,
33496
33589
  getPlanIntents: () => getPlanIntents,
33497
33590
  getPluginDeliveryDriver: () => getPluginDeliveryDriver,
33591
+ getTargetMcpPath: () => getTargetMcpPath,
33592
+ getTargetRulePath: () => getTargetRulePath,
33593
+ getTargetSkillPath: () => getTargetSkillPath,
33594
+ getTargetSubagentPath: () => getTargetSubagentPath,
33498
33595
  getUserInstallCommands: () => getUserInstallCommands,
33499
33596
  getUserInstallEnvChanges: () => getUserInstallEnvChanges,
33500
33597
  hasActiveLease: () => hasActiveLease,
@@ -33551,6 +33648,7 @@ __export(src_exports, {
33551
33648
  resolveAdapter: () => resolveAdapter,
33552
33649
  resolveCanonicalSchemaPath: () => resolveCanonicalSchemaPath3,
33553
33650
  resolveLauncher: () => resolveLauncher,
33651
+ resolveTaskExecutable: () => resolveTaskExecutable,
33554
33652
  sanitizeCommand: () => sanitizeCommand,
33555
33653
  sanitizeEnvValue: () => sanitizeEnvValue,
33556
33654
  sanitizeUrl: () => sanitizeUrl,
@@ -36697,7 +36795,7 @@ var init_shared_options = __esm({
36697
36795
  // packages/cli/src/commands/extension-dev.ts
36698
36796
  import { mkdtemp as mkdtemp4, readFile as readFile21 } from "node:fs/promises";
36699
36797
  import { tmpdir as tmpdir4 } from "node:os";
36700
- import { join as join14, resolve as resolvePath9, relative as relative5, isAbsolute as isAbsolute5, sep as sep3 } from "node:path";
36798
+ import { join as join15, resolve as resolvePath9, relative as relative5, isAbsolute as isAbsolute5, sep as sep3 } from "node:path";
36701
36799
  function createExtensionDevCommand() {
36702
36800
  const cmd = new Command("dev");
36703
36801
  cmd.description(t("extension.dev.description")).argument("[package-directory]", t("extension.dev.argPackageDirectory"), ".").requiredOption("--project <fixture-directory>", t("extension.dev.optionProject")).option("--operation <create|apply|sync|remove>", t("extension.dev.optionOperation"), "apply").option("--target <id>", t("mutation.target"), collectString2, []).option("--set <name=value>", t("mutation.set"), collectString2, []).option("--dry-run", t("mutation.dryRun")).option("--yes", t("mutation.yes")).option("--allow <permission>", t("mutation.allow"), collectString2, []).option("--watch", t("extension.dev.optionWatch")).action(async (packageDirectory, opts) => {
@@ -36751,7 +36849,7 @@ async function executeExtensionDev(packageDirectory, options) {
36751
36849
  return ExitCode.SchemaInvalid;
36752
36850
  }
36753
36851
  const effectiveDryRun = options.dryRun || options.watch;
36754
- const isolatedUserData = await mkdtemp4(join14(tmpdir4(), "aicoding-dev-userdata-"));
36852
+ const isolatedUserData = await mkdtemp4(join15(tmpdir4(), "aicoding-dev-userdata-"));
36755
36853
  const prevUserData = process.env["AICODING_USER_DATA"];
36756
36854
  process.env["AICODING_USER_DATA"] = isolatedUserData;
36757
36855
  try {
@@ -36992,7 +37090,7 @@ var init_extension_test = __esm({
36992
37090
 
36993
37091
  // packages/cli/src/commands/extension-pack.ts
36994
37092
  import { readFile as readFile23, mkdir as mkdir14 } from "node:fs/promises";
36995
- import { resolve as resolve13, join as join15, dirname as dirname13 } from "node:path";
37093
+ import { resolve as resolve13, join as join16, dirname as dirname13 } from "node:path";
36996
37094
  import { execFile as execFile5 } from "node:child_process";
36997
37095
  import { promisify as promisify5 } from "node:util";
36998
37096
  import { createHash as createHash10 } from "node:crypto";
@@ -37145,7 +37243,7 @@ async function executeExtensionPack(packageDirectory, options, cliVersion) {
37145
37243
  let tarballName;
37146
37244
  let tarballPath;
37147
37245
  tarballName = `${pkgName.replace(/^@/, "").replace(/\//g, "-")}-${pkgVersion}.tgz`;
37148
- tarballPath = join15(outputDir, tarballName);
37246
+ tarballPath = join16(outputDir, tarballName);
37149
37247
  try {
37150
37248
  await packWithNpm(pkgDir, outputDir);
37151
37249
  } catch (err) {
@@ -37912,7 +38010,7 @@ var init_journal_helper = __esm({
37912
38010
 
37913
38011
  // packages/cli/src/commands/service-locator.ts
37914
38012
  import { homedir as homedir2 } from "node:os";
37915
- import { join as join16, resolve as resolve16 } from "node:path";
38013
+ import { join as join17, resolve as resolve16 } from "node:path";
37916
38014
  var ServiceLocator;
37917
38015
  var init_service_locator = __esm({
37918
38016
  "packages/cli/src/commands/service-locator.ts"() {
@@ -37946,13 +38044,13 @@ var init_service_locator = __esm({
37946
38044
  return `mano-coding@${this.config.cliVersion}`;
37947
38045
  }
37948
38046
  getUserDataDir() {
37949
- return this.config.userDataDir ?? process.env["MANO_USER_DATA"] ?? process.env["AICODING_USER_DATA"] ?? join16(homedir2(), ".mano-coding");
38047
+ return this.config.userDataDir ?? process.env["MANO_USER_DATA"] ?? process.env["AICODING_USER_DATA"] ?? join17(homedir2(), ".mano-coding");
37950
38048
  }
37951
38049
  getRegistryUrl() {
37952
38050
  return this.config.registryUrl || process.env["MANO_REGISTRY"] || process.env["AICODING_REGISTRY"] || DEFAULT_PUBLIC_REGISTRY_URL;
37953
38051
  }
37954
38052
  getCacheRoot() {
37955
- return this.config.cacheRoot ?? join16(this.getUserDataDir(), "cache");
38053
+ return this.config.cacheRoot ?? join17(this.getUserDataDir(), "cache");
37956
38054
  }
37957
38055
  getRegistryClient() {
37958
38056
  if (!this._registryClient) {
@@ -38132,7 +38230,7 @@ var init_service_locator = __esm({
38132
38230
 
38133
38231
  // packages/cli/src/commands/plan-execution.ts
38134
38232
  import { mkdir as mkdir16, readFile as readFile26, readdir as readdir8, stat as stat6 } from "node:fs/promises";
38135
- import { join as join17, relative as relative6, resolve as resolve17 } from "node:path";
38233
+ import { join as join18, relative as relative6, resolve as resolve17 } from "node:path";
38136
38234
  import { createHash as createHash12 } from "node:crypto";
38137
38235
  async function buildIntentsFromPlan(_plan, resolutions, service, projectTargets, userInstallationKeys) {
38138
38236
  const adapterRegistry = service.getAdapterRegistry();
@@ -38434,7 +38532,7 @@ async function collectAssetIntents(packageRoot, source, destination, metadata) {
38434
38532
  if (!sourceStat.isDirectory()) throw new Error(`Asset '${source}' \u65E2\u4E0D\u662F\u6587\u4EF6\u4E5F\u4E0D\u662F\u76EE\u5F55`);
38435
38533
  const intents = [];
38436
38534
  for (const entry of await readdir8(sourcePath, { withFileTypes: true })) {
38437
- intents.push(...await collectAssetIntents(packageRoot, join17(source, entry.name), join17(destination, entry.name).replaceAll("\\", "/"), metadata));
38535
+ intents.push(...await collectAssetIntents(packageRoot, join18(source, entry.name), join18(destination, entry.name).replaceAll("\\", "/"), metadata));
38438
38536
  }
38439
38537
  return intents;
38440
38538
  }
@@ -38577,13 +38675,13 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
38577
38675
  id: templateResolution.packageId,
38578
38676
  version: templateResolution.resolvedVersion,
38579
38677
  source: templateResolution.source,
38580
- integrity: templateResolution.integrity ?? ""
38678
+ ...templateResolution.integrity ? { integrity: templateResolution.integrity } : {}
38581
38679
  } : void 0;
38582
38680
  const resolvedAddons = addonResolutions.map((r) => ({
38583
38681
  id: r.packageId,
38584
38682
  version: r.resolvedVersion,
38585
38683
  source: r.source,
38586
- integrity: r.integrity ?? ""
38684
+ ...r.integrity ? { integrity: r.integrity } : {}
38587
38685
  }));
38588
38686
  const allResolutions = [...templateResolution ? [templateResolution] : [], ...addonResolutions];
38589
38687
  const activeTargetIds = new Set(projectTargets.map((target) => target.id));
@@ -38598,7 +38696,7 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
38598
38696
  id: r.packageId,
38599
38697
  version: r.resolvedVersion,
38600
38698
  source: r.source,
38601
- integrity: r.integrity ?? ""
38699
+ ...r.integrity ? { integrity: r.integrity } : {}
38602
38700
  }));
38603
38701
  for (const intent of intents) {
38604
38702
  if (intent.action === "remove") continue;
@@ -41237,7 +41335,7 @@ var init_upgrade = __esm({
41237
41335
 
41238
41336
  // packages/cli/src/commands/cache.ts
41239
41337
  import { homedir as homedir3 } from "node:os";
41240
- import { join as join18, resolve as resolve20 } from "node:path";
41338
+ import { join as join19, resolve as resolve20 } from "node:path";
41241
41339
  import { rm as rm5, stat as stat7 } from "node:fs/promises";
41242
41340
  function createCacheCommand(cliVersion) {
41243
41341
  const cmd = new Command("cache");
@@ -41279,7 +41377,7 @@ function createCacheCommand(cliVersion) {
41279
41377
  return cmd;
41280
41378
  }
41281
41379
  function getUserDataDir() {
41282
- return process.env["AICODING_USER_DATA"] ?? join18(homedir3(), ".aicoding");
41380
+ return process.env["AICODING_USER_DATA"] ?? join19(homedir3(), ".aicoding");
41283
41381
  }
41284
41382
  function parsePositiveInt(value, name) {
41285
41383
  if (value === void 0) return void 0;
@@ -41481,7 +41579,7 @@ async function executeClean(opts, cliVersion) {
41481
41579
  throw new CliError(t("cache.cleanRequiresYes"), ExitCode.NeedsInputOrDenied, "NEEDS_CONFIRMATION");
41482
41580
  }
41483
41581
  if (cleanRegistry && !dryRun) await updateCache.clear();
41484
- if (cleanAudit && !dryRun) await rm5(join18(userDataDir, "audit"), { recursive: true, force: true });
41582
+ if (cleanAudit && !dryRun) await rm5(join19(userDataDir, "audit"), { recursive: true, force: true });
41485
41583
  if (json) {
41486
41584
  emitSuccessJson("cache clean", { dryRun, cleanedLeases: 0, clearedUpdateCache: cleanRegistry, clearedAudit: cleanAudit, message: t("cache.noInstallationsClean") });
41487
41585
  } else {
@@ -41496,7 +41594,7 @@ async function executeClean(opts, cliVersion) {
41496
41594
  throw new CliError(t("cache.cleanRequiresYes"), ExitCode.NeedsInputOrDenied, "NEEDS_CONFIRMATION");
41497
41595
  }
41498
41596
  if (cleanRegistry && !dryRun) await updateCache.clear();
41499
- if (cleanAudit && !dryRun) await rm5(join18(userDataDir, "audit"), { recursive: true, force: true });
41597
+ if (cleanAudit && !dryRun) await rm5(join19(userDataDir, "audit"), { recursive: true, force: true });
41500
41598
  if (json) {
41501
41599
  emitSuccessJson("cache clean", { dryRun, cleanedLeases: 0, clearedUpdateCache: cleanRegistry, clearedAudit: cleanAudit, message: t("cache.noInstallationsClean") });
41502
41600
  } else {
@@ -41541,7 +41639,7 @@ async function executeClean(opts, cliVersion) {
41541
41639
  totalCleaned += cleaned;
41542
41640
  }
41543
41641
  if (cleanRegistry) await updateCache.clear();
41544
- if (cleanAudit) await rm5(join18(userDataDir, "audit"), { recursive: true, force: true });
41642
+ if (cleanAudit) await rm5(join19(userDataDir, "audit"), { recursive: true, force: true });
41545
41643
  if (json) {
41546
41644
  emitSuccessJson("cache clean", { dryRun: false, cleanedLeases: totalCleaned, clearedUpdateCache: cleanRegistry, clearedAudit: cleanAudit });
41547
41645
  } else {
@@ -41563,7 +41661,7 @@ var init_cache = __esm({
41563
41661
  // packages/cli/src/commands/launch.ts
41564
41662
  import { spawn as spawn2 } from "node:child_process";
41565
41663
  import { homedir as homedir4 } from "node:os";
41566
- import { join as join19 } from "node:path";
41664
+ import { join as join20 } from "node:path";
41567
41665
  function createLaunchCommand() {
41568
41666
  const cmd = new Command("_launch");
41569
41667
  cmd.description(t("launch.description")).option("--kind <kind>", t("launch.optionKind")).option("--package <package-id>", t("launch.optionPackage")).option("--id <id>", t("launch.optionId")).option("--version <version>", t("launch.optionVersion")).option("--command <name>", t("launch.optionCommand")).allowUnknownOption(true).allowExcessArguments(true).action(async (_opts, command) => {
@@ -41596,7 +41694,7 @@ function createLaunchCommand() {
41596
41694
  return cmd;
41597
41695
  }
41598
41696
  function getUserDataDir2() {
41599
- return process.env["AICODING_USER_DATA"] ?? join19(homedir4(), ".aicoding");
41697
+ return process.env["AICODING_USER_DATA"] ?? join20(homedir4(), ".aicoding");
41600
41698
  }
41601
41699
  async function executeLaunch(launcherArgs) {
41602
41700
  const userDataDir = getUserDataDir2();
@@ -41644,7 +41742,7 @@ var init_launch = __esm({
41644
41742
  import { spawn as spawn3 } from "node:child_process";
41645
41743
  import { readFile as readFile28, realpath as realpath2 } from "node:fs/promises";
41646
41744
  import { homedir as homedir5 } from "node:os";
41647
- import { extname, join as join20, resolve as resolve21 } from "node:path";
41745
+ import { extname, join as join21, resolve as resolve21 } from "node:path";
41648
41746
  import { createInterface as createInterface2 } from "node:readline/promises";
41649
41747
  import { stdin, stderr } from "node:process";
41650
41748
  function createSelfUpgradeCommand(cliVersion) {
@@ -41706,7 +41804,7 @@ async function executeSelfUpgrade(options, cliVersion) {
41706
41804
  });
41707
41805
  await auditLog.prune().catch(() => void 0);
41708
41806
  try {
41709
- const result = await withStateLock(join20(userDataDir, "cli-update"), async () => {
41807
+ const result = await withStateLock(join21(userDataDir, "cli-update"), async () => {
41710
41808
  const target = await resolveTarget(options, cacheRepository, registry);
41711
41809
  ensureTargetAllowed(target.version, installation.currentVersion, options.allowDowngrade);
41712
41810
  if (!isCliVersionCompatible(process.version, target.enginesNode)) {
@@ -41758,7 +41856,7 @@ function validateOptions(options) {
41758
41856
  }
41759
41857
  }
41760
41858
  function getUserDataDir3() {
41761
- return process.env["AICODING_USER_DATA"] ?? join20(homedir5(), ".aicoding");
41859
+ return process.env["AICODING_USER_DATA"] ?? join21(homedir5(), ".aicoding");
41762
41860
  }
41763
41861
  function getRegistryUrl() {
41764
41862
  const raw = process.env["AICODING_NPM_REGISTRY"] || DEFAULT_NPM_REGISTRY;
@@ -41877,7 +41975,7 @@ async function isWindowsCmdShimFor(shimPath, expectedBin) {
41877
41975
  }
41878
41976
  async function readPackageJson(root) {
41879
41977
  try {
41880
- const value = JSON.parse(await readFile28(join20(root, "package.json"), "utf8"));
41978
+ const value = JSON.parse(await readFile28(join21(root, "package.json"), "utf8"));
41881
41979
  if (!value || typeof value !== "object") return void 0;
41882
41980
  const item = value;
41883
41981
  return typeof item["name"] === "string" && typeof item["version"] === "string" ? { name: item["name"], version: item["version"], bin: item["bin"] } : void 0;
@@ -41942,11 +42040,11 @@ var init_self_upgrade = __esm({
41942
42040
 
41943
42041
  // packages/cli/src/commands/update-notice.ts
41944
42042
  import { homedir as homedir6 } from "node:os";
41945
- import { join as join21 } from "node:path";
42043
+ import { join as join22 } from "node:path";
41946
42044
  async function getCachedUpdateNotice(argv, currentVersion) {
41947
42045
  const json = argv.includes("--json");
41948
42046
  const disabled = argv.includes("--offline") || argv[2] === "self-upgrade" || Boolean(process.env["AICODING_NO_UPDATE_CHECK"]) || Boolean(process.env["CI"]);
41949
- const repository = new CliUpdateCacheRepository(process.env["AICODING_USER_DATA"] ?? join21(homedir6(), ".aicoding"));
42047
+ const repository = new CliUpdateCacheRepository(process.env["AICODING_USER_DATA"] ?? join22(homedir6(), ".aicoding"));
41950
42048
  if (disabled || !json && !process.stdout.isTTY) return { json, markNotified: async () => void 0 };
41951
42049
  const cache = await repository.read();
41952
42050
  const notifiedAt = cache?.lastNotifiedAt ? Date.parse(cache.lastNotifiedAt) : Number.NaN;
@@ -41978,7 +42076,7 @@ import { createRequire as createRequire2 } from "node:module";
41978
42076
  import { readFileSync as readFileSync4 } from "node:fs";
41979
42077
  import { fileURLToPath as fileURLToPath5 } from "node:url";
41980
42078
  function resolveVersion() {
41981
- if (true) return "0.1.19";
42079
+ if (true) return "0.1.21";
41982
42080
  const candidates = [
41983
42081
  new URL("../package.json", import.meta.url),
41984
42082
  new URL("../../package.json", import.meta.url),
@@ -18,8 +18,8 @@
18
18
  "$defs": {
19
19
  "packageName": {
20
20
  "type": "string",
21
- "pattern": "^(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*$",
22
- "maxLength": 214
21
+ "pattern": "^(?:(?:gitlab|github):[a-zA-Z0-9_.-]+(?:/[a-zA-Z0-9_.-]+)+|(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*)$",
22
+ "maxLength": 256
23
23
  },
24
24
  "localId": {
25
25
  "type": "string",
@@ -18,8 +18,8 @@
18
18
  "$defs": {
19
19
  "packageName": {
20
20
  "type": "string",
21
- "pattern": "^(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*$",
22
- "maxLength": 214
21
+ "pattern": "^(?:(?:gitlab|github):[a-zA-Z0-9_.-]+(?:/[a-zA-Z0-9_.-]+)+|(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*)$",
22
+ "maxLength": 256
23
23
  },
24
24
  "localId": {
25
25
  "type": "string",
@@ -221,7 +221,7 @@
221
221
  },
222
222
  "resolvedPackage": {
223
223
  "type": "object",
224
- "required": ["id", "version", "source", "integrity"],
224
+ "required": ["id", "version", "source"],
225
225
  "properties": {
226
226
  "id": { "$ref": "#/$defs/packageName" },
227
227
  "version": { "$ref": "#/$defs/semver" },
@@ -17,7 +17,7 @@
17
17
  "$defs": {
18
18
  "packageName": {
19
19
  "type": "string",
20
- "pattern": "^(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*$"
20
+ "pattern": "^(?:(?:gitlab|github):[a-zA-Z0-9_.-]+(?:/[a-zA-Z0-9_.-]+)+|(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*)$"
21
21
  },
22
22
  "semver": {
23
23
  "type": "string",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mano-coding",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "Mano Coding CLI and toolchain",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -18,8 +18,8 @@
18
18
  "$defs": {
19
19
  "packageName": {
20
20
  "type": "string",
21
- "pattern": "^(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*$",
22
- "maxLength": 214
21
+ "pattern": "^(?:(?:gitlab|github):[a-zA-Z0-9_.-]+(?:/[a-zA-Z0-9_.-]+)+|(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*)$",
22
+ "maxLength": 256
23
23
  },
24
24
  "localId": {
25
25
  "type": "string",
@@ -18,8 +18,8 @@
18
18
  "$defs": {
19
19
  "packageName": {
20
20
  "type": "string",
21
- "pattern": "^(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*$",
22
- "maxLength": 214
21
+ "pattern": "^(?:(?:gitlab|github):[a-zA-Z0-9_.-]+(?:/[a-zA-Z0-9_.-]+)+|(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*)$",
22
+ "maxLength": 256
23
23
  },
24
24
  "localId": {
25
25
  "type": "string",
@@ -221,7 +221,7 @@
221
221
  },
222
222
  "resolvedPackage": {
223
223
  "type": "object",
224
- "required": ["id", "version", "source", "integrity"],
224
+ "required": ["id", "version", "source"],
225
225
  "properties": {
226
226
  "id": { "$ref": "#/$defs/packageName" },
227
227
  "version": { "$ref": "#/$defs/semver" },
@@ -17,7 +17,7 @@
17
17
  "$defs": {
18
18
  "packageName": {
19
19
  "type": "string",
20
- "pattern": "^(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*$"
20
+ "pattern": "^(?:(?:gitlab|github):[a-zA-Z0-9_.-]+(?:/[a-zA-Z0-9_.-]+)+|(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*)$"
21
21
  },
22
22
  "semver": {
23
23
  "type": "string",