nawabari 0.1.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 (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/cli.d.ts +9 -0
  4. package/dist/cli.js +298 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/domain/doctor.d.ts +20 -0
  7. package/dist/domain/doctor.js +167 -0
  8. package/dist/domain/doctor.js.map +1 -0
  9. package/dist/domain/errors.d.ts +29 -0
  10. package/dist/domain/errors.js +42 -0
  11. package/dist/domain/errors.js.map +1 -0
  12. package/dist/domain/session-backend.d.ts +24 -0
  13. package/dist/domain/session-backend.js +206 -0
  14. package/dist/domain/session-backend.js.map +1 -0
  15. package/dist/domain/session.d.ts +89 -0
  16. package/dist/domain/session.js +47 -0
  17. package/dist/domain/session.js.map +1 -0
  18. package/dist/errors.d.ts +8 -0
  19. package/dist/errors.js +14 -0
  20. package/dist/errors.js.map +1 -0
  21. package/dist/git.d.ts +33 -0
  22. package/dist/git.js +157 -0
  23. package/dist/git.js.map +1 -0
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.js +6 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/presentation.d.ts +9 -0
  28. package/dist/presentation.js +61 -0
  29. package/dist/presentation.js.map +1 -0
  30. package/dist/registry/atomic.d.ts +20 -0
  31. package/dist/registry/atomic.js +128 -0
  32. package/dist/registry/atomic.js.map +1 -0
  33. package/dist/registry/errors.d.ts +8 -0
  34. package/dist/registry/errors.js +30 -0
  35. package/dist/registry/errors.js.map +1 -0
  36. package/dist/registry/lock.d.ts +60 -0
  37. package/dist/registry/lock.js +727 -0
  38. package/dist/registry/lock.js.map +1 -0
  39. package/dist/registry/store.d.ts +38 -0
  40. package/dist/registry/store.js +156 -0
  41. package/dist/registry/store.js.map +1 -0
  42. package/dist/registry/types.d.ts +18 -0
  43. package/dist/registry/types.js +3 -0
  44. package/dist/registry/types.js.map +1 -0
  45. package/dist/registry.d.ts +5 -0
  46. package/dist/registry.js +6 -0
  47. package/dist/registry.js.map +1 -0
  48. package/dist/session-id.d.ts +7 -0
  49. package/dist/session-id.js +32 -0
  50. package/dist/session-id.js.map +1 -0
  51. package/dist/session-registry.d.ts +169 -0
  52. package/dist/session-registry.js +1190 -0
  53. package/dist/session-registry.js.map +1 -0
  54. package/package.json +57 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/domain/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type JsonPrimitive = null | boolean | number | string;
2
+ export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
3
+ export interface JsonObject {
4
+ [key: string]: JsonValue;
5
+ }
6
+ export type ErrorCode = "BACKEND_UNAVAILABLE" | "BRANCH_OWNED_BY_OTHER_SESSION" | "BRANCH_ALREADY_EXISTS" | "DOCTOR_FAILED" | "DIRTY_WORKTREE" | "GIT_OPERATION_FAILED" | "GIT_UNAVAILABLE" | "INVALID_ARGUMENT" | "INVALID_BRANCH" | "INVALID_BASE_REF" | "INVALID_REGISTRY" | "INVALID_SESSION_ID" | "INVALID_WORKTREE" | "LOCK_CONTENTION" | "MISSING_ARGUMENT" | "NO_COMMAND" | "NO_CURRENT_SESSION" | "NOT_GIT_REPOSITORY" | "OPERATION_REJECTED" | "OWNERSHIP_MISMATCH" | "PROTECTED_BRANCH" | "PROTECTED_WORKTREE" | "RECOVERABLE_COMMITS" | "REGISTRY_CORRUPT" | "REGISTRY_UNREADABLE" | "SESSION_NOT_FOUND" | "STALE_SESSION" | "UNSUPPORTED_RUNTIME" | "UNKNOWN_COMMAND" | "WORKTREE_OWNED_BY_OTHER_SESSION" | "WORKTREE_ALREADY_EXISTS" | "INTERNAL_ERROR";
7
+ export declare const EXIT_CODES: Readonly<{
8
+ success: 0;
9
+ usage: 2;
10
+ rejected: 3;
11
+ unavailable: 4;
12
+ doctor: 5;
13
+ internal: 70;
14
+ }>;
15
+ export declare class DomainError extends Error {
16
+ readonly code: ErrorCode;
17
+ readonly exitCode: number;
18
+ readonly details: JsonObject | null;
19
+ constructor(code: ErrorCode, message: string, details?: JsonObject | null, exitCode?: number, cause?: unknown);
20
+ }
21
+ export type DomainResult<T> = {
22
+ ok: true;
23
+ value: T;
24
+ } | {
25
+ ok: false;
26
+ error: DomainError;
27
+ };
28
+ export declare function success<T>(value: T): DomainResult<T>;
29
+ export declare function failure<T = never>(error: DomainError): DomainResult<T>;
@@ -0,0 +1,42 @@
1
+ export const EXIT_CODES = Object.freeze({
2
+ success: 0,
3
+ usage: 2,
4
+ rejected: 3,
5
+ unavailable: 4,
6
+ doctor: 5,
7
+ internal: 70,
8
+ });
9
+ function defaultExitCode(code) {
10
+ if (code === "BACKEND_UNAVAILABLE")
11
+ return EXIT_CODES.unavailable;
12
+ if (code === "DOCTOR_FAILED")
13
+ return EXIT_CODES.doctor;
14
+ if (code === "UNKNOWN_COMMAND" ||
15
+ code === "NO_COMMAND" ||
16
+ code === "INVALID_ARGUMENT" ||
17
+ code === "MISSING_ARGUMENT") {
18
+ return EXIT_CODES.usage;
19
+ }
20
+ if (code === "INTERNAL_ERROR")
21
+ return EXIT_CODES.internal;
22
+ return EXIT_CODES.rejected;
23
+ }
24
+ export class DomainError extends Error {
25
+ code;
26
+ exitCode;
27
+ details;
28
+ constructor(code, message, details = null, exitCode = defaultExitCode(code), cause) {
29
+ super(message, cause === undefined ? undefined : { cause });
30
+ this.name = "DomainError";
31
+ this.code = code;
32
+ this.exitCode = exitCode;
33
+ this.details = details;
34
+ }
35
+ }
36
+ export function success(value) {
37
+ return { ok: true, value };
38
+ }
39
+ export function failure(error) {
40
+ return { ok: false, error };
41
+ }
42
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"AA0CA,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,EAAE;CACb,CAAC,CAAC;AAEH,SAAS,eAAe,CAAC,IAAe;IACtC,IAAI,IAAI,KAAK,qBAAqB;QAAE,OAAO,UAAU,CAAC,WAAW,CAAC;IAClE,IAAI,IAAI,KAAK,eAAe;QAAE,OAAO,UAAU,CAAC,MAAM,CAAC;IACvD,IACE,IAAI,KAAK,iBAAiB;QAC1B,IAAI,KAAK,YAAY;QACrB,IAAI,KAAK,kBAAkB;QAC3B,IAAI,KAAK,kBAAkB,EAC3B,CAAC;QACD,OAAO,UAAU,CAAC,KAAK,CAAC;IAC1B,CAAC;IACD,IAAI,IAAI,KAAK,gBAAgB;QAAE,OAAO,UAAU,CAAC,QAAQ,CAAC;IAC1D,OAAO,UAAU,CAAC,QAAQ,CAAC;AAC7B,CAAC;AAED,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,CAAY;IAChB,QAAQ,CAAS;IACjB,OAAO,CAAoB;IAEpC,YACE,IAAe,EACf,OAAe,EACf,UAA6B,IAAI,EACjC,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,EAChC,KAAe;QAEf,KAAK,CAAC,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAID,MAAM,UAAU,OAAO,CAAI,KAAQ;IACjC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,OAAO,CAAY,KAAkB;IACnD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { type SessionRegistryOptions } from "../session-registry.js";
2
+ import { type DomainResult } from "./errors.js";
3
+ import { type BackendCapabilities, type GarbageCollectOptions, type GarbageCollectResult, type GuardDecision, type GuardOptions, type SessionBackend, type SessionCloseOptions, type SessionCloseResult, type SessionContext, type SessionCreateOptions, type SessionListResult, type SessionRecord, type StatusResult } from "./session.js";
4
+ export interface LocalSessionBackendOptions {
5
+ readonly git?: SessionRegistryOptions["git"];
6
+ readonly registry?: Omit<SessionRegistryOptions, "cwd" | "git">;
7
+ }
8
+ export declare const LOCAL_SESSION_CAPABILITIES: BackendCapabilities;
9
+ /** SessionBackend implementation backed only by the local Git repository. */
10
+ export declare class LocalSessionBackend implements SessionBackend {
11
+ private readonly git;
12
+ private readonly registryOptions;
13
+ constructor(options?: LocalSessionBackendOptions);
14
+ createSession(context: SessionContext, options: SessionCreateOptions): Promise<DomainResult<SessionRecord>>;
15
+ resolveCurrentSession(context: SessionContext): Promise<DomainResult<SessionRecord>>;
16
+ getSession(context: SessionContext, sessionId: string): Promise<DomainResult<SessionRecord>>;
17
+ guard(context: SessionContext, options: GuardOptions): Promise<DomainResult<GuardDecision>>;
18
+ listSessions(context: SessionContext): Promise<DomainResult<SessionListResult>>;
19
+ status(context: SessionContext): Promise<DomainResult<StatusResult>>;
20
+ closeSession(context: SessionContext, options: SessionCloseOptions): Promise<DomainResult<SessionCloseResult>>;
21
+ garbageCollect(context: SessionContext, options: GarbageCollectOptions): Promise<DomainResult<GarbageCollectResult>>;
22
+ private registryFor;
23
+ }
24
+ export declare function createLocalSessionBackend(options?: LocalSessionBackendOptions): SessionBackend;
@@ -0,0 +1,206 @@
1
+ import { SessionRegistry, } from "../session-registry.js";
2
+ import { isSessionRegistryError } from "../errors.js";
3
+ import { DomainError, failure, success } from "./errors.js";
4
+ export const LOCAL_SESSION_CAPABILITIES = Object.freeze({
5
+ session_registry: true,
6
+ provisioning: true,
7
+ lifecycle: true,
8
+ garbage_collection: true,
9
+ current_session_resolution: true,
10
+ });
11
+ const REGISTRY_ERROR_CODE_MAP = Object.freeze({
12
+ GIT_COMMAND_FAILED: "GIT_OPERATION_FAILED",
13
+ NOT_A_GIT_REPOSITORY: "NOT_GIT_REPOSITORY",
14
+ REPOSITORY_IDENTITY_AMBIGUOUS: "NOT_GIT_REPOSITORY",
15
+ WORKTREE_IDENTITY_AMBIGUOUS: "INVALID_WORKTREE",
16
+ INVALID_SESSION_ID: "INVALID_SESSION_ID",
17
+ INVALID_SESSION_RECORD: "INVALID_REGISTRY",
18
+ INVALID_BRANCH_ID: "INVALID_BRANCH",
19
+ INVALID_WORKTREE_PATH: "INVALID_WORKTREE",
20
+ INVALID_BASE_REF: "INVALID_BASE_REF",
21
+ REGISTRY_CORRUPT: "REGISTRY_CORRUPT",
22
+ UNSUPPORTED_SCHEMA_VERSION: "REGISTRY_CORRUPT",
23
+ REGISTRY_REPOSITORY_MISMATCH: "INVALID_REGISTRY",
24
+ DUPLICATE_SESSION_ID: "OPERATION_REJECTED",
25
+ DUPLICATE_WORKTREE_OWNERSHIP: "WORKTREE_OWNED_BY_OTHER_SESSION",
26
+ DUPLICATE_BRANCH_OWNERSHIP: "BRANCH_OWNED_BY_OTHER_SESSION",
27
+ WORKTREE_ALREADY_EXISTS: "WORKTREE_ALREADY_EXISTS",
28
+ BRANCH_ALREADY_EXISTS: "BRANCH_ALREADY_EXISTS",
29
+ PROTECTED_WORKTREE: "PROTECTED_WORKTREE",
30
+ PROTECTED_BRANCH: "PROTECTED_BRANCH",
31
+ SESSION_ID_COLLISION: "OPERATION_REJECTED",
32
+ SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
33
+ DIRTY_WORKTREE: "DIRTY_WORKTREE",
34
+ OWNERSHIP_MISMATCH: "OWNERSHIP_MISMATCH",
35
+ RECOVERABLE_COMMITS: "RECOVERABLE_COMMITS",
36
+ REGISTRY_LOCK_TIMEOUT: "LOCK_CONTENTION",
37
+ REGISTRY_IO_FAILURE: "REGISTRY_UNREADABLE",
38
+ });
39
+ /** SessionBackend implementation backed only by the local Git repository. */
40
+ export class LocalSessionBackend {
41
+ git;
42
+ registryOptions;
43
+ constructor(options = {}) {
44
+ this.git = options.git;
45
+ this.registryOptions = options.registry ?? {};
46
+ }
47
+ async createSession(context, options) {
48
+ try {
49
+ const registry = this.registryFor(context);
50
+ const record = registry.provision({
51
+ branchName: options.branch ?? undefined,
52
+ worktreePath: options.worktree ?? undefined,
53
+ label: options.label ?? undefined,
54
+ baseRef: options.base ?? undefined,
55
+ });
56
+ return success(toDomainRecord(record));
57
+ }
58
+ catch (error) {
59
+ return failure(toDomainError(error));
60
+ }
61
+ }
62
+ async resolveCurrentSession(context) {
63
+ try {
64
+ return success(toDomainRecord(this.registryFor(context).resolveCurrentSession()));
65
+ }
66
+ catch (error) {
67
+ return failure(toDomainError(error, "NO_CURRENT_SESSION"));
68
+ }
69
+ }
70
+ async getSession(context, sessionId) {
71
+ try {
72
+ const record = this.registryFor(context).get(sessionId);
73
+ if (record === undefined) {
74
+ return failure(new DomainError("SESSION_NOT_FOUND", `Session was not found: ${sessionId}`, { session_id: sessionId }));
75
+ }
76
+ return success(toDomainRecord(record));
77
+ }
78
+ catch (error) {
79
+ return failure(toDomainError(error));
80
+ }
81
+ }
82
+ async guard(context, options) {
83
+ try {
84
+ return success(toDomainGuardDecision(this.registryFor(context).guard({ sessionId: options.session_id })));
85
+ }
86
+ catch (error) {
87
+ return failure(toDomainError(error));
88
+ }
89
+ }
90
+ async listSessions(context) {
91
+ try {
92
+ return success({ sessions: this.registryFor(context).list().map(toDomainRecord) });
93
+ }
94
+ catch (error) {
95
+ return failure(toDomainError(error));
96
+ }
97
+ }
98
+ async status(context) {
99
+ try {
100
+ const registry = this.registryFor(context);
101
+ let currentSession = null;
102
+ try {
103
+ currentSession = toDomainRecord(registry.resolveCurrentSession());
104
+ }
105
+ catch (error) {
106
+ if (!isSessionRegistryError(error) || error.code !== "SESSION_NOT_FOUND")
107
+ throw error;
108
+ }
109
+ return success({
110
+ repository: registry.repository.repositoryId,
111
+ current_session: currentSession,
112
+ sessions: registry.list().map(toDomainRecord),
113
+ capabilities: { ...LOCAL_SESSION_CAPABILITIES },
114
+ });
115
+ }
116
+ catch (error) {
117
+ return failure(toDomainError(error));
118
+ }
119
+ }
120
+ closeSession(context, options) {
121
+ try {
122
+ const registry = this.registryFor(context);
123
+ const sessionId = options.session_id ?? registry.resolveCurrentSession().sessionId;
124
+ const result = registry.close(sessionId);
125
+ return Promise.resolve(success({
126
+ session: toDomainRecord(result.session),
127
+ worktree_removed: result.worktreeRemoved,
128
+ branch_removed: result.branchRemoved,
129
+ idempotent: result.idempotent,
130
+ }));
131
+ }
132
+ catch (error) {
133
+ return Promise.resolve(failure(toDomainError(error, "NO_CURRENT_SESSION")));
134
+ }
135
+ }
136
+ garbageCollect(context, options) {
137
+ try {
138
+ const result = this.registryFor(context).garbageCollect({ apply: options.apply });
139
+ return Promise.resolve(success(toDomainGarbageCollectResult(result)));
140
+ }
141
+ catch (error) {
142
+ return Promise.resolve(failure(toDomainError(error)));
143
+ }
144
+ }
145
+ registryFor(context) {
146
+ return new SessionRegistry({ ...this.registryOptions, cwd: context.cwd, git: this.git });
147
+ }
148
+ }
149
+ export function createLocalSessionBackend(options = {}) {
150
+ return new LocalSessionBackend(options);
151
+ }
152
+ function toDomainRecord(record) {
153
+ return {
154
+ schema_version: record.schemaVersion,
155
+ session_id: record.sessionId,
156
+ repository: record.repositoryId,
157
+ worktree: record.worktreePath,
158
+ branch: record.branchName,
159
+ state: record.state,
160
+ created_at: record.createdAt,
161
+ updated_at: record.updatedAt,
162
+ ...(record.label === undefined ? {} : { label: record.label }),
163
+ };
164
+ }
165
+ function toDomainGuardDecision(decision) {
166
+ return {
167
+ allowed: decision.allowed,
168
+ code: decision.code === "ALLOWED" ? "ALLOWED" : REGISTRY_ERROR_CODE_MAP[decision.code],
169
+ repository: decision.repositoryId,
170
+ worktree: decision.worktreePath,
171
+ branch: decision.branchName,
172
+ session_id: decision.sessionId,
173
+ owner_session_id: decision.ownerSessionId,
174
+ requested_session_id: decision.requestedSessionId,
175
+ state: decision.state,
176
+ details: { ...decision.details },
177
+ };
178
+ }
179
+ function toDomainGarbageCollectResult(result) {
180
+ return {
181
+ apply: result.apply,
182
+ candidates: result.candidates.map(toDomainRecord),
183
+ cleaned: result.cleaned.map(toDomainRecord),
184
+ blocked: result.blocked.map((blocked) => ({
185
+ session_id: blocked.sessionId,
186
+ code: REGISTRY_ERROR_CODE_MAP[blocked.code],
187
+ message: blocked.message,
188
+ details: { ...blocked.details },
189
+ })),
190
+ };
191
+ }
192
+ function toDomainError(error, fallbackCode) {
193
+ if (!isSessionRegistryError(error)) {
194
+ const cause = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
195
+ return new DomainError("INTERNAL_ERROR", "An unexpected local session operation error occurred.", { cause }, undefined, error);
196
+ }
197
+ const details = { ...error.details };
198
+ const code = domainErrorCode(error, fallbackCode);
199
+ return new DomainError(code, error.message, details);
200
+ }
201
+ function domainErrorCode(error, fallbackCode) {
202
+ if (error.code === "SESSION_NOT_FOUND" && fallbackCode !== undefined)
203
+ return fallbackCode;
204
+ return REGISTRY_ERROR_CODE_MAP[error.code];
205
+ }
206
+ //# sourceMappingURL=session-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-backend.js","sourceRoot":"","sources":["../../src/domain/session-backend.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,GAIhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,sBAAsB,EAAqD,MAAM,cAAc,CAAC;AACzG,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAsD,MAAM,aAAa,CAAC;AAsBhH,MAAM,CAAC,MAAM,0BAA0B,GAAwB,MAAM,CAAC,MAAM,CAAC;IAC3E,gBAAgB,EAAE,IAAI;IACtB,YAAY,EAAE,IAAI;IAClB,SAAS,EAAE,IAAI;IACf,kBAAkB,EAAE,IAAI;IACxB,0BAA0B,EAAE,IAAI;CACjC,CAAC,CAAC;AAEH,MAAM,uBAAuB,GAAmD,MAAM,CAAC,MAAM,CAAC;IAC5F,kBAAkB,EAAE,sBAAsB;IAC1C,oBAAoB,EAAE,oBAAoB;IAC1C,6BAA6B,EAAE,oBAAoB;IACnD,2BAA2B,EAAE,kBAAkB;IAC/C,kBAAkB,EAAE,oBAAoB;IACxC,sBAAsB,EAAE,kBAAkB;IAC1C,iBAAiB,EAAE,gBAAgB;IACnC,qBAAqB,EAAE,kBAAkB;IACzC,gBAAgB,EAAE,kBAAkB;IACpC,gBAAgB,EAAE,kBAAkB;IACpC,0BAA0B,EAAE,kBAAkB;IAC9C,4BAA4B,EAAE,kBAAkB;IAChD,oBAAoB,EAAE,oBAAoB;IAC1C,4BAA4B,EAAE,iCAAiC;IAC/D,0BAA0B,EAAE,+BAA+B;IAC3D,uBAAuB,EAAE,yBAAyB;IAClD,qBAAqB,EAAE,uBAAuB;IAC9C,kBAAkB,EAAE,oBAAoB;IACxC,gBAAgB,EAAE,kBAAkB;IACpC,oBAAoB,EAAE,oBAAoB;IAC1C,iBAAiB,EAAE,mBAAmB;IACtC,cAAc,EAAE,gBAAgB;IAChC,kBAAkB,EAAE,oBAAoB;IACxC,mBAAmB,EAAE,qBAAqB;IAC1C,qBAAqB,EAAE,iBAAiB;IACxC,mBAAmB,EAAE,qBAAqB;CAC3C,CAAC,CAAC;AAEH,6EAA6E;AAC7E,MAAM,OAAO,mBAAmB;IACb,GAAG,CAAgC;IACnC,eAAe,CAA8C;IAE9E,YAAmB,UAAsC,EAAE;QACzD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;IAChD,CAAC;IAEM,KAAK,CAAC,aAAa,CACxB,OAAuB,EACvB,OAA6B;QAE7B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC;gBAChC,UAAU,EAAE,OAAO,CAAC,MAAM,IAAI,SAAS;gBACvC,YAAY,EAAE,OAAO,CAAC,QAAQ,IAAI,SAAS;gBAC3C,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS;gBACjC,OAAO,EAAE,OAAO,CAAC,IAAI,IAAI,SAAS;aACnC,CAAC,CAAC;YACH,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,qBAAqB,CAAC,OAAuB;QACxD,IAAI,CAAC;YACH,OAAO,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC;QACpF,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,OAAuB,EAAE,SAAiB;QAChE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACxD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,OAAO,OAAO,CACZ,IAAI,WAAW,CAAC,mBAAmB,EAAE,0BAA0B,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CACvG,CAAC;YACJ,CAAC;YACD,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,OAAuB,EAAE,OAAqB;QAC/D,IAAI,CAAC;YACH,OAAO,OAAO,CAAC,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5G,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,OAAuB;QAC/C,IAAI,CAAC;YACH,OAAO,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACrF,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,OAAuB;QACzC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,cAAc,GAAyB,IAAI,CAAC;YAChD,IAAI,CAAC;gBACH,cAAc,GAAG,cAAc,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC,CAAC;YACpE,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACxB,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB;oBAAE,MAAM,KAAK,CAAC;YACxF,CAAC;YACD,OAAO,OAAO,CAAC;gBACb,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY;gBAC5C,eAAe,EAAE,cAAc;gBAC/B,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC;gBAC7C,YAAY,EAAE,EAAE,GAAG,0BAA0B,EAAE;aAChD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAEM,YAAY,CACjB,OAAuB,EACvB,OAA4B;QAE5B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,IAAI,QAAQ,CAAC,qBAAqB,EAAE,CAAC,SAAS,CAAC;YACnF,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACzC,OAAO,OAAO,CAAC,OAAO,CACpB,OAAO,CAAC;gBACN,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC;gBACvC,gBAAgB,EAAE,MAAM,CAAC,eAAe;gBACxC,cAAc,EAAE,MAAM,CAAC,aAAa;gBACpC,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC,CACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAEM,cAAc,CACnB,OAAuB,EACvB,OAA8B;QAE9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;YAClF,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,OAAuB;QACzC,OAAO,IAAI,eAAe,CAAC,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3F,CAAC;CACF;AAED,MAAM,UAAU,yBAAyB,CAAC,UAAsC,EAAE;IAChF,OAAO,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,cAAc,CAAC,MAA6B;IACnD,OAAO;QACL,cAAc,EAAE,MAAM,CAAC,aAAa;QACpC,UAAU,EAAE,MAAM,CAAC,SAAS;QAC5B,UAAU,EAAE,MAAM,CAAC,YAAY;QAC/B,QAAQ,EAAE,MAAM,CAAC,YAAY;QAC7B,MAAM,EAAE,MAAM,CAAC,UAAU;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,UAAU,EAAE,MAAM,CAAC,SAAS;QAC5B,UAAU,EAAE,MAAM,CAAC,SAAS;QAC5B,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAwD;IACrF,OAAO;QACL,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,IAAI,EAAE,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,QAAQ,CAAC,IAAI,CAAC;QACtF,UAAU,EAAE,QAAQ,CAAC,YAAY;QACjC,QAAQ,EAAE,QAAQ,CAAC,YAAY;QAC/B,MAAM,EAAE,QAAQ,CAAC,UAAU;QAC3B,UAAU,EAAE,QAAQ,CAAC,SAAS;QAC9B,gBAAgB,EAAE,QAAQ,CAAC,cAAc;QACzC,oBAAoB,EAAE,QAAQ,CAAC,kBAAkB;QACjD,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,OAAO,EAAE,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE;KACjC,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,MAAoC;IACxE,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC;QACjD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC3C,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACxC,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,IAAI,EAAE,uBAAuB,CAAC,OAAO,CAAC,IAAI,CAAC;YAC3C,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE;SAChC,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,YAAwB;IAC7D,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzF,OAAO,IAAI,WAAW,CACpB,gBAAgB,EAChB,uDAAuD,EACvD,EAAE,KAAK,EAAE,EACT,SAAS,EACT,KAAK,CACN,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAe,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAClD,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,eAAe,CAAC,KAA2B,EAAE,YAAwB;IAC5E,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC;IAC1F,OAAO,uBAAuB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,89 @@
1
+ import { type DomainResult, type ErrorCode, type JsonObject } from "./errors.js";
2
+ export type SessionState = "new" | "active" | "closing" | "closed" | "stale";
3
+ export type SessionRecord = {
4
+ schema_version: number;
5
+ session_id: string;
6
+ repository: string;
7
+ worktree: string;
8
+ branch: string;
9
+ state: SessionState;
10
+ created_at: string;
11
+ updated_at: string;
12
+ label?: string;
13
+ };
14
+ export type SessionContext = {
15
+ cwd: string;
16
+ };
17
+ export type SessionCreateOptions = {
18
+ branch: string | null;
19
+ worktree: string | null;
20
+ label: string | null;
21
+ base?: string | null;
22
+ };
23
+ export type SessionCloseOptions = {
24
+ session_id: string | null;
25
+ };
26
+ export type GuardOptions = {
27
+ session_id: string | null;
28
+ };
29
+ export type GuardDecision = {
30
+ allowed: boolean;
31
+ code: ErrorCode | "ALLOWED";
32
+ repository: string;
33
+ worktree: string;
34
+ branch: string | null;
35
+ session_id: string | null;
36
+ owner_session_id: string | null;
37
+ requested_session_id: string | null;
38
+ state: SessionState | null;
39
+ details: JsonObject;
40
+ };
41
+ export type GarbageCollectOptions = {
42
+ apply: boolean;
43
+ };
44
+ export type BackendCapabilities = {
45
+ session_registry: boolean;
46
+ provisioning: boolean;
47
+ lifecycle: boolean;
48
+ garbage_collection: boolean;
49
+ current_session_resolution: boolean;
50
+ };
51
+ export type SessionListResult = {
52
+ sessions: SessionRecord[];
53
+ };
54
+ export type StatusResult = {
55
+ repository: string | null;
56
+ current_session: SessionRecord | null;
57
+ sessions: SessionRecord[];
58
+ capabilities: BackendCapabilities;
59
+ };
60
+ export type SessionCloseResult = {
61
+ session: SessionRecord;
62
+ worktree_removed: boolean;
63
+ branch_removed: boolean;
64
+ idempotent?: boolean;
65
+ };
66
+ export type GarbageCollectBlocked = {
67
+ session_id: string;
68
+ code: ErrorCode;
69
+ message: string;
70
+ details: JsonObject;
71
+ };
72
+ export type GarbageCollectResult = {
73
+ apply: boolean;
74
+ candidates: SessionRecord[];
75
+ cleaned: SessionRecord[];
76
+ blocked?: GarbageCollectBlocked[];
77
+ };
78
+ export interface SessionBackend {
79
+ createSession(context: SessionContext, options: SessionCreateOptions): Promise<DomainResult<SessionRecord>>;
80
+ resolveCurrentSession(context: SessionContext): Promise<DomainResult<SessionRecord>>;
81
+ getSession(context: SessionContext, sessionId: string): Promise<DomainResult<SessionRecord>>;
82
+ guard(context: SessionContext, options: GuardOptions): Promise<DomainResult<GuardDecision>>;
83
+ listSessions(context: SessionContext): Promise<DomainResult<SessionListResult>>;
84
+ status(context: SessionContext): Promise<DomainResult<StatusResult>>;
85
+ closeSession(context: SessionContext, options: SessionCloseOptions): Promise<DomainResult<SessionCloseResult>>;
86
+ garbageCollect(context: SessionContext, options: GarbageCollectOptions): Promise<DomainResult<GarbageCollectResult>>;
87
+ }
88
+ export declare function unavailableCapabilities(): BackendCapabilities;
89
+ export declare function createUnavailableSessionBackend(): SessionBackend;
@@ -0,0 +1,47 @@
1
+ import { DomainError, failure } from "./errors.js";
2
+ const UNAVAILABLE_CAPABILITIES = {
3
+ session_registry: false,
4
+ provisioning: false,
5
+ lifecycle: false,
6
+ garbage_collection: false,
7
+ current_session_resolution: false,
8
+ };
9
+ export function unavailableCapabilities() {
10
+ return { ...UNAVAILABLE_CAPABILITIES };
11
+ }
12
+ class UnavailableSessionBackend {
13
+ unavailable(operation) {
14
+ return Promise.resolve(failure(new DomainError("BACKEND_UNAVAILABLE", "The requested Nawabari session capability is not available.", {
15
+ operation,
16
+ capabilities: unavailableCapabilities(),
17
+ })));
18
+ }
19
+ createSession(_context, _options) {
20
+ return this.unavailable("session.create");
21
+ }
22
+ resolveCurrentSession(_context) {
23
+ return this.unavailable("session.resolve_current");
24
+ }
25
+ guard(_context, _options) {
26
+ return this.unavailable("guard");
27
+ }
28
+ getSession(_context, _sessionId) {
29
+ return this.unavailable("session.show");
30
+ }
31
+ listSessions(_context) {
32
+ return this.unavailable("session.list");
33
+ }
34
+ status(_context) {
35
+ return this.unavailable("status");
36
+ }
37
+ closeSession(_context, _options) {
38
+ return this.unavailable("session.close");
39
+ }
40
+ garbageCollect(_context, _options) {
41
+ return this.unavailable("gc");
42
+ }
43
+ }
44
+ export function createUnavailableSessionBackend() {
45
+ return new UnavailableSessionBackend();
46
+ }
47
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/domain/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAqB,OAAO,EAAmC,MAAM,aAAa,CAAC;AAuGvG,MAAM,wBAAwB,GAAwB;IACpD,gBAAgB,EAAE,KAAK;IACvB,YAAY,EAAE,KAAK;IACnB,SAAS,EAAE,KAAK;IAChB,kBAAkB,EAAE,KAAK;IACzB,0BAA0B,EAAE,KAAK;CAClC,CAAC;AAEF,MAAM,UAAU,uBAAuB;IACrC,OAAO,EAAE,GAAG,wBAAwB,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,yBAAyB;IACrB,WAAW,CAAI,SAAiB;QACtC,OAAO,OAAO,CAAC,OAAO,CACpB,OAAO,CACL,IAAI,WAAW,CAAC,qBAAqB,EAAE,6DAA6D,EAAE;YACpG,SAAS;YACT,YAAY,EAAE,uBAAuB,EAAE;SACxC,CAAC,CACH,CACF,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,QAAwB,EAAE,QAA8B;QACpE,OAAO,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC5C,CAAC;IAED,qBAAqB,CAAC,QAAwB;QAC5C,OAAO,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,QAAwB,EAAE,QAAsB;QACpD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,UAAU,CAAC,QAAwB,EAAE,UAAkB;QACrD,OAAO,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;IAC1C,CAAC;IAED,YAAY,CAAC,QAAwB;QACnC,OAAO,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,CAAC,QAAwB;QAC7B,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED,YAAY,CAAC,QAAwB,EAAE,QAA6B;QAClE,OAAO,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;IAC3C,CAAC;IAED,cAAc,CACZ,QAAwB,EACxB,QAA+B;QAE/B,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;CACF;AAED,MAAM,UAAU,+BAA+B;IAC7C,OAAO,IAAI,yBAAyB,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export type RegistryErrorCode = "GIT_COMMAND_FAILED" | "NOT_A_GIT_REPOSITORY" | "REPOSITORY_IDENTITY_AMBIGUOUS" | "WORKTREE_IDENTITY_AMBIGUOUS" | "INVALID_SESSION_ID" | "INVALID_SESSION_RECORD" | "INVALID_BRANCH_ID" | "INVALID_WORKTREE_PATH" | "INVALID_BASE_REF" | "REGISTRY_CORRUPT" | "UNSUPPORTED_SCHEMA_VERSION" | "REGISTRY_REPOSITORY_MISMATCH" | "DUPLICATE_SESSION_ID" | "DUPLICATE_WORKTREE_OWNERSHIP" | "DUPLICATE_BRANCH_OWNERSHIP" | "WORKTREE_ALREADY_EXISTS" | "BRANCH_ALREADY_EXISTS" | "PROTECTED_WORKTREE" | "PROTECTED_BRANCH" | "SESSION_ID_COLLISION" | "SESSION_NOT_FOUND" | "DIRTY_WORKTREE" | "OWNERSHIP_MISMATCH" | "RECOVERABLE_COMMITS" | "REGISTRY_LOCK_TIMEOUT" | "REGISTRY_IO_FAILURE";
2
+ export type RegistryErrorDetails = Readonly<Record<string, boolean | number | string>>;
3
+ export declare class SessionRegistryError extends Error {
4
+ readonly code: RegistryErrorCode;
5
+ readonly details: RegistryErrorDetails;
6
+ constructor(code: RegistryErrorCode, message: string, details?: RegistryErrorDetails, cause?: unknown);
7
+ }
8
+ export declare function isSessionRegistryError(error: unknown): error is SessionRegistryError;
package/dist/errors.js ADDED
@@ -0,0 +1,14 @@
1
+ export class SessionRegistryError extends Error {
2
+ code;
3
+ details;
4
+ constructor(code, message, details = {}, cause) {
5
+ super(message, { cause });
6
+ this.name = "SessionRegistryError";
7
+ this.code = code;
8
+ this.details = details;
9
+ }
10
+ }
11
+ export function isSessionRegistryError(error) {
12
+ return error instanceof SessionRegistryError;
13
+ }
14
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AA8BA,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,IAAI,CAAoB;IACxB,OAAO,CAAuB;IAEvC,YAAY,IAAuB,EAAE,OAAe,EAAE,UAAgC,EAAE,EAAE,KAAe;QACvG,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,OAAO,KAAK,YAAY,oBAAoB,CAAC;AAC/C,CAAC"}
package/dist/git.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ export interface GitCommandRunner {
2
+ run(args: readonly string[], cwd: string): string;
3
+ }
4
+ export interface RepositoryContext {
5
+ readonly repositoryId: string;
6
+ readonly commonGitDirectory: string;
7
+ readonly worktreePath: string;
8
+ }
9
+ export interface WorktreeIdentity {
10
+ readonly worktreeId: string;
11
+ readonly worktreePath: string;
12
+ readonly branchId: string;
13
+ readonly branchName: string;
14
+ }
15
+ export interface GitWorktreeInfo {
16
+ readonly worktreePath: string;
17
+ readonly branchName: string | null;
18
+ }
19
+ export interface ResolveRepositoryOptions {
20
+ readonly cwd?: string;
21
+ readonly git?: GitCommandRunner;
22
+ }
23
+ export interface ResolveWorktreeOptions extends ResolveRepositoryOptions {
24
+ readonly repository?: RepositoryContext;
25
+ readonly branchName?: string;
26
+ }
27
+ export declare const defaultGit: GitCommandRunner;
28
+ export declare function resolveRepositoryContext(options?: ResolveRepositoryOptions): RepositoryContext;
29
+ export declare function resolveWorktreeIdentity(options?: ResolveWorktreeOptions): WorktreeIdentity;
30
+ /** Read the repository's local worktree inventory without consulting a remote. */
31
+ export declare function listGitWorktrees(git: GitCommandRunner, cwd: string): readonly GitWorktreeInfo[];
32
+ export declare function normalizeBranchId(branchName: string): string;
33
+ export declare function readCurrentBranch(git: GitCommandRunner, cwd: string): string;