@meltstudio/meltctl 5.18.0 → 5.19.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.
Files changed (2) hide show
  1. package/dist/index.js +32 -10
  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.18.0";
7453
+ CLI_VERSION = "5.19.0";
7454
7454
  }
7455
7455
  });
7456
7456
 
@@ -27403,8 +27403,14 @@ function createPmResource(config2) {
27403
27403
  });
27404
27404
  return unwrap("promote scenario", res);
27405
27405
  },
27406
- async assignFeature(phaseId, featureId) {
27407
- const res = await apiFetch(config2, `/pm/phases/${phaseId}/features`, { method: "POST", body: JSON.stringify({ featureId }) });
27406
+ /**
27407
+ * Add a feature to a phase, optionally authoring the per-phase intent in
27408
+ * the same call (#611). Omitting `init` keeps the historical behaviour —
27409
+ * the membership takes the schema defaults (target `mv`, placeholder
27410
+ * scope) and the PM refines later via {@link updatePhaseFeature}.
27411
+ */
27412
+ async assignFeature(phaseId, featureId, init) {
27413
+ const res = await apiFetch(config2, `/pm/phases/${phaseId}/features`, { method: "POST", body: JSON.stringify({ featureId, ...init }) });
27408
27414
  return unwrap("assign feature", res, 201);
27409
27415
  },
27410
27416
  async unassignFeature(phaseId, featureId) {
@@ -54055,8 +54061,14 @@ function createPmResource2(config2) {
54055
54061
  });
54056
54062
  return unwrap2("promote scenario", res);
54057
54063
  },
54058
- async assignFeature(phaseId, featureId) {
54059
- const res = await apiFetch2(config2, `/pm/phases/${phaseId}/features`, { method: "POST", body: JSON.stringify({ featureId }) });
54064
+ /**
54065
+ * Add a feature to a phase, optionally authoring the per-phase intent in
54066
+ * the same call (#611). Omitting `init` keeps the historical behaviour —
54067
+ * the membership takes the schema defaults (target `mv`, placeholder
54068
+ * scope) and the PM refines later via {@link updatePhaseFeature}.
54069
+ */
54070
+ async assignFeature(phaseId, featureId, init) {
54071
+ const res = await apiFetch2(config2, `/pm/phases/${phaseId}/features`, { method: "POST", body: JSON.stringify({ featureId, ...init }) });
54060
54072
  return unwrap2("assign feature", res, 201);
54061
54073
  },
54062
54074
  async unassignFeature(phaseId, featureId) {
@@ -55358,7 +55370,8 @@ async function deletePhase(client, input) {
55358
55370
  });
55359
55371
  }
55360
55372
  async function assignFeatureToPhase(client, input) {
55361
- return safe(() => client.pm.assignFeature(input.phaseId, input.featureId));
55373
+ const { phaseId, featureId, ...init } = input;
55374
+ return safe(() => client.pm.assignFeature(phaseId, featureId, init));
55362
55375
  }
