@trydecember/cli 0.2.4 → 0.2.5

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "module": "src/index.ts",
4
4
  "type": "module",
5
5
  "private": false,
6
- "version": "0.2.4",
6
+ "version": "0.2.5",
7
7
  "description": "Turn ideas into reality.",
8
8
  "author": "Chaitanya Sonawane",
9
9
  "license": "Apache-2.0",
@@ -132,74 +132,3 @@ export async function loginViaBrowser(
132
132
  )
133
133
  })
134
134
  }
135
-
136
- export async function loginViaDeviceCode(
137
- baseUrl: string = 'http://localhost:4000',
138
- onCodeGenerated: (userCode: string, verificationUri: string) => void
139
- ): Promise<{ token: string; email: string | null }> {
140
- return new Promise(async (resolve, reject) => {
141
- try {
142
- // 1. Generate Code
143
- const genRes = await fetch(`${baseUrl}/api/v1/auth/device/code`, {
144
- method: 'POST',
145
- headers: { 'Content-Type': 'application/json' },
146
- })
147
-
148
- if (!genRes.ok) {
149
- throw new Error('Failed to generate device code')
150
- }
151
-
152
- const genData = await genRes.json()
153
- if (!genData.success) {
154
- throw new Error(genData.message || 'Failed to generate device code')
155
- }
156
-
157
- const { deviceCode, userCode, verificationUri, expiresIn, interval } = genData.data
158
-
159
- onCodeGenerated(userCode, verificationUri)
160
-
161
- // 2. Poll for token
162
- const startTime = Date.now()
163
- const pollInterval = interval * 1000 || 5000
164
-
165
- const poll = async () => {
166
- if (Date.now() - startTime > expiresIn * 1000) {
167
- reject(new Error('Device code expired'))
168
- return
169
- }
170
-
171
- try {
172
- const tokenRes = await fetch(`${baseUrl}/api/v1/auth/device/token`, {
173
- method: 'POST',
174
- headers: { 'Content-Type': 'application/json' },
175
- body: JSON.stringify({ deviceCode }),
176
- })
177
-
178
- const tokenData = await tokenRes.json()
179
-
180
- if (tokenRes.ok && tokenData.success) {
181
- resolve({
182
- token: tokenData.data.token,
183
- email: tokenData.data.email,
184
- })
185
- return
186
- }
187
-
188
- // If not ok, check if it's authorization_pending
189
- if (tokenData.message === 'authorization_pending') {
190
- setTimeout(poll, pollInterval)
191
- } else {
192
- reject(new Error(tokenData.message || 'Polling failed'))
193
- }
194
- } catch (err) {
195
- // Network errors during polling, just keep trying
196
- setTimeout(poll, pollInterval)
197
- }
198
- }
199
-
200
- setTimeout(poll, pollInterval)
201
- } catch (err) {
202
- reject(err)
203
- }
204
- })
205
- }
@@ -0,0 +1,70 @@
1
+ export async function loginViaDeviceCode(
2
+ baseUrl: string = 'http://localhost:4000',
3
+ onCodeGenerated: (userCode: string, verificationUri: string) => void
4
+ ): Promise<{ token: string; email: string | null }> {
5
+ return new Promise(async (resolve, reject) => {
6
+ try {
7
+ // 1. Generate Code
8
+ const genRes = await fetch(`${baseUrl}/api/v1/auth/device/code`, {
9
+ method: 'POST',
10
+ headers: { 'Content-Type': 'application/json' },
11
+ })
12
+
13
+ if (!genRes.ok) {
14
+ throw new Error('Failed to generate device code')
15
+ }
16
+
17
+ const genData = await genRes.json()
18
+ if (!genData.success) {
19
+ throw new Error(genData.message || 'Failed to generate device code')
20
+ }
21
+
22
+ const { deviceCode, userCode, verificationUri, expiresIn, interval } = genData.data
23
+
24
+ onCodeGenerated(userCode, verificationUri)
25
+
26
+ // 2. Poll for token
27
+ const startTime = Date.now()
28
+ const pollInterval = interval * 1000 || 5000
29
+
30
+ const poll = async () => {
31
+ if (Date.now() - startTime > expiresIn * 1000) {
32
+ reject(new Error('Device code expired'))
33
+ return
34
+ }
35
+
36
+ try {
37
+ const tokenRes = await fetch(`${baseUrl}/api/v1/auth/device/token`, {
38
+ method: 'POST',
39
+ headers: { 'Content-Type': 'application/json' },
40
+ body: JSON.stringify({ deviceCode }),
41
+ })
42
+
43
+ const tokenData = await tokenRes.json()
44
+
45
+ if (tokenRes.ok && tokenData.success) {
46
+ resolve({
47
+ token: tokenData.data.token,
48
+ email: tokenData.data.email,
49
+ })
50
+ return
51
+ }
52
+
53
+ // If not ok, check if it's authorization_pending
54
+ if (tokenData.message === 'authorization_pending') {
55
+ setTimeout(poll, pollInterval)
56
+ } else {
57
+ reject(new Error(tokenData.message || 'Polling failed'))
58
+ }
59
+ } catch (err) {
60
+ // Network errors during polling, just keep trying
61
+ setTimeout(poll, pollInterval)
62
+ }
63
+ }
64
+
65
+ setTimeout(poll, pollInterval)
66
+ } catch (err) {
67
+ reject(err)
68
+ }
69
+ })
70
+ }
@@ -0,0 +1,2 @@
1
+ export * from './browser'
2
+ export * from './device'
@@ -3,7 +3,7 @@ import fs from 'node:fs/promises'
3
3
  import path from 'node:path'
4
4
  import { promisify } from 'node:util'
5
5
 
6
- import { AgentOperations } from '@december/agent'
6
+ import { AgentOperations, taskManager } from '@december/agent'
7
7
  import fg from 'fast-glob'
8
8
 
9
9
  const execAsync = promisify(exec)
@@ -21,29 +21,37 @@ export const localOperations: AgentOperations = {
21
21
  stdio: 'pipe',
22
22
  })
23
23
 
24
+ const task = taskManager.addTask(command, child)
25
+
24
26
  child.stdout?.on('data', (data) => {
25
27
  const chunk = data.toString()
26
28
  stdout += chunk
29
+ taskManager.appendOutput(task.id, chunk)
27
30
  onData(chunk)
28
31
  })
29
32
 
30
33
  child.stderr?.on('data', (data) => {
31
34
  const chunk = data.toString()
32
35
  stderr += chunk
36
+ taskManager.appendOutput(task.id, chunk)
33
37
  onData(chunk)
34
38
  })
35
39
 
36
40
  let isFinished = false
37
41
 
38
42
  child.on('close', (code) => {
43
+ taskManager.markCompleted(task.id, code)
39
44
  if (isFinished) return
40
45
  isFinished = true
46
+ taskManager.removeTask(task.id)
41
47
  resolve({ exitCode: code, output: stdout + '\n' + stderr })
42
48
  })
43
49
 
44
50
  child.on('error', (err) => {
51
+ taskManager.markCompleted(task.id, 1)
45
52
  if (isFinished) return
46
53
  isFinished = true
54
+ taskManager.removeTask(task.id)
47
55
  resolve({ exitCode: 1, output: `Failed to start command: ${err.message}` })
48
56
  })
49
57