@cleocode/caamp 1.3.1 → 1.4.0

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/cli.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  detectProjectProviders,
17
17
  discoverSkill,
18
18
  discoverSkillsMulti,
19
+ extractVersionTag,
19
20
  formatNetworkError,
20
21
  formatSkillRecommendations,
21
22
  generateInjectionContent,
@@ -27,6 +28,7 @@ import {
27
28
  getRegistryVersion,
28
29
  getSkill,
29
30
  getSkillDir,
31
+ getTrackedMcpServers,
30
32
  getTrackedSkills,
31
33
  groupByInstructFile,
32
34
  injectAll,
@@ -71,7 +73,7 @@ import {
71
73
  tokenizeCriteriaValue,
72
74
  updateInstructionsSingleOperation,
73
75
  validateSkill
74
- } from "./chunk-DT22SZ7X.js";
76
+ } from "./chunk-QZOOTKAJ.js";
75
77
 
76
78
  // src/cli.ts
77
79
  import { Command } from "commander";
@@ -1830,7 +1832,8 @@ async function executeCleoInstall(mode, opts, operation) {
1830
1832
  profile.packageSpec ?? resolvedOpts.command ?? "cleo-dev",
1831
1833
  channel === "dev" ? "command" : "package",
1832
1834
  succeeded.map((result) => result.provider.id),
1833
- resolvedOpts.global ?? false
1835
+ resolvedOpts.global ?? false,
1836
+ resolvedOpts.version ?? extractVersionTag(profile.packageSpec)
1834
1837
  );
1835
1838
  }
1836
1839
  if (format === "human") {
@@ -1946,6 +1949,34 @@ async function executeCleoUninstall(opts, operation) {
1946
1949
  });
1947
1950
  }
1948
1951
  }