55363
55376
  async function unassignFeatureFromPhase(client, input) {
55364
55377
  return safe(() => client.pm.unassignFeature(input.phaseId, input.featureId));
@@ -55474,10 +55487,19 @@ Mandatory caller behavior: present the phase's name + id + active/closed status
55474
55487
  "assign_feature_to_phase",
55475
55488
  {
55476
55489
  title: "Assign feature to phase",
55477
- description: "Adds an existing feature to an existing phase. Captures the feature's current_stage as a stage_snapshot at join time \u2014 closed phases keep the snapshot they ended at, even if the feature later progresses. The feature and phase must belong to the same project. Returns the membership row.",
55490
+ description: "Adds an existing feature to an existing phase, and is where the per-phase INTENT should be authored. A feature can sit in several phases, so what matters is which SLICE of it this phase builds \u2014 set targetStage and phaseDescription here rather than leaving the defaults for a follow-up update_phase_feature call. Left unset they fall back to target 'mv' and the placeholder 'PM to refine', which renders on the roadmap as an unscoped row the PM has to come back and fix. Captures the feature's current_stage as a stage_snapshot at join time \u2014 closed phases keep the snapshot they ended at, even if the feature later progresses. The feature and phase must belong to the same project. Returns the membership row.",
55478
55491
  inputSchema: {
55479
55492
  phaseId: external_exports.string().uuid().describe("Phase id from list_phases or create_phase."),
55480
- featureId: external_exports.string().uuid().describe("Feature id from list_features or create_feature.")
55493
+ featureId: external_exports.string().uuid().describe("Feature id from list_features or create_feature."),
55494
+ targetStage: external_exports.enum(STAGE_VALUES).optional().describe(
55495
+ "Per-phase target stage \u2014 what THIS phase brings the feature to, which is usually not its eventual target (e.g. 'pt' in an early phase, 'mv' in a later one). 7-stage enum (idea | poc | pt | mv | mk | ma | mbi). Defaults to 'mv' when omitted."
55496
+ ),
55497
+ phaseDescription: external_exports.string().min(1).optional().describe(
55498
+ "Per-phase scope: which part of the feature this phase builds, in PM voice \u2014 e.g. 'Core: email/password auth' in one phase and 'Extended: Google + Apple SSO, magic-link spike' in the next. Shown on the roadmap board and the client portal under the feature name, so write it for the client to read. Defaults to the 'PM to refine' placeholder when omitted."
55499
+ ),
55500
+ force: external_exports.boolean().optional().describe(
55501
+ "Required (true) only when setting targetStage on a membership in a LOCKED phase (state active/proposed) \u2014 that moves every downstream planning baseline. Plain assigns never need it."
55502
+ )
55481
55503
  }
55482
55504
  },
55483
55505
  withClientArgs(getClient2, assignFeatureToPhase)
@@ -55498,7 +55520,7 @@ Mandatory caller behavior: present the phase's name + id + active/closed status
55498
55520
  "update_phase_feature",
55499
55521
  {
55500
55522
  title: "Update phase-feature membership",
55501
- description: "Edits the per-phase intent for a feature in a phase: targetStage (what this phase aims to bring the feature to), phaseDescription (PM-authored note about what this jump means in this phase), linearEpicUrl (per-phase Linear epic), status (per-phase status \u2014 a feature can be done in one phase and in_progress in another). The same feature can have different per-phase values across phases. Use after assign_feature_to_phase when the PM wants per-membership values different from the feature-row defaults. The PM should review the proposed change before this is called \u2014 this is a write operation. Pass linearEpicUrl=null to clear the per-phase Linear link. Editing a membership in a LOCKED phase (state active/proposed) requires force=true.",
55523
+ description: "Edits the per-phase intent for a feature in a phase: targetStage (what this phase aims to bring the feature to), phaseDescription (PM-authored note about what this jump means in this phase), linearEpicUrl (per-phase Linear epic), status (per-phase status \u2014 a feature can be done in one phase and in_progress in another). The same feature can have different per-phase values across phases. Use to REVISE a membership \u2014 the initial targetStage and phaseDescription are better set on assign_feature_to_phase, in one call. The PM should review the proposed change before this is called \u2014 this is a write operation. Pass linearEpicUrl=null to clear the per-phase Linear link. Editing a membership in a LOCKED phase (state active/proposed) requires force=true.",
55502
55524
  inputSchema: {
55503
55525
  phaseId: external_exports.string().uuid().describe("Phase id from list_phases."),
55504
55526
  featureId: external_exports.string().uuid().describe("Feature id of the membership to edit."),
@@ -55506,7 +55528,7 @@ Mandatory caller behavior: present the phase's name + id + active/closed status
55506
55528
  "Per-phase target stage. What this phase aims to bring the feature to \u2014 e.g. 'pt' for prototype in an early phase, 'mv' for MVP in a later one. 7-stage enum (idea | poc | pt | mv | mk | ma | mbi)."
55507
55529
  ),
55508
55530
  phaseDescription: external_exports.string().min(1).optional().describe(
55509
- "One-line PM-voice note: what should this feature be doing once this phase's jump lands. New memberships default to 'PM to refine'."
55531
+ "Per-phase scope in PM voice: which part of the feature this phase builds / what it should be doing once this phase's jump lands. Shown on the roadmap board and the client portal under the feature name. New memberships default to the 'PM to refine' placeholder."
55510
55532
  ),
55511
55533
  linearEpicUrl: external_exports.string().url().nullable().optional().describe(
55512
55534
  "Per-phase Linear epic URL. Each phase's work on a feature can be its own epic. Pass null to clear."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meltstudio/meltctl",
3
- "version": "5.18.0",
3
+ "version": "5.19.0",
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",