@lumenflow/core 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,6 +21,12 @@ interface WUOption {
21
21
  isRepeatable?: boolean;
22
22
  }
23
23
  export declare const WU_OPTIONS: Record<string, WUOption>;
24
+ /**
25
+ * WU-1062: Additional options for wu:create command
26
+ *
27
+ * These options control how wu:create handles spec storage and branch creation.
28
+ */
29
+ export declare const WU_CREATE_OPTIONS: Record<string, WUOption>;
24
30
  /**
25
31
  * Create a commander-based CLI parser for a WU script.
26
32
  *
@@ -396,6 +396,32 @@ export const WU_OPTIONS = {
396
396
  description: 'Skip automatic pnpm install in worktree after creation (faster claims when deps already built)',
397
397
  },
398
398
  };
399
+ /**
400
+ * WU-1062: Additional options for wu:create command
401
+ *
402
+ * These options control how wu:create handles spec storage and branch creation.
403
+ */
404
+ export const WU_CREATE_OPTIONS = {
405
+ /**
406
+ * Create plan template in $LUMENFLOW_HOME/plans/
407
+ * Used with spec branch mode to store plans externally.
408
+ */
409
+ plan: {
410
+ name: 'plan',
411
+ flags: '--plan',
412
+ description: 'Create plan template in $LUMENFLOW_HOME/plans/ (external plan storage for traceability)',
413
+ },
414
+ /**
415
+ * Direct main-write mode (legacy behavior)
416
+ * Writes WU spec directly to main branch instead of spec branch.
417
+ * Use for emergency/hotfix scenarios or when spec branch workflow is not desired.
418
+ */
419
+ direct: {
420
+ name: 'direct',
421
+ flags: '--direct',
422
+ description: 'Write to main directly (legacy behavior). Default is spec branch mode (spec/wu-XXXX)',
423
+ },
424
+ };
399
425
  /**
400
426
  * Negated options that commander handles specially.
401
427
  * --no-foo creates opts.foo = false. We convert to noFoo = true.
@@ -66,6 +66,13 @@ export declare class GitAdapter {
66
66
  * await git.getStatus(); // " M file.txt\n?? untracked.txt"
67
67
  */
68
68
  getStatus(): Promise<string>;
