team-toon-tack 2.0.0 → 2.0.1

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.
@@ -217,13 +217,20 @@ async function selectStatusSource(options) {
217
217
  });
218
218
  return response.statusSource || "remote";
219
219
  }
220
- async function selectStatusMappings(states, options) {
221
- const defaults = getDefaultStatusTransitions(states);
222
- if (!options.interactive || states.length === 0) {
223
- return defaults;
220
+ async function selectStatusMappings(devStates, qaStates, options) {
221
+ // Use dev team states for todo, in_progress, done, blocked
222
+ // Use qa team states for testing (fallback to dev team if not set)
223
+ const devDefaults = getDefaultStatusTransitions(devStates);
224
+ const testingStates = qaStates && qaStates.length > 0 ? qaStates : devStates;
225
+ const testingDefaults = getDefaultStatusTransitions(testingStates);
226
+ if (!options.interactive || devStates.length === 0) {
227
+ return {
228
+ ...devDefaults,
229
+ testing: testingDefaults.testing,
230
+ };
224
231
  }
225
232
  console.log("\nšŸ“Š Configure status mappings:");
226
- const stateChoices = states.map((s) => ({
233
+ const devStateChoices = devStates.map((s) => ({
227
234
  title: `${s.name} (${s.type})`,
228
235
  value: s.name,
229
236
  }));
@@ -231,53 +238,61 @@ async function selectStatusMappings(states, options) {
231
238
  type: "select",
232
239
  name: "todo",
233
240
  message: 'Select status for "Todo" (pending tasks):',
234
- choices: stateChoices,
235
- initial: stateChoices.findIndex((c) => c.value === defaults.todo),
241
+ choices: devStateChoices,
242
+ initial: devStateChoices.findIndex((c) => c.value === devDefaults.todo),
236
243
  });
237
244
  const inProgressResponse = await prompts({
238
245
  type: "select",
239
246
  name: "in_progress",
240
247
  message: 'Select status for "In Progress" (working tasks):',
241
- choices: stateChoices,
242
- initial: stateChoices.findIndex((c) => c.value === defaults.in_progress),
248
+ choices: devStateChoices,
249
+ initial: devStateChoices.findIndex((c) => c.value === devDefaults.in_progress),
243
250
  });
244
251
  const doneResponse = await prompts({
245
252
  type: "select",
246
253
  name: "done",
247
254
  message: 'Select status for "Done" (completed tasks):',
248
- choices: stateChoices,
249
- initial: stateChoices.findIndex((c) => c.value === defaults.done),
255
+ choices: devStateChoices,
256
+ initial: devStateChoices.findIndex((c) => c.value === devDefaults.done),
250
257
  });
258
+ // Testing uses qa team states (or dev team if qa not set)
259
+ const testingStateChoices = testingStates.map((s) => ({
260
+ title: `${s.name} (${s.type})`,
261
+ value: s.name,
262
+ }));
251
263
  const testingChoices = [
252
264
  { title: "(None)", value: undefined },
253
- ...stateChoices,
265
+ ...testingStateChoices,
254
266
  ];
267
+ const testingMessage = qaStates && qaStates.length > 0
268
+ ? 'Select status for "Testing" (from QA team, for parent tasks):'
269
+ : 'Select status for "Testing" (optional, for parent tasks):';
255
270
  const testingResponse = await prompts({
256
271
  type: "select",
257
272
  name: "testing",
258
- message: 'Select status for "Testing" (optional, for parent tasks):',
273
+ message: testingMessage,
259
274
  choices: testingChoices,
260
- initial: defaults.testing
261
- ? testingChoices.findIndex((c) => c.value === defaults.testing)
275
+ initial: testingDefaults.testing
276
+ ? testingChoices.findIndex((c) => c.value === testingDefaults.testing)
262
277
  : 0,
263
278
  });
264
279
  const blockedChoices = [
265
280
  { title: "(None)", value: undefined },
266
- ...stateChoices,
281
+ ...devStateChoices,
267
282
  ];
268
283
  const blockedResponse = await prompts({
269
284
  type: "select",
270
285
  name: "blocked",
271
286
  message: 'Select status for "Blocked" (optional, for blocked tasks):',
272
287
  choices: blockedChoices,
273
- initial: defaults.blocked
274
- ? blockedChoices.findIndex((c) => c.value === defaults.blocked)
288
+ initial: devDefaults.blocked
289
+ ? blockedChoices.findIndex((c) => c.value === devDefaults.blocked)
275
290
  : 0,
276
291
  });
277
292
  return {
278
- todo: todoResponse.todo || defaults.todo,
279
- in_progress: inProgressResponse.in_progress || defaults.in_progress,
280
- done: doneResponse.done || defaults.done,
293
+ todo: todoResponse.todo || devDefaults.todo,
294
+ in_progress: inProgressResponse.in_progress || devDefaults.in_progress,
295
+ done: doneResponse.done || devDefaults.done,
281
296
  testing: testingResponse.testing,
282
297
  blocked: blockedResponse.blocked,
283
298
  };
@@ -526,10 +541,12 @@ async function init() {
526
541
  }
527
542
  // Fetch data from ALL teams (not just primary) to support cross-team operations
528
543
  console.log(` Fetching data from ${teams.length} teams...`);
529
- // Collect users, labels, states from all teams
544
+ // Collect users from all teams, but labels only from primary team
545
+ // States are stored per-team for status mapping selection
530
546
  const allUsers = [];
531
547
  const allLabels = [];
532
548
  const allStates = [];
549
+ const teamStatesMap = new Map(); // team.id -> states
533
550
  const seenUserIds = new Set();
534
551
  const seenLabelIds = new Set();
535
552
  const seenStateIds = new Set();
@@ -543,24 +560,31 @@ async function init() {
543
560
  allUsers.push(user);
544
561
  }
545
562
  }
546
- const labelsData = await client.issueLabels({
547
- filter: { team: { id: { eq: team.id } } },
548
- });
549
- for (const label of labelsData.nodes) {
550
- if (!seenLabelIds.has(label.id)) {
551
- seenLabelIds.add(label.id);
552
- allLabels.push(label);
563
+ // Labels: only from primary team (dev team)
564
+ if (team.id === primaryTeam.id) {
565
+ const labelsData = await client.issueLabels({
566
+ filter: { team: { id: { eq: team.id } } },
567
+ });
568
+ for (const label of labelsData.nodes) {
569
+ if (!seenLabelIds.has(label.id)) {
570
+ seenLabelIds.add(label.id);
571
+ allLabels.push(label);
572
+ }
553
573
  }
554
574
  }
575
+ // States: store per-team and also collect all
555
576
  const statesData = await client.workflowStates({
556
577
  filter: { team: { id: { eq: team.id } } },
557
578
  });
579
+ const teamStates = [];
558
580
  for (const state of statesData.nodes) {
581
+ teamStates.push(state);
559
582
  if (!seenStateIds.has(state.id)) {
560
583
  seenStateIds.add(state.id);
561
584
  allStates.push(state);
562
585
  }
563
586
  }
587
+ teamStatesMap.set(team.id, teamStates);
564
588
  }
565
589
  catch (error) {
566
590
  console.warn(` ⚠ Could not fetch data for team ${team.name}, skipping...`);
@@ -569,8 +593,10 @@ async function init() {
569
593
  const users = allUsers;
570
594
  const labels = allLabels;
571
595
  const states = allStates;
596
+ // Get team-specific states for status mapping
597
+ const primaryTeamStates = teamStatesMap.get(primaryTeam.id) || [];
572
598
  console.log(` Users: ${users.length}`);
573
- console.log(` Labels: ${labels.length}`);
599
+ console.log(` Labels: ${labels.length} (from ${primaryTeam.name})`);
574
600
  console.log(` Workflow states: ${states.length}`);
575
601
  // Get cycle from primary team (for current work tracking)
576
602
  const selectedTeam = await client.team(primaryTeam.id);
@@ -580,7 +606,9 @@ async function init() {
580
606
  const defaultLabel = await selectLabelFilter(labels, options);
581
607
  const statusSource = await selectStatusSource(options);
582
608
  const qaPmTeam = await selectQaPmTeam(teams, primaryTeam, options);
583
- const statusTransitions = await selectStatusMappings(states, options);
609
+ // Get qa team states for testing status mapping (fallback to primary team if not set)
610
+ const qaTeamStates = qaPmTeam ? teamStatesMap.get(qaPmTeam.id) : undefined;
611
+ const statusTransitions = await selectStatusMappings(primaryTeamStates, qaTeamStates, options);
584
612
  // Build config
585
613
  const config = buildConfig(teams, users, labels, states, statusTransitions, currentCycle ?? undefined);
586
614
  // Find keys
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "team-toon-tack",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Linear task sync & management CLI with TOON format",
5
5
  "type": "module",
6
6
  "bin": {