gitdone-agent 0.6.11 → 0.6.13
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 +59 -3
- 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.13'
|
|
31
31
|
|
|
32
32
|
const AGENT_DIR = join(homedir(), '.gitdone-agent')
|
|
33
33
|
const CONFIG_PATH = join(AGENT_DIR, 'config.json')
|
|
@@ -237,6 +237,22 @@ function runDoctor() {
|
|
|
237
237
|
// return '' (an EMPTY snapshot, worse than the collapsed view). 64 MB is plenty.
|
|
238
238
|
const GIT_MAX_BUFFER = 64 * 1024 * 1024
|
|
239
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
|
+
|
|
245
|
+
// Synthesising a per-file diff spawns a synchronous `git diff --no-index` per
|
|
246
|
+
// untracked file. Individually cheap, but a repo with a huge untracked/scratch
|
|
247
|
+
// tree (e.g. extracted game assets — thousands of files) would spawn thousands
|
|
248
|
+
// of blocking git processes and freeze the single-threaded agent for MINUTES on
|
|
249
|
+
// every snapshot, starving the 30s sync heartbeat so the machine flips offline.
|
|
250
|
+
// Bound the synthesis two ways — a file-count cap and a wall-clock budget — so
|
|
251
|
+
// no single repo can ever monopolise the event loop. Anything past either keeps
|
|
252
|
+
// the "no diff" placeholder, identical to the size-cap path above.
|
|
253
|
+
const UNTRACKED_DIFF_MAX_FILES = 200
|
|
254
|
+
const UNTRACKED_DIFF_TIME_BUDGET_MS = 3000
|
|
255
|
+
|
|
240
256
|
function git(cmd, cwd) {
|
|
241
257
|
try {
|
|
242
258
|
return execSync(cmd, { cwd, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'], maxBuffer: GIT_MAX_BUFFER }).trim()
|
|
@@ -257,6 +273,22 @@ function gitRaw(cmd, cwd) {
|
|
|
257
273
|
}
|
|
258
274
|
}
|
|
259
275
|
|
|
276
|
+
// Full-content diff of a single UNTRACKED file (against /dev/null), so the
|
|
277
|
+
// console can show a new file's whole content as an all-added diff — like
|
|
278
|
+
// GitHub Desktop (gd-370). Uses execFileSync (argv, no shell) so paths with
|
|
279
|
+
// spaces / Cyrillic reach git intact, unlike a shell command string. `--no-index`
|
|
280
|
+
// exits 1 when the file differs from empty (i.e. always) — that's expected, and
|
|
281
|
+
// its stdout still holds the diff. Returns raw bytes for parseDiffByFile.
|
|
282
|
+
function gitDiffUntracked(file, cwd) {
|
|
283
|
+
try {
|
|
284
|
+
return execFileSync('git', ['diff', '--no-index', '--', '/dev/null', file], {
|
|
285
|
+
cwd, encoding: 'buffer', stdio: ['pipe', 'pipe', 'pipe'], maxBuffer: GIT_MAX_BUFFER,
|
|
286
|
+
})
|
|
287
|
+
} catch (err) {
|
|
288
|
+
return err && err.stdout && err.stdout.length ? err.stdout : Buffer.alloc(0)
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
260
292
|
// Like git(), but surfaces failures (with stderr) instead of swallowing them —
|
|
261
293
|
// used for push/pull where we need to detect auth rejection.
|
|
262
294
|
function gitTry(cmd, cwd) {
|
|
@@ -494,6 +526,30 @@ function getSnapshot(repoPath) {
|
|
|
494
526
|
|
|
495
527
|
const diffs = parseDiffByFile(gitRaw('git diff HEAD', repoPath))
|
|
496
528
|
|
|
529
|
+
// Untracked files (`??`) aren't in `git diff HEAD`, so they had no content to
|
|
530
|
+
// show ("Нов или untracked файл — няма diff"). Synthesise an all-added diff for
|
|
531
|
+
// each from /dev/null so the console shows the whole new file — like GitHub
|
|
532
|
+
// Desktop (gd-370). Skip anything over the size cap so a stray big/binary blob
|
|
533
|
+
// can't bloat the snapshot; those keep the "no diff" placeholder.
|
|
534
|
+
const untracked = Object.keys(statuses).filter((f) => statuses[f] === '??' && !diffs[f])
|
|
535
|
+
const diffDeadline = Date.now() + UNTRACKED_DIFF_TIME_BUDGET_MS
|
|
536
|
+
let synthesised = 0
|
|
537
|
+
for (const file of untracked) {
|
|
538
|
+
// Stop before either bound so a scratch tree can't starve the heartbeat; the
|
|
539
|
+
// rest keep the "no diff" placeholder. Log once so it's visible why.
|
|
540
|
+
if (synthesised >= UNTRACKED_DIFF_MAX_FILES || Date.now() > diffDeadline) {
|
|
541
|
+
log(`⚠ untracked diff cap reached @ ${repoPath} (${synthesised}/${untracked.length} synthesised) — rest shown without preview`)
|
|
542
|
+
break
|
|
543
|
+
}
|
|
544
|
+
let st
|
|
545
|
+
try { st = statSync(join(repoPath, file)) } catch { continue }
|
|
546
|
+
if (!st.isFile() || st.size > UNTRACKED_DIFF_MAX_BYTES) continue
|
|
547
|
+
synthesised++
|
|
548
|
+
const parsed = parseDiffByFile(gitDiffUntracked(file, repoPath))
|
|
549
|
+
const val = parsed[file] ?? Object.values(parsed)[0]
|
|
550
|
+
if (val) diffs[file] = val
|
|
551
|
+
}
|
|
552
|
+
|
|
497
553
|
// Origin remote → lets the server auto-detect the GitHub repo for the History tab.
|
|
498
554
|
const remoteUrl = git('git config --get remote.origin.url', repoPath) || null
|
|
499
555
|
|