@1yefuwang1/dsh-worktrees 0.0.0-stage → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +218 -0
- package/LICENSE +21 -0
- package/README.md +471 -2
- package/client.js +1398 -0
- package/cordis.patch.yml +6 -0
- package/dist/context.d.ts +20 -0
- package/dist/context.js +70 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.js +30 -0
- package/dist/first-message.d.ts +19 -0
- package/dist/first-message.js +121 -0
- package/dist/git.d.ts +45 -0
- package/dist/git.js +806 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +183 -0
- package/dist/naming.d.ts +25 -0
- package/dist/naming.js +151 -0
- package/dist/project-context.d.ts +20 -0
- package/dist/project-context.js +82 -0
- package/dist/project-rpc.d.ts +10 -0
- package/dist/project-rpc.js +103 -0
- package/dist/project-store.d.ts +121 -0
- package/dist/project-store.js +32 -0
- package/dist/projects.d.ts +149 -0
- package/dist/projects.js +603 -0
- package/dist/quiet-rpc.d.ts +7 -0
- package/dist/quiet-rpc.js +125 -0
- package/dist/rpc.d.ts +10 -0
- package/dist/rpc.js +418 -0
- package/dist/runtime.d.ts +22 -0
- package/dist/runtime.js +123 -0
- package/dist/schema.d.ts +50 -0
- package/dist/schema.js +86 -0
- package/dist/service.d.ts +98 -0
- package/dist/service.js +943 -0
- package/dist/sessions.d.ts +31 -0
- package/dist/sessions.js +130 -0
- package/dist/store.d.ts +114 -0
- package/dist/store.js +44 -0
- package/dist/types.d.ts +262 -0
- package/dist/types.js +1 -0
- package/icon.svg +1 -0
- package/locale/en.json +6 -0
- package/package.json +106 -3
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { realpath } from 'node:fs/promises';
|
|
2
|
+
import { isAbsolute, resolve } from 'node:path';
|
|
3
|
+
import { WorktreeError, redact } from './errors.js';
|
|
4
|
+
export function capability(ctx, name) {
|
|
5
|
+
return ctx.get(name);
|
|
6
|
+
}
|
|
7
|
+
export function required(ctx, name) {
|
|
8
|
+
const result = capability(ctx, name);
|
|
9
|
+
if (result === undefined)
|
|
10
|
+
throw new WorktreeError('MISSING_CAPABILITY', `The ${name} capability is not mounted in the caller's composition.`);
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
export function policyOf(agent) {
|
|
14
|
+
return required(agent.ctx, 'sandboxPolicy').resolve({ session: agent.session });
|
|
15
|
+
}
|
|
16
|
+
export function requireFullAccess(agent) {
|
|
17
|
+
if (policyOf(agent).mode !== 'danger-full-access')
|
|
18
|
+
throw new WorktreeError('FULL_ACCESS_REQUIRED', 'This operation writes across the worktree and shared Git metadata. Select full access through the existing permission control, then retry; no permission is expanded automatically.');
|
|
19
|
+
}
|
|
20
|
+
export function planBlocksMutation(agent) {
|
|
21
|
+
const plan = capability(agent.ctx, 'planMode')?.get(agent);
|
|
22
|
+
return plan?.active === true || plan?.pending === true;
|
|
23
|
+
}
|
|
24
|
+
export async function localProjectPath(agent, requested, signal) {
|
|
25
|
+
const cwd = agent.session.header.cwd;
|
|
26
|
+
if (cwd === undefined)
|
|
27
|
+
throw new WorktreeError('NO_WORKSPACE', 'Select a project before using worktrees.');
|
|
28
|
+
const path = requested === undefined ? cwd : isAbsolute(requested) ? requested : resolve(cwd, requested);
|
|
29
|
+
const fs = required(agent.ctx, 'fs');
|
|
30
|
+
const target = await fs.resolve(path, { cwd, signal });
|
|
31
|
+
const mapped = fs.processPathFromHostPath(path);
|
|
32
|
+
if (mapped === undefined || resolve(mapped) !== resolve(fs.processPath(target)))
|
|
33
|
+
throw new WorktreeError('UNSUPPORTED_PROVIDER', 'Worktree management currently requires a local filesystem and subprocess execution world.');
|
|
34
|
+
return realpath(path);
|
|
35
|
+
}
|
|
36
|
+
function collect(stream, limit, controller) {
|
|
37
|
+
if (stream === undefined)
|
|
38
|
+
return Promise.reject(new WorktreeError('PROCESS_PROTOCOL', 'The subprocess provider did not expose the requested output pipe.'));
|
|
39
|
+
return new Promise((fulfill, reject) => {
|
|
40
|
+
const chunks = [];
|
|
41
|
+
let bytes = 0;
|
|
42
|
+
let failed = false;
|
|
43
|
+
const data = (chunk) => {
|
|
44
|
+
const value = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
45
|
+
bytes += value.length;
|
|
46
|
+
if (bytes > limit) {
|
|
47
|
+
if (!failed) {
|
|
48
|
+
failed = true;
|
|
49
|
+
const error = new WorktreeError('OUTPUT_LIMIT', 'Git output exceeded its bound; no truncated result is accepted.');
|
|
50
|
+
controller.abort(error);
|
|
51
|
+
reject(error);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (!failed)
|
|
55
|
+
chunks.push(value);
|
|
56
|
+
};
|
|
57
|
+
const finish = () => { cleanup(); if (!failed)
|
|
58
|
+
fulfill(Buffer.concat(chunks)); };
|
|
59
|
+
const error = (reason) => { cleanup(); if (!failed)
|
|
60
|
+
reject(reason); };
|
|
61
|
+
const cleanup = () => { stream.off('data', data); stream.off('end', finish); stream.off('close', finish); stream.off('error', error); };
|
|
62
|
+
stream.on('data', data);
|
|
63
|
+
stream.once('end', finish);
|
|
64
|
+
stream.once('close', finish);
|
|
65
|
+
stream.once('error', error);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** No native spawn fallback: every production Git command uses the caller's managed capabilities. */
|
|
69
|
+
export function createExecutor(agent, config, shutdown) {
|
|
70
|
+
const subprocess = required(agent.ctx, 'subprocess');
|
|
71
|
+
return async (spec) => {
|
|
72
|
+
const controller = new AbortController();
|
|
73
|
+
let timedOut = false;
|
|
74
|
+
const timeout = setTimeout(() => { timedOut = true; controller.abort(new WorktreeError('TIMEOUT', 'The Git command exceeded its deadline.')); }, spec.timeoutMs ?? config.commandTimeoutMs);
|
|
75
|
+
const signals = [controller.signal, spec.signal, shutdown].filter((s) => s !== undefined);
|
|
76
|
+
const signal = AbortSignal.any(signals);
|
|
77
|
+
let handle;
|
|
78
|
+
try {
|
|
79
|
+
const executable = await subprocess.resolveExecutable(config.gitExecutable, spec.env, signal);
|
|
80
|
+
let argv = [executable, ...spec.args];
|
|
81
|
+
const policy = policyOf(agent);
|
|
82
|
+
if (policy.mode !== 'danger-full-access') {
|
|
83
|
+
const sandbox = required(agent.ctx, 'sandbox');
|
|
84
|
+
const confined = await sandbox.confine(argv, policy, signal);
|
|
85
|
+
if (confined.enforcement !== 'full')
|
|
86
|
+
throw new WorktreeError('INCOMPLETE_SANDBOX', 'The available sandbox cannot fully enforce this operation.');
|
|
87
|
+
argv = confined.argv;
|
|
88
|
+
}
|
|
89
|
+
handle = subprocess.spawn({ argv, cwd: spec.cwd, env: spec.env, signal, graceMs: 1500, stdio: { stdin: spec.stdin === undefined ? 'ignore' : 'pipe', stdout: 'pipe', stderr: 'pipe' } });
|
|
90
|
+
const stdout = collect(handle.stdout, spec.maxBytes ?? 65536, controller);
|
|
91
|
+
const stderr = collect(handle.stderr, 65536, controller);
|
|
92
|
+
if (spec.stdin !== undefined) {
|
|
93
|
+
if (handle.stdin === undefined)
|
|
94
|
+
throw new WorktreeError('PROCESS_PROTOCOL', 'The subprocess provider did not expose its input pipe.');
|
|
95
|
+
handle.stdin.on('error', () => undefined);
|
|
96
|
+
handle.stdin.end(typeof spec.stdin === 'string' ? spec.stdin : Buffer.from(spec.stdin));
|
|
97
|
+
}
|
|
98
|
+
const [out, err, outcome] = await Promise.all([stdout, stderr, handle.done]);
|
|
99
|
+
if (signal.aborted)
|
|
100
|
+
throw timedOut ? new WorktreeError('TIMEOUT', 'The Git command exceeded its deadline.') : new WorktreeError('CANCELLED', 'Git was cancelled; committed effects may remain.');
|
|
101
|
+
if (!await handle.waitForExit(signal))
|
|
102
|
+
throw new WorktreeError('PROCESS_NOT_QUIESCENT', 'The provider could not confirm that the Git process range exited.');
|
|
103
|
+
if (outcome.exitCode === null || !(spec.allowedExitCodes ?? [0]).includes(outcome.exitCode))
|
|
104
|
+
throw new WorktreeError('GIT_FAILED', `Git failed${outcome.exitCode === null ? '' : ` (${outcome.exitCode})`}: ${redact(err.toString('utf8')) || 'no diagnostic'}`);
|
|
105
|
+
return { stdout: out, stderr: err, exitCode: outcome.exitCode };
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
handle?.terminate();
|
|
109
|
+
if (handle !== undefined) {
|
|
110
|
+
await handle.waitForExit(AbortSignal.timeout(5000)).catch(() => false);
|
|
111
|
+
handle.stdout?.destroy();
|
|
112
|
+
handle.stderr?.destroy();
|
|
113
|
+
handle.stdin?.destroy();
|
|
114
|
+
}
|
|
115
|
+
if (timedOut)
|
|
116
|
+
throw new WorktreeError('TIMEOUT', 'The Git command exceeded its deadline.');
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
clearTimeout(timeout);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { WorktreeAction, WorktreeRequest } from './types.js';
|
|
3
|
+
export declare const ACTIONS: readonly ["list", "status", "branches", "create", "start", "branch", "protect", "preview", "export", "handoff", "archive"];
|
|
4
|
+
export declare const requestSchema: z.ZodObject<{
|
|
5
|
+
action: z.ZodEnum<{
|
|
6
|
+
create: "create";
|
|
7
|
+
handoff: "handoff";
|
|
8
|
+
list: "list";
|
|
9
|
+
status: "status";
|
|
10
|
+
branches: "branches";
|
|
11
|
+
start: "start";
|
|
12
|
+
branch: "branch";
|
|
13
|
+
protect: "protect";
|
|
14
|
+
preview: "preview";
|
|
15
|
+
export: "export";
|
|
16
|
+
archive: "archive";
|
|
17
|
+
}>;
|
|
18
|
+
repoPath: z.ZodOptional<z.ZodString>;
|
|
19
|
+
id: z.ZodOptional<z.ZodString>;
|
|
20
|
+
operationId: z.ZodOptional<z.ZodString>;
|
|
21
|
+
remote: z.ZodOptional<z.ZodString>;
|
|
22
|
+
remoteIdentity: z.ZodOptional<z.ZodString>;
|
|
23
|
+
remoteBranch: z.ZodOptional<z.ZodString>;
|
|
24
|
+
sourceSessionId: z.ZodOptional<z.ZodString>;
|
|
25
|
+
sessionMode: z.ZodOptional<z.ZodEnum<{
|
|
26
|
+
new: "new";
|
|
27
|
+
continue: "continue";
|
|
28
|
+
}>>;
|
|
29
|
+
requireBlankSource: z.ZodOptional<z.ZodBoolean>;
|
|
30
|
+
settingsHash: z.ZodOptional<z.ZodString>;
|
|
31
|
+
firstPrompt: z.ZodOptional<z.ZodString>;
|
|
32
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
33
|
+
folderId: z.ZodOptional<z.ZodString>;
|
|
34
|
+
name: z.ZodOptional<z.ZodString>;
|
|
35
|
+
protected: z.ZodOptional<z.ZodBoolean>;
|
|
36
|
+
archived: z.ZodOptional<z.ZodBoolean>;
|
|
37
|
+
previewId: z.ZodOptional<z.ZodString>;
|
|
38
|
+
targetPath: z.ZodOptional<z.ZodString>;
|
|
39
|
+
query: z.ZodOptional<z.ZodString>;
|
|
40
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
41
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
42
|
+
includeArchived: z.ZodOptional<z.ZodBoolean>;
|
|
43
|
+
}, z.core.$strict>;
|
|
44
|
+
export declare function parseRequest(value: unknown): WorktreeRequest;
|
|
45
|
+
export declare function parseCommand(raw: string): WorktreeRequest;
|
|
46
|
+
export declare function hashValue(value: unknown): string;
|
|
47
|
+
export declare const mutationActions: Set<WorktreeAction>;
|
|
48
|
+
export declare const fullAccessActions: Set<WorktreeAction>;
|
|
49
|
+
/** Zod attaches non-JSON ~standard helpers; the tool registry requires a plain lossless JSON snapshot. */
|
|
50
|
+
export declare const parameterSchema: Record<string, unknown>;
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { WorktreeError } from './errors.js';
|
|
4
|
+
export const ACTIONS = ['list', 'status', 'branches', 'create', 'start', 'branch', 'protect', 'preview', 'export', 'handoff', 'archive'];
|
|
5
|
+
const text = z.string().min(1).max(4096);
|
|
6
|
+
const id = z.string().uuid();
|
|
7
|
+
export const requestSchema = z.object({
|
|
8
|
+
action: z.enum(ACTIONS), repoPath: text.optional(), id: id.optional(), operationId: id.optional(),
|
|
9
|
+
remote: text.optional(), remoteIdentity: text.optional(), remoteBranch: text.optional(),
|
|
10
|
+
sourceSessionId: z.string().min(1).max(256).optional(), sessionMode: z.enum(['new', 'continue']).optional(),
|
|
11
|
+
requireBlankSource: z.boolean().optional(), settingsHash: z.string().max(128).optional(),
|
|
12
|
+
firstPrompt: z.string().max(65536).describe('Initial task text for automatic naming; only create accepts it.').optional(),
|
|
13
|
+
projectId: id.describe('Logical project ID from workspace_project list; pair with folderId on create.').optional(),
|
|
14
|
+
folderId: z.string().min(1).max(256).describe('Project folder ID from workspace_project list; pair with projectId on create.').optional(),
|
|
15
|
+
name: text.optional(), protected: z.boolean().optional(), archived: z.boolean().optional(),
|
|
16
|
+
previewId: id.optional(), targetPath: text.optional(), query: z.string().max(256).optional(),
|
|
17
|
+
cursor: z.string().max(512).optional(), limit: z.number().int().min(1).max(100).optional(), includeArchived: z.boolean().optional(),
|
|
18
|
+
}).strict();
|
|
19
|
+
const fields = {
|
|
20
|
+
list: ['repoPath', 'cursor', 'limit', 'includeArchived'],
|
|
21
|
+
status: ['repoPath', 'id', 'operationId'],
|
|
22
|
+
branches: ['repoPath', 'remote', 'remoteIdentity', 'query', 'cursor', 'limit'],
|
|
23
|
+
create: ['repoPath', 'operationId', 'remote', 'remoteIdentity', 'remoteBranch', 'sourceSessionId', 'sessionMode', 'requireBlankSource', 'settingsHash', 'firstPrompt', 'projectId', 'folderId'],
|
|
24
|
+
start: ['id', 'sourceSessionId', 'sessionMode'],
|
|
25
|
+
branch: ['id', 'name'], protect: ['id', 'protected'],
|
|
26
|
+
preview: ['id', 'sourceSessionId', 'targetPath'], export: ['previewId'],
|
|
27
|
+
handoff: ['id', 'previewId', 'operationId'], archive: ['id', 'archived'],
|
|
28
|
+
};
|
|
29
|
+
export function parseRequest(value) {
|
|
30
|
+
const parsed = requestSchema.safeParse(value);
|
|
31
|
+
if (!parsed.success)
|
|
32
|
+
throw new WorktreeError('INVALID_REQUEST', parsed.error.issues.map(i => `${i.path.join('.') || 'request'}: ${i.message}`).join('; '));
|
|
33
|
+
const request = parsed.data;
|
|
34
|
+
for (const key of Object.keys(request))
|
|
35
|
+
if (key !== 'action' && !fields[request.action].includes(key))
|
|
36
|
+
throw new WorktreeError('INVALID_REQUEST', `${request.action} does not accept ${key}.`);
|
|
37
|
+
const required = {
|
|
38
|
+
create: ['operationId', 'remote', 'remoteBranch'], start: ['id'], branch: ['id', 'name'], protect: ['id', 'protected'],
|
|
39
|
+
preview: ['id'], export: ['previewId'], handoff: ['id', 'previewId', 'operationId'], archive: ['id'], branches: ['remote'],
|
|
40
|
+
};
|
|
41
|
+
for (const key of required[request.action] ?? [])
|
|
42
|
+
if (request[key] === undefined)
|
|
43
|
+
throw new WorktreeError('INVALID_REQUEST', `${request.action} requires ${key}.`);
|
|
44
|
+
if (request.action === 'status' && request.id !== undefined && request.operationId !== undefined)
|
|
45
|
+
throw new WorktreeError('INVALID_REQUEST', 'Status accepts either id or operationId, not both.');
|
|
46
|
+
if ((request.projectId === undefined) !== (request.folderId === undefined))
|
|
47
|
+
throw new WorktreeError('INVALID_REQUEST', 'Supply projectId and folderId together on create.');
|
|
48
|
+
return request;
|
|
49
|
+
}
|
|
50
|
+
export function parseCommand(raw) {
|
|
51
|
+
const line = raw.trim();
|
|
52
|
+
if (line === '')
|
|
53
|
+
return { action: 'list' };
|
|
54
|
+
try {
|
|
55
|
+
if (line.startsWith('{'))
|
|
56
|
+
return parseRequest(JSON.parse(line));
|
|
57
|
+
const match = /^([a-z]+)(?:\s+([\s\S]+))?$/u.exec(line);
|
|
58
|
+
if (match === null)
|
|
59
|
+
throw new WorktreeError('INVALID_REQUEST', 'Use /worktree <action> [JSON arguments].');
|
|
60
|
+
const args = match[2] === undefined ? {} : JSON.parse(match[2]);
|
|
61
|
+
if (args === null || typeof args !== 'object' || Array.isArray(args))
|
|
62
|
+
throw new WorktreeError('INVALID_REQUEST', 'Arguments must be a JSON object.');
|
|
63
|
+
if ('action' in args)
|
|
64
|
+
throw new WorktreeError('INVALID_REQUEST', 'Supply action once, before the JSON arguments.');
|
|
65
|
+
return parseRequest({ ...args, action: match[1] });
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (error instanceof WorktreeError)
|
|
69
|
+
throw error;
|
|
70
|
+
throw new WorktreeError('INVALID_REQUEST', 'Arguments must be valid JSON.');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export function hashValue(value) {
|
|
74
|
+
const canonical = (input) => {
|
|
75
|
+
if (Array.isArray(input))
|
|
76
|
+
return input.map(canonical);
|
|
77
|
+
if (input !== null && typeof input === 'object')
|
|
78
|
+
return Object.fromEntries(Object.entries(input).filter(([, v]) => v !== undefined).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => [k, canonical(v)]));
|
|
79
|
+
return input;
|
|
80
|
+
};
|
|
81
|
+
return createHash('sha256').update(JSON.stringify(canonical(value))).digest('hex');
|
|
82
|
+
}
|
|
83
|
+
export const mutationActions = new Set(['create', 'start', 'branch', 'protect', 'handoff', 'archive']);
|
|
84
|
+
export const fullAccessActions = new Set(['create', 'start', 'branch', 'preview', 'export', 'handoff']);
|
|
85
|
+
/** Zod attaches non-JSON ~standard helpers; the tool registry requires a plain lossless JSON snapshot. */
|
|
86
|
+
export const parameterSchema = JSON.parse(JSON.stringify(z.toJSONSchema(requestSchema)));
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
3
|
+
import { type SessionEvent } from '@deepseek-ai/dsh-session';
|
|
4
|
+
import { GitOperations } from './git.js';
|
|
5
|
+
import { localProjectPath } from './runtime.js';
|
|
6
|
+
import { SessionBootstrap } from './sessions.js';
|
|
7
|
+
import type { WorktreeStore } from './store.js';
|
|
8
|
+
import type { ProjectController } from './projects.js';
|
|
9
|
+
import type { CheckoutState, WorktreeConfig, WorktreeRecord, WorktreeRequest, WorktreeSetupProgress } from './types.js';
|
|
10
|
+
export interface Invocation {
|
|
11
|
+
agent: Agent;
|
|
12
|
+
origin: 'tool' | 'command' | 'ui';
|
|
13
|
+
signal: AbortSignal;
|
|
14
|
+
/** Internal observer only: cannot authorize operations; failures are ignored. */
|
|
15
|
+
onProgress?: (progress: WorktreeSetupProgress) => void;
|
|
16
|
+
/** Internal admission snapshot only; execute always replaces caller-supplied values. */
|
|
17
|
+
capturedRoot?: string;
|
|
18
|
+
}
|
|
19
|
+
type GitApi = Pick<GitOperations, 'discover' | 'remotes' | 'branches' | 'create' | 'verify' | 'status' | 'createBranch' | 'renameBranch' | 'fingerprint' | 'snapshot' | 'apply'>;
|
|
20
|
+
type BootstrapApi = Pick<SessionBootstrap, 'actor' | 'isLive' | 'settings' | 'assertBlank' | 'create' | 'close'>;
|
|
21
|
+
export interface ControllerDependencies {
|
|
22
|
+
git?: (actor: Agent, signal: AbortSignal, guard: () => void) => GitApi;
|
|
23
|
+
bootstrap?: BootstrapApi;
|
|
24
|
+
/** Live destination setting for newly admitted creates only; other roots stay static. */
|
|
25
|
+
worktreeRoot?: () => string;
|
|
26
|
+
localPath?: typeof localProjectPath;
|
|
27
|
+
onNamingEligible?: (agent: Agent) => void;
|
|
28
|
+
projects?: Pick<ProjectController, 'resolveFolder' | 'folderForPath' | 'selectionForWorktree' | 'ensureFolder' | 'recordThread' | 'bindingFor'>;
|
|
29
|
+
}
|
|
30
|
+
/** Validate before any filesystem/Git/naming effects; legacy plain configs may be relative. */
|
|
31
|
+
export declare function resolveWorktreeRoot(value: unknown, allowRelative?: boolean): string;
|
|
32
|
+
/** Caller-authorized operations; shared Git metadata is serialized per canonical common directory. */
|
|
33
|
+
export declare class WorktreeController {
|
|
34
|
+
private readonly owner;
|
|
35
|
+
private readonly config;
|
|
36
|
+
private readonly store;
|
|
37
|
+
private readonly dependencies;
|
|
38
|
+
private readonly bootstrap;
|
|
39
|
+
private readonly shutdown;
|
|
40
|
+
private readonly queues;
|
|
41
|
+
private readonly flights;
|
|
42
|
+
private readonly statuses;
|
|
43
|
+
private readonly previews;
|
|
44
|
+
private readonly namingPreparations;
|
|
45
|
+
private generation;
|
|
46
|
+
private readonly cursors;
|
|
47
|
+
private closed;
|
|
48
|
+
constructor(owner: Context, config: WorktreeConfig, store: WorktreeStore, dependencies?: ControllerDependencies);
|
|
49
|
+
records(): WorktreeRecord[];
|
|
50
|
+
cachedStatus(id: string): CheckoutState | undefined;
|
|
51
|
+
execute(request: WorktreeRequest, invocation: Invocation): Promise<unknown>;
|
|
52
|
+
private namingTask;
|
|
53
|
+
skipFirstMessageName(id: string, reason: string): Promise<void>;
|
|
54
|
+
prepareFirstMessageName(id: string, agent: Agent, event: SessionEvent<'user/message'> | undefined, signal: AbortSignal): Promise<void>;
|
|
55
|
+
private namingInvocation;
|
|
56
|
+
private messageForNaming;
|
|
57
|
+
private prepareName;
|
|
58
|
+
finishFirstMessageName(id: string, agent: Agent, signal: AbortSignal): Promise<void>;
|
|
59
|
+
private namingMaintenance;
|
|
60
|
+
private finishName;
|
|
61
|
+
close(): Promise<void>;
|
|
62
|
+
private guard;
|
|
63
|
+
private git;
|
|
64
|
+
private local;
|
|
65
|
+
private projectSelection;
|
|
66
|
+
private assertProject;
|
|
67
|
+
private bindThread;
|
|
68
|
+
private queued;
|
|
69
|
+
private record;
|
|
70
|
+
private usable;
|
|
71
|
+
private putRecord;
|
|
72
|
+
private putOperation;
|
|
73
|
+
private progress;
|
|
74
|
+
private operationResult;
|
|
75
|
+
private cursor;
|
|
76
|
+
private nextCursor;
|
|
77
|
+
private run;
|
|
78
|
+
private status;
|
|
79
|
+
private branches;
|
|
80
|
+
private normalizedCreate;
|
|
81
|
+
private sameSettings;
|
|
82
|
+
private newOperation;
|
|
83
|
+
private phase;
|
|
84
|
+
private receipt;
|
|
85
|
+
private journalFailure;
|
|
86
|
+
private create;
|
|
87
|
+
private start;
|
|
88
|
+
private candidates;
|
|
89
|
+
private checkIdle;
|
|
90
|
+
private checkClaimed;
|
|
91
|
+
private claims;
|
|
92
|
+
private sourceIn;
|
|
93
|
+
private preview;
|
|
94
|
+
private previewById;
|
|
95
|
+
private exportPatch;
|
|
96
|
+
private handoff;
|
|
97
|
+
}
|
|
98
|
+
export {};
|