@camaradesuk/git-worktree-tools 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +330 -370
- package/dist/cli/cleanpr.js +35 -4
- package/dist/cli/cleanpr.js.map +1 -1
- package/dist/cli/cleanpr.test.js +256 -0
- package/dist/cli/cleanpr.test.js.map +1 -1
- package/dist/cli/lswt.js +54 -6
- package/dist/cli/lswt.js.map +1 -1
- package/dist/cli/lswt.test.js +207 -0
- package/dist/cli/lswt.test.js.map +1 -1
- package/dist/cli/newpr.js +135 -76
- package/dist/cli/newpr.js.map +1 -1
- package/dist/cli/newpr.test.js +35 -16
- package/dist/cli/newpr.test.js.map +1 -1
- package/dist/cli/wt/clean.d.ts +17 -0
- package/dist/cli/wt/clean.d.ts.map +1 -0
- package/dist/cli/wt/clean.js +74 -0
- package/dist/cli/wt/clean.js.map +1 -0
- package/dist/cli/wt/completion.d.ts +12 -0
- package/dist/cli/wt/completion.d.ts.map +1 -0
- package/dist/cli/wt/completion.js +246 -0
- package/dist/cli/wt/completion.js.map +1 -0
- package/dist/cli/wt/completion.test.d.ts +5 -0
- package/dist/cli/wt/completion.test.d.ts.map +1 -0
- package/dist/cli/wt/completion.test.js +173 -0
- package/dist/cli/wt/completion.test.js.map +1 -0
- package/dist/cli/wt/config.d.ts +13 -0
- package/dist/cli/wt/config.d.ts.map +1 -0
- package/dist/cli/wt/config.js +175 -0
- package/dist/cli/wt/config.js.map +1 -0
- package/dist/cli/wt/config.test.d.ts +5 -0
- package/dist/cli/wt/config.test.d.ts.map +1 -0
- package/dist/cli/wt/config.test.js +260 -0
- package/dist/cli/wt/config.test.js.map +1 -0
- package/dist/cli/wt/entry.test.d.ts +8 -0
- package/dist/cli/wt/entry.test.d.ts.map +1 -0
- package/dist/cli/wt/entry.test.js +201 -0
- package/dist/cli/wt/entry.test.js.map +1 -0
- package/dist/cli/wt/init.d.ts +14 -0
- package/dist/cli/wt/init.d.ts.map +1 -0
- package/dist/cli/wt/init.js +209 -0
- package/dist/cli/wt/init.js.map +1 -0
- package/dist/cli/wt/init.test.d.ts +5 -0
- package/dist/cli/wt/init.test.d.ts.map +1 -0
- package/dist/cli/wt/init.test.js +165 -0
- package/dist/cli/wt/init.test.js.map +1 -0
- package/dist/cli/wt/init.unit.test.d.ts +5 -0
- package/dist/cli/wt/init.unit.test.d.ts.map +1 -0
- package/dist/cli/wt/init.unit.test.js +432 -0
- package/dist/cli/wt/init.unit.test.js.map +1 -0
- package/dist/cli/wt/interactive-menu.d.ts +41 -0
- package/dist/cli/wt/interactive-menu.d.ts.map +1 -0
- package/dist/cli/wt/interactive-menu.js +639 -0
- package/dist/cli/wt/interactive-menu.js.map +1 -0
- package/dist/cli/wt/interactive-menu.test.d.ts +10 -0
- package/dist/cli/wt/interactive-menu.test.d.ts.map +1 -0
- package/dist/cli/wt/interactive-menu.test.js +711 -0
- package/dist/cli/wt/interactive-menu.test.js.map +1 -0
- package/dist/cli/wt/link.d.ts +22 -0
- package/dist/cli/wt/link.d.ts.map +1 -0
- package/dist/cli/wt/link.js +115 -0
- package/dist/cli/wt/link.js.map +1 -0
- package/dist/cli/wt/list.d.ts +16 -0
- package/dist/cli/wt/list.d.ts.map +1 -0
- package/dist/cli/wt/list.js +65 -0
- package/dist/cli/wt/list.js.map +1 -0
- package/dist/cli/wt/new.d.ts +24 -0
- package/dist/cli/wt/new.d.ts.map +1 -0
- package/dist/cli/wt/new.js +130 -0
- package/dist/cli/wt/new.js.map +1 -0
- package/dist/cli/wt/run-command.d.ts +31 -0
- package/dist/cli/wt/run-command.d.ts.map +1 -0
- package/dist/cli/wt/run-command.js +49 -0
- package/dist/cli/wt/run-command.js.map +1 -0
- package/dist/cli/wt/run-command.test.d.ts +5 -0
- package/dist/cli/wt/run-command.test.d.ts.map +1 -0
- package/dist/cli/wt/run-command.test.js +88 -0
- package/dist/cli/wt/run-command.test.js.map +1 -0
- package/dist/cli/wt/state.d.ts +13 -0
- package/dist/cli/wt/state.d.ts.map +1 -0
- package/dist/cli/wt/state.js +38 -0
- package/dist/cli/wt/state.js.map +1 -0
- package/dist/cli/wt/wt.test.d.ts +8 -0
- package/dist/cli/wt/wt.test.d.ts.map +1 -0
- package/dist/cli/wt/wt.test.js +521 -0
- package/dist/cli/wt/wt.test.js.map +1 -0
- package/dist/cli/wt.d.ts +26 -0
- package/dist/cli/wt.d.ts.map +1 -0
- package/dist/cli/wt.js +169 -0
- package/dist/cli/wt.js.map +1 -0
- package/dist/cli/wt.unit.test.d.ts +7 -0
- package/dist/cli/wt.unit.test.d.ts.map +1 -0
- package/dist/cli/wt.unit.test.js +182 -0
- package/dist/cli/wt.unit.test.js.map +1 -0
- package/dist/cli/wtconfig.js +22 -8
- package/dist/cli/wtconfig.js.map +1 -1
- package/dist/cli/wtconfig.test.js +18 -16
- package/dist/cli/wtconfig.test.js.map +1 -1
- package/dist/cli/wtlink.js +66 -9
- package/dist/cli/wtlink.js.map +1 -1
- package/dist/cli/wtlink.test.js +101 -0
- package/dist/cli/wtlink.test.js.map +1 -1
- package/dist/e2e/cli.e2e.test.js +97 -1
- package/dist/e2e/cli.e2e.test.js.map +1 -1
- package/dist/e2e/lswt/lswt.e2e.test.js +33 -0
- package/dist/e2e/lswt/lswt.e2e.test.js.map +1 -1
- package/dist/e2e/newpr/scenarios.e2e.test.js +7 -7
- package/dist/e2e/newpr/scenarios.e2e.test.js.map +1 -1
- package/dist/e2e/wt/wt.e2e.test.d.ts +9 -0
- package/dist/e2e/wt/wt.e2e.test.d.ts.map +1 -0
- package/dist/e2e/wt/wt.e2e.test.js +384 -0
- package/dist/e2e/wt/wt.e2e.test.js.map +1 -0
- package/dist/e2e/wtlink/wtlink.e2e.test.js +52 -0
- package/dist/e2e/wtlink/wtlink.e2e.test.js.map +1 -1
- package/dist/lib/ai/base-provider.d.ts +22 -0
- package/dist/lib/ai/base-provider.d.ts.map +1 -1
- package/dist/lib/ai/base-provider.js +180 -99
- package/dist/lib/ai/base-provider.js.map +1 -1
- package/dist/lib/ai/base-provider.test.js +13 -14
- package/dist/lib/ai/base-provider.test.js.map +1 -1
- package/dist/lib/ai/cli-provider.d.ts +11 -7
- package/dist/lib/ai/cli-provider.d.ts.map +1 -1
- package/dist/lib/ai/cli-provider.js +19 -49
- package/dist/lib/ai/cli-provider.js.map +1 -1
- package/dist/lib/ai/cli-provider.test.js +47 -49
- package/dist/lib/ai/cli-provider.test.js.map +1 -1
- package/dist/lib/ai/index.d.ts +2 -1
- package/dist/lib/ai/index.d.ts.map +1 -1
- package/dist/lib/ai/index.js +2 -0
- package/dist/lib/ai/index.js.map +1 -1
- package/dist/lib/ai/provider-manager.js +2 -2
- package/dist/lib/ai/provider-manager.js.map +1 -1
- package/dist/lib/ai/repo-docs.d.ts +43 -0
- package/dist/lib/ai/repo-docs.d.ts.map +1 -0
- package/dist/lib/ai/repo-docs.js +274 -0
- package/dist/lib/ai/repo-docs.js.map +1 -0
- package/dist/lib/ai/repo-docs.test.d.ts +5 -0
- package/dist/lib/ai/repo-docs.test.d.ts.map +1 -0
- package/dist/lib/ai/repo-docs.test.js +357 -0
- package/dist/lib/ai/repo-docs.test.js.map +1 -0
- package/dist/lib/ai/types.d.ts +18 -2
- package/dist/lib/ai/types.d.ts.map +1 -1
- package/dist/lib/ai/types.js.map +1 -1
- package/dist/lib/config-editor.d.ts +21 -0
- package/dist/lib/config-editor.d.ts.map +1 -0
- package/dist/lib/config-editor.js +729 -0
- package/dist/lib/config-editor.js.map +1 -0
- package/dist/lib/config-editor.test.d.ts +11 -0
- package/dist/lib/config-editor.test.d.ts.map +1 -0
- package/dist/lib/config-editor.test.js +526 -0
- package/dist/lib/config-editor.test.js.map +1 -0
- package/dist/lib/config-validation.d.ts +28 -0
- package/dist/lib/config-validation.d.ts.map +1 -0
- package/dist/lib/config-validation.js +534 -0
- package/dist/lib/config-validation.js.map +1 -0
- package/dist/lib/config-validation.test.d.ts +5 -0
- package/dist/lib/config-validation.test.d.ts.map +1 -0
- package/dist/lib/config-validation.test.js +398 -0
- package/dist/lib/config-validation.test.js.map +1 -0
- package/dist/lib/config.d.ts +115 -6
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +251 -55
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.js +2 -1
- package/dist/lib/config.test.js.map +1 -1
- package/dist/lib/constants.d.ts +50 -1
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +67 -1
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/constants.test.d.ts +5 -0
- package/dist/lib/constants.test.d.ts.map +1 -0
- package/dist/lib/constants.test.js +121 -0
- package/dist/lib/constants.test.js.map +1 -0
- package/dist/lib/git.d.ts +12 -0
- package/dist/lib/git.d.ts.map +1 -1
- package/dist/lib/git.js +26 -0
- package/dist/lib/git.js.map +1 -1
- package/dist/lib/global-check.d.ts +38 -0
- package/dist/lib/global-check.d.ts.map +1 -0
- package/dist/lib/global-check.js +135 -0
- package/dist/lib/global-check.js.map +1 -0
- package/dist/lib/global-check.test.d.ts +5 -0
- package/dist/lib/global-check.test.d.ts.map +1 -0
- package/dist/lib/global-check.test.js +153 -0
- package/dist/lib/global-check.test.js.map +1 -0
- package/dist/lib/global-config.d.ts +102 -0
- package/dist/lib/global-config.d.ts.map +1 -0
- package/dist/lib/global-config.js +234 -0
- package/dist/lib/global-config.js.map +1 -0
- package/dist/lib/global-config.test.d.ts +5 -0
- package/dist/lib/global-config.test.d.ts.map +1 -0
- package/dist/lib/global-config.test.js +282 -0
- package/dist/lib/global-config.test.js.map +1 -0
- package/dist/lib/json-output.d.ts +11 -1
- package/dist/lib/json-output.d.ts.map +1 -1
- package/dist/lib/json-output.js +42 -1
- package/dist/lib/json-output.js.map +1 -1
- package/dist/lib/json-output.test.js +2 -0
- package/dist/lib/json-output.test.js.map +1 -1
- package/dist/lib/logger.d.ts +175 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +475 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/logger.test.d.ts +5 -0
- package/dist/lib/logger.test.d.ts.map +1 -0
- package/dist/lib/logger.test.js +292 -0
- package/dist/lib/logger.test.js.map +1 -0
- package/dist/lib/lswt/action-executors.test.js +2 -0
- package/dist/lib/lswt/action-executors.test.js.map +1 -1
- package/dist/lib/lswt/formatters.d.ts +1 -0
- package/dist/lib/lswt/formatters.d.ts.map +1 -1
- package/dist/lib/lswt/formatters.js +6 -1
- package/dist/lib/lswt/formatters.js.map +1 -1
- package/dist/lib/lswt/formatters.test.js +2 -2
- package/dist/lib/lswt/formatters.test.js.map +1 -1
- package/dist/lib/lswt/fuzzy-search.d.ts +27 -0
- package/dist/lib/lswt/fuzzy-search.d.ts.map +1 -0
- package/dist/lib/lswt/fuzzy-search.js +130 -0
- package/dist/lib/lswt/fuzzy-search.js.map +1 -0
- package/dist/lib/lswt/fuzzy-search.test.d.ts +5 -0
- package/dist/lib/lswt/fuzzy-search.test.d.ts.map +1 -0
- package/dist/lib/lswt/fuzzy-search.test.js +207 -0
- package/dist/lib/lswt/fuzzy-search.test.js.map +1 -0
- package/dist/lib/lswt/index.d.ts +1 -0
- package/dist/lib/lswt/index.d.ts.map +1 -1
- package/dist/lib/lswt/index.js +2 -0
- package/dist/lib/lswt/index.js.map +1 -1
- package/dist/lib/lswt/interactive.d.ts +8 -0
- package/dist/lib/lswt/interactive.d.ts.map +1 -1
- package/dist/lib/lswt/interactive.js +169 -20
- package/dist/lib/lswt/interactive.js.map +1 -1
- package/dist/lib/newpr/action-deps.test.d.ts +5 -0
- package/dist/lib/newpr/action-deps.test.d.ts.map +1 -0
- package/dist/lib/newpr/action-deps.test.js +111 -0
- package/dist/lib/newpr/action-deps.test.js.map +1 -0
- package/dist/lib/newpr/args.d.ts.map +1 -1
- package/dist/lib/newpr/args.js +15 -4
- package/dist/lib/newpr/args.js.map +1 -1
- package/dist/lib/newpr/args.test.js +210 -2
- package/dist/lib/newpr/args.test.js.map +1 -1
- package/dist/lib/newpr/types.d.ts +2 -0
- package/dist/lib/newpr/types.d.ts.map +1 -1
- package/dist/lib/prompts.d.ts +10 -0
- package/dist/lib/prompts.d.ts.map +1 -1
- package/dist/lib/prompts.js +200 -1
- package/dist/lib/prompts.js.map +1 -1
- package/dist/lib/prompts.test.js +351 -1
- package/dist/lib/prompts.test.js.map +1 -1
- package/dist/lib/schema.test.d.ts +10 -0
- package/dist/lib/schema.test.d.ts.map +1 -0
- package/dist/lib/schema.test.js +309 -0
- package/dist/lib/schema.test.js.map +1 -0
- package/dist/lib/wtconfig/environment.d.ts.map +1 -1
- package/dist/lib/wtconfig/environment.js +6 -4
- package/dist/lib/wtconfig/environment.js.map +1 -1
- package/dist/lib/wtconfig/environment.test.js +2 -7
- package/dist/lib/wtconfig/environment.test.js.map +1 -1
- package/dist/lib/wtconfig/types.d.ts +3 -1
- package/dist/lib/wtconfig/types.d.ts.map +1 -1
- package/dist/lib/wtlink/link-configs.test.js +282 -2
- package/dist/lib/wtlink/link-configs.test.js.map +1 -1
- package/dist/lib/wtlink/main-menu.js +1 -0
- package/dist/lib/wtlink/main-menu.js.map +1 -1
- package/dist/lib/wtlink/main-menu.test.d.ts +5 -0
- package/dist/lib/wtlink/main-menu.test.d.ts.map +1 -0
- package/dist/lib/wtlink/main-menu.test.js +124 -0
- package/dist/lib/wtlink/main-menu.test.js.map +1 -0
- package/dist/lib/wtlink/manage-manifest.d.ts +5 -0
- package/dist/lib/wtlink/manage-manifest.d.ts.map +1 -1
- package/dist/lib/wtlink/manage-manifest.js +65 -2
- package/dist/lib/wtlink/manage-manifest.js.map +1 -1
- package/dist/lib/wtlink/manage-manifest.test.js +282 -2
- package/dist/lib/wtlink/manage-manifest.test.js.map +1 -1
- package/package.json +3 -1
- package/schemas/worktreerc.schema.json +416 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for config validation module
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from 'vitest';
|
|
5
|
+
import { validateConfig, formatValidationErrors, } from './config-validation.js';
|
|
6
|
+
describe('validateConfig', () => {
|
|
7
|
+
describe('top-level properties', () => {
|
|
8
|
+
it('should accept valid empty config', () => {
|
|
9
|
+
const result = validateConfig({});
|
|
10
|
+
expect(result.valid).toBe(true);
|
|
11
|
+
expect(result.errors).toHaveLength(0);
|
|
12
|
+
});
|
|
13
|
+
it('should accept valid minimal config', () => {
|
|
14
|
+
const result = validateConfig({
|
|
15
|
+
baseBranch: 'main',
|
|
16
|
+
draftPr: false,
|
|
17
|
+
});
|
|
18
|
+
expect(result.valid).toBe(true);
|
|
19
|
+
expect(result.errors).toHaveLength(0);
|
|
20
|
+
});
|
|
21
|
+
it('should reject non-object config', () => {
|
|
22
|
+
const result = validateConfig('not an object');
|
|
23
|
+
expect(result.valid).toBe(false);
|
|
24
|
+
expect(result.errors[0].message).toContain('must be an object');
|
|
25
|
+
});
|
|
26
|
+
it('should reject null config', () => {
|
|
27
|
+
const result = validateConfig(null);
|
|
28
|
+
expect(result.valid).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
it('should warn on unknown top-level keys', () => {
|
|
31
|
+
const result = validateConfig({
|
|
32
|
+
baseBranch: 'main',
|
|
33
|
+
unknownKey: 'value',
|
|
34
|
+
});
|
|
35
|
+
expect(result.valid).toBe(false);
|
|
36
|
+
expect(result.errors.some((e) => e.path === 'unknownKey')).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it('should validate baseBranch type', () => {
|
|
39
|
+
const result = validateConfig({ baseBranch: 123 });
|
|
40
|
+
expect(result.valid).toBe(false);
|
|
41
|
+
expect(result.errors.some((e) => e.path === 'baseBranch')).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
it('should validate draftPr type', () => {
|
|
44
|
+
const result = validateConfig({ draftPr: 'yes' });
|
|
45
|
+
expect(result.valid).toBe(false);
|
|
46
|
+
expect(result.errors.some((e) => e.path === 'draftPr')).toBe(true);
|
|
47
|
+
});
|
|
48
|
+
it('should validate preferredEditor enum', () => {
|
|
49
|
+
const result = validateConfig({ preferredEditor: 'vim' });
|
|
50
|
+
expect(result.valid).toBe(false);
|
|
51
|
+
expect(result.errors.some((e) => e.path === 'preferredEditor')).toBe(true);
|
|
52
|
+
});
|
|
53
|
+
it('should accept valid preferredEditor values', () => {
|
|
54
|
+
expect(validateConfig({ preferredEditor: 'vscode' }).valid).toBe(true);
|
|
55
|
+
expect(validateConfig({ preferredEditor: 'cursor' }).valid).toBe(true);
|
|
56
|
+
expect(validateConfig({ preferredEditor: 'auto' }).valid).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('array properties', () => {
|
|
60
|
+
it('should accept valid sharedRepos array', () => {
|
|
61
|
+
const result = validateConfig({
|
|
62
|
+
sharedRepos: ['repo1', 'repo2'],
|
|
63
|
+
});
|
|
64
|
+
expect(result.valid).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
it('should reject non-array sharedRepos', () => {
|
|
67
|
+
const result = validateConfig({ sharedRepos: 'repo1' });
|
|
68
|
+
expect(result.valid).toBe(false);
|
|
69
|
+
expect(result.errors.some((e) => e.path === 'sharedRepos')).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
it('should reject non-string items in sharedRepos', () => {
|
|
72
|
+
const result = validateConfig({ sharedRepos: ['repo1', 123] });
|
|
73
|
+
expect(result.valid).toBe(false);
|
|
74
|
+
expect(result.errors.some((e) => e.path === 'sharedRepos[1]')).toBe(true);
|
|
75
|
+
});
|
|
76
|
+
it('should accept valid syncPatterns array', () => {
|
|
77
|
+
const result = validateConfig({
|
|
78
|
+
syncPatterns: ['.env.local', '.vscode/settings.json'],
|
|
79
|
+
});
|
|
80
|
+
expect(result.valid).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
it('should accept valid plugins array', () => {
|
|
83
|
+
const result = validateConfig({
|
|
84
|
+
plugins: ['@worktree-tools/plugin-linear', './plugins/custom.js'],
|
|
85
|
+
});
|
|
86
|
+
expect(result.valid).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe('ai config', () => {
|
|
90
|
+
it('should accept valid ai config', () => {
|
|
91
|
+
const result = validateConfig({
|
|
92
|
+
ai: {
|
|
93
|
+
provider: 'claude',
|
|
94
|
+
branchName: true,
|
|
95
|
+
prTitle: true,
|
|
96
|
+
prDescription: false,
|
|
97
|
+
commitMessage: false,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
expect(result.valid).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
it('should reject invalid ai provider', () => {
|
|
103
|
+
const result = validateConfig({
|
|
104
|
+
ai: { provider: 'invalid-provider' },
|
|
105
|
+
});
|
|
106
|
+
expect(result.valid).toBe(false);
|
|
107
|
+
expect(result.errors.some((e) => e.path === 'ai.provider')).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
it('should accept all valid ai providers', () => {
|
|
110
|
+
const providers = [
|
|
111
|
+
'auto',
|
|
112
|
+
'claude',
|
|
113
|
+
'gemini',
|
|
114
|
+
'openai',
|
|
115
|
+
'ollama',
|
|
116
|
+
'script',
|
|
117
|
+
'fallback',
|
|
118
|
+
'none',
|
|
119
|
+
];
|
|
120
|
+
for (const provider of providers) {
|
|
121
|
+
const result = validateConfig({ ai: { provider } });
|
|
122
|
+
expect(result.valid).toBe(true);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
it('should reject non-boolean ai feature flags', () => {
|
|
126
|
+
const result = validateConfig({
|
|
127
|
+
ai: { branchName: 'yes' },
|
|
128
|
+
});
|
|
129
|
+
expect(result.valid).toBe(false);
|
|
130
|
+
expect(result.errors.some((e) => e.path === 'ai.branchName')).toBe(true);
|
|
131
|
+
});
|
|
132
|
+
it('should validate ai branchStyle enum', () => {
|
|
133
|
+
expect(validateConfig({ ai: { branchStyle: 'conventional' } }).valid).toBe(true);
|
|
134
|
+
expect(validateConfig({ ai: { branchStyle: 'kebab' } }).valid).toBe(true);
|
|
135
|
+
expect(validateConfig({ ai: { branchStyle: 'snake' } }).valid).toBe(true);
|
|
136
|
+
expect(validateConfig({ ai: { branchStyle: 'invalid' } }).valid).toBe(false);
|
|
137
|
+
});
|
|
138
|
+
it('should validate ai commitStyle enum', () => {
|
|
139
|
+
expect(validateConfig({ ai: { commitStyle: 'conventional' } }).valid).toBe(true);
|
|
140
|
+
expect(validateConfig({ ai: { commitStyle: 'gitmoji' } }).valid).toBe(true);
|
|
141
|
+
expect(validateConfig({ ai: { commitStyle: 'simple' } }).valid).toBe(true);
|
|
142
|
+
expect(validateConfig({ ai: { commitStyle: 'invalid' } }).valid).toBe(false);
|
|
143
|
+
});
|
|
144
|
+
it('should validate ai provider-specific configs', () => {
|
|
145
|
+
const result = validateConfig({
|
|
146
|
+
ai: {
|
|
147
|
+
claude: { model: 'claude-3-sonnet' },
|
|
148
|
+
gemini: { model: 'gemini-pro' },
|
|
149
|
+
ollama: { model: 'llama2', host: 'http://localhost:11434' },
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
expect(result.valid).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
it('should require path in script config', () => {
|
|
155
|
+
const result = validateConfig({
|
|
156
|
+
ai: { script: {} },
|
|
157
|
+
});
|
|
158
|
+
expect(result.valid).toBe(false);
|
|
159
|
+
expect(result.errors.some((e) => e.path === 'ai.script.path')).toBe(true);
|
|
160
|
+
});
|
|
161
|
+
it('should warn on unknown ai keys', () => {
|
|
162
|
+
const result = validateConfig({
|
|
163
|
+
ai: { unknownKey: 'value' },
|
|
164
|
+
});
|
|
165
|
+
expect(result.valid).toBe(false);
|
|
166
|
+
expect(result.errors.some((e) => e.path === 'ai.unknownKey')).toBe(true);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
describe('hooks config', () => {
|
|
170
|
+
it('should accept simple string hook', () => {
|
|
171
|
+
const result = validateConfig({
|
|
172
|
+
hooks: { 'post-worktree': 'npm install' },
|
|
173
|
+
});
|
|
174
|
+
expect(result.valid).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
it('should accept array of commands hook', () => {
|
|
177
|
+
const result = validateConfig({
|
|
178
|
+
hooks: { 'post-worktree': ['npm install', 'npm run build'] },
|
|
179
|
+
});
|
|
180
|
+
expect(result.valid).toBe(true);
|
|
181
|
+
});
|
|
182
|
+
it('should accept complex hook object', () => {
|
|
183
|
+
const result = validateConfig({
|
|
184
|
+
hooks: {
|
|
185
|
+
'post-worktree': {
|
|
186
|
+
command: 'npm install',
|
|
187
|
+
timeout: 60000,
|
|
188
|
+
failOnError: true,
|
|
189
|
+
if: 'test -f package.json',
|
|
190
|
+
env: { NODE_ENV: 'development' },
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
expect(result.valid).toBe(true);
|
|
195
|
+
});
|
|
196
|
+
it('should reject invalid hook name', () => {
|
|
197
|
+
const result = validateConfig({
|
|
198
|
+
hooks: { 'invalid-hook': 'echo test' },
|
|
199
|
+
});
|
|
200
|
+
expect(result.valid).toBe(false);
|
|
201
|
+
expect(result.errors.some((e) => e.path === 'hooks.invalid-hook')).toBe(true);
|
|
202
|
+
});
|
|
203
|
+
it('should accept all valid hook names', () => {
|
|
204
|
+
const hookNames = [
|
|
205
|
+
'pre-analyze',
|
|
206
|
+
'post-analyze',
|
|
207
|
+
'pre-branch',
|
|
208
|
+
'post-branch',
|
|
209
|
+
'pre-commit',
|
|
210
|
+
'post-commit',
|
|
211
|
+
'pre-push',
|
|
212
|
+
'post-push',
|
|
213
|
+
'pre-pr',
|
|
214
|
+
'post-pr',
|
|
215
|
+
'pre-worktree',
|
|
216
|
+
'post-worktree',
|
|
217
|
+
'cleanup',
|
|
218
|
+
];
|
|
219
|
+
const hooks = {};
|
|
220
|
+
for (const name of hookNames) {
|
|
221
|
+
hooks[name] = 'echo test';
|
|
222
|
+
}
|
|
223
|
+
const result = validateConfig({ hooks });
|
|
224
|
+
expect(result.valid).toBe(true);
|
|
225
|
+
});
|
|
226
|
+
it('should validate hook timeout is non-negative', () => {
|
|
227
|
+
const result = validateConfig({
|
|
228
|
+
hooks: { 'post-worktree': { command: 'npm install', timeout: -1 } },
|
|
229
|
+
});
|
|
230
|
+
expect(result.valid).toBe(false);
|
|
231
|
+
expect(result.errors.some((e) => e.path === 'hooks.post-worktree.timeout')).toBe(true);
|
|
232
|
+
});
|
|
233
|
+
it('should validate hook env values are strings', () => {
|
|
234
|
+
const result = validateConfig({
|
|
235
|
+
hooks: { 'post-worktree': { command: 'npm install', env: { KEY: 123 } } },
|
|
236
|
+
});
|
|
237
|
+
expect(result.valid).toBe(false);
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
describe('hookDefaults config', () => {
|
|
241
|
+
it('should accept valid hookDefaults', () => {
|
|
242
|
+
const result = validateConfig({
|
|
243
|
+
hookDefaults: { timeout: 30000, maxTimeout: 60000 },
|
|
244
|
+
});
|
|
245
|
+
expect(result.valid).toBe(true);
|
|
246
|
+
});
|
|
247
|
+
it('should reject negative timeout', () => {
|
|
248
|
+
const result = validateConfig({
|
|
249
|
+
hookDefaults: { timeout: -1 },
|
|
250
|
+
});
|
|
251
|
+
expect(result.valid).toBe(false);
|
|
252
|
+
});
|
|
253
|
+
it('should warn on unknown hookDefaults keys', () => {
|
|
254
|
+
const result = validateConfig({
|
|
255
|
+
hookDefaults: { unknownKey: 'value' },
|
|
256
|
+
});
|
|
257
|
+
expect(result.valid).toBe(false);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe('generators config', () => {
|
|
261
|
+
it('should accept valid generators config', () => {
|
|
262
|
+
const result = validateConfig({
|
|
263
|
+
generators: {
|
|
264
|
+
branchName: './scripts/branch-name.js',
|
|
265
|
+
prTitle: './scripts/pr-title.js',
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
expect(result.valid).toBe(true);
|
|
269
|
+
});
|
|
270
|
+
it('should reject non-string generator paths', () => {
|
|
271
|
+
const result = validateConfig({
|
|
272
|
+
generators: { branchName: 123 },
|
|
273
|
+
});
|
|
274
|
+
expect(result.valid).toBe(false);
|
|
275
|
+
});
|
|
276
|
+
it('should warn on unknown generator keys', () => {
|
|
277
|
+
const result = validateConfig({
|
|
278
|
+
generators: { unknownGenerator: './script.js' },
|
|
279
|
+
});
|
|
280
|
+
expect(result.valid).toBe(false);
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
describe('integrations config', () => {
|
|
284
|
+
it('should accept valid linear integration', () => {
|
|
285
|
+
const result = validateConfig({
|
|
286
|
+
integrations: {
|
|
287
|
+
linear: { teamId: 'TEAM123', apiKeyEnv: 'LINEAR_API_KEY' },
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
expect(result.valid).toBe(true);
|
|
291
|
+
});
|
|
292
|
+
it('should accept valid jira integration', () => {
|
|
293
|
+
const result = validateConfig({
|
|
294
|
+
integrations: {
|
|
295
|
+
jira: {
|
|
296
|
+
projectKey: 'PROJ',
|
|
297
|
+
baseUrl: 'https://company.atlassian.net',
|
|
298
|
+
apiTokenEnv: 'JIRA_TOKEN',
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
expect(result.valid).toBe(true);
|
|
303
|
+
});
|
|
304
|
+
it('should accept valid slack integration', () => {
|
|
305
|
+
const result = validateConfig({
|
|
306
|
+
integrations: {
|
|
307
|
+
slack: {
|
|
308
|
+
webhookUrl: 'SLACK_WEBHOOK_URL',
|
|
309
|
+
channel: '#dev-notifications',
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
expect(result.valid).toBe(true);
|
|
314
|
+
});
|
|
315
|
+
it('should warn on unknown integration', () => {
|
|
316
|
+
const result = validateConfig({
|
|
317
|
+
integrations: { unknownService: {} },
|
|
318
|
+
});
|
|
319
|
+
expect(result.valid).toBe(false);
|
|
320
|
+
});
|
|
321
|
+
it('should reject non-string integration values', () => {
|
|
322
|
+
const result = validateConfig({
|
|
323
|
+
integrations: { linear: { teamId: 123 } },
|
|
324
|
+
});
|
|
325
|
+
expect(result.valid).toBe(false);
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
describe('full config validation', () => {
|
|
329
|
+
it('should accept comprehensive valid config', () => {
|
|
330
|
+
const result = validateConfig({
|
|
331
|
+
baseBranch: 'main',
|
|
332
|
+
draftPr: true,
|
|
333
|
+
branchPrefix: 'feat',
|
|
334
|
+
worktreePattern: '{repo}.pr{number}',
|
|
335
|
+
worktreeParent: '..',
|
|
336
|
+
preferredEditor: 'vscode',
|
|
337
|
+
sharedRepos: ['backend-api'],
|
|
338
|
+
syncPatterns: ['.env.local'],
|
|
339
|
+
ai: {
|
|
340
|
+
provider: 'claude',
|
|
341
|
+
branchName: true,
|
|
342
|
+
prTitle: true,
|
|
343
|
+
prDescription: true,
|
|
344
|
+
commitStyle: 'conventional',
|
|
345
|
+
},
|
|
346
|
+
hooks: {
|
|
347
|
+
'post-worktree': 'npm install',
|
|
348
|
+
},
|
|
349
|
+
hookDefaults: {
|
|
350
|
+
timeout: 30000,
|
|
351
|
+
},
|
|
352
|
+
plugins: ['@worktree-tools/plugin-slack'],
|
|
353
|
+
generators: {},
|
|
354
|
+
integrations: {
|
|
355
|
+
slack: { channel: '#dev' },
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
expect(result.valid).toBe(true);
|
|
359
|
+
expect(result.errors).toHaveLength(0);
|
|
360
|
+
});
|
|
361
|
+
it('should collect multiple errors', () => {
|
|
362
|
+
const result = validateConfig({
|
|
363
|
+
baseBranch: 123,
|
|
364
|
+
draftPr: 'yes',
|
|
365
|
+
preferredEditor: 'vim',
|
|
366
|
+
unknownKey: 'value',
|
|
367
|
+
});
|
|
368
|
+
expect(result.valid).toBe(false);
|
|
369
|
+
expect(result.errors.length).toBeGreaterThanOrEqual(4);
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
describe('formatValidationErrors', () => {
|
|
374
|
+
it('should return empty string for no errors', () => {
|
|
375
|
+
expect(formatValidationErrors([])).toBe('');
|
|
376
|
+
});
|
|
377
|
+
it('should format single error', () => {
|
|
378
|
+
const errors = [{ path: 'baseBranch', message: 'must be a string' }];
|
|
379
|
+
const result = formatValidationErrors(errors);
|
|
380
|
+
expect(result).toContain('baseBranch');
|
|
381
|
+
expect(result).toContain('must be a string');
|
|
382
|
+
});
|
|
383
|
+
it('should format multiple errors', () => {
|
|
384
|
+
const errors = [
|
|
385
|
+
{ path: 'baseBranch', message: 'must be a string' },
|
|
386
|
+
{ path: 'draftPr', message: 'must be a boolean' },
|
|
387
|
+
];
|
|
388
|
+
const result = formatValidationErrors(errors);
|
|
389
|
+
expect(result).toContain('baseBranch');
|
|
390
|
+
expect(result).toContain('draftPr');
|
|
391
|
+
});
|
|
392
|
+
it('should handle empty path', () => {
|
|
393
|
+
const errors = [{ path: '', message: 'Config must be an object' }];
|
|
394
|
+
const result = formatValidationErrors(errors);
|
|
395
|
+
expect(result).toContain('Config must be an object');
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
//# sourceMappingURL=config-validation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-validation.test.js","sourceRoot":"","sources":["../../src/lib/config-validation.test.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AIConfig } from './ai/types.js';
|
|
2
2
|
import type { HooksConfig } from './hooks/types.js';
|
|
3
|
+
import { type ValidationResult } from './config-validation.js';
|
|
3
4
|
/**
|
|
4
5
|
* Hook execution defaults configuration
|
|
5
6
|
*/
|
|
@@ -99,6 +100,42 @@ export interface IntegrationsConfig {
|
|
|
99
100
|
*/
|
|
100
101
|
slack?: SlackIntegration;
|
|
101
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Logging configuration
|
|
105
|
+
*/
|
|
106
|
+
export interface LoggingConfig {
|
|
107
|
+
/**
|
|
108
|
+
* Log level threshold
|
|
109
|
+
* Options: "silent", "error", "warn", "info", "debug", "trace"
|
|
110
|
+
* Default: "info"
|
|
111
|
+
*/
|
|
112
|
+
level?: 'silent' | 'error' | 'warn' | 'info' | 'debug' | 'trace';
|
|
113
|
+
/**
|
|
114
|
+
* Path to log file for persistent logging
|
|
115
|
+
* If set, logs will be written to this file in addition to console
|
|
116
|
+
* Supports ~ for home directory
|
|
117
|
+
*/
|
|
118
|
+
logFile?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Enable timestamps in log output
|
|
121
|
+
* Default: true
|
|
122
|
+
*/
|
|
123
|
+
timestamps?: boolean;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Global settings that typically live in the global config
|
|
127
|
+
*/
|
|
128
|
+
export interface GlobalSettings {
|
|
129
|
+
/**
|
|
130
|
+
* Warn if the package is not installed globally
|
|
131
|
+
* Default: true
|
|
132
|
+
*/
|
|
133
|
+
warnNotGlobal?: boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Logging configuration (also applies to repo/local configs)
|
|
136
|
+
*/
|
|
137
|
+
logging?: LoggingConfig;
|
|
138
|
+
}
|
|
102
139
|
/**
|
|
103
140
|
* Configuration for git-worktree-tools
|
|
104
141
|
*/
|
|
@@ -129,8 +166,8 @@ export interface WorktreeConfig {
|
|
|
129
166
|
*/
|
|
130
167
|
worktreeParent?: string;
|
|
131
168
|
/**
|
|
132
|
-
*
|
|
133
|
-
* e.g., ["
|
|
169
|
+
* Gitignored config files to sync between worktrees via hard links
|
|
170
|
+
* e.g., [".env.local", ".vscode/settings.json"]
|
|
134
171
|
*/
|
|
135
172
|
syncPatterns?: string[];
|
|
136
173
|
/**
|
|
@@ -177,16 +214,85 @@ export interface WorktreeConfig {
|
|
|
177
214
|
* Third-party integrations configuration
|
|
178
215
|
*/
|
|
179
216
|
integrations?: IntegrationsConfig;
|
|
217
|
+
/**
|
|
218
|
+
* Logging configuration
|
|
219
|
+
* Controls verbosity and log file output
|
|
220
|
+
*/
|
|
221
|
+
logging?: LoggingConfig;
|
|
222
|
+
/**
|
|
223
|
+
* Global settings
|
|
224
|
+
* These are typically set in the global config file
|
|
225
|
+
*/
|
|
226
|
+
global?: GlobalSettings;
|
|
180
227
|
}
|
|
181
228
|
/**
|
|
182
229
|
* Get default configuration values
|
|
183
230
|
*/
|
|
184
231
|
export declare function getDefaultConfig(): Required<WorktreeConfig>;
|
|
185
232
|
/**
|
|
186
|
-
*
|
|
187
|
-
|
|
233
|
+
* Options for loading configuration
|
|
234
|
+
*/
|
|
235
|
+
export interface LoadConfigOptions {
|
|
236
|
+
/** Whether to validate the config (default: true) */
|
|
237
|
+
validate?: boolean;
|
|
238
|
+
/** Whether to warn on validation errors (default: true) */
|
|
239
|
+
warnOnErrors?: boolean;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Information about a loaded config source
|
|
243
|
+
*/
|
|
244
|
+
export interface LoadedConfigSource {
|
|
245
|
+
path: string;
|
|
246
|
+
level: 'global' | 'repo' | 'local';
|
|
247
|
+
config: WorktreeConfig;
|
|
248
|
+
validation: ValidationResult | null;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Result of loading and validating config
|
|
252
|
+
*/
|
|
253
|
+
export interface LoadConfigResult {
|
|
254
|
+
config: Required<WorktreeConfig>;
|
|
255
|
+
/** Primary config path (for backward compatibility - now refers to highest priority loaded config) */
|
|
256
|
+
configPath: string | null;
|
|
257
|
+
/** Validation result for the merged config */
|
|
258
|
+
validation: ValidationResult | null;
|
|
259
|
+
/** All config sources that were loaded */
|
|
260
|
+
sources: LoadedConfigSource[];
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Load configuration from repository (or global config only if no repoRoot)
|
|
264
|
+
* Implements three-tier hierarchy: defaults ← global ← repo ← local
|
|
265
|
+
*/
|
|
266
|
+
export declare function loadConfig(repoRoot?: string, options?: LoadConfigOptions): Required<WorktreeConfig>;
|
|
267
|
+
/**
|
|
268
|
+
* Load configuration with full validation result
|
|
269
|
+
* Implements three-tier hierarchy: defaults ← global ← repo ← local
|
|
270
|
+
*/
|
|
271
|
+
export declare function loadConfigWithValidation(repoRoot?: string, options?: LoadConfigOptions): LoadConfigResult;
|
|
272
|
+
/**
|
|
273
|
+
* Save configuration to repository
|
|
274
|
+
*
|
|
275
|
+
* @param repoRoot - Repository root path
|
|
276
|
+
* @param config - Configuration to save (partial config, will preserve existing values)
|
|
277
|
+
* @param options - Save options
|
|
278
|
+
* @returns Path to saved config file
|
|
279
|
+
*/
|
|
280
|
+
export declare function saveConfig(repoRoot: string, config: WorktreeConfig, options?: {
|
|
281
|
+
validate?: boolean;
|
|
282
|
+
}): {
|
|
283
|
+
configPath: string;
|
|
284
|
+
validation: ValidationResult | null;
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Get config file path for a repository (or null if none exists)
|
|
288
|
+
* Returns the highest priority config that exists (local > repo)
|
|
289
|
+
*/
|
|
290
|
+
export declare function getConfigPath(repoRoot: string): string | null;
|
|
291
|
+
/**
|
|
292
|
+
* Get the schema URL for IDE support
|
|
293
|
+
* Uses unpkg.com to serve the schema directly from npm
|
|
188
294
|
*/
|
|
189
|
-
export
|
|
295
|
+
export { getSchemaUrl } from './global-config.js';
|
|
190
296
|
/**
|
|
191
297
|
* Generate worktree path based on config pattern
|
|
192
298
|
*/
|
|
@@ -203,8 +309,9 @@ export declare function generateBranchName(config: Required<WorktreeConfig>, des
|
|
|
203
309
|
* @param config - The worktree configuration
|
|
204
310
|
* @param description - User-provided description for the branch
|
|
205
311
|
* @param repoName - Repository name (optional, defaults to 'repo')
|
|
312
|
+
* @param repoRoot - Repository root path for documentation gathering (optional)
|
|
206
313
|
*/
|
|
207
|
-
export declare function generateBranchNameAsync(config: Required<WorktreeConfig>, description: string, repoName?: string): Promise<string>;
|
|
314
|
+
export declare function generateBranchNameAsync(config: Required<WorktreeConfig>, description: string, repoName?: string, repoRoot?: string): Promise<string>;
|
|
208
315
|
/**
|
|
209
316
|
* Context for generating PR content
|
|
210
317
|
*/
|
|
@@ -215,6 +322,8 @@ export interface PRGenerationContext {
|
|
|
215
322
|
diff?: string;
|
|
216
323
|
changedFiles?: string[];
|
|
217
324
|
commitMessages?: string[];
|
|
325
|
+
/** Repository root path for documentation gathering */
|
|
326
|
+
repoRoot?: string;
|
|
218
327
|
}
|
|
219
328
|
/**
|
|
220
329
|
* Result of PR content generation
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|