69
+ /**
70
+ * Get unpushed commits (compared to upstream)
71
+ * @returns {Promise<string>} Oneline log output for unpushed commits
72
+ * @example
73
+ * await git.getUnpushedCommits(); // "abc123 fix: ...\n"
74
+ */
75
+ getUnpushedCommits(): Promise<string>;
69
76
  /**
70
77
  * Check if a branch exists
71
78
  * @param {string} branch - Branch name
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import { simpleGit } from 'simple-git';
20
20
  import { existsSync, rmSync } from 'node:fs';
21
- import { GIT_FLAGS } from './wu-constants.js';
21
+ import { GIT_COMMANDS, GIT_FLAGS, GIT_REFS } from './wu-constants.js';
22
22
  // WU-2242: Runtime assertion helpers
23
23
  /**
24
24
  * Assert that a value is a non-empty string
@@ -117,6 +117,20 @@ export class GitAdapter {
117
117
  const result = await this.git.raw(['status', GIT_FLAGS.PORCELAIN]);
118
118
  return result.trim();
119
119
  }
120
+ /**
121
+ * Get unpushed commits (compared to upstream)
122
+ * @returns {Promise<string>} Oneline log output for unpushed commits
123
+ * @example
124
+ * await git.getUnpushedCommits(); // "abc123 fix: ...\n"
125
+ */
126
+ async getUnpushedCommits() {
127
+ const result = await this.git.raw([
128
+ GIT_COMMANDS.LOG,
129
+ GIT_REFS.UPSTREAM_RANGE,
130
+ GIT_FLAGS.ONELINE,
131
+ ]);
132
+ return result.trim();
133
+ }
120
134
  /**
121
135
  * Check if a branch exists
122
136
  * @param {string} branch - Branch name
package/dist/index.d.ts CHANGED
@@ -41,3 +41,5 @@ export * from './stamp-utils.js';
41
41
  export * from './lumenflow-config.js';
42
42
  export * from './lumenflow-config-schema.js';
43
43
  export * from './branch-check.js';
44
+ export * from './lumenflow-home.js';
45
+ export * from './spec-branch-helpers.js';
package/dist/index.js CHANGED
@@ -61,3 +61,6 @@ export * from './lumenflow-config.js';
61
61
  export * from './lumenflow-config-schema.js';
62
62
  // Branch check utilities
63
63
  export * from './branch-check.js';
64
+ // WU-1062: External plan storage and spec branch helpers
65
+ export * from './lumenflow-home.js';
66
+ export * from './spec-branch-helpers.js';
@@ -0,0 +1,130 @@
1
+ /**
2
+ * LumenFlow Home Directory Resolution
3
+ *
4
+ * WU-1062: External plan storage and no-main-write mode
5
+ *
6
+ * Provides helpers for resolving the $LUMENFLOW_HOME directory and related paths.
7
+ * Plans are stored externally in $LUMENFLOW_HOME/plans/ instead of in the repo.
8
+ *
9
+ * Default: ~/.lumenflow/
10
+ * Override: Set $LUMENFLOW_HOME environment variable
11
+ *
12
+ * @module
13
+ */
14
+ /**
15
+ * Environment variable name for LumenFlow home directory
16
+ */
17
+ export declare const LUMENFLOW_HOME_ENV = "LUMENFLOW_HOME";
18
+ /**
19
+ * Default LumenFlow home directory name
20
+ */
21
+ export declare const DEFAULT_LUMENFLOW_DIR = ".lumenflow";
22
+ /**
23
+ * Plans subdirectory name
24
+ */
25
+ export declare const PLANS_SUBDIR = "plans";
26
+ /**
27
+ * Custom protocol for external LumenFlow paths
28
+ */
29
+ export declare const LUMENFLOW_PROTOCOL = "lumenflow://";
30
+ /**
31
+ * Environment variable prefix for spec_refs
32
+ */
33
+ export declare const LUMENFLOW_HOME_VAR_PREFIX = "$LUMENFLOW_HOME";
34
+ /**
35
+ * Get the LumenFlow home directory path
36
+ *
37
+ * Resolution order:
38
+ * 1. $LUMENFLOW_HOME environment variable (with ~ expansion)
39
+ * 2. ~/.lumenflow/ default
40
+ *
41
+ * @returns {string} Absolute path to LumenFlow home directory
42
+ *
43
+ * @example
44
+ * // With LUMENFLOW_HOME=/custom/path
45
+ * getLumenflowHome() // '/custom/path'
46
+ *
47
+ * @example
48
+ * // With LUMENFLOW_HOME=~/.custom-lumenflow
49
+ * getLumenflowHome() // '/home/user/.custom-lumenflow'
50
+ *
51
+ * @example
52
+ * // Without LUMENFLOW_HOME set
53
+ * getLumenflowHome() // '/home/user/.lumenflow'
54
+ */
55
+ export declare function getLumenflowHome(): string;
56
+ /**
57
+ * Get the plans directory path
58
+ *
59
+ * Plans are stored in $LUMENFLOW_HOME/plans/
60
+ *
61
+ * @returns {string} Absolute path to plans directory
62
+ *
63
+ * @example
64
+ * getPlansDir() // '/home/user/.lumenflow/plans'
65
+ */
66
+ export declare function getPlansDir(): string;
67
+ /**
68
+ * Check if a path is an external (non-repo) path
69
+ *
70
+ * External paths include:
71
+ * - Paths starting with ~/
72
+ * - Paths starting with $LUMENFLOW_HOME
73
+ * - Paths using lumenflow:// protocol
74
+ * - Absolute paths (starting with /)
75
+ *
76
+ * @param {string} path - Path to check
77
+ * @returns {boolean} True if path is external
78
+ *
79
+ * @example
80
+ * isExternalPath('~/.lumenflow/plans/plan.md') // true
81
+ * isExternalPath('$LUMENFLOW_HOME/plans/plan.md') // true
82
+ * isExternalPath('lumenflow://plans/plan.md') // true
83
+ * isExternalPath('/home/user/.lumenflow/plans/plan.md') // true
84
+ * isExternalPath('docs/04-operations/plans/plan.md') // false
85
+ */
86
+ export declare function isExternalPath(path: string): boolean;
87
+ /**
88
+ * Normalize a spec_ref path by expanding variables and protocols
89
+ *
90
+ * Expands:
91
+ * - lumenflow://path -> $LUMENFLOW_HOME/path
92
+ * - ~/path -> /home/user/path
93
+ * - $LUMENFLOW_HOME/path -> actual LUMENFLOW_HOME value
94
+ *
95
+ * Repo-relative paths are returned unchanged.
96
+ *
97
+ * @param {string} specRef - Spec reference path
98
+ * @returns {string} Normalized absolute path or unchanged relative path
99
+ *
100
+ * @example
101
+ * normalizeSpecRef('lumenflow://plans/WU-1062-plan.md')
102
+ * // '/home/user/.lumenflow/plans/WU-1062-plan.md'
103
+ *
104
+ * @example
105
+ * normalizeSpecRef('docs/04-operations/plans/plan.md')
106
+ * // 'docs/04-operations/plans/plan.md' (unchanged)
107
+ */
108
+ export declare function normalizeSpecRef(specRef: string): string;
109
+ /**
110
+ * Get the full path for a plan file given a WU ID
111
+ *
112
+ * @param {string} wuId - Work Unit ID (e.g., 'WU-1062')
113
+ * @returns {string} Full path to the plan file
114
+ *
115
+ * @example
116
+ * getPlanPath('WU-1062')
117
+ * // '/home/user/.lumenflow/plans/WU-1062-plan.md'
118
+ */
119
+ export declare function getPlanPath(wuId: string): string;
120
+ /**
121
+ * Get the lumenflow:// protocol reference for a plan
122
+ *
123
+ * @param {string} wuId - Work Unit ID (e.g., 'WU-1062')
124
+ * @returns {string} Protocol reference (e.g., 'lumenflow://plans/WU-1062-plan.md')
125
+ *
126
+ * @example
127
+ * getPlanProtocolRef('WU-1062')
128
+ * // 'lumenflow://plans/WU-1062-plan.md'
129
+ */
130
+ export declare function getPlanProtocolRef(wuId: string): string;
@@ -0,0 +1,208 @@
1
+ /**
2
+ * LumenFlow Home Directory Resolution
3
+ *
4
+ * WU-1062: External plan storage and no-main-write mode
5
+ *
6
+ * Provides helpers for resolving the $LUMENFLOW_HOME directory and related paths.
7
+ * Plans are stored externally in $LUMENFLOW_HOME/plans/ instead of in the repo.
8
+ *
9
+ * Default: ~/.lumenflow/
10
+ * Override: Set $LUMENFLOW_HOME environment variable
11
+ *
12
+ * @module
13
+ */
14
+ import { homedir } from 'node:os';
15
+ import { join } from 'node:path';
16
+ /**
17
+ * Environment variable name for LumenFlow home directory
18
+ */
19
+ export const LUMENFLOW_HOME_ENV = 'LUMENFLOW_HOME';
20
+ /**
21
+ * Default LumenFlow home directory name
22
+ */
23
+ export const DEFAULT_LUMENFLOW_DIR = '.lumenflow';
24
+ /**
25
+ * Plans subdirectory name
26
+ */
27
+ export const PLANS_SUBDIR = 'plans';
28
+ /**
29
+ * Custom protocol for external LumenFlow paths
30
+ */
31
+ export const LUMENFLOW_PROTOCOL = 'lumenflow://';
32
+ /**
33
+ * Environment variable prefix for spec_refs
34
+ */
35
+ export const LUMENFLOW_HOME_VAR_PREFIX = '$LUMENFLOW_HOME';
36
+ /**
37
+ * Expand ~ to user's home directory
38
+ *
39
+ * @param {string} path - Path that may contain ~
40
+ * @returns {string} Expanded path
41
+ */
42
+ function expandTilde(path) {
43
+ if (path.startsWith('~/')) {
44
+ return join(homedir(), path.slice(2));
45
+ }
46
+ if (path === '~') {
47
+ return homedir();
48
+ }
49
+ return path;
50
+ }
51
+ /**
52
+ * Remove trailing slashes from path
53
+ *
54
+ * @param {string} path - Path that may have trailing slashes
55
+ * @returns {string} Path without trailing slashes
56
+ */
57
+ function removeTrailingSlash(path) {
58
+ return path.replace(/\/+$/, '');
59
+ }
60
+ /**
61
+ * Get the LumenFlow home directory path
62
+ *
63
+ * Resolution order:
64
+ * 1. $LUMENFLOW_HOME environment variable (with ~ expansion)
65
+ * 2. ~/.lumenflow/ default
66
+ *
67
+ * @returns {string} Absolute path to LumenFlow home directory
68
+ *
69
+ * @example
70
+ * // With LUMENFLOW_HOME=/custom/path
71
+ * getLumenflowHome() // '/custom/path'
72
+ *
73
+ * @example
74
+ * // With LUMENFLOW_HOME=~/.custom-lumenflow
75
+ * getLumenflowHome() // '/home/user/.custom-lumenflow'
76
+ *
77
+ * @example
78
+ * // Without LUMENFLOW_HOME set
79
+ * getLumenflowHome() // '/home/user/.lumenflow'
80
+ */
81
+ export function getLumenflowHome() {
82
+ const envValue = process.env[LUMENFLOW_HOME_ENV];
83
+ if (envValue) {
84
+ const expanded = expandTilde(envValue);
85
+ return removeTrailingSlash(expanded);
86
+ }
87
+ return join(homedir(), DEFAULT_LUMENFLOW_DIR);
88
+ }
89
+ /**
90
+ * Get the plans directory path
91
+ *
92
+ * Plans are stored in $LUMENFLOW_HOME/plans/
93
+ *
94
+ * @returns {string} Absolute path to plans directory
95
+ *
96
+ * @example
97
+ * getPlansDir() // '/home/user/.lumenflow/plans'
98
+ */
99
+ export function getPlansDir() {
100
+ return join(getLumenflowHome(), PLANS_SUBDIR);
101
+ }
102
+ /**
103
+ * Check if a path is an external (non-repo) path
104
+ *
105
+ * External paths include:
106
+ * - Paths starting with ~/
107
+ * - Paths starting with $LUMENFLOW_HOME
108
+ * - Paths using lumenflow:// protocol
109
+ * - Absolute paths (starting with /)
110
+ *
111
+ * @param {string} path - Path to check
112
+ * @returns {boolean} True if path is external
113
+ *
114
+ * @example
115
+ * isExternalPath('~/.lumenflow/plans/plan.md') // true
116
+ * isExternalPath('$LUMENFLOW_HOME/plans/plan.md') // true
117
+ * isExternalPath('lumenflow://plans/plan.md') // true
118
+ * isExternalPath('/home/user/.lumenflow/plans/plan.md') // true
119
+ * isExternalPath('docs/04-operations/plans/plan.md') // false
120
+ */
121
+ export function isExternalPath(path) {
122
+ // Check for tilde-prefixed paths
123
+ if (path.startsWith('~/')) {
124
+ return true;
125
+ }
126
+ // Check for environment variable reference
127
+ if (path.startsWith(LUMENFLOW_HOME_VAR_PREFIX)) {
128
+ return true;
129
+ }
130
+ // Check for lumenflow:// protocol
131
+ if (path.startsWith(LUMENFLOW_PROTOCOL)) {
132
+ return true;
133
+ }
134
+ // Check for absolute paths (starting with /)
135
+ if (path.startsWith('/')) {
136
+ return true;
137
+ }
138
+ return false;
139
+ }
140
+ /**
141
+ * Normalize a spec_ref path by expanding variables and protocols
142
+ *
143
+ * Expands:
144
+ * - lumenflow://path -> $LUMENFLOW_HOME/path
145
+ * - ~/path -> /home/user/path
146
+ * - $LUMENFLOW_HOME/path -> actual LUMENFLOW_HOME value
147
+ *
148
+ * Repo-relative paths are returned unchanged.
149
+ *
150
+ * @param {string} specRef - Spec reference path
151
+ * @returns {string} Normalized absolute path or unchanged relative path
152
+ *
153
+ * @example
154
+ * normalizeSpecRef('lumenflow://plans/WU-1062-plan.md')
155
+ * // '/home/user/.lumenflow/plans/WU-1062-plan.md'
156
+ *
157
+ * @example
158
+ * normalizeSpecRef('docs/04-operations/plans/plan.md')
159
+ * // 'docs/04-operations/plans/plan.md' (unchanged)
160
+ */
161
+ export function normalizeSpecRef(specRef) {
162
+ // Handle lumenflow:// protocol
163
+ if (specRef.startsWith(LUMENFLOW_PROTOCOL)) {
164
+ const relativePath = specRef.slice(LUMENFLOW_PROTOCOL.length);
165
+ return join(getLumenflowHome(), relativePath);
166
+ }
167
+ // Handle $LUMENFLOW_HOME variable
168
+ if (specRef.startsWith(LUMENFLOW_HOME_VAR_PREFIX)) {
169
+ const relativePath = specRef.slice(LUMENFLOW_HOME_VAR_PREFIX.length);
170
+ // Remove leading slash if present
171
+ const cleanPath = relativePath.startsWith('/') ? relativePath.slice(1) : relativePath;
172
+ return join(getLumenflowHome(), cleanPath);
173
+ }
174
+ // Handle tilde expansion
175
+ if (specRef.startsWith('~/')) {
176
+ return expandTilde(specRef);
177
+ }
178
+ // Return relative paths unchanged
179
+ return specRef;
180
+ }
181
+ /**
182
+ * Get the full path for a plan file given a WU ID
183
+ *
184
+ * @param {string} wuId - Work Unit ID (e.g., 'WU-1062')
185
+ * @returns {string} Full path to the plan file
186
+ *
187
+ * @example
188
+ * getPlanPath('WU-1062')
189
+ * // '/home/user/.lumenflow/plans/WU-1062-plan.md'
190
+ */
191
+ export function getPlanPath(wuId) {
192
+ const filename = `${wuId}-plan.md`;
193
+ return join(getPlansDir(), filename);
194
+ }
195
+ /**
196
+ * Get the lumenflow:// protocol reference for a plan
197
+ *
198
+ * @param {string} wuId - Work Unit ID (e.g., 'WU-1062')
199
+ * @returns {string} Protocol reference (e.g., 'lumenflow://plans/WU-1062-plan.md')
200
+ *
201
+ * @example
202
+ * getPlanProtocolRef('WU-1062')
203
+ * // 'lumenflow://plans/WU-1062-plan.md'
204
+ */
205
+ export function getPlanProtocolRef(wuId) {
206
+ const filename = `${wuId}-plan.md`;
207
+ return `${LUMENFLOW_PROTOCOL}${PLANS_SUBDIR}/${filename}`;
208
+ }
@@ -20,7 +20,7 @@ import { TEST_TYPES, WU_TYPES } from './wu-constants.js';
20
20
  * Code file extensions that require automated tests.
