@formigio/fazemos-cli 0.10.52 → 0.10.54

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/api.d.ts CHANGED
@@ -71,6 +71,30 @@ export declare function resolveOrgIdMaybeSlug(value: string): Promise<string>;
71
71
  * archive) and needs subsequent lookups to see the new data.
72
72
  */
73
73
  export declare function refreshAuthMeCache(): Promise<AuthMeResponse | null>;
74
+ /**
75
+ * F49 CHG-2 — Cross-org API key resolver.
76
+ *
77
+ * In agent execution contexts (Fargate tasks), the launcher injects env vars:
78
+ * FAZEMOS_API_KEY — primary org fzm_ key (always present for agents)
79
+ * FAZEMOS_ORG_ID — primary org UUID
80
+ * FAZEMOS_API_KEY__{ORG_SLUG_UPPER_SNAKE} — cross-org key(s), one per target org
81
+ *
82
+ * Resolution order (BD-2 enforcement — no disk write, env-var-only):
83
+ * 1. If FAZEMOS_API_KEY is present → agent context (API key auth)
84
+ * a. If active org UUID differs from FAZEMOS_ORG_ID → cross-org call
85
+ * - Resolve active org slug from authMeCache
86
+ * - Look up FAZEMOS_API_KEY__{SLUG.toUpperCase().replace(/-/g,'_')}
87
+ * - If found → return cross-org key
88
+ * - If absent → fall through to FAZEMOS_API_KEY (server returns natural 404)
89
+ * b. Otherwise (primary org or no org context) → return FAZEMOS_API_KEY
90
+ * 2. No FAZEMOS_API_KEY → human Cognito-token context → return null (caller uses getToken)
91
+ *
92
+ * Slug normalization is EXACTLY `.toUpperCase().replace(/-/g, '_')` per BD-4
93
+ * (no other transformation). Example: "never-behind" → "NEVER_BEHIND".
94
+ *
95
+ * NEVER writes anything to disk — reads process.env only (BD-2 hard property).
96
+ */
97
+ export declare function resolveBearerToken(activeOrgId: string | null): string | null;
74
98
  /**
75
99
  * Core API helper. Always authenticates, always sends X-Org-Id when one is
76
100
  * active, and sends X-Fazemos-Project-Id when a project is active (or one
package/dist/api.js CHANGED
@@ -1,4 +1,4 @@
1
- import { getEnv, getToken, getActiveOrgId, getActiveProjectId, findProjectBySlug, findOrgBySlug, setAuthMeCache, clearAuthMeCache, } from './config.js';
1
+ import { getEnv, getToken, getActiveOrgId, getActiveProjectId, findProjectBySlug, findOrgBySlug, findOrgById, setAuthMeCache, clearAuthMeCache, } from './config.js';
2
2
  import { refreshSession } from './auth.js';
3
3
  /**
4
4
  * Error thrown when an API request returns a non-2xx response. Carries the
@@ -100,6 +100,54 @@ export async function refreshAuthMeCache() {
100
100
  }
101
101
  return null;
102
102
  }
103
+ /**
104
+ * F49 CHG-2 — Cross-org API key resolver.
105
+ *
106
+ * In agent execution contexts (Fargate tasks), the launcher injects env vars:
107
+ * FAZEMOS_API_KEY — primary org fzm_ key (always present for agents)
108
+ * FAZEMOS_ORG_ID — primary org UUID
109
+ * FAZEMOS_API_KEY__{ORG_SLUG_UPPER_SNAKE} — cross-org key(s), one per target org
110
+ *
111
+ * Resolution order (BD-2 enforcement — no disk write, env-var-only):
112
+ * 1. If FAZEMOS_API_KEY is present → agent context (API key auth)
113
+ * a. If active org UUID differs from FAZEMOS_ORG_ID → cross-org call
114
+ * - Resolve active org slug from authMeCache
115
+ * - Look up FAZEMOS_API_KEY__{SLUG.toUpperCase().replace(/-/g,'_')}
116
+ * - If found → return cross-org key
117
+ * - If absent → fall through to FAZEMOS_API_KEY (server returns natural 404)
118
+ * b. Otherwise (primary org or no org context) → return FAZEMOS_API_KEY
119
+ * 2. No FAZEMOS_API_KEY → human Cognito-token context → return null (caller uses getToken)
120
+ *
121
+ * Slug normalization is EXACTLY `.toUpperCase().replace(/-/g, '_')` per BD-4
122
+ * (no other transformation). Example: "never-behind" → "NEVER_BEHIND".
123
+ *
124
+ * NEVER writes anything to disk — reads process.env only (BD-2 hard property).
125
+ */
126
+ export function resolveBearerToken(activeOrgId) {
127
+ const primaryApiKey = process.env.FAZEMOS_API_KEY;
128
+ if (!primaryApiKey) {
129
+ // Cognito-token path — caller falls back to getToken() / refreshSession()
130
+ return null;
131
+ }
132
+ const primaryOrgId = process.env.FAZEMOS_ORG_ID;
133
+ if (activeOrgId && primaryOrgId && activeOrgId !== primaryOrgId) {
134
+ // Active org differs from the primary key's org — look for a cross-org key.
135
+ // Slug normalization: EXACT rule per manifest BD-4 and Dex checklist:
136
+ // .toUpperCase().replace(/-/g, '_')
137
+ const activeOrg = findOrgById(activeOrgId);
138
+ if (activeOrg?.slug) {
139
+ const upperSnake = activeOrg.slug.toUpperCase().replace(/-/g, '_');
140
+ const crossOrgKey = process.env[`FAZEMOS_API_KEY__${upperSnake}`];
141
+ if (crossOrgKey) {
142
+ return crossOrgKey;
143
+ }
144
+ // Cross-org key absent (EC3 — env var not yet injected, or SSM mint lagged):
145
+ // fall through to primary key; server returns natural 404. No client-side error.
146
+ }
147
+ }
148
+ // Primary org call, or cross-org slug unresolvable → use primary API key
149
+ return primaryApiKey;
150
+ }
103
151
  /**
104
152
  * Core API helper. Always authenticates, always sends X-Org-Id when one is
105
153
  * active, and sends X-Fazemos-Project-Id when a project is active (or one
@@ -118,20 +166,27 @@ export async function refreshAuthMeCache() {
118
166
  */
