gitdone-agent 0.6.10 → 0.6.12
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 +52 -6
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
// roots anytime with --root (repeatable). The running agent reads its config
|
|
10
10
|
// from ~/.gitdone-agent/config.json, so the autostart entry needs no args.
|
|
11
11
|
|
|
12
|
-
import { execSync, spawn } from 'node:child_process'
|
|
12
|
+
import { execSync, execFileSync, spawn } from 'node:child_process'
|
|
13
13
|
import {
|
|
14
14
|
existsSync, writeFileSync, readFileSync, unlinkSync,
|
|
15
|
-
mkdirSync, copyFileSync, appendFileSync, readdirSync, rmSync,
|
|
15
|
+
mkdirSync, copyFileSync, appendFileSync, readdirSync, rmSync, statSync,
|
|
16
16
|
} from 'node:fs'
|
|
17
17
|
import { resolve, join } from 'node:path'
|
|
18
18
|
import { homedir, hostname, tmpdir } from 'node:os'
|
|
@@ -27,7 +27,7 @@ import { randomUUID } from 'node:crypto'
|
|
|
27
27
|
// Reported to the server on every sync so the web UI can flag outdated agents.
|
|
28
28
|
// Keep in lockstep with packages/agent/package.json "version" AND
|
|
29
29
|
// src/lib/agentVersion.ts LATEST_AGENT_VERSION.
|
|
30
|
-
const AGENT_VERSION = '0.6.
|
|
30
|
+
const AGENT_VERSION = '0.6.12'
|
|
31
31
|
|
|
32
32
|
const AGENT_DIR = join(homedir(), '.gitdone-agent')
|
|
33
33
|
const CONFIG_PATH = join(AGENT_DIR, 'config.json')
|
|
@@ -231,9 +231,20 @@ function runDoctor() {
|
|
|
231
231
|
|
|
232
232
|
// ─── Git helpers ─────────────────────────────────────────────────────────────
|
|
233
233
|
|
|
234
|
+
// Room for large command output. `git status --porcelain -uall` (gd-369) lists
|
|
235
|
+
// every untracked file individually, so a repo with a big new/untracked tree can
|
|
236
|
+
// blow past execSync's default 1 MB buffer — which would throw and silently
|
|
237
|
+
// return '' (an EMPTY snapshot, worse than the collapsed view). 64 MB is plenty.
|
|
238
|
+
const GIT_MAX_BUFFER = 64 * 1024 * 1024
|
|
239
|
+
|
|
240
|
+
// Cap for synthesising an untracked file's full-content diff (gd-370) — above
|
|
241
|
+
// this the file keeps the "no diff" placeholder so a huge/binary blob can't
|
|
242
|
+
// bloat the snapshot payload.
|
|
243
|
+
const UNTRACKED_DIFF_MAX_BYTES = 1024 * 1024
|
|
244
|
+
|
|
234
245
|
function git(cmd, cwd) {
|
|
235
246
|
try {
|
|
236
|
-
return execSync(cmd, { cwd, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim()
|
|
247
|
+
return execSync(cmd, { cwd, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'], maxBuffer: GIT_MAX_BUFFER }).trim()
|
|
237
248
|
} catch {
|
|
238
249
|
return ''
|
|
239
250
|
}
|
|
@@ -245,12 +256,28 @@ function git(cmd, cwd) {
|
|
|
245
256
|
// (gd-276). Callers decode per-file via decodeDiffText().
|
|
246
257
|
function gitRaw(cmd, cwd) {
|
|
247
258
|
try {
|
|
248
|
-
return execSync(cmd, { cwd, encoding: 'buffer', stdio: ['pipe', 'pipe', 'pipe'] })
|
|
259
|
+
return execSync(cmd, { cwd, encoding: 'buffer', stdio: ['pipe', 'pipe', 'pipe'], maxBuffer: GIT_MAX_BUFFER })
|
|
249
260
|
} catch {
|
|
250
261
|
return Buffer.alloc(0)
|
|
251
262
|
}
|
|
252
263
|
}
|
|
253
264
|
|
|
265
|
+
// Full-content diff of a single UNTRACKED file (against /dev/null), so the
|
|
266
|
+
// console can show a new file's whole content as an all-added diff — like
|
|
267
|
+
// GitHub Desktop (gd-370). Uses execFileSync (argv, no shell) so paths with
|
|
268
|
+
// spaces / Cyrillic reach git intact, unlike a shell command string. `--no-index`
|
|
269
|
+
// exits 1 when the file differs from empty (i.e. always) — that's expected, and
|
|
270
|
+
// its stdout still holds the diff. Returns raw bytes for parseDiffByFile.
|
|
271
|
+
function gitDiffUntracked(file, cwd) {
|
|
272
|
+
try {
|
|
273
|
+
return execFileSync('git', ['diff', '--no-index', '--', '/dev/null', file], {
|
|
274
|
+
cwd, encoding: 'buffer', stdio: ['pipe', 'pipe', 'pipe'], maxBuffer: GIT_MAX_BUFFER,
|
|
275
|
+
})
|
|
276
|
+
} catch (err) {
|
|
277
|
+
return err && err.stdout && err.stdout.length ? err.stdout : Buffer.alloc(0)
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
254
281
|
// Like git(), but surfaces failures (with stderr) instead of swallowing them —
|
|
255
282
|
// used for push/pull where we need to detect auth rejection.
|
|
256
283
|
function gitTry(cmd, cwd) {
|
|
@@ -461,7 +488,10 @@ function parseDiffByFile(diffBuf) {
|
|
|
461
488
|
function getSnapshot(repoPath) {
|
|
462
489
|
const branch = git('git branch --show-current', repoPath) || 'HEAD'
|
|
463
490
|
|
|
464
|
-
|
|
491
|
+
// -uall lists every untracked file individually instead of collapsing a new
|
|
492
|
+
// directory into a single `dir/` entry — so the change list matches what
|
|
493
|
+
// GitHub Desktop shows, file-for-file (gd-369).
|
|
494
|
+
const statusLines = git('git status --porcelain -uall', repoPath).split('\n').filter(Boolean)
|
|
465
495
|
const modified = []
|
|
466
496
|
const staged = []
|
|
467
497
|
const statuses = {}
|
|
@@ -485,6 +515,22 @@ function getSnapshot(repoPath) {
|
|
|
485
515
|
|
|
486
516
|
const diffs = parseDiffByFile(gitRaw('git diff HEAD', repoPath))
|
|
487
517
|
|
|
518
|
+
// Untracked files (`??`) aren't in `git diff HEAD`, so they had no content to
|
|
519
|
+
// show ("Нов или untracked файл — няма diff"). Synthesise an all-added diff for
|
|
520
|
+
// each from /dev/null so the console shows the whole new file — like GitHub
|
|
521
|
+
// Desktop (gd-370). Skip anything over the size cap so a stray big/binary blob
|
|
522
|
+
// can't bloat the snapshot; those keep the "no diff" placeholder.
|
|
523
|
+
for (const [file, xy] of Object.entries(statuses)) {
|
|
524
|
+
if (xy !== '??' || diffs[file]) continue
|
|
525
|
+
try {
|
|
526
|
+
const st = statSync(join(repoPath, file))
|
|
527
|
+
if (!st.isFile() || st.size > UNTRACKED_DIFF_MAX_BYTES) continue
|
|
528
|
+
} catch { continue }
|
|
529
|
+
const parsed = parseDiffByFile(gitDiffUntracked(file, repoPath))
|
|
530
|
+
const val = parsed[file] ?? Object.values(parsed)[0]
|
|
531
|
+
if (val) diffs[file] = val
|
|
532
|
+
}
|
|
533
|
+
|
|
488
534
|
// Origin remote → lets the server auto-detect the GitHub repo for the History tab.
|
|
489
535
|
const remoteUrl = git('git config --get remote.origin.url', repoPath) || null
|
|
490
536
|
|