@atollhq/cli 0.1.1 → 0.1.3

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
@@ -19,6 +19,26 @@ atoll auth status
19
19
 
20
20
  API keys are created in the Atoll web app under **Settings > Members > Add Agent** (for agents) or **Settings > Members > Create API Key** (for integrations).
21
21
 
22
+ ### Multiple auth profiles
23
+
24
+ Use profiles when you have multiple agent keys with different org or project access:
25
+
26
+ ```bash
27
+ atoll auth login --profile agent-a --key sk_atoll_... --org acme
28
+ atoll auth login --profile agent-b --key sk_atoll_... --org client
29
+ atoll auth profiles
30
+ atoll auth use agent-a
31
+ ```
32
+
33
+ Run a single command with a specific profile:
34
+
35
+ ```bash
36
+ atoll --profile agent-b issue list
37
+ atoll --profile agent-a --org acme issue create --title "Fix login bug"
38
+ ```
39
+
40
+ Each profile can store its own API key, default org, default team, and base URL. `--org` and `--team` still override the selected profile for a single command.
41
+
22
42
  ## Usage
23
43
 
24
44
  ```bash
@@ -34,14 +54,15 @@ Run `atoll --help` or `atoll <command> --help` for the full reference.
34
54
 
35
55
  ## Configuration
36
56
 
37
- The CLI stores state in `~/.atoll/config.json`. You can override the org or team per-command:
57
+ The CLI stores state in `~/.atoll/config.json`. You can override the profile, org, or team per-command:
38
58
 
39
59
  ```bash
60
+ atoll --profile agent-a issue list
40
61
  atoll --org my-org issue list
41
62
  atoll --team eng issue create --title "..."
42
63
  ```
43
64
 
44
- Or via env vars: `ATOLL_API_KEY`, `ATOLL_ORG`, `ATOLL_TEAM`, `ATOLL_BASE_URL`.
65
+ Or via env vars: `ATOLL_PROFILE`, `ATOLL_API_KEY`, `ATOLL_ORG`, `ATOLL_TEAM`, `ATOLL_BASE_URL`.
45
66
 
46
67
  ## Output URLs
47
68
 
package/dist/index.js CHANGED
@@ -14,8 +14,12 @@ var __export = (target, all) => {
14
14
  var config_exports = {};
15
15
  __export(config_exports, {
16
16
  deleteConfig: () => deleteConfig,
17
+ ensureProfile: () => ensureProfile,
18
+ getActiveProfile: () => getActiveProfile,
17
19
  getApiKey: () => getApiKey,
20
+ getProfile: () => getProfile,
18
21
  readConfig: () => readConfig,
22
+ resolveConfig: () => resolveConfig,
19
23
  writeConfig: () => writeConfig
20
24
  });
21
25
  function readConfig() {
@@ -37,8 +41,32 @@ function deleteConfig() {
37
41
  (0, import_node_fs.unlinkSync)(CONFIG_PATH);
38
42
  }
39
43
  }
40
- function getApiKey() {
41
- return process.env.ATOLL_API_KEY || readConfig().apiKey;
44
+ function getActiveProfile(config = readConfig()) {
45
+ return process.env.ATOLL_PROFILE || config.activeProfile;
46
+ }
47
+ function getProfile(config, profileName) {
48
+ if (!profileName) return void 0;
49
+ return config.profiles?.[profileName];
50
+ }
51
+ function ensureProfile(config, profileName) {
52
+ config.profiles ??= {};
53
+ config.profiles[profileName] ??= {};
54
+ return config.profiles[profileName];
55
+ }
56
+ function resolveConfig(opts) {
57
+ const config = readConfig();
58
+ const profileName = opts?.profile || getActiveProfile(config);
59
+ const profile = getProfile(config, profileName);
60
+ return {
61
+ profile: profileName,
62
+ apiKey: process.env.ATOLL_API_KEY || profile?.apiKey || (profileName ? void 0 : config.apiKey),
63
+ orgSlug: process.env.ATOLL_ORG || profile?.orgSlug || (profileName ? void 0 : config.orgSlug),
64
+ defaultTeam: process.env.ATOLL_TEAM || profile?.defaultTeam || (profileName ? void 0 : config.defaultTeam),
65
+ baseUrl: process.env.ATOLL_BASE_URL || profile?.baseUrl || (profileName ? void 0 : config.baseUrl)
66
+ };
67
+ }
68
+ function getApiKey(opts) {
69
+ return resolveConfig(opts).apiKey;
42
70
  }
43
71
  var import_node_fs, import_node_os, import_node_path, CONFIG_DIR, CONFIG_PATH;
44
72
  var init_config = __esm({
@@ -54,6 +82,8 @@ var init_config = __esm({
54
82
 
55
83
  // src/index.ts
56
84
  var import_commander8 = require("commander");
85
+ var import_node_fs2 = require("fs");
86
+ var import_node_path2 = require("path");
57
87
 
58
88
  // src/commands/auth.ts
59
89
  var import_commander = require("commander");
@@ -86,10 +116,12 @@ function outputError(message) {
86
116
  var DEFAULT_BASE_URL = "https://atollhq.com";
87
117
  var AtollClient = class {
88
118
  constructor(opts) {
89
- this.baseUrl = opts?.baseUrl || process.env.ATOLL_BASE_URL || DEFAULT_BASE_URL;
90
- const key = opts?.apiKey || getApiKey();
119
+ const config = resolveConfig({ profile: opts?.profile });
120
+ this.baseUrl = opts?.baseUrl || config.baseUrl || DEFAULT_BASE_URL;
121
+ const key = opts?.apiKey || config.apiKey;
91
122
  if (!key) {
92
- outputError("No API key found. Run `atoll auth login --key <API_KEY>` or set ATOLL_API_KEY.");
123
+ const suffix = config.profile ? ` for profile "${config.profile}"` : "";
124
+ outputError(`No API key found${suffix}. Run \`atoll auth login --key <API_KEY>\` or set ATOLL_API_KEY.`);
93
125
  process.exit(1);
94
126
  }
95
127
  this.apiKey = key;
