gitdone-agent 0.1.2 → 0.1.3
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/index.js +74 -13
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -3,10 +3,31 @@
|
|
|
3
3
|
// Usage: bun index.js --key=gdo_xxx --name=my-repo --path=/path/to/repo [--install]
|
|
4
4
|
|
|
5
5
|
import { execSync, spawn } from 'node:child_process'
|
|
6
|
-
import { existsSync, writeFileSync, unlinkSync } from 'node:fs'
|
|
6
|
+
import { existsSync, writeFileSync, unlinkSync, mkdirSync, copyFileSync, appendFileSync } from 'node:fs'
|
|
7
7
|
import { resolve, join } from 'node:path'
|
|
8
8
|
import { homedir } from 'node:os'
|
|
9
9
|
|
|
10
|
+
// ─── Stable agent dir + logging ────────────────────────────────────────────────
|
|
11
|
+
// Everything persistent lives here: a stable copy of the agent script (so
|
|
12
|
+
// autostart never points at a purged npx temp dir) and a per-repo log file
|
|
13
|
+
// (so failures are visible even when the agent runs in a hidden window).
|
|
14
|
+
|
|
15
|
+
const AGENT_DIR = join(homedir(), '.gitdone-agent')
|
|
16
|
+
|
|
17
|
+
function ensureAgentDir() {
|
|
18
|
+
if (!existsSync(AGENT_DIR)) mkdirSync(AGENT_DIR, { recursive: true })
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let LOG_PATH = null
|
|
22
|
+
|
|
23
|
+
function log(msg) {
|
|
24
|
+
const line = `[${new Date().toISOString()}] ${msg}`
|
|
25
|
+
console.log(line)
|
|
26
|
+
if (LOG_PATH) {
|
|
27
|
+
try { appendFileSync(LOG_PATH, line + '\n') } catch { /* best-effort */ }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
10
31
|
// ─── Arg parsing ─────────────────────────────────────────────────────────────
|
|
11
32
|
|
|
12
33
|
function parseArgs() {
|
|
@@ -27,17 +48,18 @@ function parseArgs() {
|
|
|
27
48
|
const url = (args.url ?? 'https://gitdone.eu').replace(/\/$/, '')
|
|
28
49
|
const install = 'install' in args
|
|
29
50
|
const uninstall = 'uninstall' in args
|
|
51
|
+
const doctor = 'doctor' in args
|
|
30
52
|
|
|
31
|
-
if (!key && !uninstall) {
|
|
53
|
+
if (!key && !uninstall && !doctor) {
|
|
32
54
|
console.error('Error: --key is required (e.g. --key=gdo_xxx)')
|
|
33
55
|
process.exit(1)
|
|
34
56
|
}
|
|
35
|
-
if (!existsSync(repoPath) && !uninstall) {
|
|
57
|
+
if (!existsSync(repoPath) && !uninstall && !doctor) {
|
|
36
58
|
console.error(`Error: path does not exist: ${repoPath}`)
|
|
37
59
|
process.exit(1)
|
|
38
60
|
}
|
|
39
61
|
|
|
40
|
-
return { key, path: repoPath, name, projectId, interval, url, install, uninstall }
|
|
62
|
+
return { key, path: repoPath, name, projectId, interval, url, install, uninstall, doctor }
|
|
41
63
|
}
|
|
42
64
|
|
|
43
65
|
// ─── Windows auto-start ───────────────────────────────────────────────────────
|
|
@@ -53,8 +75,19 @@ function getNodePath() {
|
|
|
53
75
|
}
|
|
54
76
|
|
|
55
77
|
function installStartup({ name, key, path: repoPath, url, interval, projectId }) {
|
|
78
|
+
ensureAgentDir()
|
|
56
79
|
const nodePath = getNodePath()
|
|
57
|
-
|
|
80
|
+
|
|
81
|
+
// Copy this script to a stable location. process.argv[1] may point inside an
|
|
82
|
+
// npx cache dir that gets purged later — referencing it from autostart would
|
|
83
|
+
// silently break on the next login. A stable copy survives.
|
|
84
|
+
const stableAgent = join(AGENT_DIR, 'agent.mjs')
|
|
85
|
+
try {
|
|
86
|
+
copyFileSync(resolve(process.argv[1]), stableAgent)
|
|
87
|
+
} catch (err) {
|
|
88
|
+
console.error(`Warning: could not copy agent to ${stableAgent}: ${err.message}`)
|
|
89
|
+
}
|
|
90
|
+
const agentPath = existsSync(stableAgent) ? stableAgent : resolve(process.argv[1])
|
|
58
91
|
const startupDir = getStartupDir()
|
|
59
92
|
|
|
60
93
|
const argLine = [
|
|
@@ -76,9 +109,11 @@ function installStartup({ name, key, path: repoPath, url, interval, projectId })
|
|
|
76
109
|
writeFileSync(vbsPath, vbs, 'utf8')
|
|
77
110
|
|
|
78
111
|
console.log(`✓ Инсталиран! При следващото влизане в Windows агентът ще стартира автоматично.`)
|
|
79
|
-
console.log(`
|
|
80
|
-
console.log(`
|
|
81
|
-
console.log(`
|
|
112
|
+
console.log(` Файл : ${vbsPath}`)
|
|
113
|
+
console.log(` Агент : ${agentPath}`)
|
|
114
|
+
console.log(` Repo : ${repoPath}`)
|
|
115
|
+
console.log(` Name : ${name}`)
|
|
116
|
+
console.log(` Лог : ${join(AGENT_DIR, `${name}.log`)}`)
|
|
82
117
|
console.log()
|
|
83
118
|
}
|
|
84
119
|
|
|
@@ -92,6 +127,20 @@ function uninstallStartup(name) {
|
|
|
92
127
|
}
|
|
93
128
|
}
|
|
94
129
|
|
|
130
|
+
// ─── Doctor: print where things are so "offline" is debuggable ─────────────────
|
|
131
|
+
|
|
132
|
+
function runDoctor(name) {
|
|
133
|
+
const vbsPath = join(getStartupDir(), `gitdone-${name}.vbs`)
|
|
134
|
+
const stableAgent = join(AGENT_DIR, 'agent.mjs')
|
|
135
|
+
const logPath = join(AGENT_DIR, `${name}.log`)
|
|
136
|
+
console.log('gitdone-agent doctor')
|
|
137
|
+
console.log(` node : ${getNodePath()}`)
|
|
138
|
+
console.log(` agent dir : ${AGENT_DIR} ${existsSync(AGENT_DIR) ? '(ok)' : '(MISSING)'}`)
|
|
139
|
+
console.log(` stable agent : ${stableAgent} ${existsSync(stableAgent) ? '(ok)' : '(not installed)'}`)
|
|
140
|
+
console.log(` autostart vbs : ${vbsPath} ${existsSync(vbsPath) ? '(ok)' : '(not installed)'}`)
|
|
141
|
+
console.log(` log file : ${logPath} ${existsSync(logPath) ? '(ok)' : '(none yet)'}`)
|
|
142
|
+
}
|
|
143
|
+
|
|
95
144
|
// ─── Git helpers ─────────────────────────────────────────────────────────────
|
|
96
145
|
|
|
97
146
|
function git(cmd, cwd) {
|
|
@@ -174,11 +223,11 @@ async function executeCommand(cmd, repoPath, url, key) {
|
|
|
174
223
|
const out = git('git pull', repoPath)
|
|
175
224
|
result = out || 'pulled'
|
|
176
225
|
}
|
|
177
|
-
|
|
226
|
+
log(`✓ ${cmd.type}: ${result}`)
|
|
178
227
|
} catch (err) {
|
|
179
228
|
status = 'error'
|
|
180
229
|
result = err.message
|
|
181
|
-
|
|
230
|
+
log(`✗ ${cmd.type} failed: ${result}`)
|
|
182
231
|
}
|
|
183
232
|
await reportCommandResult(url, key, cmd.id, status, result)
|
|
184
233
|
}
|
|
@@ -203,7 +252,19 @@ async function push({ url, key, name, projectId, repoPath, snapshot }) {
|
|
|
203
252
|
|
|
204
253
|
async function main() {
|
|
205
254
|
const config = parseArgs()
|
|
206
|
-
const { key, path: repoPath, name, projectId, interval, url, install, uninstall } = config
|
|
255
|
+
const { key, path: repoPath, name, projectId, interval, url, install, uninstall, doctor } = config
|
|
256
|
+
|
|
257
|
+
if (doctor) {
|
|
258
|
+
runDoctor(name)
|
|
259
|
+
process.exit(0)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Route all runtime logs to a per-repo file too, so a silently-running
|
|
263
|
+
// (hidden-window) agent still leaves a trail to debug "why is it offline".
|
|
264
|
+
if (!uninstall) {
|
|
265
|
+
ensureAgentDir()
|
|
266
|
+
LOG_PATH = join(AGENT_DIR, `${name}.log`)
|
|
267
|
+
}
|
|
207
268
|
|
|
208
269
|
if (uninstall) {
|
|
209
270
|
uninstallStartup(name)
|
|
@@ -243,9 +304,9 @@ async function main() {
|
|
|
243
304
|
const snapshot = getSnapshot(repoPath)
|
|
244
305
|
await push({ url, key, name, projectId, repoPath, snapshot })
|
|
245
306
|
const changed = snapshot.modified.length + snapshot.staged.length
|
|
246
|
-
|
|
307
|
+
log(`✓ pushed — branch: ${snapshot.branch}, changes: ${changed}`)
|
|
247
308
|
} catch (err) {
|
|
248
|
-
|
|
309
|
+
log(`✗ error: ${err.message}`)
|
|
249
310
|
}
|
|
250
311
|
}
|
|
251
312
|
|