119
167
  export async function api(method, path, body, opts = {}) {
120
168
  const env = getEnv();
121
- let token = getToken();
122
169
  const orgId = getActiveOrgId();
123
- // Auto-refresh if token is expired
124
- if (!token) {
125
- token = await refreshSession();
170
+ // F49 CHG-2: resolve bearer token API key (agent context) or Cognito JWT (human context)
171
+ const apiKey = resolveBearerToken(orgId);
172
+ let token = null;
173
+ if (!apiKey) {
174
+ // Cognito auth path — human users / local dev
175
+ token = getToken();
176
+ // Auto-refresh if token is expired
126
177
  if (!token) {
127
- throw new Error('Session expired. Run: fazemos auth login');
178
+ token = await refreshSession();
179
+ if (!token) {
180
+ throw new Error('Session expired. Run: fazemos auth login');
181
+ }
128
182
  }
129
183
  }
130
184
  const headers = {
131
185
  'Content-Type': 'application/json',
132
186
  };
133
- if (token) {
134
- headers['Authorization'] = `Bearer ${token}`;
187
+ const bearer = apiKey ?? token;
188
+ if (bearer) {
189
+ headers['Authorization'] = `Bearer ${bearer}`;
135
190
  }
136
191
  if (orgId) {
137
192
  headers['X-Org-Id'] = orgId;
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,QAAQ,EACR,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,cAAc,EACd,gBAAgB,GAEjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,MAAM,CAAS;IACf,IAAI,CAAU;IACd,IAAI,CAAW;IACf,YAAY,OAAe,EAAE,MAAc,EAAE,IAAa,EAAE,IAAc;QACxE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AA4BD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,YAAqB;IAChE,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,OAAO,GAAG,iBAAiB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QACrD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,mEAAmE;YACnE,kEAAkE;YAClE,oCAAoC;YACpC,MAAM,kBAAkB,EAAE,CAAC;YAC3B,OAAO,GAAG,iBAAiB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,QAAQ,CAChB,oBAAoB,YAAY,EAAE,EAClC,GAAG,EACH,iBAAiB,CAClB,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC,EAAE,CAAC;IACpB,CAAC;IAED,OAAO,kBAAkB,EAAE,CAAC;AAC9B,CAAC;AAED,oFAAoF;AACpF,MAAM,OAAO,GAAG,iEAAiE,CAAC;AAElF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAa;IACvD,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEtC,IAAI,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,kBAAkB,EAAE,CAAC;QAC3B,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,gBAAgB,KAAK,yEAAyE,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC,EAAE,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAmB,CAAC;QAClG,IAAI,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,MAAM,IAAI,EAAE,EAAE,CAAC;YACjD,cAAc,CAAC,EAAE,CAAC,CAAC;YACnB,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;QAClE,gEAAgE;QAChE,iBAAiB;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAA0B;IAC3D,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAClD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,0EAA0E;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAChD,IAAI,WAAW,IAAI,YAAY,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;QAChE,4EAA4E;QAC5E,sEAAsE;QACtE,sCAAsC;QACtC,MAAM,SAAS,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;QAC3C,IAAI,SAAS,EAAE,IAAI,EAAE,CAAC;YACpB,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACnE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,UAAU,EAAE,CAAC,CAAC;YAClE,IAAI,WAAW,EAAE,CAAC;gBAChB,OAAO,WAAW,CAAC;YACrB,CAAC;YACD,6EAA6E;YAC7E,iFAAiF;QACnF,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,MAAc,EACd,IAAY,EACZ,IAAc,EACd,OAAmB,EAAE;IAErB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAE/B,2FAA2F;IAC3F,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAEzC,IAAI,KAAK,GAAkB,IAAI,CAAC;IAChC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,8CAA8C;QAC9C,KAAK,GAAG,QAAQ,EAAE,CAAC;QACnB,mCAAmC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,MAAM,cAAc,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;KACnC,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,IAAI,KAAK,CAAC;IAC/B,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,EAAE,CAAC;IAChD,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED,yEAAyE;IACzE,2EAA2E;IAC3E,yEAAyE;IACzE,mBAAmB;IACnB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACjE,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,CAAC,sBAAsB,CAAC,GAAG,SAAS,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,oCAAoC;IACpC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,oEAAoE;IACpE,yEAAyE;IACzE,qEAAqE;IACrE,oDAAoD;IACpD,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;IACjC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;IACtD,CAAC;IAED,MAAM,OAAO,GAAgB;QAC3B,MAAM;QACN,OAAO;KACR,CAAC;IAEF,IAAI,IAAI,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEnC,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,GAAG,GACP,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;YACvC,CAAC,CAAE,IAA0C;YAC7C,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,IAAI,GAAG,GAAG,EAAE,IAAI,CAAC;QACvB,MAAM,GAAG,GAAG,GAAG,EAAE,KAAK,IAAI,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QAEpD,+DAA+D;QAC/D,8DAA8D;QAC9D,IAAI,IAAI,KAAK,yBAAyB,EAAE,CAAC;YACvC,MAAM,IAAI,QAAQ,CAChB,8BAA8B,EAC9B,QAAQ,CAAC,MAAM,EACf,IAAI,EACJ,IAAI,CACL,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACnC,gBAAgB,EAAE,CAAC;AACrB,CAAC"}
package/dist/index.js CHANGED
@@ -532,7 +532,7 @@ program
532
532
  // ── Directory context (`fazemos use`) ───────────────────────
533
533
  program
534
534
  .command('use')
535
- .description(`Set the default org/project for the current directory (writes ${DIR_CONFIG_FILENAME}). Running the CLI anywhere under that directory scopes calls to this org/project automatically.`)
535
+ .description(`Set the default org/project for the current directory (writes ${DIR_CONFIG_FILENAME}). Running the CLI anywhere under that directory scopes calls to this org/project automatically. Environment (dev/prod) is deliberately session-scoped, not directory-scoped — set FAZEMOS_ENV or pass --env instead.`)
536
536
  .option('-o, --org <slug>', 'Org slug to pin for this directory')
537
537
  .option('-p, --project <slug>', 'Project slug to pin for this directory')
538
538
  .option('--show', 'Show the directory context in effect and which file provides it')
@@ -3814,6 +3814,30 @@ function findPhaseById(definition, phaseId) {
3814
3814
  return (definition?.phases || []).find((p) => p.id === phaseId);
3815
3815
  }
3816
3816
  const VALID_STEP_TYPES = ['human', 'agent', 'script', 'gate', 'human_approval'];
3817
+ /**
3818
+ * G15 — resolve a template identifier that may be a UUID *or* a template name
3819
+ * to a UUID. The template-by-id endpoints (`GET/PUT/PATCH /api/pipeline-templates/:id`)
3820
+ * require a UUID param (`requireUuidParam` middleware — a non-UUID arg returns
3821
+ * "id must be a valid UUID" with empty stdout), so a name like "aiv-full-auto"
3822
+ * must first be resolved via the project-scoped list. UUIDs pass through
3823
+ * untouched (no extra API call). Names are matched within the active project
3824
+ * (or `--project <slug>`); slug is also matched for forward-compatibility if the
3825
+ * API ever adds one.
3826
+ */
3827
+ async function resolveTemplateId(idOrName, opts = {}) {
3828
+ if (UUID_RE.test(idOrName))
3829
+ return idOrName;
3830
+ const data = await api('GET', '/api/pipeline-templates', undefined, projectOpts(opts));
3831
+ const matches = (data.templates ?? []).filter((t) => t.name === idOrName || t.slug === idOrName);
3832
+ if (matches.length === 1)
3833
+ return matches[0].id;
3834
+ if (matches.length === 0) {
3835
+ throw new Error(`No template named "${idOrName}" in the active project. ` +
3836
+ `Run "tpl list" to see names/IDs, pass --project <slug> to look in another project, or use the template UUID.`);
3837
+ }
3838
+ throw new Error(`Multiple templates named "${idOrName}" (${matches.map((t) => t.id).join(', ')}). ` +
3839
+ `Use the template UUID to disambiguate.`);
3840
+ }
3817
3841
  // ── Templates ──────────────────────────────────────────────
3818
3842
  const templates = program.command('templates').alias('tpl').description('Pipeline template commands.\n\n' +
3819
3843
  ' Templates define multi-step workflows: template → phases → steps → I/O.\n' +
@@ -3856,12 +3880,14 @@ templates
3856
3880
  templates
3857
3881
  .command('show')
3858
3882
  .description('Show template detail including phases, steps, I/O declarations, pipeline inputs, and revision number. Use this to inspect the full structure of a template and discover phase/step IDs needed by other commands.')
3859
- .argument('<id>', 'Template ID (use "tpl list" to find IDs)')
3883
+ .argument('<id>', 'Template ID or name (use "tpl list" to find them)')
3860
3884
  .option('--json', 'Output the template definition as JSON (same as tpl export). Useful for piping/inspecting without a temp file.')
3861
3885
  .option('--show-sections', 'Print full sections content for all steps (default: truncated at 200 chars)')
3886
+ .option('--project <slug>', 'Override active project when resolving a template name')
3862
3887
  .action(async (id, opts) => {
3863
3888
  try {
3864
- const data = await api('GET', `/api/pipeline-templates/${id}`);
3889
+ const resolvedId = await resolveTemplateId(id, opts);
3890
+ const data = await api('GET', `/api/pipeline-templates/${resolvedId}`);
3865
3891
  const t = data.template;
3866
3892
  // --json mode: emit definition JSON (same as tpl export)
3867
3893
  if (opts.json) {
@@ -3982,11 +4008,13 @@ templates
3982
4008
  templates
3983
4009
  .command('export')
3984
4010
  .description('Export a template\'s full definition JSON to stdout or a file. Includes all phases, steps, sections, verification, uat, agent_config, I/O wires, and pipeline inputs. The exported JSON is the canonical input to "tpl update-definition". Round-trip: tpl export <id> > def.json && tpl update-definition <id> def.json is a no-op.')
3985
- .argument('<id>', 'Template ID (use "tpl list" to find IDs)')
4011
+ .argument('<id>', 'Template ID or name (use "tpl list" to find them)')
3986
4012
  .option('--out <file>', 'Write output to file instead of stdout')
4013
+ .option('--project <slug>', 'Override active project when resolving a template name')
3987
4014
  .action(async (id, opts) => {
3988
4015
  try {
3989
- const data = await api('GET', `/api/pipeline-templates/${id}`);
4016
+ const resolvedId = await resolveTemplateId(id, opts);
4017
+ const data = await api('GET', `/api/pipeline-templates/${resolvedId}`);
3990
4018
  const t = data.template;
3991
4019
  const json = JSON.stringify(t.definition, null, 2);
3992
4020
  if (opts.out) {