nixelo 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/README.md +98 -0
  2. package/dist/commands/apiKeys.d.ts +3 -0
  3. package/dist/commands/apiKeys.d.ts.map +1 -0
  4. package/dist/commands/apiKeys.js +200 -0
  5. package/dist/commands/apiKeys.js.map +1 -0
  6. package/dist/commands/auth.d.ts +7 -0
  7. package/dist/commands/auth.d.ts.map +1 -0
  8. package/dist/commands/auth.js +201 -0
  9. package/dist/commands/auth.js.map +1 -0
  10. package/dist/commands/automations.d.ts +3 -0
  11. package/dist/commands/automations.d.ts.map +1 -0
  12. package/dist/commands/automations.js +302 -0
  13. package/dist/commands/automations.js.map +1 -0
  14. package/dist/commands/commandTree.d.ts +10 -0
  15. package/dist/commands/commandTree.d.ts.map +1 -0
  16. package/dist/commands/commandTree.js +36 -0
  17. package/dist/commands/commandTree.js.map +1 -0
  18. package/dist/commands/completion.d.ts +6 -0
  19. package/dist/commands/completion.d.ts.map +1 -0
  20. package/dist/commands/completion.js +101 -0
  21. package/dist/commands/completion.js.map +1 -0
  22. package/dist/commands/config.d.ts +3 -0
  23. package/dist/commands/config.d.ts.map +1 -0
  24. package/dist/commands/config.js +133 -0
  25. package/dist/commands/config.js.map +1 -0
  26. package/dist/commands/documents.d.ts +3 -0
  27. package/dist/commands/documents.d.ts.map +1 -0
  28. package/dist/commands/documents.js +200 -0
  29. package/dist/commands/documents.js.map +1 -0
  30. package/dist/commands/fields.d.ts +3 -0
  31. package/dist/commands/fields.d.ts.map +1 -0
  32. package/dist/commands/fields.js +199 -0
  33. package/dist/commands/fields.js.map +1 -0
  34. package/dist/commands/filters.d.ts +3 -0
  35. package/dist/commands/filters.d.ts.map +1 -0
  36. package/dist/commands/filters.js +243 -0
  37. package/dist/commands/filters.js.map +1 -0
  38. package/dist/commands/global.d.ts +5 -0
  39. package/dist/commands/global.d.ts.map +1 -0
  40. package/dist/commands/global.js +42 -0
  41. package/dist/commands/global.js.map +1 -0
  42. package/dist/commands/index.d.ts +23 -0
  43. package/dist/commands/index.d.ts.map +1 -0
  44. package/dist/commands/index.js +23 -0
  45. package/dist/commands/index.js.map +1 -0
  46. package/dist/commands/invites.d.ts +3 -0
  47. package/dist/commands/invites.d.ts.map +1 -0
  48. package/dist/commands/invites.js +113 -0
  49. package/dist/commands/invites.js.map +1 -0
  50. package/dist/commands/issues/filter.d.ts +19 -0
  51. package/dist/commands/issues/filter.d.ts.map +1 -0
  52. package/dist/commands/issues/filter.js +72 -0
  53. package/dist/commands/issues/filter.js.map +1 -0
  54. package/dist/commands/issues/options.d.ts +33 -0
  55. package/dist/commands/issues/options.d.ts.map +1 -0
  56. package/dist/commands/issues/options.js +68 -0
  57. package/dist/commands/issues/options.js.map +1 -0
  58. package/dist/commands/issues/output.d.ts +12 -0
  59. package/dist/commands/issues/output.d.ts.map +1 -0
  60. package/dist/commands/issues/output.js +285 -0
  61. package/dist/commands/issues/output.js.map +1 -0
  62. package/dist/commands/issues.d.ts +3 -0
  63. package/dist/commands/issues.d.ts.map +1 -0
  64. package/dist/commands/issues.js +483 -0
  65. package/dist/commands/issues.js.map +1 -0
  66. package/dist/commands/labels.d.ts +3 -0
  67. package/dist/commands/labels.d.ts.map +1 -0
  68. package/dist/commands/labels.js +222 -0
  69. package/dist/commands/labels.js.map +1 -0
  70. package/dist/commands/notifications.d.ts +3 -0
  71. package/dist/commands/notifications.d.ts.map +1 -0
  72. package/dist/commands/notifications.js +127 -0
  73. package/dist/commands/notifications.js.map +1 -0
  74. package/dist/commands/projects.d.ts +5 -0
  75. package/dist/commands/projects.d.ts.map +1 -0
  76. package/dist/commands/projects.js +749 -0
  77. package/dist/commands/projects.js.map +1 -0
  78. package/dist/commands/registerAll.d.ts +3 -0
  79. package/dist/commands/registerAll.d.ts.map +1 -0
  80. package/dist/commands/registerAll.js +54 -0
  81. package/dist/commands/registerAll.js.map +1 -0
  82. package/dist/commands/sprints.d.ts +3 -0
  83. package/dist/commands/sprints.d.ts.map +1 -0
  84. package/dist/commands/sprints.js +359 -0
  85. package/dist/commands/sprints.js.map +1 -0
  86. package/dist/commands/stats.d.ts +3 -0
  87. package/dist/commands/stats.d.ts.map +1 -0
  88. package/dist/commands/stats.js +206 -0
  89. package/dist/commands/stats.js.map +1 -0
  90. package/dist/commands/teams.d.ts +3 -0
  91. package/dist/commands/teams.d.ts.map +1 -0
  92. package/dist/commands/teams.js +435 -0
  93. package/dist/commands/teams.js.map +1 -0
  94. package/dist/commands/templates.d.ts +3 -0
  95. package/dist/commands/templates.d.ts.map +1 -0
  96. package/dist/commands/templates.js +264 -0
  97. package/dist/commands/templates.js.map +1 -0
  98. package/dist/commands/time.d.ts +3 -0
  99. package/dist/commands/time.d.ts.map +1 -0
  100. package/dist/commands/time.js +191 -0
  101. package/dist/commands/time.js.map +1 -0
  102. package/dist/commands/tokens.d.ts +3 -0
  103. package/dist/commands/tokens.d.ts.map +1 -0
  104. package/dist/commands/tokens.js +76 -0
  105. package/dist/commands/tokens.js.map +1 -0
  106. package/dist/commands/users.d.ts +5 -0
  107. package/dist/commands/users.d.ts.map +1 -0
  108. package/dist/commands/users.js +160 -0
  109. package/dist/commands/users.js.map +1 -0
  110. package/dist/commands/version.d.ts +3 -0
  111. package/dist/commands/version.d.ts.map +1 -0
  112. package/dist/commands/version.js +17 -0
  113. package/dist/commands/version.js.map +1 -0
  114. package/dist/commands/webhooks.d.ts +3 -0
  115. package/dist/commands/webhooks.d.ts.map +1 -0
  116. package/dist/commands/webhooks.js +407 -0
  117. package/dist/commands/webhooks.js.map +1 -0
  118. package/dist/commands/workspaces.d.ts +3 -0
  119. package/dist/commands/workspaces.d.ts.map +1 -0
  120. package/dist/commands/workspaces.js +424 -0
  121. package/dist/commands/workspaces.js.map +1 -0
  122. package/dist/index.d.ts +8 -0
  123. package/dist/index.d.ts.map +1 -0
  124. package/dist/index.js +14 -0
  125. package/dist/index.js.map +1 -0
  126. package/dist/lib/auth.d.ts +20 -0
  127. package/dist/lib/auth.d.ts.map +1 -0
  128. package/dist/lib/auth.js +80 -0
  129. package/dist/lib/auth.js.map +1 -0
  130. package/dist/lib/convex.d.ts +1243 -0
  131. package/dist/lib/convex.d.ts.map +1 -0
  132. package/dist/lib/convex.js +675 -0
  133. package/dist/lib/convex.js.map +1 -0
  134. package/dist/lib/options.d.ts +10 -0
  135. package/dist/lib/options.d.ts.map +1 -0
  136. package/dist/lib/options.js +79 -0
  137. package/dist/lib/options.js.map +1 -0
  138. package/dist/lib/output.d.ts +19 -0
  139. package/dist/lib/output.d.ts.map +1 -0
  140. package/dist/lib/output.js +60 -0
  141. package/dist/lib/output.js.map +1 -0
  142. package/dist/lib/project-key.d.ts +5 -0
  143. package/dist/lib/project-key.d.ts.map +1 -0
  144. package/dist/lib/project-key.js +56 -0
  145. package/dist/lib/project-key.js.map +1 -0
  146. package/dist/lib/prompt.d.ts +5 -0
  147. package/dist/lib/prompt.d.ts.map +1 -0
  148. package/dist/lib/prompt.js +28 -0
  149. package/dist/lib/prompt.js.map +1 -0
  150. package/dist/lib/user-picker.d.ts +4 -0
  151. package/dist/lib/user-picker.d.ts.map +1 -0
  152. package/dist/lib/user-picker.js +57 -0
  153. package/dist/lib/user-picker.js.map +1 -0
  154. package/package.json +51 -0
