@commandgarden/cli 2.12.1 → 2.14.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 (73) hide show
  1. package/dist/main.js +58 -28
  2. package/node_modules/@commandgarden/app/dist/client/assets/{Slides-CHeVcB9K.js → Slides-DWQmJfkp.js} +1 -1
  3. package/node_modules/@commandgarden/app/dist/client/assets/{index-DR1TjI6k.js → index-C8yqRQk-.js} +37 -37
  4. package/node_modules/@commandgarden/app/dist/client/assets/index-rHqHbsBw.css +1 -0
  5. package/node_modules/@commandgarden/app/dist/client/index.html +19 -19
  6. package/node_modules/@commandgarden/app/dist/server/journal/journal.service.d.ts +2 -0
  7. package/node_modules/@commandgarden/app/dist/server/journal/journal.service.js +54 -24
  8. package/node_modules/@commandgarden/app/dist/server/journal/journal.types.d.ts +8 -0
  9. package/node_modules/@commandgarden/app/dist/server/main.js +1 -1
  10. package/node_modules/@commandgarden/app/dist/server/routes/audit.js +27 -16
  11. package/node_modules/@commandgarden/app/dist/server/routes/config.js +8 -2
  12. package/node_modules/@commandgarden/app/dist/server/routes/connectors.js +37 -26
  13. package/node_modules/@commandgarden/app/dist/server/routes/run.js +3 -4
  14. package/node_modules/@commandgarden/app/dist/server/routes/status.js +2 -1
  15. package/node_modules/@commandgarden/app/dist/server/routes/utils.d.ts +2 -0
  16. package/node_modules/@commandgarden/app/dist/server/routes/utils.js +4 -0
  17. package/node_modules/@commandgarden/app/dist/server/store.js +53 -53
  18. package/node_modules/@commandgarden/app/package.json +42 -42
  19. package/node_modules/@commandgarden/chrome/dist/content-script.js.map +1 -1
  20. package/node_modules/@commandgarden/chrome/dist/manifest.json +26 -26
  21. package/node_modules/@commandgarden/chrome/dist/popup.html +218 -218
  22. package/node_modules/@commandgarden/chrome/dist/popup.js.map +1 -1
  23. package/node_modules/@commandgarden/chrome/dist/service-worker.js.map +1 -1
  24. package/node_modules/@commandgarden/chrome/package.json +26 -26
  25. package/node_modules/@commandgarden/daemon/connectors/ado-git-commits.eval.js +100 -100
  26. package/node_modules/@commandgarden/daemon/connectors/ado-git-commits.yaml +71 -71
  27. package/node_modules/@commandgarden/daemon/connectors/gcs-kb-content.yaml +61 -61
  28. package/node_modules/@commandgarden/daemon/connectors/gcs-kb-pages.yaml +54 -54
  29. package/node_modules/@commandgarden/daemon/connectors/jira-my-tickets.eval.js +115 -115
  30. package/node_modules/@commandgarden/daemon/connectors/jira-my-tickets.yaml +54 -54
  31. package/node_modules/@commandgarden/daemon/connectors/lib/msal-token.js +20 -20
  32. package/node_modules/@commandgarden/daemon/connectors/outlook-my-meetings.eval.js +204 -204
  33. package/node_modules/@commandgarden/daemon/connectors/outlook-my-meetings.yaml +42 -42
  34. package/node_modules/@commandgarden/daemon/connectors/saba-pending-training.eval.js +94 -94
  35. package/node_modules/@commandgarden/daemon/connectors/saba-pending-training.yaml +34 -34
  36. package/node_modules/@commandgarden/daemon/connectors/socket-security-news.yaml +63 -63
  37. package/node_modules/@commandgarden/daemon/connectors/teams-room-availability.eval.js +437 -437
  38. package/node_modules/@commandgarden/daemon/connectors/teams-room-availability.yaml +53 -53
  39. package/node_modules/@commandgarden/daemon/connectors/teams-rooms-availability.eval.js +547 -547
  40. package/node_modules/@commandgarden/daemon/connectors/teams-rooms-availability.yaml +48 -48
  41. package/node_modules/@commandgarden/daemon/connectors/timetracking-projects.eval.js +52 -52
  42. package/node_modules/@commandgarden/daemon/connectors/timetracking-projects.yaml +42 -42
  43. package/node_modules/@commandgarden/daemon/connectors/timetracking-report.eval.js +81 -81
  44. package/node_modules/@commandgarden/daemon/connectors/timetracking-report.yaml +52 -52
  45. package/node_modules/@commandgarden/daemon/connectors/tldrsec-newsletter.eval.js +27 -27
  46. package/node_modules/@commandgarden/daemon/connectors/tldrsec-newsletter.yaml +38 -38
  47. package/node_modules/@commandgarden/daemon/connectors/tokenmaster-clients-list.yaml +55 -55
  48. package/node_modules/@commandgarden/daemon/dist/audit-store.js +8 -8
  49. package/node_modules/@commandgarden/daemon/dist/auth.d.ts +1 -0
  50. package/node_modules/@commandgarden/daemon/dist/auth.d.ts.map +1 -1
  51. package/node_modules/@commandgarden/daemon/dist/auth.js +10 -0
  52. package/node_modules/@commandgarden/daemon/dist/auth.js.map +1 -1
  53. package/node_modules/@commandgarden/daemon/dist/main.js +12 -5
  54. package/node_modules/@commandgarden/daemon/dist/main.js.map +1 -1
  55. package/node_modules/@commandgarden/daemon/dist/server.d.ts.map +1 -1
  56. package/node_modules/@commandgarden/daemon/dist/server.js +10 -0
  57. package/node_modules/@commandgarden/daemon/dist/server.js.map +1 -1
  58. package/node_modules/@commandgarden/daemon/package.json +32 -32
  59. package/node_modules/@commandgarden/shared/dist/daemon-client.d.ts +5 -1
  60. package/node_modules/@commandgarden/shared/dist/daemon-client.d.ts.map +1 -1
  61. package/node_modules/@commandgarden/shared/dist/daemon-client.js +32 -14
  62. package/node_modules/@commandgarden/shared/dist/daemon-client.js.map +1 -1
  63. package/node_modules/@commandgarden/shared/package.json +32 -32
  64. package/package.json +58 -58
  65. package/node_modules/@commandgarden/app/dist/client/assets/index-CDD2bVHm.css +0 -1
  66. package/node_modules/@commandgarden/app/dist/server/daemon-client.test.js +0 -47
  67. package/node_modules/@commandgarden/app/dist/server/routes/routes.test.js +0 -137
  68. package/node_modules/@commandgarden/app/dist/server/store.test.js +0 -59
  69. package/node_modules/@commandgarden/chrome/dist/fetch-interceptor.js +0 -44
  70. package/node_modules/@commandgarden/daemon/dist/cdp-client.d.ts +0 -24
  71. package/node_modules/@commandgarden/daemon/dist/cdp-client.d.ts.map +0 -1
  72. package/node_modules/@commandgarden/daemon/dist/cdp-client.js +0 -150
  73. package/node_modules/@commandgarden/daemon/dist/cdp-client.js.map +0 -1
