tabstax-cli 0.1.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.
Files changed (59) hide show
  1. package/README.md +110 -0
  2. package/bin/hey.js +2 -0
  3. package/dist/__tests__/api.test.d.ts +6 -0
  4. package/dist/__tests__/api.test.d.ts.map +1 -0
  5. package/dist/__tests__/api.test.js +146 -0
  6. package/dist/__tests__/api.test.js.map +1 -0
  7. package/dist/__tests__/config.test.d.ts +6 -0
  8. package/dist/__tests__/config.test.d.ts.map +1 -0
  9. package/dist/__tests__/config.test.js +78 -0
  10. package/dist/__tests__/config.test.js.map +1 -0
  11. package/dist/__tests__/output.test.d.ts +6 -0
  12. package/dist/__tests__/output.test.d.ts.map +1 -0
  13. package/dist/__tests__/output.test.js +104 -0
  14. package/dist/__tests__/output.test.js.map +1 -0
  15. package/dist/commands/add.d.ts +12 -0
  16. package/dist/commands/add.d.ts.map +1 -0
  17. package/dist/commands/add.js +76 -0
  18. package/dist/commands/add.js.map +1 -0
  19. package/dist/commands/auth.d.ts +11 -0
  20. package/dist/commands/auth.d.ts.map +1 -0
  21. package/dist/commands/auth.js +135 -0
  22. package/dist/commands/auth.js.map +1 -0
  23. package/dist/commands/context.d.ts +15 -0
  24. package/dist/commands/context.d.ts.map +1 -0
  25. package/dist/commands/context.js +75 -0
  26. package/dist/commands/context.js.map +1 -0
  27. package/dist/commands/done.d.ts +13 -0
  28. package/dist/commands/done.d.ts.map +1 -0
  29. package/dist/commands/done.js +76 -0
  30. package/dist/commands/done.js.map +1 -0
  31. package/dist/commands/edit.d.ts +27 -0
  32. package/dist/commands/edit.d.ts.map +1 -0
  33. package/dist/commands/edit.js +170 -0
  34. package/dist/commands/edit.js.map +1 -0
  35. package/dist/commands/list.d.ts +11 -0
  36. package/dist/commands/list.d.ts.map +1 -0
  37. package/dist/commands/list.js +112 -0
  38. package/dist/commands/list.js.map +1 -0
  39. package/dist/commands/remove.d.ts +9 -0
  40. package/dist/commands/remove.d.ts.map +1 -0
  41. package/dist/commands/remove.js +69 -0
  42. package/dist/commands/remove.js.map +1 -0
  43. package/dist/index.d.ts +7 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +113 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/lib/api.d.ts +69 -0
  48. package/dist/lib/api.d.ts.map +1 -0
  49. package/dist/lib/api.js +303 -0
  50. package/dist/lib/api.js.map +1 -0
  51. package/dist/lib/config.d.ts +51 -0
  52. package/dist/lib/config.d.ts.map +1 -0
  53. package/dist/lib/config.js +131 -0
  54. package/dist/lib/config.js.map +1 -0
  55. package/dist/lib/output.d.ts +37 -0
  56. package/dist/lib/output.d.ts.map +1 -0
  57. package/dist/lib/output.js +209 -0
  58. package/dist/lib/output.js.map +1 -0
  59. package/package.json +64 -0