package/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # nixelo CLI
2
+
3
+ > TLDR: Local command-line interface for Nixelo. The npm package is not published yet.
4
+
5
+ ## Status
6
+
7
+ - Package and binary name: `nixelo`
8
+ - Current version: `0.0.1`
9
+ - Registry state: unpublished
10
+ - Release verification: `pnpm run cli:release:verify`
11
+ - Focused tests: `pnpm run test:cli:run`
12
+
13
+ Until publication, build and run the workspace entrypoint:
14
+
15
+ ```bash
16
+ pnpm --dir packages/cli run build
17
+ node packages/cli/dist/index.js --help
18
+ ```
19
+
20
+ After publication, the equivalent entrypoint will be `npx nixelo <command>`.
21
+
22
+ ## Versioning
23
+
24
+ Keep releases on `0.0.x` until all of these are true:
25
+
26
+ - package publication and provenance are verified;
27
+ - login, organization identity, issue mutation, revocation, logout, and expired-token live smoke pass;
28
+ - command registration, help, and shell completion parity gates pass;
29
+ - the CLI HTTP API and token-scope documentation match mounted routes;
30
+ - no known P1 or P2 CLI correctness or security defect remains.
31
+
32
+ The first minor version requires a documented stable command and output contract. A major version
33
+ requires an intentional incompatible contract change with migration guidance.
34
+
35
+ ## Authentication And Scope
36
+
37
+ `nixelo login` opens browser authentication and stores one organization-bound CLI token under
38
+ `~/.config/nixelo/`. Use `nixelo login --admin` to request admin scopes when the selected
39
+ organization permits them. `NIXELO_TOKEN` takes precedence over local token storage.
40
+
41
+ The active token, not local config, selects the organization for every request. Run
42
+ `nixelo whoami` to inspect it. `config set --project <key>` stores only a default project key
43
+ within that organization; logging into another organization can require a different project key.
44
+
45
+ ## Command Families
46
+
47
+ ```text
48
+ nixelo login
49
+ nixelo logout
50
+ nixelo whoami
51
+ nixelo apikeys
52
+ nixelo automations
53
+ nixelo tokens
54
+ nixelo config
55
+ nixelo docs
56
+ nixelo fields
57
+ nixelo time
58
+ nixelo templates
59
+ nixelo stats
60
+ nixelo filters
61
+ nixelo issues
62
+ nixelo invites
63
+ nixelo projects
64
+ nixelo sprints
65
+ nixelo labels
66
+ nixelo notifications
67
+ nixelo teams
68
+ nixelo workspaces
69
+ nixelo webhooks
70
+ nixelo users
71
+ nixelo version
72
+ nixelo completion bash|zsh|fish
73
+ ```
74
+
75
+ Run `nixelo --help` for the complete generated command tree and
76
+ `nixelo <command> --help` for arguments and options. Supported machine-readable output uses
77
+ `--json` or `--output json|csv` where applicable. Destructive commands expose `--yes` for
78
+ explicit non-interactive confirmation.
79
+
80
+ ## Configuration
81
+
82
+ ```bash
83
+ nixelo config get
84
+ nixelo config path
85
+ nixelo config set --project ENG
86
+ nixelo config clear --project
87
+ ```
88
+
89
+ Configuration and authentication files live under `~/.config/nixelo/`.
90
+
91
+ ## Development
92
+
93
+ ```bash
94
+ pnpm --dir packages/cli install
95
+ pnpm --dir packages/cli run build
96
+ pnpm --dir packages/cli run typecheck
97
+ pnpm run test:cli:run
98
+ ```
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerApiKeyCommands(program: Command): void;
3
+ //# sourceMappingURL=apiKeys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiKeys.d.ts","sourceRoot":"","sources":["../../src/commands/apiKeys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAqJxC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuG7D"}
@@ -0,0 +1,200 @@
1
+ import { generateApiKey, getApiKeyUsage, listApiKeys, revokeApiKey, rotateApiKey } from "../lib/convex.js";
2
+ import { parseCommaSeparatedListOption, parseDateOption, parsePositiveIntegerOption, readRequiredText } from "../lib/options.js";
3
+ import { getActiveOutputFormat, printError, printJson, printOutput, printRows } from "../lib/output.js";
4
+ import { requireConfirmation } from "../lib/prompt.js";
5
+ import { addOutputOptions } from "./global.js";
6
+ function printGeneratedApiKey(result) {
7
+ const format = getActiveOutputFormat();
8
+ if (format === "json") {
9
+ printJson(result);
10
+ return;
11
+ }
12
+ if (format === "csv") {
13
+ printRows([result], [
14
+ { header: "id", value: key => key.id },
15
+ { header: "apiKey", value: key => key.apiKey },
16
+ { header: "name", value: key => key.name },
17
+ { header: "scopes", value: key => key.scopes.join(" ") },
18
+ { header: "expiresAt", value: key => key.expiresAt ?? "" }
19
+ ], "csv");
20
+ return;
21
+ }
22
+ printOutput(`API key created: ${result.name} (${result.id})`);
23
+ printOutput(`API key: ${result.apiKey}`);
24
+ printOutput("Save this key now. It cannot be shown again.");
25
+ if (result.expiresAt !== undefined) {
26
+ printOutput(`Expires: ${new Date(result.expiresAt).toISOString()}`);
27
+ }
28
+ }
29
+ function printRevokedApiKey(result) {
30
+ const format = getActiveOutputFormat();
31
+ if (format === "json") {
32
+ printJson(result);
33
+ return;
34
+ }
35
+ if (format === "csv") {
36
+ printRows([result], [
37
+ { header: "id", value: key => key.id },
38
+ { header: "prefix", value: key => key.keyPrefix },
39
+ { header: "name", value: key => key.name },
40
+ { header: "revokedAt", value: key => key.revokedAt }
41
+ ], "csv");
42
+ return;
43
+ }
44
+ printOutput(`API key revoked: ${result.name} (${result.id})`);
45
+ }
46
+ function printRotatedApiKey(result) {
47
+ const format = getActiveOutputFormat();
48
+ if (format === "json") {
49
+ printJson(result);
50
+ return;
51
+ }
52
+ if (format === "csv") {
53
+ printRows([result], [
54
+ { header: "id", value: key => key.id },
55
+ { header: "apiKey", value: key => key.apiKey },
56
+ { header: "name", value: key => key.name },
57
+ { header: "oldKeyExpiresAt", value: key => key.oldKeyExpiresAt }
58
+ ], "csv");
59
+ return;
60
+ }
61
+ printOutput(`API key rotated: ${result.name} (${result.id})`);
62
+ printOutput(`API key: ${result.apiKey}`);
63
+ printOutput("Save this key now. It cannot be shown again.");
64
+ printOutput(`Old key expires: ${new Date(result.oldKeyExpiresAt).toISOString()}`);
65
+ }
66
+ function printApiKeyUsage(result) {
67
+ const format = getActiveOutputFormat();
68
+ if (format === "json") {
69
+ printJson(result);
70
+ return;
71
+ }
72
+ printRows([
73
+ { metric: "Total calls", value: result.totalCalls },
74
+ { metric: "Last 24 hours", value: result.last24Hours },
75
+ { metric: "Last hour", value: result.lastHour },
76
+ { metric: "Successful calls", value: result.successCount },
77
+ { metric: "Failed calls", value: result.errorCount },
78
+ { metric: "Average response (ms)", value: result.avgResponseTime }
79
+ ], [
80
+ { header: "metric", value: row => row.metric },
81
+ { header: "value", value: row => row.value }
82
+ ], format);
83
+ if (format === "csv" || result.recentLogs.length === 0)
84
+ return;
85
+ printOutput("");
86
+ printOutput("Recent requests:");
87
+ printRows(result.recentLogs, [
88
+ { header: "method", value: log => log.method },
89
+ { header: "endpoint", value: log => log.endpoint },
90
+ { header: "status", value: log => log.statusCode },
91
+ { header: "responseMs", value: log => log.responseTime },
92
+ { header: "createdAt", value: log => new Date(log.createdAt).toISOString() },
93
+ { header: "error", value: log => log.error ?? "" }
94
+ ], "table");
95
+ }
96
+ function readApiKeyId(value) {
97
+ const keyId = value.trim();
98
+ if (!keyId)
99
+ throw new Error("API key ID is required.");
100
+ return keyId;
101
+ }
102
+ export function registerApiKeyCommands(program) {
103
+ const apiKeysCmd = program.command("apikeys").description("Manage API keys");
104
+ addOutputOptions(apiKeysCmd.command("list"))
105
+ .option("-n, --limit <number>", "Maximum API keys to return")
106
+ .description("List owned API keys for the selected organization")
107
+ .action(async (opts) => {
108
+ try {
109
+ const result = await listApiKeys(parsePositiveIntegerOption(opts.limit));
110
+ const format = getActiveOutputFormat();
111
+ if (format === "json") {
112
+ printJson(result);
113
+ return;
114
+ }
115
+ if (result.apiKeys.length === 0) {
116
+ printOutput("No API keys found.");
117
+ return;
118
+ }
119
+ printRows(result.apiKeys, [
120
+ { header: "id", value: key => key.id },
121
+ { header: "prefix", value: key => key.keyPrefix },
122
+ { header: "name", value: key => key.name },
123
+ { header: "project", value: key => key.projectKey ?? "global" },
124
+ { header: "active", value: key => key.isActive },
125
+ { header: "scopes", value: key => key.scopes.join(" ") },
126
+ { header: "usage", value: key => key.usageCount },
127
+ {
128
+ header: "expiresAt",
129
+ value: key => key.expiresAt === undefined ? "" : new Date(key.expiresAt).toISOString()
130
+ }
131
+ ], format);
132
+ if (result.truncated && format !== "csv") {
133
+ printOutput("Results truncated at the requested limit (maximum 100).");
134
+ }
135
+ }
136
+ catch (error) {
137
+ printError("Failed:", error instanceof Error ? error.message : error);
138
+ process.exit(1);
139
+ }
140
+ });
141
+ addOutputOptions(apiKeysCmd.command("generate"))
142
+ .requiredOption("--name <name>", "API key name")
143
+ .requiredOption("--scopes <scopes>", "Comma-separated read scopes")
144
+ .option("--expires <date>", "Expiration date in YYYY-MM-DD")
145
+ .description("Generate a global read-only API key")
146
+ .action(async (opts) => {
147
+ try {
148
+ const name = readRequiredText(opts.name, "Name", "--name");
149
+ const scopes = parseCommaSeparatedListOption(readRequiredText(opts.scopes, "Scopes", "--scopes"));
150
+ if (scopes.length === 0)
151
+ throw new Error("At least one scope is required.");
152
+ const expiresAt = parseDateOption(opts.expires, "--expires");
153
+ printGeneratedApiKey(await generateApiKey({ expiresAt, name, scopes }));
154
+ }
155
+ catch (error) {
156
+ printError("Failed:", error instanceof Error ? error.message : error);
157
+ process.exit(1);
158
+ }
159
+ });
160
+ addOutputOptions(apiKeysCmd.command("revoke"))
161
+ .argument("<id>", "Active API key ID")
162
+ .option("-y, --yes", "Confirm API key revocation")
163
+ .description("Revoke an active owned API key")
164
+ .action(async (keyId, opts) => {
165
+ try {
166
+ const id = readApiKeyId(keyId);
167
+ await requireConfirmation(`Revoke API key ${id}?`, opts.yes === true);
168
+ printRevokedApiKey(await revokeApiKey(id));
169
+ }
170
+ catch (error) {
171
+ printError("Failed:", error instanceof Error ? error.message : error);
172
+ process.exit(1);
173
+ }
174
+ });
175
+ addOutputOptions(apiKeysCmd.command("rotate"))
176
+ .argument("<id>", "Active API key ID")
177
+ .description("Rotate an active owned API key with a 24-hour grace period")
178
+ .action(async (keyId) => {
179
+ try {
180
+ printRotatedApiKey(await rotateApiKey(readApiKeyId(keyId)));
181
+ }
182
+ catch (error) {
183
+ printError("Failed:", error instanceof Error ? error.message : error);
184
+ process.exit(1);
185
+ }
186
+ });
187
+ addOutputOptions(apiKeysCmd.command("usage"))
188
+ .argument("<id>", "API key ID")
189
+ .description("Show usage statistics for an owned API key")
190
+ .action(async (keyId) => {
191
+ try {
192
+ printApiKeyUsage(await getApiKeyUsage(readApiKeyId(keyId)));
193
+ }
194
+ catch (error) {
195
+ printError("Failed:", error instanceof Error ? error.message : error);
196
+ process.exit(1);
197
+ }
198
+ });
199
+ }
200
+ //# sourceMappingURL=apiKeys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiKeys.js","sourceRoot":"","sources":["../../src/commands/apiKeys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Command } from "commander";
2
+ export declare function buildLoginUrl(port: number, baseUrl?: string, state?: string, includeAdminScopes?: boolean): string;
3
+ export declare function quoteWindowsStartUrl(url: string): string;
4
+ export declare function registerLoginCommand(program: Command): void;
5
+ export declare function registerLogoutCommand(program: Command): void;
6
+ export declare function registerWhoamiCommand(program: Command): void;
7
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA8BxC,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,SAAoE,EAC3E,KAAK,CAAC,EAAE,MAAM,EACd,kBAAkB,UAAQ,GACzB,MAAM,CAMR;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAqJD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiC3D;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkB5D;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAe5D"}
@@ -0,0 +1,201 @@
1
+ import { spawn } from "node:child_process";
2
+ import { randomBytes } from "node:crypto";
3
+ import { createServer } from "node:http";
4
+ import { deleteToken, saveToken } from "../lib/auth.js";
5
+ import { buildCliApiUrl, CLI_API_PATHS, getCurrentUser, isCliAuthenticationError } from "../lib/convex.js";
6
+ import { getActiveOutputFormat, printError, printJson, printOutput, printRows } from "../lib/output.js";
7
+ import { addOutputOptions } from "./global.js";
8
+ import { printCurrentUser } from "./users.js";
9
+ const LOGIN_STATE_BYTES = 32;
10
+ const LOCAL_CALLBACK_HOST = "127.0.0.1";
11
+ function createLoginState() {
12
+ return randomBytes(LOGIN_STATE_BYTES).toString("base64url");
13
+ }
14
+ export function buildLoginUrl(port, baseUrl = process.env.NIXELO_AUTH_URL ?? buildCliApiUrl(CLI_API_PATHS.auth), state, includeAdminScopes = false) {
15
+ const url = new URL(baseUrl);
16
+ url.searchParams.set("port", String(port));
17
+ if (state)
18
+ url.searchParams.set("state", state);
19
+ if (includeAdminScopes)
20
+ url.searchParams.set("admin", "1");
21
+ return url.toString();
22
+ }
23
+ export function quoteWindowsStartUrl(url) {
24
+ return `"${url.replaceAll('"', "%22")}"`;
25
+ }
26
+ function isExpectedCallbackHost(hostHeader, expectedPort) {
27
+ return expectedPort !== null && hostHeader === `${LOCAL_CALLBACK_HOST}:${expectedPort}`;
28
+ }
29
+ function parseCallbackRequest(rawUrl, expectedState, hostHeader, expectedPort, method = "GET") {
30
+ const url = new URL(rawUrl, `http://${LOCAL_CALLBACK_HOST}`);
31
+ const token = url.searchParams.get("token");
32
+ const state = url.searchParams.get("state");
33
+ const error = url.searchParams.get("error");
34
+ const isCallback = url.pathname === "/callback";
35
+ if (!isCallback)
36
+ return { kind: "ignore" };
37
+ if (method !== "GET") {
38
+ return {
39
+ kind: "failure",
40
+ message: "Invalid login callback method",
41
+ responseBody: "Authentication callback must use GET."
42
+ };
43
+ }
44
+ if (!isExpectedCallbackHost(hostHeader, expectedPort)) {
45
+ return {
46
+ kind: "failure",
47
+ message: "Invalid login callback host",
48
+ responseBody: "Authentication callback host mismatch. Run `npx nixelo login` again."
49
+ };
50
+ }
51
+ if (state !== expectedState) {
52
+ return {
53
+ kind: "failure",
54
+ message: "Login state mismatch",
55
+ responseBody: "Authentication state mismatch. Run `npx nixelo login` again."
56
+ };
57
+ }
58
+ if (error) {
59
+ return {
60
+ kind: "failure",
61
+ message: `Login failed: ${error}`,
62
+ responseBody: "Authentication failed. Return to your terminal and try again."
63
+ };
64
+ }
65
+ if (!token) {
66
+ return {
67
+ kind: "failure",
68
+ message: "Login callback missing token",
69
+ responseBody: "Authentication callback was missing a token."
70
+ };
71
+ }
72
+ return { kind: "success", token };
73
+ }
74
+ async function startCallbackServer(expectedState, onReady) {
75
+ return new Promise((resolve, reject) => {
76
+ let expectedPort = null;
77
+ const server = createServer((req, res) => {
78
+ const callbackResult = parseCallbackRequest(req.url ?? "/", expectedState, req.headers.host, expectedPort, req.method);
79
+ if (callbackResult.kind === "ignore") {
80
+ res.writeHead(404, { "Content-Type": "text/plain" });
81
+ res.end("Not found");
82
+ return;
83
+ }
84
+ if (callbackResult.kind === "failure") {
85
+ res.writeHead(400, { "Content-Type": "text/plain" });
86
+ res.end(callbackResult.responseBody);
87
+ server.close(() => reject(new Error(callbackResult.message)));
88
+ return;
89
+ }
90
+ res.writeHead(200, { "Content-Type": "text/plain" });
91
+ res.end("Authenticated! You may close this window and return to your terminal.");
92
+ server.close(() => resolve(callbackResult.token));
93
+ });
94
+ const timeout = setTimeout(() => {
95
+ server.close(() => reject(new Error("Login timed out after 120s")));
96
+ }, 120_000);
97
+ server.on("close", () => clearTimeout(timeout));
98
+ server.on("error", reject);
99
+ server.listen(0, LOCAL_CALLBACK_HOST, () => {
100
+ const address = server.address();
101
+ if (!address || typeof address !== "object") {
102
+ server.close(() => reject(new Error("Could not get free port")));
103
+ return;
104
+ }
105
+ expectedPort = address.port;
106
+ try {
107
+ onReady(address.port);
108
+ }
109
+ catch (error) {
110
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
111
+ server.close(() => reject(normalizedError));
112
+ }
113
+ });
114
+ });
115
+ }
116
+ function openBrowser(url) {
117
+ const platform = process.platform;
118
+ if (platform === "win32") {
119
+ const child = spawn("cmd", ["/c", "start", "", quoteWindowsStartUrl(url)], {
120
+ detached: true,
121
+ stdio: "ignore"
122
+ });
123
+ child.on("error", () => undefined);
124
+ child.unref();
125
+ return;
126
+ }
127
+ const command = platform === "darwin" ? "open" : "xdg-open";
128
+ const child = spawn(command, [url], { detached: true, stdio: "ignore" });
129
+ child.on("error", () => undefined);
130
+ child.unref();
131
+ }
132
+ function printLoginProgress(format, message) {
133
+ if (format === "table") {
134
+ printOutput(message);
135
+ return;
136
+ }
137
+ printError(message);
138
+ }
139
+ export function registerLoginCommand(program) {
140
+ addOutputOptions(program
141
+ .command("login")
142
+ .description("Authenticate with Nixelo via browser OAuth")
143
+ .option("--admin", "request admin CLI scopes for workspace administration")).action(async (options) => {
144
+ try {
145
+ const format = getActiveOutputFormat();
146
+ const state = createLoginState();
147
+ const token = await startCallbackServer(state, port => {
148
+ const authUrl = buildLoginUrl(port, undefined, state, options.admin === true);
149
+ printLoginProgress(format, "Opening browser to authenticate...");
150
+ printLoginProgress(format, `If the browser doesn't open, visit: ${authUrl}`);
151
+ openBrowser(authUrl);
152
+ });
153
+ await saveToken(token);
154
+ if (format === "json") {
155
+ printJson({ authenticated: true });
156
+ }
157
+ else if (format === "csv") {
158
+ printRows([{ authenticated: true }], [{ header: "authenticated", value: row => row.authenticated }], format);
159
+ }
160
+ else {
161
+ printOutput("Authenticated!");
162
+ }
163
+ }
164
+ catch (error) {
165
+ printError("Login failed:", error instanceof Error ? error.message : error);
166
+ process.exit(1);
167
+ }
168
+ });
169
+ }
170
+ export function registerLogoutCommand(program) {
171
+ addOutputOptions(program.command("logout").description("Remove stored token")).action(async () => {
172
+ await deleteToken();
173
+ const format = getActiveOutputFormat();
174
+ if (format === "json") {
175
+ printJson({ loggedOut: true });
176
+ }
177
+ else if (format === "csv") {
178
+ printRows([{ loggedOut: true }], [{ header: "loggedOut", value: row => row.loggedOut }], format);
179
+ }
180
+ else {
181
+ printOutput("Logged out.");
182
+ }
183
+ });
184
+ }
185
+ export function registerWhoamiCommand(program) {
186
+ addOutputOptions(program.command("whoami").description("Show authenticated user")).action(async () => {
187
+ try {
188
+ printCurrentUser(await getCurrentUser());
189
+ }
190
+ catch (error) {
191
+ if (isCliAuthenticationError(error)) {
192
+ printError("Not authenticated. Run `npx nixelo login` first.");
193
+ }
194
+ else {
195
+ printError("Failed:", error instanceof Error ? error.message : error);
196
+ }
197
+ process.exit(1);
198
+ }
199
+ });
200
+ }
201
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerAutomationCommands(program: Command): void;
3
+ //# sourceMappingURL=automations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../../src/commands/automations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAiQxC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkGjE"}