@ferueda/grove 0.2.0 → 0.3.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.
- package/dist/errors.d.ts +34 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +55 -0
- package/dist/git/branch.d.ts +8 -0
- package/dist/git/branch.d.ts.map +1 -1
- package/dist/git/branch.js +57 -0
- package/dist/hooks.d.ts +3 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +11 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/pool.d.ts +20 -20
- package/dist/pool.d.ts.map +1 -1
- package/dist/pool.js +395 -182
- package/dist/process/detect.d.ts +9 -2
- package/dist/process/detect.d.ts.map +1 -1
- package/dist/process/detect.js +7 -5
- package/dist/process/terminate.js +2 -2
- package/dist/queries.d.ts +8 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +97 -0
- package/dist/schemas.d.ts +79 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +29 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +5 -0
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +1 -1
package/dist/process/detect.d.ts
CHANGED
|
@@ -3,9 +3,16 @@ export interface ProcessInfo {
|
|
|
3
3
|
PID: number;
|
|
4
4
|
Name?: string;
|
|
5
5
|
}
|
|
6
|
+
export interface ProcessScanResult {
|
|
7
|
+
processes: ProcessInfo[];
|
|
8
|
+
unverified: boolean;
|
|
9
|
+
}
|
|
6
10
|
export declare function startedAt(pid: number): Promise<number | null>;
|
|
7
11
|
export declare function reserveOwner(entry: WorktreeEntry): Promise<void>;
|
|
8
12
|
export declare function ownerAlive(entry: WorktreeEntry): Promise<boolean>;
|
|
9
|
-
export declare function findInWorktree(worktreePath: string): Promise<
|
|
10
|
-
export declare function isWorktreeInUse(worktreePath: string): Promise<
|
|
13
|
+
export declare function findInWorktree(worktreePath: string): Promise<ProcessScanResult>;
|
|
14
|
+
export declare function isWorktreeInUse(worktreePath: string): Promise<{
|
|
15
|
+
inUse: boolean;
|
|
16
|
+
unverified: boolean;
|
|
17
|
+
}>;
|
|
11
18
|
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/process/detect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAkBD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+BnE;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAMtE;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBvE;AAUD,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/process/detect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;CACrB;AAkBD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+BnE;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAMtE;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBvE;AAUD,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkDrF;AAED,wBAAsB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAG5G"}
|
package/dist/process/detect.js
CHANGED
|
@@ -98,7 +98,7 @@ export async function findInWorktree(worktreePath) {
|
|
|
98
98
|
procs = await readdir("/proc");
|
|
99
99
|
}
|
|
100
100
|
catch {
|
|
101
|
-
return [];
|
|
101
|
+
return { processes: [], unverified: true };
|
|
102
102
|
}
|
|
103
103
|
for (const p of procs) {
|
|
104
104
|
if (!/^\d+$/.test(p))
|
|
@@ -115,6 +115,7 @@ export async function findInWorktree(worktreePath) {
|
|
|
115
115
|
continue;
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
+
return { processes: result, unverified: false };
|
|
118
119
|
}
|
|
119
120
|
else if (process.platform === "darwin") {
|
|
120
121
|
try {
|
|
@@ -134,14 +135,15 @@ export async function findInWorktree(worktreePath) {
|
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
}
|
|
138
|
+
return { processes: result, unverified: false };
|
|
137
139
|
}
|
|
138
140
|
catch {
|
|
139
|
-
|
|
141
|
+
return { processes: [], unverified: true };
|
|
140
142
|
}
|
|
141
143
|
}
|
|
142
|
-
return
|
|
144
|
+
return { processes: [], unverified: true };
|
|
143
145
|
}
|
|
144
146
|
export async function isWorktreeInUse(worktreePath) {
|
|
145
|
-
const
|
|
146
|
-
return
|
|
147
|
+
const scan = await findInWorktree(worktreePath);
|
|
148
|
+
return { inUse: scan.processes.length > 0, unverified: scan.unverified };
|
|
147
149
|
}
|
|
@@ -85,8 +85,8 @@ export async function filterProtectedProcesses(procs, currentPID) {
|
|
|
85
85
|
return procs.filter((p) => !protectedPids.has(p.PID));
|
|
86
86
|
}
|
|
87
87
|
export async function terminateWorktreeProcesses(worktreePath, gracePeriodMs) {
|
|
88
|
-
const
|
|
89
|
-
const targetProcs = await filterProtectedProcesses(
|
|
88
|
+
const { processes } = await findInWorktree(worktreePath);
|
|
89
|
+
const targetProcs = await filterProtectedProcesses(processes, process.pid);
|
|
90
90
|
if (targetProcs.length === 0) {
|
|
91
91
|
return [];
|
|
92
92
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WorktreeEntry } from "./schemas.js";
|
|
2
|
+
import type { WorktreeStatus, GroveLease } from "./types.js";
|
|
3
|
+
import type { GroveConfig } from "./index.js";
|
|
4
|
+
export declare function entryToLease(wt: WorktreeEntry, processSafety: "verified" | "unverified", repoRoot: string): GroveLease;
|
|
5
|
+
export declare function listWorktrees(poolDir: string): Promise<WorktreeStatus[]>;
|
|
6
|
+
export declare function listLeases(poolDir: string, config: GroveConfig): Promise<GroveLease[]>;
|
|
7
|
+
export declare function inspectLease(leaseIdOrPath: string, poolDir: string, config: GroveConfig): Promise<GroveLease | null>;
|
|
8
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAsB,MAAM,YAAY,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO9C,wBAAgB,YAAY,CAAC,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,GAAG,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAkBtH;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAsC9E;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAqB5F;AAED,wBAAsB,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAkB1H"}
|
package/dist/queries.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { relative, isAbsolute } from "node:path";
|
|
2
|
+
import { isDirty, getHeadSha } from "./git/index.js";
|
|
3
|
+
import { readState, healState, writeState } from "./state.js";
|
|
4
|
+
import { ownerAlive, findInWorktree } from "./process/detect.js";
|
|
5
|
+
import { withStateLock } from "./lock.js";
|
|
6
|
+
function cwdInWorktree(cwd, worktreePath) {
|
|
7
|
+
const rel = relative(worktreePath, cwd);
|
|
8
|
+
return !rel.startsWith("..") && !isAbsolute(rel);
|
|
9
|
+
}
|
|
10
|
+
export function entryToLease(wt, processSafety, repoRoot) {
|
|
11
|
+
return {
|
|
12
|
+
leaseId: wt.leaseId,
|
|
13
|
+
ownerId: wt.ownerId,
|
|
14
|
+
slotName: wt.name,
|
|
15
|
+
path: wt.path,
|
|
16
|
+
repoRoot,
|
|
17
|
+
branch: wt.branch,
|
|
18
|
+
baseRef: wt.baseRef,
|
|
19
|
+
baseSha: wt.baseSha,
|
|
20
|
+
acquiredHeadSha: wt.acquiredHeadSha || "",
|
|
21
|
+
currentHeadSha: wt.currentHeadSha || "",
|
|
22
|
+
state: wt.state || "available",
|
|
23
|
+
pendingCleanup: wt.pendingCleanup,
|
|
24
|
+
processSafety,
|
|
25
|
+
createdAt: wt.createdAt || wt.created_at || "",
|
|
26
|
+
updatedAt: wt.updatedAt || wt.created_at || "",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export async function listWorktrees(poolDir) {
|
|
30
|
+
const result = [];
|
|
31
|
+
await withStateLock(poolDir, async () => {
|
|
32
|
+
let state = await readState(poolDir);
|
|
33
|
+
state = await healState(state);
|
|
34
|
+
await writeState(poolDir, state);
|
|
35
|
+
const cwd = process.cwd();
|
|
36
|
+
for (const wt of state.worktrees) {
|
|
37
|
+
if (wt.destroying || wt.state === "destroying" || wt.leaseId)
|
|
38
|
+
continue;
|
|
39
|
+
let status = "available";
|
|
40
|
+
const { processes } = await findInWorktree(wt.path);
|
|
41
|
+
const alive = await ownerAlive(wt);
|
|
42
|
+
if (alive) {
|
|
43
|
+
status = "in-use";
|
|
44
|
+
}
|
|
45
|
+
else if (processes.length > 0) {
|
|
46
|
+
status = "in-use";
|
|
47
|
+
if (cwdInWorktree(cwd, wt.path)) {
|
|
48
|
+
status = "you're here";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else if (await isDirty(wt.path)) {
|
|
52
|
+
status = "dirty";
|
|
53
|
+
}
|
|
54
|
+
result.push({
|
|
55
|
+
name: wt.name,
|
|
56
|
+
path: wt.path,
|
|
57
|
+
status,
|
|
58
|
+
processes,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
export async function listLeases(poolDir, config) {
|
|
65
|
+
const result = [];
|
|
66
|
+
await withStateLock(poolDir, async () => {
|
|
67
|
+
let state = await readState(poolDir);
|
|
68
|
+
state = await healState(state);
|
|
69
|
+
for (const wt of state.worktrees) {
|
|
70
|
+
if (!wt.leaseId)
|
|
71
|
+
continue;
|
|
72
|
+
const { unverified } = await findInWorktree(wt.path);
|
|
73
|
+
try {
|
|
74
|
+
wt.currentHeadSha = await getHeadSha(wt.path);
|
|
75
|
+
}
|
|
76
|
+
catch { }
|
|
77
|
+
result.push(entryToLease(wt, unverified ? "unverified" : "verified", config.repoRoot));
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
export async function inspectLease(leaseIdOrPath, poolDir, config) {
|
|
83
|
+
let wt;
|
|
84
|
+
await withStateLock(poolDir, async () => {
|
|
85
|
+
let state = await readState(poolDir);
|
|
86
|
+
state = await healState(state);
|
|
87
|
+
wt = state.worktrees.find(w => w.leaseId === leaseIdOrPath || w.path === leaseIdOrPath);
|
|
88
|
+
});
|
|
89
|
+
if (!wt || !wt.leaseId)
|
|
90
|
+
return null;
|
|
91
|
+
const { unverified } = await findInWorktree(wt.path);
|
|
92
|
+
try {
|
|
93
|
+
wt.currentHeadSha = await getHeadSha(wt.path);
|
|
94
|
+
}
|
|
95
|
+
catch { }
|
|
96
|
+
return entryToLease(wt, unverified ? "unverified" : "verified", config.repoRoot);
|
|
97
|
+
}
|
package/dist/schemas.d.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
export declare const GroveCleanupIntentSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
3
|
+
cleanup: z.ZodLiteral<"preserve">;
|
|
4
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
5
|
+
cleanup: z.ZodLiteral<"reset">;
|
|
6
|
+
resetTo: z.ZodOptional<z.ZodString>;
|
|
7
|
+
force: z.ZodOptional<z.ZodBoolean>;
|
|
8
|
+
cleanIgnored: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
10
|
+
cleanup: z.ZodLiteral<"quarantine">;
|
|
11
|
+
}, z.core.$strip>], "cleanup">;
|
|
12
|
+
export type GroveCleanupIntent = z.infer<typeof GroveCleanupIntentSchema>;
|
|
13
|
+
export declare const LeaseIdSchema: z.ZodString;
|
|
2
14
|
export declare const WorktreeEntrySchema: z.ZodObject<{
|
|
3
15
|
name: z.ZodString;
|
|
4
16
|
path: z.ZodString;
|
|
@@ -6,6 +18,35 @@ export declare const WorktreeEntrySchema: z.ZodObject<{
|
|
|
6
18
|
destroying: z.ZodOptional<z.ZodBoolean>;
|
|
7
19
|
owner_pid: z.ZodOptional<z.ZodNumber>;
|
|
8
20
|
owner_started_at: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
leaseId: z.ZodOptional<z.ZodString>;
|
|
22
|
+
ownerId: z.ZodOptional<z.ZodString>;
|
|
23
|
+
baseRef: z.ZodOptional<z.ZodString>;
|
|
24
|
+
baseSha: z.ZodOptional<z.ZodString>;
|
|
25
|
+
acquiredHeadSha: z.ZodOptional<z.ZodString>;
|
|
26
|
+
currentHeadSha: z.ZodOptional<z.ZodString>;
|
|
27
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
28
|
+
state: z.ZodOptional<z.ZodEnum<{
|
|
29
|
+
available: "available";
|
|
30
|
+
destroying: "destroying";
|
|
31
|
+
leased: "leased";
|
|
32
|
+
quarantined: "quarantined";
|
|
33
|
+
releasing: "releasing";
|
|
34
|
+
}>>;
|
|
35
|
+
pendingCleanup: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
36
|
+
cleanup: z.ZodLiteral<"preserve">;
|
|
37
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
38
|
+
cleanup: z.ZodLiteral<"reset">;
|
|
39
|
+
resetTo: z.ZodOptional<z.ZodString>;
|
|
40
|
+
force: z.ZodOptional<z.ZodBoolean>;
|
|
41
|
+
cleanIgnored: z.ZodOptional<z.ZodBoolean>;
|
|
42
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
43
|
+
cleanup: z.ZodLiteral<"quarantine">;
|
|
44
|
+
}, z.core.$strip>], "cleanup">>;
|
|
45
|
+
processSafety: z.ZodOptional<z.ZodEnum<{
|
|
46
|
+
unverified: "unverified";
|
|
47
|
+
verified: "verified";
|
|
48
|
+
}>>;
|
|
49
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
9
50
|
}, z.core.$strip>;
|
|
10
51
|
export type WorktreeEntry = z.infer<typeof WorktreeEntrySchema>;
|
|
11
52
|
export declare const GroveStateSchema: z.ZodObject<{
|
|
@@ -16,6 +57,35 @@ export declare const GroveStateSchema: z.ZodObject<{
|
|
|
16
57
|
destroying: z.ZodOptional<z.ZodBoolean>;
|
|
17
58
|
owner_pid: z.ZodOptional<z.ZodNumber>;
|
|
18
59
|
owner_started_at: z.ZodOptional<z.ZodNumber>;
|
|
60
|
+
leaseId: z.ZodOptional<z.ZodString>;
|
|
61
|
+
ownerId: z.ZodOptional<z.ZodString>;
|
|
62
|
+
baseRef: z.ZodOptional<z.ZodString>;
|
|
63
|
+
baseSha: z.ZodOptional<z.ZodString>;
|
|
64
|
+
acquiredHeadSha: z.ZodOptional<z.ZodString>;
|
|
65
|
+
currentHeadSha: z.ZodOptional<z.ZodString>;
|
|
66
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
67
|
+
state: z.ZodOptional<z.ZodEnum<{
|
|
68
|
+
available: "available";
|
|
69
|
+
destroying: "destroying";
|
|
70
|
+
leased: "leased";
|
|
71
|
+
quarantined: "quarantined";
|
|
72
|
+
releasing: "releasing";
|
|
73
|
+
}>>;
|
|
74
|
+
pendingCleanup: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
75
|
+
cleanup: z.ZodLiteral<"preserve">;
|
|
76
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
77
|
+
cleanup: z.ZodLiteral<"reset">;
|
|
78
|
+
resetTo: z.ZodOptional<z.ZodString>;
|
|
79
|
+
force: z.ZodOptional<z.ZodBoolean>;
|
|
80
|
+
cleanIgnored: z.ZodOptional<z.ZodBoolean>;
|
|
81
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
82
|
+
cleanup: z.ZodLiteral<"quarantine">;
|
|
83
|
+
}, z.core.$strip>], "cleanup">>;
|
|
84
|
+
processSafety: z.ZodOptional<z.ZodEnum<{
|
|
85
|
+
unverified: "unverified";
|
|
86
|
+
verified: "verified";
|
|
87
|
+
}>>;
|
|
88
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
19
89
|
}, z.core.$strip>>;
|
|
20
90
|
}, z.core.$strip>;
|
|
21
91
|
export type GroveState = z.infer<typeof GroveStateSchema>;
|
|
@@ -24,10 +94,19 @@ export declare const GroveConfigSchema: z.ZodObject<{
|
|
|
24
94
|
groveDir: z.ZodOptional<z.ZodString>;
|
|
25
95
|
groveRoot: z.ZodOptional<z.ZodString>;
|
|
26
96
|
maxTrees: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
97
|
+
safeDeleteBranchPrefixes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
98
|
+
hookTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
27
99
|
hooks: z.ZodOptional<z.ZodObject<{
|
|
28
100
|
postCreate: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
101
|
+
postAcquire: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
102
|
+
preRelease: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
103
|
+
postRelease: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
29
104
|
preDestroy: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
30
105
|
}, z.core.$strip>>;
|
|
106
|
+
onHookFailure: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
107
|
+
fail: "fail";
|
|
108
|
+
ignore: "ignore";
|
|
109
|
+
}>>>;
|
|
31
110
|
fetchOnAcquire: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
32
111
|
}, z.core.$strip>;
|
|
33
112
|
export type GroveConfig = z.input<typeof GroveConfigSchema>;
|
package/dist/schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,wBAAwB;;;;;;;;;8BASnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,aAAa,aAAoF,CAAC;AAE/G,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoB9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAE3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;iBAkB5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
|
package/dist/schemas.js
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
export const GroveCleanupIntentSchema = z.discriminatedUnion("cleanup", [
|
|
3
|
+
z.object({ cleanup: z.literal("preserve") }),
|
|
4
|
+
z.object({
|
|
5
|
+
cleanup: z.literal("reset"),
|
|
6
|
+
resetTo: z.string().optional(),
|
|
7
|
+
force: z.boolean().optional(),
|
|
8
|
+
cleanIgnored: z.boolean().optional(),
|
|
9
|
+
}),
|
|
10
|
+
z.object({ cleanup: z.literal("quarantine") }),
|
|
11
|
+
]);
|
|
12
|
+
export const LeaseIdSchema = z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/, "Invalid lease ID format");
|
|
2
13
|
export const WorktreeEntrySchema = z.object({
|
|
3
14
|
name: z.string(),
|
|
4
15
|
path: z.string(),
|
|
@@ -6,6 +17,18 @@ export const WorktreeEntrySchema = z.object({
|
|
|
6
17
|
destroying: z.boolean().optional(),
|
|
7
18
|
owner_pid: z.number().optional(),
|
|
8
19
|
owner_started_at: z.number().optional(),
|
|
20
|
+
// Lease Mode fields
|
|
21
|
+
leaseId: LeaseIdSchema.optional(),
|
|
22
|
+
ownerId: z.string().optional(),
|
|
23
|
+
baseRef: z.string().optional(),
|
|
24
|
+
baseSha: z.string().optional(),
|
|
25
|
+
acquiredHeadSha: z.string().optional(),
|
|
26
|
+
currentHeadSha: z.string().optional(),
|
|
27
|
+
branch: z.string().optional(),
|
|
28
|
+
state: z.enum(["leased", "available", "releasing", "destroying", "quarantined"]).optional(),
|
|
29
|
+
pendingCleanup: GroveCleanupIntentSchema.optional(),
|
|
30
|
+
processSafety: z.enum(["verified", "unverified"]).optional(),
|
|
31
|
+
updatedAt: z.string().optional(),
|
|
9
32
|
});
|
|
10
33
|
export const GroveStateSchema = z.object({
|
|
11
34
|
worktrees: z.array(WorktreeEntrySchema),
|
|
@@ -15,11 +38,17 @@ export const GroveConfigSchema = z.object({
|
|
|
15
38
|
groveDir: z.string().optional(),
|
|
16
39
|
groveRoot: z.string().optional(),
|
|
17
40
|
maxTrees: z.number().optional().default(16),
|
|
41
|
+
safeDeleteBranchPrefixes: z.array(z.string()).optional(),
|
|
42
|
+
hookTimeoutMs: z.number().optional(),
|
|
18
43
|
hooks: z
|
|
19
44
|
.object({
|
|
20
45
|
postCreate: z.array(z.string()).optional(),
|
|
46
|
+
postAcquire: z.array(z.string()).optional(),
|
|
47
|
+
preRelease: z.array(z.string()).optional(),
|
|
48
|
+
postRelease: z.array(z.string()).optional(),
|
|
21
49
|
preDestroy: z.array(z.string()).optional(),
|
|
22
50
|
})
|
|
23
51
|
.optional(),
|
|
52
|
+
onHookFailure: z.enum(["ignore", "fail"]).optional().default("ignore"),
|
|
24
53
|
fetchOnAcquire: z.boolean().optional().default(true),
|
|
25
54
|
});
|
package/dist/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK/C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAwBrE;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnF;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK/C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAwBrE;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnF;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CA2BtE"}
|
package/dist/state.js
CHANGED
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { GroveCleanupIntent } from "./schemas.js";
|
|
2
|
+
export type WorktreeStatusInfo = "available" | "dirty" | "in-use" | "you're here";
|
|
3
|
+
export interface AcquiredSlot {
|
|
4
|
+
readonly path: string;
|
|
5
|
+
readonly name: string;
|
|
6
|
+
}
|
|
7
|
+
export interface WorktreeStatus {
|
|
8
|
+
name: string;
|
|
9
|
+
path: string;
|
|
10
|
+
status: WorktreeStatusInfo;
|
|
11
|
+
processes: {
|
|
12
|
+
PID: number;
|
|
13
|
+
Name?: string;
|
|
14
|
+
}[];
|
|
15
|
+
}
|
|
16
|
+
type AcquireMode = {
|
|
17
|
+
mode: "branch";
|
|
18
|
+
branch: string;
|
|
19
|
+
createBranch?: {
|
|
20
|
+
from: string;
|
|
21
|
+
ifExists?: "reuse" | "fail";
|
|
22
|
+
};
|
|
23
|
+
} | {
|
|
24
|
+
mode: "detached";
|
|
25
|
+
ref: string;
|
|
26
|
+
};
|
|
27
|
+
export type AcquireLeaseOptions = AcquireMode & {
|
|
28
|
+
leaseId: string;
|
|
29
|
+
ownerId?: string;
|
|
30
|
+
ifLeased?: "return-existing" | "fail";
|
|
31
|
+
fetchOnAcquire?: boolean;
|
|
32
|
+
metadata?: Record<string, string>;
|
|
33
|
+
};
|
|
34
|
+
export type ReleaseLeaseOptions = GroveCleanupIntent;
|
|
35
|
+
export interface DestroyLeaseOptions {
|
|
36
|
+
force?: boolean;
|
|
37
|
+
deleteBranch?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface RepairLeaseOptions {
|
|
40
|
+
leaseId: string;
|
|
41
|
+
action: "quarantine" | "resume-cleanup" | "force-destroy";
|
|
42
|
+
force?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface GroveLease {
|
|
45
|
+
leaseId: string;
|
|
46
|
+
ownerId?: string | undefined;
|
|
47
|
+
slotName: string;
|
|
48
|
+
path: string;
|
|
49
|
+
repoRoot: string;
|
|
50
|
+
branch?: string | undefined;
|
|
51
|
+
baseRef?: string | undefined;
|
|
52
|
+
baseSha?: string | undefined;
|
|
53
|
+
acquiredHeadSha: string;
|
|
54
|
+
currentHeadSha: string;
|
|
55
|
+
state: "leased" | "available" | "releasing" | "destroying" | "quarantined";
|
|
56
|
+
pendingCleanup?: GroveCleanupIntent | undefined;
|
|
57
|
+
processSafety?: "verified" | "unverified" | undefined;
|
|
58
|
+
createdAt: string;
|
|
59
|
+
updatedAt: string;
|
|
60
|
+
}
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,aAAa,CAAC;AAElF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,kBAAkB,CAAC;IAC3B,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7C;AAED,KAAK,WAAW,GACZ;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;KAC7B,CAAC;CACH,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEN,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,GAAG,gBAAgB,GAAG,eAAe,CAAC;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,QAAQ,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,aAAa,CAAC;IAC3E,cAAc,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAChD,aAAa,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|