@forgecart/cli 2.202610102045.0 → 2.202610110825.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 (50) hide show
  1. package/dist/src/authorization/cli-unauthorized-refusal.d.ts +10 -4
  2. package/dist/src/authorization/cli-unauthorized-refusal.js +11 -3
  3. package/dist/src/authorization/cli-unauthorized-refusal.js.map +1 -1
  4. package/dist/src/cli.js +4 -0
  5. package/dist/src/cli.js.map +1 -1
  6. package/dist/src/commands/init.js +5 -47
  7. package/dist/src/commands/init.js.map +1 -1
  8. package/dist/src/commands/sync.d.ts +14 -0
  9. package/dist/src/commands/sync.js +49 -0
  10. package/dist/src/commands/sync.js.map +1 -0
  11. package/dist/src/exit-ladder.d.ts +8 -1
  12. package/dist/src/exit-ladder.js +7 -0
  13. package/dist/src/exit-ladder.js.map +1 -1
  14. package/dist/src/sync/sync-api.error.d.ts +15 -0
  15. package/dist/src/sync/sync-api.error.js +26 -0
  16. package/dist/src/sync/sync-api.error.js.map +1 -0
  17. package/dist/src/sync/sync-divergence.d.ts +43 -0
  18. package/dist/src/sync/sync-divergence.js +104 -0
  19. package/dist/src/sync/sync-divergence.js.map +1 -0
  20. package/dist/src/sync/sync-dotenv.file.d.ts +36 -0
  21. package/dist/src/sync/sync-dotenv.file.js +95 -0
  22. package/dist/src/sync/sync-dotenv.file.js.map +1 -0
  23. package/dist/src/sync/sync-env.runner.d.ts +29 -0
  24. package/dist/src/sync/sync-env.runner.js +95 -0
  25. package/dist/src/sync/sync-env.runner.js.map +1 -0
  26. package/dist/src/sync/sync-record.file.d.ts +28 -0
  27. package/dist/src/sync/sync-record.file.js +86 -0
  28. package/dist/src/sync/sync-record.file.js.map +1 -0
  29. package/dist/src/sync/sync-repository.d.ts +110 -0
  30. package/dist/src/sync/sync-repository.js +396 -0
  31. package/dist/src/sync/sync-repository.js.map +1 -0
  32. package/dist/src/sync/sync-round.d.ts +95 -0
  33. package/dist/src/sync/sync-round.js +355 -0
  34. package/dist/src/sync/sync-round.js.map +1 -0
  35. package/dist/src/sync/sync-watch.d.ts +48 -0
  36. package/dist/src/sync/sync-watch.js +144 -0
  37. package/dist/src/sync/sync-watch.js.map +1 -0
  38. package/dist/src/sync/sync.runner.d.ts +37 -0
  39. package/dist/src/sync/sync.runner.js +121 -0
  40. package/dist/src/sync/sync.runner.js.map +1 -0
  41. package/dist/src/sync/type/sync.types.d.ts +159 -0
  42. package/dist/src/sync/type/sync.types.js +30 -0
  43. package/dist/src/sync/type/sync.types.js.map +1 -0
  44. package/dist/src/sync/workspace-sync.client.d.ts +85 -0
  45. package/dist/src/sync/workspace-sync.client.js +317 -0
  46. package/dist/src/sync/workspace-sync.client.js.map +1 -0
  47. package/dist/src/util/dotenv.util.d.ts +28 -0
  48. package/dist/src/util/dotenv.util.js +81 -0
  49. package/dist/src/util/dotenv.util.js.map +1 -0
  50. package/package.json +1 -1
