opencode-hive 1.3.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/hive-core/src/index.d.ts +4 -0
  2. package/dist/hive-core/src/services/agentsMdService.d.ts +32 -0
  3. package/dist/hive-core/src/services/configService.d.ts +78 -0
  4. package/dist/hive-core/src/services/contextService.d.ts +25 -0
  5. package/dist/hive-core/src/services/dockerSandboxService.d.ts +76 -0
  6. package/dist/hive-core/src/services/featureService.d.ts +19 -0
  7. package/dist/hive-core/src/services/index.d.ts +16 -0
  8. package/dist/hive-core/src/services/planService.d.ts +15 -0
  9. package/dist/hive-core/src/services/reviewService.d.ts +12 -0
  10. package/dist/hive-core/src/services/sessionService.d.ts +18 -0
  11. package/dist/hive-core/src/services/subtaskService.d.ts +17 -0
  12. package/dist/hive-core/src/services/taskDependencyGraph.d.ts +41 -0
  13. package/dist/hive-core/src/services/taskService.d.ts +124 -0
  14. package/dist/hive-core/src/services/worktreeService.d.ts +66 -0
  15. package/dist/hive-core/src/types.d.ts +221 -0
  16. package/dist/hive-core/src/utils/detection.d.ts +14 -0
  17. package/dist/hive-core/src/utils/paths.d.ts +105 -0
  18. package/dist/index.js +17007 -16691
  19. package/dist/{agents → opencode-hive/src/agents}/architect.d.ts +1 -1
  20. package/dist/opencode-hive/src/agents/hive.d.ts +12 -0
  21. package/dist/opencode-hive/src/agents/swarm.d.ts +12 -0
  22. package/package.json +1 -1
  23. package/skills/writing-plans/SKILL.md +15 -1
  24. package/dist/agents/hive.d.ts +0 -12
  25. package/dist/agents/swarm.d.ts +0 -12
  26. /package/dist/{agents → opencode-hive/src/agents}/custom-agents.d.ts +0 -0
  27. /package/dist/{agents → opencode-hive/src/agents}/forager.d.ts +0 -0
  28. /package/dist/{agents → opencode-hive/src/agents}/hygienic.d.ts +0 -0
  29. /package/dist/{agents → opencode-hive/src/agents}/index.d.ts +0 -0
  30. /package/dist/{agents → opencode-hive/src/agents}/scout.d.ts +0 -0
  31. /package/dist/{hooks → opencode-hive/src/hooks}/system-hook.d.ts +0 -0
  32. /package/dist/{hooks → opencode-hive/src/hooks}/variant-hook.d.ts +0 -0
  33. /package/dist/{index.d.ts → opencode-hive/src/index.d.ts} +0 -0
  34. /package/dist/{mcp → opencode-hive/src/mcp}/ast-grep.d.ts +0 -0
  35. /package/dist/{mcp → opencode-hive/src/mcp}/context7.d.ts +0 -0
  36. /package/dist/{mcp → opencode-hive/src/mcp}/grep-app.d.ts +0 -0
  37. /package/dist/{mcp → opencode-hive/src/mcp}/index.d.ts +0 -0
  38. /package/dist/{mcp → opencode-hive/src/mcp}/types.d.ts +0 -0
  39. /package/dist/{mcp → opencode-hive/src/mcp}/websearch.d.ts +0 -0
  40. /package/dist/{skills → opencode-hive/src/skills}/builtin.d.ts +0 -0
  41. /package/dist/{skills → opencode-hive/src/skills}/file-loader.d.ts +0 -0
  42. /package/dist/{skills → opencode-hive/src/skills}/index.d.ts +0 -0
  43. /package/dist/{skills → opencode-hive/src/skills}/registry.generated.d.ts +0 -0
  44. /package/dist/{skills → opencode-hive/src/skills}/types.d.ts +0 -0
  45. /package/dist/{utils → opencode-hive/src/utils}/compaction-prompt.d.ts +0 -0
  46. /package/dist/{utils → opencode-hive/src/utils}/format.d.ts +0 -0
  47. /package/dist/{utils → opencode-hive/src/utils}/prompt-budgeting.d.ts +0 -0
  48. /package/dist/{utils → opencode-hive/src/utils}/prompt-file.d.ts +0 -0
  49. /package/dist/{utils → opencode-hive/src/utils}/prompt-observability.d.ts +0 -0
  50. /package/dist/{utils → opencode-hive/src/utils}/worker-prompt.d.ts +0 -0
