@meltstudio/meltctl 5.0.2 → 5.0.4

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.
Files changed (2) hide show
  1. package/dist/index.js +143 -106
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7450,7 +7450,7 @@ var CLI_VERSION;
7450
7450
  var init_version = __esm({
7451
7451
  "src/utils/version.ts"() {
7452
7452
  "use strict";
7453
- CLI_VERSION = "5.0.2";
7453
+ CLI_VERSION = "5.0.4";
7454
7454
  }
7455
7455
  });
7456
7456
 
@@ -26416,47 +26416,92 @@ var {
26416
26416
  } = import_index.default;
26417
26417
 
26418
26418
  // src/commands/templates.ts
26419
- init_source();
26420
- var import_fs_extra2 = __toESM(require_lib(), 1);
26421
- import path2 from "path";
26422
- import os3 from "os";
26423
-
26424
- // src/utils/auth.ts
26425
26419
  var import_fs_extra = __toESM(require_lib(), 1);
26420
+ init_source();
26426
26421
  import path from "path";
26427
26422
  import os2 from "os";
26428
- var AUTH_DIR = path.join(os2.homedir(), ".meltctl");
26429
- var AUTH_FILE = path.join(AUTH_DIR, "auth.json");
26430
- var API_BASE = process.env["MELTCTL_API_URL"] ?? "https://api.meltctl.meltstudio.co";
26431
- async function getStoredAuth() {
26432
- if (!await import_fs_extra.default.pathExists(AUTH_FILE)) {
26433
- return void 0;
26434
- }
26435
- try {
26436
- return await import_fs_extra.default.readJson(AUTH_FILE);
26437
- } catch {
26438
- return void 0;
26439
- }
26440
- }
26441
- async function storeAuth(auth) {
26442
- await import_fs_extra.default.ensureDir(AUTH_DIR);
26443
- await import_fs_extra.default.writeJson(AUTH_FILE, auth, { spaces: 2 });
26444
- }
26445
- async function clearAuth() {
26446
- if (await import_fs_extra.default.pathExists(AUTH_FILE)) {
26447
- await import_fs_extra.default.remove(AUTH_FILE);
26448
- }
26449
- }
26450
- async function isAuthenticated() {
26451
- const auth = await getStoredAuth();
26452
- if (!auth) {
26453
- return false;
26454
- }
26455
- return new Date(auth.expiresAt) > /* @__PURE__ */ new Date();
26423
+ var MIGRATION_DOC = `# Migrate this repo to Melt's current model
26424
+
26425
+ You are reading this because \`meltctl project templates\` was run (most likely by the legacy
26426
+ \`/melt-update\` skill). The per-repo Melt skill model has been **retired company-wide** and
26427
+ replaced by org-distributed \`/melt-dev-*\` skills. **This migration is mandatory \u2014 it is not a
26428
+ content refresh.** Perform the steps below now. Do NOT do a file-by-file template sync, and do
26429
+ NOT offer to skip, abort, or keep the old files.
26430
+
26431
+ ## 1. Remove the legacy per-repo skill files (the only mandatory deletion)
26432
+
26433
+ These are superseded and non-functional. \`git rm -r\` any of these that exist:
26434
+ - \`.claude/skills/melt-{setup,plan,validate,review,pr,debug,audit,ux-audit,security-audit,update,help,link}/\`
26435
+ - \`.cursor/commands/melt-*.md\` and \`.opencode/commands/melt-*.md\`
26436
+
26437
+ Leave any non-Melt skills/commands the developer authored.
26438
+
26439
+ ## 2. Update AGENTS.md \u2014 preserve the developer's content; add what's missing
26440
+
26441
+ AGENTS.md is the developer's living document; it holds project-specific rules and standards,
26442
+ not just Melt boilerplate. **Never delete or "slim" their content** \u2014 not their inline
26443
+ standards, not their own rules. ADD what's missing:
26444
+ - A \`## Stack\` block (languages, frameworks, test runner, package manager, database, deploy)
26445
+ - A \`## Project docs\` index pointing at satellite docs (TECH_DEBT.md, ARCHITECTURE.md, \u2026)
26446
+ - One line noting Melt's universal standards also ship with the \`/melt-dev-*\` skills now
26447
+
26448
+ **One exception \u2014 replace the retired Melt skill-list.** If AGENTS.md has a \`## Workflow
26449
+ Skills\` section that is the standard Melt list (a boilerplate intro plus \`/melt-*\` bullets),
26450
+ remove that section as part of this migration: the skills are org-distributed and
26451
+ auto-discovered now, so it is obsolete and points at skills you just deleted. Preserve any
26452
+ custom entries the developer added inside it. This is the ONLY Melt-authored section the
26453
+ migration removes \u2014 everything else stays untouched.
26454
+
26455
+ ## 3. Ensure .mcp.json has the servers the project needs
26456
+
26457
+ Propose, and write only on the developer's confirmation (merging \u2014 never clobbering existing
26458
+ servers), a browser server for any web/UI project:
26459
+ \`\`\`json
26460
+ "chrome-devtools": { "command": "npx", "args": ["-y", "chrome-devtools-mcp@latest", "--isolated"] }
26461
+ \`\`\`
26462
+ Add any other clearly-useful, stack-appropriate servers.
26463
+
26464
+ ## 4. Never touch these
26465
+
26466
+ \`.claude/settings.json\` and \`.gitignore\` are entirely developer-owned.
26467
+
26468
+ ## 5. Consistency review \u2014 propose cleanups, don't apply them
26469
+
26470
+ After the additive changes, re-read the whole AGENTS.md and look for anything that's now
26471
+ redundant, stale, contradicts a section you just added, or plainly no longer makes sense (a
26472
+ rule referencing a removed tool, a section the new \`## Stack\` block now duplicates, generic
26473
+ boilerplate the team clearly never customized). For each, **propose** the change to the
26474
+ developer with a one-line reason and let THEM decide \u2014 apply a removal or edit only on their
26475
+ explicit approval. Additive is the default; this pass keeps the repo coherent without you
26476
+ unilaterally deleting their content.
26477
+
26478
+ ## After migrating
26479
+
26480
+ The \`/melt-dev-*\` skills are distributed via the Anthropic org Skills registry and auto-update
26481
+ in Claude Code. If they are not available in your session, that is an org-enrollment issue \u2014
26482
+ raise it in #dev. It is not a reason to stay on the old model.
26483
+ `;
26484
+ async function templatesCommand() {
26485
+ const tmpDir = path.join(os2.tmpdir(), `melt-migration-${Date.now()}`);
26486
+ await import_fs_extra.default.ensureDir(tmpDir);
26487
+ await import_fs_extra.default.writeFile(path.join(tmpDir, "MIGRATION.md"), MIGRATION_DOC, "utf-8");
26488
+ const notice = [
26489
+ "",
26490
+ source_default.bold.yellow("\u26A0 The per-repo Melt skill model has been retired (company-wide)."),
26491
+ "This command now hands back MIGRATION INSTRUCTIONS, not a template refresh.",
26492
+ `\u2192 Follow ${source_default.cyan("MIGRATION.md")} in the directory printed below to migrate this repo now.`,
26493
+ ` (In Claude Code with the org skills, ${source_default.cyan("/melt-dev-update")} does the same migration.)`,
26494
+ ""
26495
+ ].join("\n");
26496
+ console.error(notice);
26497
+ console.log(tmpDir);
26456
26498
  }
26457
26499
 
26458
- // src/utils/api.ts
26500
+ // src/commands/login.ts
26459
26501
  init_source();
26502
+ import http from "http";
26503
+ import { URL as URL2 } from "url";
26504
+ import { exec } from "child_process";
26460
26505
 
26461
26506
  // ../sdk/dist/resources/audits.js
26462
26507
  function createAuditsResource(config2) {
@@ -42051,83 +42096,40 @@ var RULE_BY_ID = new Map(ISSUE_RULES.map((r) => [r.id, r]));
42051
42096
  // ../sdk/dist/utils/health-issues-derivation.js
42052
42097
  var FOURTEEN_DAYS_MS = 14 * 24 * 60 * 60 * 1e3;
42053
42098
 
42054
- // src/utils/api.ts
42055
- async function getToken() {
42056
- const envToken = process.env["MELTCTL_TOKEN"];
42057
- if (envToken) {
42058
- return envToken;
42059
- }
42060
- const auth = await getStoredAuth();
42061
- if (!auth) {
42062
- console.error(
42063
- source_default.red(
42064
- "Not authenticated. Run `npx @meltstudio/meltctl@latest login` or set MELTCTL_TOKEN for CI."
42065
- )
42066
- );
42067
- process.exit(1);
42099
+ // src/utils/auth.ts
42100
+ var import_fs_extra2 = __toESM(require_lib(), 1);
42101
+ import path2 from "path";
42102
+ import os3 from "os";
42103
+ var AUTH_DIR = path2.join(os3.homedir(), ".meltctl");
42104
+ var AUTH_FILE = path2.join(AUTH_DIR, "auth.json");
42105
+ var API_BASE = process.env["MELTCTL_API_URL"] ?? "https://api.meltctl.meltstudio.co";
42106
+ async function getStoredAuth() {
42107
+ if (!await import_fs_extra2.default.pathExists(AUTH_FILE)) {
42108
+ return void 0;
42068
42109
  }
42069
- if (new Date(auth.expiresAt) <= /* @__PURE__ */ new Date()) {
42070
- console.error(
42071
- source_default.red(
42072
- "Session expired. Run `npx @meltstudio/meltctl@latest login` to re-authenticate, or set MELTCTL_TOKEN for CI."
42073
- )
42074
- );
42075
- process.exit(1);
42110
+ try {
42111
+ return await import_fs_extra2.default.readJson(AUTH_FILE);
42112
+ } catch {
42113
+ return void 0;
42076
42114
  }
42077
- return auth.token;
42078
- }
42079
- async function getClient() {
42080
- const token = await getToken();
42081
- return createMeltClient({ baseUrl: API_BASE, token });
42082
42115
  }
42083
-
42084
- // src/utils/templates.ts
42085
- async function fetchTemplates() {
42086
- const client = await getClient();
42087
- return client.templates.fetch();
42116
+ async function storeAuth(auth) {
42117
+ await import_fs_extra2.default.ensureDir(AUTH_DIR);
42118
+ await import_fs_extra2.default.writeJson(AUTH_FILE, auth, { spaces: 2 });
42088
42119
  }
42089
-
42090
- // src/commands/templates.ts
42091
- async function templatesCommand() {
42092
- if (!await isAuthenticated()) {
42093
- console.error(source_default.red("Not authenticated. Run `npx @meltstudio/meltctl@latest login` first."));
42094
- process.exit(1);
42095
- }
42096
- let templates;
42097
- try {
42098
- templates = await fetchTemplates();
42099
- } catch (error48) {
42100
- if (error48 instanceof Error && error48.message.includes("expired")) {
42101
- console.error(
42102
- source_default.red("Session expired. Run `npx @meltstudio/meltctl@latest login` to re-authenticate.")
42103
- );
42104
- } else if (error48 instanceof Error && error48.message.includes("fetch")) {
42105
- console.error(source_default.red("Could not reach Melt API. Check your connection."));
42106
- } else {
42107
- console.error(
42108
- source_default.red(
42109
- `Failed to fetch templates: ${error48 instanceof Error ? error48.message : "Unknown error"}`
42110
- )
42111
- );
42112
- }
42113
- process.exit(1);
42120
+ async function clearAuth() {
42121
+ if (await import_fs_extra2.default.pathExists(AUTH_FILE)) {
42122
+ await import_fs_extra2.default.remove(AUTH_FILE);
42114
42123
  }
42115
- const tmpDir = path2.join(os3.tmpdir(), `melt-templates-${Date.now()}`);
42116
- await import_fs_extra2.default.ensureDir(tmpDir);
42117
- for (const [filePath, content] of Object.entries(templates)) {
42118
- const fullPath = path2.join(tmpDir, filePath);
42119
- await import_fs_extra2.default.ensureDir(path2.dirname(fullPath));
42120
- await import_fs_extra2.default.writeFile(fullPath, content, "utf-8");
42124
+ }
42125
+ async function isAuthenticated() {
42126
+ const auth = await getStoredAuth();
42127
+ if (!auth) {
42128
+ return false;
42121
42129
  }
42122
- console.log(tmpDir);
42130
+ return new Date(auth.expiresAt) > /* @__PURE__ */ new Date();
42123
42131
  }
42124
42132
 
42125
- // src/commands/login.ts
42126
- init_source();
42127
- import http from "http";
42128
- import { URL as URL2 } from "url";
42129
- import { exec } from "child_process";
42130
-
42131
42133
  // src/utils/banner.ts
42132
42134
  init_source();
42133
42135
 
@@ -42479,6 +42481,39 @@ async function versionCheckCommand() {
42479
42481
  // src/commands/standup.ts
42480
42482
  init_source();
42481
42483
  init_dist11();
42484
+
42485
+ // src/utils/api.ts
42486
+ init_source();
42487
+ async function getToken() {
42488
+ const envToken = process.env["MELTCTL_TOKEN"];
42489
+ if (envToken) {
42490
+ return envToken;
42491
+ }
42492
+ const auth = await getStoredAuth();
42493
+ if (!auth) {
42494
+ console.error(
42495
+ source_default.red(
42496
+ "Not authenticated. Run `npx @meltstudio/meltctl@latest login` or set MELTCTL_TOKEN for CI."
42497
+ )
42498
+ );
42499
+ process.exit(1);
42500
+ }
42501
+ if (new Date(auth.expiresAt) <= /* @__PURE__ */ new Date()) {
42502
+ console.error(
42503
+ source_default.red(
42504
+ "Session expired. Run `npx @meltstudio/meltctl@latest login` to re-authenticate, or set MELTCTL_TOKEN for CI."
42505
+ )
42506
+ );
42507
+ process.exit(1);
42508
+ }
42509
+ return auth.token;
42510
+ }
42511
+ async function getClient() {
42512
+ const token = await getToken();
42513
+ return createMeltClient({ baseUrl: API_BASE, token });
42514
+ }
42515
+
42516
+ // src/commands/standup.ts
42482
42517
  var EDITOR_HINT = source_default.dim("(type \\e to open your editor)");
42483
42518
  async function promptField(message, required2) {
42484
42519
  const value = await dist_default7({ message: `${message} ${EDITOR_HINT}` });
@@ -55442,7 +55477,9 @@ ${source_default.dim(" /melt-dev-link Connect and verify ticket tracker + br
55442
55477
  ${source_default.dim(" /melt-dev-update Refresh AGENTS.md + MCP config to the latest")}
55443
55478
  `
55444
55479
  );
55445
- project.command("templates").description("fetch latest templates to a temp directory (for /melt-dev-update)").action(async () => {
55480
+ project.command("templates").description(
55481
+ "write the repo-migration playbook to a temp dir (the /melt-update \u2192 /melt-dev-* path); /melt-dev-update does the same"
55482
+ ).action(async () => {
55446
55483
  await templatesCommand();
55447
55484
  });
55448
55485
  program2.command("standup").description("submit your daily standup report").addOption(new Option("--yesterday <text>").hideHelp()).addOption(new Option("--today <text>").hideHelp()).addOption(new Option("--blockers <text>").hideHelp()).action(async (options) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meltstudio/meltctl",
3
- "version": "5.0.2",
3
+ "version": "5.0.4",
4
4
  "description": "AI-first development tooling for Melt teams — companion CLI for the org-distributed Claude Code dev skills",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",