@@ -0,0 +1,396 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { access, mkdir, readdir, readFile, rm, rmdir, writeFile } from 'node:fs/promises';
4
+ import { dirname, join } from 'node:path';
5
+ import { CliExitLadder, CliRefusal } from '../exit-ladder.js';
6
+ import { SyncChangeKind } from './type/sync.types.js';
7
+ /** Where sync keeps its private state, under the storefront's `.forgecart/` — which never travels. */
8
+ export const SYNC_STATE_PATH = ['.forgecart', 'sync'];
9
+ /** The private repository, and the index the laptop's tree is snapshotted into. */
10
+ const REPOSITORY_DIR = 'board.git';
11
+ const INDEX_FILE = 'sync.index';
12
+ /**
13
+ * The global config every git run reads: a file that is never written, so the
14
+ * merchant's own `~/.gitconfig` — an `autocrlf`, a global excludes file — can
15
+ * never change what travels.
16
+ */
17
+ const NO_GLOBAL_CONFIG_FILE = 'no-global.config';
18
+ /** The ref the serving branch is fetched into, and the ref keeping the recorded base reachable. */
19
+ const FETCHED_SERVING_REF = 'refs/sync/serving';
20
+ const BASE_REF = 'refs/sync/base';
21
+ /** The one ref a push bundle carries — the name the pod admits. */
22
+ const PUSH_REF = 'refs/heads/serving';
23
+ /** The carrier commit's message: the pod mints the landed commit itself. */
24
+ const PUSH_MESSAGE = 'forgecart sync';
25
+ /** The top-level entry of the serving tree that never travels: the platform's `.forgecart/`. */
26
+ const PLATFORM_DIR = '.forgecart';
27
+ /**
28
+ * What never travels: the laptop's `.forgecart/`, and every path the board's
29
+ * runtime ignore authority keeps out of serving history (the pod's
30
+ * `info/exclude`) — installed and generated trees, the platform's islands and
31
+ * every `.env`.
32
+ */
33
+ const EXCLUDE_PATTERNS = [
34
+ `/${PLATFORM_DIR}/`,
35
+ '.forge/',
36
+ 'node_modules/',
37
+ '.next/',
38
+ '.git/',
39
+ 'repos/',
40
+ '.env',
41
+ '.env.*',
42
+ '*.tsbuildinfo',
43
+ 'next-env.d.ts',
44
+ '.npm/',
45
+ '.worktrees/',
46
+ ];
47
+ /** The private state directory's own ignore file: a merchant's repository never tracks any of it. */
48
+ const STATE_DIR_GITIGNORE = '*\n';
49
+ /** The status letters `git diff-tree` names a change with, as the change kinds sync reads. */
50
+ const CHANGE_KINDS = new Map(Object.values(SyncChangeKind).map((kind) => [kind, kind]));
51
+ /** The largest output one git run may hand back — a tree listing or a bundle path list. */
52
+ const GIT_OUTPUT_LIMIT_BYTES = 256 * 1024 * 1024;
53
+ /**
54
+ * The laptop's side of `forgecart sync` (#2781): a private bare git repository
55
+ * under `.forgecart/sync/`, its work tree the storefront. It snapshots the
56
+ * laptop's tree into its own index — the paths the board would carry, nothing
57
+ * the runtime keeps out of serving history — holds the serving commits the
58
+ * pulled bundles bring, writes a serving tree onto the laptop, and cuts the ONE
59
+ * commit a push sends as a git bundle on the serving tip.
60
+ *
61
+ * Every git run reads no system and no global config, and no `GIT_*` variable
62
+ * of the caller's: what travels never depends on the machine it runs on. The
63
+ * merchant's own repository, if the storefront is one, is never read or
64
+ * written.
65
+ */
66
+ export class SyncRepository {
67
+ storefront;
68
+ stateDir;
69
+ gitDir;
70
+ constructor(storefront) {
71
+ this.storefront = storefront;
72
+ this.stateDir = join(storefront, ...SYNC_STATE_PATH);
73
+ this.gitDir = join(this.stateDir, REPOSITORY_DIR);
74
+ }
75
+ /**
76
+ * `git` must be on the PATH: sync keeps the laptop's tree in a git repository
77
+ * and moves it as git bundles. Refused by name, on exit 1.
78
+ */
79
+ static async assertGitOnPath() {
80
+ const found = await new Promise((resolve) => {
81
+ // eslint-disable-next-line sonarjs/no-os-command-from-path -- the merchant's own `git`, resolved from the PATH of the machine sync runs on; its install path is not portable
82
+ const child = spawn('git', ['--version'], { stdio: 'ignore' });
83
+ child.on('error', () => {
84
+ resolve(false);
85
+ });
86
+ child.on('close', (status) => {
87
+ resolve(status === 0);
88
+ });
89
+ });
90
+ if (found)
91
+ return;
92
+ throw new CliRefusal(CliExitLadder.error, [
93
+ 'git is not on the PATH: sync keeps this storefront in a private git repository under .forgecart/sync and moves it as git bundles. Install git and re-run.',
94
+ ]);
95
+ }
96
+ /**
97
+ * Create the private repository on first use, and (re)write the paths that
98
+ * never travel. `git init --bare` refuses a work tree, so it alone runs
99
+ * without the repository's own environment.
100
+ */
101
+ async prepare() {
102
+ await mkdir(this.stateDir, { recursive: true });
103
+ await writeFile(join(this.stateDir, '.gitignore'), STATE_DIR_GITIGNORE, 'utf8');
104
+ if (!(await this.exists(join(this.gitDir, 'HEAD')))) {
105
+ const args = ['init', '--bare', '--quiet', this.gitDir];
106
+ this.assertSucceeded(args, await this.spawnGit(args, this.isolatedEnv(), {}));
107
+ }
108
+ await mkdir(join(this.gitDir, 'info'), { recursive: true });
109
+ await writeFile(this.excludeFile(), `${EXCLUDE_PATTERNS.join('\n')}\n`, 'utf8');
110
+ }
111
+ /** The laptop's tree as it stands — every path that travels — written into the private index. */
112
+ async snapshot() {
113
+ await this.git(['add', '--all', '--', '.']);
114
+ return this.line(await this.git(['write-tree']));
115
+ }
116
+ /** Whether the private repository holds `sha` as a commit. */
117
+ async hasCommit(sha) {
118
+ const run = await this.git(['cat-file', '-e', `${sha}^{commit}`], { allowFailure: true });
119
+ return run.status === 0;
120
+ }
121
+ /** The tree with no entry — the base of a first sync. */
122
+ async emptyTree() {
123
+ return this.line(await this.git(['mktree', '-z'], { input: '' }));
124
+ }
125
+ /**
126
+ * Take a pulled bundle's serving branch into the private repository — git's
127
+ * own fetch from the bundle file, which checks every object it admits — and
128
+ * answer the serving commit it carried. The bundle file lives only as long
129
+ * as the fetch.
130
+ */
131
+ async fetchBundle(bytes) {
132
+ const bundlePath = this.spoolPath('pull');
133
+ await writeFile(bundlePath, bytes);
134
+ try {
135
+ await this.git([
136
+ '-c',
137
+ 'fetch.fsckObjects=true',
138
+ 'fetch',
139
+ '--quiet',
140
+ '--no-tags',
141
+ bundlePath,
142
+ `+refs/heads/serving:${FETCHED_SERVING_REF}`,
143
+ ]);
144
+ return this.line(await this.git(['rev-parse', '--verify', `${FETCHED_SERVING_REF}^{commit}`]));
145
+ }
146
+ finally {
147
+ await rm(bundlePath, { force: true });
148
+ }
149
+ }
150
+ /** Keep `sha` — the recorded base — reachable whatever the serving branch does next. */
151
+ async keepBase(sha) {
152
+ await this.git(['update-ref', BASE_REF, sha]);
153
+ }
154
+ /** The tree of `commit` that travels: its own, without the platform's `.forgecart/`. */
155
+ async travellingTree(commit) {
156
+ const entries = await this.topLevelEntries(`${commit}^{tree}`);
157
+ return this.makeTree(entries.filter((entry) => this.entryName(entry) !== PLATFORM_DIR));
158
+ }
159
+ /** The paths `to` changes against `from`, path by path. */
160
+ async changes(from, to) {
161
+ const run = await this.git(['diff-tree', '-r', '-z', '--no-renames', from, to]);
162
+ const fields = run.stdout.split('\0');
163
+ const changes = [];
164
+ for (let index = 0; index + 1 < fields.length; index += 2) {
165
+ changes.push({ kind: this.changeKind(fields[index]), path: fields[index + 1] });
166
+ }
167
+ return changes;
168
+ }
169
+ /**
170
+ * Write the tree `to` onto the laptop, standing at `from`: every path `from`
171
+ * holds and `to` does not is removed, every path `to` adds or changes is
172
+ * written, and nothing else on the laptop — no ignored file, nothing that
173
+ * never travels — is touched. The private index then holds `to`, so every
174
+ * path of it stays tracked whatever the laptop's ignore rules say.
175
+ */
176
+ async materialize(from, to) {
177
+ const changes = await this.changes(from, to);
178
+ const removed = changes.filter((change) => change.kind === SyncChangeKind.DELETED);
179
+ const written = changes.filter((change) => change.kind !== SyncChangeKind.DELETED);
180
+ for (const change of removed) {
181
+ await this.removePath(change.path);
182
+ }
183
+ await this.checkOut(to, written.map((change) => change.path));
184
+ await this.git(['read-tree', to]);
185
+ return { written: written.length, removed: removed.length };
186
+ }
187
+ /**
188
+ * The ONE commit a push sends: the laptop's tree on the serving tip `serving`,
189
+ * keeping the platform's `.forgecart/` the serving tree carries — the laptop's
190
+ * own never travels.
191
+ */
192
+ async pushCommit(localTree, serving) {
193
+ const local = await this.topLevelEntries(localTree);
194
+ const platform = (await this.topLevelEntries(`${serving}^{tree}`)).filter((entry) => this.entryName(entry) === PLATFORM_DIR);
195
+ const tree = await this.makeTree([...local, ...platform]);
196
+ return this.line(await this.git(['commit-tree', tree, '-p', serving, '-m', PUSH_MESSAGE]));
197
+ }
198
+ /**
199
+ * `commit` as the git bundle a push sends: its one ref `refs/heads/serving`,
200
+ * its one prerequisite the serving tip `serving` it was cut on.
201
+ */
202
+ async pushBundle(commit, serving) {
203
+ await this.git(['update-ref', PUSH_REF, commit]);
204
+ const bundlePath = this.spoolPath('push');
205
+ try {
206
+ await this.git(['bundle', 'create', bundlePath, PUSH_REF, `^${serving}`]);
207
+ return await readFile(bundlePath);
208
+ }
209
+ finally {
210
+ await rm(bundlePath, { force: true });
211
+ }
212
+ }
213
+ /** The top-level entries of `tree`, in `ls-tree -z` form — the form `mktree -z` reads back. */
214
+ async topLevelEntries(tree) {
215
+ const run = await this.git(['ls-tree', '-z', tree]);
216
+ return run.stdout.split('\0').filter((entry) => entry !== '');
217
+ }
218
+ async makeTree(entries) {
219
+ const input = entries.map((entry) => `${entry}\0`).join('');
220
+ return this.line(await this.git(['mktree', '-z'], { input }));
221
+ }
222
+ /** An `ls-tree` entry's name: everything after its tab. */
223
+ entryName(entry) {
224
+ return entry.slice(entry.indexOf('\t') + 1);
225
+ }
226
+ /** A `diff-tree -z` record's status letter — the last word of its metadata. */
227
+ changeKind(metadata) {
228
+ const status = metadata.slice(metadata.lastIndexOf(' ') + 1);
229
+ const kind = CHANGE_KINDS.get(status);
230
+ if (kind === undefined) {
231
+ throw new Error(`git diff-tree answered a change sync cannot read: "${metadata}".`);
232
+ }
233
+ return kind;
234
+ }
235
+ /** Write `paths` of `tree` onto the laptop, replacing what stands there — through an index of its own. */
236
+ async checkOut(tree, paths) {
237
+ if (paths.length === 0)
238
+ return;
239
+ const indexFile = join(this.gitDir, `checkout-${randomUUID()}.index`);
240
+ try {
241
+ await this.git(['read-tree', tree], { indexFile });
242
+ await this.git(['checkout-index', '--force', '-z', '--stdin'], {
243
+ indexFile,
244
+ input: paths.map((path) => `${path}\0`).join(''),
245
+ });
246
+ }
247
+ finally {
248
+ await rm(indexFile, { force: true });
249
+ }
250
+ }
251
+ /** Remove one file the laptop holds, and every directory the removal leaves empty. */
252
+ async removePath(relativePath) {
253
+ await rm(join(this.storefront, relativePath), { force: true });
254
+ for (let parent = dirname(relativePath); parent !== '.'; parent = dirname(parent)) {
255
+ const directory = join(this.storefront, parent);
256
+ const entries = await this.entriesOf(directory);
257
+ if (entries === null || entries.length > 0)
258
+ return;
259
+ await rmdir(directory);
260
+ }
261
+ }
262
+ /** A directory's entries — null when it is gone. */
263
+ async entriesOf(directory) {
264
+ try {
265
+ return await readdir(directory);
266
+ }
267
+ catch (error) {
268
+ if (error.code === 'ENOENT')
269
+ return null;
270
+ throw error;
271
+ }
272
+ }
273
+ async exists(path) {
274
+ try {
275
+ await access(path);
276
+ return true;
277
+ }
278
+ catch {
279
+ return false;
280
+ }
281
+ }
282
+ /** A fresh bundle path in the private state directory, alive for one transfer. */
283
+ spoolPath(purpose) {
284
+ return join(this.stateDir, `${purpose}-${randomUUID()}.bundle`);
285
+ }
286
+ excludeFile() {
287
+ return join(this.gitDir, 'info', 'exclude');
288
+ }
289
+ /** A one-line answer — an object id — without its newline. */
290
+ line(run) {
291
+ return run.stdout.trim();
292
+ }
293
+ /**
294
+ * Run git on the private repository, the storefront its work tree. A non-zero
295
+ * exit is an error naming the command and git's own words — unless the
296
+ * caller reads it as an answer.
297
+ */
298
+ async git(args, options = {}) {
299
+ const env = this.repositoryEnv(options.indexFile ?? join(this.gitDir, INDEX_FILE));
300
+ const run = await this.spawnGit([...this.gitFlags(), ...args], env, options);
301
+ if (options.allowFailure !== true)
302
+ this.assertSucceeded(args, run);
303
+ return run;
304
+ }
305
+ /** A git run that exited non-zero is an error naming the command and git's own words. */
306
+ assertSucceeded(args, run) {
307
+ if (run.status === 0)
308
+ return;
309
+ throw new Error(`git ${args.join(' ')} failed in ${this.storefront} (exit ${String(run.status)}): ${run.stderr.trim()}`);
310
+ }
311
+ async spawnGit(args, env, options) {
312
+ return new Promise((resolve, reject) => {
313
+ // eslint-disable-next-line sonarjs/no-os-command-from-path -- the merchant's own `git`, resolved from the PATH of the machine sync runs on; its install path is not portable
314
+ const child = spawn('git', args, {
315
+ cwd: this.storefront,
316
+ env,
317
+ stdio: ['pipe', 'pipe', 'pipe'],
318
+ });
319
+ const stdout = [];
320
+ const stderr = [];
321
+ let size = 0;
322
+ child.stdout.on('data', (chunk) => {
323
+ size += chunk.length;
324
+ if (size > GIT_OUTPUT_LIMIT_BYTES) {
325
+ child.kill();
326
+ return;
327
+ }
328
+ stdout.push(chunk);
329
+ });
330
+ child.stderr.on('data', (chunk) => {
331
+ stderr.push(chunk);
332
+ });
333
+ child.on('error', reject);
334
+ child.on('close', (status) => {
335
+ resolve({
336
+ status: status ?? -1,
337
+ stdout: Buffer.concat(stdout).toString('utf8'),
338
+ stderr: Buffer.concat(stderr).toString('utf8'),
339
+ });
340
+ });
341
+ child.stdin.on('error', () => {
342
+ // A git that stops reading its input has exited: its status and its
343
+ // stderr, read on `close`, say why.
344
+ });
345
+ child.stdin.end(options.input ?? '');
346
+ });
347
+ }
348
+ /**
349
+ * The flags every run carries: byte-exact content, the work tree the bare
350
+ * repository is given, the paths that never travel as the only excludes
351
+ * besides the storefront's own `.gitignore`, and an identity for the carrier
352
+ * commit.
353
+ */
354
+ gitFlags() {
355
+ return [
356
+ '-c',
357
+ 'core.autocrlf=false',
358
+ '-c',
359
+ 'core.safecrlf=false',
360
+ '-c',
361
+ 'core.quotepath=false',
362
+ '-c',
363
+ 'core.bare=false',
364
+ '-c',
365
+ `core.excludesFile=${this.excludeFile()}`,
366
+ '-c',
367
+ 'gc.auto=0',
368
+ '-c',
369
+ 'commit.gpgsign=false',
370
+ '-c',
371
+ 'user.name=forgecart sync',
372
+ '-c',
373
+ 'user.email=sync@forgecart.local',
374
+ ];
375
+ }
376
+ /** The repository's environment: the private repository, the storefront as its work tree, and `indexFile`. */
377
+ repositoryEnv(indexFile) {
378
+ return {
379
+ ...this.isolatedEnv(),
380
+ GIT_DIR: this.gitDir,
381
+ GIT_WORK_TREE: this.storefront,
382
+ GIT_INDEX_FILE: indexFile,
383
+ };
384
+ }
385
+ /** The caller's environment without any `GIT_*` variable, reading no system and no global config. */
386
+ isolatedEnv() {
387
+ const inherited = Object.entries(process.env).filter(([key]) => !key.startsWith('GIT_'));
388
+ return {
389
+ ...Object.fromEntries(inherited),
390
+ GIT_CONFIG_NOSYSTEM: '1',
391
+ GIT_CONFIG_GLOBAL: join(this.stateDir, NO_GLOBAL_CONFIG_FILE),
392
+ GIT_TERMINAL_PROMPT: '0',
393
+ };
394
+ }
395
+ }
396
+ //# sourceMappingURL=sync-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-repository.js","sourceRoot":"","sources":["../../../src/sync/sync-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ import type { CliCredentials } from '../authorization/type/cli-authorization.types.js';
2
+ import { type SyncDivergenceSelection } from './sync-divergence.js';
3
+ import type { SyncDotenvFile } from './sync-dotenv.file.js';
4
+ import type { SyncRecordFile } from './sync-record.file.js';
5
+ import type { SyncRepository } from './sync-repository.js';
6
+ import { type SyncRoundEnd, type SyncRoundOptions } from './type/sync.types.js';
7
+ import type { WorkspaceSyncClient } from './workspace-sync.client.js';
8
+ /**
9
+ * One round of `forgecart sync` (#2781): read the board's serving commit,
10
+ * snapshot the laptop's tree, hold the serving tree locally, print the plan
11
+ * ONCE, and move what it says — the laptop's tree and the serving tree are the
12
+ * same tree when it ends, or nothing moved.
13
+ *
14
+ * Both sides are compared against the base — the serving commit the laptop
15
+ * last matched. Only the workspace changed: its tree is written onto the
16
+ * laptop. Only the laptop changed: its tree is committed on the serving tip and
17
+ * pushed as ONE git bundle, which the pod lands through its promote pipeline or
18
+ * rejects with the gates' diagnostics (exit 1). Both changed: ONE selection —
19
+ * local overrides workspace, workspace overrides local, or Abort — never a
20
+ * merge; an abort or an unanswered selection ends the run on exit 4. The
21
+ * merchant lines of `.env` travel with the tree; the platform's keys never do.
22
+ */
23
+ export declare class SyncRound {
24
+ private readonly options;
25
+ private readonly credentials;
26
+ private readonly client;
27
+ private readonly repository;
28
+ private readonly records;
29
+ private readonly dotenv;
30
+ private readonly selection;
31
+ constructor(options: SyncRoundOptions, credentials: CliCredentials, client: WorkspaceSyncClient, repository: SyncRepository, records: SyncRecordFile, dotenv: SyncDotenvFile, selection: SyncDivergenceSelection);
32
+ /** Run the round; a board that moves under its push is read again, a bounded number of times. */
33
+ run(): Promise<SyncRoundEnd>;
34
+ private attempt;
35
+ /** Decide, print the plan once, and move what it says. */
36
+ private settle;
37
+ private verdictOf;
38
+ /** The two trees agree: record where they stand, and send `.env` lines the laptop changed. */
39
+ private inSync;
40
+ /** Only the workspace changed — or it overrides the laptop: its tree and its `.env` lines land on the laptop. */
41
+ private pull;
42
+ /** Only the laptop changed, and the run never pushes: nothing moves. */
43
+ private keepLocal;
44
+ /**
45
+ * Push the laptop's tree onto the serving tip — or over it, when local
46
+ * overrides workspace — as ONE commit in ONE bundle, with the changed `.env`
47
+ * lines. A tree the gates reject ends the run on exit 1 with their
48
+ * diagnostics; a board that moved before the push landed is read again.
49
+ */
50
+ private land;
51
+ /** Both sides changed: the selection decides which tree wins, or the run stops with nothing moved. */
52
+ private diverged;
53
+ /** The divergence in words, as its refusal prints it. */
54
+ private divergenceLines;
55
+ /**
56
+ * `--dry-run`: the plan, and every path a push would send — from the record
57
+ * and the serving commit alone, so the one read of the serving commit is all
58
+ * that leaves the machine. Nothing moves on either side.
59
+ */
60
+ private dryRun;
61
+ private dryVerdict;
62
+ /** The plan, printed once per round before anything moves. */
63
+ private printPlan;
64
+ /** The `.env` keys the plan carries, as a count. */
65
+ private envPlan;
66
+ private printChanges;
67
+ /** The record — when the private repository still holds its base; else a first sync. */
68
+ private heldRecord;
69
+ /** The serving commit, held in the private repository — fetched as a bundle unless it already is. */
70
+ private holdServing;
71
+ /**
72
+ * The bundle a pull reads: the serving commits since the recorded base when
73
+ * there is one, the whole board otherwise — or when the workspace cannot cut
74
+ * that delta. Which one is printed.
75
+ */
76
+ private pulledBundle;
77
+ /** The commit a push landed, held locally so the next round compares against it. */
78
+ private holdLanded;
79
+ /** The push, or null when the board moved past the commit it was cut on before it landed. */
80
+ private sendPush;
81
+ /** A push the workspace did not take: exit 1, with what refused it. */
82
+ private rejection;
83
+ /** The `.env` lines a round in sync sends alone — none for a run that never pushes. */
84
+ private sendEnvAlone;
85
+ /** The workspace's `.env` lines, taken — none when no bundle was read this round. */
86
+ private takeEnv;
87
+ private viewOf;
88
+ /** The travelling tree of the recorded base — the empty tree before a first sync. */
89
+ private baseOf;
90
+ /** Record that the laptop stands on `servingSha`, and keep that commit held. */
91
+ private record;
92
+ private settled;
93
+ private lastSync;
94
+ private short;
95
+ }