package/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # Hey CLI - TabStax Command Line Interface
2
+
3
+ A conversational CLI for managing your Next Actions directly from the terminal. Works with the [TabStax](https://tabstax.app) browser extension.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g tabstax-cli
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # Login to your TabStax account
15
+ hey login
16
+
17
+ # Set your default project
18
+ hey use "My Project"
19
+
20
+ # Add a next action
21
+ hey "Build the login page"
22
+
23
+ # Add a breadcrumb (completed action)
24
+ hey -x "Fixed the auth bug"
25
+
26
+ # List your actions
27
+ hey ls
28
+
29
+ # Mark action #1 as done
30
+ hey done 1
31
+ ```
32
+
33
+ ## Commands
34
+
35
+ ### Actions
36
+ | Command | Description |
37
+ |---------|-------------|
38
+ | `hey "message"` | Add a next action |
39
+ | `hey -x "message"` | Add a breadcrumb (past tense, already done) |
40
+ | `hey done [n]` | Mark action #n as complete (default: #1) |
41
+ | `hey rm <n>` | Remove action #n |
42
+ | `hey edit <n> "text"` | Edit action #n content |
43
+ | `hey mv <from> <to>` | Move action to different position |
44
+
45
+ ### Listing
46
+ | Command | Description |
47
+ |---------|-------------|
48
+ | `hey ls` | List actions for current project |
49
+ | `hey ls stax` | List all your stax with priorities |
50
+ | `hey ls --all` | Expanded view with actions per stax |
51
+ | `hey ls --done` | Show breadcrumbs only |
52
+
53
+ ### Projects & Priority
54
+ | Command | Description |
55
+ |---------|-------------|
56
+ | `hey use <project>` | Set default project (fuzzy matched) |
57
+ | `hey pri <project> <level>` | Set priority: `must`, `should`, `good`, `meh` |
58
+ | `hey which` | Show current context |
59
+
60
+ ### Authentication
61
+ | Command | Description |
62
+ |---------|-------------|
63
+ | `hey login` | Log in to TabStax |
64
+ | `hey logout` | Log out |
65
+ | `hey whoami` | Show current user |
66
+ | `hey status` | Show CLI status |
67
+
68
+ ## Features
69
+
70
+ - **7-action limit** per project to maintain focus (bypass with `--force`)
71
+ - **Fuzzy project matching** - `hey use tab` matches "TabStax"
72
+ - **Priority icons** - ★ must, ◆ should, ○ good, · meh
73
+ - **Breadcrumbs** - Track what you've done, not just what's next
74
+ - **Syncs with extension** - Changes appear in TabStax browser extension instantly
75
+
76
+ ## Examples
77
+
78
+ ```bash
79
+ # Quick workflow
80
+ hey use "insurance"
81
+ hey "Call agent about claim"
82
+ hey "Upload documents"
83
+ hey -x "Submitted form 1099"
84
+ hey done 1
85
+ hey ls
86
+
87
+ # See all projects
88
+ hey ls stax
89
+
90
+ # Set project as high priority
91
+ hey pri "insurance" must
92
+
93
+ # Force add when at limit
94
+ hey "One more thing" --force
95
+ ```
96
+
97
+ ## Requirements
98
+
99
+ - Node.js 18+
100
+ - TabStax account (free or paid)
101
+
102
+ ## Links
103
+
104
+ - [TabStax Extension](https://tabstax.app)
105
+ - [GitHub](https://github.com/Hulupeep/tabstax)
106
+ - [Issues](https://github.com/Hulupeep/tabstax/issues)
107
+
108
+ ## License
109
+
110
+ MIT
package/bin/hey.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/index.js'
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tests for api.ts
3
+ * CONTRACT: CRUD-001 through CRUD-005 - API operations
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=api.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/api.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Tests for api.ts
3
+ * CONTRACT: CRUD-001 through CRUD-005 - API operations
4
+ */
5
+ import { jest, describe, it, expect, beforeEach } from '@jest/globals';
6
+ // Create mock functions that we can control
7
+ const mockSelect = jest.fn().mockReturnThis();
8
+ const mockInsert = jest.fn().mockReturnThis();
9
+ const mockUpdate = jest.fn().mockReturnThis();
10
+ const mockDelete = jest.fn().mockReturnThis();
11
+ const mockEq = jest.fn().mockReturnThis();
12
+ const mockIlike = jest.fn().mockReturnThis();
13
+ const mockGte = jest.fn().mockReturnThis();
14
+ const mockOrder = jest.fn().mockReturnThis();
15
+ const mockLimit = jest.fn().mockReturnThis();
16
+ const mockSingle = jest.fn();
17
+ const mockMaybeSingle = jest.fn();
18
+ const mockUpsert = jest.fn().mockReturnThis();
19
+ const mockFrom = jest.fn(() => ({
20
+ select: mockSelect,
21
+ insert: mockInsert,
22
+ update: mockUpdate,
23
+ delete: mockDelete,
24
+ eq: mockEq,
25
+ ilike: mockIlike,
26
+ gte: mockGte,
27
+ order: mockOrder,
28
+ limit: mockLimit,
29
+ single: mockSingle,
30
+ maybeSingle: mockMaybeSingle,
31
+ upsert: mockUpsert,
32
+ }));
33
+ jest.unstable_mockModule('@supabase/supabase-js', () => ({
34
+ createClient: jest.fn(() => ({
35
+ from: mockFrom,
36
+ auth: {
37
+ signInWithPassword: jest.fn(),
38
+ },
39
+ })),
40
+ }));
41
+ jest.unstable_mockModule('../lib/config.js', () => ({
42
+ config: {
43
+ getAuth: jest.fn(() => ({
44
+ accessToken: 'test-token',
45
+ userId: 'user-123',
46
+ })),
47
+ getSupabaseUrl: jest.fn(() => 'https://test.supabase.co'),
48
+ getSupabaseAnonKey: jest.fn(() => 'test-anon-key'),
49
+ setAuth: jest.fn(),
50
+ clearAuth: jest.fn(),
51
+ },
52
+ }));
53
+ describe('ApiClient', () => {
54
+ beforeEach(() => {
55
+ jest.clearAllMocks();
56
+ });
57
+ describe('CRUD-001: Adding next actions', () => {
58
+ it('should have addAction method', async () => {
59
+ const { api } = await import('../lib/api.js');
60
+ expect(typeof api.addAction).toBe('function');
61
+ });
62
+ });
63
+ describe('CRUD-002: Adding breadcrumbs', () => {
64
+ it('should have addAction method for breadcrumbs', async () => {
65
+ const { api } = await import('../lib/api.js');
66
+ expect(typeof api.addAction).toBe('function');
67
+ });
68
+ });
69
+ describe('CRUD-003: Completing actions', () => {
70
+ it('should have completeAction method', async () => {
71
+ const { api } = await import('../lib/api.js');
72
+ expect(typeof api.completeAction).toBe('function');
73
+ });
74
+ });
75
+ describe('CRUD-004: Deleting actions', () => {
76
+ it('should have deleteAction method', async () => {
77
+ const { api } = await import('../lib/api.js');
78
+ expect(typeof api.deleteAction).toBe('function');
79
+ });
80
+ });
81
+ describe('CRUD-005: Editing actions', () => {
82
+ it('should have editAction method', async () => {
83
+ const { api } = await import('../lib/api.js');
84
+ expect(typeof api.editAction).toBe('function');
85
+ });
86
+ });
87
+ describe('Fuzzy search', () => {
88
+ it('should have fuzzyFindStax method', async () => {
89
+ const { api } = await import('../lib/api.js');
90
+ expect(typeof api.fuzzyFindStax).toBe('function');
91
+ });
92
+ });
93
+ describe('Attention blocks', () => {
94
+ it('should have setAttentionBlock method', async () => {
95
+ const { api } = await import('../lib/api.js');
96
+ expect(typeof api.setAttentionBlock).toBe('function');
97
+ });
98
+ it('should have getAttentionBlock method', async () => {
99
+ const { api } = await import('../lib/api.js');
100
+ expect(typeof api.getAttentionBlock).toBe('function');
101
+ });
102
+ });
103
+ describe('Stax queries', () => {
104
+ it('should have getAllStax method', async () => {
105
+ const { api } = await import('../lib/api.js');
106
+ expect(typeof api.getAllStax).toBe('function');
107
+ });
108
+ it('should have getStaxByName method', async () => {
109
+ const { api } = await import('../lib/api.js');
110
+ expect(typeof api.getStaxByName).toBe('function');
111
+ });
112
+ it('should have getStaxWithActions method', async () => {
113
+ const { api } = await import('../lib/api.js');
114
+ expect(typeof api.getStaxWithActions).toBe('function');
115
+ });
116
+ });
117
+ describe('Action queries', () => {
118
+ it('should have getActions method', async () => {
119
+ const { api } = await import('../lib/api.js');
120
+ expect(typeof api.getActions).toBe('function');
121
+ });
122
+ it('should have countActiveActions method', async () => {
123
+ const { api } = await import('../lib/api.js');
124
+ expect(typeof api.countActiveActions).toBe('function');
125
+ });
126
+ it('should have getRecentBreadcrumbs method', async () => {
127
+ const { api } = await import('../lib/api.js');
128
+ expect(typeof api.getRecentBreadcrumbs).toBe('function');
129
+ });
130
+ });
131
+ describe('Auth methods', () => {
132
+ it('should have signIn method', async () => {
133
+ const { api } = await import('../lib/api.js');
134
+ expect(typeof api.signIn).toBe('function');
135
+ });
136
+ it('should have signOut method', async () => {
137
+ const { api } = await import('../lib/api.js');
138
+ expect(typeof api.signOut).toBe('function');
139
+ });
140
+ it('should have resetClient method', async () => {
141
+ const { api } = await import('../lib/api.js');
142
+ expect(typeof api.resetClient).toBe('function');
143
+ });
144
+ });
145
+ });
146
+ //# sourceMappingURL=api.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.test.js","sourceRoot":"","sources":["../../src/__tests__/api.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAEtE,4CAA4C;AAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,CAAA;AAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,CAAA;AAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,CAAA;AAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,CAAA;AAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,CAAA;AACzC,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,CAAA;AAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,CAAA;AAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,CAAA;AAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,CAAA;AAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAA;AAC5B,MAAM,eAAe,GAAG,IAAI,CAAC,EAAE,EAAE,CAAA;AACjC,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,CAAA;AAE7C,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9B,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,UAAU;IAClB,EAAE,EAAE,MAAM;IACV,KAAK,EAAE,SAAS;IAChB,GAAG,EAAE,OAAO;IACZ,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,UAAU;IAClB,WAAW,EAAE,eAAe;IAC5B,MAAM,EAAE,UAAU;CACnB,CAAC,CAAC,CAAA;AAEH,IAAI,CAAC,mBAAmB,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC;IACvD,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE;YACJ,kBAAkB,EAAE,IAAI,CAAC,EAAE,EAAE;SAC9B;KACF,CAAC,CAAC;CACJ,CAAC,CAAC,CAAA;AAEH,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC;IAClD,MAAM,EAAE;QACN,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;YACtB,WAAW,EAAE,YAAY;YACzB,MAAM,EAAE,UAAU;SACnB,CAAC,CAAC;QACH,cAAc,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,0BAA0B,CAAC;QACzD,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC;QAClD,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;QAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE;KACrB;CACF,CAAC,CAAC,CAAA;AAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,aAAa,EAAE,CAAA;IACtB,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;QAC7C,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC5C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC/C,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;QAC5C,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC5D,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC/C,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;QAC5C,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACjD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACpD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;YAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAClD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAChD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;YAChD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACnD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACvD,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACvD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAChD,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;YAChD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACnD,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACrD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACxD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAChD,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACrD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACxD,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC1D,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC7C,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7C,MAAM,CAAC,OAAO,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACjD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tests for config.ts
3
+ * CONTRACT: AUTH-002 - Config must persist auth tokens securely
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Tests for config.ts
3
+ * CONTRACT: AUTH-002 - Config must persist auth tokens securely
4
+ */
5
+ import { jest, describe, it, expect, beforeEach } from '@jest/globals';
6
+ // Simple mock conf module
7
+ const mockStore = {};
8
+ jest.unstable_mockModule('conf', () => ({
9
+ default: class MockConf {
10
+ path = '/mock/config/path';
11
+ _store = {};
12
+ constructor(options) {
13
+ this._store = { ...options.defaults };
14
+ Object.assign(mockStore, options.defaults);
15
+ }
16
+ get(key) {
17
+ return mockStore[key];
18
+ }
19
+ set(key, value) {
20
+ mockStore[key] = value;
21
+ }
22
+ clear() {
23
+ Object.keys(mockStore).forEach((k) => delete mockStore[k]);
24
+ }
25
+ },
26
+ }));
27
+ describe('ConfigManager', () => {
28
+ beforeEach(async () => {
29
+ // Reset mock store
30
+ Object.keys(mockStore).forEach((k) => delete mockStore[k]);
31
+ jest.resetModules();
32
+ });
33
+ describe('AUTH-002: Auth config persistence', () => {
34
+ it('should initialize with default auth config', async () => {
35
+ const { config } = await import('../lib/config.js');
36
+ const auth = config.getAuth();
37
+ expect(auth.accessToken).toBeNull();
38
+ expect(auth.userId).toBeNull();
39
+ expect(auth.userEmail).toBeNull();
40
+ });
41
+ it('should persist auth when setAuth is called', async () => {
42
+ const { config } = await import('../lib/config.js');
43
+ config.setAuth({
44
+ accessToken: 'test-token',
45
+ userId: 'user-123',
46
+ userEmail: 'test@example.com',
47
+ });
48
+ const auth = config.getAuth();
49
+ expect(auth.accessToken).toBe('test-token');
50
+ expect(auth.userId).toBe('user-123');
51
+ expect(auth.userEmail).toBe('test@example.com');
52
+ });
53
+ it('should clear auth on clearAuth', async () => {
54
+ const { config } = await import('../lib/config.js');
55
+ config.setAuth({ accessToken: 'test-token' });
56
+ config.clearAuth();
57
+ const auth = config.getAuth();
58
+ expect(auth.accessToken).toBeNull();
59
+ });
60
+ });
61
+ describe('LIMIT-001: Limits config', () => {
62
+ it('should have maxActionsPerStax of 7 by default', async () => {
63
+ const { config } = await import('../lib/config.js');
64
+ const limits = config.getLimits();
65
+ expect(limits.maxActionsPerStax).toBe(7);
66
+ });
67
+ });
68
+ describe('Context management', () => {
69
+ it('should store and retrieve last project', async () => {
70
+ const { config } = await import('../lib/config.js');
71
+ config.setLastProject('Test Project', 'project-123');
72
+ const context = config.getContext();
73
+ expect(context.lastProject).toBe('Test Project');
74
+ expect(context.lastProjectId).toBe('project-123');
75
+ });
76
+ });
77
+ });
78
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tests for output.ts
3
+ * Tests terminal formatting and display functions
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=output.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/output.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Tests for output.ts
3
+ * Tests terminal formatting and display functions
4
+ */
5
+ import { jest, describe, it, expect } from '@jest/globals';
6
+ // Mock chalk to avoid ESM issues
7
+ jest.unstable_mockModule('chalk', () => ({
8
+ default: {
9
+ red: (s) => `[red]${s}[/red]`,
10
+ green: (s) => `[green]${s}[/green]`,
11
+ yellow: (s) => `[yellow]${s}[/yellow]`,
12
+ blue: (s) => `[blue]${s}[/blue]`,
13
+ gray: (s) => `[gray]${s}[/gray]`,
14
+ bold: (s) => `[bold]${s}[/bold]`,
15
+ cyan: (s) => `[cyan]${s}[/cyan]`,
16
+ },
17
+ }));
18
+ jest.unstable_mockModule('../lib/config.js', () => ({
19
+ config: {
20
+ getLimits: () => ({ maxActionsPerStax: 7, warnAt: 5 }),
21
+ },
22
+ }));
23
+ describe('Output formatting', () => {
24
+ describe('Priority formatting', () => {
25
+ it('should format must priority with star icon', async () => {
26
+ const { PRIORITY_ICONS } = await import('../lib/output.js');
27
+ expect(PRIORITY_ICONS.must).toBe('★');
28
+ });
29
+ it('should format should priority with diamond icon', async () => {
30
+ const { PRIORITY_ICONS } = await import('../lib/output.js');
31
+ expect(PRIORITY_ICONS.should).toBe('◆');
32
+ });
33
+ it('should format good priority with circle icon', async () => {
34
+ const { PRIORITY_ICONS } = await import('../lib/output.js');
35
+ expect(PRIORITY_ICONS.good).toBe('○');
36
+ });
37
+ it('should format meh priority with dot icon', async () => {
38
+ const { PRIORITY_ICONS } = await import('../lib/output.js');
39
+ expect(PRIORITY_ICONS.meh).toBe('·');
40
+ });
41
+ });
42
+ describe('Relative time formatting', () => {
43
+ it('should format recent time as "just now"', async () => {
44
+ const { formatRelativeTime } = await import('../lib/output.js');
45
+ const result = formatRelativeTime(new Date());
46
+ expect(result).toBe('just now');
47
+ });
48
+ it('should format minutes ago correctly', async () => {
49
+ const { formatRelativeTime } = await import('../lib/output.js');
50
+ const tenMinutesAgo = new Date(Date.now() - 10 * 60 * 1000);
51
+ const result = formatRelativeTime(tenMinutesAgo);
52
+ expect(result).toBe('10m ago');
53
+ });
54
+ it('should format hours ago correctly', async () => {
55
+ const { formatRelativeTime } = await import('../lib/output.js');
56
+ const fiveHoursAgo = new Date(Date.now() - 5 * 60 * 60 * 1000);
57
+ const result = formatRelativeTime(fiveHoursAgo);
58
+ expect(result).toBe('5h ago');
59
+ });
60
+ it('should format days ago correctly', async () => {
61
+ const { formatRelativeTime } = await import('../lib/output.js');
62
+ const threeDaysAgo = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000);
63
+ const result = formatRelativeTime(threeDaysAgo);
64
+ expect(result).toBe('3d ago');
65
+ });
66
+ });
67
+ describe('Limit status formatting', () => {
68
+ it('should include count in output', async () => {
69
+ const { formatLimitStatus } = await import('../lib/output.js');
70
+ const result = formatLimitStatus(3, 7);
71
+ expect(result).toContain('3/7');
72
+ });
73
+ it('should include count when approaching limit', async () => {
74
+ const { formatLimitStatus } = await import('../lib/output.js');
75
+ const result = formatLimitStatus(5, 7);
76
+ expect(result).toContain('5/7');
77
+ });
78
+ it('should include count when at limit', async () => {
79
+ const { formatLimitStatus } = await import('../lib/output.js');
80
+ const result = formatLimitStatus(7, 7);
81
+ expect(result).toContain('7/7');
82
+ });
83
+ });
84
+ describe('Action age formatting', () => {
85
+ it('should format new action as "now"', async () => {
86
+ const { formatActionAge } = await import('../lib/output.js');
87
+ const result = formatActionAge(new Date());
88
+ expect(result).toBe('now');
89
+ });
90
+ it('should format hours correctly', async () => {
91
+ const { formatActionAge } = await import('../lib/output.js');
92
+ const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000);
93
+ const result = formatActionAge(twoHoursAgo);
94
+ expect(result).toBe('2h');
95
+ });
96
+ it('should format days correctly', async () => {
97
+ const { formatActionAge } = await import('../lib/output.js');
98
+ const threeDaysAgo = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000);
99
+ const result = formatActionAge(threeDaysAgo);
100
+ expect(result).toBe('3d');
101
+ });
102
+ });
103
+ });
104
+ //# sourceMappingURL=output.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.test.js","sourceRoot":"","sources":["../../src/__tests__/output.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Add command for Hey CLI
3
+ * hey "msg" adds a next action
4
+ * hey -x "msg" adds a breadcrumb (completed action)
5
+ */
6
+ export interface AddOptions {
7
+ breadcrumb?: boolean;
8
+ force?: boolean;
9
+ project?: string;
10
+ }
11
+ export declare function add(content: string, options?: AddOptions): Promise<void>;
12
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AASD,wBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAuElF"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Add command for Hey CLI
3
+ * hey "msg" adds a next action
4
+ * hey -x "msg" adds a breadcrumb (completed action)
5
+ */
6
+ import { config } from '../lib/config.js';
7
+ import { api } from '../lib/api.js';
8
+ import { printSuccess, printError, printWarning, formatAction, formatBreadcrumb, printLimitWarning, } from '../lib/output.js';
9
+ function requireAuth() {
10
+ if (!config.isAuthenticated()) {
11
+ printError('Not logged in. Run: hey login');
12
+ process.exit(1);
13
+ }
14
+ }
15
+ export async function add(content, options = {}) {
16
+ requireAuth();
17
+ try {
18
+ const context = config.getContext();
19
+ const limits = config.getLimits();
20
+ const projectName = options.project ?? context.lastProject;
21
+ if (!projectName) {
22
+ printError('No project specified. Use: hey -p <project> "msg" or hey use <project>');
23
+ process.exit(1);
24
+ }
25
+ // Find the stax
26
+ const matches = await api.fuzzyFindStax(projectName);
27
+ if (matches.length === 0) {
28
+ printError(`Project "${projectName}" not found`);
29
+ const allStax = await api.getAllStax();
30
+ if (allStax.length > 0) {
31
+ console.log();
32
+ console.log('Available projects:');
33
+ allStax.slice(0, 5).forEach(s => console.log(` - ${s.name}`));
34
+ }
35
+ process.exit(1);
36
+ }
37
+ if (matches.length > 1) {
38
+ printWarning(`Multiple matches for "${projectName}":`);
39
+ matches.forEach(s => console.log(` - ${s.name}`));
40
+ console.log();
41
+ console.log('Be more specific or use: hey use <project>');
42
+ process.exit(1);
43
+ }
44
+ const stax = matches[0];
45
+ // Update last project context
46
+ config.setLastProject(stax.name, stax.id);
47
+ // If adding a next action (not breadcrumb), check limits
48
+ if (!options.breadcrumb) {
49
+ const currentCount = await api.countActiveActions(stax.id);
50
+ if (currentCount >= limits.maxActionsPerStax && !options.force) {
51
+ printLimitWarning(stax, currentCount, limits.maxActionsPerStax);
52
+ process.exit(1);
53
+ }
54
+ if (currentCount >= limits.maxActionsPerStax && options.force) {
55
+ printWarning(`Adding above limit (${currentCount + 1}/${limits.maxActionsPerStax})`);
56
+ }
57
+ }
58
+ // Add the action
59
+ const action = await api.addAction(stax.id, content, options.breadcrumb ?? false);
60
+ // Print success
61
+ if (options.breadcrumb) {
62
+ printSuccess(`Breadcrumb added to ${stax.name}`);
63
+ console.log(formatBreadcrumb(action));
64
+ }
65
+ else {
66
+ printSuccess(`Action added to ${stax.name}`);
67
+ console.log(formatAction(action, 0));
68
+ }
69
+ }
70
+ catch (error) {
71
+ const message = error instanceof Error ? error.message : 'Failed to add';
72
+ printError(message);
73
+ process.exit(1);
74
+ }
75
+ }
76
+ //# sourceMappingURL=add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Authentication commands for Hey CLI
3
+ * hey login, hey logout, hey whoami
4
+ */
5
+ export declare function login(options: {
6
+ token?: string;
7
+ }): Promise<void>;
8
+ export declare function logout(): Promise<void>;
9
+ export declare function whoami(): Promise<void>;
10
+ export declare function status(): Promise<void>;
11
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoDH,wBAAsB,KAAK,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCtE;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAG5C;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAqB5C;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CA4B5C"}