clawvault 2.5.2 → 2.5.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.
- package/README.md +159 -200
- package/bin/clawvault.js +111 -111
- package/bin/command-registration.test.js +166 -166
- package/bin/command-runtime.js +93 -93
- package/bin/command-runtime.test.js +154 -154
- package/bin/help-contract.test.js +39 -39
- package/bin/register-config-commands.js +153 -153
- package/bin/register-config-route-commands.test.js +121 -121
- package/bin/register-core-commands.js +237 -237
- package/bin/register-kanban-commands.js +56 -56
- package/bin/register-kanban-commands.test.js +83 -83
- package/bin/register-maintenance-commands.js +282 -282
- package/bin/register-project-commands.js +209 -209
- package/bin/register-project-commands.test.js +206 -206
- package/bin/register-query-commands.js +317 -317
- package/bin/register-query-commands.test.js +65 -65
- package/bin/register-resilience-commands.js +182 -182
- package/bin/register-resilience-commands.test.js +81 -81
- package/bin/register-route-commands.js +114 -114
- package/bin/register-session-lifecycle-commands.js +206 -206
- package/bin/register-tailscale-commands.js +106 -106
- package/bin/register-task-commands.js +348 -348
- package/bin/register-task-commands.test.js +69 -69
- package/bin/register-template-commands.js +72 -72
- package/bin/register-vault-operations-commands.js +300 -300
- package/bin/test-helpers/cli-command-fixtures.js +119 -119
- package/dashboard/lib/graph-diff.js +104 -104
- package/dashboard/lib/graph-diff.test.js +75 -75
- package/dashboard/lib/vault-parser.js +556 -556
- package/dashboard/lib/vault-parser.test.js +254 -254
- package/dashboard/public/app.js +796 -796
- package/dashboard/public/index.html +52 -52
- package/dashboard/public/styles.css +221 -221
- package/dashboard/server.js +374 -374
- package/dist/{chunk-HWUNREDJ.js → chunk-FG6RJMCN.js} +1 -1
- package/dist/{chunk-HRTPQQF2.js → chunk-IZEY5S74.js} +1 -1
- package/dist/{chunk-BHO7WSAY.js → chunk-LMEMZGUV.js} +1 -1
- package/dist/{chunk-PLZKZW4I.js → chunk-OSMS7QIG.js} +1 -1
- package/dist/cli/index.js +3 -3
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/observe.js +2 -2
- package/dist/commands/status.js +1 -1
- package/dist/index.js +4 -4
- package/hooks/clawvault/HOOK.md +83 -74
- package/hooks/clawvault/handler.js +816 -816
- package/hooks/clawvault/handler.test.js +263 -263
- package/package.json +94 -125
- package/templates/checkpoint.md +19 -19
- package/templates/daily-note.md +19 -19
- package/templates/daily.md +19 -19
- package/templates/decision.md +17 -17
- package/templates/handoff.md +19 -19
- package/templates/lesson.md +16 -16
- package/templates/person.md +19 -19
- package/templates/project.md +23 -23
|
@@ -1,154 +1,154 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
4
|
-
const {
|
|
5
|
-
spawnMock,
|
|
6
|
-
resolveConfiguredVaultPathMock,
|
|
7
|
-
clawvaultCtorMock,
|
|
8
|
-
loadMock
|
|
9
|
-
} = vi.hoisted(() => ({
|
|
10
|
-
spawnMock: vi.fn(),
|
|
11
|
-
resolveConfiguredVaultPathMock: vi.fn(),
|
|
12
|
-
clawvaultCtorMock: vi.fn(),
|
|
13
|
-
loadMock: vi.fn()
|
|
14
|
-
}));
|
|
15
|
-
|
|
16
|
-
vi.mock('child_process', () => ({
|
|
17
|
-
spawn: spawnMock
|
|
18
|
-
}));
|
|
19
|
-
|
|
20
|
-
vi.mock('../dist/index.js', () => ({
|
|
21
|
-
ClawVault: clawvaultCtorMock,
|
|
22
|
-
resolveVaultPath: resolveConfiguredVaultPathMock,
|
|
23
|
-
QmdUnavailableError: class QmdUnavailableError extends Error {},
|
|
24
|
-
QMD_INSTALL_COMMAND: 'install-qmd'
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
|
-
async function loadRuntimeModule() {
|
|
28
|
-
vi.resetModules();
|
|
29
|
-
return await import('./command-runtime.js');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
vi.clearAllMocks();
|
|
34
|
-
clawvaultCtorMock.mockImplementation(() => ({
|
|
35
|
-
load: loadMock
|
|
36
|
-
}));
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe('command runtime helpers', () => {
|
|
40
|
-
it('delegates vault path resolution and loads vaults', async () => {
|
|
41
|
-
resolveConfiguredVaultPathMock.mockReturnValue('/resolved/vault');
|
|
42
|
-
loadMock.mockResolvedValue(undefined);
|
|
43
|
-
const { getVault, resolveVaultPath } = await loadRuntimeModule();
|
|
44
|
-
|
|
45
|
-
const resolved = resolveVaultPath('/explicit');
|
|
46
|
-
expect(resolveConfiguredVaultPathMock).toHaveBeenCalledWith({ explicitPath: '/explicit' });
|
|
47
|
-
expect(resolved).toBe('/resolved/vault');
|
|
48
|
-
|
|
49
|
-
await getVault('/explicit');
|
|
50
|
-
expect(clawvaultCtorMock).toHaveBeenCalledWith('/resolved/vault');
|
|
51
|
-
expect(loadMock).toHaveBeenCalled();
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('maps qmd ENOENT failures to QmdUnavailableError', async () => {
|
|
55
|
-
const { runQmd, QmdUnavailableError } = await loadRuntimeModule();
|
|
56
|
-
spawnMock.mockImplementation(() => {
|
|
57
|
-
const handlers = {};
|
|
58
|
-
const proc = {
|
|
59
|
-
on: (event, handler) => {
|
|
60
|
-
handlers[event] = handler;
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
queueMicrotask(() => {
|
|
64
|
-
handlers.error?.({ code: 'ENOENT' });
|
|
65
|
-
});
|
|
66
|
-
return proc;
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
await expect(runQmd(['update'])).rejects.toBeInstanceOf(QmdUnavailableError);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('injects qmd index from environment when configured', async () => {
|
|
73
|
-
const previous = process.env.CLAWVAULT_QMD_INDEX;
|
|
74
|
-
process.env.CLAWVAULT_QMD_INDEX = 'clawvault-test';
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const { runQmd } = await loadRuntimeModule();
|
|
78
|
-
spawnMock.mockImplementation((_command, _args) => {
|
|
79
|
-
const handlers = {};
|
|
80
|
-
const proc = {
|
|
81
|
-
on: (event, handler) => {
|
|
82
|
-
handlers[event] = handler;
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
queueMicrotask(() => {
|
|
86
|
-
handlers.close?.(0);
|
|
87
|
-
});
|
|
88
|
-
return proc;
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
await runQmd(['update']);
|
|
92
|
-
expect(spawnMock).toHaveBeenCalledWith(
|
|
93
|
-
'qmd',
|
|
94
|
-
['--index', 'clawvault-test', 'update'],
|
|
95
|
-
{ stdio: 'inherit' }
|
|
96
|
-
);
|
|
97
|
-
} finally {
|
|
98
|
-
if (previous === undefined) {
|
|
99
|
-
delete process.env.CLAWVAULT_QMD_INDEX;
|
|
100
|
-
} else {
|
|
101
|
-
process.env.CLAWVAULT_QMD_INDEX = previous;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('surfaces qmd non-zero exit codes as errors', async () => {
|
|
107
|
-
const { runQmd } = await loadRuntimeModule();
|
|
108
|
-
spawnMock.mockImplementation(() => {
|
|
109
|
-
const handlers = {};
|
|
110
|
-
const proc = {
|
|
111
|
-
on: (event, handler) => {
|
|
112
|
-
handlers[event] = handler;
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
queueMicrotask(() => {
|
|
116
|
-
handlers.close?.(2);
|
|
117
|
-
});
|
|
118
|
-
return proc;
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
await expect(runQmd(['update'])).rejects.toThrow('qmd exited with code 2');
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('exports and enforces argument/path sanitization helpers', async () => {
|
|
125
|
-
const { sanitizeQmdArg, validatePathWithinBase } = await loadRuntimeModule();
|
|
126
|
-
expect(sanitizeQmdArg('update')).toBe('update');
|
|
127
|
-
expect(sanitizeQmdArg(42)).toBe('42');
|
|
128
|
-
expect(() => sanitizeQmdArg('bad\0arg')).toThrow('contains null byte');
|
|
129
|
-
|
|
130
|
-
const safePath = validatePathWithinBase('notes/today.md', '/tmp/vault');
|
|
131
|
-
expect(safePath).toBe(path.resolve('/tmp/vault', 'notes/today.md'));
|
|
132
|
-
expect(() => validatePathWithinBase('../etc/passwd', '/tmp/vault')).toThrow('Path traversal detected');
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('rejects qmd args with null-byte injection attempts', async () => {
|
|
136
|
-
const { runQmd } = await loadRuntimeModule();
|
|
137
|
-
await expect(runQmd(['up\0date'])).rejects.toThrow('contains null byte');
|
|
138
|
-
expect(spawnMock).not.toHaveBeenCalled();
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it('prints consistent qmd missing guidance', async () => {
|
|
142
|
-
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
143
|
-
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
144
|
-
try {
|
|
145
|
-
const { printQmdMissing } = await loadRuntimeModule();
|
|
146
|
-
printQmdMissing();
|
|
147
|
-
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('ClawVault requires qmd.'));
|
|
148
|
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('install-qmd'));
|
|
149
|
-
} finally {
|
|
150
|
-
errorSpy.mockRestore();
|
|
151
|
-
logSpy.mockRestore();
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
});
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
spawnMock,
|
|
6
|
+
resolveConfiguredVaultPathMock,
|
|
7
|
+
clawvaultCtorMock,
|
|
8
|
+
loadMock
|
|
9
|
+
} = vi.hoisted(() => ({
|
|
10
|
+
spawnMock: vi.fn(),
|
|
11
|
+
resolveConfiguredVaultPathMock: vi.fn(),
|
|
12
|
+
clawvaultCtorMock: vi.fn(),
|
|
13
|
+
loadMock: vi.fn()
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
vi.mock('child_process', () => ({
|
|
17
|
+
spawn: spawnMock
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
vi.mock('../dist/index.js', () => ({
|
|
21
|
+
ClawVault: clawvaultCtorMock,
|
|
22
|
+
resolveVaultPath: resolveConfiguredVaultPathMock,
|
|
23
|
+
QmdUnavailableError: class QmdUnavailableError extends Error {},
|
|
24
|
+
QMD_INSTALL_COMMAND: 'install-qmd'
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
async function loadRuntimeModule() {
|
|
28
|
+
vi.resetModules();
|
|
29
|
+
return await import('./command-runtime.js');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
vi.clearAllMocks();
|
|
34
|
+
clawvaultCtorMock.mockImplementation(() => ({
|
|
35
|
+
load: loadMock
|
|
36
|
+
}));
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('command runtime helpers', () => {
|
|
40
|
+
it('delegates vault path resolution and loads vaults', async () => {
|
|
41
|
+
resolveConfiguredVaultPathMock.mockReturnValue('/resolved/vault');
|
|
42
|
+
loadMock.mockResolvedValue(undefined);
|
|
43
|
+
const { getVault, resolveVaultPath } = await loadRuntimeModule();
|
|
44
|
+
|
|
45
|
+
const resolved = resolveVaultPath('/explicit');
|
|
46
|
+
expect(resolveConfiguredVaultPathMock).toHaveBeenCalledWith({ explicitPath: '/explicit' });
|
|
47
|
+
expect(resolved).toBe('/resolved/vault');
|
|
48
|
+
|
|
49
|
+
await getVault('/explicit');
|
|
50
|
+
expect(clawvaultCtorMock).toHaveBeenCalledWith('/resolved/vault');
|
|
51
|
+
expect(loadMock).toHaveBeenCalled();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('maps qmd ENOENT failures to QmdUnavailableError', async () => {
|
|
55
|
+
const { runQmd, QmdUnavailableError } = await loadRuntimeModule();
|
|
56
|
+
spawnMock.mockImplementation(() => {
|
|
57
|
+
const handlers = {};
|
|
58
|
+
const proc = {
|
|
59
|
+
on: (event, handler) => {
|
|
60
|
+
handlers[event] = handler;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
queueMicrotask(() => {
|
|
64
|
+
handlers.error?.({ code: 'ENOENT' });
|
|
65
|
+
});
|
|
66
|
+
return proc;
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await expect(runQmd(['update'])).rejects.toBeInstanceOf(QmdUnavailableError);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('injects qmd index from environment when configured', async () => {
|
|
73
|
+
const previous = process.env.CLAWVAULT_QMD_INDEX;
|
|
74
|
+
process.env.CLAWVAULT_QMD_INDEX = 'clawvault-test';
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const { runQmd } = await loadRuntimeModule();
|
|
78
|
+
spawnMock.mockImplementation((_command, _args) => {
|
|
79
|
+
const handlers = {};
|
|
80
|
+
const proc = {
|
|
81
|
+
on: (event, handler) => {
|
|
82
|
+
handlers[event] = handler;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
queueMicrotask(() => {
|
|
86
|
+
handlers.close?.(0);
|
|
87
|
+
});
|
|
88
|
+
return proc;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
await runQmd(['update']);
|
|
92
|
+
expect(spawnMock).toHaveBeenCalledWith(
|
|
93
|
+
'qmd',
|
|
94
|
+
['--index', 'clawvault-test', 'update'],
|
|
95
|
+
{ stdio: 'inherit' }
|
|
96
|
+
);
|
|
97
|
+
} finally {
|
|
98
|
+
if (previous === undefined) {
|
|
99
|
+
delete process.env.CLAWVAULT_QMD_INDEX;
|
|
100
|
+
} else {
|
|
101
|
+
process.env.CLAWVAULT_QMD_INDEX = previous;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('surfaces qmd non-zero exit codes as errors', async () => {
|
|
107
|
+
const { runQmd } = await loadRuntimeModule();
|
|
108
|
+
spawnMock.mockImplementation(() => {
|
|
109
|
+
const handlers = {};
|
|
110
|
+
const proc = {
|
|
111
|
+
on: (event, handler) => {
|
|
112
|
+
handlers[event] = handler;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
queueMicrotask(() => {
|
|
116
|
+
handlers.close?.(2);
|
|
117
|
+
});
|
|
118
|
+
return proc;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
await expect(runQmd(['update'])).rejects.toThrow('qmd exited with code 2');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('exports and enforces argument/path sanitization helpers', async () => {
|
|
125
|
+
const { sanitizeQmdArg, validatePathWithinBase } = await loadRuntimeModule();
|
|
126
|
+
expect(sanitizeQmdArg('update')).toBe('update');
|
|
127
|
+
expect(sanitizeQmdArg(42)).toBe('42');
|
|
128
|
+
expect(() => sanitizeQmdArg('bad\0arg')).toThrow('contains null byte');
|
|
129
|
+
|
|
130
|
+
const safePath = validatePathWithinBase('notes/today.md', '/tmp/vault');
|
|
131
|
+
expect(safePath).toBe(path.resolve('/tmp/vault', 'notes/today.md'));
|
|
132
|
+
expect(() => validatePathWithinBase('../etc/passwd', '/tmp/vault')).toThrow('Path traversal detected');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('rejects qmd args with null-byte injection attempts', async () => {
|
|
136
|
+
const { runQmd } = await loadRuntimeModule();
|
|
137
|
+
await expect(runQmd(['up\0date'])).rejects.toThrow('contains null byte');
|
|
138
|
+
expect(spawnMock).not.toHaveBeenCalled();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('prints consistent qmd missing guidance', async () => {
|
|
142
|
+
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
143
|
+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
144
|
+
try {
|
|
145
|
+
const { printQmdMissing } = await loadRuntimeModule();
|
|
146
|
+
printQmdMissing();
|
|
147
|
+
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('ClawVault requires qmd.'));
|
|
148
|
+
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('install-qmd'));
|
|
149
|
+
} finally {
|
|
150
|
+
errorSpy.mockRestore();
|
|
151
|
+
logSpy.mockRestore();
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
});
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { registerAllCommandModules } from './test-helpers/cli-command-fixtures.js';
|
|
3
|
-
|
|
4
|
-
describe('CLI help contract', () => {
|
|
5
|
-
it('includes expected high-level command surface', () => {
|
|
6
|
-
const help = registerAllCommandModules().helpInformation();
|
|
7
|
-
expect(help).toContain('init');
|
|
8
|
-
expect(help).toContain('context');
|
|
9
|
-
expect(help).toContain('inject');
|
|
10
|
-
expect(help).toContain('doctor');
|
|
11
|
-
expect(help).toContain('embed');
|
|
12
|
-
expect(help).toContain('compat');
|
|
13
|
-
expect(help).toContain('graph');
|
|
14
|
-
expect(help).toContain('reflect');
|
|
15
|
-
expect(help).toContain('replay');
|
|
16
|
-
expect(help).toContain('repair-session');
|
|
17
|
-
expect(help).toContain('project');
|
|
18
|
-
expect(help).toContain('template');
|
|
19
|
-
expect(help).toContain('config');
|
|
20
|
-
expect(help).toContain('route');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('documents context/compat/inject/project help details', () => {
|
|
24
|
-
const program = registerAllCommandModules();
|
|
25
|
-
const contextHelp = program.commands.find((command) => command.name() === 'context')?.helpInformation() ?? '';
|
|
26
|
-
const compatHelp = program.commands.find((command) => command.name() === 'compat')?.helpInformation() ?? '';
|
|
27
|
-
const injectHelp = program.commands.find((command) => command.name() === 'inject')?.helpInformation() ?? '';
|
|
28
|
-
const projectCommand = program.commands.find((command) => command.name() === 'project');
|
|
29
|
-
const projectListHelp = projectCommand?.commands.find((command) => command.name() === 'list')?.helpInformation() ?? '';
|
|
30
|
-
const projectBoardHelp = projectCommand?.commands.find((command) => command.name() === 'board')?.helpInformation() ?? '';
|
|
31
|
-
expect(contextHelp).toContain('--profile <profile>');
|
|
32
|
-
expect(contextHelp).toContain('auto');
|
|
33
|
-
expect(compatHelp).toContain('--strict');
|
|
34
|
-
expect(injectHelp).toContain('inject.maxResults');
|
|
35
|
-
expect(injectHelp).toContain('inject.scope');
|
|
36
|
-
expect(projectListHelp).toContain('archived projects are hidden');
|
|
37
|
-
expect(projectBoardHelp).toContain('default: status');
|
|
38
|
-
});
|
|
39
|
-
});
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { registerAllCommandModules } from './test-helpers/cli-command-fixtures.js';
|
|
3
|
+
|
|
4
|
+
describe('CLI help contract', () => {
|
|
5
|
+
it('includes expected high-level command surface', () => {
|
|
6
|
+
const help = registerAllCommandModules().helpInformation();
|
|
7
|
+
expect(help).toContain('init');
|
|
8
|
+
expect(help).toContain('context');
|
|
9
|
+
expect(help).toContain('inject');
|
|
10
|
+
expect(help).toContain('doctor');
|
|
11
|
+
expect(help).toContain('embed');
|
|
12
|
+
expect(help).toContain('compat');
|
|
13
|
+
expect(help).toContain('graph');
|
|
14
|
+
expect(help).toContain('reflect');
|
|
15
|
+
expect(help).toContain('replay');
|
|
16
|
+
expect(help).toContain('repair-session');
|
|
17
|
+
expect(help).toContain('project');
|
|
18
|
+
expect(help).toContain('template');
|
|
19
|
+
expect(help).toContain('config');
|
|
20
|
+
expect(help).toContain('route');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('documents context/compat/inject/project help details', () => {
|
|
24
|
+
const program = registerAllCommandModules();
|
|
25
|
+
const contextHelp = program.commands.find((command) => command.name() === 'context')?.helpInformation() ?? '';
|
|
26
|
+
const compatHelp = program.commands.find((command) => command.name() === 'compat')?.helpInformation() ?? '';
|
|
27
|
+
const injectHelp = program.commands.find((command) => command.name() === 'inject')?.helpInformation() ?? '';
|
|
28
|
+
const projectCommand = program.commands.find((command) => command.name() === 'project');
|
|
29
|
+
const projectListHelp = projectCommand?.commands.find((command) => command.name() === 'list')?.helpInformation() ?? '';
|
|
30
|
+
const projectBoardHelp = projectCommand?.commands.find((command) => command.name() === 'board')?.helpInformation() ?? '';
|
|
31
|
+
expect(contextHelp).toContain('--profile <profile>');
|
|
32
|
+
expect(contextHelp).toContain('auto');
|
|
33
|
+
expect(compatHelp).toContain('--strict');
|
|
34
|
+
expect(injectHelp).toContain('inject.maxResults');
|
|
35
|
+
expect(injectHelp).toContain('inject.scope');
|
|
36
|
+
expect(projectListHelp).toContain('archived projects are hidden');
|
|
37
|
+
expect(projectBoardHelp).toContain('default: status');
|
|
38
|
+
});
|
|
39
|
+
});
|