spidersan 0.20.1 → 0.20.2
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/CHANGELOG.md +8 -0
- package/dist/bin/command-registry.d.ts +25 -0
- package/dist/bin/command-registry.d.ts.map +1 -0
- package/dist/bin/command-registry.js +29 -0
- package/dist/bin/command-registry.js.map +1 -0
- package/dist/bin/spidersan.d.ts +16 -0
- package/dist/bin/spidersan.d.ts.map +1 -0
- package/dist/bin/spidersan.js +98 -0
- package/dist/bin/spidersan.js.map +1 -0
- package/dist/commands/abandon.d.ts +8 -0
- package/dist/commands/abandon.d.ts.map +1 -0
- package/dist/commands/abandon.js +43 -0
- package/dist/commands/abandon.js.map +1 -0
- package/dist/commands/cleanup.d.ts +8 -0
- package/dist/commands/cleanup.d.ts.map +1 -0
- package/dist/commands/cleanup.js +50 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/config.d.ts +15 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +309 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/conflicts.d.ts +34 -0
- package/dist/commands/conflicts.d.ts.map +1 -0
- package/dist/commands/conflicts.js +773 -0
- package/dist/commands/conflicts.js.map +1 -0
- package/dist/commands/context.d.ts +8 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +104 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/cross-conflicts.d.ts +17 -0
- package/dist/commands/cross-conflicts.d.ts.map +1 -0
- package/dist/commands/cross-conflicts.js +273 -0
- package/dist/commands/cross-conflicts.js.map +1 -0
- package/dist/commands/depends.d.ts +11 -0
- package/dist/commands/depends.d.ts.map +1 -0
- package/dist/commands/depends.js +63 -0
- package/dist/commands/depends.js.map +1 -0
- package/dist/commands/doctor.d.ts +30 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +558 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/git-watch.d.ts +24 -0
- package/dist/commands/git-watch.d.ts.map +1 -0
- package/dist/commands/git-watch.js +84 -0
- package/dist/commands/git-watch.js.map +1 -0
- package/dist/commands/github-sync.d.ts +42 -0
- package/dist/commands/github-sync.d.ts.map +1 -0
- package/dist/commands/github-sync.js +191 -0
- package/dist/commands/github-sync.js.map +1 -0
- package/dist/commands/index.d.ts +25 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +29 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +23 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +45 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/log.d.ts +7 -0
- package/dist/commands/log.d.ts.map +1 -0
- package/dist/commands/log.js +110 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/merge-order.d.ts +9 -0
- package/dist/commands/merge-order.d.ts.map +1 -0
- package/dist/commands/merge-order.js +100 -0
- package/dist/commands/merge-order.js.map +1 -0
- package/dist/commands/merged.d.ts +8 -0
- package/dist/commands/merged.d.ts.map +1 -0
- package/dist/commands/merged.js +37 -0
- package/dist/commands/merged.js.map +1 -0
- package/dist/commands/pr-check.d.ts +24 -0
- package/dist/commands/pr-check.d.ts.map +1 -0
- package/dist/commands/pr-check.js +85 -0
- package/dist/commands/pr-check.js.map +1 -0
- package/dist/commands/ready-check.d.ts +11 -0
- package/dist/commands/ready-check.d.ts.map +1 -0
- package/dist/commands/ready-check.js +150 -0
- package/dist/commands/ready-check.js.map +1 -0
- package/dist/commands/rebase-helper.d.ts +3 -0
- package/dist/commands/rebase-helper.d.ts.map +1 -0
- package/dist/commands/rebase-helper.js +52 -0
- package/dist/commands/rebase-helper.js.map +1 -0
- package/dist/commands/register.d.ts +10 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +176 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/registry-sync.d.ts +9 -0
- package/dist/commands/registry-sync.d.ts.map +1 -0
- package/dist/commands/registry-sync.js +129 -0
- package/dist/commands/registry-sync.js.map +1 -0
- package/dist/commands/stale.d.ts +17 -0
- package/dist/commands/stale.d.ts.map +1 -0
- package/dist/commands/stale.js +136 -0
- package/dist/commands/stale.js.map +1 -0
- package/dist/commands/sync.d.ts +21 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +78 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/verify-trunk.d.ts +18 -0
- package/dist/commands/verify-trunk.d.ts.map +1 -0
- package/dist/commands/verify-trunk.js +77 -0
- package/dist/commands/verify-trunk.js.map +1 -0
- package/dist/commands/watch.d.ts +8 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +509 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/activity.d.ts +53 -0
- package/dist/lib/activity.d.ts.map +1 -0
- package/dist/lib/activity.js +271 -0
- package/dist/lib/activity.js.map +1 -0
- package/dist/lib/agent-errors.d.ts +41 -0
- package/dist/lib/agent-errors.d.ts.map +1 -0
- package/dist/lib/agent-errors.js +145 -0
- package/dist/lib/agent-errors.js.map +1 -0
- package/dist/lib/ai/context-builder.d.ts +16 -0
- package/dist/lib/ai/context-builder.d.ts.map +1 -0
- package/dist/lib/ai/context-builder.js +229 -0
- package/dist/lib/ai/context-builder.js.map +1 -0
- package/dist/lib/ai/event-handler.d.ts +21 -0
- package/dist/lib/ai/event-handler.d.ts.map +1 -0
- package/dist/lib/ai/event-handler.js +111 -0
- package/dist/lib/ai/event-handler.js.map +1 -0
- package/dist/lib/ai/index.d.ts +13 -0
- package/dist/lib/ai/index.d.ts.map +1 -0
- package/dist/lib/ai/index.js +11 -0
- package/dist/lib/ai/index.js.map +1 -0
- package/dist/lib/ai/llm-client.d.ts +37 -0
- package/dist/lib/ai/llm-client.d.ts.map +1 -0
- package/dist/lib/ai/llm-client.js +225 -0
- package/dist/lib/ai/llm-client.js.map +1 -0
- package/dist/lib/ai/reasoner.d.ts +11 -0
- package/dist/lib/ai/reasoner.d.ts.map +1 -0
- package/dist/lib/ai/reasoner.js +227 -0
- package/dist/lib/ai/reasoner.js.map +1 -0
- package/dist/lib/ai/setup.d.ts +40 -0
- package/dist/lib/ai/setup.d.ts.map +1 -0
- package/dist/lib/ai/setup.js +154 -0
- package/dist/lib/ai/setup.js.map +1 -0
- package/dist/lib/ai/types.d.ts +135 -0
- package/dist/lib/ai/types.d.ts.map +1 -0
- package/dist/lib/ai/types.js +42 -0
- package/dist/lib/ai/types.js.map +1 -0
- package/dist/lib/ast.d.ts +44 -0
- package/dist/lib/ast.d.ts.map +1 -0
- package/dist/lib/ast.js +160 -0
- package/dist/lib/ast.js.map +1 -0
- package/dist/lib/carries.d.ts +22 -0
- package/dist/lib/carries.d.ts.map +1 -0
- package/dist/lib/carries.js +56 -0
- package/dist/lib/carries.js.map +1 -0
- package/dist/lib/colony-subscriber.d.ts +56 -0
- package/dist/lib/colony-subscriber.d.ts.map +1 -0
- package/dist/lib/colony-subscriber.js +265 -0
- package/dist/lib/colony-subscriber.js.map +1 -0
- package/dist/lib/config.d.ts +62 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +235 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/conflict-analyzer.d.ts +33 -0
- package/dist/lib/conflict-analyzer.d.ts.map +1 -0
- package/dist/lib/conflict-analyzer.js +114 -0
- package/dist/lib/conflict-analyzer.js.map +1 -0
- package/dist/lib/conflict-renderer.d.ts +7 -0
- package/dist/lib/conflict-renderer.d.ts.map +1 -0
- package/dist/lib/conflict-renderer.js +145 -0
- package/dist/lib/conflict-renderer.js.map +1 -0
- package/dist/lib/conflict-tier.d.ts +20 -0
- package/dist/lib/conflict-tier.d.ts.map +1 -0
- package/dist/lib/conflict-tier.js +49 -0
- package/dist/lib/conflict-tier.js.map +1 -0
- package/dist/lib/crypto.d.ts +71 -0
- package/dist/lib/crypto.d.ts.map +1 -0
- package/dist/lib/crypto.js +176 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/ecosystem-env.d.ts +33 -0
- package/dist/lib/ecosystem-env.d.ts.map +1 -0
- package/dist/lib/ecosystem-env.js +62 -0
- package/dist/lib/ecosystem-env.js.map +1 -0
- package/dist/lib/errors.d.ts +35 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +71 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/git-events-subscriber.d.ts +86 -0
- package/dist/lib/git-events-subscriber.d.ts.map +1 -0
- package/dist/lib/git-events-subscriber.js +870 -0
- package/dist/lib/git-events-subscriber.js.map +1 -0
- package/dist/lib/git-merge-analyzer.d.ts +38 -0
- package/dist/lib/git-merge-analyzer.d.ts.map +1 -0
- package/dist/lib/git-merge-analyzer.js +23 -0
- package/dist/lib/git-merge-analyzer.js.map +1 -0
- package/dist/lib/git.d.ts +103 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +670 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/github.d.ts +151 -0
- package/dist/lib/github.d.ts.map +1 -0
- package/dist/lib/github.js +425 -0
- package/dist/lib/github.js.map +1 -0
- package/dist/lib/graph.d.ts +38 -0
- package/dist/lib/graph.d.ts.map +1 -0
- package/dist/lib/graph.js +165 -0
- package/dist/lib/graph.js.map +1 -0
- package/dist/lib/machine.d.ts +14 -0
- package/dist/lib/machine.d.ts.map +1 -0
- package/dist/lib/machine.js +38 -0
- package/dist/lib/machine.js.map +1 -0
- package/dist/lib/notify.d.ts +68 -0
- package/dist/lib/notify.d.ts.map +1 -0
- package/dist/lib/notify.js +111 -0
- package/dist/lib/notify.js.map +1 -0
- package/dist/lib/outline.d.ts +6 -0
- package/dist/lib/outline.d.ts.map +1 -0
- package/dist/lib/outline.js +60 -0
- package/dist/lib/outline.js.map +1 -0
- package/dist/lib/push-registry.d.ts +22 -0
- package/dist/lib/push-registry.d.ts.map +1 -0
- package/dist/lib/push-registry.js +21 -0
- package/dist/lib/push-registry.js.map +1 -0
- package/dist/lib/reconcile.d.ts +100 -0
- package/dist/lib/reconcile.d.ts.map +1 -0
- package/dist/lib/reconcile.js +121 -0
- package/dist/lib/reconcile.js.map +1 -0
- package/dist/lib/regex-utils.d.ts +6 -0
- package/dist/lib/regex-utils.d.ts.map +1 -0
- package/dist/lib/regex-utils.js +24 -0
- package/dist/lib/regex-utils.js.map +1 -0
- package/dist/lib/register-renderer.d.ts +10 -0
- package/dist/lib/register-renderer.d.ts.map +1 -0
- package/dist/lib/register-renderer.js +19 -0
- package/dist/lib/register-renderer.js.map +1 -0
- package/dist/lib/remote-drift.d.ts +61 -0
- package/dist/lib/remote-drift.d.ts.map +1 -0
- package/dist/lib/remote-drift.js +227 -0
- package/dist/lib/remote-drift.js.map +1 -0
- package/dist/lib/security.d.ts +72 -0
- package/dist/lib/security.d.ts.map +1 -0
- package/dist/lib/security.js +180 -0
- package/dist/lib/security.js.map +1 -0
- package/dist/lib/semantic-analysis.d.ts +31 -0
- package/dist/lib/semantic-analysis.d.ts.map +1 -0
- package/dist/lib/semantic-analysis.js +120 -0
- package/dist/lib/semantic-analysis.js.map +1 -0
- package/dist/lib/supabase-credentials.d.ts +36 -0
- package/dist/lib/supabase-credentials.d.ts.map +1 -0
- package/dist/lib/supabase-credentials.js +43 -0
- package/dist/lib/supabase-credentials.js.map +1 -0
- package/dist/lib/trunk.d.ts +39 -0
- package/dist/lib/trunk.d.ts.map +1 -0
- package/dist/lib/trunk.js +116 -0
- package/dist/lib/trunk.js.map +1 -0
- package/dist/lib/update-check.d.ts +11 -0
- package/dist/lib/update-check.d.ts.map +1 -0
- package/dist/lib/update-check.js +113 -0
- package/dist/lib/update-check.js.map +1 -0
- package/dist/lib/watch-renderer.d.ts +13 -0
- package/dist/lib/watch-renderer.d.ts.map +1 -0
- package/dist/lib/watch-renderer.js +35 -0
- package/dist/lib/watch-renderer.js.map +1 -0
- package/dist/storage/adapter.d.ts +81 -0
- package/dist/storage/adapter.d.ts.map +1 -0
- package/dist/storage/adapter.js +8 -0
- package/dist/storage/adapter.js.map +1 -0
- package/dist/storage/branch-registry-store.d.ts +13 -0
- package/dist/storage/branch-registry-store.d.ts.map +1 -0
- package/dist/storage/branch-registry-store.js +2 -0
- package/dist/storage/branch-registry-store.js.map +1 -0
- package/dist/storage/factory.d.ts +6 -0
- package/dist/storage/factory.d.ts.map +1 -0
- package/dist/storage/factory.js +14 -0
- package/dist/storage/factory.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +11 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/json-branch-registry-store.d.ts +19 -0
- package/dist/storage/json-branch-registry-store.d.ts.map +1 -0
- package/dist/storage/json-branch-registry-store.js +138 -0
- package/dist/storage/json-branch-registry-store.js.map +1 -0
- package/dist/storage/local.d.ts +20 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/local.js +40 -0
- package/dist/storage/local.js.map +1 -0
- package/dist/storage/memory-branch-registry-store.d.ts +16 -0
- package/dist/storage/memory-branch-registry-store.d.ts.map +1 -0
- package/dist/storage/memory-branch-registry-store.js +68 -0
- package/dist/storage/memory-branch-registry-store.js.map +1 -0
- package/dist/storage/supabase-registry-sync-client-impl.d.ts +40 -0
- package/dist/storage/supabase-registry-sync-client-impl.d.ts.map +1 -0
- package/dist/storage/supabase-registry-sync-client-impl.js +278 -0
- package/dist/storage/supabase-registry-sync-client-impl.js.map +1 -0
- package/dist/storage/supabase-registry-sync-client.d.ts +9 -0
- package/dist/storage/supabase-registry-sync-client.d.ts.map +1 -0
- package/dist/storage/supabase-registry-sync-client.js +2 -0
- package/dist/storage/supabase-registry-sync-client.js.map +1 -0
- package/dist/storage/supabase.d.ts +28 -0
- package/dist/storage/supabase.d.ts.map +1 -0
- package/dist/storage/supabase.js +56 -0
- package/dist/storage/supabase.js.map +1 -0
- package/dist/types/cloud.d.ts +102 -0
- package/dist/types/cloud.d.ts.map +1 -0
- package/dist/types/cloud.js +13 -0
- package/dist/types/cloud.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reconcile-on-read (tb-8sa.1 step 2)
|
|
3
|
+
*
|
|
4
|
+
* The registry's `status` field is only as fresh as the last `spidersan merged`
|
|
5
|
+
* / `sync` call — and a committed registry snapshot can carry an `active` entry
|
|
6
|
+
* for a branch that has since merged. Trusting that stale status is what
|
|
7
|
+
* produced the phantom-conflict incident (a fully-merged branch still flagged
|
|
8
|
+
* as conflicting from a stale worktree).
|
|
9
|
+
*
|
|
10
|
+
* Reconcile-on-read folds git truth in BEFORE conflicts / ready-check /
|
|
11
|
+
* merge-order answer:
|
|
12
|
+
* - ref gone from local AND remote → orphaned (drop)
|
|
13
|
+
* - tip is an ancestor of trunk → merged (drop)
|
|
14
|
+
* - trunk has a patch-id-equivalent squash → merged (drop, tb-tr1z)
|
|
15
|
+
* - otherwise → live (keep)
|
|
16
|
+
*
|
|
17
|
+
* It only consults git for entries the registry still calls `active`; entries
|
|
18
|
+
* already marked `completed` / `abandoned` are honoured without a git probe.
|
|
19
|
+
*/
|
|
20
|
+
import type { Branch } from '../storage/adapter.js';
|
|
21
|
+
export interface ReconcileResult {
|
|
22
|
+
/** Branches still genuinely in flight — the set readers should act on. */
|
|
23
|
+
live: Branch[];
|
|
24
|
+
/** Names detected as merged into trunk (by status or by is-ancestor). */
|
|
25
|
+
merged: string[];
|
|
26
|
+
/** Names whose ref is gone from both local and remote. */
|
|
27
|
+
orphaned: string[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Injectable git probes so reconcile is unit-testable without a real repo.
|
|
31
|
+
* Defaults wire to the real `git.ts` helpers via {@link defaultReconcileDeps}.
|
|
32
|
+
*/
|
|
33
|
+
export interface ReconcileDeps {
|
|
34
|
+
/** Resolve a branch name to a usable ref, or `null` if no ref exists. */
|
|
35
|
+
resolveRef: (name: string) => string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve the LOCAL ref (`refs/heads/<name>`), or `null` if none. When the
|
|
38
|
+
* primary ref is the remote-tracking one, a stale `origin/<name>` can be an
|
|
39
|
+
* ancestor of trunk while fresh unpushed local commits are not — both must
|
|
40
|
+
* be merged before the branch is reconciled away. Optional for injectors.
|
|
41
|
+
*/
|
|
42
|
+
resolveLocalRef?: (name: string) => string | null;
|
|
43
|
+
/** True if `ref` is fully merged into `trunkRef`. */
|
|
44
|
+
isMerged: (ref: string, trunkRef: string) => boolean;
|
|
45
|
+
/**
|
|
46
|
+
* True if `ref`'s content landed in trunk via a SQUASH merge (tb-tr1z) —
|
|
47
|
+
* consulted only when `isMerged` says no, since squash merges never make
|
|
48
|
+
* the tip an ancestor. Optional for injectors.
|
|
49
|
+
*/
|
|
50
|
+
isSquashMerged?: (ref: string, trunkRef: string) => boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Branch names that exist on the remote now, or `null` if it can't be asked.
|
|
53
|
+
* {@link activeBranches} drops an orphan only when this confirms it is gone.
|
|
54
|
+
* Absent (injectors) behaves like `null`: orphans are kept.
|
|
55
|
+
*/
|
|
56
|
+
remoteHeads?: () => Set<string> | null;
|
|
57
|
+
/** Bare trunk branch name (e.g. `main`) — never reconciled away. */
|
|
58
|
+
trunkName: string;
|
|
59
|
+
/** Ref used as the merge target for is-ancestor (prefers `origin/main`). */
|
|
60
|
+
trunkRef: string;
|
|
61
|
+
}
|
|
62
|
+
export declare function defaultReconcileDeps(): ReconcileDeps;
|
|
63
|
+
/**
|
|
64
|
+
* Partition registered branches into live / merged / orphaned using git truth.
|
|
65
|
+
*
|
|
66
|
+
* @param branches the raw registry entries (e.g. `await storage.list()`)
|
|
67
|
+
* @param deps git probes; defaults to the real repo
|
|
68
|
+
*/
|
|
69
|
+
export declare function reconcileBranches(branches: Branch[], deps?: ReconcileDeps): ReconcileResult;
|
|
70
|
+
/**
|
|
71
|
+
* Read-path convenience for conflict detection: registered `active` branches
|
|
72
|
+
* minus those PROVEN merged into trunk (is-ancestor / squash-equivalent, or
|
|
73
|
+
* status `completed`) and those PROVEN deleted.
|
|
74
|
+
*
|
|
75
|
+
* An orphan (no local or tracking ref) is ambiguous: deleted, or live on
|
|
76
|
+
* another machine and never fetched here. A squash-merged, deleted branch is
|
|
77
|
+
* never an ancestor of trunk, so it only ever reads as orphaned — keeping every
|
|
78
|
+
* orphan made those phantom-conflict forever. So an orphan is dropped only when
|
|
79
|
+
* `git ls-remote` confirms the branch is gone from the remote; if the remote
|
|
80
|
+
* can't be asked, orphans are kept (a phantom beats a missed conflict). This
|
|
81
|
+
* matters most for ready-check, which gets no cross-machine registry pull.
|
|
82
|
+
*
|
|
83
|
+
* Read-side filter only — nothing is deleted. This is what conflicts /
|
|
84
|
+
* ready-check / merge-order should call; `sync` uses {@link reconcileBranches}
|
|
85
|
+
* directly to actually prune merged and orphaned entries.
|
|
86
|
+
*/
|
|
87
|
+
export declare function activeBranches(branches: Branch[], deps?: ReconcileDeps): Branch[];
|
|
88
|
+
/**
|
|
89
|
+
* Split orphans (no local or tracking ref) into those the remote confirms are
|
|
90
|
+
* `gone` and those to `kept` — still on the remote (unfetched here), or every
|
|
91
|
+
* one of them when the remote can't be asked (`remoteChecked: false`). Shared by
|
|
92
|
+
* {@link activeBranches} (read side) and `sync` (which deletes `gone` only, sp-slemub).
|
|
93
|
+
* Only hits the network when there is an orphan to decide.
|
|
94
|
+
*/
|
|
95
|
+
export declare function splitOrphans(orphaned: string[], deps?: Pick<ReconcileDeps, 'remoteHeads'>): {
|
|
96
|
+
gone: string[];
|
|
97
|
+
kept: string[];
|
|
98
|
+
remoteChecked: boolean;
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/lib/reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC5B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,yEAAyE;IACzE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC1B,yEAAyE;IACzE,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC5C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAClD,qDAAqD;IACrD,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5D;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACvC,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,oBAAoB,IAAI,aAAa,CAapD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC7B,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,GAAE,aAAsC,GAC7C,eAAe,CA+CjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,aAAsC,GAAG,MAAM,EAAE,CAIzG;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CACxB,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,GAAE,IAAI,CAAC,aAAa,EAAE,aAAa,CAA4C,GACpF;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,OAAO,CAAA;CAAE,CAK5D"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reconcile-on-read (tb-8sa.1 step 2)
|
|
3
|
+
*
|
|
4
|
+
* The registry's `status` field is only as fresh as the last `spidersan merged`
|
|
5
|
+
* / `sync` call — and a committed registry snapshot can carry an `active` entry
|
|
6
|
+
* for a branch that has since merged. Trusting that stale status is what
|
|
7
|
+
* produced the phantom-conflict incident (a fully-merged branch still flagged
|
|
8
|
+
* as conflicting from a stale worktree).
|
|
9
|
+
*
|
|
10
|
+
* Reconcile-on-read folds git truth in BEFORE conflicts / ready-check /
|
|
11
|
+
* merge-order answer:
|
|
12
|
+
* - ref gone from local AND remote → orphaned (drop)
|
|
13
|
+
* - tip is an ancestor of trunk → merged (drop)
|
|
14
|
+
* - trunk has a patch-id-equivalent squash → merged (drop, tb-tr1z)
|
|
15
|
+
* - otherwise → live (keep)
|
|
16
|
+
*
|
|
17
|
+
* It only consults git for entries the registry still calls `active`; entries
|
|
18
|
+
* already marked `completed` / `abandoned` are honoured without a git probe.
|
|
19
|
+
*/
|
|
20
|
+
import { resolveBranchRef, resolveLocalBranchRef, isMergedInto, isSquashMergedInto, listRemoteHeads } from './git.js';
|
|
21
|
+
import { getTrunkBranch } from './trunk.js';
|
|
22
|
+
export function defaultReconcileDeps() {
|
|
23
|
+
const trunkName = getTrunkBranch();
|
|
24
|
+
// Prefer the remote trunk ref so a stale local `main` can't mask merges.
|
|
25
|
+
const trunkRef = resolveBranchRef(trunkName) ?? trunkName;
|
|
26
|
+
return {
|
|
27
|
+
resolveRef: (name) => resolveBranchRef(name),
|
|
28
|
+
resolveLocalRef: (name) => resolveLocalBranchRef(name),
|
|
29
|
+
isMerged: (ref, trunk) => isMergedInto(ref, trunk),
|
|
30
|
+
isSquashMerged: (ref, trunk) => isSquashMergedInto(ref, trunk),
|
|
31
|
+
remoteHeads: () => listRemoteHeads(),
|
|
32
|
+
trunkName,
|
|
33
|
+
trunkRef,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Partition registered branches into live / merged / orphaned using git truth.
|
|
38
|
+
*
|
|
39
|
+
* @param branches the raw registry entries (e.g. `await storage.list()`)
|
|
40
|
+
* @param deps git probes; defaults to the real repo
|
|
41
|
+
*/
|
|
42
|
+
export function reconcileBranches(branches, deps = defaultReconcileDeps()) {
|
|
43
|
+
const live = [];
|
|
44
|
+
const merged = [];
|
|
45
|
+
const orphaned = [];
|
|
46
|
+
for (const branch of branches) {
|
|
47
|
+
// The trunk itself is never "in flight" but also never reconciled away —
|
|
48
|
+
// pass it through unchanged so readers keep their existing handling.
|
|
49
|
+
if (branch.name === deps.trunkName) {
|
|
50
|
+
live.push(branch);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
// Honour terminal registry status without a git probe.
|
|
54
|
+
if (branch.status === 'completed') {
|
|
55
|
+
merged.push(branch.name);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (branch.status === 'abandoned') {
|
|
59
|
+
orphaned.push(branch.name);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// status === 'active' — fold in git truth. Squash merges never make
|
|
63
|
+
// the tip an ancestor, so fall back to patch-id equivalence (tb-tr1z).
|
|
64
|
+
const provenMerged = (r) => deps.isMerged(r, deps.trunkRef) || (deps.isSquashMerged?.(r, deps.trunkRef) ?? false);
|
|
65
|
+
const ref = deps.resolveRef(branch.name);
|
|
66
|
+
if (ref === null) {
|
|
67
|
+
orphaned.push(branch.name);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (provenMerged(ref)) {
|
|
71
|
+
// The primary ref may be a stale origin/<name> while unpushed local
|
|
72
|
+
// commits exist — only reconcile away if the local tip (when it
|
|
73
|
+
// exists and differs) is merged too.
|
|
74
|
+
const localRef = deps.resolveLocalRef?.(branch.name) ?? null;
|
|
75
|
+
if (localRef === null || localRef === ref || provenMerged(localRef)) {
|
|
76
|
+
merged.push(branch.name);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
live.push(branch);
|
|
81
|
+
}
|
|
82
|
+
return { live, merged, orphaned };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Read-path convenience for conflict detection: registered `active` branches
|
|
86
|
+
* minus those PROVEN merged into trunk (is-ancestor / squash-equivalent, or
|
|
87
|
+
* status `completed`) and those PROVEN deleted.
|
|
88
|
+
*
|
|
89
|
+
* An orphan (no local or tracking ref) is ambiguous: deleted, or live on
|
|
90
|
+
* another machine and never fetched here. A squash-merged, deleted branch is
|
|
91
|
+
* never an ancestor of trunk, so it only ever reads as orphaned — keeping every
|
|
92
|
+
* orphan made those phantom-conflict forever. So an orphan is dropped only when
|
|
93
|
+
* `git ls-remote` confirms the branch is gone from the remote; if the remote
|
|
94
|
+
* can't be asked, orphans are kept (a phantom beats a missed conflict). This
|
|
95
|
+
* matters most for ready-check, which gets no cross-machine registry pull.
|
|
96
|
+
*
|
|
97
|
+
* Read-side filter only — nothing is deleted. This is what conflicts /
|
|
98
|
+
* ready-check / merge-order should call; `sync` uses {@link reconcileBranches}
|
|
99
|
+
* directly to actually prune merged and orphaned entries.
|
|
100
|
+
*/
|
|
101
|
+
export function activeBranches(branches, deps = defaultReconcileDeps()) {
|
|
102
|
+
const { live, orphaned } = reconcileBranches(branches, deps);
|
|
103
|
+
const keep = new Set([...live.map(b => b.name), ...splitOrphans(orphaned, deps).kept]);
|
|
104
|
+
return branches.filter(b => b.status === 'active' && keep.has(b.name));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Split orphans (no local or tracking ref) into those the remote confirms are
|
|
108
|
+
* `gone` and those to `kept` — still on the remote (unfetched here), or every
|
|
109
|
+
* one of them when the remote can't be asked (`remoteChecked: false`). Shared by
|
|
110
|
+
* {@link activeBranches} (read side) and `sync` (which deletes `gone` only, sp-slemub).
|
|
111
|
+
* Only hits the network when there is an orphan to decide.
|
|
112
|
+
*/
|
|
113
|
+
export function splitOrphans(orphaned, deps = { remoteHeads: () => listRemoteHeads() }) {
|
|
114
|
+
if (orphaned.length === 0)
|
|
115
|
+
return { gone: [], kept: [], remoteChecked: true };
|
|
116
|
+
const heads = deps.remoteHeads?.() ?? null;
|
|
117
|
+
if (heads === null)
|
|
118
|
+
return { gone: [], kept: orphaned, remoteChecked: false };
|
|
119
|
+
return { gone: orphaned.filter(n => !heads.has(n)), kept: orphaned.filter(n => heads.has(n)), remoteChecked: true };
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=reconcile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/lib/reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility for combining multiple Regular Expressions into a single efficient RegExp.
|
|
3
|
+
* Consolidates patterns using the OR (|) operator to reduce matching complexity from O(N*M) to O(1).
|
|
4
|
+
*/
|
|
5
|
+
export declare function compilePatterns(patterns: RegExp[]): RegExp[];
|
|
6
|
+
//# sourceMappingURL=regex-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regex-utils.d.ts","sourceRoot":"","sources":["../../src/lib/regex-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAqB5D"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility for combining multiple Regular Expressions into a single efficient RegExp.
|
|
3
|
+
* Consolidates patterns using the OR (|) operator to reduce matching complexity from O(N*M) to O(1).
|
|
4
|
+
*/
|
|
5
|
+
export function compilePatterns(patterns) {
|
|
6
|
+
if (!patterns || patterns.length === 0)
|
|
7
|
+
return [];
|
|
8
|
+
// Group patterns by their flags to preserve behavior (e.g., 'i', 'g', 'm')
|
|
9
|
+
const grouped = new Map();
|
|
10
|
+
for (const p of patterns) {
|
|
11
|
+
const flags = p.flags;
|
|
12
|
+
if (!grouped.has(flags)) {
|
|
13
|
+
grouped.set(flags, []);
|
|
14
|
+
}
|
|
15
|
+
// Use non-capturing groups to ensure OR logic applies correctly to the whole pattern
|
|
16
|
+
grouped.get(flags).push(`(?:${p.source})`);
|
|
17
|
+
}
|
|
18
|
+
const result = [];
|
|
19
|
+
for (const [flags, sources] of grouped.entries()) {
|
|
20
|
+
result.push(new RegExp(sources.join('|'), flags));
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=regex-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regex-utils.js","sourceRoot":"","sources":["../../src/lib/regex-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAkB;IAC9C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElD,2EAA2E;IAC3E,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE5C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC3B,CAAC;QACD,qFAAqF;QACrF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface RegisterRenderOptions {
|
|
2
|
+
branchName: string;
|
|
3
|
+
files: string[];
|
|
4
|
+
isUpdate: boolean;
|
|
5
|
+
autoDetected?: boolean;
|
|
6
|
+
autoDetectedFiles?: string[];
|
|
7
|
+
}
|
|
8
|
+
/** Pure. Returns terminal string for spidersan register success output. */
|
|
9
|
+
export declare function renderRegisterResult(opts: RegisterRenderOptions): string;
|
|
10
|
+
//# sourceMappingURL=register-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-renderer.d.ts","sourceRoot":"","sources":["../../src/lib/register-renderer.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAmBxE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Pure. Returns terminal string for spidersan register success output. */
|
|
2
|
+
export function renderRegisterResult(opts) {
|
|
3
|
+
const lines = [];
|
|
4
|
+
const detectedFiles = opts.autoDetectedFiles ?? opts.files;
|
|
5
|
+
if (opts.autoDetected && detectedFiles.length > 0) {
|
|
6
|
+
lines.push(`🕷️ Auto-detected ${detectedFiles.length} changed file(s)`);
|
|
7
|
+
}
|
|
8
|
+
if (opts.isUpdate) {
|
|
9
|
+
lines.push(`🕷️ Updated branch: ${opts.branchName}`);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
lines.push(`🕷️ Registered branch: ${opts.branchName}`);
|
|
13
|
+
}
|
|
14
|
+
if (opts.files.length > 0) {
|
|
15
|
+
lines.push(` Files: ${opts.files.join(', ')}`);
|
|
16
|
+
}
|
|
17
|
+
return lines.join('\n').trimEnd();
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=register-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-renderer.js","sourceRoot":"","sources":["../../src/lib/register-renderer.ts"],"names":[],"mappings":"AAQA,2EAA2E;AAC3E,MAAM,UAAU,oBAAoB,CAAC,IAA2B;IAC5D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,KAAK,CAAC;IAE3D,IAAI,IAAI,CAAC,YAAY,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,qBAAqB,aAAa,CAAC,MAAM,kBAAkB,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,uBAAuB,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACJ,KAAK,CAAC,IAAI,CAAC,0BAA0B,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* remote-drift.ts
|
|
3
|
+
*
|
|
4
|
+
* Detects whether origin/main has advanced past local HEAD and cross-references
|
|
5
|
+
* the drift zone against (a) the registered file list and (b) unstaged tracked
|
|
6
|
+
* files in the working tree.
|
|
7
|
+
*
|
|
8
|
+
* Core primitives (getDriftZone, getUnstagedTrackedFiles, classifyDriftZone)
|
|
9
|
+
* are exported so that watch --fetch-poll can reuse them without importing
|
|
10
|
+
* from the command layer.
|
|
11
|
+
*/
|
|
12
|
+
export interface DriftEntry {
|
|
13
|
+
file: string;
|
|
14
|
+
registered: boolean;
|
|
15
|
+
tier: 1 | 2 | 3 | null;
|
|
16
|
+
unstaged: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface DriftResult {
|
|
19
|
+
branch: string;
|
|
20
|
+
remote: string;
|
|
21
|
+
localAhead: number;
|
|
22
|
+
remoteAhead: number;
|
|
23
|
+
state: 'synced' | 'local_ahead' | 'remote_ahead' | 'diverged';
|
|
24
|
+
driftZone: string[];
|
|
25
|
+
registeredInDrift: DriftEntry[];
|
|
26
|
+
unstagedInDrift: DriftEntry[];
|
|
27
|
+
safeToPush: boolean;
|
|
28
|
+
rebaseContinueRisk: boolean;
|
|
29
|
+
recommendation: 'synced' | 'push_clean' | 'pull_rebase' | 'rebase_clean' | 'rebase_with_conflict_prep';
|
|
30
|
+
}
|
|
31
|
+
export interface DriftSkipped {
|
|
32
|
+
skipped: true;
|
|
33
|
+
reason: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function isOfflineError(error: unknown): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Returns the union of files touched by commits that origin/<branch> has but
|
|
38
|
+
* local HEAD does not. Requires a prior `git fetch origin`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getDriftZone(remote: string, branch: string): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Returns tracked files that have unstaged modifications (working tree vs index).
|
|
43
|
+
*/
|
|
44
|
+
export declare function getUnstagedTrackedFiles(): string[];
|
|
45
|
+
/**
|
|
46
|
+
* Cross-references driftFiles against registeredFiles + unstagedFiles.
|
|
47
|
+
* Returns a DriftEntry for each file in the drift zone.
|
|
48
|
+
*/
|
|
49
|
+
export declare function classifyDriftZone(driftFiles: string[], registeredFiles: string[], unstagedFiles: string[], tierOptions?: {
|
|
50
|
+
extraTier3?: RegExp[];
|
|
51
|
+
extraTier2?: RegExp[];
|
|
52
|
+
}): DriftEntry[];
|
|
53
|
+
/**
|
|
54
|
+
* Main entry point. Fetches origin, computes drift, classifies against registry
|
|
55
|
+
* and working tree. Returns DriftSkipped for graceful-degradation cases.
|
|
56
|
+
*/
|
|
57
|
+
export declare function computeDriftResult(registeredFiles: string[], options?: {
|
|
58
|
+
remote?: string;
|
|
59
|
+
branch?: string;
|
|
60
|
+
}): Promise<DriftResult | DriftSkipped>;
|
|
61
|
+
//# sourceMappingURL=remote-drift.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-drift.d.ts","sourceRoot":"","sources":["../../src/lib/remote-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,QAAQ,GAAG,aAAa,GAAG,cAAc,GAAG,UAAU,CAAC;IAC9D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,iBAAiB,EAAE,UAAU,EAAE,CAAC;IAChC,eAAe,EAAE,UAAU,EAAE,CAAC;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,QAAQ,GAAG,YAAY,GAAG,aAAa,GAAG,cAAc,GAAG,2BAA2B,CAAC;CAC1G;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB;AAYD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGtD;AAcD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAgCrE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAOlD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC7B,UAAU,EAAE,MAAM,EAAE,EACpB,eAAe,EAAE,MAAM,EAAE,EACzB,aAAa,EAAE,MAAM,EAAE,EACvB,WAAW,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAC/D,UAAU,EAAE,CAgBd;AAuBD;;;GAGG;AACH,wBAAsB,kBAAkB,CACpC,eAAe,EAAE,MAAM,EAAE,EACzB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,OAAO,CAAC,WAAW,GAAG,YAAY,CAAC,CAuGrC"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* remote-drift.ts
|
|
3
|
+
*
|
|
4
|
+
* Detects whether origin/main has advanced past local HEAD and cross-references
|
|
5
|
+
* the drift zone against (a) the registered file list and (b) unstaged tracked
|
|
6
|
+
* files in the working tree.
|
|
7
|
+
*
|
|
8
|
+
* Core primitives (getDriftZone, getUnstagedTrackedFiles, classifyDriftZone)
|
|
9
|
+
* are exported so that watch --fetch-poll can reuse them without importing
|
|
10
|
+
* from the command layer.
|
|
11
|
+
*/
|
|
12
|
+
import { execFileSync } from 'child_process';
|
|
13
|
+
import * as fs from 'fs';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
import { getCurrentBranch, getAheadBehind } from './git.js';
|
|
16
|
+
import { classifyTier } from './conflict-tier.js';
|
|
17
|
+
import { validateBranchName } from './security.js';
|
|
18
|
+
const GIT_TIMEOUT_MS = 15_000;
|
|
19
|
+
function execGit(args) {
|
|
20
|
+
return execFileSync('git', args, {
|
|
21
|
+
encoding: 'utf-8',
|
|
22
|
+
env: { ...process.env },
|
|
23
|
+
timeout: GIT_TIMEOUT_MS,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export function isOfflineError(error) {
|
|
27
|
+
const msg = String(error instanceof Error ? error.message : error);
|
|
28
|
+
return /ENOTFOUND|ETIMEDOUT|ECONNREFUSED|network|Could not resolve host|unable to connect|cannot access/i.test(msg);
|
|
29
|
+
}
|
|
30
|
+
function isInRebase() {
|
|
31
|
+
try {
|
|
32
|
+
const gitDir = execGit(['rev-parse', '--git-dir']).trim();
|
|
33
|
+
return (fs.existsSync(path.join(gitDir, 'rebase-merge')) ||
|
|
34
|
+
fs.existsSync(path.join(gitDir, 'rebase-apply')));
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns the union of files touched by commits that origin/<branch> has but
|
|
42
|
+
* local HEAD does not. Requires a prior `git fetch origin`.
|
|
43
|
+
*/
|
|
44
|
+
export function getDriftZone(remote, branch) {
|
|
45
|
+
const safeBranch = validateBranchName(branch);
|
|
46
|
+
const upstreamRef = `${remote}/${safeBranch}`;
|
|
47
|
+
let commitList;
|
|
48
|
+
try {
|
|
49
|
+
commitList = execGit(['rev-list', `HEAD..${upstreamRef}`]).trim();
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
if (!commitList)
|
|
55
|
+
return [];
|
|
56
|
+
const shas = commitList.split('\n').filter(Boolean);
|
|
57
|
+
const files = new Set();
|
|
58
|
+
for (const sha of shas) {
|
|
59
|
+
try {
|
|
60
|
+
const stat = execGit(['show', '--stat', '--format=', sha]);
|
|
61
|
+
for (const line of stat.split('\n')) {
|
|
62
|
+
// Lines like: " src/lib/git.ts | 10 ++--"
|
|
63
|
+
const match = /^\s+(.+?)\s+\|/.exec(line);
|
|
64
|
+
if (match && match[1]) {
|
|
65
|
+
files.add(match[1].trim());
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// skip unparseable commit
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return [...files];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Returns tracked files that have unstaged modifications (working tree vs index).
|
|
77
|
+
*/
|
|
78
|
+
export function getUnstagedTrackedFiles() {
|
|
79
|
+
try {
|
|
80
|
+
const output = execGit(['diff', '--name-only']).trim();
|
|
81
|
+
return output ? output.split('\n').filter(Boolean) : [];
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Cross-references driftFiles against registeredFiles + unstagedFiles.
|
|
89
|
+
* Returns a DriftEntry for each file in the drift zone.
|
|
90
|
+
*/
|
|
91
|
+
export function classifyDriftZone(driftFiles, registeredFiles, unstagedFiles, tierOptions) {
|
|
92
|
+
const registeredSet = new Set(registeredFiles);
|
|
93
|
+
const unstagedSet = new Set(unstagedFiles);
|
|
94
|
+
return driftFiles.map((file) => {
|
|
95
|
+
const registered = registeredSet.has(file);
|
|
96
|
+
const unstaged = unstagedSet.has(file);
|
|
97
|
+
const tier = registered
|
|
98
|
+
? classifyTier(file, {
|
|
99
|
+
extraTier3: tierOptions?.extraTier3 ?? [],
|
|
100
|
+
extraTier2: tierOptions?.extraTier2 ?? [],
|
|
101
|
+
})
|
|
102
|
+
: null;
|
|
103
|
+
return { file, registered, tier, unstaged };
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function deriveState(localAhead, remoteAhead) {
|
|
107
|
+
if (localAhead === 0 && remoteAhead === 0)
|
|
108
|
+
return 'synced';
|
|
109
|
+
if (localAhead > 0 && remoteAhead === 0)
|
|
110
|
+
return 'local_ahead';
|
|
111
|
+
if (localAhead === 0 && remoteAhead > 0)
|
|
112
|
+
return 'remote_ahead';
|
|
113
|
+
return 'diverged';
|
|
114
|
+
}
|
|
115
|
+
function deriveRecommendation(state, registeredInDrift, unstagedInDrift) {
|
|
116
|
+
if (state === 'synced')
|
|
117
|
+
return 'synced';
|
|
118
|
+
if (state === 'local_ahead')
|
|
119
|
+
return 'push_clean';
|
|
120
|
+
// remote_ahead or diverged
|
|
121
|
+
if (registeredInDrift.length > 0 || unstagedInDrift.length > 0) {
|
|
122
|
+
return 'rebase_with_conflict_prep';
|
|
123
|
+
}
|
|
124
|
+
return state === 'diverged' ? 'rebase_clean' : 'pull_rebase';
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Main entry point. Fetches origin, computes drift, classifies against registry
|
|
128
|
+
* and working tree. Returns DriftSkipped for graceful-degradation cases.
|
|
129
|
+
*/
|
|
130
|
+
export async function computeDriftResult(registeredFiles, options) {
|
|
131
|
+
const remote = options?.remote ?? 'origin';
|
|
132
|
+
// Detect mid-rebase
|
|
133
|
+
if (isInRebase()) {
|
|
134
|
+
return { skipped: true, reason: 'Rebase in progress — run after completing or aborting rebase' };
|
|
135
|
+
}
|
|
136
|
+
// Determine branch
|
|
137
|
+
let branch;
|
|
138
|
+
try {
|
|
139
|
+
branch = options?.branch ?? getCurrentBranch();
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return { skipped: true, reason: 'Not in a git repository' };
|
|
143
|
+
}
|
|
144
|
+
if (branch === 'HEAD') {
|
|
145
|
+
return { skipped: true, reason: 'Detached HEAD — cannot determine branch' };
|
|
146
|
+
}
|
|
147
|
+
// Fetch
|
|
148
|
+
try {
|
|
149
|
+
execGit(['fetch', remote]);
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
if (isOfflineError(error)) {
|
|
153
|
+
return { skipped: true, reason: '⚠ Remote unreachable — drift check skipped' };
|
|
154
|
+
}
|
|
155
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
156
|
+
if (/No such remote|remote .* not found/i.test(msg)) {
|
|
157
|
+
return { skipped: true, reason: `No remote '${remote}' found` };
|
|
158
|
+
}
|
|
159
|
+
// Unknown fetch error — still skip gracefully
|
|
160
|
+
return { skipped: true, reason: `Fetch failed: ${msg}` };
|
|
161
|
+
}
|
|
162
|
+
// Check if remote branch exists
|
|
163
|
+
const safeBranch = validateBranchName(branch);
|
|
164
|
+
const upstreamRef = `${remote}/${safeBranch}`;
|
|
165
|
+
try {
|
|
166
|
+
execGit(['rev-parse', '--verify', upstreamRef]);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// Remote branch doesn't exist yet (first push)
|
|
170
|
+
return {
|
|
171
|
+
branch,
|
|
172
|
+
remote: upstreamRef,
|
|
173
|
+
localAhead: 0,
|
|
174
|
+
remoteAhead: 0,
|
|
175
|
+
state: 'synced',
|
|
176
|
+
driftZone: [],
|
|
177
|
+
registeredInDrift: [],
|
|
178
|
+
unstagedInDrift: [],
|
|
179
|
+
safeToPush: true,
|
|
180
|
+
rebaseContinueRisk: false,
|
|
181
|
+
recommendation: 'push_clean',
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// Ahead/behind
|
|
185
|
+
let localAhead;
|
|
186
|
+
let remoteAhead;
|
|
187
|
+
try {
|
|
188
|
+
const ab = getAheadBehind(remote, branch);
|
|
189
|
+
localAhead = ab.ahead;
|
|
190
|
+
remoteAhead = ab.behind; // getAheadBehind returns { ahead: local, behind: remote }
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
194
|
+
if (/not a git repository/i.test(msg)) {
|
|
195
|
+
return { skipped: true, reason: 'Not in a git repository' };
|
|
196
|
+
}
|
|
197
|
+
return { skipped: true, reason: `Could not compute ahead/behind: ${msg}` };
|
|
198
|
+
}
|
|
199
|
+
const state = deriveState(localAhead, remoteAhead);
|
|
200
|
+
// Only compute drift zone when remote has new commits
|
|
201
|
+
let driftZone = [];
|
|
202
|
+
let entries = [];
|
|
203
|
+
if (remoteAhead > 0) {
|
|
204
|
+
driftZone = getDriftZone(remote, branch);
|
|
205
|
+
const unstagedFiles = getUnstagedTrackedFiles();
|
|
206
|
+
entries = classifyDriftZone(driftZone, registeredFiles, unstagedFiles);
|
|
207
|
+
}
|
|
208
|
+
const registeredInDrift = entries.filter(e => e.registered);
|
|
209
|
+
const unstagedInDrift = entries.filter(e => e.unstaged);
|
|
210
|
+
const rebaseContinueRisk = unstagedInDrift.length > 0;
|
|
211
|
+
const safeToPush = remoteAhead === 0;
|
|
212
|
+
const recommendation = deriveRecommendation(state, registeredInDrift, unstagedInDrift);
|
|
213
|
+
return {
|
|
214
|
+
branch,
|
|
215
|
+
remote: upstreamRef,
|
|
216
|
+
localAhead,
|
|
217
|
+
remoteAhead,
|
|
218
|
+
state,
|
|
219
|
+
driftZone,
|
|
220
|
+
registeredInDrift,
|
|
221
|
+
unstagedInDrift,
|
|
222
|
+
safeToPush,
|
|
223
|
+
rebaseContinueRisk,
|
|
224
|
+
recommendation,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=remote-drift.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-drift.js","sourceRoot":"","sources":["../../src/lib/remote-drift.ts"],"names":[],"mappings":"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"}
|