1952
+ function checkCleoEntryHealth(command, lockTracked) {
1953
+ if (!command) {
1954
+ return {
1955
+ commandReachable: true,
1956
+ commandDetail: "(no command)",
1957
+ configPresent: true,
1958
+ lockTracked,
1959
+ status: lockTracked ? "healthy" : "degraded"
1960
+ };
1961
+ }
1962
+ const reachability = checkCommandReachability(command);
1963
+ if (!reachability.reachable) {
1964
+ return {
1965
+ commandReachable: false,
1966
+ commandDetail: reachability.detail,
1967
+ configPresent: true,
1968
+ lockTracked,
1969
+ status: "broken"
1970
+ };
1971
+ }
1972
+ return {
1973
+ commandReachable: true,
1974
+ commandDetail: reachability.detail,
1975
+ configPresent: true,
1976
+ lockTracked,
1977
+ status: lockTracked ? "healthy" : "degraded"
1978
+ };
1979
+ }
1949
1980
  async function executeCleoShow(opts, operation) {
1950
1981
  const mvi = "standard";
1951
1982
  let format;
@@ -1971,41 +2002,123 @@ async function executeCleoShow(opts, operation) {
1971
2002
  process.exit(1);
1972
2003
  }
1973
2004
  const channelFilter = opts.channel ? normalizeCleoChannel(opts.channel) : null;
1974
- const scope = opts.global ? "global" : "project";
2005
+ const scopes = [];
2006
+ if (opts.global && !opts.project) {
2007
+ scopes.push("global");
2008
+ } else if (opts.project && !opts.global) {
2009
+ scopes.push("project");
2010
+ } else {
2011
+ scopes.push("project", "global");
2012
+ }
2013
+ const lockEntries = await getTrackedMcpServers();
1975
2014
  const entries = [];
1976
- for (const provider of providers) {
1977
- const providerEntries = await listMcpServers(provider, scope);
1978
- for (const entry of providerEntries) {
1979
- const channel = resolveChannelFromServerName(entry.name);
1980
- if (!channel) continue;
1981
- if (channelFilter && channel !== channelFilter) continue;
1982
- entries.push({
1983
- provider: provider.id,
1984
- serverName: entry.name,
1985
- channel,
1986
- command: typeof entry.config.command === "string" ? entry.config.command : void 0,
1987
- args: Array.isArray(entry.config.args) ? entry.config.args.filter((value) => typeof value === "string") : [],
1988
- env: typeof entry.config.env === "object" && entry.config.env !== null ? entry.config.env : {}
1989
- });
2015
+ const warnings = [];
2016
+ for (const scope of scopes) {
2017
+ for (const provider of providers) {
2018
+ const providerEntries = await listMcpServers(provider, scope);
2019
+ for (const entry of providerEntries) {
2020
+ const channel = resolveChannelFromServerName(entry.name);
2021
+ if (!channel) continue;
2022
+ if (channelFilter && channel !== channelFilter) continue;
2023
+ const command = typeof entry.config.command === "string" ? entry.config.command : void 0;
2024
+ const args = Array.isArray(entry.config.args) ? entry.config.args.filter((value) => typeof value === "string") : [];
2025
+ const env = typeof entry.config.env === "object" && entry.config.env !== null ? entry.config.env : {};
2026
+ const lockEntry = lockEntries[entry.name];
2027
+ const lockTracked = lockEntry !== void 0;
2028
+ const health = checkCleoEntryHealth(command, lockTracked);
2029
+ entries.push({
2030
+ provider: provider.id,
2031
+ providerName: provider.toolName,
2032
+ serverName: entry.name,
2033
+ channel,
2034
+ scope,
2035
+ command,
2036
+ args,
2037
+ env,
2038
+ version: lockEntry?.version ?? null,
2039
+ source: lockEntry?.source ?? null,
2040
+ sourceType: lockEntry?.sourceType ?? null,
2041
+ installedAt: lockEntry?.installedAt ?? null,
2042
+ updatedAt: lockEntry?.updatedAt ?? null,
2043
+ health
2044
+ });
2045
+ if (health.status === "broken") {
2046
+ warnings.push({
2047
+ code: "W_COMMAND_UNREACHABLE",
2048
+ message: `${entry.name} command not reachable on ${provider.toolName} (${health.commandDetail})`
2049
+ });
2050
+ } else if (health.status === "degraded") {
2051
+ warnings.push({
2052
+ code: "W_NOT_TRACKED",
2053
+ message: `${entry.name} on ${provider.toolName} is not tracked in lock file`
2054
+ });
2055
+ }
2056
+ }
1990
2057
  }
1991
2058
  }
2059
+ const issueCount = entries.filter((e) => e.health.status !== "healthy").length;
1992
2060
  if (format === "human") {
1993
2061
  if (entries.length === 0) {
1994
- console.log(pc6.dim("No CLEO MCP profiles found."));
2062
+ console.log(pc6.dim("No CLEO channel profiles found."));
1995
2063
  } else {
2064
+ console.log(pc6.bold("CLEO Channel Profiles"));
2065
+ console.log();
2066
+ const header = [
2067
+ "Channel".padEnd(10),
2068
+ "Version".padEnd(10),
2069
+ "Provider".padEnd(15),
2070
+ "Scope".padEnd(9),
2071
+ "Command".padEnd(33),
2072
+ "Status".padEnd(10),
2073
+ "Installed".padEnd(12)
2074
+ ].join("");
2075
+ console.log(` ${pc6.dim(header)}`);
2076
+ console.log(` ${pc6.dim("-".repeat(99))}`);
1996
2077
  for (const entry of entries) {
1997
- console.log(`${pc6.bold(entry.provider.padEnd(22))} ${entry.serverName.padEnd(10)} ${pc6.dim(entry.channel)}`);
2078
+ const commandStr = entry.command ? `${entry.command} ${entry.args.join(" ")}`.slice(0, 31).padEnd(33) : pc6.dim("-").padEnd(33);
2079
+ const versionStr = (entry.version ?? "-").padEnd(10);
2080
+ const installedStr = entry.installedAt ? entry.installedAt.slice(0, 10).padEnd(12) : "-".padEnd(12);
2081
+ let statusStr;
2082
+ if (entry.health.status === "healthy") {
2083
+ statusStr = pc6.green("healthy".padEnd(10));
2084
+ } else if (entry.health.status === "degraded") {
2085
+ statusStr = pc6.yellow("degraded".padEnd(10));
2086
+ } else {
2087
+ statusStr = pc6.red("broken".padEnd(10));
2088
+ }
2089
+ console.log(
2090
+ ` ${entry.channel.padEnd(10)}${versionStr}${entry.providerName.padEnd(15)}${entry.scope.padEnd(9)}${commandStr}${statusStr}${installedStr}`
2091
+ );
2092
+ }
2093
+ console.log();
2094
+ const summary = ` ${entries.length} profile${entries.length !== 1 ? "s" : ""}`;
2095
+ if (issueCount > 0) {
2096
+ console.log(`${summary} | ${pc6.yellow(`${issueCount} issue${issueCount !== 1 ? "s" : ""}`)}`);
2097
+ console.log();
2098
+ console.log(" Issues:");
2099
+ for (const w of warnings) {
2100
+ console.log(` ${pc6.yellow("!")} ${w.message}`);
2101
+ }
2102
+ } else {
2103
+ console.log(summary);
1998
2104
  }
1999
2105
  }
2000
2106
  }
2001
2107
  if (format === "json") {
2002
- outputSuccess(operation, mvi, {
2003
- providers: providers.map((provider) => provider.id),
2004
- scope,
2005
- channel: channelFilter,
2006
- profiles: entries,
2007
- count: entries.length
2008
- });
2108
+ outputSuccess(
2109
+ operation,
2110
+ mvi,
2111
+ {
2112
+ providers: providers.map((provider) => provider.id),
2113
+ scopes,
2114
+ channel: channelFilter,
2115
+ profiles: entries,
2116
+ count: entries.length
2117
+ },
2118
+ void 0,
2119
+ void 0,
2120
+ warnings.length > 0 ? warnings : void 0
2121
+ );
2009
2122
  }
2010
2123
  }
2011
2124
  function buildInstallOptions(command) {
@@ -2026,7 +2139,7 @@ function registerMcpCleoCommands(parent) {
2026
2139
  cleo.command("uninstall").description("Uninstall CLEO MCP profile for a channel").requiredOption("--channel <channel>", "CLEO channel: stable|beta|dev").option("--provider <id>", "Target provider (repeatable)", collect, []).option("--all", "Apply to all detected providers").option("-g, --global", "Use global scope").option("--dry-run", "Preview without writing").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (opts) => {
2027
2140
  await executeCleoUninstall(opts, "mcp.cleo.uninstall");
2028
2141
  });
2029
- cleo.command("show").description("Show installed CLEO MCP channel profiles").option("--provider <id>", "Target provider (repeatable)", collect, []).option("--all", "Inspect all detected providers").option("-g, --global", "Use global scope").option("--channel <channel>", "Filter channel: stable|beta|dev").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (opts) => {
2142
+ cleo.command("show").description("Show installed CLEO MCP channel profiles").option("--provider <id>", "Target provider (repeatable)", collect, []).option("--all", "Inspect all detected providers").option("-g, --global", "Global scope only").option("-p, --project", "Project scope only").option("--channel <channel>", "Filter channel: stable|beta|dev").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (opts) => {
2030
2143
  await executeCleoShow(opts, "mcp.cleo.show");
2031
2144
  });
2032
2145
  }
@@ -2045,7 +2158,7 @@ function registerMcpCleoCompatibilityCommands(parent) {
2045
2158
  }
2046
2159
  await executeCleoUninstall(opts, "mcp.uninstall");
2047
2160
  });