21
21
  * @constant {string[]}
22
22
  */
23
- const CODE_EXTENSIONS = Object.freeze(['.js', '.ts', '.tsx', '.js']);
23
+ const CODE_EXTENSIONS = Object.freeze(['.js', '.ts', '.tsx', '.mjs']);
24
24
  /**
25
25
  * Non-code file extensions (documentation, data, config).
26
26
  * @constant {string[]}
@@ -18,6 +18,7 @@
18
18
  * @see {@link tools/wu-claim.mjs} - Pre-flight orphan check
19
19
  * @see {@link tools/lib/git-adapter.mjs} - worktreeRemove with cleanup
20
20
  */
21
+ import { existsSync } from 'node:fs';
21
22
  /**
22
23
  * Result of orphan detection
23
24
  * @typedef {object} OrphanDetectionResult
@@ -50,6 +51,21 @@ export declare function parseWorktreeList(porcelainOutput: string): WorktreeEntr
50
51
  * @returns {Promise<Set<string>>} Set of absolute paths tracked by git worktree
51
52
  */
52
53
  export declare function getTrackedWorktreePaths(projectRoot: any): Promise<Set<string>>;
54
+ /**
55
+ * Identify tracked worktrees that are missing on disk
56
+ *
57
+ * @param {string[]} trackedPaths - Absolute paths from git worktree list
58
+ * @param {(path: string) => boolean} [existsFn] - Optional fs.existsSync override
59
+ * @returns {string[]} Missing worktree paths
60
+ */
61
+ export declare function getMissingWorktreesFromTracked(trackedPaths: any, existsFn?: typeof existsSync): any[];
62
+ /**
63
+ * Detect tracked worktrees that are missing on disk
64
+ *
65
+ * @param {string} [projectRoot] - Project root directory (defaults to cwd)
66
+ * @returns {Promise<string[]>} Missing tracked worktree paths
67
+ */
68
+ export declare function detectMissingTrackedWorktrees(projectRoot: any): Promise<any[]>;
53
69
  /**
54
70
  * Get list of directories in worktrees/ folder
55
71
  *
@@ -75,6 +75,30 @@ export async function getTrackedWorktreePaths(projectRoot) {
75
75
  const entries = parseWorktreeList(output);
76
76
  return new Set(entries.map((e) => e.path));
77
77
  }
78
+ /**
79
+ * Identify tracked worktrees that are missing on disk
80
+ *
81
+ * @param {string[]} trackedPaths - Absolute paths from git worktree list
82
+ * @param {(path: string) => boolean} [existsFn] - Optional fs.existsSync override
83
+ * @returns {string[]} Missing worktree paths
84
+ */
85
+ export function getMissingWorktreesFromTracked(trackedPaths, existsFn = existsSync) {
86
+ if (!Array.isArray(trackedPaths)) {
87
+ return [];
88
+ }
89
+ return trackedPaths.filter((trackedPath) => !existsFn(trackedPath));
90
+ }
91
+ /**
92
+ * Detect tracked worktrees that are missing on disk
93
+ *
94
+ * @param {string} [projectRoot] - Project root directory (defaults to cwd)
95
+ * @returns {Promise<string[]>} Missing tracked worktree paths
96
+ */
97
+ export async function detectMissingTrackedWorktrees(projectRoot) {
98
+ const root = projectRoot || process.cwd();
99
+ const tracked = await getTrackedWorktreePaths(root);
100
+ return getMissingWorktreesFromTracked([...tracked]);
101
+ }
78
102
  /**
79
103
  * Get list of directories in worktrees/ folder
80
104
  *
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Spec Branch Helpers
3
+ *
4
+ * WU-1062: External plan storage and no-main-write mode
5
+ *
6
+ * Provides helpers for working with spec branches (spec/wu-XXXX).
7
+ * wu:create writes to spec branches by default; wu:claim merges them to main.
8
+ *
9
+ * @module
10
+ */
11
+ import type { SimpleGit } from 'simple-git';
12
+ /**
13
+ * Spec branch prefix
14
+ */
15
+ export declare const SPEC_BRANCH_PREFIX = "spec/";
16
+ /**
17
+ * WU source location constants
18
+ */
19
+ export declare const WU_SOURCE: {
20
+ /** WU exists on main branch only */
21
+ readonly MAIN: "main";
22
+ /** WU exists on spec branch only */
23
+ readonly SPEC_BRANCH: "spec_branch";
24
+ /** WU exists on both main and spec branch */
25
+ readonly BOTH: "both";
26
+ /** WU not found anywhere */
27
+ readonly NOT_FOUND: "not_found";
28
+ };
29
+ export type WUSourceType = (typeof WU_SOURCE)[keyof typeof WU_SOURCE];
30
+ /**
31
+ * Get the spec branch name for a WU
32
+ *
33
+ * @param {string} wuId - Work Unit ID (e.g., 'WU-1062')
34
+ * @returns {string} Spec branch name (e.g., 'spec/wu-1062')
35
+ *
36
+ * @example
37
+ * getSpecBranchName('WU-1062') // 'spec/wu-1062'
38
+ */
39
+ export declare function getSpecBranchName(wuId: string): string;
40
+ /**
41
+ * Get the origin-qualified spec branch name
42
+ *
43
+ * @param {string} wuId - Work Unit ID
44
+ * @returns {string} Origin-qualified branch name (e.g., 'origin/spec/wu-1062')
45
+ */
46
+ export declare function getOriginSpecBranch(wuId: string): string;
47
+ /**
48
+ * Check if a spec branch exists on origin
49
+ *
50
+ * @param {string} wuId - Work Unit ID
51
+ * @param {SimpleGit} git - Git adapter instance
52
+ * @returns {Promise<boolean>} True if spec branch exists
53
+ *
54
+ * @example
55
+ * const exists = await specBranchExists('WU-1062', git);
56
+ */
57
+ export declare function specBranchExists(wuId: string, git: SimpleGit): Promise<boolean>;
58
+ /**
59
+ * Check if a WU exists on main branch
60
+ *
61
+ * @param {string} wuId - Work Unit ID
62
+ * @param {SimpleGit} git - Git adapter instance
63
+ * @returns {Promise<boolean>} True if WU YAML exists on main
64
+ */
65
+ export declare function isWUOnMain(wuId: string, git: SimpleGit): Promise<boolean>;
66
+ /**
67
+ * Merge spec branch to main branch (fast-forward only)
68
+ *
69
+ * This is used by wu:claim when a WU exists only on a spec branch.
70
+ * The spec branch is merged to main before creating the worktree.
71
+ *
72
+ * @param {string} wuId - Work Unit ID
73
+ * @param {SimpleGit} git - Git adapter instance
74
+ * @throws {Error} If merge fails (e.g., due to conflicts)
75
+ *
76
+ * @example
77
+ * await mergeSpecBranchToMain('WU-1062', git);
78
+ */
79
+ export declare function mergeSpecBranchToMain(wuId: string, git: SimpleGit): Promise<void>;
80
+ /**
81
+ * Delete spec branch after merge
82
+ *
83
+ * @param {string} wuId - Work Unit ID
84
+ * @param {SimpleGit} git - Git adapter instance
85
+ */
86
+ export declare function deleteSpecBranch(wuId: string, git: SimpleGit): Promise<void>;
87
+ /**
88
+ * Determine the source of a WU (main, spec branch, both, or not found)
89
+ *
90
+ * Used by wu:claim to decide whether to merge spec branch before creating worktree.
91
+ *
92
+ * @param {string} wuId - Work Unit ID
93
+ * @param {SimpleGit} git - Git adapter instance
94
+ * @returns {Promise<WUSourceType>} Source location constant
95
+ *
96
+ * @example
97
+ * const source = await getWUSource('WU-1062', git);
98
+ * if (source === WU_SOURCE.SPEC_BRANCH) {
99
+ * await mergeSpecBranchToMain('WU-1062', git);
100
+ * }
101
+ */
102
+ export declare function getWUSource(wuId: string, git: SimpleGit): Promise<WUSourceType>;
103
+ /**
104
+ * Create a spec branch from current HEAD
105
+ *
106
+ * Used by wu:create in default mode (no --direct flag).
107
+ *
108
+ * @param {string} wuId - Work Unit ID
109
+ * @param {SimpleGit} git - Git adapter instance
110
+ */
111
+ export declare function createSpecBranch(wuId: string, git: SimpleGit): Promise<void>;
112
+ /**
113
+ * Push spec branch to origin
114
+ *
115
+ * @param {string} wuId - Work Unit ID
116
+ * @param {SimpleGit} git - Git adapter instance
117
+ */
118
+ export declare function pushSpecBranch(wuId: string, git: SimpleGit): Promise<void>;