exponential-cli 1.0.0

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 ADDED
@@ -0,0 +1,226 @@
1
+ # Exponential CLI
2
+
3
+ CLI tool to interact with the Exponential productivity app. Pull actions, projects, and workspaces from your Exponential account for use with LLMs and automation.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g exponential-cli
9
+ ```
10
+
11
+ Or run directly with npx:
12
+
13
+ ```bash
14
+ npx exponential-cli --help
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ### 1. Generate an API Token
20
+
21
+ 1. Log into Exponential
22
+ 2. Navigate to `/tokens`
23
+ 3. Create a new API key with type "JWT"
24
+ 4. Copy the generated token
25
+
26
+ ### 2. Configure the CLI
27
+
28
+ ```bash
29
+ exponential auth login --token <your-jwt-token> --api-url https://app.exponential.so
30
+ ```
31
+
32
+ ### 3. Verify Authentication
33
+
34
+ ```bash
35
+ exponential auth whoami
36
+ ```
37
+
38
+ ## Commands
39
+
40
+ ### Authentication
41
+
42
+ ```bash
43
+ # Login with token
44
+ exponential auth login --token <jwt> --api-url <url>
45
+
46
+ # Check authentication status
47
+ exponential auth whoami
48
+ exponential auth status
49
+
50
+ # Logout
51
+ exponential auth logout
52
+ ```
53
+
54
+ ### Actions
55
+
56
+ ```bash
57
+ # List all active actions
58
+ exponential actions list
59
+
60
+ # List actions for a specific project
61
+ exponential actions list --project <project-id>
62
+
63
+ # List actions with a specific kanban status
64
+ exponential actions list --status IN_PROGRESS
65
+
66
+ # Get today's actions
67
+ exponential actions today
68
+
69
+ # Get actions in a date range
70
+ exponential actions range --start 2024-01-01 --end 2024-01-31
71
+
72
+ # Get kanban board view
73
+ exponential actions kanban --project <project-id>
74
+ ```
75
+
76
+ ### Projects
77
+
78
+ ```bash
79
+ # List all projects
80
+ exponential projects list
81
+
82
+ # List projects in a workspace
83
+ exponential projects list --workspace <workspace-id>
84
+ ```
85
+
86
+ ### Workspaces
87
+
88
+ ```bash
89
+ # List all workspaces
90
+ exponential workspaces list
91
+
92
+ # Set default workspace
93
+ exponential workspaces set-default <workspace-slug>
94
+ ```
95
+
96
+ ## Output Formats
97
+
98
+ ### JSON Output (for LLMs and automation)
99
+
100
+ By default, output is JSON when piped. Force JSON output:
101
+
102
+ ```bash
103
+ exponential actions list --json
104
+ ```
105
+
106
+ Example output:
107
+
108
+ ```json
109
+ {
110
+ "actions": [
111
+ {
112
+ "id": "clx123abc",
113
+ "name": "Fix authentication bug",
114
+ "description": "JWT tokens expiring too early",
115
+ "status": "ACTIVE",
116
+ "priority": "1st Priority",
117
+ "kanbanStatus": "IN_PROGRESS",
118
+ "dueDate": "2024-01-15T00:00:00.000Z",
119
+ "project": {
120
+ "id": "clx456def",
121
+ "name": "Exponential App"
122
+ },
123
+ "assignees": []
124
+ }
125
+ ],
126
+ "total": 1,
127
+ "filters": {}
128
+ }
129
+ ```
130
+
131
+ ### Pretty Output (for humans)
132
+
133
+ Force human-readable output:
134
+
135
+ ```bash
136
+ exponential actions list --pretty
137
+ ```
138
+
139
+ ## LLM Integration
140
+
141
+ ### Python Example
142
+
143
+ ```python
144
+ import subprocess
145
+ import json
146
+
147
+ def get_exponential_actions(project_id=None):
148
+ cmd = ['exponential', 'actions', 'list', '--json']
149
+ if project_id:
150
+ cmd.extend(['--project', project_id])
151
+
152
+ result = subprocess.run(cmd, capture_output=True, text=True)
153
+ return json.loads(result.stdout)
154
+
155
+ # Get all actions
156
+ actions = get_exponential_actions()
157
+
158
+ # Get actions for a specific project
159
+ project_actions = get_exponential_actions('clx456def')
160
+ ```
161
+
162
+ ### Shell Example
163
+
164
+ ```bash
165
+ # Get actions and pipe to jq
166
+ exponential actions list --json | jq '.actions[] | {name, priority, status: .kanbanStatus}'
167
+
168
+ # Count actions by status
169
+ exponential actions kanban --json | jq '.actions | group_by(.kanbanStatus) | map({status: .[0].kanbanStatus, count: length})'
170
+ ```
171
+
172
+ ### Claude/LLM Prompt Example
173
+
174
+ ```
175
+ I have access to the Exponential CLI. Here are my current actions:
176
+
177
+ $(exponential actions list --json)
178
+
179
+ Based on these actions, what should I work on next considering priority and due dates?
180
+ ```
181
+
182
+ ## Configuration
183
+
184
+ Configuration is stored in:
185
+ - macOS: `~/Library/Preferences/exponential-cli-nodejs/config.json`
186
+ - Linux: `~/.config/exponential-cli-nodejs/config.json`
187
+ - Windows: `%APPDATA%\exponential-cli-nodejs\config.json`
188
+
189
+ ## Kanban Status Values
190
+
191
+ - `BACKLOG` - In backlog
192
+ - `TODO` - Ready to work on
193
+ - `IN_PROGRESS` - Currently being worked on
194
+ - `IN_REVIEW` - In review
195
+ - `DONE` - Completed
196
+ - `CANCELLED` - Cancelled
197
+
198
+ ## Priority Values
199
+
200
+ - `1st Priority` through `5th Priority`
201
+ - `Quick` - Quick tasks
202
+ - `Scheduled` - Scheduled tasks
203
+ - `Errand` - Errands
204
+ - `Remember` - Things to remember
205
+ - `Watch` - Items to watch
206
+ - `Someday Maybe` - Future possibilities
207
+
208
+ ## Development
209
+
210
+ ```bash
211
+ # Install dependencies
212
+ npm install
213
+
214
+ # Build
215
+ npm run build
216
+
217
+ # Run locally
218
+ node bin/exponential.js --help
219
+
220
+ # Link for local testing
221
+ npm link
222
+ ```
223
+
224
+ ## License
225
+
226
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/index.js';
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,538 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command as Command5 } from "commander";
5
+
6
+ // src/commands/auth.ts
7
+ import { Command } from "commander";
8
+ import chalk2 from "chalk";
9
+
10
+ // src/config/index.ts
11
+ import { createConfigStore } from "exponential-sdk";
12
+ var configStore = createConfigStore({ projectName: "exponential-cli" });
13
+ function getConfig() {
14
+ return configStore.loadConfig();
15
+ }
16
+ function setConfig(values) {
17
+ configStore.saveConfig(values);
18
+ }
19
+ function clearConfig() {
20
+ configStore.clearConfig();
21
+ }
22
+ function isAuthenticated() {
23
+ return configStore.isAuthenticated();
24
+ }
25
+ function getConfigPath() {
26
+ return configStore.getConfigPath();
27
+ }
28
+
29
+ // src/client/index.ts
30
+ import { ExponentialClient } from "exponential-sdk";
31
+ import { isTRPCError, TRPCClientError } from "exponential-sdk";
32
+ var clientInstance = null;
33
+ function getClient() {
34
+ if (!isAuthenticated()) {
35
+ throw new Error("Not authenticated. Run: exponential auth login --token <your-jwt> --api-url <url>");
36
+ }
37
+ if (clientInstance) {
38
+ return clientInstance;
39
+ }
40
+ const config = getConfig();
41
+ clientInstance = new ExponentialClient({
42
+ token: config.token,
43
+ apiUrl: config.apiUrl
44
+ });
45
+ return clientInstance;
46
+ }
47
+ function resetClient() {
48
+ clientInstance = null;
49
+ }
50
+
51
+ // src/utils/errors.ts
52
+ import chalk from "chalk";
53
+ var ExponentialError = class extends Error {
54
+ constructor(message, code, suggestion, details) {
55
+ super(message);
56
+ this.code = code;
57
+ this.suggestion = suggestion;
58
+ this.details = details;
59
+ this.name = "ExponentialError";
60
+ }
61
+ };
62
+ function handleError(error, json = false) {
63
+ if (error instanceof ExponentialError) {
64
+ if (json) {
65
+ console.log(JSON.stringify({
66
+ error: {
67
+ code: error.code,
68
+ message: error.message,
69
+ suggestion: error.suggestion
70
+ }
71
+ }, null, 2));
72
+ } else {
73
+ console.error(chalk.red(`Error: ${error.message}`));
74
+ if (error.suggestion) {
75
+ console.error(chalk.yellow(`Suggestion: ${error.suggestion}`));
76
+ }
77
+ }
78
+ process.exit(1);
79
+ }
80
+ if (isTRPCError(error)) {
81
+ const code = error.data?.code ?? "UNKNOWN";
82
+ let message = error.message;
83
+ let suggestion;
84
+ switch (code) {
85
+ case "UNAUTHORIZED":
86
+ message = "Authentication failed. Your token may have expired.";
87
+ suggestion = "Run: exponential auth login --token <new-token> --api-url <url>";
88
+ break;
89
+ case "NOT_FOUND":
90
+ message = "Resource not found";
91
+ break;
92
+ case "FORBIDDEN":
93
+ message = "Access denied";
94
+ break;
95
+ }
96
+ if (json) {
97
+ console.log(JSON.stringify({
98
+ error: {
99
+ code,
100
+ message,
101
+ suggestion
102
+ }
103
+ }, null, 2));
104
+ } else {
105
+ console.error(chalk.red(`Error [${code}]: ${message}`));
106
+ if (suggestion) {
107
+ console.error(chalk.yellow(`Suggestion: ${suggestion}`));
108
+ }
109
+ }
110
+ process.exit(1);
111
+ }
112
+ if (json) {
113
+ console.log(JSON.stringify({
114
+ error: {
115
+ code: "UNKNOWN",
116
+ message: error instanceof Error ? error.message : String(error)
117
+ }
118
+ }, null, 2));
119
+ } else {
120
+ console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
121
+ }
122
+ process.exit(1);
123
+ }
124
+
125
+ // src/commands/auth.ts
126
+ function createAuthCommand() {
127
+ const auth = new Command("auth").description("Authentication commands");
128
+ auth.command("login").description("Configure CLI with your API token").requiredOption("--token <token>", "JWT token from /tokens page").requiredOption("--api-url <url>", "API URL (e.g., https://app.exponential.so)").action(async (options) => {
129
+ try {
130
+ let apiUrl = options.apiUrl.replace(/\/+$/, "");
131
+ if (!apiUrl.startsWith("http://localhost") && !apiUrl.startsWith("https://")) {
132
+ apiUrl = `https://${apiUrl}`;
133
+ }
134
+ setConfig({
135
+ token: options.token,
136
+ apiUrl
137
+ });
138
+ resetClient();
139
+ console.log(chalk2.gray("Validating token..."));
140
+ const client = getClient();
141
+ await client.workspaces.list();
142
+ console.log(chalk2.green("Successfully authenticated!"));
143
+ console.log(chalk2.gray(`Config saved to: ${getConfigPath()}`));
144
+ } catch (error) {
145
+ clearConfig();
146
+ handleError(error);
147
+ }
148
+ });
149
+ auth.command("logout").description("Remove stored credentials").action(() => {
150
+ clearConfig();
151
+ resetClient();
152
+ console.log(chalk2.green("Successfully logged out."));
153
+ console.log(chalk2.gray(`Config cleared from: ${getConfigPath()}`));
154
+ });
155
+ auth.command("whoami").description("Show current authentication status").action(async () => {
156
+ if (!isAuthenticated()) {
157
+ console.log(chalk2.yellow("Not authenticated."));
158
+ console.log(chalk2.gray("Run: exponential auth login --token <jwt> --api-url <url>"));
159
+ process.exit(1);
160
+ }
161
+ try {
162
+ const config = getConfig();
163
+ const client = getClient();
164
+ const workspaces = await client.workspaces.list();
165
+ console.log(chalk2.green("Authenticated"));
166
+ console.log(chalk2.gray(`API URL: ${config.apiUrl}`));
167
+ console.log(chalk2.gray(`Workspaces: ${workspaces.length}`));
168
+ console.log(chalk2.gray(`Config: ${getConfigPath()}`));
169
+ } catch (error) {
170
+ handleError(error);
171
+ }
172
+ });
173
+ auth.command("status").description("Show detailed authentication status").action(() => {
174
+ const config = getConfig();
175
+ console.log(chalk2.bold("\nAuthentication Status"));
176
+ console.log(chalk2.gray("\u2500".repeat(40)));
177
+ console.log(`Authenticated: ${isAuthenticated() ? chalk2.green("Yes") : chalk2.red("No")}`);
178
+ console.log(`API URL: ${config.apiUrl || chalk2.gray("(not set)")}`);
179
+ console.log(`Token: ${config.token ? chalk2.gray(`${config.token.substring(0, 20)}...`) : chalk2.gray("(not set)")}`);
180
+ console.log(`Config Path: ${getConfigPath()}`);
181
+ console.log();
182
+ });
183
+ return auth;
184
+ }
185
+
186
+ // src/commands/actions.ts
187
+ import { Command as Command2 } from "commander";
188
+
189
+ // src/utils/output.ts
190
+ import chalk3 from "chalk";
191
+ function shouldUseJson(forceJson, forcePretty) {
192
+ if (forceJson) return true;
193
+ if (forcePretty) return false;
194
+ return !process.stdout.isTTY;
195
+ }
196
+ function transformAction(action) {
197
+ return {
198
+ id: action.id,
199
+ name: action.name,
200
+ description: action.description,
201
+ status: action.status,
202
+ priority: action.priority,
203
+ kanbanStatus: action.kanbanStatus,
204
+ dueDate: action.dueDate?.toISOString() ?? null,
205
+ scheduledStart: action.scheduledStart?.toISOString() ?? null,
206
+ scheduledEnd: action.scheduledEnd?.toISOString() ?? null,
207
+ project: action.project ? {
208
+ id: action.project.id,
209
+ name: action.project.name
210
+ } : null,
211
+ workspace: action.workspace ? {
212
+ id: action.workspace.id,
213
+ slug: action.workspace.slug,
214
+ name: action.workspace.name
215
+ } : null,
216
+ assignees: action.assignees?.map((a) => ({
217
+ id: a.user.id,
218
+ name: a.user.name,
219
+ email: a.user.email
220
+ })) ?? [],
221
+ createdAt: action.createdAt?.toISOString() ?? (/* @__PURE__ */ new Date()).toISOString(),
222
+ completedAt: action.completedAt?.toISOString() ?? null
223
+ };
224
+ }
225
+ function transformProject(project) {
226
+ return {
227
+ id: project.id,
228
+ name: project.name,
229
+ description: project.description,
230
+ status: project.status,
231
+ priority: project.priority,
232
+ workspace: project.workspace ? {
233
+ id: project.workspace.id,
234
+ slug: project.workspace.slug,
235
+ name: project.workspace.name
236
+ } : null
237
+ };
238
+ }
239
+ function transformWorkspace(workspace) {
240
+ return {
241
+ id: workspace.id,
242
+ name: workspace.name,
243
+ slug: workspace.slug,
244
+ type: workspace.type
245
+ };
246
+ }
247
+ function outputActionsJson(actions, filters = {}) {
248
+ const output = {
249
+ actions: actions.map(transformAction),
250
+ total: actions.length,
251
+ filters
252
+ };
253
+ console.log(JSON.stringify(output, null, 2));
254
+ }
255
+ function outputActionsPretty(actions) {
256
+ if (actions.length === 0) {
257
+ console.log(chalk3.gray("No actions found."));
258
+ return;
259
+ }
260
+ console.log(chalk3.bold(`
261
+ Actions (${actions.length} total)`));
262
+ console.log(chalk3.gray("\u2500".repeat(50)));
263
+ for (const action of actions) {
264
+ const statusColor = getKanbanStatusColor(action.kanbanStatus);
265
+ const statusBadge = action.kanbanStatus ? chalk3[statusColor](`[${action.kanbanStatus}]`) : chalk3.gray("[NO STATUS]");
266
+ console.log(`
267
+ ${statusBadge} ${chalk3.bold(action.name)}`);
268
+ console.log(chalk3.gray(` ID: ${action.id}`));
269
+ if (action.project) {
270
+ console.log(` ${chalk3.cyan("Project:")} ${action.project.name}`);
271
+ }
272
+ console.log(` ${chalk3.magenta("Priority:")} ${action.priority}`);
273
+ if (action.dueDate) {
274
+ const dueDate = new Date(action.dueDate);
275
+ const isOverdue = dueDate < /* @__PURE__ */ new Date();
276
+ const dateStr = formatDate(dueDate);
277
+ console.log(` ${chalk3.yellow("Due:")} ${isOverdue ? chalk3.red(dateStr) : dateStr}`);
278
+ }
279
+ if (action.description) {
280
+ console.log(` ${chalk3.gray("Description:")} ${action.description.substring(0, 100)}${action.description.length > 100 ? "..." : ""}`);
281
+ }
282
+ }
283
+ console.log();
284
+ }
285
+ function outputProjectsJson(projects) {
286
+ const output = {
287
+ projects: projects.map(transformProject),
288
+ total: projects.length
289
+ };
290
+ console.log(JSON.stringify(output, null, 2));
291
+ }
292
+ function outputProjectsPretty(projects) {
293
+ if (projects.length === 0) {
294
+ console.log(chalk3.gray("No projects found."));
295
+ return;
296
+ }
297
+ console.log(chalk3.bold(`
298
+ Projects (${projects.length} total)`));
299
+ console.log(chalk3.gray("\u2500".repeat(50)));
300
+ for (const project of projects) {
301
+ console.log(`
302
+ ${chalk3.bold(project.name)}`);
303
+ console.log(chalk3.gray(` ID: ${project.id}`));
304
+ if (project.status) {
305
+ console.log(` ${chalk3.cyan("Status:")} ${project.status}`);
306
+ }
307
+ if (project.priority) {
308
+ console.log(` ${chalk3.magenta("Priority:")} ${project.priority}`);
309
+ }
310
+ if (project.workspace) {
311
+ console.log(` ${chalk3.yellow("Workspace:")} ${project.workspace.name} (${project.workspace.slug})`);
312
+ }
313
+ if (project.description) {
314
+ console.log(` ${chalk3.gray("Description:")} ${project.description.substring(0, 100)}${project.description.length > 100 ? "..." : ""}`);
315
+ }
316
+ }
317
+ console.log();
318
+ }
319
+ function outputWorkspacesJson(workspaces) {
320
+ const output = {
321
+ workspaces: workspaces.map(transformWorkspace),
322
+ total: workspaces.length
323
+ };
324
+ console.log(JSON.stringify(output, null, 2));
325
+ }
326
+ function outputWorkspacesPretty(workspaces) {
327
+ if (workspaces.length === 0) {
328
+ console.log(chalk3.gray("No workspaces found."));
329
+ return;
330
+ }
331
+ console.log(chalk3.bold(`
332
+ Workspaces (${workspaces.length} total)`));
333
+ console.log(chalk3.gray("\u2500".repeat(50)));
334
+ for (const workspace of workspaces) {
335
+ console.log(`
336
+ ${chalk3.bold(workspace.name)}`);
337
+ console.log(chalk3.gray(` ID: ${workspace.id}`));
338
+ console.log(` ${chalk3.cyan("Slug:")} ${workspace.slug}`);
339
+ console.log(` ${chalk3.magenta("Type:")} ${workspace.type}`);
340
+ }
341
+ console.log();
342
+ }
343
+ function getKanbanStatusColor(status) {
344
+ switch (status) {
345
+ case "BACKLOG":
346
+ return "gray";
347
+ case "TODO":
348
+ return "blue";
349
+ case "IN_PROGRESS":
350
+ return "yellow";
351
+ case "IN_REVIEW":
352
+ return "cyan";
353
+ case "DONE":
354
+ return "green";
355
+ case "CANCELLED":
356
+ return "red";
357
+ default:
358
+ return "gray";
359
+ }
360
+ }
361
+ function formatDate(date) {
362
+ return date.toLocaleDateString("en-US", {
363
+ year: "numeric",
364
+ month: "short",
365
+ day: "numeric"
366
+ });
367
+ }
368
+
369
+ // src/commands/actions.ts
370
+ function createActionsCommand() {
371
+ const actions = new Command2("actions").description("Manage actions/tasks");
372
+ actions.command("list").description("List all actions").option("--project <id>", "Filter by project ID").option("--status <status>", "Filter by kanban status (BACKLOG, TODO, IN_PROGRESS, IN_REVIEW, DONE)").option("--assignee <id>", "Filter by assignee ID").action(async (options, cmd) => {
373
+ const globalOpts = cmd.optsWithGlobals();
374
+ const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
375
+ try {
376
+ const client = getClient();
377
+ const kanbanStatus = options.status;
378
+ const actions2 = await client.actions.list({
379
+ projectId: options.project,
380
+ status: kanbanStatus,
381
+ assigneeId: options.assignee
382
+ });
383
+ if (useJson) {
384
+ outputActionsJson(actions2, {
385
+ projectId: options.project,
386
+ kanbanStatus: options.status
387
+ });
388
+ } else {
389
+ outputActionsPretty(actions2);
390
+ }
391
+ } catch (error) {
392
+ handleError(error, useJson);
393
+ }
394
+ });
395
+ actions.command("today").description("Get actions due today").option("--workspace <id>", "Filter by workspace ID").action(async (options, cmd) => {
396
+ const globalOpts = cmd.optsWithGlobals();
397
+ const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
398
+ try {
399
+ const client = getClient();
400
+ const actions2 = await client.actions.getToday(options.workspace);
401
+ if (useJson) {
402
+ outputActionsJson(actions2, { workspaceId: options.workspace });
403
+ } else {
404
+ outputActionsPretty(actions2);
405
+ }
406
+ } catch (error) {
407
+ handleError(error, useJson);
408
+ }
409
+ });
410
+ actions.command("range").description("Get actions by date range").requiredOption("--start <date>", "Start date (YYYY-MM-DD)").requiredOption("--end <date>", "End date (YYYY-MM-DD)").option("--workspace <id>", "Filter by workspace ID").action(async (options, cmd) => {
411
+ const globalOpts = cmd.optsWithGlobals();
412
+ const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
413
+ try {
414
+ const startDate = new Date(options.start);
415
+ const endDate = new Date(options.end);
416
+ if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
417
+ throw new Error("Invalid date format. Use YYYY-MM-DD");
418
+ }
419
+ const client = getClient();
420
+ const actions2 = await client.actions.getByDateRange(startDate, endDate, options.workspace);
421
+ if (useJson) {
422
+ outputActionsJson(actions2, { workspaceId: options.workspace });
423
+ } else {
424
+ outputActionsPretty(actions2);
425
+ }
426
+ } catch (error) {
427
+ handleError(error, useJson);
428
+ }
429
+ });
430
+ actions.command("kanban").description("Get kanban board actions").option("--project <id>", "Filter by project ID").option("--status <status>", "Filter by kanban status").option("--assignee <id>", "Filter by assignee ID").action(async (options, cmd) => {
431
+ const globalOpts = cmd.optsWithGlobals();
432
+ const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
433
+ try {
434
+ const client = getClient();
435
+ const kanbanStatus = options.status;
436
+ const actions2 = await client.actions.getKanban({
437
+ projectId: options.project,
438
+ status: kanbanStatus,
439
+ assigneeId: options.assignee
440
+ });
441
+ if (useJson) {
442
+ outputActionsJson(actions2, {
443
+ projectId: options.project,
444
+ kanbanStatus: options.status
445
+ });
446
+ } else {
447
+ outputActionsPretty(actions2);
448
+ }
449
+ } catch (error) {
450
+ handleError(error, useJson);
451
+ }
452
+ });
453
+ return actions;
454
+ }
455
+
456
+ // src/commands/projects.ts
457
+ import { Command as Command3 } from "commander";
458
+ function createProjectsCommand() {
459
+ const projects = new Command3("projects").description("Manage projects");
460
+ projects.command("list").description("List all projects").option("--workspace <id>", "Filter by workspace ID").option("--include-actions", "Include actions in output").action(async (options, cmd) => {
461
+ const globalOpts = cmd.optsWithGlobals();
462
+ const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
463
+ try {
464
+ const client = getClient();
465
+ const projects2 = await client.projects.list({
466
+ workspaceId: options.workspace,
467
+ includeActions: options.includeActions
468
+ });
469
+ if (useJson) {
470
+ outputProjectsJson(projects2);
471
+ } else {
472
+ outputProjectsPretty(projects2);
473
+ }
474
+ } catch (error) {
475
+ handleError(error, useJson);
476
+ }
477
+ });
478
+ return projects;
479
+ }
480
+
481
+ // src/commands/workspaces.ts
482
+ import { Command as Command4 } from "commander";
483
+ import chalk4 from "chalk";
484
+ function createWorkspacesCommand() {
485
+ const workspaces = new Command4("workspaces").description("Manage workspaces");
486
+ workspaces.command("list").description("List all workspaces").action(async (_options, cmd) => {
487
+ const globalOpts = cmd.optsWithGlobals();
488
+ const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
489
+ try {
490
+ const client = getClient();
491
+ const workspaces2 = await client.workspaces.list();
492
+ if (useJson) {
493
+ outputWorkspacesJson(workspaces2);
494
+ } else {
495
+ const config = getConfig();
496
+ outputWorkspacesPretty(workspaces2);
497
+ if (config.defaultWorkspaceSlug) {
498
+ console.log(chalk4.gray(`Default workspace: ${config.defaultWorkspaceSlug}`));
499
+ }
500
+ }
501
+ } catch (error) {
502
+ handleError(error, useJson);
503
+ }
504
+ });
505
+ workspaces.command("set-default <slug>").description("Set the default workspace").action(async (slug) => {
506
+ try {
507
+ const client = getClient();
508
+ const workspaces2 = await client.workspaces.list();
509
+ const workspace = workspaces2.find((w) => w.slug === slug);
510
+ if (!workspace) {
511
+ console.error(chalk4.red(`Workspace with slug "${slug}" not found.`));
512
+ console.log(chalk4.gray("Available workspaces:"));
513
+ workspaces2.forEach((w) => {
514
+ console.log(chalk4.gray(` - ${w.slug} (${w.name})`));
515
+ });
516
+ process.exit(1);
517
+ }
518
+ setConfig({
519
+ defaultWorkspaceId: workspace.id,
520
+ defaultWorkspaceSlug: workspace.slug
521
+ });
522
+ console.log(chalk4.green(`Default workspace set to: ${workspace.name} (${workspace.slug})`));
523
+ } catch (error) {
524
+ handleError(error);
525
+ }
526
+ });
527
+ return workspaces;
528
+ }
529
+
530
+ // src/index.ts
531
+ var program = new Command5();
532
+ program.name("exponential").description("CLI to interact with Exponential productivity app").version("1.0.0").option("--json", "Output as JSON (default when piped)").option("--pretty", "Force pretty-printed output");
533
+ program.addCommand(createAuthCommand());
534
+ program.addCommand(createActionsCommand());
535
+ program.addCommand(createProjectsCommand());
536
+ program.addCommand(createWorkspacesCommand());
537
+ program.parse();
538
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/auth.ts","../src/config/index.ts","../src/client/index.ts","../src/utils/errors.ts","../src/commands/actions.ts","../src/utils/output.ts","../src/commands/projects.ts","../src/commands/workspaces.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { createAuthCommand } from './commands/auth.js';\nimport { createActionsCommand } from './commands/actions.js';\nimport { createProjectsCommand } from './commands/projects.js';\nimport { createWorkspacesCommand } from './commands/workspaces.js';\n\nconst program = new Command();\n\nprogram\n .name('exponential')\n .description('CLI to interact with Exponential productivity app')\n .version('1.0.0')\n .option('--json', 'Output as JSON (default when piped)')\n .option('--pretty', 'Force pretty-printed output');\n\n// Add subcommands\nprogram.addCommand(createAuthCommand());\nprogram.addCommand(createActionsCommand());\nprogram.addCommand(createProjectsCommand());\nprogram.addCommand(createWorkspacesCommand());\n\nprogram.parse();\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { getConfig, setConfig, clearConfig, isAuthenticated, getConfigPath } from '../config/index.js';\nimport { getClient, resetClient } from '../client/index.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function createAuthCommand(): Command {\n const auth = new Command('auth')\n .description('Authentication commands');\n\n auth\n .command('login')\n .description('Configure CLI with your API token')\n .requiredOption('--token <token>', 'JWT token from /tokens page')\n .requiredOption('--api-url <url>', 'API URL (e.g., https://app.exponential.so)')\n .action(async (options: { token: string; apiUrl: string }) => {\n try {\n // Normalize API URL (remove trailing slash)\n let apiUrl = options.apiUrl.replace(/\\/+$/, '');\n\n // Ensure HTTPS for non-localhost\n if (!apiUrl.startsWith('http://localhost') && !apiUrl.startsWith('https://')) {\n apiUrl = `https://${apiUrl}`;\n }\n\n // Store the config\n setConfig({\n token: options.token,\n apiUrl: apiUrl,\n });\n\n // Reset client to use new config\n resetClient();\n\n // Validate by trying to list workspaces\n console.log(chalk.gray('Validating token...'));\n const client = getClient();\n await client.workspaces.list();\n\n console.log(chalk.green('Successfully authenticated!'));\n console.log(chalk.gray(`Config saved to: ${getConfigPath()}`));\n } catch (error) {\n // Clear invalid config\n clearConfig();\n handleError(error);\n }\n });\n\n auth\n .command('logout')\n .description('Remove stored credentials')\n .action(() => {\n clearConfig();\n resetClient();\n console.log(chalk.green('Successfully logged out.'));\n console.log(chalk.gray(`Config cleared from: ${getConfigPath()}`));\n });\n\n auth\n .command('whoami')\n .description('Show current authentication status')\n .action(async () => {\n if (!isAuthenticated()) {\n console.log(chalk.yellow('Not authenticated.'));\n console.log(chalk.gray('Run: exponential auth login --token <jwt> --api-url <url>'));\n process.exit(1);\n }\n\n try {\n const config = getConfig();\n const client = getClient();\n\n // Validate token by listing workspaces\n const workspaces = await client.workspaces.list();\n\n console.log(chalk.green('Authenticated'));\n console.log(chalk.gray(`API URL: ${config.apiUrl}`));\n console.log(chalk.gray(`Workspaces: ${(workspaces as unknown[]).length}`));\n console.log(chalk.gray(`Config: ${getConfigPath()}`));\n } catch (error) {\n handleError(error);\n }\n });\n\n auth\n .command('status')\n .description('Show detailed authentication status')\n .action(() => {\n const config = getConfig();\n\n console.log(chalk.bold('\\nAuthentication Status'));\n console.log(chalk.gray('─'.repeat(40)));\n console.log(`Authenticated: ${isAuthenticated() ? chalk.green('Yes') : chalk.red('No')}`);\n console.log(`API URL: ${config.apiUrl || chalk.gray('(not set)')}`);\n console.log(`Token: ${config.token ? chalk.gray(`${config.token.substring(0, 20)}...`) : chalk.gray('(not set)')}`);\n console.log(`Config Path: ${getConfigPath()}`);\n console.log();\n });\n\n return auth;\n}\n","import { createConfigStore } from 'exponential-sdk';\nimport type { ExponentialConfig } from 'exponential-sdk';\n\nconst configStore = createConfigStore({ projectName: 'exponential-cli' });\n\nexport type { ExponentialConfig };\n\nexport function getConfig(): ExponentialConfig {\n return configStore.loadConfig();\n}\n\nexport function setConfig(values: Partial<ExponentialConfig>): void {\n configStore.saveConfig(values);\n}\n\nexport function clearConfig(): void {\n configStore.clearConfig();\n}\n\nexport function isAuthenticated(): boolean {\n return configStore.isAuthenticated();\n}\n\nexport function getConfigPath(): string {\n return configStore.getConfigPath();\n}\n","import { ExponentialClient } from 'exponential-sdk';\nimport { getConfig, isAuthenticated } from '../config/index.js';\n\nlet clientInstance: ExponentialClient | null = null;\n\nexport function getClient() {\n if (!isAuthenticated()) {\n throw new Error('Not authenticated. Run: exponential auth login --token <your-jwt> --api-url <url>');\n }\n\n if (clientInstance) {\n return clientInstance;\n }\n\n const config = getConfig();\n clientInstance = new ExponentialClient({\n token: config.token,\n apiUrl: config.apiUrl,\n });\n\n return clientInstance;\n}\n\nexport function resetClient() {\n clientInstance = null;\n}\n\nexport { isTRPCError, TRPCClientError } from 'exponential-sdk';\n","import chalk from 'chalk';\nimport { isTRPCError } from '../client/index.js';\n\nexport class ExponentialError extends Error {\n constructor(\n message: string,\n public code: string,\n public suggestion?: string,\n public details?: unknown\n ) {\n super(message);\n this.name = 'ExponentialError';\n }\n}\n\nexport function handleError(error: unknown, json: boolean = false): never {\n if (error instanceof ExponentialError) {\n if (json) {\n console.log(JSON.stringify({\n error: {\n code: error.code,\n message: error.message,\n suggestion: error.suggestion,\n },\n }, null, 2));\n } else {\n console.error(chalk.red(`Error: ${error.message}`));\n if (error.suggestion) {\n console.error(chalk.yellow(`Suggestion: ${error.suggestion}`));\n }\n }\n process.exit(1);\n }\n\n if (isTRPCError(error)) {\n const code = error.data?.code ?? 'UNKNOWN';\n let message = error.message;\n let suggestion: string | undefined;\n\n switch (code) {\n case 'UNAUTHORIZED':\n message = 'Authentication failed. Your token may have expired.';\n suggestion = 'Run: exponential auth login --token <new-token> --api-url <url>';\n break;\n case 'NOT_FOUND':\n message = 'Resource not found';\n break;\n case 'FORBIDDEN':\n message = 'Access denied';\n break;\n }\n\n if (json) {\n console.log(JSON.stringify({\n error: {\n code,\n message,\n suggestion,\n },\n }, null, 2));\n } else {\n console.error(chalk.red(`Error [${code}]: ${message}`));\n if (suggestion) {\n console.error(chalk.yellow(`Suggestion: ${suggestion}`));\n }\n }\n process.exit(1);\n }\n\n // Generic error handling\n if (json) {\n console.log(JSON.stringify({\n error: {\n code: 'UNKNOWN',\n message: error instanceof Error ? error.message : String(error),\n },\n }, null, 2));\n } else {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));\n }\n process.exit(1);\n}\n","import { Command } from 'commander';\nimport { getClient } from '../client/index.js';\nimport { handleError } from '../utils/errors.js';\nimport {\n shouldUseJson,\n outputActionsJson,\n outputActionsPretty,\n} from '../utils/output.js';\nimport type { Action, KanbanStatus } from 'exponential-sdk';\n\ninterface GlobalOptions {\n json?: boolean;\n pretty?: boolean;\n workspace?: string;\n}\n\nexport function createActionsCommand(): Command {\n const actions = new Command('actions')\n .description('Manage actions/tasks');\n\n actions\n .command('list')\n .description('List all actions')\n .option('--project <id>', 'Filter by project ID')\n .option('--status <status>', 'Filter by kanban status (BACKLOG, TODO, IN_PROGRESS, IN_REVIEW, DONE)')\n .option('--assignee <id>', 'Filter by assignee ID')\n .action(async (options: { project?: string; status?: string; assignee?: string }, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals() as GlobalOptions;\n const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);\n\n try {\n const client = getClient();\n const kanbanStatus = options.status as KanbanStatus | undefined;\n\n const actions = await client.actions.list({\n projectId: options.project,\n status: kanbanStatus,\n assigneeId: options.assignee,\n });\n\n if (useJson) {\n outputActionsJson(actions, {\n projectId: options.project,\n kanbanStatus: options.status,\n });\n } else {\n outputActionsPretty(actions);\n }\n } catch (error) {\n handleError(error, useJson);\n }\n });\n\n actions\n .command('today')\n .description('Get actions due today')\n .option('--workspace <id>', 'Filter by workspace ID')\n .action(async (options: { workspace?: string }, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals() as GlobalOptions;\n const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);\n\n try {\n const client = getClient();\n const actions = await client.actions.getToday(options.workspace);\n\n if (useJson) {\n outputActionsJson(actions, { workspaceId: options.workspace });\n } else {\n outputActionsPretty(actions);\n }\n } catch (error) {\n handleError(error, useJson);\n }\n });\n\n actions\n .command('range')\n .description('Get actions by date range')\n .requiredOption('--start <date>', 'Start date (YYYY-MM-DD)')\n .requiredOption('--end <date>', 'End date (YYYY-MM-DD)')\n .option('--workspace <id>', 'Filter by workspace ID')\n .action(async (options: { start: string; end: string; workspace?: string }, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals() as GlobalOptions;\n const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);\n\n try {\n const startDate = new Date(options.start);\n const endDate = new Date(options.end);\n\n if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {\n throw new Error('Invalid date format. Use YYYY-MM-DD');\n }\n\n const client = getClient();\n const actions = await client.actions.getByDateRange(startDate, endDate, options.workspace);\n\n if (useJson) {\n outputActionsJson(actions, { workspaceId: options.workspace });\n } else {\n outputActionsPretty(actions);\n }\n } catch (error) {\n handleError(error, useJson);\n }\n });\n\n actions\n .command('kanban')\n .description('Get kanban board actions')\n .option('--project <id>', 'Filter by project ID')\n .option('--status <status>', 'Filter by kanban status')\n .option('--assignee <id>', 'Filter by assignee ID')\n .action(async (options: { project?: string; status?: string; assignee?: string }, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals() as GlobalOptions;\n const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);\n\n try {\n const client = getClient();\n const kanbanStatus = options.status as KanbanStatus | undefined;\n\n const actions = await client.actions.getKanban({\n projectId: options.project,\n status: kanbanStatus,\n assigneeId: options.assignee,\n });\n\n if (useJson) {\n outputActionsJson(actions, {\n projectId: options.project,\n kanbanStatus: options.status,\n });\n } else {\n outputActionsPretty(actions);\n }\n } catch (error) {\n handleError(error, useJson);\n }\n });\n\n return actions;\n}\n","import chalk from 'chalk';\nimport type {\n Action,\n ActionOutput,\n ActionsListOutput,\n Project,\n ProjectOutput,\n ProjectsListOutput,\n Workspace,\n WorkspaceOutput,\n WorkspacesListOutput,\n} from 'exponential-sdk';\n\n// Detect if output is being piped\nexport function shouldUseJson(forceJson?: boolean, forcePretty?: boolean): boolean {\n if (forceJson) return true;\n if (forcePretty) return false;\n return !process.stdout.isTTY;\n}\n\n// Transform Action to ActionOutput (serialize dates)\nexport function transformAction(action: Action): ActionOutput {\n return {\n id: action.id,\n name: action.name,\n description: action.description,\n status: action.status,\n priority: action.priority,\n kanbanStatus: action.kanbanStatus,\n dueDate: action.dueDate?.toISOString() ?? null,\n scheduledStart: action.scheduledStart?.toISOString() ?? null,\n scheduledEnd: action.scheduledEnd?.toISOString() ?? null,\n project: action.project ? {\n id: action.project.id,\n name: action.project.name,\n } : null,\n workspace: action.workspace ? {\n id: action.workspace.id,\n slug: action.workspace.slug,\n name: action.workspace.name,\n } : null,\n assignees: action.assignees?.map(a => ({\n id: a.user.id,\n name: a.user.name,\n email: a.user.email,\n })) ?? [],\n createdAt: action.createdAt?.toISOString() ?? new Date().toISOString(),\n completedAt: action.completedAt?.toISOString() ?? null,\n };\n}\n\n// Transform Project to ProjectOutput\nexport function transformProject(project: Project): ProjectOutput {\n return {\n id: project.id,\n name: project.name,\n description: project.description,\n status: project.status,\n priority: project.priority,\n workspace: project.workspace ? {\n id: project.workspace.id,\n slug: project.workspace.slug,\n name: project.workspace.name,\n } : null,\n };\n}\n\n// Transform Workspace to WorkspaceOutput\nexport function transformWorkspace(workspace: Workspace): WorkspaceOutput {\n return {\n id: workspace.id,\n name: workspace.name,\n slug: workspace.slug,\n type: workspace.type,\n };\n}\n\n// Output actions as JSON\nexport function outputActionsJson(actions: Action[], filters: ActionsListOutput['filters'] = {}): void {\n const output: ActionsListOutput = {\n actions: actions.map(transformAction),\n total: actions.length,\n filters,\n };\n console.log(JSON.stringify(output, null, 2));\n}\n\n// Output actions in pretty format\nexport function outputActionsPretty(actions: Action[]): void {\n if (actions.length === 0) {\n console.log(chalk.gray('No actions found.'));\n return;\n }\n\n console.log(chalk.bold(`\\nActions (${actions.length} total)`));\n console.log(chalk.gray('─'.repeat(50)));\n\n for (const action of actions) {\n const statusColor = getKanbanStatusColor(action.kanbanStatus);\n const statusBadge = action.kanbanStatus\n ? chalk[statusColor](`[${action.kanbanStatus}]`)\n : chalk.gray('[NO STATUS]');\n\n console.log(`\\n${statusBadge} ${chalk.bold(action.name)}`);\n console.log(chalk.gray(` ID: ${action.id}`));\n\n if (action.project) {\n console.log(` ${chalk.cyan('Project:')} ${action.project.name}`);\n }\n\n console.log(` ${chalk.magenta('Priority:')} ${action.priority}`);\n\n if (action.dueDate) {\n const dueDate = new Date(action.dueDate);\n const isOverdue = dueDate < new Date();\n const dateStr = formatDate(dueDate);\n console.log(` ${chalk.yellow('Due:')} ${isOverdue ? chalk.red(dateStr) : dateStr}`);\n }\n\n if (action.description) {\n console.log(` ${chalk.gray('Description:')} ${action.description.substring(0, 100)}${action.description.length > 100 ? '...' : ''}`);\n }\n }\n console.log();\n}\n\n// Output projects as JSON\nexport function outputProjectsJson(projects: Project[]): void {\n const output: ProjectsListOutput = {\n projects: projects.map(transformProject),\n total: projects.length,\n };\n console.log(JSON.stringify(output, null, 2));\n}\n\n// Output projects in pretty format\nexport function outputProjectsPretty(projects: Project[]): void {\n if (projects.length === 0) {\n console.log(chalk.gray('No projects found.'));\n return;\n }\n\n console.log(chalk.bold(`\\nProjects (${projects.length} total)`));\n console.log(chalk.gray('─'.repeat(50)));\n\n for (const project of projects) {\n console.log(`\\n${chalk.bold(project.name)}`);\n console.log(chalk.gray(` ID: ${project.id}`));\n\n if (project.status) {\n console.log(` ${chalk.cyan('Status:')} ${project.status}`);\n }\n\n if (project.priority) {\n console.log(` ${chalk.magenta('Priority:')} ${project.priority}`);\n }\n\n if (project.workspace) {\n console.log(` ${chalk.yellow('Workspace:')} ${project.workspace.name} (${project.workspace.slug})`);\n }\n\n if (project.description) {\n console.log(` ${chalk.gray('Description:')} ${project.description.substring(0, 100)}${project.description.length > 100 ? '...' : ''}`);\n }\n }\n console.log();\n}\n\n// Output workspaces as JSON\nexport function outputWorkspacesJson(workspaces: Workspace[]): void {\n const output: WorkspacesListOutput = {\n workspaces: workspaces.map(transformWorkspace),\n total: workspaces.length,\n };\n console.log(JSON.stringify(output, null, 2));\n}\n\n// Output workspaces in pretty format\nexport function outputWorkspacesPretty(workspaces: Workspace[]): void {\n if (workspaces.length === 0) {\n console.log(chalk.gray('No workspaces found.'));\n return;\n }\n\n console.log(chalk.bold(`\\nWorkspaces (${workspaces.length} total)`));\n console.log(chalk.gray('─'.repeat(50)));\n\n for (const workspace of workspaces) {\n console.log(`\\n${chalk.bold(workspace.name)}`);\n console.log(chalk.gray(` ID: ${workspace.id}`));\n console.log(` ${chalk.cyan('Slug:')} ${workspace.slug}`);\n console.log(` ${chalk.magenta('Type:')} ${workspace.type}`);\n }\n console.log();\n}\n\n// Helper functions\nfunction getKanbanStatusColor(status: string | null): 'gray' | 'blue' | 'yellow' | 'cyan' | 'green' | 'red' {\n switch (status) {\n case 'BACKLOG': return 'gray';\n case 'TODO': return 'blue';\n case 'IN_PROGRESS': return 'yellow';\n case 'IN_REVIEW': return 'cyan';\n case 'DONE': return 'green';\n case 'CANCELLED': return 'red';\n default: return 'gray';\n }\n}\n\nfunction formatDate(date: Date): string {\n return date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n}\n","import { Command } from 'commander';\nimport { getClient } from '../client/index.js';\nimport { handleError } from '../utils/errors.js';\nimport {\n shouldUseJson,\n outputProjectsJson,\n outputProjectsPretty,\n} from '../utils/output.js';\nimport type { Project } from 'exponential-sdk';\n\ninterface GlobalOptions {\n json?: boolean;\n pretty?: boolean;\n workspace?: string;\n}\n\nexport function createProjectsCommand(): Command {\n const projects = new Command('projects')\n .description('Manage projects');\n\n projects\n .command('list')\n .description('List all projects')\n .option('--workspace <id>', 'Filter by workspace ID')\n .option('--include-actions', 'Include actions in output')\n .action(async (options: { workspace?: string; includeActions?: boolean }, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals() as GlobalOptions;\n const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);\n\n try {\n const client = getClient();\n const projects = await client.projects.list({\n workspaceId: options.workspace,\n includeActions: options.includeActions,\n });\n\n if (useJson) {\n outputProjectsJson(projects);\n } else {\n outputProjectsPretty(projects);\n }\n } catch (error) {\n handleError(error, useJson);\n }\n });\n\n return projects;\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { getClient } from '../client/index.js';\nimport { getConfig, setConfig } from '../config/index.js';\nimport { handleError } from '../utils/errors.js';\nimport {\n shouldUseJson,\n outputWorkspacesJson,\n outputWorkspacesPretty,\n} from '../utils/output.js';\nimport type { Workspace } from 'exponential-sdk';\n\ninterface GlobalOptions {\n json?: boolean;\n pretty?: boolean;\n}\n\nexport function createWorkspacesCommand(): Command {\n const workspaces = new Command('workspaces')\n .description('Manage workspaces');\n\n workspaces\n .command('list')\n .description('List all workspaces')\n .action(async (_options: Record<string, never>, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals() as GlobalOptions;\n const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);\n\n try {\n const client = getClient();\n const workspaces = await client.workspaces.list();\n\n if (useJson) {\n outputWorkspacesJson(workspaces);\n } else {\n const config = getConfig();\n outputWorkspacesPretty(workspaces);\n\n if (config.defaultWorkspaceSlug) {\n console.log(chalk.gray(`Default workspace: ${config.defaultWorkspaceSlug}`));\n }\n }\n } catch (error) {\n handleError(error, useJson);\n }\n });\n\n workspaces\n .command('set-default <slug>')\n .description('Set the default workspace')\n .action(async (slug: string) => {\n try {\n const client = getClient();\n const workspaces = await client.workspaces.list();\n\n const workspace = workspaces.find((w: Workspace) => w.slug === slug);\n\n if (!workspace) {\n console.error(chalk.red(`Workspace with slug \"${slug}\" not found.`));\n console.log(chalk.gray('Available workspaces:'));\n workspaces.forEach((w: Workspace) => {\n console.log(chalk.gray(` - ${w.slug} (${w.name})`));\n });\n process.exit(1);\n }\n\n setConfig({\n defaultWorkspaceId: workspace.id,\n defaultWorkspaceSlug: workspace.slug,\n });\n\n console.log(chalk.green(`Default workspace set to: ${workspace.name} (${workspace.slug})`));\n } catch (error) {\n handleError(error);\n }\n });\n\n return workspaces;\n}\n"],"mappings":"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","names":["Command","chalk","chalk","Command","chalk","Command","actions","Command","Command","projects","Command","chalk","Command","workspaces","chalk","Command"]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "exponential-cli",
3
+ "version": "1.0.0",
4
+ "description": "CLI to interact with Exponential productivity app - pull actions for LLM consumption",
5
+ "type": "module",
6
+ "bin": {
7
+ "exponential": "bin/exponential.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "files": [
12
+ "dist",
13
+ "bin"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsup",
17
+ "dev": "tsup --watch",
18
+ "typecheck": "tsc --noEmit",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "engines": {
22
+ "node": ">=18.0.0"
23
+ },
24
+ "keywords": [
25
+ "cli",
26
+ "productivity",
27
+ "actions",
28
+ "tasks",
29
+ "exponential"
30
+ ],
31
+ "author": "",
32
+ "license": "MIT",
33
+ "dependencies": {
34
+ "chalk": "^5.3.0",
35
+ "commander": "^12.1.0",
36
+ "exponential-sdk": "^1.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^20.14.10",
40
+ "tsup": "^8.3.5",
41
+ "typescript": "^5.7.2"
42
+ }
43
+ }