@@ -132,28 +164,47 @@ var AtollClient = class {
132
164
 
133
165
  // src/commands/auth.ts
134
166
  var authCommand = new import_commander.Command("auth").description("Manage authentication");
135
- authCommand.command("login").description("Save an API key to ~/.atoll/config.json").requiredOption("--key <API_KEY>", "API key to store").action((opts) => {
167
+ authCommand.command("login").description("Save an API key to ~/.atoll/config.json").requiredOption("--key <API_KEY>", "API key to store").option("--profile <name>", "Profile name to store this API key under").option("--org <slug>", "Default org slug for this profile").option("--team <team>", "Default team slug or ID for this profile").option("--base-url <url>", "Base URL for this profile").action((opts) => {
136
168
  const config = readConfig();
137
- config.apiKey = opts.key;
169
+ const profileName = opts.profile || process.env.ATOLL_PROFILE || config.activeProfile;
170
+ const orgSlug = opts.org ?? process.env.ATOLL_CLI_ORG;
171
+ const defaultTeam = opts.team ?? process.env.ATOLL_CLI_TEAM;
172
+ const baseUrl = opts.baseUrl;
173
+ if (profileName) {
174
+ const profile = ensureProfile(config, profileName);
175
+ profile.apiKey = opts.key;
176
+ if (orgSlug !== void 0) profile.orgSlug = orgSlug;
177
+ if (defaultTeam !== void 0) profile.defaultTeam = defaultTeam;
178
+ if (baseUrl !== void 0) profile.baseUrl = baseUrl;
179
+ config.activeProfile = profileName;
180
+ } else {
181
+ config.apiKey = opts.key;
182
+ if (orgSlug !== void 0) config.orgSlug = orgSlug;
183
+ if (defaultTeam !== void 0) config.defaultTeam = defaultTeam;
184
+ if (baseUrl !== void 0) config.baseUrl = baseUrl;
185
+ }
138
186
  writeConfig(config);
139
187
  output(
140
- { status: "ok", message: "API key saved" },
141
- "\u2713 API key saved to ~/.atoll/config.json"
188
+ { status: "ok", message: "API key saved", profile: profileName ?? null },
189
+ profileName ? `\u2713 API key saved to profile "${profileName}" in ~/.atoll/config.json` : "\u2713 API key saved to ~/.atoll/config.json"
142
190
  );
143
191
  });
144
- authCommand.command("status").description("Show current auth status and user info").action(async () => {
145
- const apiKey = getApiKey();
192
+ authCommand.command("status").description("Show current auth status and user info").option("--profile <name>", "Profile name to check").action(async (opts) => {
193
+ const resolved = resolveConfig({ profile: opts.profile });
194
+ const apiKey = resolved.apiKey;
146
195
  if (!apiKey) {
147
- outputError("Not authenticated. Run `atoll auth login --key <API_KEY>` or set ATOLL_API_KEY.");
196
+ const suffix = resolved.profile ? ` for profile "${resolved.profile}"` : "";
197
+ outputError(`Not authenticated${suffix}. Run \`atoll auth login --key <API_KEY>\` or set ATOLL_API_KEY.`);
148
198
  process.exit(1);
149
199
  }
150
200
  try {
151
- const client = new AtollClient({ apiKey });
201
+ const client = new AtollClient({ apiKey, baseUrl: resolved.baseUrl, profile: opts.profile });
152
202
  const me = await client.get("/api/auth/me");
153
203
  output(
154
204
  { status: "authenticated", ...me },
155
205
  [
156
206
  "\u2713 Authenticated",
207
+ resolved.profile ? ` Profile: ${resolved.profile}` : null,
157
208
  me.user?.name ? ` User: ${me.user.name}` : null,
158
209
  me.user?.email ? ` Email: ${me.user.email}` : null,
159
210
  me.org?.name ? ` Org: ${me.org.name} (${me.org.slug})` : null
@@ -169,13 +220,67 @@ authCommand.command("status").description("Show current auth status and user inf
169
220
  process.exit(1);
170
221
  }
171
222
  });
172
- authCommand.command("logout").description("Remove stored API key").action(() => {
223
+ authCommand.command("profiles").description("List saved auth profiles").action(() => {
224
+ const config = readConfig();
225
+ const activeProfile = config.activeProfile;
226
+ const profiles = Object.entries(config.profiles ?? {}).sort(([a], [b]) => a.localeCompare(b)).map(([name, profile]) => ({
227
+ name,
228
+ active: name === activeProfile,
229
+ apiKeySet: !!profile.apiKey,
230
+ orgSlug: profile.orgSlug ?? null,
231
+ defaultTeam: profile.defaultTeam ?? null,
232
+ baseUrl: profile.baseUrl ?? null
233
+ }));
234
+ if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === "json") {
235
+ output({ activeProfile: activeProfile ?? null, profiles }, "");
236
+ return;
237
+ }
238
+ if (profiles.length === 0) {
239
+ console.log("No profiles configured.");
240
+ return;
241
+ }
242
+ for (const profile of profiles) {
243
+ const marker = profile.active ? "*" : " ";
244
+ const parts = [
245
+ `${marker} ${profile.name}`,
246
+ profile.apiKeySet ? "key=set" : "key=not set",
247
+ profile.orgSlug ? `org=${profile.orgSlug}` : null,
248
+ profile.defaultTeam ? `team=${profile.defaultTeam}` : null,
249
+ profile.baseUrl ? `baseUrl=${profile.baseUrl}` : null
250
+ ].filter(Boolean);
251
+ console.log(parts.join(" "));
252
+ }
253
+ });
254
+ authCommand.command("use <profile>").description("Set the active auth profile").action((profileName) => {
255
+ const config = readConfig();
256
+ if (!getProfile(config, profileName)) {
257
+ outputError(`Profile "${profileName}" not found. Run \`atoll auth login --profile ${profileName} --key <API_KEY>\` first.`);
258
+ process.exit(1);
259
+ }
260
+ config.activeProfile = profileName;
261
+ writeConfig(config);
262
+ output(
263
+ { activeProfile: profileName },
264
+ `\u2713 Active profile set to "${profileName}"`
265
+ );
266
+ });
267
+ authCommand.command("logout").description("Remove stored API key").option("--profile <name>", "Profile name to log out").action((opts) => {
173
268
  const config = readConfig();
174
- delete config.apiKey;
269
+ const profileName = opts.profile || process.env.ATOLL_PROFILE || config.activeProfile;
270
+ if (profileName) {
271
+ const profile = getProfile(config, profileName);
272
+ if (!profile) {
273
+ outputError(`Profile "${profileName}" not found.`);
274
+ process.exit(1);
275
+ }
276
+ delete profile.apiKey;
277
+ } else {
278
+ delete config.apiKey;
279
+ }
175
280
  writeConfig(config);
176
281
  output(
177
- { status: "ok", message: "Logged out" },
178
- "\u2713 Logged out \u2014 API key removed (org/team config preserved)"
282
+ { status: "ok", message: "Logged out", profile: profileName ?? null },
283
+ profileName ? `\u2713 Logged out of profile "${profileName}" \u2014 API key removed (org/team config preserved)` : "\u2713 Logged out \u2014 API key removed (org/team config preserved)"
179
284
  );
180
285
  });
181
286
 
@@ -280,9 +385,9 @@ async function resolveOrg(client, orgSlugOverride) {
280
385
  process.exit(1);
281
386
  }
282
387
  if (orgs.length === 1) return orgs[0];
283
- const { readConfig: readConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
284
- const config = readConfig2();
285
- const slug = orgSlugOverride ?? process.env.ATOLL_ORG ?? config.orgSlug;
388
+ const { resolveConfig: resolveConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
389
+ const config = resolveConfig2();
390
+ const slug = orgSlugOverride ?? config.orgSlug;
286
391
  if (slug) {
287
392
  const match = orgs.find((o) => o.slug === slug);
288
393
  if (match) return match;
@@ -841,42 +946,76 @@ var configCommand = new import_commander6.Command("config").description("Manage
841
946
  Examples:
842
947
  $ atoll config show
843
948
  $ atoll config set-org my-org
844
- $ atoll config set-team team-abc123`);
845
- configCommand.command("show").description("Display current configuration").action(() => {
949
+ $ atoll config set-team team-abc123
950
+ $ atoll config set-base-url https://atollhq.com`);
951
+ configCommand.command("show").description("Display current configuration").option("--profile <name>", "Profile name to show").action((opts) => {
846
952
  const cfg = readConfig();
847
- const apiKeySet = !!(process.env.ATOLL_API_KEY || cfg.apiKey);
953
+ const activeProfile = cfg.activeProfile;
954
+ const resolved = resolveConfig({ profile: opts.profile });
955
+ const apiKeySet = !!resolved.apiKey;
848
956
  if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === "json") {
849
957
  output(
850
958
  {
851
- orgSlug: cfg.orgSlug ?? null,
852
- defaultTeam: cfg.defaultTeam ?? null,
853
- apiKeySet
959
+ activeProfile: activeProfile ?? null,
960
+ selectedProfile: resolved.profile ?? null,
961
+ orgSlug: resolved.orgSlug ?? null,
962
+ defaultTeam: resolved.defaultTeam ?? null,
963
+ baseUrl: resolved.baseUrl ?? null,
964
+ apiKeySet,
965
+ profiles: Object.keys(cfg.profiles ?? {}).sort()
854
966
  },
855
967
  ""
856
968
  );
857
969
  return;
858
970
  }
859
971
  console.log(`${bold("Atoll CLI Configuration")}`);
860
- console.log(` ${dim("Org slug:")} ${cfg.orgSlug ? bold(cfg.orgSlug) : gray("(not set)")}`);
861
- console.log(` ${dim("Default team:")} ${cfg.defaultTeam ? bold(cfg.defaultTeam) : gray("(not set)")}`);
972
+ console.log(` ${dim("Active profile:")} ${activeProfile ? bold(activeProfile) : gray("(not set)")}`);
973
+ console.log(` ${dim("Selected profile:")} ${resolved.profile ? bold(resolved.profile) : gray("(legacy config)")}`);
974
+ console.log(` ${dim("Org slug:")} ${resolved.orgSlug ? bold(resolved.orgSlug) : gray("(not set)")}`);
975
+ console.log(` ${dim("Default team:")} ${resolved.defaultTeam ? bold(resolved.defaultTeam) : gray("(not set)")}`);
976
+ console.log(` ${dim("Base URL:")} ${resolved.baseUrl ? bold(resolved.baseUrl) : gray("(default)")}`);
862
977
  console.log(` ${dim("API key:")} ${apiKeySet ? bold("set") : gray("not set \u2014 run `atoll auth login`")}`);
863
978
  });
864
- configCommand.command("set-org <slug>").description("Set the default organisation slug").action((slug) => {
979
+ configCommand.command("set-org <slug>").description("Set the default organisation slug").option("--profile <name>", "Profile name to update").action((slug, opts) => {
865
980
  const cfg = readConfig();
866
- cfg.orgSlug = slug;
981
+ const profileName = opts.profile || process.env.ATOLL_PROFILE || cfg.activeProfile;
982
+ if (profileName) {
983
+ ensureProfile(cfg, profileName).orgSlug = slug;
984
+ } else {
985
+ cfg.orgSlug = slug;
986
+ }
867
987
  writeConfig(cfg);
868
988
  output(
869
- { orgSlug: slug },
870
- success(`Default org set to "${slug}"`)
989
+ { orgSlug: slug, profile: profileName ?? null },
990
+ profileName ? success(`Default org for profile "${profileName}" set to "${slug}"`) : success(`Default org set to "${slug}"`)
871
991
  );
872
992
  });
873
- configCommand.command("set-team <team>").description("Set the default team slug or ID").action((team) => {
993
+ configCommand.command("set-team <team>").description("Set the default team slug or ID").option("--profile <name>", "Profile name to update").action((team, opts) => {
874
994
  const cfg = readConfig();
875
- cfg.defaultTeam = team;
995
+ const profileName = opts.profile || process.env.ATOLL_PROFILE || cfg.activeProfile;
996
+ if (profileName) {
997
+ ensureProfile(cfg, profileName).defaultTeam = team;
998
+ } else {
999
+ cfg.defaultTeam = team;
1000
+ }
876
1001
  writeConfig(cfg);
877
1002
  output(
878
- { defaultTeam: team },
879
- success(`Default team set to "${team}"`)
1003
+ { defaultTeam: team, profile: profileName ?? null },
1004
+ profileName ? success(`Default team for profile "${profileName}" set to "${team}"`) : success(`Default team set to "${team}"`)
1005
+ );
1006
+ });
1007
+ configCommand.command("set-base-url <url>").description("Set the default API base URL").option("--profile <name>", "Profile name to update").action((url, opts) => {
1008
+ const cfg = readConfig();
1009
+ const profileName = opts.profile || process.env.ATOLL_PROFILE || cfg.activeProfile;
1010
+ if (profileName) {
1011
+ ensureProfile(cfg, profileName).baseUrl = url;
1012
+ } else {
1013
+ cfg.baseUrl = url;
1014
+ }
1015
+ writeConfig(cfg);
1016
+ output(
1017
+ { baseUrl: url, profile: profileName ?? null },
1018
+ profileName ? success(`Base URL for profile "${profileName}" set to "${url}"`) : success(`Base URL set to "${url}"`)
880
1019
  );
881
1020
  });
882
1021
 
@@ -900,9 +1039,9 @@ async function resolveOrgId2(client, orgSlugOverride) {
900
1039
  process.exit(1);
901
1040
  }
902
1041
  if (orgs.length === 1) return orgs[0].id;
903
- const { readConfig: readConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
904
- const config = readConfig2();
905
- const slug = orgSlugOverride ?? process.env.ATOLL_ORG ?? config.orgSlug;
1042
+ const { resolveConfig: resolveConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
1043
+ const config = resolveConfig2();
1044
+ const slug = orgSlugOverride ?? config.orgSlug;
906
1045
  if (slug) {
907
1046
  const match = orgs.find((o) => o.slug === slug);
908
1047
  if (match) return match.id;
@@ -990,17 +1129,34 @@ webhookCommand.command("delete <id>").description("Delete a webhook").action(asy
990
1129
  });
991
1130
 
992
1131
  // src/index.ts
993
- var program = new import_commander8.Command("atoll").description("Atoll CLI \u2014 project management from the terminal").version("0.1.0").addHelpText("after", `
1132
+ function readCliVersion() {
1133
+ try {
1134
+ const packageJson = JSON.parse((0, import_node_fs2.readFileSync)((0, import_node_path2.join)(__dirname, "..", "package.json"), "utf-8"));
1135
+ return packageJson.version ?? "0.0.0";
1136
+ } catch {
1137
+ return "0.0.0";
1138
+ }
1139
+ }
1140
+ var program = new import_commander8.Command("atoll").description("Atoll CLI \u2014 project management from the terminal").version(readCliVersion()).addHelpText("after", `
994
1141
  Examples:
995
1142
  $ atoll issue list
996
1143
  $ atoll issue create --title "Fix login bug" --priority 1
997
1144
  $ atoll issue view ATOLL-42
998
1145
  $ atoll project list
999
1146
  $ atoll milestone list --project <id>
1000
- $ atoll config show`).option("--org <slug>", "Override default org slug (env: ATOLL_ORG)").option("--team <id>", "Override default team slug/ID (env: ATOLL_TEAM)").hook("preAction", (thisCommand) => {
1147
+ $ atoll config show`).option("--profile <name>", "Use a saved auth profile (env: ATOLL_PROFILE)").option("--org <slug>", "Override default org slug (env: ATOLL_ORG)").option("--team <id>", "Override default team slug/ID (env: ATOLL_TEAM)").hook("preAction", (thisCommand) => {
1001
1148
  const opts = thisCommand.opts();
1002
- if (opts.org) process.env.ATOLL_ORG = opts.org;
1003
- if (opts.team) process.env.ATOLL_TEAM = opts.team;
1149
+ if (opts.profile) {
1150
+ process.env.ATOLL_PROFILE = opts.profile;
1151
+ }
1152
+ if (opts.org) {
1153
+ process.env.ATOLL_ORG = opts.org;
1154
+ process.env.ATOLL_CLI_ORG = opts.org;
1155
+ }
1156
+ if (opts.team) {
1157
+ process.env.ATOLL_TEAM = opts.team;
1158
+ process.env.ATOLL_CLI_TEAM = opts.team;
1159
+ }
1004
1160
  });
1005
1161
  program.addCommand(authCommand);
1006
1162
  program.addCommand(issueCommand);
@@ -1033,8 +1189,8 @@ _atoll_completions() {
1033
1189
  local issue_cmds="list view create update delete assign unassign"
1034
1190
  local project_cmds="list create view"
1035
1191
  local milestone_cmds="list create"
1036
- local config_cmds="show set-org set-team"
1037
- local auth_cmds="login logout status"
1192
+ local config_cmds="show set-org set-team set-base-url"
1193
+ local auth_cmds="login logout status profiles use"
1038
1194
  local webhook_cmds="list create delete"
1039
1195
  local completion_cmds="bash zsh"
1040
1196
 
@@ -1136,13 +1292,16 @@ _atoll() {
1136
1292
  _values 'subcommand' \\
1137
1293
  'show[Show configuration]' \\
1138
1294
  'set-org[Set default org slug]' \\
1139
- 'set-team[Set default team]'
1295
+ 'set-team[Set default team]' \\
1296
+ 'set-base-url[Set default API base URL]'
1140
1297
  ;;
1141
1298
  auth)
1142
1299
  _values 'subcommand' \\
1143
1300
  'login[Log in]' \\
1144
1301
  'logout[Log out]' \\
1145
- 'status[Show auth status]'
1302
+ 'status[Show auth status]' \\
1303
+ 'profiles[List auth profiles]' \\
1304
+ 'use[Set active auth profile]'
1146
1305
  ;;
1147
1306
  webhook)
1148
1307
  _values 'subcommand' \\
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/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":"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AA;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"]}
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 baseUrl?: string;\n activeProfile?: string;\n profiles?: Record<string, AtollProfile>;\n}\n\nexport interface AtollProfile {\n apiKey?: string;\n orgSlug?: string;\n defaultTeam?: string;\n baseUrl?: string;\n}\n\nexport interface ResolvedConfig extends AtollProfile {\n profile?: 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 getActiveProfile(config = readConfig()): string | undefined {\n return process.env.ATOLL_PROFILE || config.activeProfile;\n}\n\nexport function getProfile(config: AtollConfig, profileName?: string): AtollProfile | undefined {\n if (!profileName) return undefined;\n return config.profiles?.[profileName];\n}\n\nexport function ensureProfile(config: AtollConfig, profileName: string): AtollProfile {\n config.profiles ??= {};\n config.profiles[profileName] ??= {};\n return config.profiles[profileName];\n}\n\nexport function resolveConfig(opts?: { profile?: string }): ResolvedConfig {\n const config = readConfig();\n const profileName = opts?.profile || getActiveProfile(config);\n const profile = getProfile(config, profileName);\n\n return {\n profile: profileName,\n apiKey: process.env.ATOLL_API_KEY || profile?.apiKey || (profileName ? undefined : config.apiKey),\n orgSlug: process.env.ATOLL_ORG || profile?.orgSlug || (profileName ? undefined : config.orgSlug),\n defaultTeam: process.env.ATOLL_TEAM || profile?.defaultTeam || (profileName ? undefined : config.defaultTeam),\n baseUrl: process.env.ATOLL_BASE_URL || profile?.baseUrl || (profileName ? undefined : config.baseUrl),\n };\n}\n\nexport function getApiKey(opts?: { profile?: string }): string | undefined {\n return resolveConfig(opts).apiKey;\n}\n","import { Command } from 'commander';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\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\nfunction readCliVersion(): string {\n try {\n const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8')) as {\n version?: string;\n };\n return packageJson.version ?? '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n\nconst program = new Command('atoll')\n .description('Atoll CLI — project management from the terminal')\n .version(readCliVersion())\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('--profile <name>', 'Use a saved auth profile (env: ATOLL_PROFILE)')\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.profile) {\n process.env.ATOLL_PROFILE = opts.profile;\n }\n if (opts.org) {\n process.env.ATOLL_ORG = opts.org;\n process.env.ATOLL_CLI_ORG = opts.org;\n }\n if (opts.team) {\n process.env.ATOLL_TEAM = opts.team;\n process.env.ATOLL_CLI_TEAM = opts.team;\n }\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 set-base-url\"\n local auth_cmds=\"login logout status profiles use\"\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 'set-base-url[Set default API base URL]'\n ;;\n auth)\n _values 'subcommand' \\\\\n 'login[Log in]' \\\\\n 'logout[Log out]' \\\\\n 'status[Show auth status]' \\\\\n 'profiles[List auth profiles]' \\\\\n 'use[Set active auth profile]'\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 {\n ensureProfile,\n getProfile,\n readConfig,\n resolveConfig,\n writeConfig,\n} 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 .option('--profile <name>', 'Profile name to store this API key under')\n .option('--org <slug>', 'Default org slug for this profile')\n .option('--team <team>', 'Default team slug or ID for this profile')\n .option('--base-url <url>', 'Base URL for this profile')\n .action((opts: { key: string; profile?: string; org?: string; team?: string; baseUrl?: string }) => {\n const config = readConfig();\n const profileName = opts.profile || process.env.ATOLL_PROFILE || config.activeProfile;\n const orgSlug = opts.org ?? process.env.ATOLL_CLI_ORG;\n const defaultTeam = opts.team ?? process.env.ATOLL_CLI_TEAM;\n const baseUrl = opts.baseUrl;\n\n if (profileName) {\n const profile = ensureProfile(config, profileName);\n profile.apiKey = opts.key;\n if (orgSlug !== undefined) profile.orgSlug = orgSlug;\n if (defaultTeam !== undefined) profile.defaultTeam = defaultTeam;\n if (baseUrl !== undefined) profile.baseUrl = baseUrl;\n config.activeProfile = profileName;\n } else {\n config.apiKey = opts.key;\n if (orgSlug !== undefined) config.orgSlug = orgSlug;\n if (defaultTeam !== undefined) config.defaultTeam = defaultTeam;\n if (baseUrl !== undefined) config.baseUrl = baseUrl;\n }\n\n writeConfig(config);\n output(\n { status: 'ok', message: 'API key saved', profile: profileName ?? null },\n profileName\n ? `✓ API key saved to profile \"${profileName}\" in ~/.atoll/config.json`\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 .option('--profile <name>', 'Profile name to check')\n .action(async (opts: { profile?: string }) => {\n const resolved = resolveConfig({ profile: opts.profile });\n const apiKey = resolved.apiKey;\n if (!apiKey) {\n const suffix = resolved.profile ? ` for profile \"${resolved.profile}\"` : '';\n outputError(`Not authenticated${suffix}. 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, baseUrl: resolved.baseUrl, profile: opts.profile });\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 resolved.profile ? ` Profile: ${resolved.profile}` : null,\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('profiles')\n .description('List saved auth profiles')\n .action(() => {\n const config = readConfig();\n const activeProfile = config.activeProfile;\n const profiles = Object.entries(config.profiles ?? {})\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, profile]) => ({\n name,\n active: name === activeProfile,\n apiKeySet: !!profile.apiKey,\n orgSlug: profile.orgSlug ?? null,\n defaultTeam: profile.defaultTeam ?? null,\n baseUrl: profile.baseUrl ?? null,\n }));\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n output({ activeProfile: activeProfile ?? null, profiles }, '');\n return;\n }\n\n if (profiles.length === 0) {\n console.log('No profiles configured.');\n return;\n }\n\n for (const profile of profiles) {\n const marker = profile.active ? '*' : ' ';\n const parts = [\n `${marker} ${profile.name}`,\n profile.apiKeySet ? 'key=set' : 'key=not set',\n profile.orgSlug ? `org=${profile.orgSlug}` : null,\n profile.defaultTeam ? `team=${profile.defaultTeam}` : null,\n profile.baseUrl ? `baseUrl=${profile.baseUrl}` : null,\n ].filter(Boolean);\n console.log(parts.join(' '));\n }\n });\n\nauthCommand\n .command('use <profile>')\n .description('Set the active auth profile')\n .action((profileName: string) => {\n const config = readConfig();\n if (!getProfile(config, profileName)) {\n outputError(`Profile \"${profileName}\" not found. Run \\`atoll auth login --profile ${profileName} --key <API_KEY>\\` first.`);\n process.exit(1);\n }\n\n config.activeProfile = profileName;\n writeConfig(config);\n output(\n { activeProfile: profileName },\n `✓ Active profile set to \"${profileName}\"`,\n );\n });\n\nauthCommand\n .command('logout')\n .description('Remove stored API key')\n .option('--profile <name>', 'Profile name to log out')\n .action((opts: { profile?: string }) => {\n // Only clear the API key — preserve org/team config settings.\n const config = readConfig();\n const profileName = opts.profile || process.env.ATOLL_PROFILE || config.activeProfile;\n\n if (profileName) {\n const profile = getProfile(config, profileName);\n if (!profile) {\n outputError(`Profile \"${profileName}\" not found.`);\n process.exit(1);\n }\n delete profile.apiKey;\n } else {\n delete config.apiKey;\n }\n\n writeConfig(config);\n output(\n { status: 'ok', message: 'Logged out', profile: profileName ?? null },\n profileName\n ? `✓ Logged out of profile \"${profileName}\" — API key removed (org/team config preserved)`\n : '✓ Logged out — API key removed (org/team config preserved)',\n );\n });\n","import { resolveConfig } 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; profile?: string }) {\n const config = resolveConfig({ profile: opts?.profile });\n this.baseUrl = opts?.baseUrl || config.baseUrl || DEFAULT_BASE_URL;\n\n const key = opts?.apiKey || config.apiKey;\n if (!key) {\n const suffix = config.profile ? ` for profile \"${config.profile}\"` : '';\n outputError(`No API key found${suffix}. 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: explicit override -> selected profile/env -> legacy config.\n const { resolveConfig } = await import('../lib/config.js');\n const config = resolveConfig();\n const slug = orgSlugOverride ?? 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 { ensureProfile, readConfig, resolveConfig, writeConfig } from '../lib/config.js';\nimport { output } from '../lib/output.js';\nimport { success, bold, dim, gray } from '../lib/colors.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 $ atoll config set-base-url https://atollhq.com`);\n\n// ── atoll config show ───────────────────────────────────────────────────────\n\nconfigCommand\n .command('show')\n .description('Display current configuration')\n .option('--profile <name>', 'Profile name to show')\n .action((opts: { profile?: string }) => {\n const cfg = readConfig();\n const activeProfile = cfg.activeProfile;\n const resolved = resolveConfig({ profile: opts.profile });\n const apiKeySet = !!resolved.apiKey;\n\n if (!process.stdout.isTTY || process.env.OUTPUT_FORMAT === 'json') {\n output(\n {\n activeProfile: activeProfile ?? null,\n selectedProfile: resolved.profile ?? null,\n orgSlug: resolved.orgSlug ?? null,\n defaultTeam: resolved.defaultTeam ?? null,\n baseUrl: resolved.baseUrl ?? null,\n apiKeySet,\n profiles: Object.keys(cfg.profiles ?? {}).sort(),\n },\n '',\n );\n return;\n }\n\n console.log(`${bold('Atoll CLI Configuration')}`);\n console.log(` ${dim('Active profile:')} ${activeProfile ? bold(activeProfile) : gray('(not set)')}`);\n console.log(` ${dim('Selected profile:')} ${resolved.profile ? bold(resolved.profile) : gray('(legacy config)')}`);\n console.log(` ${dim('Org slug:')} ${resolved.orgSlug ? bold(resolved.orgSlug) : gray('(not set)')}`);\n console.log(` ${dim('Default team:')} ${resolved.defaultTeam ? bold(resolved.defaultTeam) : gray('(not set)')}`);\n console.log(` ${dim('Base URL:')} ${resolved.baseUrl ? bold(resolved.baseUrl) : gray('(default)')}`);\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 .option('--profile <name>', 'Profile name to update')\n .action((slug: string, opts: { profile?: string }) => {\n const cfg = readConfig();\n const profileName = opts.profile || process.env.ATOLL_PROFILE || cfg.activeProfile;\n if (profileName) {\n ensureProfile(cfg, profileName).orgSlug = slug;\n } else {\n cfg.orgSlug = slug;\n }\n writeConfig(cfg);\n\n output(\n { orgSlug: slug, profile: profileName ?? null },\n profileName\n ? success(`Default org for profile \"${profileName}\" set to \"${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 .option('--profile <name>', 'Profile name to update')\n .action((team: string, opts: { profile?: string }) => {\n const cfg = readConfig();\n const profileName = opts.profile || process.env.ATOLL_PROFILE || cfg.activeProfile;\n if (profileName) {\n ensureProfile(cfg, profileName).defaultTeam = team;\n } else {\n cfg.defaultTeam = team;\n }\n writeConfig(cfg);\n\n output(\n { defaultTeam: team, profile: profileName ?? null },\n profileName\n ? success(`Default team for profile \"${profileName}\" set to \"${team}\"`)\n : success(`Default team set to \"${team}\"`),\n );\n });\n\n// ── atoll config set-base-url ───────────────────────────────────────────────\n\nconfigCommand\n .command('set-base-url <url>')\n .description('Set the default API base URL')\n .option('--profile <name>', 'Profile name to update')\n .action((url: string, opts: { profile?: string }) => {\n const cfg = readConfig();\n const profileName = opts.profile || process.env.ATOLL_PROFILE || cfg.activeProfile;\n if (profileName) {\n ensureProfile(cfg, profileName).baseUrl = url;\n } else {\n cfg.baseUrl = url;\n }\n writeConfig(cfg);\n\n output(\n { baseUrl: url, profile: profileName ?? null },\n profileName\n ? success(`Base URL for profile \"${profileName}\" set to \"${url}\"`)\n : success(`Base URL set to \"${url}\"`),\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 { resolveConfig } = await import('../lib/config.js');\n const config = resolveConfig();\n const slug = orgSlugOverride ?? 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;AAAA;AAAA;AAAA;AAAA;AA2BO,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,iBAAiB,SAAS,WAAW,GAAuB;AAC1E,SAAO,QAAQ,IAAI,iBAAiB,OAAO;AAC7C;AAEO,SAAS,WAAW,QAAqB,aAAgD;AAC9F,MAAI,CAAC,YAAa,QAAO;AACzB,SAAO,OAAO,WAAW,WAAW;AACtC;AAEO,SAAS,cAAc,QAAqB,aAAmC;AACpF,SAAO,aAAa,CAAC;AACrB,SAAO,SAAS,WAAW,MAAM,CAAC;AAClC,SAAO,OAAO,SAAS,WAAW;AACpC;AAEO,SAAS,cAAc,MAA6C;AACzE,QAAM,SAAS,WAAW;AAC1B,QAAM,cAAc,MAAM,WAAW,iBAAiB,MAAM;AAC5D,QAAM,UAAU,WAAW,QAAQ,WAAW;AAE9C,SAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ,QAAQ,IAAI,iBAAiB,SAAS,WAAW,cAAc,SAAY,OAAO;AAAA,IAC1F,SAAS,QAAQ,IAAI,aAAa,SAAS,YAAY,cAAc,SAAY,OAAO;AAAA,IACxF,aAAa,QAAQ,IAAI,cAAc,SAAS,gBAAgB,cAAc,SAAY,OAAO;AAAA,IACjG,SAAS,QAAQ,IAAI,kBAAkB,SAAS,YAAY,cAAc,SAAY,OAAO;AAAA,EAC/F;AACF;AAEO,SAAS,UAAU,MAAiD;AACzE,SAAO,cAAc,IAAI,EAAE;AAC7B;AAhFA,oBACA,gBACA,kBAsBM,YACA;AAzBN;AAAA;AAAA;AAAA,qBAA+E;AAC/E,qBAAwB;AACxB,uBAAqB;AAsBrB,IAAM,iBAAa,2BAAK,wBAAQ,GAAG,QAAQ;AAC3C,IAAM,kBAAc,uBAAK,YAAY,aAAa;AAAA;AAAA;;;ACzBlD,IAAAA,oBAAwB;AACxB,IAAAC,kBAA6B;AAC7B,IAAAC,oBAAqB;;;ACFrB,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,MAAgE;AAC1E,UAAM,SAAS,cAAc,EAAE,SAAS,MAAM,QAAQ,CAAC;AACvD,SAAK,UAAU,MAAM,WAAW,OAAO,WAAW;AAElD,UAAM,MAAM,MAAM,UAAU,OAAO;AACnC,QAAI,CAAC,KAAK;AACR,YAAM,SAAS,OAAO,UAAU,iBAAiB,OAAO,OAAO,MAAM;AACrE,kBAAY,mBAAmB,MAAM,kEAAkE;AACvG,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;;;ADnDO,IAAM,cAAc,IAAI,yBAAQ,MAAM,EAC1C,YAAY,uBAAuB;AAEtC,YACG,QAAQ,OAAO,EACf,YAAY,yCAAyC,EACrD,eAAe,mBAAmB,kBAAkB,EACpD,OAAO,oBAAoB,0CAA0C,EACrE,OAAO,gBAAgB,mCAAmC,EAC1D,OAAO,iBAAiB,0CAA0C,EAClE,OAAO,oBAAoB,2BAA2B,EACtD,OAAO,CAAC,SAA2F;AAClG,QAAM,SAAS,WAAW;AAC1B,QAAM,cAAc,KAAK,WAAW,QAAQ,IAAI,iBAAiB,OAAO;AACxE,QAAM,UAAU,KAAK,OAAO,QAAQ,IAAI;AACxC,QAAM,cAAc,KAAK,QAAQ,QAAQ,IAAI;AAC7C,QAAM,UAAU,KAAK;AAErB,MAAI,aAAa;AACf,UAAM,UAAU,cAAc,QAAQ,WAAW;AACjD,YAAQ,SAAS,KAAK;AACtB,QAAI,YAAY,OAAW,SAAQ,UAAU;AAC7C,QAAI,gBAAgB,OAAW,SAAQ,cAAc;AACrD,QAAI,YAAY,OAAW,SAAQ,UAAU;AAC7C,WAAO,gBAAgB;AAAA,EACzB,OAAO;AACL,WAAO,SAAS,KAAK;AACrB,QAAI,YAAY,OAAW,QAAO,UAAU;AAC5C,QAAI,gBAAgB,OAAW,QAAO,cAAc;AACpD,QAAI,YAAY,OAAW,QAAO,UAAU;AAAA,EAC9C;AAEA,cAAY,MAAM;AAClB;AAAA,IACE,EAAE,QAAQ,MAAM,SAAS,iBAAiB,SAAS,eAAe,KAAK;AAAA,IACvE,cACI,oCAA+B,WAAW,8BAC1C;AAAA,EACN;AACF,CAAC;AAEH,YACG,QAAQ,QAAQ,EAChB,YAAY,wCAAwC,EACpD,OAAO,oBAAoB,uBAAuB,EAClD,OAAO,OAAO,SAA+B;AAC5C,QAAM,WAAW,cAAc,EAAE,SAAS,KAAK,QAAQ,CAAC;AACxD,QAAM,SAAS,SAAS;AACxB,MAAI,CAAC,QAAQ;AACX,UAAM,SAAS,SAAS,UAAU,iBAAiB,SAAS,OAAO,MAAM;AACzE,gBAAY,oBAAoB,MAAM,kEAAkE;AACxG,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI;AACF,UAAM,SAAS,IAAI,YAAY,EAAE,QAAQ,SAAS,SAAS,SAAS,SAAS,KAAK,QAAQ,CAAC;AAC3F,UAAM,KAAK,MAAM,OAAO,IAGrB,cAAc;AAEjB;AAAA,MACE,EAAE,QAAQ,iBAAiB,GAAG,GAAG;AAAA,MACjC;AAAA,QACE;AAAA,QACA,SAAS,UAAU,cAAc,SAAS,OAAO,KAAK;AAAA,QACtD,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,UAAU,EAClB,YAAY,0BAA0B,EACtC,OAAO,MAAM;AACZ,QAAM,SAAS,WAAW;AAC1B,QAAM,gBAAgB,OAAO;AAC7B,QAAM,WAAW,OAAO,QAAQ,OAAO,YAAY,CAAC,CAAC,EAClD,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACrC,IAAI,CAAC,CAAC,MAAM,OAAO,OAAO;AAAA,IACzB;AAAA,IACA,QAAQ,SAAS;AAAA,IACjB,WAAW,CAAC,CAAC,QAAQ;AAAA,IACrB,SAAS,QAAQ,WAAW;AAAA,IAC5B,aAAa,QAAQ,eAAe;AAAA,IACpC,SAAS,QAAQ,WAAW;AAAA,EAC9B,EAAE;AAEJ,MAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACjE,WAAO,EAAE,eAAe,iBAAiB,MAAM,SAAS,GAAG,EAAE;AAC7D;AAAA,EACF;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,YAAQ,IAAI,yBAAyB;AACrC;AAAA,EACF;AAEA,aAAW,WAAW,UAAU;AAC9B,UAAM,SAAS,QAAQ,SAAS,MAAM;AACtC,UAAM,QAAQ;AAAA,MACZ,GAAG,MAAM,IAAI,QAAQ,IAAI;AAAA,MACzB,QAAQ,YAAY,YAAY;AAAA,MAChC,QAAQ,UAAU,OAAO,QAAQ,OAAO,KAAK;AAAA,MAC7C,QAAQ,cAAc,QAAQ,QAAQ,WAAW,KAAK;AAAA,MACtD,QAAQ,UAAU,WAAW,QAAQ,OAAO,KAAK;AAAA,IACnD,EAAE,OAAO,OAAO;AAChB,YAAQ,IAAI,MAAM,KAAK,IAAI,CAAC;AAAA,EAC9B;AACF,CAAC;AAEH,YACG,QAAQ,eAAe,EACvB,YAAY,6BAA6B,EACzC,OAAO,CAAC,gBAAwB;AAC/B,QAAM,SAAS,WAAW;AAC1B,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,gBAAY,YAAY,WAAW,iDAAiD,WAAW,2BAA2B;AAC1H,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,SAAO,gBAAgB;AACvB,cAAY,MAAM;AAClB;AAAA,IACE,EAAE,eAAe,YAAY;AAAA,IAC7B,iCAA4B,WAAW;AAAA,EACzC;AACF,CAAC;AAEH,YACG,QAAQ,QAAQ,EAChB,YAAY,uBAAuB,EACnC,OAAO,oBAAoB,yBAAyB,EACpD,OAAO,CAAC,SAA+B;AAEtC,QAAM,SAAS,WAAW;AAC1B,QAAM,cAAc,KAAK,WAAW,QAAQ,IAAI,iBAAiB,OAAO;AAExE,MAAI,aAAa;AACf,UAAM,UAAU,WAAW,QAAQ,WAAW;AAC9C,QAAI,CAAC,SAAS;AACZ,kBAAY,YAAY,WAAW,cAAc;AACjD,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,WAAO,QAAQ;AAAA,EACjB,OAAO;AACL,WAAO,OAAO;AAAA,EAChB;AAEA,cAAY,MAAM;AAClB;AAAA,IACE,EAAE,QAAQ,MAAM,SAAS,cAAc,SAAS,eAAe,KAAK;AAAA,IACpE,cACI,iCAA4B,WAAW,yDACvC;AAAA,EACN;AACF,CAAC;;;AGpLH,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,eAAAC,eAAc,IAAI,MAAM;AAChC,QAAM,SAASA,eAAc;AAC7B,QAAM,OAAO,mBAAmB,OAAO;AAEvC,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;AAIO,IAAM,gBAAgB,IAAI,0BAAQ,QAAQ,EAC9C,YAAY,+CAA+C,EAC3D,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,kDAK0B;AAIlD,cACG,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,OAAO,oBAAoB,sBAAsB,EACjD,OAAO,CAAC,SAA+B;AACtC,QAAM,MAAM,WAAW;AACvB,QAAM,gBAAgB,IAAI;AAC1B,QAAM,WAAW,cAAc,EAAE,SAAS,KAAK,QAAQ,CAAC;AACxD,QAAM,YAAY,CAAC,CAAC,SAAS;AAE7B,MAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACjE;AAAA,MACE;AAAA,QACE,eAAe,iBAAiB;AAAA,QAChC,iBAAiB,SAAS,WAAW;AAAA,QACrC,SAAS,SAAS,WAAW;AAAA,QAC7B,aAAa,SAAS,eAAe;AAAA,QACrC,SAAS,SAAS,WAAW;AAAA,QAC7B;AAAA,QACA,UAAU,OAAO,KAAK,IAAI,YAAY,CAAC,CAAC,EAAE,KAAK;AAAA,MACjD;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AAEA,UAAQ,IAAI,GAAG,KAAK,yBAAyB,CAAC,EAAE;AAChD,UAAQ,IAAI,KAAK,IAAI,iBAAiB,CAAC,IAAI,gBAAgB,KAAK,aAAa,IAAI,KAAK,WAAW,CAAC,EAAE;AACpG,UAAQ,IAAI,KAAK,IAAI,mBAAmB,CAAC,IAAI,SAAS,UAAU,KAAK,SAAS,OAAO,IAAI,KAAK,iBAAiB,CAAC,EAAE;AAClH,UAAQ,IAAI,KAAK,IAAI,WAAW,CAAC,OAAO,SAAS,UAAU,KAAK,SAAS,OAAO,IAAI,KAAK,WAAW,CAAC,EAAE;AACvG,UAAQ,IAAI,KAAK,IAAI,eAAe,CAAC,IAAI,SAAS,cAAc,KAAK,SAAS,WAAW,IAAI,KAAK,WAAW,CAAC,EAAE;AAChH,UAAQ,IAAI,KAAK,IAAI,WAAW,CAAC,OAAO,SAAS,UAAU,KAAK,SAAS,OAAO,IAAI,KAAK,WAAW,CAAC,EAAE;AACvG,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,oBAAoB,wBAAwB,EACnD,OAAO,CAAC,MAAc,SAA+B;AACpD,QAAM,MAAM,WAAW;AACvB,QAAM,cAAc,KAAK,WAAW,QAAQ,IAAI,iBAAiB,IAAI;AACrE,MAAI,aAAa;AACf,kBAAc,KAAK,WAAW,EAAE,UAAU;AAAA,EAC5C,OAAO;AACL,QAAI,UAAU;AAAA,EAChB;AACA,cAAY,GAAG;AAEf;AAAA,IACE,EAAE,SAAS,MAAM,SAAS,eAAe,KAAK;AAAA,IAC9C,cACI,QAAQ,4BAA4B,WAAW,aAAa,IAAI,GAAG,IACnE,QAAQ,uBAAuB,IAAI,GAAG;AAAA,EAC5C;AACF,CAAC;AAIH,cACG,QAAQ,iBAAiB,EACzB,YAAY,iCAAiC,EAC7C,OAAO,oBAAoB,wBAAwB,EACnD,OAAO,CAAC,MAAc,SAA+B;AACpD,QAAM,MAAM,WAAW;AACvB,QAAM,cAAc,KAAK,WAAW,QAAQ,IAAI,iBAAiB,IAAI;AACrE,MAAI,aAAa;AACf,kBAAc,KAAK,WAAW,EAAE,cAAc;AAAA,EAChD,OAAO;AACL,QAAI,cAAc;AAAA,EACpB;AACA,cAAY,GAAG;AAEf;AAAA,IACE,EAAE,aAAa,MAAM,SAAS,eAAe,KAAK;AAAA,IAClD,cACI,QAAQ,6BAA6B,WAAW,aAAa,IAAI,GAAG,IACpE,QAAQ,wBAAwB,IAAI,GAAG;AAAA,EAC7C;AACF,CAAC;AAIH,cACG,QAAQ,oBAAoB,EAC5B,YAAY,8BAA8B,EAC1C,OAAO,oBAAoB,wBAAwB,EACnD,OAAO,CAAC,KAAa,SAA+B;AACnD,QAAM,MAAM,WAAW;AACvB,QAAM,cAAc,KAAK,WAAW,QAAQ,IAAI,iBAAiB,IAAI;AACrE,MAAI,aAAa;AACf,kBAAc,KAAK,WAAW,EAAE,UAAU;AAAA,EAC5C,OAAO;AACL,QAAI,UAAU;AAAA,EAChB;AACA,cAAY,GAAG;AAEf;AAAA,IACE,EAAE,SAAS,KAAK,SAAS,eAAe,KAAK;AAAA,IAC7C,cACI,QAAQ,yBAAyB,WAAW,aAAa,GAAG,GAAG,IAC/D,QAAQ,oBAAoB,GAAG,GAAG;AAAA,EACxC;AACF,CAAC;;;ACzHH,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,eAAAC,eAAc,IAAI,MAAM;AAChC,QAAM,SAASA,eAAc;AAC7B,QAAM,OAAO,mBAAmB,OAAO;AAEvC,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;;;AXnKH,SAAS,iBAAyB;AAChC,MAAI;AACF,UAAM,cAAc,KAAK,UAAM,kCAAa,wBAAK,WAAW,MAAM,cAAc,GAAG,OAAO,CAAC;AAG3F,WAAO,YAAY,WAAW;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,UAAU,IAAI,0BAAQ,OAAO,EAChC,YAAY,uDAAkD,EAC9D,QAAQ,eAAe,CAAC,EACxB,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAOF,EAEnB,OAAO,oBAAoB,+CAA+C,EAC1E,OAAO,gBAAgB,4CAA4C,EACnE,OAAO,eAAe,iDAAiD,EACvE,KAAK,aAAa,CAAC,gBAAgB;AAClC,QAAM,OAAO,YAAY,KAAK;AAC9B,MAAI,KAAK,SAAS;AAChB,YAAQ,IAAI,gBAAgB,KAAK;AAAA,EACnC;AACA,MAAI,KAAK,KAAK;AACZ,YAAQ,IAAI,YAAY,KAAK;AAC7B,YAAQ,IAAI,gBAAgB,KAAK;AAAA,EACnC;AACA,MAAI,KAAK,MAAM;AACb,YAAQ,IAAI,aAAa,KAAK;AAC9B,YAAQ,IAAI,iBAAiB,KAAK;AAAA,EACpC;AACF,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;AAAA;AAAA;AAAA;AA6ET;","names":["import_commander","import_node_fs","import_node_path","import_commander","resolveConfig","import_commander","BOLD","DIM","RESET","import_commander","import_commander","progressBar","import_commander","import_commander","handleApiError","resolveOrgId","resolveConfig","padEnd"]}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@atollhq/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Atoll CLI — project management from the terminal",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "bin": {
8
- "atoll": "./dist/index.js"
8
+ "atoll": "dist/index.js"
9
9
  },
10
10
  "files": [
11
11
  "dist",