2048
- parent.command("show").description("Show channel-managed MCP profile").argument("<name>", "Managed MCP profile name (cleo)").option("--provider <id>", "Target provider (repeatable)", collect, []).option("--all", "Inspect all detected providers").option("-g, --global", "Use global scope").option("--channel <channel>", "Filter channel: stable|beta|dev").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (name, opts) => {
2161
+ parent.command("show").description("Show channel-managed MCP profile").argument("<name>", "Managed MCP profile name (cleo)").option("--provider <id>", "Target provider (repeatable)", collect, []).option("--all", "Inspect all detected providers").option("-g, --global", "Global scope only").option("-p, --project", "Project scope only").option("--channel <channel>", "Filter channel: stable|beta|dev").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (name, opts) => {
2049
2162
  if (name !== "cleo") {
2050
2163
  emitJsonError("mcp.show", "standard", ErrorCodes.INVALID_INPUT, "Only managed profile 'cleo' is supported by mcp show.", ErrorCategories.VALIDATION, { name });
2051
2164
  process.exit(1);
@@ -2090,7 +2203,7 @@ function registerCleoCommands(program2) {
2090
2203
  cleo.command("uninstall").description("Uninstall CLEO profile for a channel").requiredOption("--channel <channel>", "CLEO channel: stable|beta|dev").option("--provider <id>", "Target provider (repeatable)", collect, []).option("--all", "Apply to all detected providers").option("-g, --global", "Use global scope").option("--dry-run", "Preview without writing").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (opts) => {
2091
2204
  await executeCleoUninstall(opts, "cleo.uninstall");
2092
2205
  });
2093
- cleo.command("show").description("Show installed CLEO channel profiles").option("--provider <id>", "Target provider (repeatable)", collect, []).option("--all", "Inspect all detected providers").option("-g, --global", "Use global scope").option("--channel <channel>", "Filter channel: stable|beta|dev").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (opts) => {
2206
+ cleo.command("show").description("Show installed CLEO channel profiles").option("--provider <id>", "Target provider (repeatable)", collect, []).option("--all", "Inspect all detected providers").option("-g, --global", "Global scope only").option("-p, --project", "Project scope only").option("--channel <channel>", "Filter channel: stable|beta|dev").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (opts) => {
2094
2207
  await executeCleoShow(opts, "cleo.show");
2095
2208
  });
2096
2209
  }