@@ -1,218 +1,218 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <link rel="preconnect" href="https://fonts.googleapis.com" />
6
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
7
- <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
8
- <style>
9
- * { margin: 0; padding: 0; box-sizing: border-box; border-radius: 0 !important; }
10
- body {
11
- width: 320px;
12
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
13
- font-size: 13px;
14
- background: #0a0a0a;
15
- color: #e5e5e5;
16
- }
17
- .header {
18
- padding: 12px 16px;
19
- border-bottom: 1px solid #262626;
20
- }
21
- .header-title {
22
- font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
23
- font-size: 14px;
24
- font-weight: 700;
25
- letter-spacing: -0.02em;
26
- color: #e5e5e5;
27
- }
28
- .header-title span {
29
- font-weight: 400;
30
- opacity: 0.6;
31
- }
32
- .header-sub {
33
- font-family: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;
34
- font-size: 0.6rem;
35
- font-weight: 500;
36
- text-transform: uppercase;
37
- letter-spacing: 0.12em;
38
- opacity: 0.4;
39
- margin-top: 2px;
40
- }
41
- .status-row {
42
- display: flex;
43
- align-items: center;
44
- gap: 8px;
45
- padding: 10px 16px;
46
- border-bottom: 1px solid #262626;
47
- }
48
- .dot {
49
- width: 8px;
50
- height: 8px;
51
- flex-shrink: 0;
52
- }
53
- .dot.connected { background: #4ade80; }
54
- .dot.disconnected { background: #f87171; }
55
- .dot.disabled { background: #737373; }
56
- .status-text { flex: 1; }
57
- .toggle {
58
- position: relative;
59
- width: 36px;
60
- height: 20px;
61
- flex-shrink: 0;
62
- cursor: pointer;
63
- }
64
- .toggle input {
65
- opacity: 0;
66
- width: 0;
67
- height: 0;
68
- }
69
- .toggle-track {
70
- position: absolute;
71
- inset: 0;
72
- background: #262626;
73
- transition: background 0.15s;
74
- }
75
- .toggle input:checked + .toggle-track {
76
- background: #4ade80;
77
- }
78
- .toggle-knob {
79
- position: absolute;
80
- top: 2px;
81
- left: 2px;
82
- width: 16px;
83
- height: 16px;
84
- background: #e5e5e5;
85
- transition: transform 0.15s;
86
- pointer-events: none;
87
- }
88
- .toggle input:checked ~ .toggle-knob {
89
- transform: translateX(16px);
90
- }
91
- .activity-list {
92
- max-height: 240px;
93
- overflow-y: auto;
94
- }
95
- .activity-item {
96
- display: flex;
97
- align-items: center;
98
- gap: 8px;
99
- padding: 8px 16px;
100
- border-bottom: 1px solid #171717;
101
- transition: background 0.1s;
102
- }
103
- .activity-item:hover {
104
- background: #171717;
105
- }
106
- .activity-icon { font-size: 12px; flex-shrink: 0; }
107
- .activity-icon.ok { color: #4ade80; }
108
- .activity-icon.fail { color: #f87171; }
109
- .activity-name { flex: 1; font-family: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace; font-size: 12px; }
110
- .activity-time { color: #a3a3a3; font-size: 11px; flex-shrink: 0; }
111
- .empty {
112
- padding: 16px;
113
- text-align: center;
114
- color: #737373;
115
- font-style: italic;
116
- }
117
- /* Approval section */
118
- .approval-section {
119
- border-bottom: 1px solid #262626;
120
- background: #171717;
121
- }
122
- .approval-header {
123
- padding: 10px 16px 4px;
124
- font-size: 12px;
125
- font-weight: 600;
126
- color: #e5e5e5;
127
- }
128
- .approval-count {
129
- display: inline-block;
130
- font-size: 10px;
131
- min-width: 16px;
132
- text-align: center;
133
- padding: 0 5px;
134
- line-height: 16px;
135
- background: rgba(251, 191, 36, 0.15);
136
- color: #fbbf24;
137
- font-weight: 700;
138
- margin-left: 6px;
139
- vertical-align: 1px;
140
- }
141
- .approval-card {
142
- padding: 10px 16px;
143
- display: flex;
144
- flex-direction: column;
145
- gap: 6px;
146
- }
147
- .approval-card + .approval-card {
148
- border-top: 1px solid #262626;
149
- }
150
- .approval-connector {
151
- font-family: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;
152
- font-size: 12px;
153
- color: #e5e5e5;
154
- }
155
- .approval-detail {
156
- font-size: 11px;
157
- color: #a3a3a3;
158
- }
159
- .approval-cap {
160
- display: inline-block;
161
- font-size: 10px;
162
- padding: 1px 6px;
163
- background: rgba(251, 191, 36, 0.12);
164
- color: #fbbf24;
165
- font-family: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;
166
- }
167
- .approval-actions {
168
- display: flex;
169
- gap: 8px;
170
- margin-top: 2px;
171
- }
172
- .btn-approve, .btn-reject {
173
- font-size: 11px;
174
- padding: 4px 14px;
175
- border: none;
176
- cursor: pointer;
177
- font-weight: 600;
178
- transition: background 0.15s, color 0.15s;
179
- }
180
- .btn-approve {
181
- background: #4ade80;
182
- color: #0a0a0a;
183
- }
184
- .btn-approve:hover { background: #22c55e; }
185
- .btn-approve:active { background: #16a34a; }
186
- .btn-reject {
187
- background: transparent;
188
- color: #a3a3a3;
189
- border: 1px solid #262626;
190
- }
191
- .btn-reject:hover { background: #171717; color: #e5e5e5; }
192
- .btn-reject:active { background: #262626; }
193
- /* Scrollbar */
194
- ::-webkit-scrollbar { width: 6px; height: 6px; }
195
- ::-webkit-scrollbar-track { background: transparent; }
196
- ::-webkit-scrollbar-thumb { background: rgba(229, 229, 229, 0.2); }
197
- ::-webkit-scrollbar-thumb:hover { background: rgba(229, 229, 229, 0.35); }
198
- </style>
199
- </head>
200
- <body>
201
- <div class="header">
202
- <div class="header-title"><span>command</span>Garden</div>
203
- <div class="header-sub">browser automation</div>
204
- </div>
205
- <div class="status-row">
206
- <div id="dot" class="dot disabled"></div>
207
- <span id="status-text" class="status-text">Checking…</span>
208
- <label class="toggle">
209
- <input type="checkbox" id="toggle-input">
210
- <div class="toggle-track"></div>
211
- <div class="toggle-knob"></div>
212
- </label>
213
- </div>
214
- <div id="approvals"></div>
215
- <div id="activity" class="activity-list"></div>
216
- <script src="popup.js"></script>
217
- </body>
218
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
6
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
7
+ <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
8
+ <style>
9
+ * { margin: 0; padding: 0; box-sizing: border-box; border-radius: 0 !important; }
10
+ body {
11
+ width: 320px;
12
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
13
+ font-size: 13px;
14
+ background: #0a0a0a;
15
+ color: #e5e5e5;
16
+ }
17
+ .header {
18
+ padding: 12px 16px;
19
+ border-bottom: 1px solid #262626;
20
+ }
21
+ .header-title {
22
+ font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
23
+ font-size: 14px;
24
+ font-weight: 700;
25
+ letter-spacing: -0.02em;
26
+ color: #e5e5e5;
27
+ }
28
+ .header-title span {
29
+ font-weight: 400;
30
+ opacity: 0.6;
31
+ }
32
+ .header-sub {
33
+ font-family: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;
34
+ font-size: 0.6rem;
35
+ font-weight: 500;
36
+ text-transform: uppercase;
37
+ letter-spacing: 0.12em;
38
+ opacity: 0.4;
39
+ margin-top: 2px;
40
+ }
41
+ .status-row {
42
+ display: flex;
43
+ align-items: center;
44
+ gap: 8px;
45
+ padding: 10px 16px;
46
+ border-bottom: 1px solid #262626;
47
+ }
48
+ .dot {
49
+ width: 8px;
50
+ height: 8px;
51
+ flex-shrink: 0;
52
+ }
53
+ .dot.connected { background: #4ade80; }
54
+ .dot.disconnected { background: #f87171; }
55
+ .dot.disabled { background: #737373; }
56
+ .status-text { flex: 1; }
57
+ .toggle {
58
+ position: relative;
59
+ width: 36px;
60
+ height: 20px;
61
+ flex-shrink: 0;
62
+ cursor: pointer;
63
+ }
64
+ .toggle input {
65
+ opacity: 0;
66
+ width: 0;
67
+ height: 0;
68
+ }
69
+ .toggle-track {
70
+ position: absolute;
71
+ inset: 0;
72
+ background: #262626;
73
+ transition: background 0.15s;
74
+ }
75
+ .toggle input:checked + .toggle-track {
76
+ background: #4ade80;
77
+ }
78
+ .toggle-knob {
79
+ position: absolute;
80
+ top: 2px;
81
+ left: 2px;
82
+ width: 16px;
83
+ height: 16px;
84
+ background: #e5e5e5;
85
+ transition: transform 0.15s;
86
+ pointer-events: none;
87
+ }
88
+ .toggle input:checked ~ .toggle-knob {
89
+ transform: translateX(16px);
90
+ }
91
+ .activity-list {
92
+ max-height: 240px;
93
+ overflow-y: auto;
94
+ }
95
+ .activity-item {
96
+ display: flex;
97
+ align-items: center;
98
+ gap: 8px;
99
+ padding: 8px 16px;
100
+ border-bottom: 1px solid #171717;
101
+ transition: background 0.1s;
102
+ }
103
+ .activity-item:hover {
104
+ background: #171717;
105
+ }
106
+ .activity-icon { font-size: 12px; flex-shrink: 0; }
107
+ .activity-icon.ok { color: #4ade80; }
108
+ .activity-icon.fail { color: #f87171; }
109
+ .activity-name { flex: 1; font-family: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace; font-size: 12px; }
110
+ .activity-time { color: #a3a3a3; font-size: 11px; flex-shrink: 0; }
111
+ .empty {
112
+ padding: 16px;
113
+ text-align: center;
114
+ color: #737373;
115
+ font-style: italic;
116
+ }
117
+ /* Approval section */
118
+ .approval-section {
119
+ border-bottom: 1px solid #262626;
120
+ background: #171717;
121
+ }
122
+ .approval-header {
123
+ padding: 10px 16px 4px;
124
+ font-size: 12px;
125
+ font-weight: 600;
126
+ color: #e5e5e5;
127
+ }
128
+ .approval-count {
129
+ display: inline-block;
130
+ font-size: 10px;
131
+ min-width: 16px;
132
+ text-align: center;
133
+ padding: 0 5px;
134
+ line-height: 16px;
135
+ background: rgba(251, 191, 36, 0.15);
136
+ color: #fbbf24;
137
+ font-weight: 700;
138
+ margin-left: 6px;
139
+ vertical-align: 1px;
140
+ }
141
+ .approval-card {
142
+ padding: 10px 16px;
143
+ display: flex;
144
+ flex-direction: column;
145
+ gap: 6px;
146
+ }
147
+ .approval-card + .approval-card {
148
+ border-top: 1px solid #262626;
149
+ }
150
+ .approval-connector {
151
+ font-family: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;
152
+ font-size: 12px;
153
+ color: #e5e5e5;
154
+ }
155
+ .approval-detail {
156
+ font-size: 11px;
157
+ color: #a3a3a3;
158
+ }
159
+ .approval-cap {
160
+ display: inline-block;
161
+ font-size: 10px;
162
+ padding: 1px 6px;
163
+ background: rgba(251, 191, 36, 0.12);
164
+ color: #fbbf24;
165
+ font-family: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;
166
+ }
167
+ .approval-actions {
168
+ display: flex;
169
+ gap: 8px;
170
+ margin-top: 2px;
171
+ }
172
+ .btn-approve, .btn-reject {
173
+ font-size: 11px;
174
+ padding: 4px 14px;
175
+ border: none;
176
+ cursor: pointer;
177
+ font-weight: 600;
178
+ transition: background 0.15s, color 0.15s;
179
+ }
180
+ .btn-approve {
181
+ background: #4ade80;
182
+ color: #0a0a0a;
183
+ }
184
+ .btn-approve:hover { background: #22c55e; }
185
+ .btn-approve:active { background: #16a34a; }
186
+ .btn-reject {
187
+ background: transparent;
188
+ color: #a3a3a3;
189
+ border: 1px solid #262626;
190
+ }
191
+ .btn-reject:hover { background: #171717; color: #e5e5e5; }
192
+ .btn-reject:active { background: #262626; }
193
+ /* Scrollbar */
194
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
195
+ ::-webkit-scrollbar-track { background: transparent; }
196
+ ::-webkit-scrollbar-thumb { background: rgba(229, 229, 229, 0.2); }
197
+ ::-webkit-scrollbar-thumb:hover { background: rgba(229, 229, 229, 0.35); }
198
+ </style>
199
+ </head>
200
+ <body>
201
+ <div class="header">
202
+ <div class="header-title"><span>command</span>Garden</div>
203
+ <div class="header-sub">browser automation</div>
204
+ </div>
205
+ <div class="status-row">
206
+ <div id="dot" class="dot disabled"></div>
207
+ <span id="status-text" class="status-text">Checking…</span>
208
+ <label class="toggle">
209
+ <input type="checkbox" id="toggle-input">
210
+ <div class="toggle-track"></div>
211
+ <div class="toggle-knob"></div>
212
+ </label>
213
+ </div>
214
+ <div id="approvals"></div>
215
+ <div id="activity" class="activity-list"></div>
216
+ <script src="popup.js"></script>
217
+ </body>
218
+ </html>
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/popup/time-ago.ts", "../src/popup/popup.ts"],
4
- "sourcesContent": ["// src/popup/time-ago.ts\nexport function timeAgo(timestamp: number, now: number = Date.now()): string {\n const seconds = Math.floor((now - timestamp) / 1000);\n if (seconds < 60) return 'just now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n", "// src/popup/popup.ts\n/// <reference lib=\"dom\" />\nimport type { PopupStatusResponse, ApprovalInfo } from './popup-types.js';\nimport { timeAgo } from './time-ago.js';\n\nconst dot = document.getElementById('dot')!;\nconst statusText = document.getElementById('status-text')!;\nconst toggleInput = document.getElementById('toggle-input') as HTMLInputElement;\nconst activityEl = document.getElementById('activity')!;\nconst approvalsEl = document.getElementById('approvals')!;\n\nlet currentEnabled = true;\n\nfunction escapeHtml(text: string): string {\n const el = document.createElement('span');\n el.textContent = text;\n return el.innerHTML;\n}\n\nfunction renderApprovals(approvals: ApprovalInfo[]): void {\n if (approvals.length === 0) {\n approvalsEl.innerHTML = '';\n return;\n }\n\n const cards = approvals.map(a =>\n `<div class=\"approval-card\" data-id=\"${escapeHtml(a.approvalId)}\">\n <div class=\"approval-connector\">${escapeHtml(a.connectorKey)}</div>\n <div class=\"approval-detail\">Step ${a.stepIndex + 1} [${escapeHtml(a.stepType)}] <span class=\"approval-cap\">${escapeHtml(a.capability)}</span></div>\n <div class=\"approval-actions\">\n <button class=\"btn-approve\" data-approval-id=\"${escapeHtml(a.approvalId)}\" data-approved=\"true\">Approve</button>\n <button class=\"btn-reject\" data-approval-id=\"${escapeHtml(a.approvalId)}\" data-approved=\"false\">Reject</button>\n </div>\n </div>`\n ).join('');\n\n approvalsEl.innerHTML =\n `<div class=\"approval-section\">\n <div class=\"approval-header\">Pending approvals <span class=\"approval-count\">${approvals.length}</span></div>\n ${cards}\n </div>`;\n\n approvalsEl.querySelectorAll('[data-approval-id]').forEach(btn => {\n btn.addEventListener('click', () => {\n const approvalId = (btn as HTMLElement).dataset.approvalId!;\n const approved = (btn as HTMLElement).dataset.approved === 'true';\n (btn as HTMLButtonElement).disabled = true;\n chrome.runtime.sendMessage(\n { type: 'approvalDecision', approvalId, approved },\n () => { fetchStatus(); },\n );\n });\n });\n}\n\nfunction render(status: PopupStatusResponse): void {\n currentEnabled = status.enabled;\n toggleInput.checked = status.enabled;\n\n if (!status.enabled) {\n dot.className = 'dot disabled';\n statusText.textContent = 'Disabled';\n } else if (status.connected) {\n dot.className = 'dot connected';\n statusText.textContent = 'Connected';\n } else {\n dot.className = 'dot disconnected';\n statusText.textContent = 'Disconnected';\n }\n\n renderApprovals(status.pendingApprovals ?? []);\n\n if (status.recentActivity.length === 0) {\n activityEl.innerHTML = '<div class=\"empty\">No recent activity</div>';\n return;\n }\n\n const now = Date.now();\n activityEl.innerHTML = status.recentActivity\n .map(entry => {\n const icon = entry.ok\n ? '<span class=\"activity-icon ok\">\u2713</span>'\n : '<span class=\"activity-icon fail\">\u2717</span>';\n return `<div class=\"activity-item\">${icon}<span class=\"activity-name\">${escapeHtml(entry.connector)}</span><span class=\"activity-time\">${timeAgo(entry.timestamp, now)}</span></div>`;\n })\n .join('');\n}\n\nfunction fetchStatus(): void {\n chrome.runtime.sendMessage({ type: 'getStatus' }, (response: PopupStatusResponse) => {\n if (chrome.runtime.lastError) {\n statusText.textContent = 'Error';\n return;\n }\n render(response);\n });\n}\n\ntoggleInput.addEventListener('change', () => {\n const newEnabled = toggleInput.checked;\n toggleInput.disabled = true;\n chrome.runtime.sendMessage({ type: 'setEnabled', enabled: newEnabled }, (response: PopupStatusResponse) => {\n toggleInput.disabled = false;\n if (chrome.runtime.lastError) {\n toggleInput.checked = currentEnabled;\n return;\n }\n render(response);\n });\n});\n\n// Listen for push updates from the service worker (approval state changes)\nchrome.runtime.onMessage.addListener((msg) => {\n if (msg.type === 'approvalUpdate') {\n renderApprovals(msg.pendingApprovals ?? []);\n }\n});\n\nfetchStatus();\n"],
4
+ "sourcesContent": ["// src/popup/time-ago.ts\r\nexport function timeAgo(timestamp: number, now: number = Date.now()): string {\r\n const seconds = Math.floor((now - timestamp) / 1000);\r\n if (seconds < 60) return 'just now';\r\n const minutes = Math.floor(seconds / 60);\r\n if (minutes < 60) return `${minutes}m ago`;\r\n const hours = Math.floor(minutes / 60);\r\n if (hours < 24) return `${hours}h ago`;\r\n const days = Math.floor(hours / 24);\r\n return `${days}d ago`;\r\n}\r\n", "// src/popup/popup.ts\r\n/// <reference lib=\"dom\" />\r\nimport type { PopupStatusResponse, ApprovalInfo } from './popup-types.js';\r\nimport { timeAgo } from './time-ago.js';\r\n\r\nconst dot = document.getElementById('dot')!;\r\nconst statusText = document.getElementById('status-text')!;\r\nconst toggleInput = document.getElementById('toggle-input') as HTMLInputElement;\r\nconst activityEl = document.getElementById('activity')!;\r\nconst approvalsEl = document.getElementById('approvals')!;\r\n\r\nlet currentEnabled = true;\r\n\r\nfunction escapeHtml(text: string): string {\r\n const el = document.createElement('span');\r\n el.textContent = text;\r\n return el.innerHTML;\r\n}\r\n\r\nfunction renderApprovals(approvals: ApprovalInfo[]): void {\r\n if (approvals.length === 0) {\r\n approvalsEl.innerHTML = '';\r\n return;\r\n }\r\n\r\n const cards = approvals.map(a =>\r\n `<div class=\"approval-card\" data-id=\"${escapeHtml(a.approvalId)}\">\r\n <div class=\"approval-connector\">${escapeHtml(a.connectorKey)}</div>\r\n <div class=\"approval-detail\">Step ${a.stepIndex + 1} [${escapeHtml(a.stepType)}] <span class=\"approval-cap\">${escapeHtml(a.capability)}</span></div>\r\n <div class=\"approval-actions\">\r\n <button class=\"btn-approve\" data-approval-id=\"${escapeHtml(a.approvalId)}\" data-approved=\"true\">Approve</button>\r\n <button class=\"btn-reject\" data-approval-id=\"${escapeHtml(a.approvalId)}\" data-approved=\"false\">Reject</button>\r\n </div>\r\n </div>`\r\n ).join('');\r\n\r\n approvalsEl.innerHTML =\r\n `<div class=\"approval-section\">\r\n <div class=\"approval-header\">Pending approvals <span class=\"approval-count\">${approvals.length}</span></div>\r\n ${cards}\r\n </div>`;\r\n\r\n approvalsEl.querySelectorAll('[data-approval-id]').forEach(btn => {\r\n btn.addEventListener('click', () => {\r\n const approvalId = (btn as HTMLElement).dataset.approvalId!;\r\n const approved = (btn as HTMLElement).dataset.approved === 'true';\r\n (btn as HTMLButtonElement).disabled = true;\r\n chrome.runtime.sendMessage(\r\n { type: 'approvalDecision', approvalId, approved },\r\n () => { fetchStatus(); },\r\n );\r\n });\r\n });\r\n}\r\n\r\nfunction render(status: PopupStatusResponse): void {\r\n currentEnabled = status.enabled;\r\n toggleInput.checked = status.enabled;\r\n\r\n if (!status.enabled) {\r\n dot.className = 'dot disabled';\r\n statusText.textContent = 'Disabled';\r\n } else if (status.connected) {\r\n dot.className = 'dot connected';\r\n statusText.textContent = 'Connected';\r\n } else {\r\n dot.className = 'dot disconnected';\r\n statusText.textContent = 'Disconnected';\r\n }\r\n\r\n renderApprovals(status.pendingApprovals ?? []);\r\n\r\n if (status.recentActivity.length === 0) {\r\n activityEl.innerHTML = '<div class=\"empty\">No recent activity</div>';\r\n return;\r\n }\r\n\r\n const now = Date.now();\r\n activityEl.innerHTML = status.recentActivity\r\n .map(entry => {\r\n const icon = entry.ok\r\n ? '<span class=\"activity-icon ok\">\u2713</span>'\r\n : '<span class=\"activity-icon fail\">\u2717</span>';\r\n return `<div class=\"activity-item\">${icon}<span class=\"activity-name\">${escapeHtml(entry.connector)}</span><span class=\"activity-time\">${timeAgo(entry.timestamp, now)}</span></div>`;\r\n })\r\n .join('');\r\n}\r\n\r\nfunction fetchStatus(): void {\r\n chrome.runtime.sendMessage({ type: 'getStatus' }, (response: PopupStatusResponse) => {\r\n if (chrome.runtime.lastError) {\r\n statusText.textContent = 'Error';\r\n return;\r\n }\r\n render(response);\r\n });\r\n}\r\n\r\ntoggleInput.addEventListener('change', () => {\r\n const newEnabled = toggleInput.checked;\r\n toggleInput.disabled = true;\r\n chrome.runtime.sendMessage({ type: 'setEnabled', enabled: newEnabled }, (response: PopupStatusResponse) => {\r\n toggleInput.disabled = false;\r\n if (chrome.runtime.lastError) {\r\n toggleInput.checked = currentEnabled;\r\n return;\r\n }\r\n render(response);\r\n });\r\n});\r\n\r\n// Listen for push updates from the service worker (approval state changes)\r\nchrome.runtime.onMessage.addListener((msg) => {\r\n if (msg.type === 'approvalUpdate') {\r\n renderApprovals(msg.pendingApprovals ?? []);\r\n }\r\n});\r\n\r\nfetchStatus();\r\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }