@atollhq/cli 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -41,7 +41,18 @@ atoll --org my-org issue list
41
41
  atoll --team eng issue create --title "..."
42
42
  ```
43
43
 
44
- Or via env vars: `ATOLL_API_KEY`, `ATOLL_ORG`, `ATOLL_TEAM`.
44
+ Or via env vars: `ATOLL_API_KEY`, `ATOLL_ORG`, `ATOLL_TEAM`, `ATOLL_BASE_URL`.
45
+
46
+ ## Output URLs
47
+
48
+ Issue and project JSON output includes a canonical `url` field pointing at the Atoll web app (honoring `ATOLL_BASE_URL` for self-hosted / local dev), suitable for pasting into standups, notifications, and follow-ups:
49
+
50
+ ```bash
51
+ atoll issue view ATOLL-42 | jq -r .url
52
+ # https://atollhq.com/acme/projects/atoll/issues/42
53
+ ```
54
+
55
+ `url` is `null` for orphan issues (no project) or missing identifiers, so consumers should handle that case.
45
56
 
46
57
  ## License
47
58
 
package/dist/index.js CHANGED
@@ -235,6 +235,30 @@ var RESET = isTTY() ? "\x1B[0m" : "";
235
235
  var BOLD = isTTY() ? "\x1B[1m" : "";
236
236
  var DIM = isTTY() ? "\x1B[2m" : "";
237
237
 
238
+ // src/lib/urls.ts
239
+ function derivePrefix(name) {
240
+ const cleaned = name.replace(/[^a-zA-Z0-9\s]/g, " ").trim();
241
+ const words = cleaned.split(/\s+/).filter(Boolean);
242
+ if (words.length === 0) return "TSK";
243
+ if (words.length >= 2) {
244
+ return words.slice(0, 5).map((w) => w[0]).join("").toUpperCase();
245
+ }
246
+ const word = words[0];
247
+ if (word.length <= 4) return word.toUpperCase();
248
+ return word.slice(0, 3).toUpperCase();
249
+ }
250
+ function stripTrailingSlash(baseUrl) {
251
+ return baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
252
+ }
253
+ function buildIssueUrl(baseUrl, orgSlug, projectSlug, issueNumber) {
254
+ if (!orgSlug || !projectSlug || issueNumber == null) return null;
255
+ return `${stripTrailingSlash(baseUrl)}/${orgSlug}/projects/${projectSlug}/issues/${issueNumber}`;
256
+ }
257
+ function buildProjectUrl(baseUrl, orgSlug, projectSlug) {
258
+ if (!orgSlug || !projectSlug) return null;
259
+ return `${stripTrailingSlash(baseUrl)}/${orgSlug}/projects/${projectSlug}`;
260
+ }
261
+
238
262
  // src/commands/issue.ts
239
263
  function handleApiError(err) {
240
264
  const msg = err.message ?? String(err);
@@ -249,30 +273,48 @@ function handleApiError(err) {
249
273
  }
250
274
  var VALID_STATUSES = ["backlog", "todo", "in_progress", "done", "cancelled"];
251
275
  var PRIORITY_LABELS = { 0: "Urgent", 1: "High", 2: "Medium", 3: "Low" };
252
- async function resolveOrgId(client, orgSlugOverride) {
276
+ async function resolveOrg(client, orgSlugOverride) {
253
277
  const { orgs } = await client.get("/api/orgs");
254
278
  if (!orgs || orgs.length === 0) {
255
279
  outputError("No organizations found. Create one first.");
256
280
  process.exit(1);
257
281
  }
258
- if (orgs.length === 1) return orgs[0].id;
282
+ if (orgs.length === 1) return orgs[0];
259
283
  const { readConfig: readConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
260
284
  const config = readConfig2();
261
285
  const slug = orgSlugOverride ?? process.env.ATOLL_ORG ?? config.orgSlug;
262
286
  if (slug) {
263
287
  const match = orgs.find((o) => o.slug === slug);
264
- if (match) return match.id;
288
+ if (match) return match;
265
289
  outputError(`Org "${slug}" not found. Available: ${orgs.map((o) => o.slug).join(", ")}`);
266
290
  process.exit(1);
267
291
  }
268
292
  outputError(`Multiple orgs found. Use --org <slug> or run \`atoll config set-org <slug>\`. Available: ${orgs.map((o) => o.slug).join(", ")}`);
269
293
  process.exit(1);
270
294
  }
295
+ async function resolveOrgId(client, orgSlugOverride) {
296
+ return (await resolveOrg(client, orgSlugOverride)).id;
297
+ }
298
+ async function fetchProjectMap(client, orgId) {
299
+ const { projects } = await client.get(
300
+ `/api/orgs/${orgId}/projects`
301
+ );
302
+ const map = /* @__PURE__ */ new Map();
303
+ for (const p of projects ?? []) map.set(p.id, p);
304
+ return map;
305
+ }
306
+ function attachIssueUrl(issue, baseUrl, orgSlug, projects) {
307
+ const project = issue.project_id ? projects.get(issue.project_id) : void 0;
308
+ return {
309
+ ...issue,
310
+ url: buildIssueUrl(baseUrl, orgSlug, project?.slug, issue.number ?? null)
311
+ };
312
+ }
271
313
  async function resolveIssueId(client, orgId, identifier) {
272
314
  if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(identifier)) {
273
315
  return identifier;
274
316
  }