@@ -0,0 +1,4 @@
1
+ export * from "./types.js";
2
+ export * from "./utils/paths.js";
3
+ export * from "./utils/detection.js";
4
+ export * from "./services/index.js";
@@ -0,0 +1,32 @@
1
+ import type { ContextService } from './contextService.js';
2
+ export interface InitResult {
3
+ content: string;
4
+ existed: boolean;
5
+ }
6
+ export interface SyncResult {
7
+ proposals: string[];
8
+ diff: string;
9
+ }
10
+ export interface ApplyResult {
11
+ path: string;
12
+ chars: number;
13
+ isNew: boolean;
14
+ }
15
+ export declare class AgentsMdService {
16
+ private readonly rootDir;
17
+ private readonly contextService;
18
+ constructor(rootDir: string, contextService: ContextService);
19
+ init(): Promise<InitResult>;
20
+ sync(featureName: string): Promise<SyncResult>;
21
+ apply(content: string): ApplyResult;
22
+ private extractFindings;
23
+ private generateProposals;
24
+ private formatDiff;
25
+ private scanAndGenerate;
26
+ private detectProjectInfo;
27
+ private detectPackageManager;
28
+ private detectLanguage;
29
+ private detectTestFramework;
30
+ private detectMonorepo;
31
+ private generateTemplate;
32
+ }
@@ -0,0 +1,78 @@
1
+ import type { AgentModelConfig, HiveConfig, ResolvedCustomAgentConfig } from '../types.js';
2
+ import type { SandboxConfig } from './dockerSandboxService.js';
3
+ /**
4
+ * ConfigService manages user config at ~/.config/opencode/agent_hive.json
5
+ *
6
+ * This is USER config (not project-scoped):
7
+ * - VSCode extension reads/writes this
8
+ * - OpenCode plugin reads this to enable features
9
+ * - Agent does NOT have tools to access this
10
+ */
11
+ export declare class ConfigService {
12
+ private configPath;
13
+ private cachedConfig;
14
+ private cachedCustomAgentConfigs;
15
+ constructor();
16
+ /**
17
+ * Get config path
18
+ */
19
+ getPath(): string;
20
+ /**
21
+ * Get the full config, merged with defaults.
22
+ */
23
+ get(): HiveConfig;
24
+ /**
25
+ * Update config (partial merge).
26
+ */
27
+ set(updates: Partial<HiveConfig>): HiveConfig;
28
+ /**
29
+ * Check if config file exists.
30
+ */
31
+ exists(): boolean;
32
+ /**
33
+ * Initialize config with defaults if it doesn't exist.
34
+ */
35
+ init(): HiveConfig;
36
+ /**
37
+ * Get agent-specific model config
38
+ */
39
+ getAgentConfig(agent: string): AgentModelConfig | ResolvedCustomAgentConfig;
40
+ getCustomAgentConfigs(): Record<string, ResolvedCustomAgentConfig>;
41
+ hasConfiguredAgent(agent: string): boolean;
42
+ private isBuiltInAgent;
43
+ private isReservedCustomAgentName;
44
+ private isSupportedCustomAgentBase;
45
+ private isPlannerAgent;
46
+ private isObjectRecord;
47
+ private resolveAutoLoadSkills;
48
+ /**
49
+ * Check if OMO-Slim delegation is enabled via user config.
50
+ */
51
+ isOmoSlimEnabled(): boolean;
52
+ /**
53
+ * Get list of globally disabled skills.
54
+ */
55
+ getDisabledSkills(): string[];
56
+ /**
57
+ * Get list of globally disabled MCPs.
58
+ */
59
+ getDisabledMcps(): string[];
60
+ /**
61
+ * Get sandbox configuration for worker isolation.
62
+ * Returns { mode: 'none' | 'docker', image?: string, persistent?: boolean }
63
+ */
64
+ getSandboxConfig(): SandboxConfig;
65
+ /**
66
+ * Get hook execution cadence for a specific hook.
67
+ * Returns the configured cadence or 1 (every turn) if not set.
68
+ * Validates cadence values and defaults to 1 for invalid values.
69
+ *
70
+ * @param hookName - The OpenCode hook name (e.g., 'experimental.chat.system.transform')
71
+ * @param options - Optional configuration
72
+ * @param options.safetyCritical - If true, enforces cadence=1 regardless of config
73
+ * @returns Validated cadence value (always >= 1)
74
+ */
75
+ getHookCadence(hookName: string, options?: {
76
+ safetyCritical?: boolean;
77
+ }): number;
78
+ }
@@ -0,0 +1,25 @@
1
+ import type { ContextFile } from '../types.js';
2
+ export type { ContextFile };
3
+ export declare const RESERVED_OVERVIEW_CONTEXT = "overview";
4
+ export declare class ContextService {
5
+ private projectRoot;
6
+ constructor(projectRoot: string);
7
+ write(featureName: string, fileName: string, content: string): string;
8
+ read(featureName: string, fileName: string): string | null;
9
+ list(featureName: string): ContextFile[];
10
+ getOverview(featureName: string): ContextFile | null;
11
+ listExecutionContext(featureName: string): ContextFile[];
12
+ delete(featureName: string, fileName: string): boolean;
13
+ compile(featureName: string): string;
14
+ archive(featureName: string): {
15
+ archived: string[];
16
+ archivePath: string;
17
+ };
18
+ stats(featureName: string): {
19
+ count: number;
20
+ totalChars: number;
21
+ oldest?: string;
22
+ newest?: string;
23
+ };
24
+ private normalizeFileName;
25
+ }
@@ -0,0 +1,76 @@
1
+ export interface SandboxConfig {
2
+ mode: 'none' | 'docker';
3
+ image?: string;
4
+ persistent?: boolean;
5
+ }
6
+ /**
7
+ * DockerSandboxService handles Level 1 Docker sandboxing for Hive workers.
8
+ * Uses ephemeral containers (docker run --rm) with volume mounts.
9
+ *
10
+ * Level 1: Lightweight docker run (no devcontainer.json, no persistent containers)
11
+ */
12
+ export declare class DockerSandboxService {
13
+ /**
14
+ * Detects appropriate Docker image based on project files in worktree.
15
+ *
16
+ * @param worktreePath - Path to the worktree directory
17
+ * @returns Docker image name, or null if Dockerfile exists (user manages their own)
18
+ */
19
+ static detectImage(worktreePath: string): string | null;
20
+ /**
21
+ * Builds docker run command with volume mount and working directory.
22
+ *
23
+ * @param worktreePath - Path to the worktree directory
24
+ * @param command - Command to execute inside container
25
+ * @param image - Docker image to use
26
+ * @returns Complete docker run command string
27
+ */
28
+ static buildRunCommand(worktreePath: string, command: string, image: string): string;
29
+ /**
30
+ * Generates a container name from a worktree path.
31
+ * Extracts feature and task from .hive/.worktrees/<feature>/<task> pattern.
32
+ *
33
+ * @param worktreePath - Path to the worktree directory
34
+ * @returns Container name (e.g., 'hive-my-feature-my-task')
35
+ */
36
+ static containerName(worktreePath: string): string;
37
+ /**
38
+ * Ensures a persistent container exists for the worktree.
39
+ * If container already running, returns its name.
40
+ * Otherwise, creates a new detached container.
41
+ *
42
+ * @param worktreePath - Path to the worktree directory
43
+ * @param image - Docker image to use
44
+ * @returns Container name
45
+ */
46
+ static ensureContainer(worktreePath: string, image: string): string;
47
+ /**
48
+ * Builds a docker exec command for persistent containers.
49
+ *
50
+ * @param containerName - Name of the running container
51
+ * @param command - Command to execute
52
+ * @returns Complete docker exec command string
53
+ */
54
+ static buildExecCommand(containerName: string, command: string): string;
55
+ /**
56
+ * Stops and removes a persistent container for a worktree.
57
+ *
58
+ * @param worktreePath - Path to the worktree directory
59
+ */
60
+ static stopContainer(worktreePath: string): void;
61
+ /**
62
+ * Checks if Docker is available on the system.
63
+ *
64
+ * @returns true if docker is available, false otherwise
65
+ */
66
+ static isDockerAvailable(): boolean;
67
+ /**
68
+ * Wraps a command with Docker container execution based on config.
69
+ *
70
+ * @param worktreePath - Path to the worktree directory
71
+ * @param command - Command to execute
72
+ * @param config - Sandbox configuration
73
+ * @returns Wrapped command (or original if no wrapping needed)
74
+ */
75
+ static wrapCommand(worktreePath: string, command: string, config: SandboxConfig): string;
76
+ }
@@ -0,0 +1,19 @@
1
+ import type { FeatureJson, FeatureStatusType, FeatureInfo } from '../types.js';
2
+ export declare class FeatureService {
3
+ private projectRoot;
4
+ private reviewService;
5
+ constructor(projectRoot: string);
6
+ private getReviewService;
7
+ create(name: string, ticket?: string): FeatureJson;
8
+ get(name: string): FeatureJson | null;
9
+ list(): string[];
10
+ getActive(): FeatureJson | null;
11
+ setActive(name: string): void;
12
+ updateStatus(name: string, status: FeatureStatusType): FeatureJson;
13
+ getInfo(name: string): FeatureInfo | null;
14
+ private getTasks;
15
+ complete(name: string): FeatureJson;
16
+ setSession(name: string, sessionId: string): void;
17
+ getSession(name: string): string | undefined;
18
+ private readActiveFeatureName;
19
+ }
@@ -0,0 +1,16 @@
1
+ export { FeatureService } from './featureService.js';
2
+ export { PlanService } from './planService.js';
3
+ export { TaskService } from './taskService.js';
4
+ export { SubtaskService } from './subtaskService.js';
5
+ export { WorktreeService, createWorktreeService } from './worktreeService.js';
6
+ export type { WorktreeInfo, DiffResult, ApplyResult, CommitResult, MergeResult, WorktreeConfig } from './worktreeService.js';
7
+ export { ContextService } from './contextService.js';
8
+ export { ReviewService } from './reviewService.js';
9
+ export { SessionService } from './sessionService.js';
10
+ export { ConfigService } from './configService.js';
11
+ export { AgentsMdService } from './agentsMdService.js';
12
+ export type { InitResult, SyncResult, ApplyResult as AgentsMdApplyResult } from './agentsMdService.js';
13
+ export { DockerSandboxService } from './dockerSandboxService.js';
14
+ export type { SandboxConfig } from './dockerSandboxService.js';
15
+ export { buildEffectiveDependencies, computeRunnableAndBlocked } from './taskDependencyGraph.js';
16
+ export type { TaskWithDeps, RunnableBlockedResult } from './taskDependencyGraph.js';
@@ -0,0 +1,15 @@
1
+ import type { PlanComment, PlanReadResult } from '../types.js';
2
+ export declare class PlanService {
3
+ private projectRoot;
4
+ private reviewService;
5
+ constructor(projectRoot: string);
6
+ private getReviewService;
7
+ write(featureName: string, content: string): string;
8
+ read(featureName: string): PlanReadResult | null;
9
+ approve(featureName: string): void;
10
+ isApproved(featureName: string): boolean;
11
+ revokeApproval(featureName: string): void;
12
+ getComments(featureName: string): PlanComment[];
13
+ addComment(featureName: string, comment: Omit<PlanComment, 'id'>): PlanComment;
14
+ clearComments(featureName: string): void;
15
+ }
@@ -0,0 +1,12 @@
1
+ import type { ReviewCounts, ReviewDocument, ReviewThread } from '../types.js';
2
+ export declare class ReviewService {
3
+ private projectRoot;
4
+ constructor(projectRoot: string);
5
+ getThreads(featureName: string, document: ReviewDocument): ReviewThread[];
6
+ saveThreads(featureName: string, document: ReviewDocument, threads: ReviewThread[]): void;
7
+ clear(featureName: string, document: ReviewDocument): void;
8
+ countByDocument(featureName: string): ReviewCounts;
9
+ hasUnresolvedThreads(featureName: string, document?: ReviewDocument): boolean;
10
+ private readComments;
11
+ private getCanonicalPath;
12
+ }
@@ -0,0 +1,18 @@
1
+ import { SessionInfo } from '../types.js';
2
+ export declare class SessionService {
3
+ private projectRoot;
4
+ constructor(projectRoot: string);
5
+ private getSessionsPath;
6
+ private getSessions;
7
+ private saveSessions;
8
+ track(featureName: string, sessionId: string, taskFolder?: string): SessionInfo;
9
+ setMaster(featureName: string, sessionId: string): void;
10
+ getMaster(featureName: string): string | undefined;
11
+ list(featureName: string): SessionInfo[];
12
+ get(featureName: string, sessionId: string): SessionInfo | undefined;
13
+ getByTask(featureName: string, taskFolder: string): SessionInfo | undefined;
14
+ remove(featureName: string, sessionId: string): boolean;
15
+ findFeatureBySession(sessionId: string): string | null;
16
+ fork(featureName: string, fromSessionId?: string): SessionInfo;
17
+ fresh(featureName: string, title?: string): SessionInfo;
18
+ }
@@ -0,0 +1,17 @@
1
+ import { Subtask, SubtaskType, TaskStatusType } from '../types.js';
2
+ export declare class SubtaskService {
3
+ private projectRoot;
4
+ constructor(projectRoot: string);
5
+ create(featureName: string, taskFolder: string, name: string, type?: SubtaskType): Subtask;
6
+ update(featureName: string, taskFolder: string, subtaskId: string, status: TaskStatusType): Subtask;
7
+ list(featureName: string, taskFolder: string): Subtask[];
8
+ get(featureName: string, taskFolder: string, subtaskId: string): Subtask | null;
9
+ writeSpec(featureName: string, taskFolder: string, subtaskId: string, content: string): string;
10
+ writeReport(featureName: string, taskFolder: string, subtaskId: string, content: string): string;
11
+ readSpec(featureName: string, taskFolder: string, subtaskId: string): string | null;
12
+ readReport(featureName: string, taskFolder: string, subtaskId: string): string | null;
13
+ delete(featureName: string, taskFolder: string, subtaskId: string): void;
14
+ private listFolders;
15
+ private findFolder;
16
+ private slugify;
17
+ }
@@ -0,0 +1,41 @@
1
+ import type { TaskStatusType } from '../types.js';
2
+ /**
3
+ * Minimal task info needed for dependency graph computation.
4
+ */
5
+ export interface TaskWithDeps {
6
+ folder: string;
7
+ status: TaskStatusType;
8
+ dependsOn?: string[];
9
+ }
10
+ /**
11
+ * Result of computing runnable and blocked tasks.
12
+ */
13
+ export interface RunnableBlockedResult {
14
+ /** Task folders that are pending and have all dependencies satisfied (done) */
15
+ runnable: string[];
16
+ /** Map of task folder -> array of unsatisfied dependency folders */
17
+ blocked: Record<string, string[]>;
18
+ }
19
+ /**
20
+ * Compute which pending tasks are runnable (all deps done) and which are blocked.
21
+ *
22
+ * A task is runnable if:
23
+ * - Its status is 'pending'
24
+ * - All its dependencies have status 'done'
25
+ *
26
+ * A task is blocked if:
27
+ * - Its status is 'pending'
28
+ * - At least one dependency does NOT have status 'done'
29
+ *
30
+ * Only 'done' satisfies a dependency. Other statuses (in_progress, cancelled,
31
+ * failed, blocked, partial) do NOT satisfy dependencies.
32
+ *
33
+ * @param tasks - Array of tasks with their status and dependencies
34
+ * @returns Object with runnable task folders and blocked tasks with their missing deps
35
+ */
36
+ export declare function computeRunnableAndBlocked(tasks: TaskWithDeps[]): RunnableBlockedResult;
37
+ /**
38
+ * Compute effective dependencies for each task, applying legacy numeric
39
+ * sequential fallback when dependsOn is undefined.
40
+ */
41
+ export declare function buildEffectiveDependencies(tasks: TaskWithDeps[]): Map<string, string[]>;
@@ -0,0 +1,124 @@
1
+ import { LockOptions } from '../utils/paths.js';
2
+ import { TaskStatus, TaskStatusType, TasksSyncResult, TaskInfo, Subtask, SubtaskType, WorkerSession } from '../types.js';
3
+ /** Current schema version for TaskStatus */
4
+ export declare const TASK_STATUS_SCHEMA_VERSION = 1;
5
+ /** Fields that can be updated by background workers without clobbering completion-owned fields */
6
+ export interface BackgroundPatchFields {
7
+ idempotencyKey?: string;
8
+ workerSession?: Partial<WorkerSession>;
9
+ }
10
+ /** Fields owned by the completion flow (not to be touched by background patches) */
11
+ export interface CompletionFields {
12
+ status?: TaskStatusType;
13
+ summary?: string;
14
+ completedAt?: string;
15
+ }
16
+ export declare class TaskService {
17
+ private projectRoot;
18
+ constructor(projectRoot: string);
19
+ sync(featureName: string): TasksSyncResult;
20
+ /**
21
+ * Create a manual task with auto-incrementing index.
22
+ * Folder format: "01-task-name", "02-task-name", etc.
23
+ * Index ensures alphabetical sort = chronological order.
24
+ */
25
+ create(featureName: string, name: string, order?: number): string;
26
+ private createFromPlan;
27
+ buildSpecContent(params: {
28
+ featureName: string;
29
+ task: {
30
+ folder: string;
31
+ name: string;
32
+ order: number;
33
+ description?: string;
34
+ };
35
+ dependsOn: string[];
36
+ allTasks: Array<{
37
+ folder: string;
38
+ name: string;
39
+ order: number;
40
+ }>;
41
+ planContent?: string | null;
42
+ contextFiles?: Array<{
43
+ name: string;
44
+ content: string;
45
+ }>;
46
+ completedTasks?: Array<{
47
+ name: string;
48
+ summary: string;
49
+ }>;
50
+ }): string;
51
+ private extractPlanSection;
52
+ /**
53
+ * Resolve dependency numbers to folder names.
54
+ * - If dependsOnNumbers is null (not specified), apply implicit sequential default (N-1 for N > 1).
55
+ * - If dependsOnNumbers is [] (explicit "none"), return empty array.
56
+ * - Otherwise, map numbers to corresponding task folders.
57
+ */
58
+ private resolveDependencies;
59
+ /**
60
+ * Validate the dependency graph for errors before creating tasks.
61
+ * Throws descriptive errors pointing the operator to fix plan.md.
62
+ *
63
+ * Checks for:
64
+ * - Unknown task numbers in dependencies
65
+ * - Self-dependencies
66
+ * - Cycles (using DFS topological sort)
67
+ */
68
+ private validateDependencyGraph;
69
+ /**
70
+ * Detect cycles in the dependency graph using DFS.
71
+ * Throws a descriptive error if a cycle is found.
72
+ */
73
+ private detectCycles;
74
+ writeSpec(featureName: string, taskFolder: string, content: string): string;
75
+ /**
76
+ * Update task status with locked atomic write.
77
+ * Uses file locking to prevent race conditions between concurrent updates.
78
+ *
79
+ * @param featureName - Feature name
80
+ * @param taskFolder - Task folder name
81
+ * @param updates - Fields to update (status, summary, baseCommit)
82
+ * @param lockOptions - Optional lock configuration
83
+ * @returns Updated TaskStatus
84
+ */
85
+ update(featureName: string, taskFolder: string, updates: Partial<Pick<TaskStatus, 'status' | 'summary' | 'baseCommit'>>, lockOptions?: LockOptions): TaskStatus;
86
+ /**
87
+ * Patch only background-owned fields without clobbering completion-owned fields.
88
+ * Safe for concurrent use by background workers.
89
+ *
90
+ * Uses deep merge for workerSession to allow partial updates like:
91
+ * - patchBackgroundFields(..., { workerSession: { lastHeartbeatAt: '...' } })
92
+ * will update only lastHeartbeatAt, preserving other workerSession fields.
93
+ *
94
+ * @param featureName - Feature name
95
+ * @param taskFolder - Task folder name
96
+ * @param patch - Background-owned fields to update
97
+ * @param lockOptions - Optional lock configuration
98
+ * @returns Updated TaskStatus
99
+ */
100
+ patchBackgroundFields(featureName: string, taskFolder: string, patch: BackgroundPatchFields, lockOptions?: LockOptions): TaskStatus;
101
+ /**
102
+ * Get raw TaskStatus including all fields (for internal use or debugging).
103
+ */
104
+ getRawStatus(featureName: string, taskFolder: string): TaskStatus | null;
105
+ get(featureName: string, taskFolder: string): TaskInfo | null;
106
+ list(featureName: string): TaskInfo[];
107
+ writeReport(featureName: string, taskFolder: string, report: string): string;
108
+ private listFolders;
109
+ private deleteTask;
110
+ private getNextOrder;
111
+ private parseTasksFromPlan;
112
+ createSubtask(featureName: string, taskFolder: string, name: string, type?: SubtaskType): Subtask;
113
+ updateSubtask(featureName: string, taskFolder: string, subtaskId: string, status: TaskStatusType): Subtask;
114
+ listSubtasks(featureName: string, taskFolder: string): Subtask[];
115
+ deleteSubtask(featureName: string, taskFolder: string, subtaskId: string): void;
116
+ getSubtask(featureName: string, taskFolder: string, subtaskId: string): Subtask | null;
117
+ writeSubtaskSpec(featureName: string, taskFolder: string, subtaskId: string, content: string): string;
118
+ writeSubtaskReport(featureName: string, taskFolder: string, subtaskId: string, content: string): string;
119
+ readSubtaskSpec(featureName: string, taskFolder: string, subtaskId: string): string | null;
120
+ readSubtaskReport(featureName: string, taskFolder: string, subtaskId: string): string | null;
121
+ private listSubtaskFolders;
122
+ private findSubtaskFolder;
123
+ private slugify;
124
+ }
@@ -0,0 +1,66 @@
1
+ export interface WorktreeInfo {
2
+ path: string;
3
+ branch: string;
4
+ commit: string;
5
+ feature: string;
6
+ step: string;
7
+ }
8
+ export interface DiffResult {
9
+ hasDiff: boolean;
10
+ diffContent: string;
11
+ filesChanged: string[];
12
+ insertions: number;
13
+ deletions: number;
14
+ }
15
+ export interface ApplyResult {
16
+ success: boolean;
17
+ error?: string;
18
+ filesAffected: string[];
19
+ }
20
+ export interface CommitResult {
21
+ committed: boolean;
22
+ sha: string;
23
+ message?: string;
24
+ }
25
+ export interface MergeResult {
26
+ success: boolean;
27
+ merged: boolean;
28
+ sha?: string;
29
+ filesChanged?: string[];
30
+ conflicts?: string[];
31
+ error?: string;
32
+ }
33
+ export interface WorktreeConfig {
34
+ baseDir: string;
35
+ hiveDir: string;
36
+ }
37
+ export declare class WorktreeService {
38
+ private config;
39
+ constructor(config: WorktreeConfig);
40
+ private getGit;
41
+ private getWorktreesDir;
42
+ private getWorktreePath;
43
+ private getStepStatusPath;
44
+ private getBranchName;
45
+ create(feature: string, step: string, baseBranch?: string): Promise<WorktreeInfo>;
46
+ get(feature: string, step: string): Promise<WorktreeInfo | null>;
47
+ getDiff(feature: string, step: string, baseCommit?: string): Promise<DiffResult>;
48
+ exportPatch(feature: string, step: string, baseBranch?: string): Promise<string>;
49
+ applyDiff(feature: string, step: string, baseBranch?: string): Promise<ApplyResult>;
50
+ revertDiff(feature: string, step: string, baseBranch?: string): Promise<ApplyResult>;
51
+ private parseFilesFromDiff;
52
+ revertFromSavedDiff(diffPath: string): Promise<ApplyResult>;
53
+ remove(feature: string, step: string, deleteBranch?: boolean): Promise<void>;
54
+ list(feature?: string): Promise<WorktreeInfo[]>;
55
+ cleanup(feature?: string): Promise<{
56
+ removed: string[];
57
+ pruned: boolean;
58
+ }>;
59
+ checkConflicts(feature: string, step: string, baseBranch?: string): Promise<string[]>;
60
+ checkConflictsFromSavedDiff(diffPath: string, reverse?: boolean): Promise<string[]>;
61
+ commitChanges(feature: string, step: string, message?: string): Promise<CommitResult>;
62
+ merge(feature: string, step: string, strategy?: "merge" | "squash" | "rebase", message?: string): Promise<MergeResult>;
63
+ hasUncommittedChanges(feature: string, step: string): Promise<boolean>;
64
+ private parseConflictsFromError;
65
+ }
66
+ export declare function createWorktreeService(projectDir: string): WorktreeService;