275
- const match = identifier.match(/^(?:[A-Za-z]+-)?(\d+)$/);
317
+ const match = identifier.match(/^(?:[A-Za-z0-9]+-)?(\d+)$/);
276
318
  if (!match) {
277
319
  outputError(`Invalid identifier: "${identifier}". Use a UUID or PREFIX-NUMBER (e.g. ATOLL-42).`);
278
320
  process.exit(2);
@@ -298,8 +340,13 @@ async function resolveIssueId(client, orgId, identifier) {
298
340
  outputError(`Issue #${num} not found.`);
299
341
  process.exit(1);
300
342
  }
301
- function formatIdentifier(issue) {
302
- return issue.number != null ? `ATOLL-${issue.number}` : issue.id.slice(0, 8);
343
+ function formatIdentifier(issue, projects) {
344
+ if (issue.number == null) return issue.id.slice(0, 8);
345
+ if (projects && issue.project_id) {
346
+ const project = projects.get(issue.project_id);
347
+ if (project?.name) return `${derivePrefix(project.name)}-${issue.number}`;
348
+ }
349
+ return `ATOLL-${issue.number}`;
303
350
  }
304
351
  function padEnd(str, len) {
305
352
  return str.length >= len ? str.slice(0, len) : str + " ".repeat(len - str.length);
@@ -315,35 +362,41 @@ Examples:
315
362
  issueCommand.command("list").description("List issues").option("--status <status>", `Filter by status (${VALID_STATUSES.join(", ")})`).option("--assignee <user>", "Filter by assignee ID").option("--priority <n>", "Filter by priority (0=urgent, 1=high, 2=medium, 3=low)", parseInt).option("--limit <n>", "Max results (1-100)", parseInt).action(async (opts) => {
316
363
  try {
317
364
  const client = new AtollClient();
318
- const orgId = await resolveOrgId(client);
365
+ const org = await resolveOrg(client);
319
366
  const params = new URLSearchParams();
320
367
  if (opts.status) params.set("status", opts.status);
321
368
  if (opts.assignee) params.set("assigneeId", opts.assignee);
322
369
  if (opts.priority !== void 0) params.set("priority", String(opts.priority));
323
370
  if (opts.limit !== void 0) params.set("limit", String(opts.limit));
324
371
  const qs = params.toString();
325
- const data = await client.get(`/api/orgs/${orgId}/issues${qs ? `?${qs}` : ""}`);
372
+ const [data, projects] = await Promise.all([
373
+ client.get(`/api/orgs/${org.id}/issues${qs ? `?${qs}` : ""}`),
374
+ fetchProjectMap(client, org.id)
375
+ ]);
376
+ const enriched = data.issues.map(
377
+ (issue) => attachIssueUrl(issue, client.baseUrl, org.slug, projects)
378
+ );
326
379
  if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === "json") {
327
- for (const issue of data.issues) {
380
+ for (const issue of enriched) {
328
381
  process.stdout.write(JSON.stringify(issue) + "\n");
329
382
  }
330
383
  return;
331
384
  }
332
- if (data.issues.length === 0) {
385
+ if (enriched.length === 0) {
333
386
  console.log("No issues found.");
334
387
  return;
335
388
  }
336
389
  const header = bold(`${padEnd("ID", 10)} ${padEnd("STATUS", 14)} ${padEnd("PRI", 8)} TITLE`);
337
390
  console.log(header);
338
391
  console.log("\u2500".repeat(82));
339
- for (const issue of data.issues) {
340
- const id = formatIdentifier(issue);
392
+ for (const issue of enriched) {
393
+ const id = formatIdentifier(issue, projects);
341
394
  const pri = PRIORITY_LABELS[issue.priority] ?? String(issue.priority);
342
395
  const title = issue.title.length > 50 ? issue.title.slice(0, 47) + "\u2026" : issue.title;
343
396
  const icon = priorityIcon(issue.priority);
344
397
  console.log(`${padEnd(id, 10)} ${statusColor(issue.status, padEnd(issue.status, 14))} ${icon} ${padEnd(pri, 8)} ${title}`);
345
398
  }
346
- console.log(dim(`${data.issues.length} of ${data.total} issues`));
399
+ console.log(dim(`${enriched.length} of ${data.total} issues`));
347
400
  } catch (err) {
348
401
  handleApiError(err);
349
402
  }
@@ -351,33 +404,38 @@ issueCommand.command("list").description("List issues").option("--status <status
351
404
  issueCommand.command("view <identifier>").description("View issue details (UUID or PREFIX-NUMBER e.g. ATOLL-42)").action(async (identifier) => {
352
405
  try {
353
406
  const client = new AtollClient();
354
- const orgId = await resolveOrgId(client);
355
- const issueId = await resolveIssueId(client, orgId, identifier);
356
- const { issue } = await client.get(`/api/orgs/${orgId}/issues/${issueId}`);
407
+ const org = await resolveOrg(client);
408
+ const issueId = await resolveIssueId(client, org.id, identifier);
409
+ const [{ issue }, projects] = await Promise.all([
410
+ client.get(`/api/orgs/${org.id}/issues/${issueId}`),
411
+ fetchProjectMap(client, org.id)
412
+ ]);
413
+ const enriched = attachIssueUrl(issue, client.baseUrl, org.slug, projects);
357
414
  if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === "json") {
358
- process.stdout.write(JSON.stringify(issue) + "\n");
415
+ process.stdout.write(JSON.stringify(enriched) + "\n");
359
416
  return;
360
417
  }
361
- const id = formatIdentifier(issue);
362
- const pri = PRIORITY_LABELS[issue.priority] ?? String(issue.priority);
363
- console.log(`${bold(id)} ${issue.title}`);
364
- console.log(`Status: ${statusColor(issue.status, issue.status)} Priority: ${priorityIcon(issue.priority)} ${pri}`);
365
- if (issue.assignee_id) console.log(`Assignee: ${issue.assignee_id}`);
366
- if (issue.due_date) console.log(`Due: ${issue.due_date}`);
367
- if (issue.description) {
418
+ const id = formatIdentifier(enriched, projects);
419
+ const pri = PRIORITY_LABELS[enriched.priority] ?? String(enriched.priority);
420
+ console.log(`${bold(id)} ${enriched.title}`);
421
+ console.log(`Status: ${statusColor(enriched.status, enriched.status)} Priority: ${priorityIcon(enriched.priority)} ${pri}`);
422
+ if (enriched.url) console.log(`URL: ${enriched.url}`);
423
+ if (enriched.assignee_id) console.log(`Assignee: ${enriched.assignee_id}`);
424
+ if (enriched.due_date) console.log(`Due: ${enriched.due_date}`);
425
+ if (enriched.description) {
368
426
  console.log(`
369
- ${issue.description}`);
427
+ ${enriched.description}`);
370
428
  }
371
- if (issue.issue_labels && issue.issue_labels.length > 0) {
372
- const labels = issue.issue_labels.map((l) => l.labels.name).join(", ");
429
+ if (enriched.issue_labels && enriched.issue_labels.length > 0) {
430
+ const labels = enriched.issue_labels.map((l) => l.labels.name).join(", ");
373
431
  console.log(`Labels: ${labels}`);
374
432
  }
375
- if (issue.sub_tasks && Array.isArray(issue.sub_tasks) && issue.sub_tasks.length > 0) {
433
+ if (enriched.sub_tasks && Array.isArray(enriched.sub_tasks) && enriched.sub_tasks.length > 0) {
376
434
  console.log(`
377
- Subtasks: ${issue.sub_tasks.length}`);
435
+ Subtasks: ${enriched.sub_tasks.length}`);
378
436
  }
379
- if (issue.created_at) console.log(dim(`Created: ${issue.created_at}`));
380
- if (issue.updated_at) console.log(dim(`Updated: ${issue.updated_at}`));
437
+ if (enriched.created_at) console.log(dim(`Created: ${enriched.created_at}`));
438
+ if (enriched.updated_at) console.log(dim(`Updated: ${enriched.updated_at}`));
381
439
  } catch (err) {
382
440
  handleApiError(err);
383
441
  }
@@ -393,15 +451,18 @@ issueCommand.command("create").description("Create a new issue").requiredOption(
393
451
  process.exit(2);
394
452
  }
395
453
  const client = new AtollClient();
396
- const orgId = await resolveOrgId(client);
454
+ const org = await resolveOrg(client);
397
455
  const body = { title: opts.title };
398
456
  if (opts.description !== void 0) body.description = opts.description;
399
457
  if (opts.status) body.status = opts.status;
400
458
  if (opts.priority !== void 0) body.priority = opts.priority;
401
- const { issue } = await client.post(`/api/orgs/${orgId}/issues`, body);
459
+ const { issue } = await client.post(`/api/orgs/${org.id}/issues`, body);
460
+ const projects = await fetchProjectMap(client, org.id);
461
+ const enriched = attachIssueUrl(issue, client.baseUrl, org.slug, projects);
402
462
  output(
403
- { issue },
404
- success(`Created ${formatIdentifier(issue)}: ${issue.title}`)
463
+ { issue: enriched },
464
+ success(`Created ${formatIdentifier(enriched, projects)}: ${enriched.title}${enriched.url ? `
465
+ ${enriched.url}` : ""}`)
405
466
  );
406
467
  } catch (err) {
407
468
  handleApiError(err);
@@ -426,12 +487,14 @@ issueCommand.command("update <identifier>").description("Update an issue").optio
426
487
  process.exit(2);
427
488
  }
428
489
  const client = new AtollClient();
429
- const orgId = await resolveOrgId(client);
430
- const issueId = await resolveIssueId(client, orgId, identifier);
431
- const { issue } = await client.patch(`/api/orgs/${orgId}/issues/${issueId}`, body);
490
+ const org = await resolveOrg(client);
491
+ const issueId = await resolveIssueId(client, org.id, identifier);
492
+ const { issue } = await client.patch(`/api/orgs/${org.id}/issues/${issueId}`, body);
493
+ const projects = await fetchProjectMap(client, org.id);
494
+ const enriched = attachIssueUrl(issue, client.baseUrl, org.slug, projects);
432
495
  output(
433
- { issue },
434
- success(`Updated ${formatIdentifier(issue)}: ${issue.title}`)
496
+ { issue: enriched },
497
+ success(`Updated ${formatIdentifier(enriched, projects)}: ${enriched.title}`)
435
498
  );
436
499
  } catch (err) {
437
500
  handleApiError(err);
@@ -454,8 +517,8 @@ issueCommand.command("delete <identifier>").description("Delete an issue (admin/
454
517
  issueCommand.command("assign <identifier>").description("Assign an issue to a user or agent").requiredOption("--to <user>", 'User/agent ID or "self" for yourself').action(async (identifier, opts) => {
455
518
  try {
456
519
  const client = new AtollClient();
457
- const orgId = await resolveOrgId(client);
458
- const issueId = await resolveIssueId(client, orgId, identifier);
520
+ const org = await resolveOrg(client);
521
+ const issueId = await resolveIssueId(client, org.id, identifier);
459
522
  let assigneeId = opts.to;
460
523
  if (assigneeId === "self") {
461
524
  const me = await client.get("/api/auth/me");
@@ -465,7 +528,7 @@ issueCommand.command("assign <identifier>").description("Assign an issue to a us
465
528
  process.exit(1);
466
529
  }
467
530
  const { members } = await client.get(
468
- `/api/orgs/${orgId}/members`
531
+ `/api/orgs/${org.id}/members`
469
532
  );
470
533
  const member = members.find((m) => m.id === callerUserId || m.user_id === callerUserId);
471
534
  if (!member) {
@@ -475,12 +538,14 @@ issueCommand.command("assign <identifier>").description("Assign an issue to a us
475
538
  assigneeId = member.id;
476
539
  }
477
540
  const { issue } = await client.patch(
478
- `/api/orgs/${orgId}/issues/${issueId}`,
541
+ `/api/orgs/${org.id}/issues/${issueId}`,
479
542
  { assignee_id: assigneeId }
480
543
  );
544
+ const projects = await fetchProjectMap(client, org.id);
545
+ const enriched = attachIssueUrl(issue, client.baseUrl, org.slug, projects);
481
546
  output(
482
- { issue },
483
- success(`Assigned ${formatIdentifier(issue)} to ${opts.to}`)
547
+ { issue: enriched },
548
+ success(`Assigned ${formatIdentifier(enriched, projects)} to ${opts.to}`)
484
549
  );
485
550
  } catch (err) {
486
551
  handleApiError(err);
@@ -489,15 +554,17 @@ issueCommand.command("assign <identifier>").description("Assign an issue to a us
489
554
  issueCommand.command("unassign <identifier>").description("Remove assignee from an issue").action(async (identifier) => {
490
555
  try {
491
556
  const client = new AtollClient();
492
- const orgId = await resolveOrgId(client);
493
- const issueId = await resolveIssueId(client, orgId, identifier);
557
+ const org = await resolveOrg(client);
558
+ const issueId = await resolveIssueId(client, org.id, identifier);
494
559
  const { issue } = await client.patch(
495
- `/api/orgs/${orgId}/issues/${issueId}`,
560
+ `/api/orgs/${org.id}/issues/${issueId}`,
496
561
  { assignee_id: null }
497
562
  );
563
+ const projects = await fetchProjectMap(client, org.id);
564
+ const enriched = attachIssueUrl(issue, client.baseUrl, org.slug, projects);
498
565
  output(
499
- { issue },
500
- success(`Unassigned ${formatIdentifier(issue)}`)
566
+ { issue: enriched },
567
+ success(`Unassigned ${formatIdentifier(enriched, projects)}`)
501
568
  );
502
569
  } catch (err) {
503
570
  handleApiError(err);
@@ -602,6 +669,9 @@ commentCommand.command("delete <comment-id>").description("Delete a comment").re
602
669
 
603
670
  // src/commands/project.ts
604
671
  var import_commander4 = require("commander");
672
+ function attachProjectUrl(project, baseUrl, orgSlug) {
673
+ return { ...project, url: buildProjectUrl(baseUrl, orgSlug, project.slug) };
674
+ }
605
675
  function progressBar(progress, width = 20) {
606
676
  const filled = Math.round(progress / 100 * width);
607
677
  const empty = width - filled;
@@ -615,9 +685,9 @@ Examples:
615
685
  projectCommand.command("list").description("List all projects with progress").action(async () => {
616
686
  const client = new AtollClient();
617
687
  try {
618
- const orgId = await resolveOrgId(client);
619
- const data = await client.get(`/api/orgs/${orgId}/projects`);
620
- const projects = data.projects ?? [];
688
+ const org = await resolveOrg(client);
689
+ const data = await client.get(`/api/orgs/${org.id}/projects`);
690
+ const projects = (data.projects ?? []).map((p) => attachProjectUrl(p, client.baseUrl, org.slug));
621
691
  if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === "json") {
622
692
  for (const p of projects) {
623
693
  process.stdout.write(JSON.stringify(p) + "\n");
@@ -634,6 +704,7 @@ projectCommand.command("list").description("List all projects with progress").ac
634
704
  console.log(`${bold(`${p.icon} ${p.name}`)} ${dim(`(${p.id})`)}`);
635
705
  if (p.description) console.log(` ${dim(p.description)}`);
636
706
  console.log(` ${cyan(bar)} ${p.issueCount ?? 0} issues, ${p.completedCount ?? 0} done`);
707
+ if (p.url) console.log(` ${dim(p.url)}`);
637
708
  if (p.status === "archived") console.log(` ${dim("[archived]")}`);
638
709
  console.log("");
639
710
  }
@@ -644,16 +715,18 @@ projectCommand.command("list").description("List all projects with progress").ac
644
715
  projectCommand.command("create").description("Create a new project").requiredOption("--name <name>", "Project name").option("--description <desc>", "Project description").option("--color <color>", "Project color (hex)", "#6366f1").option("--icon <icon>", "Project icon (emoji)", "\u{1F4C1}").action(async (opts) => {
645
716
  const client = new AtollClient();
646
717
  try {
647
- const orgId = await resolveOrgId(client);
648
- const data = await client.post(`/api/orgs/${orgId}/projects`, {
718
+ const org = await resolveOrg(client);
719
+ const data = await client.post(`/api/orgs/${org.id}/projects`, {
649
720
  name: opts.name,
650
721
  description: opts.description ?? null,
651
722
  color: opts.color,
652
723
  icon: opts.icon
653
724
  });
725
+ const project = attachProjectUrl(data.project, client.baseUrl, org.slug);
654
726
  output(
655
- { project: data.project },
656
- success(`Created project ${data.project.icon} ${data.project.name} (${dim(data.project.id)})`)
727
+ { project },
728
+ success(`Created project ${project.icon} ${project.name} (${dim(project.id)})${project.url ? `
729
+ ${project.url}` : ""}`)
657
730
  );
658
731
  } catch (err) {
659
732
  handleApiError(err);
@@ -662,11 +735,11 @@ projectCommand.command("create").description("Create a new project").requiredOpt
662
735
  projectCommand.command("view <projectId>").description("View project details and issues").action(async (projectId) => {
663
736
  const client = new AtollClient();
664
737
  try {
665
- const orgId = await resolveOrgId(client);
738
+ const org = await resolveOrg(client);
666
739
  const data = await client.get(
667
- `/api/orgs/${orgId}/projects/${projectId}`
740
+ `/api/orgs/${org.id}/projects/${projectId}`
668
741
  );
669
- const p = data.project;
742
+ const p = attachProjectUrl(data.project, client.baseUrl, org.slug);
670
743
  if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === "json") {
671
744
  process.stdout.write(JSON.stringify(p) + "\n");
672
745
  return;
@@ -674,6 +747,7 @@ projectCommand.command("view <projectId>").description("View project details and
674
747
  const progress = p.progress ?? 0;
675
748
  console.log(bold(`${p.icon} ${p.name}`));
676
749
  if (p.description) console.log(` ${p.description}`);
750
+ if (p.url) console.log(` ${dim(p.url)}`);
677
751
  console.log(` ${cyan(progressBar(progress))}`);
678
752
  console.log(` ${p.issueCount ?? 0} issues \xB7 ${p.completedCount ?? 0} completed`);
679
753
  console.log("");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/config.ts","../src/index.ts","../src/commands/auth.ts","../src/lib/client.ts","../src/lib/output.ts","../src/commands/issue.ts","../src/lib/colors.ts","../src/commands/comment.ts","../src/commands/project.ts","../src/commands/milestone.ts","../src/commands/config.ts","../src/commands/webhook.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport interface AtollConfig {\n apiKey?: string;\n orgSlug?: string;\n defaultTeam?: string;\n}\n\nconst CONFIG_DIR = join(homedir(), '.atoll');\nconst CONFIG_PATH = join(CONFIG_DIR, 'config.json');\n\nexport function readConfig(): AtollConfig {\n if (!existsSync(CONFIG_PATH)) return {};\n try {\n return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));\n } catch {\n return {};\n }\n}\n\nexport function writeConfig(config: AtollConfig): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport function deleteConfig(): void {\n if (existsSync(CONFIG_PATH)) {\n unlinkSync(CONFIG_PATH);\n }\n}\n\nexport function getApiKey(): string | undefined {\n return process.env.ATOLL_API_KEY || readConfig().apiKey;\n}\n","import { Command } from 'commander';\nimport { authCommand } from './commands/auth.js';\nimport { issueCommand } from './commands/issue.js';\nimport { commentCommand } from './commands/comment.js';\nimport { projectCommand } from './commands/project.js';\nimport { milestoneCommand } from './commands/milestone.js';\nimport { configCommand } from './commands/config.js';\nimport { webhookCommand } from './commands/webhook.js';\n\nconst program = new Command('atoll')\n .description('Atoll CLI — project management from the terminal')\n .version('0.1.0')\n .addHelpText('after', `\nExamples:\n $ atoll issue list\n $ atoll issue create --title \"Fix login bug\" --priority 1\n $ atoll issue view ATOLL-42\n $ atoll project list\n $ atoll milestone list --project <id>\n $ atoll config show`)\n // Global overrides — passed via env vars so sub-commands can pick them up\n .option('--org <slug>', 'Override default org slug (env: ATOLL_ORG)')\n .option('--team <id>', 'Override default team slug/ID (env: ATOLL_TEAM)')\n .hook('preAction', (thisCommand) => {\n const opts = thisCommand.opts();\n if (opts.org) process.env.ATOLL_ORG = opts.org;\n if (opts.team) process.env.ATOLL_TEAM = opts.team;\n });\n\nprogram.addCommand(authCommand);\nprogram.addCommand(issueCommand);\nprogram.addCommand(commentCommand);\nprogram.addCommand(projectCommand);\nprogram.addCommand(milestoneCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(webhookCommand);\n\n// ── atoll completion ────────────────────────────────────────────────────────\n\nconst completionCommand = new Command('completion')\n .description('Output shell completion scripts')\n .addHelpText('after', `\nExamples:\n $ atoll completion bash >> ~/.bashrc\n $ atoll completion zsh >> ~/.zshrc`);\n\ncompletionCommand\n .command('bash')\n .description('Output bash completion script')\n .action(() => {\n process.stdout.write(bashCompletion());\n });\n\ncompletionCommand\n .command('zsh')\n .description('Output zsh completion script')\n .action(() => {\n process.stdout.write(zshCompletion());\n });\n\nprogram.addCommand(completionCommand);\n\nprogram.parse();\n\n// ---------------------------------------------------------------------------\n// Completion script generators\n// ---------------------------------------------------------------------------\n\nfunction bashCompletion(): string {\n return `# Atoll CLI bash completion\n# Add to ~/.bashrc: source <(atoll completion bash)\n\n_atoll_completions() {\n local cur prev words cword\n _init_completion || return\n\n local commands=\"auth issue comment project milestone config webhook completion\"\n local issue_cmds=\"list view create update delete assign unassign\"\n local project_cmds=\"list create view\"\n local milestone_cmds=\"list create\"\n local config_cmds=\"show set-org set-team\"\n local auth_cmds=\"login logout status\"\n local webhook_cmds=\"list create delete\"\n local completion_cmds=\"bash zsh\"\n\n if [ \"\\${COMP_CWORD}\" -eq 1 ]; then\n COMPREPLY=( $(compgen -W \"\\${commands}\" -- \"\\${cur}\") )\n return 0\n fi\n\n case \"\\${words[1]}\" in\n issue)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${issue_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n project)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${project_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n milestone)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${milestone_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n config)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${config_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n auth)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${auth_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n webhook)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${webhook_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n completion)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${completion_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n esac\n}\n\ncomplete -F _atoll_completions atoll\n`;\n}\n\nfunction zshCompletion(): string {\n return `#compdef atoll\n# Atoll CLI zsh completion\n# Add to ~/.zshrc: source <(atoll completion zsh)\n\n_atoll() {\n local state\n\n _arguments \\\\\n '1: :->command' \\\\\n '*: :->args'\n\n case \\$state in\n command)\n _values 'command' \\\\\n 'auth[Manage authentication]' \\\\\n 'issue[Manage issues]' \\\\\n 'comment[Manage comments]' \\\\\n 'project[Manage projects]' \\\\\n 'milestone[Manage milestones]' \\\\\n 'config[Manage CLI configuration]' \\\\\n 'webhook[Manage outbound webhooks]' \\\\\n 'completion[Output shell completion scripts]'\n ;;\n args)\n case \\$words[2] in\n issue)\n _values 'subcommand' \\\\\n 'list[List issues]' \\\\\n 'view[View issue details]' \\\\\n 'create[Create a new issue]' \\\\\n 'update[Update an issue]' \\\\\n 'delete[Delete an issue]' \\\\\n 'assign[Assign an issue]' \\\\\n 'unassign[Remove assignee]'\n ;;\n project)\n _values 'subcommand' \\\\\n 'list[List projects]' \\\\\n 'create[Create a project]' \\\\\n 'view[View project details]'\n ;;\n milestone)\n _values 'subcommand' \\\\\n 'list[List milestones]' \\\\\n 'create[Create a milestone]'\n ;;\n config)\n _values 'subcommand' \\\\\n 'show[Show configuration]' \\\\\n 'set-org[Set default org slug]' \\\\\n 'set-team[Set default team]'\n ;;\n auth)\n _values 'subcommand' \\\\\n 'login[Log in]' \\\\\n 'logout[Log out]' \\\\\n 'status[Show auth status]'\n ;;\n webhook)\n _values 'subcommand' \\\\\n 'list[List webhooks]' \\\\\n 'create[Create a webhook]' \\\\\n 'delete[Delete a webhook]'\n ;;\n completion)\n _values 'shell' 'bash' 'zsh'\n ;;\n esac\n ;;\n esac\n}\n\n_atoll \"\\$@\"\n`;\n}\n","import { Command } from 'commander';\nimport { readConfig, writeConfig, deleteConfig, getApiKey } from '../lib/config.js';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\n\nexport const authCommand = new Command('auth')\n .description('Manage authentication');\n\nauthCommand\n .command('login')\n .description('Save an API key to ~/.atoll/config.json')\n .requiredOption('--key <API_KEY>', 'API key to store')\n .action((opts: { key: string }) => {\n const config = readConfig();\n config.apiKey = opts.key;\n writeConfig(config);\n output(\n { status: 'ok', message: 'API key saved' },\n '✓ API key saved to ~/.atoll/config.json',\n );\n });\n\nauthCommand\n .command('status')\n .description('Show current auth status and user info')\n .action(async () => {\n const apiKey = getApiKey();\n if (!apiKey) {\n outputError('Not authenticated. Run `atoll auth login --key <API_KEY>` or set ATOLL_API_KEY.');\n process.exit(1);\n }\n\n try {\n const client = new AtollClient({ apiKey });\n const me = await client.get<{\n user?: { email?: string; name?: string };\n org?: { slug?: string; name?: string };\n }>('/api/auth/me');\n\n output(\n { status: 'authenticated', ...me },\n [\n '✓ Authenticated',\n me.user?.name ? ` User: ${me.user.name}` : null,\n me.user?.email ? ` Email: ${me.user.email}` : null,\n me.org?.name ? ` Org: ${me.org.name} (${me.org.slug})` : null,\n ]\n .filter(Boolean)\n .join('\\n'),\n );\n } catch (err) {\n const msg = (err as Error).message || '';\n if (/API (401|403):/.test(msg)) {\n outputError('API key is invalid or expired');\n process.exit(1);\n }\n outputError(`Auth check failed: ${msg}`);\n process.exit(1);\n }\n });\n\nauthCommand\n .command('logout')\n .description('Remove stored API key')\n .action(() => {\n // Only clear the API key — preserve org/team config settings\n const config = readConfig();\n delete config.apiKey;\n writeConfig(config);\n output(\n { status: 'ok', message: 'Logged out' },\n '✓ Logged out — API key removed (org/team config preserved)',\n );\n });\n","import { getApiKey } from './config.js';\nimport { outputError } from './output.js';\n\nconst DEFAULT_BASE_URL = 'https://atollhq.com';\n\nexport class AtollClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(opts?: { baseUrl?: string; apiKey?: string }) {\n this.baseUrl = opts?.baseUrl || process.env.ATOLL_BASE_URL || DEFAULT_BASE_URL;\n\n const key = opts?.apiKey || getApiKey();\n if (!key) {\n outputError('No API key found. Run `atoll auth login --key <API_KEY>` or set ATOLL_API_KEY.');\n process.exit(1);\n }\n this.apiKey = key;\n }\n\n async request<T = unknown>(path: string, init?: RequestInit): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const res = await fetch(url, {\n ...init,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n ...init?.headers,\n },\n });\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`API ${res.status}: ${body}`);\n }\n\n return res.json() as Promise<T>;\n }\n\n async get<T = unknown>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'GET' });\n }\n\n async post<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async patch<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'PATCH',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async delete<T = unknown>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'DELETE' });\n }\n}\n","export type OutputRecord = Record<string, unknown>;\n\nfunction isJsonMode(): boolean {\n if (process.env.OUTPUT_FORMAT === 'json') return true;\n return !process.stdout.isTTY;\n}\n\nexport function output(data: OutputRecord, humanReadable: string): void {\n if (isJsonMode()) {\n process.stdout.write(JSON.stringify(data) + '\\n');\n } else {\n console.log(humanReadable);\n }\n}\n\nexport function outputError(message: string): void {\n if (isJsonMode()) {\n process.stdout.write(JSON.stringify({ error: message }) + '\\n');\n } else {\n console.error(`Error: ${message}`);\n }\n}\n","import { Command } from 'commander';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\nimport { bold, dim, gray, statusColor, priorityIcon, success } from '../lib/colors.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface Issue {\n id: string;\n title: string;\n description?: string | null;\n status: string;\n priority: number;\n number?: number | null;\n assignee_id?: string | null;\n team_id?: string | null;\n project_id?: string | null;\n due_date?: string | null;\n created_at?: string;\n updated_at?: string;\n sub_tasks?: unknown[];\n issue_labels?: { label_id: string; labels: { name: string; color: string } }[];\n}\n\ninterface ListResponse {\n issues: Issue[];\n total: number;\n limit: number;\n offset: number;\n}\n\ninterface SingleResponse {\n issue: Issue;\n}\n\ninterface Org {\n id: string;\n name: string;\n slug: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nexport function handleApiError(err: unknown): never {\n const msg = (err as Error).message ?? String(err);\n if (/API 401\\b/.test(msg)) {\n outputError('Session expired — run `atoll auth login` to re-authenticate.');\n } else if (/API 403\\b/.test(msg)) {\n outputError('Permission denied. You do not have access to this resource.');\n } else {\n outputError(msg);\n }\n process.exit(1);\n}\n\nconst VALID_STATUSES = ['backlog', 'todo', 'in_progress', 'done', 'cancelled'] as const;\nconst PRIORITY_LABELS: Record<number, string> = { 0: 'Urgent', 1: 'High', 2: 'Medium', 3: 'Low' };\n\nexport async function resolveOrgId(client: AtollClient, orgSlugOverride?: string): Promise<string> {\n const { orgs } = await client.get<{ orgs: Org[] }>('/api/orgs');\n if (!orgs || orgs.length === 0) {\n outputError('No organizations found. Create one first.');\n process.exit(1);\n }\n if (orgs.length === 1) return orgs[0].id;\n\n // Resolve slug: CLI override → env var (set by --org global flag) → config file\n const { readConfig } = await import('../lib/config.js');\n const config = readConfig();\n const slug = orgSlugOverride ?? process.env.ATOLL_ORG ?? config.orgSlug;\n\n if (slug) {\n const match = orgs.find((o) => o.slug === slug);\n if (match) return match.id;\n outputError(`Org \"${slug}\" not found. Available: ${orgs.map((o) => o.slug).join(', ')}`);\n process.exit(1);\n }\n outputError(`Multiple orgs found. Use --org <slug> or run \\`atoll config set-org <slug>\\`. Available: ${orgs.map((o) => o.slug).join(', ')}`);\n process.exit(1);\n}\n\n/**\n * Resolve a human-readable identifier (e.g. \"ATOLL-42\" or \"42\") to a UUID.\n * Falls back to treating the identifier as a UUID if it doesn't match the pattern.\n */\nexport async function resolveIssueId(client: AtollClient, orgId: string, identifier: string): Promise<string> {\n // If it looks like a UUID already, return as-is\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(identifier)) {\n return identifier;\n }\n\n // Extract number from PREFIX-NUMBER or plain number\n const match = identifier.match(/^(?:[A-Za-z]+-)?(\\d+)$/);\n if (!match) {\n outputError(`Invalid identifier: \"${identifier}\". Use a UUID or PREFIX-NUMBER (e.g. ATOLL-42).`);\n process.exit(2);\n }\n\n const num = parseInt(match[1], 10);\n\n // Use number filter to avoid pagination issues with large issue lists\n const { issues } = await client.get<ListResponse>(\n `/api/orgs/${orgId}/issues?number=${num}&limit=1`,\n );\n if (issues.length > 0 && issues[0].number === num) {\n return issues[0].id;\n }\n\n // Fallback: paginate through all issues if the API doesn't support ?number= filtering\n let offset = 0;\n const pageSize = 100;\n while (true) {\n const page = await client.get<ListResponse>(\n `/api/orgs/${orgId}/issues?limit=${pageSize}&offset=${offset}`,\n );\n const found = page.issues.find((i) => i.number === num);\n if (found) return found.id;\n offset += pageSize;\n if (offset >= page.total) break;\n }\n\n outputError(`Issue #${num} not found.`);\n process.exit(1);\n}\n\nfunction formatIdentifier(issue: Issue): string {\n return issue.number != null ? `ATOLL-${issue.number}` : issue.id.slice(0, 8);\n}\n\nfunction padEnd(str: string, len: number): string {\n return str.length >= len ? str.slice(0, len) : str + ' '.repeat(len - str.length);\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\nexport const issueCommand = new Command('issue')\n .description('Manage issues')\n .addHelpText('after', `\nExamples:\n $ atoll issue list\n $ atoll issue list --status in_progress --priority 1\n $ atoll issue view ATOLL-42\n $ atoll issue create --title \"Fix login\" --priority 1 --status todo\n $ atoll issue update ATOLL-42 --status done\n $ atoll issue assign ATOLL-42 --to <user-id>`);\n\n// ---- list ----\nissueCommand\n .command('list')\n .description('List issues')\n .option('--status <status>', `Filter by status (${VALID_STATUSES.join(', ')})`)\n .option('--assignee <user>', 'Filter by assignee ID')\n .option('--priority <n>', 'Filter by priority (0=urgent, 1=high, 2=medium, 3=low)', parseInt)\n .option('--limit <n>', 'Max results (1-100)', parseInt)\n .action(async (opts: { status?: string; assignee?: string; priority?: number; limit?: number }) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n\n const params = new URLSearchParams();\n if (opts.status) params.set('status', opts.status);\n if (opts.assignee) params.set('assigneeId', opts.assignee);\n if (opts.priority !== undefined) params.set('priority', String(opts.priority));\n if (opts.limit !== undefined) params.set('limit', String(opts.limit));\n\n const qs = params.toString();\n const data = await client.get<ListResponse>(`/api/orgs/${orgId}/issues${qs ? `?${qs}` : ''}`);\n\n // JSON mode: NDJSON\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n for (const issue of data.issues) {\n process.stdout.write(JSON.stringify(issue) + '\\n');\n }\n return;\n }\n\n // TTY: table\n if (data.issues.length === 0) {\n console.log('No issues found.');\n return;\n }\n\n const header = bold(`${padEnd('ID', 10)} ${padEnd('STATUS', 14)} ${padEnd('PRI', 8)} TITLE`);\n console.log(header);\n console.log('─'.repeat(82));\n for (const issue of data.issues) {\n const id = formatIdentifier(issue);\n const pri = PRIORITY_LABELS[issue.priority] ?? String(issue.priority);\n const title = issue.title.length > 50 ? issue.title.slice(0, 47) + '…' : issue.title;\n const icon = priorityIcon(issue.priority);\n console.log(`${padEnd(id, 10)} ${statusColor(issue.status, padEnd(issue.status, 14))} ${icon} ${padEnd(pri, 8)} ${title}`);\n }\n console.log(dim(`${data.issues.length} of ${data.total} issues`));\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- view ----\nissueCommand\n .command('view <identifier>')\n .description('View issue details (UUID or PREFIX-NUMBER e.g. ATOLL-42)')\n .action(async (identifier: string) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, identifier);\n\n const { issue } = await client.get<SingleResponse>(`/api/orgs/${orgId}/issues/${issueId}`);\n\n // JSON mode\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n process.stdout.write(JSON.stringify(issue) + '\\n');\n return;\n }\n\n // TTY: formatted detail\n const id = formatIdentifier(issue);\n const pri = PRIORITY_LABELS[issue.priority] ?? String(issue.priority);\n console.log(`${bold(id)} ${issue.title}`);\n console.log(`Status: ${statusColor(issue.status, issue.status)} Priority: ${priorityIcon(issue.priority)} ${pri}`);\n if (issue.assignee_id) console.log(`Assignee: ${issue.assignee_id}`);\n if (issue.due_date) console.log(`Due: ${issue.due_date}`);\n if (issue.description) {\n console.log(`\\n${issue.description}`);\n }\n if (issue.issue_labels && issue.issue_labels.length > 0) {\n const labels = issue.issue_labels.map((l) => l.labels.name).join(', ');\n console.log(`Labels: ${labels}`);\n }\n if (issue.sub_tasks && Array.isArray(issue.sub_tasks) && issue.sub_tasks.length > 0) {\n console.log(`\\nSubtasks: ${issue.sub_tasks.length}`);\n }\n if (issue.created_at) console.log(dim(`Created: ${issue.created_at}`));\n if (issue.updated_at) console.log(dim(`Updated: ${issue.updated_at}`));\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- create ----\nissueCommand\n .command('create')\n .description('Create a new issue')\n .requiredOption('--title <title>', 'Issue title')\n .option('--description <text>', 'Issue description')\n .option('--status <status>', `Status (${VALID_STATUSES.join(', ')})`)\n .option('--priority <n>', 'Priority (0=urgent, 1=high, 2=medium, 3=low)', parseInt)\n .action(async (opts: { title: string; description?: string; status?: string; priority?: number }) => {\n try {\n if (opts.status && !VALID_STATUSES.includes(opts.status as typeof VALID_STATUSES[number])) {\n outputError(`Invalid status \"${opts.status}\". Must be one of: ${VALID_STATUSES.join(', ')}`);\n process.exit(2);\n }\n if (opts.priority !== undefined && ![0, 1, 2, 3].includes(opts.priority)) {\n outputError('Priority must be 0 (urgent), 1 (high), 2 (medium), or 3 (low).');\n process.exit(2);\n }\n\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n\n const body: Record<string, unknown> = { title: opts.title };\n if (opts.description !== undefined) body.description = opts.description;\n if (opts.status) body.status = opts.status;\n if (opts.priority !== undefined) body.priority = opts.priority;\n\n const { issue } = await client.post<SingleResponse>(`/api/orgs/${orgId}/issues`, body);\n\n output(\n { issue },\n success(`Created ${formatIdentifier(issue)}: ${issue.title}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- update ----\nissueCommand\n .command('update <identifier>')\n .description('Update an issue')\n .option('--title <t>', 'New title')\n .option('--status <s>', `New status (${VALID_STATUSES.join(', ')})`)\n .option('--priority <p>', 'New priority (0-3)', parseInt)\n .action(async (identifier: string, opts: { title?: string; status?: string; priority?: number }) => {\n try {\n if (opts.status && !VALID_STATUSES.includes(opts.status as typeof VALID_STATUSES[number])) {\n outputError(`Invalid status \"${opts.status}\". Must be one of: ${VALID_STATUSES.join(', ')}`);\n process.exit(2);\n }\n if (opts.priority !== undefined && ![0, 1, 2, 3].includes(opts.priority)) {\n outputError('Priority must be 0-3.');\n process.exit(2);\n }\n\n const body: Record<string, unknown> = {};\n if (opts.title !== undefined) body.title = opts.title;\n if (opts.status) body.status = opts.status;\n if (opts.priority !== undefined) body.priority = opts.priority;\n\n if (Object.keys(body).length === 0) {\n outputError('No fields to update. Provide --title, --status, or --priority.');\n process.exit(2);\n }\n\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, identifier);\n\n const { issue } = await client.patch<SingleResponse>(`/api/orgs/${orgId}/issues/${issueId}`, body);\n\n output(\n { issue },\n success(`Updated ${formatIdentifier(issue)}: ${issue.title}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- delete ----\nissueCommand\n .command('delete <identifier>')\n .description('Delete an issue (admin/owner only)')\n .action(async (identifier: string) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, identifier);\n\n await client.delete(`/api/orgs/${orgId}/issues/${issueId}`);\n\n output(\n { success: true, id: issueId },\n success(`Deleted issue ${identifier}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- assign ----\nissueCommand\n .command('assign <identifier>')\n .description('Assign an issue to a user or agent')\n .requiredOption('--to <user>', 'User/agent ID or \"self\" for yourself')\n .action(async (identifier: string, opts: { to: string }) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, identifier);\n\n let assigneeId = opts.to;\n if (assigneeId === 'self') {\n const me = await client.get<{ auth?: { userId?: string } }>('/api/auth/me');\n // For agent keys, auth.userId IS the org_members.id directly\n const callerUserId = me.auth?.userId;\n if (!callerUserId) {\n outputError('Could not resolve your user ID.');\n process.exit(1);\n }\n // Agent callers: userId is the member id — use directly\n // Human callers: userId is the supabase auth id — look up member id\n const { members } = await client.get<{ members: { id: string; user_id: string }[] }>(\n `/api/orgs/${orgId}/members`,\n );\n const member = members.find((m) => m.id === callerUserId || m.user_id === callerUserId);\n if (!member) {\n outputError('You are not a member of this organisation.');\n process.exit(1);\n }\n assigneeId = member.id;\n }\n\n const { issue } = await client.patch<SingleResponse>(\n `/api/orgs/${orgId}/issues/${issueId}`,\n { assignee_id: assigneeId },\n );\n\n output(\n { issue },\n success(`Assigned ${formatIdentifier(issue)} to ${opts.to}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- unassign ----\nissueCommand\n .command('unassign <identifier>')\n .description('Remove assignee from an issue')\n .action(async (identifier: string) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, identifier);\n\n const { issue } = await client.patch<SingleResponse>(\n `/api/orgs/${orgId}/issues/${issueId}`,\n { assignee_id: null },\n );\n\n output(\n { issue },\n success(`Unassigned ${formatIdentifier(issue)}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n","/**\n * TTY-aware ANSI color helpers.\n * Colors are only emitted when stdout is a TTY and OUTPUT_FORMAT !== 'json'.\n */\n\nfunction isTTY(): boolean {\n return process.stdout.isTTY === true && process.env.OUTPUT_FORMAT !== 'json';\n}\n\nfunction ansi(code: string, text: string): string {\n if (!isTTY()) return text;\n return `\\x1b[${code}m${text}\\x1b[0m`;\n}\n\n// Basic colors\nexport const bold = (t: string) => ansi('1', t);\nexport const dim = (t: string) => ansi('2', t);\nexport const red = (t: string) => ansi('31', t);\nexport const green = (t: string) => ansi('32', t);\nexport const yellow = (t: string) => ansi('33', t);\nexport const blue = (t: string) => ansi('34', t);\nexport const cyan = (t: string) => ansi('36', t);\nexport const gray = (t: string) => ansi('90', t);\nexport const white = (t: string) => ansi('37', t);\n\n// Status badge colors\nexport function statusColor(status: string, text: string): string {\n switch (status) {\n case 'done': return green(text);\n case 'in_progress': return yellow(text);\n case 'backlog':\n case 'todo': return gray(text);\n case 'cancelled': return red(text);\n default: return text;\n }\n}\n\n// Priority icons\nexport function priorityIcon(priority: number): string {\n switch (priority) {\n case 0: return red('⚠⚠⚠'); // urgent\n case 1: return yellow('▄▆█'); // high\n case 2: return cyan('▄▆'); // medium\n case 3: return dim('---'); // low\n default: return String(priority);\n }\n}\n\n// Helpers\nexport const success = (msg: string) => green(`✓ ${msg}`);\nexport const error = (msg: string) => red(`Error: ${msg}`);\n\n// Raw ANSI codes (for use in format strings where needed)\nexport const RESET = isTTY() ? '\\x1b[0m' : '';\nexport const BOLD = isTTY() ? '\\x1b[1m' : '';\nexport const DIM = isTTY() ? '\\x1b[2m' : '';\n","import { Command } from 'commander';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\nimport { handleApiError, resolveOrgId, resolveIssueId } from './issue.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface CommentAuthor {\n id: string;\n display_name: string;\n type: string;\n avatar_url?: string;\n}\n\ninterface Comment {\n id: string;\n body: string;\n author_id: string;\n author_type?: string;\n author?: CommentAuthor;\n created_at?: string;\n updated_at?: string;\n}\n\ninterface ListCommentsResponse {\n comments: Comment[];\n}\n\ninterface SingleCommentResponse {\n comment: Comment;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\nconst CYAN = '\\x1b[36m';\n\nfunction formatAuthor(comment: Comment): string {\n const name = comment.author?.display_name ?? comment.author_id;\n const badge = (comment.author?.type ?? comment.author_type) === 'agent' ? ' [agent]' : '';\n return `${name}${badge}`;\n}\n\nfunction formatTimestamp(ts?: string): string {\n if (!ts) return '';\n const d = new Date(ts);\n return d.toLocaleString();\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\nexport const commentCommand = new Command('comment')\n .description('Manage issue comments');\n\n// ---- list ----\ncommentCommand\n .command('list <identifier>')\n .description('List comments on an issue (UUID or PREFIX-NUMBER e.g. ATOLL-42)')\n .action(async (identifier: string) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, identifier);\n\n const data = await client.get<ListCommentsResponse>(\n `/api/orgs/${orgId}/issues/${issueId}/comments`,\n );\n\n // JSON mode: NDJSON\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n for (const comment of data.comments) {\n process.stdout.write(JSON.stringify(comment) + '\\n');\n }\n return;\n }\n\n // TTY: human-readable\n if (data.comments.length === 0) {\n console.log('No comments found.');\n return;\n }\n\n for (const comment of data.comments) {\n const author = formatAuthor(comment);\n const time = formatTimestamp(comment.created_at);\n console.log(`${BOLD}${CYAN}${author}${RESET} ${DIM}${time}${RESET}`);\n console.log(comment.body);\n console.log();\n }\n console.log(`${DIM}${data.comments.length} comment(s)${RESET}`);\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- add ----\ncommentCommand\n .command('add <identifier>')\n .description('Add a comment to an issue')\n .requiredOption('--body <text>', 'Comment body')\n .action(async (identifier: string, opts: { body: string }) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, identifier);\n\n const { comment } = await client.post<SingleCommentResponse>(\n `/api/orgs/${orgId}/issues/${issueId}/comments`,\n { body: opts.body },\n );\n\n output(\n { comment },\n `✓ Comment added to ${identifier}`,\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- update ----\ncommentCommand\n .command('update <comment-id>')\n .description('Update a comment')\n .requiredOption('--body <text>', 'New comment body')\n .requiredOption('--issue <identifier>', 'Issue identifier (e.g. UUID or PREFIX-NUMBER)')\n .action(async (commentId: string, opts: { body: string; issue: string }) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, opts.issue);\n\n const { comment } = await client.patch<SingleCommentResponse>(\n `/api/orgs/${orgId}/issues/${issueId}/comments/${commentId}`,\n { body: opts.body },\n );\n\n output(\n { comment },\n `✓ Comment ${commentId} updated`,\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- delete ----\ncommentCommand\n .command('delete <comment-id>')\n .description('Delete a comment')\n .requiredOption('--issue <identifier>', 'Issue identifier (e.g. UUID or PREFIX-NUMBER)')\n .action(async (commentId: string, opts: { issue: string }) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, opts.issue);\n\n await client.delete(`/api/orgs/${orgId}/issues/${issueId}/comments/${commentId}`);\n\n output(\n { success: true, id: commentId },\n `✓ Comment ${commentId} deleted`,\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n","import { Command } from 'commander';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\nimport { resolveOrgId, handleApiError } from './issue.js';\nimport { bold, dim, cyan, green, success } from '../lib/colors.js';\n\ninterface Project {\n id: string;\n name: string;\n description?: string | null;\n status: 'active' | 'archived';\n color: string;\n icon: string;\n issueCount?: number;\n completedCount?: number;\n progress?: number;\n created_at?: string;\n}\n\ninterface Issue {\n id: string;\n title: string;\n status: string;\n priority: number;\n number?: number | null;\n}\n\nfunction progressBar(progress: number, width = 20): string {\n const filled = Math.round((progress / 100) * width);\n const empty = width - filled;\n return `[${'█'.repeat(filled)}${'░'.repeat(empty)}] ${progress}%`;\n}\n\nexport const projectCommand = new Command('project')\n .description('Manage projects')\n .addHelpText('after', `\nExamples:\n $ atoll project list\n $ atoll project create --name \"My Project\" --icon 🚀\n $ atoll project view <project-id>`);\n\n// ── atoll project list ──────────────────────────────────────────────────────\n\nprojectCommand\n .command('list')\n .description('List all projects with progress')\n .action(async () => {\n const client = new AtollClient();\n try {\n const orgId = await resolveOrgId(client);\n const data = await client.get<{ projects: Project[] }>(`/api/orgs/${orgId}/projects`);\n const projects = data.projects ?? [];\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n for (const p of projects) {\n process.stdout.write(JSON.stringify(p) + '\\n');\n }\n return;\n }\n\n if (projects.length === 0) {\n console.log(dim('No projects found.'));\n return;\n }\n\n for (const p of projects) {\n const progress = p.progress ?? 0;\n const bar = progressBar(progress);\n console.log(`${bold(`${p.icon} ${p.name}`)} ${dim(`(${p.id})`)}`);\n if (p.description) console.log(` ${dim(p.description)}`);\n console.log(` ${cyan(bar)} ${p.issueCount ?? 0} issues, ${p.completedCount ?? 0} done`);\n if (p.status === 'archived') console.log(` ${dim('[archived]')}`);\n console.log('');\n }\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ── atoll project create ────────────────────────────────────────────────────\n\nprojectCommand\n .command('create')\n .description('Create a new project')\n .requiredOption('--name <name>', 'Project name')\n .option('--description <desc>', 'Project description')\n .option('--color <color>', 'Project color (hex)', '#6366f1')\n .option('--icon <icon>', 'Project icon (emoji)', '📁')\n .action(async (opts) => {\n const client = new AtollClient();\n try {\n const orgId = await resolveOrgId(client);\n const data = await client.post<{ project: Project }>(`/api/orgs/${orgId}/projects`, {\n name: opts.name,\n description: opts.description ?? null,\n color: opts.color,\n icon: opts.icon,\n });\n\n output(\n { project: data.project },\n success(`Created project ${data.project.icon} ${data.project.name} (${dim(data.project.id)})`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ── atoll project view ──────────────────────────────────────────────────────\n\nprojectCommand\n .command('view <projectId>')\n .description('View project details and issues')\n .action(async (projectId) => {\n const client = new AtollClient();\n try {\n const orgId = await resolveOrgId(client);\n const data = await client.get<{ project: Project & { issues: Issue[] } }>(\n `/api/orgs/${orgId}/projects/${projectId}`,\n );\n const p = data.project;\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n process.stdout.write(JSON.stringify(p) + '\\n');\n return;\n }\n\n const progress = p.progress ?? 0;\n console.log(bold(`${p.icon} ${p.name}`));\n if (p.description) console.log(` ${p.description}`);\n console.log(` ${cyan(progressBar(progress))}`);\n console.log(` ${(p.issueCount ?? 0)} issues · ${(p.completedCount ?? 0)} completed`);\n console.log('');\n\n const issues: Issue[] = (p as unknown as { issues?: Issue[] }).issues ?? [];\n if (issues.length === 0) {\n console.log(dim('No issues in this project.'));\n return;\n }\n\n console.log(bold('Issues'));\n for (const issue of issues) {\n const num = issue.number ? `#${issue.number}` : issue.id.slice(0, 8);\n console.log(` ${dim(num)} ${issue.title} ${dim(`[${issue.status}]`)}`);\n }\n } catch (err) {\n handleApiError(err);\n }\n });\n","import { Command } from 'commander';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\nimport { resolveOrgId, handleApiError } from './issue.js';\nimport { bold, dim, cyan, red, success } from '../lib/colors.js';\n\ninterface Milestone {\n id: string;\n name: string;\n description?: string | null;\n due_date?: string | null;\n status: 'active' | 'closed';\n issueCount?: number;\n completedCount?: number;\n progress?: number;\n isOverdue?: boolean;\n}\n\nfunction progressBar(progress: number, width = 20): string {\n const filled = Math.round((progress / 100) * width);\n const empty = width - filled;\n return `[${'█'.repeat(filled)}${'░'.repeat(empty)}] ${progress}%`;\n}\n\nexport const milestoneCommand = new Command('milestone')\n .description('Manage milestones')\n .addHelpText('after', `\nExamples:\n $ atoll milestone list --project <project-id>\n $ atoll milestone create --project <project-id> --name \"v1.0\" --date 2026-06-01`);\n\n// ── atoll milestone list ────────────────────────────────────────────────────\n\nmilestoneCommand\n .command('list')\n .description('List milestones for a project')\n .requiredOption('--project <id>', 'Project ID')\n .action(async (opts) => {\n const client = new AtollClient();\n try {\n const orgId = await resolveOrgId(client);\n const data = await client.get<{ milestones: Milestone[] }>(\n `/api/orgs/${orgId}/projects/${opts.project}/milestones`,\n );\n const milestones = data.milestones ?? [];\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n for (const m of milestones) {\n process.stdout.write(JSON.stringify(m) + '\\n');\n }\n return;\n }\n\n if (milestones.length === 0) {\n console.log(dim('No milestones found.'));\n return;\n }\n\n for (const m of milestones) {\n const progress = m.progress ?? 0;\n const bar = progressBar(progress);\n const overdue = m.isOverdue ? ` ${red('[OVERDUE]')}` : '';\n console.log(`${bold(m.name)} ${dim(`(${m.id})`)}${overdue}`);\n if (m.due_date) console.log(` Due: ${m.due_date}`);\n if (m.description) console.log(` ${dim(m.description)}`);\n console.log(` ${cyan(bar)} ${m.issueCount ?? 0} issues, ${m.completedCount ?? 0} done`);\n if (m.status === 'closed') console.log(` ${dim('[closed]')}`);\n console.log('');\n }\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ── atoll milestone create ──────────────────────────────────────────────────\n\nmilestoneCommand\n .command('create')\n .description('Create a new milestone')\n .requiredOption('--project <id>', 'Project ID')\n .requiredOption('--name <name>', 'Milestone name')\n .option('--date <YYYY-MM-DD>', 'Due date')\n .option('--description <desc>', 'Description')\n .action(async (opts) => {\n const client = new AtollClient();\n try {\n const orgId = await resolveOrgId(client);\n const data = await client.post<{ milestone: Milestone }>(\n `/api/orgs/${orgId}/projects/${opts.project}/milestones`,\n {\n name: opts.name,\n description: opts.description ?? null,\n dueDate: opts.date ?? null,\n },\n );\n\n output(\n { milestone: data.milestone },\n success(`Milestone created: ${bold(data.milestone.name)} ${dim(`(${data.milestone.id})`)}`),\n );\n if (data.milestone.due_date) {\n console.log(` Due: ${data.milestone.due_date}`);\n }\n } catch (err) {\n handleApiError(err);\n }\n });\n","import { Command } from 'commander';\nimport { readConfig, writeConfig } from '../lib/config.js';\nimport { output, outputError } from '../lib/output.js';\nimport { success, bold, dim, gray } from '../lib/colors.js';\nimport { getApiKey } from '../lib/config.js';\n\nexport const configCommand = new Command('config')\n .description('Manage CLI configuration (org, team, API key)')\n .addHelpText('after', `\nExamples:\n $ atoll config show\n $ atoll config set-org my-org\n $ atoll config set-team team-abc123`);\n\n// ── atoll config show ───────────────────────────────────────────────────────\n\nconfigCommand\n .command('show')\n .description('Display current configuration')\n .action(() => {\n const cfg = readConfig();\n const apiKeySet = !!(process.env.ATOLL_API_KEY || cfg.apiKey);\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n output(\n {\n orgSlug: cfg.orgSlug ?? null,\n defaultTeam: cfg.defaultTeam ?? null,\n apiKeySet,\n },\n '',\n );\n return;\n }\n\n console.log(`${bold('Atoll CLI Configuration')}`);\n console.log(` ${dim('Org slug:')} ${cfg.orgSlug ? bold(cfg.orgSlug) : gray('(not set)')}`);\n console.log(` ${dim('Default team:')} ${cfg.defaultTeam ? bold(cfg.defaultTeam) : gray('(not set)')}`);\n console.log(` ${dim('API key:')} ${apiKeySet ? bold('set') : gray('not set — run `atoll auth login`')}`);\n });\n\n// ── atoll config set-org ────────────────────────────────────────────────────\n\nconfigCommand\n .command('set-org <slug>')\n .description('Set the default organisation slug')\n .action((slug: string) => {\n const cfg = readConfig();\n cfg.orgSlug = slug;\n writeConfig(cfg);\n\n output(\n { orgSlug: slug },\n success(`Default org set to \"${slug}\"`),\n );\n });\n\n// ── atoll config set-team ───────────────────────────────────────────────────\n\nconfigCommand\n .command('set-team <team>')\n .description('Set the default team slug or ID')\n .action((team: string) => {\n const cfg = readConfig();\n cfg.defaultTeam = team;\n writeConfig(cfg);\n\n output(\n { defaultTeam: team },\n success(`Default team set to \"${team}\"`),\n );\n });\n","import { Command } from 'commander';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\nimport { bold, dim, green, gray, success } from '../lib/colors.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface Webhook {\n id: string;\n url: string;\n events: string[];\n enabled: boolean;\n created_at: string;\n}\n\ninterface WebhookListResponse {\n webhooks: Webhook[];\n}\n\ninterface WebhookCreateResponse {\n webhook: Webhook;\n secret: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction handleApiError(err: unknown): never {\n const msg = (err as Error).message ?? String(err);\n if (/API 401\\b/.test(msg)) {\n outputError('Session expired — run `atoll auth login` to re-authenticate.');\n } else if (/API 403\\b/.test(msg)) {\n outputError('Permission denied. You do not have access to this resource.');\n } else {\n outputError(msg);\n }\n process.exit(1);\n}\n\nasync function resolveOrgId(client: AtollClient, orgSlugOverride?: string): Promise<string> {\n const { orgs } = await client.get<{ orgs: { id: string; slug: string }[] }>('/api/orgs');\n if (!orgs || orgs.length === 0) {\n outputError('No organizations found.');\n process.exit(1);\n }\n if (orgs.length === 1) return orgs[0].id;\n\n const { readConfig } = await import('../lib/config.js');\n const config = readConfig();\n const slug = orgSlugOverride ?? process.env.ATOLL_ORG ?? config.orgSlug;\n\n if (slug) {\n const match = orgs.find((o) => o.slug === slug);\n if (match) return match.id;\n outputError(`Org \"${slug}\" not found. Available: ${orgs.map((o) => o.slug).join(', ')}`);\n process.exit(1);\n }\n outputError(`Multiple orgs found. Use --org <slug>.`);\n process.exit(1);\n}\n\nfunction padEnd(str: string, len: number): string {\n return str.length >= len ? str.slice(0, len) : str + ' '.repeat(len - str.length);\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\nexport const webhookCommand = new Command('webhook')\n .description('Manage outbound webhooks')\n .addHelpText('after', `\nExamples:\n $ atoll webhook list\n $ atoll webhook create --url https://example.com/hook --events issue.created,issue.updated\n $ atoll webhook delete <id>`);\n\n// ---- list ----\nwebhookCommand\n .command('list')\n .description('List webhooks for the current org')\n .action(async () => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n\n const data = await client.get<WebhookListResponse>(`/api/webhooks?orgId=${orgId}`);\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n for (const wh of data.webhooks) {\n process.stdout.write(JSON.stringify(wh) + '\\n');\n }\n return;\n }\n\n if (data.webhooks.length === 0) {\n console.log('No webhooks configured.');\n return;\n }\n\n const header = bold(`${padEnd('ID', 38)} ${padEnd('URL', 40)} ${padEnd('EVENTS', 20)} ACTIVE`);\n console.log(header);\n console.log('─'.repeat(100));\n for (const wh of data.webhooks) {\n const evts = wh.events.length === 0 ? 'all' : wh.events.join(',');\n const active = wh.enabled ? green('yes') : gray('no');\n const url = wh.url.length > 38 ? wh.url.slice(0, 35) + '…' : wh.url;\n const evtStr = evts.length > 18 ? evts.slice(0, 15) + '…' : evts;\n console.log(`${padEnd(wh.id.slice(0, 36), 38)} ${padEnd(url, 40)} ${padEnd(evtStr, 20)} ${active}`);\n }\n console.log(dim(`${data.webhooks.length} webhook(s)`));\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- create ----\nwebhookCommand\n .command('create')\n .description('Create a new webhook')\n .requiredOption('--url <url>', 'Payload URL (HTTPS)')\n .option('--events <events>', 'Comma-separated event types (default: all)', '')\n .action(async (opts: { url: string; events: string }) => {\n try {\n if (!opts.url.startsWith('https://')) {\n outputError('URL must use HTTPS.');\n process.exit(2);\n }\n\n const events = opts.events\n ? opts.events.split(',').map((e) => e.trim()).filter(Boolean)\n : [];\n\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n\n const data = await client.post<WebhookCreateResponse>(\n `/api/webhooks?orgId=${orgId}`,\n { url: opts.url, events },\n );\n\n output(\n { webhook: data.webhook, secret: data.secret },\n [\n success(`Created webhook ${data.webhook.id}`),\n '',\n bold('Signing secret (save this — shown only once):'),\n ` ${data.secret}`,\n ].join('\\n'),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- delete ----\nwebhookCommand\n .command('delete <id>')\n .description('Delete a webhook')\n .action(async (id: string) => {\n try {\n const client = new AtollClient();\n await client.delete(`/api/webhooks/${id}`);\n\n output(\n { success: true, id },\n success(`Deleted webhook ${id}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n"],"mappings":"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","names":["import_commander","import_commander","readConfig","import_commander","BOLD","DIM","RESET","import_commander","import_commander","progressBar","import_commander","import_commander","handleApiError","resolveOrgId","readConfig","padEnd"]}
1
+ {"version":3,"sources":["../src/lib/config.ts","../src/index.ts","../src/commands/auth.ts","../src/lib/client.ts","../src/lib/output.ts","../src/commands/issue.ts","../src/lib/colors.ts","../src/lib/urls.ts","../src/commands/comment.ts","../src/commands/project.ts","../src/commands/milestone.ts","../src/commands/config.ts","../src/commands/webhook.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport interface AtollConfig {\n apiKey?: string;\n orgSlug?: string;\n defaultTeam?: string;\n}\n\nconst CONFIG_DIR = join(homedir(), '.atoll');\nconst CONFIG_PATH = join(CONFIG_DIR, 'config.json');\n\nexport function readConfig(): AtollConfig {\n if (!existsSync(CONFIG_PATH)) return {};\n try {\n return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));\n } catch {\n return {};\n }\n}\n\nexport function writeConfig(config: AtollConfig): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport function deleteConfig(): void {\n if (existsSync(CONFIG_PATH)) {\n unlinkSync(CONFIG_PATH);\n }\n}\n\nexport function getApiKey(): string | undefined {\n return process.env.ATOLL_API_KEY || readConfig().apiKey;\n}\n","import { Command } from 'commander';\nimport { authCommand } from './commands/auth.js';\nimport { issueCommand } from './commands/issue.js';\nimport { commentCommand } from './commands/comment.js';\nimport { projectCommand } from './commands/project.js';\nimport { milestoneCommand } from './commands/milestone.js';\nimport { configCommand } from './commands/config.js';\nimport { webhookCommand } from './commands/webhook.js';\n\nconst program = new Command('atoll')\n .description('Atoll CLI — project management from the terminal')\n .version('0.1.0')\n .addHelpText('after', `\nExamples:\n $ atoll issue list\n $ atoll issue create --title \"Fix login bug\" --priority 1\n $ atoll issue view ATOLL-42\n $ atoll project list\n $ atoll milestone list --project <id>\n $ atoll config show`)\n // Global overrides — passed via env vars so sub-commands can pick them up\n .option('--org <slug>', 'Override default org slug (env: ATOLL_ORG)')\n .option('--team <id>', 'Override default team slug/ID (env: ATOLL_TEAM)')\n .hook('preAction', (thisCommand) => {\n const opts = thisCommand.opts();\n if (opts.org) process.env.ATOLL_ORG = opts.org;\n if (opts.team) process.env.ATOLL_TEAM = opts.team;\n });\n\nprogram.addCommand(authCommand);\nprogram.addCommand(issueCommand);\nprogram.addCommand(commentCommand);\nprogram.addCommand(projectCommand);\nprogram.addCommand(milestoneCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(webhookCommand);\n\n// ── atoll completion ────────────────────────────────────────────────────────\n\nconst completionCommand = new Command('completion')\n .description('Output shell completion scripts')\n .addHelpText('after', `\nExamples:\n $ atoll completion bash >> ~/.bashrc\n $ atoll completion zsh >> ~/.zshrc`);\n\ncompletionCommand\n .command('bash')\n .description('Output bash completion script')\n .action(() => {\n process.stdout.write(bashCompletion());\n });\n\ncompletionCommand\n .command('zsh')\n .description('Output zsh completion script')\n .action(() => {\n process.stdout.write(zshCompletion());\n });\n\nprogram.addCommand(completionCommand);\n\nprogram.parse();\n\n// ---------------------------------------------------------------------------\n// Completion script generators\n// ---------------------------------------------------------------------------\n\nfunction bashCompletion(): string {\n return `# Atoll CLI bash completion\n# Add to ~/.bashrc: source <(atoll completion bash)\n\n_atoll_completions() {\n local cur prev words cword\n _init_completion || return\n\n local commands=\"auth issue comment project milestone config webhook completion\"\n local issue_cmds=\"list view create update delete assign unassign\"\n local project_cmds=\"list create view\"\n local milestone_cmds=\"list create\"\n local config_cmds=\"show set-org set-team\"\n local auth_cmds=\"login logout status\"\n local webhook_cmds=\"list create delete\"\n local completion_cmds=\"bash zsh\"\n\n if [ \"\\${COMP_CWORD}\" -eq 1 ]; then\n COMPREPLY=( $(compgen -W \"\\${commands}\" -- \"\\${cur}\") )\n return 0\n fi\n\n case \"\\${words[1]}\" in\n issue)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${issue_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n project)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${project_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n milestone)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${milestone_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n config)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${config_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n auth)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${auth_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n webhook)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${webhook_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n completion)\n if [ \"\\${COMP_CWORD}\" -eq 2 ]; then\n COMPREPLY=( $(compgen -W \"\\${completion_cmds}\" -- \"\\${cur}\") )\n fi\n ;;\n esac\n}\n\ncomplete -F _atoll_completions atoll\n`;\n}\n\nfunction zshCompletion(): string {\n return `#compdef atoll\n# Atoll CLI zsh completion\n# Add to ~/.zshrc: source <(atoll completion zsh)\n\n_atoll() {\n local state\n\n _arguments \\\\\n '1: :->command' \\\\\n '*: :->args'\n\n case \\$state in\n command)\n _values 'command' \\\\\n 'auth[Manage authentication]' \\\\\n 'issue[Manage issues]' \\\\\n 'comment[Manage comments]' \\\\\n 'project[Manage projects]' \\\\\n 'milestone[Manage milestones]' \\\\\n 'config[Manage CLI configuration]' \\\\\n 'webhook[Manage outbound webhooks]' \\\\\n 'completion[Output shell completion scripts]'\n ;;\n args)\n case \\$words[2] in\n issue)\n _values 'subcommand' \\\\\n 'list[List issues]' \\\\\n 'view[View issue details]' \\\\\n 'create[Create a new issue]' \\\\\n 'update[Update an issue]' \\\\\n 'delete[Delete an issue]' \\\\\n 'assign[Assign an issue]' \\\\\n 'unassign[Remove assignee]'\n ;;\n project)\n _values 'subcommand' \\\\\n 'list[List projects]' \\\\\n 'create[Create a project]' \\\\\n 'view[View project details]'\n ;;\n milestone)\n _values 'subcommand' \\\\\n 'list[List milestones]' \\\\\n 'create[Create a milestone]'\n ;;\n config)\n _values 'subcommand' \\\\\n 'show[Show configuration]' \\\\\n 'set-org[Set default org slug]' \\\\\n 'set-team[Set default team]'\n ;;\n auth)\n _values 'subcommand' \\\\\n 'login[Log in]' \\\\\n 'logout[Log out]' \\\\\n 'status[Show auth status]'\n ;;\n webhook)\n _values 'subcommand' \\\\\n 'list[List webhooks]' \\\\\n 'create[Create a webhook]' \\\\\n 'delete[Delete a webhook]'\n ;;\n completion)\n _values 'shell' 'bash' 'zsh'\n ;;\n esac\n ;;\n esac\n}\n\n_atoll \"\\$@\"\n`;\n}\n","import { Command } from 'commander';\nimport { readConfig, writeConfig, deleteConfig, getApiKey } from '../lib/config.js';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\n\nexport const authCommand = new Command('auth')\n .description('Manage authentication');\n\nauthCommand\n .command('login')\n .description('Save an API key to ~/.atoll/config.json')\n .requiredOption('--key <API_KEY>', 'API key to store')\n .action((opts: { key: string }) => {\n const config = readConfig();\n config.apiKey = opts.key;\n writeConfig(config);\n output(\n { status: 'ok', message: 'API key saved' },\n '✓ API key saved to ~/.atoll/config.json',\n );\n });\n\nauthCommand\n .command('status')\n .description('Show current auth status and user info')\n .action(async () => {\n const apiKey = getApiKey();\n if (!apiKey) {\n outputError('Not authenticated. Run `atoll auth login --key <API_KEY>` or set ATOLL_API_KEY.');\n process.exit(1);\n }\n\n try {\n const client = new AtollClient({ apiKey });\n const me = await client.get<{\n user?: { email?: string; name?: string };\n org?: { slug?: string; name?: string };\n }>('/api/auth/me');\n\n output(\n { status: 'authenticated', ...me },\n [\n '✓ Authenticated',\n me.user?.name ? ` User: ${me.user.name}` : null,\n me.user?.email ? ` Email: ${me.user.email}` : null,\n me.org?.name ? ` Org: ${me.org.name} (${me.org.slug})` : null,\n ]\n .filter(Boolean)\n .join('\\n'),\n );\n } catch (err) {\n const msg = (err as Error).message || '';\n if (/API (401|403):/.test(msg)) {\n outputError('API key is invalid or expired');\n process.exit(1);\n }\n outputError(`Auth check failed: ${msg}`);\n process.exit(1);\n }\n });\n\nauthCommand\n .command('logout')\n .description('Remove stored API key')\n .action(() => {\n // Only clear the API key — preserve org/team config settings\n const config = readConfig();\n delete config.apiKey;\n writeConfig(config);\n output(\n { status: 'ok', message: 'Logged out' },\n '✓ Logged out — API key removed (org/team config preserved)',\n );\n });\n","import { getApiKey } from './config.js';\nimport { outputError } from './output.js';\n\nconst DEFAULT_BASE_URL = 'https://atollhq.com';\n\nexport class AtollClient {\n readonly baseUrl: string;\n private apiKey: string;\n\n constructor(opts?: { baseUrl?: string; apiKey?: string }) {\n this.baseUrl = opts?.baseUrl || process.env.ATOLL_BASE_URL || DEFAULT_BASE_URL;\n\n const key = opts?.apiKey || getApiKey();\n if (!key) {\n outputError('No API key found. Run `atoll auth login --key <API_KEY>` or set ATOLL_API_KEY.');\n process.exit(1);\n }\n this.apiKey = key;\n }\n\n async request<T = unknown>(path: string, init?: RequestInit): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const res = await fetch(url, {\n ...init,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n ...init?.headers,\n },\n });\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`API ${res.status}: ${body}`);\n }\n\n return res.json() as Promise<T>;\n }\n\n async get<T = unknown>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'GET' });\n }\n\n async post<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async patch<T = unknown>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'PATCH',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async delete<T = unknown>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'DELETE' });\n }\n}\n","export type OutputRecord = Record<string, unknown>;\n\nfunction isJsonMode(): boolean {\n if (process.env.OUTPUT_FORMAT === 'json') return true;\n return !process.stdout.isTTY;\n}\n\nexport function output(data: OutputRecord, humanReadable: string): void {\n if (isJsonMode()) {\n process.stdout.write(JSON.stringify(data) + '\\n');\n } else {\n console.log(humanReadable);\n }\n}\n\nexport function outputError(message: string): void {\n if (isJsonMode()) {\n process.stdout.write(JSON.stringify({ error: message }) + '\\n');\n } else {\n console.error(`Error: ${message}`);\n }\n}\n","import { Command } from 'commander';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\nimport { bold, dim, gray, statusColor, priorityIcon, success } from '../lib/colors.js';\nimport { buildIssueUrl, derivePrefix } from '../lib/urls.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface Issue {\n id: string;\n title: string;\n description?: string | null;\n status: string;\n priority: number;\n number?: number | null;\n assignee_id?: string | null;\n team_id?: string | null;\n project_id?: string | null;\n due_date?: string | null;\n created_at?: string;\n updated_at?: string;\n sub_tasks?: unknown[];\n issue_labels?: { label_id: string; labels: { name: string; color: string } }[];\n}\n\ninterface ListResponse {\n issues: Issue[];\n total: number;\n limit: number;\n offset: number;\n}\n\ninterface SingleResponse {\n issue: Issue;\n}\n\ninterface Org {\n id: string;\n name: string;\n slug: string;\n}\n\ninterface ProjectSummary {\n id: string;\n name: string;\n slug?: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nexport function handleApiError(err: unknown): never {\n const msg = (err as Error).message ?? String(err);\n if (/API 401\\b/.test(msg)) {\n outputError('Session expired — run `atoll auth login` to re-authenticate.');\n } else if (/API 403\\b/.test(msg)) {\n outputError('Permission denied. You do not have access to this resource.');\n } else {\n outputError(msg);\n }\n process.exit(1);\n}\n\nconst VALID_STATUSES = ['backlog', 'todo', 'in_progress', 'done', 'cancelled'] as const;\nconst PRIORITY_LABELS: Record<number, string> = { 0: 'Urgent', 1: 'High', 2: 'Medium', 3: 'Low' };\n\nexport async function resolveOrg(client: AtollClient, orgSlugOverride?: string): Promise<Org> {\n const { orgs } = await client.get<{ orgs: Org[] }>('/api/orgs');\n if (!orgs || orgs.length === 0) {\n outputError('No organizations found. Create one first.');\n process.exit(1);\n }\n if (orgs.length === 1) return orgs[0];\n\n // Resolve slug: CLI override → env var (set by --org global flag) → config file\n const { readConfig } = await import('../lib/config.js');\n const config = readConfig();\n const slug = orgSlugOverride ?? process.env.ATOLL_ORG ?? config.orgSlug;\n\n if (slug) {\n const match = orgs.find((o) => o.slug === slug);\n if (match) return match;\n outputError(`Org \"${slug}\" not found. Available: ${orgs.map((o) => o.slug).join(', ')}`);\n process.exit(1);\n }\n outputError(`Multiple orgs found. Use --org <slug> or run \\`atoll config set-org <slug>\\`. Available: ${orgs.map((o) => o.slug).join(', ')}`);\n process.exit(1);\n}\n\nexport async function resolveOrgId(client: AtollClient, orgSlugOverride?: string): Promise<string> {\n return (await resolveOrg(client, orgSlugOverride)).id;\n}\n\n/**\n * Fetch the org's projects and return a map keyed by project id.\n * Used to derive PREFIX-NUMBER identifiers and canonical URLs for issues.\n */\nexport async function fetchProjectMap(\n client: AtollClient,\n orgId: string,\n): Promise<Map<string, ProjectSummary>> {\n const { projects } = await client.get<{ projects: ProjectSummary[] }>(\n `/api/orgs/${orgId}/projects`,\n );\n const map = new Map<string, ProjectSummary>();\n for (const p of projects ?? []) map.set(p.id, p);\n return map;\n}\n\nexport interface IssueWithUrl extends Issue {\n url: string | null;\n}\n\nexport function attachIssueUrl(\n issue: Issue,\n baseUrl: string,\n orgSlug: string,\n projects: Map<string, ProjectSummary>,\n): IssueWithUrl {\n const project = issue.project_id ? projects.get(issue.project_id) : undefined;\n return {\n ...issue,\n url: buildIssueUrl(baseUrl, orgSlug, project?.slug, issue.number ?? null),\n };\n}\n\n/**\n * Resolve a human-readable identifier (e.g. \"ATOLL-42\" or \"42\") to a UUID.\n * Falls back to treating the identifier as a UUID if it doesn't match the pattern.\n */\nexport async function resolveIssueId(client: AtollClient, orgId: string, identifier: string): Promise<string> {\n // If it looks like a UUID already, return as-is\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(identifier)) {\n return identifier;\n }\n\n // Extract number from PREFIX-NUMBER or plain number. Prefix may contain\n // digits (e.g. \"Q2-42\") since derivePrefix preserves alphanumerics.\n const match = identifier.match(/^(?:[A-Za-z0-9]+-)?(\\d+)$/);\n if (!match) {\n outputError(`Invalid identifier: \"${identifier}\". Use a UUID or PREFIX-NUMBER (e.g. ATOLL-42).`);\n process.exit(2);\n }\n\n const num = parseInt(match[1], 10);\n\n // Use number filter to avoid pagination issues with large issue lists\n const { issues } = await client.get<ListResponse>(\n `/api/orgs/${orgId}/issues?number=${num}&limit=1`,\n );\n if (issues.length > 0 && issues[0].number === num) {\n return issues[0].id;\n }\n\n // Fallback: paginate through all issues if the API doesn't support ?number= filtering\n let offset = 0;\n const pageSize = 100;\n while (true) {\n const page = await client.get<ListResponse>(\n `/api/orgs/${orgId}/issues?limit=${pageSize}&offset=${offset}`,\n );\n const found = page.issues.find((i) => i.number === num);\n if (found) return found.id;\n offset += pageSize;\n if (offset >= page.total) break;\n }\n\n outputError(`Issue #${num} not found.`);\n process.exit(1);\n}\n\nfunction formatIdentifier(issue: Issue, projects?: Map<string, ProjectSummary>): string {\n if (issue.number == null) return issue.id.slice(0, 8);\n if (projects && issue.project_id) {\n const project = projects.get(issue.project_id);\n if (project?.name) return `${derivePrefix(project.name)}-${issue.number}`;\n }\n return `ATOLL-${issue.number}`;\n}\n\nfunction padEnd(str: string, len: number): string {\n return str.length >= len ? str.slice(0, len) : str + ' '.repeat(len - str.length);\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\nexport const issueCommand = new Command('issue')\n .description('Manage issues')\n .addHelpText('after', `\nExamples:\n $ atoll issue list\n $ atoll issue list --status in_progress --priority 1\n $ atoll issue view ATOLL-42\n $ atoll issue create --title \"Fix login\" --priority 1 --status todo\n $ atoll issue update ATOLL-42 --status done\n $ atoll issue assign ATOLL-42 --to <user-id>`);\n\n// ---- list ----\nissueCommand\n .command('list')\n .description('List issues')\n .option('--status <status>', `Filter by status (${VALID_STATUSES.join(', ')})`)\n .option('--assignee <user>', 'Filter by assignee ID')\n .option('--priority <n>', 'Filter by priority (0=urgent, 1=high, 2=medium, 3=low)', parseInt)\n .option('--limit <n>', 'Max results (1-100)', parseInt)\n .action(async (opts: { status?: string; assignee?: string; priority?: number; limit?: number }) => {\n try {\n const client = new AtollClient();\n const org = await resolveOrg(client);\n\n const params = new URLSearchParams();\n if (opts.status) params.set('status', opts.status);\n if (opts.assignee) params.set('assigneeId', opts.assignee);\n if (opts.priority !== undefined) params.set('priority', String(opts.priority));\n if (opts.limit !== undefined) params.set('limit', String(opts.limit));\n\n const qs = params.toString();\n const [data, projects] = await Promise.all([\n client.get<ListResponse>(`/api/orgs/${org.id}/issues${qs ? `?${qs}` : ''}`),\n fetchProjectMap(client, org.id),\n ]);\n\n const enriched = data.issues.map((issue) =>\n attachIssueUrl(issue, client.baseUrl, org.slug, projects),\n );\n\n // JSON mode: NDJSON\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n for (const issue of enriched) {\n process.stdout.write(JSON.stringify(issue) + '\\n');\n }\n return;\n }\n\n // TTY: table\n if (enriched.length === 0) {\n console.log('No issues found.');\n return;\n }\n\n const header = bold(`${padEnd('ID', 10)} ${padEnd('STATUS', 14)} ${padEnd('PRI', 8)} TITLE`);\n console.log(header);\n console.log('─'.repeat(82));\n for (const issue of enriched) {\n const id = formatIdentifier(issue, projects);\n const pri = PRIORITY_LABELS[issue.priority] ?? String(issue.priority);\n const title = issue.title.length > 50 ? issue.title.slice(0, 47) + '…' : issue.title;\n const icon = priorityIcon(issue.priority);\n console.log(`${padEnd(id, 10)} ${statusColor(issue.status, padEnd(issue.status, 14))} ${icon} ${padEnd(pri, 8)} ${title}`);\n }\n console.log(dim(`${enriched.length} of ${data.total} issues`));\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- view ----\nissueCommand\n .command('view <identifier>')\n .description('View issue details (UUID or PREFIX-NUMBER e.g. ATOLL-42)')\n .action(async (identifier: string) => {\n try {\n const client = new AtollClient();\n const org = await resolveOrg(client);\n const issueId = await resolveIssueId(client, org.id, identifier);\n\n const [{ issue }, projects] = await Promise.all([\n client.get<SingleResponse>(`/api/orgs/${org.id}/issues/${issueId}`),\n fetchProjectMap(client, org.id),\n ]);\n\n const enriched = attachIssueUrl(issue, client.baseUrl, org.slug, projects);\n\n // JSON mode\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n process.stdout.write(JSON.stringify(enriched) + '\\n');\n return;\n }\n\n // TTY: formatted detail\n const id = formatIdentifier(enriched, projects);\n const pri = PRIORITY_LABELS[enriched.priority] ?? String(enriched.priority);\n console.log(`${bold(id)} ${enriched.title}`);\n console.log(`Status: ${statusColor(enriched.status, enriched.status)} Priority: ${priorityIcon(enriched.priority)} ${pri}`);\n if (enriched.url) console.log(`URL: ${enriched.url}`);\n if (enriched.assignee_id) console.log(`Assignee: ${enriched.assignee_id}`);\n if (enriched.due_date) console.log(`Due: ${enriched.due_date}`);\n if (enriched.description) {\n console.log(`\\n${enriched.description}`);\n }\n if (enriched.issue_labels && enriched.issue_labels.length > 0) {\n const labels = enriched.issue_labels.map((l) => l.labels.name).join(', ');\n console.log(`Labels: ${labels}`);\n }\n if (enriched.sub_tasks && Array.isArray(enriched.sub_tasks) && enriched.sub_tasks.length > 0) {\n console.log(`\\nSubtasks: ${enriched.sub_tasks.length}`);\n }\n if (enriched.created_at) console.log(dim(`Created: ${enriched.created_at}`));\n if (enriched.updated_at) console.log(dim(`Updated: ${enriched.updated_at}`));\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- create ----\nissueCommand\n .command('create')\n .description('Create a new issue')\n .requiredOption('--title <title>', 'Issue title')\n .option('--description <text>', 'Issue description')\n .option('--status <status>', `Status (${VALID_STATUSES.join(', ')})`)\n .option('--priority <n>', 'Priority (0=urgent, 1=high, 2=medium, 3=low)', parseInt)\n .action(async (opts: { title: string; description?: string; status?: string; priority?: number }) => {\n try {\n if (opts.status && !VALID_STATUSES.includes(opts.status as typeof VALID_STATUSES[number])) {\n outputError(`Invalid status \"${opts.status}\". Must be one of: ${VALID_STATUSES.join(', ')}`);\n process.exit(2);\n }\n if (opts.priority !== undefined && ![0, 1, 2, 3].includes(opts.priority)) {\n outputError('Priority must be 0 (urgent), 1 (high), 2 (medium), or 3 (low).');\n process.exit(2);\n }\n\n const client = new AtollClient();\n const org = await resolveOrg(client);\n\n const body: Record<string, unknown> = { title: opts.title };\n if (opts.description !== undefined) body.description = opts.description;\n if (opts.status) body.status = opts.status;\n if (opts.priority !== undefined) body.priority = opts.priority;\n\n const { issue } = await client.post<SingleResponse>(`/api/orgs/${org.id}/issues`, body);\n const projects = await fetchProjectMap(client, org.id);\n const enriched = attachIssueUrl(issue, client.baseUrl, org.slug, projects);\n\n output(\n { issue: enriched },\n success(`Created ${formatIdentifier(enriched, projects)}: ${enriched.title}${enriched.url ? `\\n${enriched.url}` : ''}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- update ----\nissueCommand\n .command('update <identifier>')\n .description('Update an issue')\n .option('--title <t>', 'New title')\n .option('--status <s>', `New status (${VALID_STATUSES.join(', ')})`)\n .option('--priority <p>', 'New priority (0-3)', parseInt)\n .action(async (identifier: string, opts: { title?: string; status?: string; priority?: number }) => {\n try {\n if (opts.status && !VALID_STATUSES.includes(opts.status as typeof VALID_STATUSES[number])) {\n outputError(`Invalid status \"${opts.status}\". Must be one of: ${VALID_STATUSES.join(', ')}`);\n process.exit(2);\n }\n if (opts.priority !== undefined && ![0, 1, 2, 3].includes(opts.priority)) {\n outputError('Priority must be 0-3.');\n process.exit(2);\n }\n\n const body: Record<string, unknown> = {};\n if (opts.title !== undefined) body.title = opts.title;\n if (opts.status) body.status = opts.status;\n if (opts.priority !== undefined) body.priority = opts.priority;\n\n if (Object.keys(body).length === 0) {\n outputError('No fields to update. Provide --title, --status, or --priority.');\n process.exit(2);\n }\n\n const client = new AtollClient();\n const org = await resolveOrg(client);\n const issueId = await resolveIssueId(client, org.id, identifier);\n\n const { issue } = await client.patch<SingleResponse>(`/api/orgs/${org.id}/issues/${issueId}`, body);\n const projects = await fetchProjectMap(client, org.id);\n const enriched = attachIssueUrl(issue, client.baseUrl, org.slug, projects);\n\n output(\n { issue: enriched },\n success(`Updated ${formatIdentifier(enriched, projects)}: ${enriched.title}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- delete ----\nissueCommand\n .command('delete <identifier>')\n .description('Delete an issue (admin/owner only)')\n .action(async (identifier: string) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, identifier);\n\n await client.delete(`/api/orgs/${orgId}/issues/${issueId}`);\n\n output(\n { success: true, id: issueId },\n success(`Deleted issue ${identifier}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- assign ----\nissueCommand\n .command('assign <identifier>')\n .description('Assign an issue to a user or agent')\n .requiredOption('--to <user>', 'User/agent ID or \"self\" for yourself')\n .action(async (identifier: string, opts: { to: string }) => {\n try {\n const client = new AtollClient();\n const org = await resolveOrg(client);\n const issueId = await resolveIssueId(client, org.id, identifier);\n\n let assigneeId = opts.to;\n if (assigneeId === 'self') {\n const me = await client.get<{ auth?: { userId?: string } }>('/api/auth/me');\n // For agent keys, auth.userId IS the org_members.id directly\n const callerUserId = me.auth?.userId;\n if (!callerUserId) {\n outputError('Could not resolve your user ID.');\n process.exit(1);\n }\n // Agent callers: userId is the member id — use directly\n // Human callers: userId is the supabase auth id — look up member id\n const { members } = await client.get<{ members: { id: string; user_id: string }[] }>(\n `/api/orgs/${org.id}/members`,\n );\n const member = members.find((m) => m.id === callerUserId || m.user_id === callerUserId);\n if (!member) {\n outputError('You are not a member of this organisation.');\n process.exit(1);\n }\n assigneeId = member.id;\n }\n\n const { issue } = await client.patch<SingleResponse>(\n `/api/orgs/${org.id}/issues/${issueId}`,\n { assignee_id: assigneeId },\n );\n const projects = await fetchProjectMap(client, org.id);\n const enriched = attachIssueUrl(issue, client.baseUrl, org.slug, projects);\n\n output(\n { issue: enriched },\n success(`Assigned ${formatIdentifier(enriched, projects)} to ${opts.to}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- unassign ----\nissueCommand\n .command('unassign <identifier>')\n .description('Remove assignee from an issue')\n .action(async (identifier: string) => {\n try {\n const client = new AtollClient();\n const org = await resolveOrg(client);\n const issueId = await resolveIssueId(client, org.id, identifier);\n\n const { issue } = await client.patch<SingleResponse>(\n `/api/orgs/${org.id}/issues/${issueId}`,\n { assignee_id: null },\n );\n const projects = await fetchProjectMap(client, org.id);\n const enriched = attachIssueUrl(issue, client.baseUrl, org.slug, projects);\n\n output(\n { issue: enriched },\n success(`Unassigned ${formatIdentifier(enriched, projects)}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n","/**\n * TTY-aware ANSI color helpers.\n * Colors are only emitted when stdout is a TTY and OUTPUT_FORMAT !== 'json'.\n */\n\nfunction isTTY(): boolean {\n return process.stdout.isTTY === true && process.env.OUTPUT_FORMAT !== 'json';\n}\n\nfunction ansi(code: string, text: string): string {\n if (!isTTY()) return text;\n return `\\x1b[${code}m${text}\\x1b[0m`;\n}\n\n// Basic colors\nexport const bold = (t: string) => ansi('1', t);\nexport const dim = (t: string) => ansi('2', t);\nexport const red = (t: string) => ansi('31', t);\nexport const green = (t: string) => ansi('32', t);\nexport const yellow = (t: string) => ansi('33', t);\nexport const blue = (t: string) => ansi('34', t);\nexport const cyan = (t: string) => ansi('36', t);\nexport const gray = (t: string) => ansi('90', t);\nexport const white = (t: string) => ansi('37', t);\n\n// Status badge colors\nexport function statusColor(status: string, text: string): string {\n switch (status) {\n case 'done': return green(text);\n case 'in_progress': return yellow(text);\n case 'backlog':\n case 'todo': return gray(text);\n case 'cancelled': return red(text);\n default: return text;\n }\n}\n\n// Priority icons\nexport function priorityIcon(priority: number): string {\n switch (priority) {\n case 0: return red('⚠⚠⚠'); // urgent\n case 1: return yellow('▄▆█'); // high\n case 2: return cyan('▄▆'); // medium\n case 3: return dim('---'); // low\n default: return String(priority);\n }\n}\n\n// Helpers\nexport const success = (msg: string) => green(`✓ ${msg}`);\nexport const error = (msg: string) => red(`Error: ${msg}`);\n\n// Raw ANSI codes (for use in format strings where needed)\nexport const RESET = isTTY() ? '\\x1b[0m' : '';\nexport const BOLD = isTTY() ? '\\x1b[1m' : '';\nexport const DIM = isTTY() ? '\\x1b[2m' : '';\n","// URL builders for Atoll canonical web routes.\n// Mirrors the routing and identifier conventions in agent-pm.\n\n/**\n * Derive a short uppercase prefix from a project name.\n * Mirrors agent-pm/lib/issue-identifier.ts — keep in sync.\n */\nexport function derivePrefix(name: string): string {\n const cleaned = name.replace(/[^a-zA-Z0-9\\s]/g, ' ').trim();\n const words = cleaned.split(/\\s+/).filter(Boolean);\n\n if (words.length === 0) return 'TSK';\n\n if (words.length >= 2) {\n return words\n .slice(0, 5)\n .map((w) => w[0])\n .join('')\n .toUpperCase();\n }\n\n const word = words[0];\n if (word.length <= 4) return word.toUpperCase();\n return word.slice(0, 3).toUpperCase();\n}\n\nexport function issueIdentifier(\n projectName: string | null | undefined,\n issueNumber: number | null | undefined,\n): string | null {\n if (issueNumber == null) return null;\n const prefix = projectName ? derivePrefix(projectName) : 'TSK';\n return `${prefix}-${issueNumber}`;\n}\n\nfunction stripTrailingSlash(baseUrl: string): string {\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n}\n\nexport function buildIssueUrl(\n baseUrl: string,\n orgSlug: string,\n projectSlug: string | null | undefined,\n issueNumber: number | null | undefined,\n): string | null {\n // Use the project-scoped route (/{org}/projects/{projectSlug}/issues/{number})\n // rather than the prefix-based identifier route. The prefix route is\n // ambiguous (two projects can derive the same prefix, and numeric-containing\n // prefixes like \"Q2\" fail the web app's [A-Z]{2,} regex).\n if (!orgSlug || !projectSlug || issueNumber == null) return null;\n return `${stripTrailingSlash(baseUrl)}/${orgSlug}/projects/${projectSlug}/issues/${issueNumber}`;\n}\n\nexport function buildProjectUrl(\n baseUrl: string,\n orgSlug: string,\n projectSlug: string | null | undefined,\n): string | null {\n if (!orgSlug || !projectSlug) return null;\n return `${stripTrailingSlash(baseUrl)}/${orgSlug}/projects/${projectSlug}`;\n}\n\nexport function buildInitiativeUrl(\n baseUrl: string,\n orgSlug: string,\n initiativeId: string | null | undefined,\n): string | null {\n if (!orgSlug || !initiativeId) return null;\n return `${stripTrailingSlash(baseUrl)}/${orgSlug}/initiatives/${initiativeId}`;\n}\n","import { Command } from 'commander';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\nimport { handleApiError, resolveOrgId, resolveIssueId } from './issue.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface CommentAuthor {\n id: string;\n display_name: string;\n type: string;\n avatar_url?: string;\n}\n\ninterface Comment {\n id: string;\n body: string;\n author_id: string;\n author_type?: string;\n author?: CommentAuthor;\n created_at?: string;\n updated_at?: string;\n}\n\ninterface ListCommentsResponse {\n comments: Comment[];\n}\n\ninterface SingleCommentResponse {\n comment: Comment;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\nconst CYAN = '\\x1b[36m';\n\nfunction formatAuthor(comment: Comment): string {\n const name = comment.author?.display_name ?? comment.author_id;\n const badge = (comment.author?.type ?? comment.author_type) === 'agent' ? ' [agent]' : '';\n return `${name}${badge}`;\n}\n\nfunction formatTimestamp(ts?: string): string {\n if (!ts) return '';\n const d = new Date(ts);\n return d.toLocaleString();\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\nexport const commentCommand = new Command('comment')\n .description('Manage issue comments');\n\n// ---- list ----\ncommentCommand\n .command('list <identifier>')\n .description('List comments on an issue (UUID or PREFIX-NUMBER e.g. ATOLL-42)')\n .action(async (identifier: string) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, identifier);\n\n const data = await client.get<ListCommentsResponse>(\n `/api/orgs/${orgId}/issues/${issueId}/comments`,\n );\n\n // JSON mode: NDJSON\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n for (const comment of data.comments) {\n process.stdout.write(JSON.stringify(comment) + '\\n');\n }\n return;\n }\n\n // TTY: human-readable\n if (data.comments.length === 0) {\n console.log('No comments found.');\n return;\n }\n\n for (const comment of data.comments) {\n const author = formatAuthor(comment);\n const time = formatTimestamp(comment.created_at);\n console.log(`${BOLD}${CYAN}${author}${RESET} ${DIM}${time}${RESET}`);\n console.log(comment.body);\n console.log();\n }\n console.log(`${DIM}${data.comments.length} comment(s)${RESET}`);\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- add ----\ncommentCommand\n .command('add <identifier>')\n .description('Add a comment to an issue')\n .requiredOption('--body <text>', 'Comment body')\n .action(async (identifier: string, opts: { body: string }) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, identifier);\n\n const { comment } = await client.post<SingleCommentResponse>(\n `/api/orgs/${orgId}/issues/${issueId}/comments`,\n { body: opts.body },\n );\n\n output(\n { comment },\n `✓ Comment added to ${identifier}`,\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- update ----\ncommentCommand\n .command('update <comment-id>')\n .description('Update a comment')\n .requiredOption('--body <text>', 'New comment body')\n .requiredOption('--issue <identifier>', 'Issue identifier (e.g. UUID or PREFIX-NUMBER)')\n .action(async (commentId: string, opts: { body: string; issue: string }) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, opts.issue);\n\n const { comment } = await client.patch<SingleCommentResponse>(\n `/api/orgs/${orgId}/issues/${issueId}/comments/${commentId}`,\n { body: opts.body },\n );\n\n output(\n { comment },\n `✓ Comment ${commentId} updated`,\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- delete ----\ncommentCommand\n .command('delete <comment-id>')\n .description('Delete a comment')\n .requiredOption('--issue <identifier>', 'Issue identifier (e.g. UUID or PREFIX-NUMBER)')\n .action(async (commentId: string, opts: { issue: string }) => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n const issueId = await resolveIssueId(client, orgId, opts.issue);\n\n await client.delete(`/api/orgs/${orgId}/issues/${issueId}/comments/${commentId}`);\n\n output(\n { success: true, id: commentId },\n `✓ Comment ${commentId} deleted`,\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n","import { Command } from 'commander';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\nimport { resolveOrg, handleApiError } from './issue.js';\nimport { bold, dim, cyan, green, success } from '../lib/colors.js';\nimport { buildProjectUrl } from '../lib/urls.js';\n\ninterface Project {\n id: string;\n name: string;\n slug?: string | null;\n description?: string | null;\n status: 'active' | 'archived';\n color: string;\n icon: string;\n issueCount?: number;\n completedCount?: number;\n progress?: number;\n created_at?: string;\n}\n\nfunction attachProjectUrl<T extends Project>(project: T, baseUrl: string, orgSlug: string): T & { url: string | null } {\n return { ...project, url: buildProjectUrl(baseUrl, orgSlug, project.slug) };\n}\n\ninterface Issue {\n id: string;\n title: string;\n status: string;\n priority: number;\n number?: number | null;\n}\n\nfunction progressBar(progress: number, width = 20): string {\n const filled = Math.round((progress / 100) * width);\n const empty = width - filled;\n return `[${'█'.repeat(filled)}${'░'.repeat(empty)}] ${progress}%`;\n}\n\nexport const projectCommand = new Command('project')\n .description('Manage projects')\n .addHelpText('after', `\nExamples:\n $ atoll project list\n $ atoll project create --name \"My Project\" --icon 🚀\n $ atoll project view <project-id>`);\n\n// ── atoll project list ──────────────────────────────────────────────────────\n\nprojectCommand\n .command('list')\n .description('List all projects with progress')\n .action(async () => {\n const client = new AtollClient();\n try {\n const org = await resolveOrg(client);\n const data = await client.get<{ projects: Project[] }>(`/api/orgs/${org.id}/projects`);\n const projects = (data.projects ?? []).map((p) => attachProjectUrl(p, client.baseUrl, org.slug));\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n for (const p of projects) {\n process.stdout.write(JSON.stringify(p) + '\\n');\n }\n return;\n }\n\n if (projects.length === 0) {\n console.log(dim('No projects found.'));\n return;\n }\n\n for (const p of projects) {\n const progress = p.progress ?? 0;\n const bar = progressBar(progress);\n console.log(`${bold(`${p.icon} ${p.name}`)} ${dim(`(${p.id})`)}`);\n if (p.description) console.log(` ${dim(p.description)}`);\n console.log(` ${cyan(bar)} ${p.issueCount ?? 0} issues, ${p.completedCount ?? 0} done`);\n if (p.url) console.log(` ${dim(p.url)}`);\n if (p.status === 'archived') console.log(` ${dim('[archived]')}`);\n console.log('');\n }\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ── atoll project create ────────────────────────────────────────────────────\n\nprojectCommand\n .command('create')\n .description('Create a new project')\n .requiredOption('--name <name>', 'Project name')\n .option('--description <desc>', 'Project description')\n .option('--color <color>', 'Project color (hex)', '#6366f1')\n .option('--icon <icon>', 'Project icon (emoji)', '📁')\n .action(async (opts) => {\n const client = new AtollClient();\n try {\n const org = await resolveOrg(client);\n const data = await client.post<{ project: Project }>(`/api/orgs/${org.id}/projects`, {\n name: opts.name,\n description: opts.description ?? null,\n color: opts.color,\n icon: opts.icon,\n });\n const project = attachProjectUrl(data.project, client.baseUrl, org.slug);\n\n output(\n { project },\n success(`Created project ${project.icon} ${project.name} (${dim(project.id)})${project.url ? `\\n${project.url}` : ''}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ── atoll project view ──────────────────────────────────────────────────────\n\nprojectCommand\n .command('view <projectId>')\n .description('View project details and issues')\n .action(async (projectId) => {\n const client = new AtollClient();\n try {\n const org = await resolveOrg(client);\n const data = await client.get<{ project: Project & { issues: Issue[] } }>(\n `/api/orgs/${org.id}/projects/${projectId}`,\n );\n const p = attachProjectUrl(data.project, client.baseUrl, org.slug);\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n process.stdout.write(JSON.stringify(p) + '\\n');\n return;\n }\n\n const progress = p.progress ?? 0;\n console.log(bold(`${p.icon} ${p.name}`));\n if (p.description) console.log(` ${p.description}`);\n if (p.url) console.log(` ${dim(p.url)}`);\n console.log(` ${cyan(progressBar(progress))}`);\n console.log(` ${(p.issueCount ?? 0)} issues · ${(p.completedCount ?? 0)} completed`);\n console.log('');\n\n const issues: Issue[] = (p as unknown as { issues?: Issue[] }).issues ?? [];\n if (issues.length === 0) {\n console.log(dim('No issues in this project.'));\n return;\n }\n\n console.log(bold('Issues'));\n for (const issue of issues) {\n const num = issue.number ? `#${issue.number}` : issue.id.slice(0, 8);\n console.log(` ${dim(num)} ${issue.title} ${dim(`[${issue.status}]`)}`);\n }\n } catch (err) {\n handleApiError(err);\n }\n });\n","import { Command } from 'commander';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\nimport { resolveOrgId, handleApiError } from './issue.js';\nimport { bold, dim, cyan, red, success } from '../lib/colors.js';\n\ninterface Milestone {\n id: string;\n name: string;\n description?: string | null;\n due_date?: string | null;\n status: 'active' | 'closed';\n issueCount?: number;\n completedCount?: number;\n progress?: number;\n isOverdue?: boolean;\n}\n\nfunction progressBar(progress: number, width = 20): string {\n const filled = Math.round((progress / 100) * width);\n const empty = width - filled;\n return `[${'█'.repeat(filled)}${'░'.repeat(empty)}] ${progress}%`;\n}\n\nexport const milestoneCommand = new Command('milestone')\n .description('Manage milestones')\n .addHelpText('after', `\nExamples:\n $ atoll milestone list --project <project-id>\n $ atoll milestone create --project <project-id> --name \"v1.0\" --date 2026-06-01`);\n\n// ── atoll milestone list ────────────────────────────────────────────────────\n\nmilestoneCommand\n .command('list')\n .description('List milestones for a project')\n .requiredOption('--project <id>', 'Project ID')\n .action(async (opts) => {\n const client = new AtollClient();\n try {\n const orgId = await resolveOrgId(client);\n const data = await client.get<{ milestones: Milestone[] }>(\n `/api/orgs/${orgId}/projects/${opts.project}/milestones`,\n );\n const milestones = data.milestones ?? [];\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n for (const m of milestones) {\n process.stdout.write(JSON.stringify(m) + '\\n');\n }\n return;\n }\n\n if (milestones.length === 0) {\n console.log(dim('No milestones found.'));\n return;\n }\n\n for (const m of milestones) {\n const progress = m.progress ?? 0;\n const bar = progressBar(progress);\n const overdue = m.isOverdue ? ` ${red('[OVERDUE]')}` : '';\n console.log(`${bold(m.name)} ${dim(`(${m.id})`)}${overdue}`);\n if (m.due_date) console.log(` Due: ${m.due_date}`);\n if (m.description) console.log(` ${dim(m.description)}`);\n console.log(` ${cyan(bar)} ${m.issueCount ?? 0} issues, ${m.completedCount ?? 0} done`);\n if (m.status === 'closed') console.log(` ${dim('[closed]')}`);\n console.log('');\n }\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ── atoll milestone create ──────────────────────────────────────────────────\n\nmilestoneCommand\n .command('create')\n .description('Create a new milestone')\n .requiredOption('--project <id>', 'Project ID')\n .requiredOption('--name <name>', 'Milestone name')\n .option('--date <YYYY-MM-DD>', 'Due date')\n .option('--description <desc>', 'Description')\n .action(async (opts) => {\n const client = new AtollClient();\n try {\n const orgId = await resolveOrgId(client);\n const data = await client.post<{ milestone: Milestone }>(\n `/api/orgs/${orgId}/projects/${opts.project}/milestones`,\n {\n name: opts.name,\n description: opts.description ?? null,\n dueDate: opts.date ?? null,\n },\n );\n\n output(\n { milestone: data.milestone },\n success(`Milestone created: ${bold(data.milestone.name)} ${dim(`(${data.milestone.id})`)}`),\n );\n if (data.milestone.due_date) {\n console.log(` Due: ${data.milestone.due_date}`);\n }\n } catch (err) {\n handleApiError(err);\n }\n });\n","import { Command } from 'commander';\nimport { readConfig, writeConfig } from '../lib/config.js';\nimport { output, outputError } from '../lib/output.js';\nimport { success, bold, dim, gray } from '../lib/colors.js';\nimport { getApiKey } from '../lib/config.js';\n\nexport const configCommand = new Command('config')\n .description('Manage CLI configuration (org, team, API key)')\n .addHelpText('after', `\nExamples:\n $ atoll config show\n $ atoll config set-org my-org\n $ atoll config set-team team-abc123`);\n\n// ── atoll config show ───────────────────────────────────────────────────────\n\nconfigCommand\n .command('show')\n .description('Display current configuration')\n .action(() => {\n const cfg = readConfig();\n const apiKeySet = !!(process.env.ATOLL_API_KEY || cfg.apiKey);\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n output(\n {\n orgSlug: cfg.orgSlug ?? null,\n defaultTeam: cfg.defaultTeam ?? null,\n apiKeySet,\n },\n '',\n );\n return;\n }\n\n console.log(`${bold('Atoll CLI Configuration')}`);\n console.log(` ${dim('Org slug:')} ${cfg.orgSlug ? bold(cfg.orgSlug) : gray('(not set)')}`);\n console.log(` ${dim('Default team:')} ${cfg.defaultTeam ? bold(cfg.defaultTeam) : gray('(not set)')}`);\n console.log(` ${dim('API key:')} ${apiKeySet ? bold('set') : gray('not set — run `atoll auth login`')}`);\n });\n\n// ── atoll config set-org ────────────────────────────────────────────────────\n\nconfigCommand\n .command('set-org <slug>')\n .description('Set the default organisation slug')\n .action((slug: string) => {\n const cfg = readConfig();\n cfg.orgSlug = slug;\n writeConfig(cfg);\n\n output(\n { orgSlug: slug },\n success(`Default org set to \"${slug}\"`),\n );\n });\n\n// ── atoll config set-team ───────────────────────────────────────────────────\n\nconfigCommand\n .command('set-team <team>')\n .description('Set the default team slug or ID')\n .action((team: string) => {\n const cfg = readConfig();\n cfg.defaultTeam = team;\n writeConfig(cfg);\n\n output(\n { defaultTeam: team },\n success(`Default team set to \"${team}\"`),\n );\n });\n","import { Command } from 'commander';\nimport { AtollClient } from '../lib/client.js';\nimport { output, outputError } from '../lib/output.js';\nimport { bold, dim, green, gray, success } from '../lib/colors.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface Webhook {\n id: string;\n url: string;\n events: string[];\n enabled: boolean;\n created_at: string;\n}\n\ninterface WebhookListResponse {\n webhooks: Webhook[];\n}\n\ninterface WebhookCreateResponse {\n webhook: Webhook;\n secret: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction handleApiError(err: unknown): never {\n const msg = (err as Error).message ?? String(err);\n if (/API 401\\b/.test(msg)) {\n outputError('Session expired — run `atoll auth login` to re-authenticate.');\n } else if (/API 403\\b/.test(msg)) {\n outputError('Permission denied. You do not have access to this resource.');\n } else {\n outputError(msg);\n }\n process.exit(1);\n}\n\nasync function resolveOrgId(client: AtollClient, orgSlugOverride?: string): Promise<string> {\n const { orgs } = await client.get<{ orgs: { id: string; slug: string }[] }>('/api/orgs');\n if (!orgs || orgs.length === 0) {\n outputError('No organizations found.');\n process.exit(1);\n }\n if (orgs.length === 1) return orgs[0].id;\n\n const { readConfig } = await import('../lib/config.js');\n const config = readConfig();\n const slug = orgSlugOverride ?? process.env.ATOLL_ORG ?? config.orgSlug;\n\n if (slug) {\n const match = orgs.find((o) => o.slug === slug);\n if (match) return match.id;\n outputError(`Org \"${slug}\" not found. Available: ${orgs.map((o) => o.slug).join(', ')}`);\n process.exit(1);\n }\n outputError(`Multiple orgs found. Use --org <slug>.`);\n process.exit(1);\n}\n\nfunction padEnd(str: string, len: number): string {\n return str.length >= len ? str.slice(0, len) : str + ' '.repeat(len - str.length);\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\nexport const webhookCommand = new Command('webhook')\n .description('Manage outbound webhooks')\n .addHelpText('after', `\nExamples:\n $ atoll webhook list\n $ atoll webhook create --url https://example.com/hook --events issue.created,issue.updated\n $ atoll webhook delete <id>`);\n\n// ---- list ----\nwebhookCommand\n .command('list')\n .description('List webhooks for the current org')\n .action(async () => {\n try {\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n\n const data = await client.get<WebhookListResponse>(`/api/webhooks?orgId=${orgId}`);\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n for (const wh of data.webhooks) {\n process.stdout.write(JSON.stringify(wh) + '\\n');\n }\n return;\n }\n\n if (data.webhooks.length === 0) {\n console.log('No webhooks configured.');\n return;\n }\n\n const header = bold(`${padEnd('ID', 38)} ${padEnd('URL', 40)} ${padEnd('EVENTS', 20)} ACTIVE`);\n console.log(header);\n console.log('─'.repeat(100));\n for (const wh of data.webhooks) {\n const evts = wh.events.length === 0 ? 'all' : wh.events.join(',');\n const active = wh.enabled ? green('yes') : gray('no');\n const url = wh.url.length > 38 ? wh.url.slice(0, 35) + '…' : wh.url;\n const evtStr = evts.length > 18 ? evts.slice(0, 15) + '…' : evts;\n console.log(`${padEnd(wh.id.slice(0, 36), 38)} ${padEnd(url, 40)} ${padEnd(evtStr, 20)} ${active}`);\n }\n console.log(dim(`${data.webhooks.length} webhook(s)`));\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- create ----\nwebhookCommand\n .command('create')\n .description('Create a new webhook')\n .requiredOption('--url <url>', 'Payload URL (HTTPS)')\n .option('--events <events>', 'Comma-separated event types (default: all)', '')\n .action(async (opts: { url: string; events: string }) => {\n try {\n if (!opts.url.startsWith('https://')) {\n outputError('URL must use HTTPS.');\n process.exit(2);\n }\n\n const events = opts.events\n ? opts.events.split(',').map((e) => e.trim()).filter(Boolean)\n : [];\n\n const client = new AtollClient();\n const orgId = await resolveOrgId(client);\n\n const data = await client.post<WebhookCreateResponse>(\n `/api/webhooks?orgId=${orgId}`,\n { url: opts.url, events },\n );\n\n output(\n { webhook: data.webhook, secret: data.secret },\n [\n success(`Created webhook ${data.webhook.id}`),\n '',\n bold('Signing secret (save this — shown only once):'),\n ` ${data.secret}`,\n ].join('\\n'),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n\n// ---- delete ----\nwebhookCommand\n .command('delete <id>')\n .description('Delete a webhook')\n .action(async (id: string) => {\n try {\n const client = new AtollClient();\n await client.delete(`/api/webhooks/${id}`);\n\n output(\n { success: true, id },\n success(`Deleted webhook ${id}`),\n );\n } catch (err) {\n handleApiError(err);\n }\n });\n"],"mappings":";;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaO,SAAS,aAA0B;AACxC,MAAI,KAAC,2BAAW,WAAW,EAAG,QAAO,CAAC;AACtC,MAAI;AACF,WAAO,KAAK,UAAM,6BAAa,aAAa,OAAO,CAAC;AAAA,EACtD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,YAAY,QAA2B;AACrD,MAAI,KAAC,2BAAW,UAAU,GAAG;AAC3B,kCAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AACA,oCAAc,aAAa,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM,OAAO;AAC5E;AAEO,SAAS,eAAqB;AACnC,UAAI,2BAAW,WAAW,GAAG;AAC3B,mCAAW,WAAW;AAAA,EACxB;AACF;AAEO,SAAS,YAAgC;AAC9C,SAAO,QAAQ,IAAI,iBAAiB,WAAW,EAAE;AACnD;AArCA,oBACA,gBACA,kBAQM,YACA;AAXN;AAAA;AAAA;AAAA,qBAA+E;AAC/E,qBAAwB;AACxB,uBAAqB;AAQrB,IAAM,iBAAa,2BAAK,wBAAQ,GAAG,QAAQ;AAC3C,IAAM,kBAAc,uBAAK,YAAY,aAAa;AAAA;AAAA;;;ACXlD,IAAAA,oBAAwB;;;ACAxB,uBAAwB;AACxB;;;ACDA;;;ACEA,SAAS,aAAsB;AAC7B,MAAI,QAAQ,IAAI,kBAAkB,OAAQ,QAAO;AACjD,SAAO,CAAC,QAAQ,OAAO;AACzB;AAEO,SAAS,OAAO,MAAoB,eAA6B;AACtE,MAAI,WAAW,GAAG;AAChB,YAAQ,OAAO,MAAM,KAAK,UAAU,IAAI,IAAI,IAAI;AAAA,EAClD,OAAO;AACL,YAAQ,IAAI,aAAa;AAAA,EAC3B;AACF;AAEO,SAAS,YAAY,SAAuB;AACjD,MAAI,WAAW,GAAG;AAChB,YAAQ,OAAO,MAAM,KAAK,UAAU,EAAE,OAAO,QAAQ,CAAC,IAAI,IAAI;AAAA,EAChE,OAAO;AACL,YAAQ,MAAM,UAAU,OAAO,EAAE;AAAA,EACnC;AACF;;;ADlBA,IAAM,mBAAmB;AAElB,IAAM,cAAN,MAAkB;AAAA,EAIvB,YAAY,MAA8C;AACxD,SAAK,UAAU,MAAM,WAAW,QAAQ,IAAI,kBAAkB;AAE9D,UAAM,MAAM,MAAM,UAAU,UAAU;AACtC,QAAI,CAAC,KAAK;AACR,kBAAY,gFAAgF;AAC5F,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,QAAqB,MAAc,MAAgC;AACvE,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI;AAClC,UAAM,MAAM,MAAM,MAAM,KAAK;AAAA,MAC3B,GAAG;AAAA,MACH,SAAS;AAAA,QACP,iBAAiB,UAAU,KAAK,MAAM;AAAA,QACtC,gBAAgB;AAAA,QAChB,GAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAM,IAAI,MAAM,OAAO,IAAI,MAAM,KAAK,IAAI,EAAE;AAAA,IAC9C;AAEA,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA,EAEA,MAAM,IAAiB,MAA0B;AAC/C,WAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,EAChD;AAAA,EAEA,MAAM,KAAkB,MAAc,MAA4B;AAChE,WAAO,KAAK,QAAW,MAAM;AAAA,MAC3B,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAmB,MAAc,MAA4B;AACjE,WAAO,KAAK,QAAW,MAAM;AAAA,MAC3B,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAoB,MAA0B;AAClD,WAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,SAAS,CAAC;AAAA,EACnD;AACF;;;ADvDO,IAAM,cAAc,IAAI,yBAAQ,MAAM,EAC1C,YAAY,uBAAuB;AAEtC,YACG,QAAQ,OAAO,EACf,YAAY,yCAAyC,EACrD,eAAe,mBAAmB,kBAAkB,EACpD,OAAO,CAAC,SAA0B;AACjC,QAAM,SAAS,WAAW;AAC1B,SAAO,SAAS,KAAK;AACrB,cAAY,MAAM;AAClB;AAAA,IACE,EAAE,QAAQ,MAAM,SAAS,gBAAgB;AAAA,IACzC;AAAA,EACF;AACF,CAAC;AAEH,YACG,QAAQ,QAAQ,EAChB,YAAY,wCAAwC,EACpD,OAAO,YAAY;AAClB,QAAM,SAAS,UAAU;AACzB,MAAI,CAAC,QAAQ;AACX,gBAAY,iFAAiF;AAC7F,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI;AACF,UAAM,SAAS,IAAI,YAAY,EAAE,OAAO,CAAC;AACzC,UAAM,KAAK,MAAM,OAAO,IAGrB,cAAc;AAEjB;AAAA,MACE,EAAE,QAAQ,iBAAiB,GAAG,GAAG;AAAA,MACjC;AAAA,QACE;AAAA,QACA,GAAG,MAAM,OAAO,WAAW,GAAG,KAAK,IAAI,KAAK;AAAA,QAC5C,GAAG,MAAM,QAAQ,YAAY,GAAG,KAAK,KAAK,KAAK;AAAA,QAC/C,GAAG,KAAK,OAAO,UAAU,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,MAAM;AAAA,MAC5D,EACG,OAAO,OAAO,EACd,KAAK,IAAI;AAAA,IACd;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,MAAO,IAAc,WAAW;AACtC,QAAI,iBAAiB,KAAK,GAAG,GAAG;AAC9B,kBAAY,+BAA+B;AAC3C,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,gBAAY,sBAAsB,GAAG,EAAE;AACvC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,YACG,QAAQ,QAAQ,EAChB,YAAY,uBAAuB,EACnC,OAAO,MAAM;AAEZ,QAAM,SAAS,WAAW;AAC1B,SAAO,OAAO;AACd,cAAY,MAAM;AAClB;AAAA,IACE,EAAE,QAAQ,MAAM,SAAS,aAAa;AAAA,IACtC;AAAA,EACF;AACF,CAAC;;;AGzEH,IAAAC,oBAAwB;;;ACKxB,SAAS,QAAiB;AACxB,SAAO,QAAQ,OAAO,UAAU,QAAQ,QAAQ,IAAI,kBAAkB;AACxE;AAEA,SAAS,KAAK,MAAc,MAAsB;AAChD,MAAI,CAAC,MAAM,EAAG,QAAO;AACrB,SAAO,QAAQ,IAAI,IAAI,IAAI;AAC7B;AAGO,IAAM,OAAO,CAAC,MAAc,KAAK,KAAK,CAAC;AACvC,IAAM,MAAM,CAAC,MAAc,KAAK,KAAK,CAAC;AACtC,IAAM,MAAM,CAAC,MAAc,KAAK,MAAM,CAAC;AACvC,IAAM,QAAQ,CAAC,MAAc,KAAK,MAAM,CAAC;AACzC,IAAM,SAAS,CAAC,MAAc,KAAK,MAAM,CAAC;AAE1C,IAAM,OAAO,CAAC,MAAc,KAAK,MAAM,CAAC;AACxC,IAAM,OAAO,CAAC,MAAc,KAAK,MAAM,CAAC;AAIxC,SAAS,YAAY,QAAgB,MAAsB;AAChE,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAe,aAAO,MAAM,IAAI;AAAA,IACrC,KAAK;AAAe,aAAO,OAAO,IAAI;AAAA,IACtC,KAAK;AAAA,IACL,KAAK;AAAe,aAAO,KAAK,IAAI;AAAA,IACpC,KAAK;AAAe,aAAO,IAAI,IAAI;AAAA,IACnC;AAAoB,aAAO;AAAA,EAC7B;AACF;AAGO,SAAS,aAAa,UAA0B;AACrD,UAAQ,UAAU;AAAA,IAChB,KAAK;AAAG,aAAO,IAAI,oBAAK;AAAA;AAAA,IACxB,KAAK;AAAG,aAAO,OAAO,oBAAK;AAAA;AAAA,IAC3B,KAAK;AAAG,aAAO,KAAK,cAAI;AAAA;AAAA,IACxB,KAAK;AAAG,aAAO,IAAI,KAAK;AAAA;AAAA,IACxB;AAAS,aAAO,OAAO,QAAQ;AAAA,EACjC;AACF;AAGO,IAAM,UAAU,CAAC,QAAgB,MAAM,UAAK,GAAG,EAAE;AAIjD,IAAM,QAAQ,MAAM,IAAI,YAAY;AACpC,IAAM,OAAO,MAAM,IAAI,YAAY;AACnC,IAAM,MAAM,MAAM,IAAI,YAAY;;;AChDlC,SAAS,aAAa,MAAsB;AACjD,QAAM,UAAU,KAAK,QAAQ,mBAAmB,GAAG,EAAE,KAAK;AAC1D,QAAM,QAAQ,QAAQ,MAAM,KAAK,EAAE,OAAO,OAAO;AAEjD,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,MAAI,MAAM,UAAU,GAAG;AACrB,WAAO,MACJ,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EACf,KAAK,EAAE,EACP,YAAY;AAAA,EACjB;AAEA,QAAM,OAAO,MAAM,CAAC;AACpB,MAAI,KAAK,UAAU,EAAG,QAAO,KAAK,YAAY;AAC9C,SAAO,KAAK,MAAM,GAAG,CAAC,EAAE,YAAY;AACtC;AAWA,SAAS,mBAAmB,SAAyB;AACnD,SAAO,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AACxD;AAEO,SAAS,cACd,SACA,SACA,aACA,aACe;AAKf,MAAI,CAAC,WAAW,CAAC,eAAe,eAAe,KAAM,QAAO;AAC5D,SAAO,GAAG,mBAAmB,OAAO,CAAC,IAAI,OAAO,aAAa,WAAW,WAAW,WAAW;AAChG;AAEO,SAAS,gBACd,SACA,SACA,aACe;AACf,MAAI,CAAC,WAAW,CAAC,YAAa,QAAO;AACrC,SAAO,GAAG,mBAAmB,OAAO,CAAC,IAAI,OAAO,aAAa,WAAW;AAC1E;;;AFNO,SAAS,eAAe,KAAqB;AAClD,QAAM,MAAO,IAAc,WAAW,OAAO,GAAG;AAChD,MAAI,YAAY,KAAK,GAAG,GAAG;AACzB,gBAAY,mEAA8D;AAAA,EAC5E,WAAW,YAAY,KAAK,GAAG,GAAG;AAChC,gBAAY,6DAA6D;AAAA,EAC3E,OAAO;AACL,gBAAY,GAAG;AAAA,EACjB;AACA,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,iBAAiB,CAAC,WAAW,QAAQ,eAAe,QAAQ,WAAW;AAC7E,IAAM,kBAA0C,EAAE,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM;AAEhG,eAAsB,WAAW,QAAqB,iBAAwC;AAC5F,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,IAAqB,WAAW;AAC9D,MAAI,CAAC,QAAQ,KAAK,WAAW,GAAG;AAC9B,gBAAY,2CAA2C;AACvD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,KAAK,WAAW,EAAG,QAAO,KAAK,CAAC;AAGpC,QAAM,EAAE,YAAAC,YAAW,IAAI,MAAM;AAC7B,QAAM,SAASA,YAAW;AAC1B,QAAM,OAAO,mBAAmB,QAAQ,IAAI,aAAa,OAAO;AAEhE,MAAI,MAAM;AACR,UAAM,QAAQ,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC9C,QAAI,MAAO,QAAO;AAClB,gBAAY,QAAQ,IAAI,2BAA2B,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AACvF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,cAAY,4FAA4F,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAC5I,UAAQ,KAAK,CAAC;AAChB;AAEA,eAAsB,aAAa,QAAqB,iBAA2C;AACjG,UAAQ,MAAM,WAAW,QAAQ,eAAe,GAAG;AACrD;AAMA,eAAsB,gBACpB,QACA,OACsC;AACtC,QAAM,EAAE,SAAS,IAAI,MAAM,OAAO;AAAA,IAChC,aAAa,KAAK;AAAA,EACpB;AACA,QAAM,MAAM,oBAAI,IAA4B;AAC5C,aAAW,KAAK,YAAY,CAAC,EAAG,KAAI,IAAI,EAAE,IAAI,CAAC;AAC/C,SAAO;AACT;AAMO,SAAS,eACd,OACA,SACA,SACA,UACc;AACd,QAAM,UAAU,MAAM,aAAa,SAAS,IAAI,MAAM,UAAU,IAAI;AACpE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,KAAK,cAAc,SAAS,SAAS,SAAS,MAAM,MAAM,UAAU,IAAI;AAAA,EAC1E;AACF;AAMA,eAAsB,eAAe,QAAqB,OAAe,YAAqC;AAE5G,MAAI,kEAAkE,KAAK,UAAU,GAAG;AACtF,WAAO;AAAA,EACT;AAIA,QAAM,QAAQ,WAAW,MAAM,2BAA2B;AAC1D,MAAI,CAAC,OAAO;AACV,gBAAY,wBAAwB,UAAU,iDAAiD;AAC/F,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,MAAM,SAAS,MAAM,CAAC,GAAG,EAAE;AAGjC,QAAM,EAAE,OAAO,IAAI,MAAM,OAAO;AAAA,IAC9B,aAAa,KAAK,kBAAkB,GAAG;AAAA,EACzC;AACA,MAAI,OAAO,SAAS,KAAK,OAAO,CAAC,EAAE,WAAW,KAAK;AACjD,WAAO,OAAO,CAAC,EAAE;AAAA,EACnB;AAGA,MAAI,SAAS;AACb,QAAM,WAAW;AACjB,SAAO,MAAM;AACX,UAAM,OAAO,MAAM,OAAO;AAAA,MACxB,aAAa,KAAK,iBAAiB,QAAQ,WAAW,MAAM;AAAA,IAC9D;AACA,UAAM,QAAQ,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG;AACtD,QAAI,MAAO,QAAO,MAAM;AACxB,cAAU;AACV,QAAI,UAAU,KAAK,MAAO;AAAA,EAC5B;AAEA,cAAY,UAAU,GAAG,aAAa;AACtC,UAAQ,KAAK,CAAC;AAChB;AAEA,SAAS,iBAAiB,OAAc,UAAgD;AACtF,MAAI,MAAM,UAAU,KAAM,QAAO,MAAM,GAAG,MAAM,GAAG,CAAC;AACpD,MAAI,YAAY,MAAM,YAAY;AAChC,UAAM,UAAU,SAAS,IAAI,MAAM,UAAU;AAC7C,QAAI,SAAS,KAAM,QAAO,GAAG,aAAa,QAAQ,IAAI,CAAC,IAAI,MAAM,MAAM;AAAA,EACzE;AACA,SAAO,SAAS,MAAM,MAAM;AAC9B;AAEA,SAAS,OAAO,KAAa,KAAqB;AAChD,SAAO,IAAI,UAAU,MAAM,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,OAAO,MAAM,IAAI,MAAM;AAClF;AAMO,IAAM,eAAe,IAAI,0BAAQ,OAAO,EAC5C,YAAY,eAAe,EAC3B,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+CAOuB;AAG/C,aACG,QAAQ,MAAM,EACd,YAAY,aAAa,EACzB,OAAO,qBAAqB,qBAAqB,eAAe,KAAK,IAAI,CAAC,GAAG,EAC7E,OAAO,qBAAqB,uBAAuB,EACnD,OAAO,kBAAkB,0DAA0D,QAAQ,EAC3F,OAAO,eAAe,uBAAuB,QAAQ,EACrD,OAAO,OAAO,SAAoF;AACjG,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,MAAM,MAAM,WAAW,MAAM;AAEnC,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,QAAI,KAAK,SAAU,QAAO,IAAI,cAAc,KAAK,QAAQ;AACzD,QAAI,KAAK,aAAa,OAAW,QAAO,IAAI,YAAY,OAAO,KAAK,QAAQ,CAAC;AAC7E,QAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AAEpE,UAAM,KAAK,OAAO,SAAS;AAC3B,UAAM,CAAC,MAAM,QAAQ,IAAI,MAAM,QAAQ,IAAI;AAAA,MACzC,OAAO,IAAkB,aAAa,IAAI,EAAE,UAAU,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,MAC1E,gBAAgB,QAAQ,IAAI,EAAE;AAAA,IAChC,CAAC;AAED,UAAM,WAAW,KAAK,OAAO;AAAA,MAAI,CAAC,UAChC,eAAe,OAAO,OAAO,SAAS,IAAI,MAAM,QAAQ;AAAA,IAC1D;AAGA,QAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACjE,iBAAW,SAAS,UAAU;AAC5B,gBAAQ,OAAO,MAAM,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,MACnD;AACA;AAAA,IACF;AAGA,QAAI,SAAS,WAAW,GAAG;AACzB,cAAQ,IAAI,kBAAkB;AAC9B;AAAA,IACF;AAEA,UAAM,SAAS,KAAK,GAAG,OAAO,MAAM,EAAE,CAAC,IAAI,OAAO,UAAU,EAAE,CAAC,IAAI,OAAO,OAAO,CAAC,CAAC,QAAQ;AAC3F,YAAQ,IAAI,MAAM;AAClB,YAAQ,IAAI,SAAI,OAAO,EAAE,CAAC;AAC1B,eAAW,SAAS,UAAU;AAC5B,YAAM,KAAK,iBAAiB,OAAO,QAAQ;AAC3C,YAAM,MAAM,gBAAgB,MAAM,QAAQ,KAAK,OAAO,MAAM,QAAQ;AACpE,YAAM,QAAQ,MAAM,MAAM,SAAS,KAAK,MAAM,MAAM,MAAM,GAAG,EAAE,IAAI,WAAM,MAAM;AAC/E,YAAM,OAAO,aAAa,MAAM,QAAQ;AACxC,cAAQ,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,IAAI,YAAY,MAAM,QAAQ,OAAO,MAAM,QAAQ,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,OAAO,KAAK,CAAC,CAAC,IAAI,KAAK,EAAE;AAAA,IAC3H;AACA,YAAQ,IAAI,IAAI,GAAG,SAAS,MAAM,OAAO,KAAK,KAAK,SAAS,CAAC;AAAA,EAC/D,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,aACG,QAAQ,mBAAmB,EAC3B,YAAY,0DAA0D,EACtE,OAAO,OAAO,eAAuB;AACpC,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,MAAM,MAAM,WAAW,MAAM;AACnC,UAAM,UAAU,MAAM,eAAe,QAAQ,IAAI,IAAI,UAAU;AAE/D,UAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC9C,OAAO,IAAoB,aAAa,IAAI,EAAE,WAAW,OAAO,EAAE;AAAA,MAClE,gBAAgB,QAAQ,IAAI,EAAE;AAAA,IAChC,CAAC;AAED,UAAM,WAAW,eAAe,OAAO,OAAO,SAAS,IAAI,MAAM,QAAQ;AAGzE,QAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACjE,cAAQ,OAAO,MAAM,KAAK,UAAU,QAAQ,IAAI,IAAI;AACpD;AAAA,IACF;AAGA,UAAM,KAAK,iBAAiB,UAAU,QAAQ;AAC9C,UAAM,MAAM,gBAAgB,SAAS,QAAQ,KAAK,OAAO,SAAS,QAAQ;AAC1E,YAAQ,IAAI,GAAG,KAAK,EAAE,CAAC,IAAI,SAAS,KAAK,EAAE;AAC3C,YAAQ,IAAI,WAAW,YAAY,SAAS,QAAQ,SAAS,MAAM,CAAC,eAAe,aAAa,SAAS,QAAQ,CAAC,IAAI,GAAG,EAAE;AAC3H,QAAI,SAAS,IAAK,SAAQ,IAAI,QAAQ,SAAS,GAAG,EAAE;AACpD,QAAI,SAAS,YAAa,SAAQ,IAAI,aAAa,SAAS,WAAW,EAAE;AACzE,QAAI,SAAS,SAAU,SAAQ,IAAI,QAAQ,SAAS,QAAQ,EAAE;AAC9D,QAAI,SAAS,aAAa;AACxB,cAAQ,IAAI;AAAA,EAAK,SAAS,WAAW,EAAE;AAAA,IACzC;AACA,QAAI,SAAS,gBAAgB,SAAS,aAAa,SAAS,GAAG;AAC7D,YAAM,SAAS,SAAS,aAAa,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,KAAK,IAAI;AACxE,cAAQ,IAAI,WAAW,MAAM,EAAE;AAAA,IACjC;AACA,QAAI,SAAS,aAAa,MAAM,QAAQ,SAAS,SAAS,KAAK,SAAS,UAAU,SAAS,GAAG;AAC5F,cAAQ,IAAI;AAAA,YAAe,SAAS,UAAU,MAAM,EAAE;AAAA,IACxD;AACA,QAAI,SAAS,WAAY,SAAQ,IAAI,IAAI,YAAY,SAAS,UAAU,EAAE,CAAC;AAC3E,QAAI,SAAS,WAAY,SAAQ,IAAI,IAAI,YAAY,SAAS,UAAU,EAAE,CAAC;AAAA,EAC7E,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,aACG,QAAQ,QAAQ,EAChB,YAAY,oBAAoB,EAChC,eAAe,mBAAmB,aAAa,EAC/C,OAAO,wBAAwB,mBAAmB,EAClD,OAAO,qBAAqB,WAAW,eAAe,KAAK,IAAI,CAAC,GAAG,EACnE,OAAO,kBAAkB,gDAAgD,QAAQ,EACjF,OAAO,OAAO,SAAsF;AACnG,MAAI;AACF,QAAI,KAAK,UAAU,CAAC,eAAe,SAAS,KAAK,MAAuC,GAAG;AACzF,kBAAY,mBAAmB,KAAK,MAAM,sBAAsB,eAAe,KAAK,IAAI,CAAC,EAAE;AAC3F,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,QAAI,KAAK,aAAa,UAAa,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,SAAS,KAAK,QAAQ,GAAG;AACxE,kBAAY,gEAAgE;AAC5E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,MAAM,MAAM,WAAW,MAAM;AAEnC,UAAM,OAAgC,EAAE,OAAO,KAAK,MAAM;AAC1D,QAAI,KAAK,gBAAgB,OAAW,MAAK,cAAc,KAAK;AAC5D,QAAI,KAAK,OAAQ,MAAK,SAAS,KAAK;AACpC,QAAI,KAAK,aAAa,OAAW,MAAK,WAAW,KAAK;AAEtD,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,KAAqB,aAAa,IAAI,EAAE,WAAW,IAAI;AACtF,UAAM,WAAW,MAAM,gBAAgB,QAAQ,IAAI,EAAE;AACrD,UAAM,WAAW,eAAe,OAAO,OAAO,SAAS,IAAI,MAAM,QAAQ;AAEzE;AAAA,MACE,EAAE,OAAO,SAAS;AAAA,MAClB,QAAQ,WAAW,iBAAiB,UAAU,QAAQ,CAAC,KAAK,SAAS,KAAK,GAAG,SAAS,MAAM;AAAA,EAAK,SAAS,GAAG,KAAK,EAAE,EAAE;AAAA,IACxH;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,aACG,QAAQ,qBAAqB,EAC7B,YAAY,iBAAiB,EAC7B,OAAO,eAAe,WAAW,EACjC,OAAO,gBAAgB,eAAe,eAAe,KAAK,IAAI,CAAC,GAAG,EAClE,OAAO,kBAAkB,sBAAsB,QAAQ,EACvD,OAAO,OAAO,YAAoB,SAAiE;AAClG,MAAI;AACF,QAAI,KAAK,UAAU,CAAC,eAAe,SAAS,KAAK,MAAuC,GAAG;AACzF,kBAAY,mBAAmB,KAAK,MAAM,sBAAsB,eAAe,KAAK,IAAI,CAAC,EAAE;AAC3F,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,QAAI,KAAK,aAAa,UAAa,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,SAAS,KAAK,QAAQ,GAAG;AACxE,kBAAY,uBAAuB;AACnC,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,OAAgC,CAAC;AACvC,QAAI,KAAK,UAAU,OAAW,MAAK,QAAQ,KAAK;AAChD,QAAI,KAAK,OAAQ,MAAK,SAAS,KAAK;AACpC,QAAI,KAAK,aAAa,OAAW,MAAK,WAAW,KAAK;AAEtD,QAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,kBAAY,gEAAgE;AAC5E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,MAAM,MAAM,WAAW,MAAM;AACnC,UAAM,UAAU,MAAM,eAAe,QAAQ,IAAI,IAAI,UAAU;AAE/D,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,MAAsB,aAAa,IAAI,EAAE,WAAW,OAAO,IAAI,IAAI;AAClG,UAAM,WAAW,MAAM,gBAAgB,QAAQ,IAAI,EAAE;AACrD,UAAM,WAAW,eAAe,OAAO,OAAO,SAAS,IAAI,MAAM,QAAQ;AAEzE;AAAA,MACE,EAAE,OAAO,SAAS;AAAA,MAClB,QAAQ,WAAW,iBAAiB,UAAU,QAAQ,CAAC,KAAK,SAAS,KAAK,EAAE;AAAA,IAC9E;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,aACG,QAAQ,qBAAqB,EAC7B,YAAY,oCAAoC,EAChD,OAAO,OAAO,eAAuB;AACpC,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,QAAQ,MAAM,aAAa,MAAM;AACvC,UAAM,UAAU,MAAM,eAAe,QAAQ,OAAO,UAAU;AAE9D,UAAM,OAAO,OAAO,aAAa,KAAK,WAAW,OAAO,EAAE;AAE1D;AAAA,MACE,EAAE,SAAS,MAAM,IAAI,QAAQ;AAAA,MAC7B,QAAQ,iBAAiB,UAAU,EAAE;AAAA,IACvC;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,aACG,QAAQ,qBAAqB,EAC7B,YAAY,oCAAoC,EAChD,eAAe,eAAe,sCAAsC,EACpE,OAAO,OAAO,YAAoB,SAAyB;AAC1D,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,MAAM,MAAM,WAAW,MAAM;AACnC,UAAM,UAAU,MAAM,eAAe,QAAQ,IAAI,IAAI,UAAU;AAE/D,QAAI,aAAa,KAAK;AACtB,QAAI,eAAe,QAAQ;AACzB,YAAM,KAAK,MAAM,OAAO,IAAoC,cAAc;AAE1E,YAAM,eAAe,GAAG,MAAM;AAC9B,UAAI,CAAC,cAAc;AACjB,oBAAY,iCAAiC;AAC7C,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAGA,YAAM,EAAE,QAAQ,IAAI,MAAM,OAAO;AAAA,QAC/B,aAAa,IAAI,EAAE;AAAA,MACrB;AACA,YAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,gBAAgB,EAAE,YAAY,YAAY;AACtF,UAAI,CAAC,QAAQ;AACX,oBAAY,4CAA4C;AACxD,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,mBAAa,OAAO;AAAA,IACtB;AAEA,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO;AAAA,MAC7B,aAAa,IAAI,EAAE,WAAW,OAAO;AAAA,MACrC,EAAE,aAAa,WAAW;AAAA,IAC5B;AACA,UAAM,WAAW,MAAM,gBAAgB,QAAQ,IAAI,EAAE;AACrD,UAAM,WAAW,eAAe,OAAO,OAAO,SAAS,IAAI,MAAM,QAAQ;AAEzE;AAAA,MACE,EAAE,OAAO,SAAS;AAAA,MAClB,QAAQ,YAAY,iBAAiB,UAAU,QAAQ,CAAC,OAAO,KAAK,EAAE,EAAE;AAAA,IAC1E;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,aACG,QAAQ,uBAAuB,EAC/B,YAAY,+BAA+B,EAC3C,OAAO,OAAO,eAAuB;AACpC,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,MAAM,MAAM,WAAW,MAAM;AACnC,UAAM,UAAU,MAAM,eAAe,QAAQ,IAAI,IAAI,UAAU;AAE/D,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO;AAAA,MAC7B,aAAa,IAAI,EAAE,WAAW,OAAO;AAAA,MACrC,EAAE,aAAa,KAAK;AAAA,IACtB;AACA,UAAM,WAAW,MAAM,gBAAgB,QAAQ,IAAI,EAAE;AACrD,UAAM,WAAW,eAAe,OAAO,OAAO,SAAS,IAAI,MAAM,QAAQ;AAEzE;AAAA,MACE,EAAE,OAAO,SAAS;AAAA,MAClB,QAAQ,cAAc,iBAAiB,UAAU,QAAQ,CAAC,EAAE;AAAA,IAC9D;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;;;AGxeH,IAAAC,oBAAwB;AAsCxB,IAAMC,QAAO;AACb,IAAMC,OAAM;AACZ,IAAMC,SAAQ;AACd,IAAM,OAAO;AAEb,SAAS,aAAa,SAA0B;AAC9C,QAAM,OAAO,QAAQ,QAAQ,gBAAgB,QAAQ;AACrD,QAAM,SAAS,QAAQ,QAAQ,QAAQ,QAAQ,iBAAiB,UAAU,aAAa;AACvF,SAAO,GAAG,IAAI,GAAG,KAAK;AACxB;AAEA,SAAS,gBAAgB,IAAqB;AAC5C,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,IAAI,IAAI,KAAK,EAAE;AACrB,SAAO,EAAE,eAAe;AAC1B;AAMO,IAAM,iBAAiB,IAAI,0BAAQ,SAAS,EAChD,YAAY,uBAAuB;AAGtC,eACG,QAAQ,mBAAmB,EAC3B,YAAY,iEAAiE,EAC7E,OAAO,OAAO,eAAuB;AACpC,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,QAAQ,MAAM,aAAa,MAAM;AACvC,UAAM,UAAU,MAAM,eAAe,QAAQ,OAAO,UAAU;AAE9D,UAAM,OAAO,MAAM,OAAO;AAAA,MACxB,aAAa,KAAK,WAAW,OAAO;AAAA,IACtC;AAGA,QAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACjE,iBAAW,WAAW,KAAK,UAAU;AACnC,gBAAQ,OAAO,MAAM,KAAK,UAAU,OAAO,IAAI,IAAI;AAAA,MACrD;AACA;AAAA,IACF;AAGA,QAAI,KAAK,SAAS,WAAW,GAAG;AAC9B,cAAQ,IAAI,oBAAoB;AAChC;AAAA,IACF;AAEA,eAAW,WAAW,KAAK,UAAU;AACnC,YAAM,SAAS,aAAa,OAAO;AACnC,YAAM,OAAO,gBAAgB,QAAQ,UAAU;AAC/C,cAAQ,IAAI,GAAGF,KAAI,GAAG,IAAI,GAAG,MAAM,GAAGE,MAAK,IAAID,IAAG,GAAG,IAAI,GAAGC,MAAK,EAAE;AACnE,cAAQ,IAAI,QAAQ,IAAI;AACxB,cAAQ,IAAI;AAAA,IACd;AACA,YAAQ,IAAI,GAAGD,IAAG,GAAG,KAAK,SAAS,MAAM,cAAcC,MAAK,EAAE;AAAA,EAChE,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,eACG,QAAQ,kBAAkB,EAC1B,YAAY,2BAA2B,EACvC,eAAe,iBAAiB,cAAc,EAC9C,OAAO,OAAO,YAAoB,SAA2B;AAC5D,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,QAAQ,MAAM,aAAa,MAAM;AACvC,UAAM,UAAU,MAAM,eAAe,QAAQ,OAAO,UAAU;AAE9D,UAAM,EAAE,QAAQ,IAAI,MAAM,OAAO;AAAA,MAC/B,aAAa,KAAK,WAAW,OAAO;AAAA,MACpC,EAAE,MAAM,KAAK,KAAK;AAAA,IACpB;AAEA;AAAA,MACE,EAAE,QAAQ;AAAA,MACV,2BAAsB,UAAU;AAAA,IAClC;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,eACG,QAAQ,qBAAqB,EAC7B,YAAY,kBAAkB,EAC9B,eAAe,iBAAiB,kBAAkB,EAClD,eAAe,wBAAwB,+CAA+C,EACtF,OAAO,OAAO,WAAmB,SAA0C;AAC1E,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,QAAQ,MAAM,aAAa,MAAM;AACvC,UAAM,UAAU,MAAM,eAAe,QAAQ,OAAO,KAAK,KAAK;AAE9D,UAAM,EAAE,QAAQ,IAAI,MAAM,OAAO;AAAA,MAC/B,aAAa,KAAK,WAAW,OAAO,aAAa,SAAS;AAAA,MAC1D,EAAE,MAAM,KAAK,KAAK;AAAA,IACpB;AAEA;AAAA,MACE,EAAE,QAAQ;AAAA,MACV,kBAAa,SAAS;AAAA,IACxB;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,eACG,QAAQ,qBAAqB,EAC7B,YAAY,kBAAkB,EAC9B,eAAe,wBAAwB,+CAA+C,EACtF,OAAO,OAAO,WAAmB,SAA4B;AAC5D,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,QAAQ,MAAM,aAAa,MAAM;AACvC,UAAM,UAAU,MAAM,eAAe,QAAQ,OAAO,KAAK,KAAK;AAE9D,UAAM,OAAO,OAAO,aAAa,KAAK,WAAW,OAAO,aAAa,SAAS,EAAE;AAEhF;AAAA,MACE,EAAE,SAAS,MAAM,IAAI,UAAU;AAAA,MAC/B,kBAAa,SAAS;AAAA,IACxB;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;;;AC9KH,IAAAC,oBAAwB;AAqBxB,SAAS,iBAAoC,SAAY,SAAiB,SAA6C;AACrH,SAAO,EAAE,GAAG,SAAS,KAAK,gBAAgB,SAAS,SAAS,QAAQ,IAAI,EAAE;AAC5E;AAUA,SAAS,YAAY,UAAkB,QAAQ,IAAY;AACzD,QAAM,SAAS,KAAK,MAAO,WAAW,MAAO,KAAK;AAClD,QAAM,QAAQ,QAAQ;AACtB,SAAO,IAAI,SAAI,OAAO,MAAM,CAAC,GAAG,SAAI,OAAO,KAAK,CAAC,KAAK,QAAQ;AAChE;AAEO,IAAM,iBAAiB,IAAI,0BAAQ,SAAS,EAChD,YAAY,iBAAiB,EAC7B,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA,oCAIY;AAIpC,eACG,QAAQ,MAAM,EACd,YAAY,iCAAiC,EAC7C,OAAO,YAAY;AAClB,QAAM,SAAS,IAAI,YAAY;AAC/B,MAAI;AACF,UAAM,MAAM,MAAM,WAAW,MAAM;AACnC,UAAM,OAAO,MAAM,OAAO,IAA6B,aAAa,IAAI,EAAE,WAAW;AACrF,UAAM,YAAY,KAAK,YAAY,CAAC,GAAG,IAAI,CAAC,MAAM,iBAAiB,GAAG,OAAO,SAAS,IAAI,IAAI,CAAC;AAE/F,QAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACjE,iBAAW,KAAK,UAAU;AACxB,gBAAQ,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,IAAI;AAAA,MAC/C;AACA;AAAA,IACF;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,cAAQ,IAAI,IAAI,oBAAoB,CAAC;AACrC;AAAA,IACF;AAEA,eAAW,KAAK,UAAU;AACxB,YAAM,WAAW,EAAE,YAAY;AAC/B,YAAM,MAAM,YAAY,QAAQ;AAChC,cAAQ,IAAI,GAAG,KAAK,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE;AAChE,UAAI,EAAE,YAAa,SAAQ,IAAI,KAAK,IAAI,EAAE,WAAW,CAAC,EAAE;AACxD,cAAQ,IAAI,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,YAAY,EAAE,kBAAkB,CAAC,OAAO;AACxF,UAAI,EAAE,IAAK,SAAQ,IAAI,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE;AACxC,UAAI,EAAE,WAAW,WAAY,SAAQ,IAAI,KAAK,IAAI,YAAY,CAAC,EAAE;AACjE,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAIH,eACG,QAAQ,QAAQ,EAChB,YAAY,sBAAsB,EAClC,eAAe,iBAAiB,cAAc,EAC9C,OAAO,wBAAwB,qBAAqB,EACpD,OAAO,mBAAmB,uBAAuB,SAAS,EAC1D,OAAO,iBAAiB,wBAAwB,WAAI,EACpD,OAAO,OAAO,SAAS;AACtB,QAAM,SAAS,IAAI,YAAY;AAC/B,MAAI;AACF,UAAM,MAAM,MAAM,WAAW,MAAM;AACnC,UAAM,OAAO,MAAM,OAAO,KAA2B,aAAa,IAAI,EAAE,aAAa;AAAA,MACnF,MAAM,KAAK;AAAA,MACX,aAAa,KAAK,eAAe;AAAA,MACjC,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,IACb,CAAC;AACD,UAAM,UAAU,iBAAiB,KAAK,SAAS,OAAO,SAAS,IAAI,IAAI;AAEvE;AAAA,MACE,EAAE,QAAQ;AAAA,MACV,QAAQ,mBAAmB,QAAQ,IAAI,IAAI,QAAQ,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC,IAAI,QAAQ,MAAM;AAAA,EAAK,QAAQ,GAAG,KAAK,EAAE,EAAE;AAAA,IACxH;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAIH,eACG,QAAQ,kBAAkB,EAC1B,YAAY,iCAAiC,EAC7C,OAAO,OAAO,cAAc;AAC3B,QAAM,SAAS,IAAI,YAAY;AAC/B,MAAI;AACF,UAAM,MAAM,MAAM,WAAW,MAAM;AACnC,UAAM,OAAO,MAAM,OAAO;AAAA,MACxB,aAAa,IAAI,EAAE,aAAa,SAAS;AAAA,IAC3C;AACA,UAAM,IAAI,iBAAiB,KAAK,SAAS,OAAO,SAAS,IAAI,IAAI;AAEjE,QAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACjE,cAAQ,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,IAAI;AAC7C;AAAA,IACF;AAEA,UAAM,WAAW,EAAE,YAAY;AAC/B,YAAQ,IAAI,KAAK,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC;AACvC,QAAI,EAAE,YAAa,SAAQ,IAAI,KAAK,EAAE,WAAW,EAAE;AACnD,QAAI,EAAE,IAAK,SAAQ,IAAI,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE;AACxC,YAAQ,IAAI,KAAK,KAAK,YAAY,QAAQ,CAAC,CAAC,EAAE;AAC9C,YAAQ,IAAI,KAAM,EAAE,cAAc,CAAE,gBAAc,EAAE,kBAAkB,CAAE,YAAY;AACpF,YAAQ,IAAI,EAAE;AAEd,UAAM,SAAmB,EAAsC,UAAU,CAAC;AAC1E,QAAI,OAAO,WAAW,GAAG;AACvB,cAAQ,IAAI,IAAI,4BAA4B,CAAC;AAC7C;AAAA,IACF;AAEA,YAAQ,IAAI,KAAK,QAAQ,CAAC;AAC1B,eAAW,SAAS,QAAQ;AAC1B,YAAM,MAAM,MAAM,SAAS,IAAI,MAAM,MAAM,KAAK,MAAM,GAAG,MAAM,GAAG,CAAC;AACnE,cAAQ,IAAI,KAAK,IAAI,GAAG,CAAC,KAAK,MAAM,KAAK,KAAK,IAAI,IAAI,MAAM,MAAM,GAAG,CAAC,EAAE;AAAA,IAC1E;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;;;AC7JH,IAAAC,oBAAwB;AAkBxB,SAASC,aAAY,UAAkB,QAAQ,IAAY;AACzD,QAAM,SAAS,KAAK,MAAO,WAAW,MAAO,KAAK;AAClD,QAAM,QAAQ,QAAQ;AACtB,SAAO,IAAI,SAAI,OAAO,MAAM,CAAC,GAAG,SAAI,OAAO,KAAK,CAAC,KAAK,QAAQ;AAChE;AAEO,IAAM,mBAAmB,IAAI,0BAAQ,WAAW,EACpD,YAAY,mBAAmB,EAC/B,YAAY,SAAS;AAAA;AAAA;AAAA,kFAG0D;AAIlF,iBACG,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,eAAe,kBAAkB,YAAY,EAC7C,OAAO,OAAO,SAAS;AACtB,QAAM,SAAS,IAAI,YAAY;AAC/B,MAAI;AACF,UAAM,QAAQ,MAAM,aAAa,MAAM;AACvC,UAAM,OAAO,MAAM,OAAO;AAAA,MACxB,aAAa,KAAK,aAAa,KAAK,OAAO;AAAA,IAC7C;AACA,UAAM,aAAa,KAAK,cAAc,CAAC;AAEvC,QAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACjE,iBAAW,KAAK,YAAY;AAC1B,gBAAQ,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,IAAI;AAAA,MAC/C;AACA;AAAA,IACF;AAEA,QAAI,WAAW,WAAW,GAAG;AAC3B,cAAQ,IAAI,IAAI,sBAAsB,CAAC;AACvC;AAAA,IACF;AAEA,eAAW,KAAK,YAAY;AAC1B,YAAM,WAAW,EAAE,YAAY;AAC/B,YAAM,MAAMA,aAAY,QAAQ;AAChC,YAAM,UAAU,EAAE,YAAY,IAAI,IAAI,WAAW,CAAC,KAAK;AACvD,cAAQ,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC,GAAG,OAAO,EAAE;AAC3D,UAAI,EAAE,SAAU,SAAQ,IAAI,UAAU,EAAE,QAAQ,EAAE;AAClD,UAAI,EAAE,YAAa,SAAQ,IAAI,KAAK,IAAI,EAAE,WAAW,CAAC,EAAE;AACxD,cAAQ,IAAI,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,YAAY,EAAE,kBAAkB,CAAC,OAAO;AACxF,UAAI,EAAE,WAAW,SAAU,SAAQ,IAAI,KAAK,IAAI,UAAU,CAAC,EAAE;AAC7D,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAIH,iBACG,QAAQ,QAAQ,EAChB,YAAY,wBAAwB,EACpC,eAAe,kBAAkB,YAAY,EAC7C,eAAe,iBAAiB,gBAAgB,EAChD,OAAO,uBAAuB,UAAU,EACxC,OAAO,wBAAwB,aAAa,EAC5C,OAAO,OAAO,SAAS;AACtB,QAAM,SAAS,IAAI,YAAY;AAC/B,MAAI;AACF,UAAM,QAAQ,MAAM,aAAa,MAAM;AACvC,UAAM,OAAO,MAAM,OAAO;AAAA,MACxB,aAAa,KAAK,aAAa,KAAK,OAAO;AAAA,MAC3C;AAAA,QACE,MAAM,KAAK;AAAA,QACX,aAAa,KAAK,eAAe;AAAA,QACjC,SAAS,KAAK,QAAQ;AAAA,MACxB;AAAA,IACF;AAEA;AAAA,MACE,EAAE,WAAW,KAAK,UAAU;AAAA,MAC5B,QAAQ,sBAAsB,KAAK,KAAK,UAAU,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,UAAU,EAAE,GAAG,CAAC,EAAE;AAAA,IAC5F;AACA,QAAI,KAAK,UAAU,UAAU;AAC3B,cAAQ,IAAI,UAAU,KAAK,UAAU,QAAQ,EAAE;AAAA,IACjD;AAAA,EACF,SAAS,KAAK;AACZ,mBAAe,GAAG;AAAA,EACpB;AACF,CAAC;;;AC1GH,IAAAC,oBAAwB;AACxB;AAKO,IAAM,gBAAgB,IAAI,0BAAQ,QAAQ,EAC9C,YAAY,+CAA+C,EAC3D,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA,sCAIc;AAItC,cACG,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,OAAO,MAAM;AACZ,QAAM,MAAM,WAAW;AACvB,QAAM,YAAY,CAAC,EAAE,QAAQ,IAAI,iBAAiB,IAAI;AAEtD,MAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACjE;AAAA,MACE;AAAA,QACE,SAAS,IAAI,WAAW;AAAA,QACxB,aAAa,IAAI,eAAe;AAAA,QAChC;AAAA,MACF;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AAEA,UAAQ,IAAI,GAAG,KAAK,yBAAyB,CAAC,EAAE;AAChD,UAAQ,IAAI,KAAK,IAAI,WAAW,CAAC,OAAO,IAAI,UAAU,KAAK,IAAI,OAAO,IAAI,KAAK,WAAW,CAAC,EAAE;AAC7F,UAAQ,IAAI,KAAK,IAAI,eAAe,CAAC,IAAI,IAAI,cAAc,KAAK,IAAI,WAAW,IAAI,KAAK,WAAW,CAAC,EAAE;AACtG,UAAQ,IAAI,KAAK,IAAI,UAAU,CAAC,QAAQ,YAAY,KAAK,KAAK,IAAI,KAAK,uCAAkC,CAAC,EAAE;AAC9G,CAAC;AAIH,cACG,QAAQ,gBAAgB,EACxB,YAAY,mCAAmC,EAC/C,OAAO,CAAC,SAAiB;AACxB,QAAM,MAAM,WAAW;AACvB,MAAI,UAAU;AACd,cAAY,GAAG;AAEf;AAAA,IACE,EAAE,SAAS,KAAK;AAAA,IAChB,QAAQ,uBAAuB,IAAI,GAAG;AAAA,EACxC;AACF,CAAC;AAIH,cACG,QAAQ,iBAAiB,EACzB,YAAY,iCAAiC,EAC7C,OAAO,CAAC,SAAiB;AACxB,QAAM,MAAM,WAAW;AACvB,MAAI,cAAc;AAClB,cAAY,GAAG;AAEf;AAAA,IACE,EAAE,aAAa,KAAK;AAAA,IACpB,QAAQ,wBAAwB,IAAI,GAAG;AAAA,EACzC;AACF,CAAC;;;ACvEH,IAAAC,oBAAwB;AA8BxB,SAASC,gBAAe,KAAqB;AAC3C,QAAM,MAAO,IAAc,WAAW,OAAO,GAAG;AAChD,MAAI,YAAY,KAAK,GAAG,GAAG;AACzB,gBAAY,mEAA8D;AAAA,EAC5E,WAAW,YAAY,KAAK,GAAG,GAAG;AAChC,gBAAY,6DAA6D;AAAA,EAC3E,OAAO;AACL,gBAAY,GAAG;AAAA,EACjB;AACA,UAAQ,KAAK,CAAC;AAChB;AAEA,eAAeC,cAAa,QAAqB,iBAA2C;AAC1F,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,IAA8C,WAAW;AACvF,MAAI,CAAC,QAAQ,KAAK,WAAW,GAAG;AAC9B,gBAAY,yBAAyB;AACrC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,KAAK,WAAW,EAAG,QAAO,KAAK,CAAC,EAAE;AAEtC,QAAM,EAAE,YAAAC,YAAW,IAAI,MAAM;AAC7B,QAAM,SAASA,YAAW;AAC1B,QAAM,OAAO,mBAAmB,QAAQ,IAAI,aAAa,OAAO;AAEhE,MAAI,MAAM;AACR,UAAM,QAAQ,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC9C,QAAI,MAAO,QAAO,MAAM;AACxB,gBAAY,QAAQ,IAAI,2BAA2B,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AACvF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,cAAY,wCAAwC;AACpD,UAAQ,KAAK,CAAC;AAChB;AAEA,SAASC,QAAO,KAAa,KAAqB;AAChD,SAAO,IAAI,UAAU,MAAM,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,OAAO,MAAM,IAAI,MAAM;AAClF;AAMO,IAAM,iBAAiB,IAAI,0BAAQ,SAAS,EAChD,YAAY,0BAA0B,EACtC,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA,8BAIM;AAG9B,eACG,QAAQ,MAAM,EACd,YAAY,mCAAmC,EAC/C,OAAO,YAAY;AAClB,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,QAAQ,MAAMF,cAAa,MAAM;AAEvC,UAAM,OAAO,MAAM,OAAO,IAAyB,uBAAuB,KAAK,EAAE;AAEjF,QAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACjE,iBAAW,MAAM,KAAK,UAAU;AAC9B,gBAAQ,OAAO,MAAM,KAAK,UAAU,EAAE,IAAI,IAAI;AAAA,MAChD;AACA;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,WAAW,GAAG;AAC9B,cAAQ,IAAI,yBAAyB;AACrC;AAAA,IACF;AAEA,UAAM,SAAS,KAAK,GAAGE,QAAO,MAAM,EAAE,CAAC,IAAIA,QAAO,OAAO,EAAE,CAAC,IAAIA,QAAO,UAAU,EAAE,CAAC,SAAS;AAC7F,YAAQ,IAAI,MAAM;AAClB,YAAQ,IAAI,SAAI,OAAO,GAAG,CAAC;AAC3B,eAAW,MAAM,KAAK,UAAU;AAC9B,YAAM,OAAO,GAAG,OAAO,WAAW,IAAI,QAAQ,GAAG,OAAO,KAAK,GAAG;AAChE,YAAM,SAAS,GAAG,UAAU,MAAM,KAAK,IAAI,KAAK,IAAI;AACpD,YAAM,MAAM,GAAG,IAAI,SAAS,KAAK,GAAG,IAAI,MAAM,GAAG,EAAE,IAAI,WAAM,GAAG;AAChE,YAAM,SAAS,KAAK,SAAS,KAAK,KAAK,MAAM,GAAG,EAAE,IAAI,WAAM;AAC5D,cAAQ,IAAI,GAAGA,QAAO,GAAG,GAAG,MAAM,GAAG,EAAE,GAAG,EAAE,CAAC,IAAIA,QAAO,KAAK,EAAE,CAAC,IAAIA,QAAO,QAAQ,EAAE,CAAC,IAAI,MAAM,EAAE;AAAA,IACpG;AACA,YAAQ,IAAI,IAAI,GAAG,KAAK,SAAS,MAAM,aAAa,CAAC;AAAA,EACvD,SAAS,KAAK;AACZ,IAAAH,gBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,eACG,QAAQ,QAAQ,EAChB,YAAY,sBAAsB,EAClC,eAAe,eAAe,qBAAqB,EACnD,OAAO,qBAAqB,8CAA8C,EAAE,EAC5E,OAAO,OAAO,SAA0C;AACvD,MAAI;AACF,QAAI,CAAC,KAAK,IAAI,WAAW,UAAU,GAAG;AACpC,kBAAY,qBAAqB;AACjC,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,KAAK,SAChB,KAAK,OAAO,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO,IAC1D,CAAC;AAEL,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,QAAQ,MAAMC,cAAa,MAAM;AAEvC,UAAM,OAAO,MAAM,OAAO;AAAA,MACxB,uBAAuB,KAAK;AAAA,MAC5B,EAAE,KAAK,KAAK,KAAK,OAAO;AAAA,IAC1B;AAEA;AAAA,MACE,EAAE,SAAS,KAAK,SAAS,QAAQ,KAAK,OAAO;AAAA,MAC7C;AAAA,QACE,QAAQ,mBAAmB,KAAK,QAAQ,EAAE,EAAE;AAAA,QAC5C;AAAA,QACA,KAAK,oDAA+C;AAAA,QACpD,KAAK,KAAK,MAAM;AAAA,MAClB,EAAE,KAAK,IAAI;AAAA,IACb;AAAA,EACF,SAAS,KAAK;AACZ,IAAAD,gBAAe,GAAG;AAAA,EACpB;AACF,CAAC;AAGH,eACG,QAAQ,aAAa,EACrB,YAAY,kBAAkB,EAC9B,OAAO,OAAO,OAAe;AAC5B,MAAI;AACF,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,OAAO,OAAO,iBAAiB,EAAE,EAAE;AAEzC;AAAA,MACE,EAAE,SAAS,MAAM,GAAG;AAAA,MACpB,QAAQ,mBAAmB,EAAE,EAAE;AAAA,IACjC;AAAA,EACF,SAAS,KAAK;AACZ,IAAAA,gBAAe,GAAG;AAAA,EACpB;AACF,CAAC;;;AXrKH,IAAM,UAAU,IAAI,0BAAQ,OAAO,EAChC,YAAY,uDAAkD,EAC9D,QAAQ,OAAO,EACf,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAOF,EAEnB,OAAO,gBAAgB,4CAA4C,EACnE,OAAO,eAAe,iDAAiD,EACvE,KAAK,aAAa,CAAC,gBAAgB;AAClC,QAAM,OAAO,YAAY,KAAK;AAC9B,MAAI,KAAK,IAAK,SAAQ,IAAI,YAAY,KAAK;AAC3C,MAAI,KAAK,KAAM,SAAQ,IAAI,aAAa,KAAK;AAC/C,CAAC;AAEH,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,YAAY;AAC/B,QAAQ,WAAW,cAAc;AACjC,QAAQ,WAAW,cAAc;AACjC,QAAQ,WAAW,gBAAgB;AACnC,QAAQ,WAAW,aAAa;AAChC,QAAQ,WAAW,cAAc;AAIjC,IAAM,oBAAoB,IAAI,0BAAQ,YAAY,EAC/C,YAAY,iCAAiC,EAC7C,YAAY,SAAS;AAAA;AAAA;AAAA,sCAGc;AAEtC,kBACG,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,OAAO,MAAM;AACZ,UAAQ,OAAO,MAAM,eAAe,CAAC;AACvC,CAAC;AAEH,kBACG,QAAQ,KAAK,EACb,YAAY,8BAA8B,EAC1C,OAAO,MAAM;AACZ,UAAQ,OAAO,MAAM,cAAc,CAAC;AACtC,CAAC;AAEH,QAAQ,WAAW,iBAAiB;AAEpC,QAAQ,MAAM;AAMd,SAAS,iBAAyB;AAChC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8DT;AAEA,SAAS,gBAAwB;AAC/B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0ET;","names":["import_commander","import_commander","readConfig","import_commander","BOLD","DIM","RESET","import_commander","import_commander","progressBar","import_commander","import_commander","handleApiError","resolveOrgId","readConfig","padEnd"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atollhq/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Atoll CLI — project management from the terminal",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",