@productbrain/cli 0.1.0-beta.71 → 0.1.0-beta.72

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 (80) hide show
  1. package/dist/__tests__/audit.test.js +44 -44
  2. package/dist/__tests__/capture.test.js +37 -37
  3. package/dist/__tests__/constellation.test.js +14 -14
  4. package/dist/__tests__/context-strategy.test.js +8 -8
  5. package/dist/__tests__/fields.test.js +20 -20
  6. package/dist/__tests__/ingest.test.js +28 -28
  7. package/dist/__tests__/orient.test.js +8 -8
  8. package/dist/__tests__/promote.test.js +15 -15
  9. package/dist/__tests__/proposals.test.js +18 -18
  10. package/dist/__tests__/relate.test.js +14 -14
  11. package/dist/__tests__/session-touch.test.js +11 -11
  12. package/dist/__tests__/session.test.js +2 -2
  13. package/dist/__tests__/setup.test.js +7 -7
  14. package/dist/__tests__/update.test.js +21 -21
  15. package/dist/__tests__/workspace.test.js +20 -20
  16. package/dist/commands/accept.js +4 -4
  17. package/dist/commands/admin/cockpit.d.ts +4 -2
  18. package/dist/commands/admin/cockpit.d.ts.map +1 -1
  19. package/dist/commands/admin/cockpit.js +213 -6
  20. package/dist/commands/admin/cockpit.js.map +1 -1
  21. package/dist/commands/admin/index.d.ts.map +1 -1
  22. package/dist/commands/admin/index.js +2 -0
  23. package/dist/commands/admin/index.js.map +1 -1
  24. package/dist/commands/admin/inspect.d.ts +9 -0
  25. package/dist/commands/admin/inspect.d.ts.map +1 -1
  26. package/dist/commands/admin/inspect.js +19 -0
  27. package/dist/commands/admin/inspect.js.map +1 -1
  28. package/dist/commands/admin/inspect.test.js +20 -1
  29. package/dist/commands/admin/inspect.test.js.map +1 -1
  30. package/dist/commands/admin/manage.d.ts +8 -0
  31. package/dist/commands/admin/manage.d.ts.map +1 -0
  32. package/dist/commands/admin/manage.js +76 -0
  33. package/dist/commands/admin/manage.js.map +1 -0
  34. package/dist/commands/audit.js +4 -4
  35. package/dist/commands/brief.js +4 -4
  36. package/dist/commands/capture.js +6 -6
  37. package/dist/commands/chain-walk.js +2 -2
  38. package/dist/commands/changes.js +2 -2
  39. package/dist/commands/codex-prep.js +2 -2
  40. package/dist/commands/collections.js +5 -5
  41. package/dist/commands/constellation.js +2 -2
  42. package/dist/commands/context.js +2 -2
  43. package/dist/commands/cross-cut.js +2 -2
  44. package/dist/commands/doctor.js +3 -3
  45. package/dist/commands/doctor.test.js +1 -1
  46. package/dist/commands/fields.js +2 -2
  47. package/dist/commands/get.js +3 -3
  48. package/dist/commands/handshake.js +5 -5
  49. package/dist/commands/ingest.js +6 -6
  50. package/dist/commands/init.d.ts +1 -1
  51. package/dist/commands/init.js +1 -1
  52. package/dist/commands/orient.js +2 -2
  53. package/dist/commands/promote.js +4 -4
  54. package/dist/commands/proposals.js +2 -2
  55. package/dist/commands/reject.js +2 -2
  56. package/dist/commands/relate.js +3 -3
  57. package/dist/commands/search.js +2 -2
  58. package/dist/commands/session.js +7 -7
  59. package/dist/commands/setup.js +5 -5
  60. package/dist/commands/update.js +3 -3
  61. package/dist/commands/usage.d.ts +1 -1
  62. package/dist/commands/usage.js +4 -4
  63. package/dist/commands/verify.js +2 -2
  64. package/dist/commands/workspace.js +4 -4
  65. package/dist/generators/chain-rules.d.ts +3 -3
  66. package/dist/generators/chain-rules.js +3 -3
  67. package/dist/generators/chain-rules.test.js +2 -2
  68. package/dist/generators/portable-knowledge.js +1 -1
  69. package/dist/index.js +1 -1
  70. package/dist/index.js.map +1 -1
  71. package/dist/lib/activation.js +2 -2
  72. package/dist/lib/activation.test.js +3 -3
  73. package/dist/lib/client.d.ts +4 -4
  74. package/dist/lib/client.js +8 -8
  75. package/dist/lib/client.js.map +1 -1
  76. package/dist/lib/onboarding-path-b.js +8 -8
  77. package/dist/lib/onboarding-shared.js +2 -2
  78. package/dist/lib/onboarding.js +4 -4
  79. package/dist/lib/workspace-probe.js +2 -2
  80. package/package.json +1 -1
@@ -3,16 +3,16 @@
3
3
  * BET-181 Slice 3: compound view (entry + grouped relations).
4
4
  *
5
5
  * Verifies:
6
- * 1. Mock convexCall returns known constellation structure; command outputs entry + grouped relations
6
+ * 1. Mock kernelCall returns known constellation structure; command outputs entry + grouped relations
7
7
  * 2. Edge: entry with no relations returns entry-only, empty relations object
8
8
  * 3. Relation types in output derive from the server response, not hardcoded
9
9
  */
10
10
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
11
11
  import { runConstellation } from '../commands/constellation.js';
12
12
  import { setOutputMode } from '../lib/runner.js';
13
- const convexCallMock = vi.fn();
13
+ const kernelCallMock = vi.fn();
14
14
  vi.mock('../lib/client.js', () => ({
15
- convexCall: (...args) => convexCallMock(...args),
15
+ kernelCall: (...args) => kernelCallMock(...args),
16
16
  }));
17
17
  vi.mock('../lib/config.js', () => ({
18
18
  getConfigOrGuide: vi.fn((_fn) => Promise.resolve({ apiKey: 'pb_sk_test', siteUrl: 'https://test.convex.site' })),
@@ -95,12 +95,12 @@ afterEach(() => {
95
95
  });
96
96
  describe('runConstellation — JSON mode (non-TTY)', () => {
97
97
  it('calls chain.getConstellation with the correct entryId', withTty(false, async () => {
98
- convexCallMock.mockResolvedValue(CONSTELLATION_FIXTURE);
98
+ kernelCallMock.mockResolvedValue(CONSTELLATION_FIXTURE);
99
99
  await runConstellation({ entryId: 'BET-181' });
100
- expect(convexCallMock).toHaveBeenCalledWith('chain.getConstellation', { entryId: 'BET-181' });
100
+ expect(kernelCallMock).toHaveBeenCalledWith('chain.getConstellation', { entryId: 'BET-181' });
101
101
  }));
102
102
  it('outputs entry and grouped relations as JSON in non-TTY mode', withTty(false, async () => {
103
- convexCallMock.mockResolvedValue(CONSTELLATION_FIXTURE);
103
+ kernelCallMock.mockResolvedValue(CONSTELLATION_FIXTURE);
104
104
  await runConstellation({ entryId: 'BET-181' });
105
105
  const parsed = JSON.parse(stdoutOutput);
106
106
  expect(parsed.entry.entryId).toBe('BET-181');
@@ -114,7 +114,7 @@ describe('runConstellation — JSON mode (non-TTY)', () => {
114
114
  ...CONSTELLATION_FIXTURE,
115
115
  entry: { ...CONSTELLATION_FIXTURE.entry, _id: 'sys-id', _creationTime: 999999 },
116
116
  };
117
- convexCallMock.mockResolvedValue(fixtureWithInternals);
117
+ kernelCallMock.mockResolvedValue(fixtureWithInternals);
118
118
  await runConstellation({ entryId: 'BET-181' });
119
119
  const parsed = JSON.parse(stdoutOutput);
120
120
  expect(parsed.entry).not.toHaveProperty('_id');
@@ -123,13 +123,13 @@ describe('runConstellation — JSON mode (non-TTY)', () => {
123
123
  });
124
124
  describe('runConstellation — pretty mode (TTY)', () => {
125
125
  it('outputs human-readable grouped view in TTY mode', withTty(true, async () => {
126
- convexCallMock.mockResolvedValue(CONSTELLATION_FIXTURE);
126
+ kernelCallMock.mockResolvedValue(CONSTELLATION_FIXTURE);
127
127
  await runConstellation({ entryId: 'BET-181' });
128
128
  expect(stdoutOutput).toContain('BET-181');
129
129
  expect(stdoutOutput).toContain('CLI Agent-Native Foundation');
130
130
  }));
131
131
  it('shows relation types grouped in TTY output', withTty(true, async () => {
132
- convexCallMock.mockResolvedValue(CONSTELLATION_FIXTURE);
132
+ kernelCallMock.mockResolvedValue(CONSTELLATION_FIXTURE);
133
133
  await runConstellation({ entryId: 'BET-181' });
134
134
  expect(stdoutOutput).toContain('part_of');
135
135
  expect(stdoutOutput).toContain('informed_by');
@@ -137,7 +137,7 @@ describe('runConstellation — pretty mode (TTY)', () => {
137
137
  expect(stdoutOutput).toContain('FEAT-100');
138
138
  }));
139
139
  it('shows direction arrows in TTY output', withTty(true, async () => {
140
- convexCallMock.mockResolvedValue(CONSTELLATION_FIXTURE);
140
+ kernelCallMock.mockResolvedValue(CONSTELLATION_FIXTURE);
141
141
  await runConstellation({ entryId: 'BET-181' });
142
142
  // outgoing → for part_of, incoming ← for informed_by
143
143
  expect(stdoutOutput).toContain('→');
@@ -160,7 +160,7 @@ describe('runConstellation — edge case: entry with no relations', () => {
160
160
  relationTypes: [],
161
161
  },
162
162
  };
163
- convexCallMock.mockResolvedValue(noRelationsFixture);
163
+ kernelCallMock.mockResolvedValue(noRelationsFixture);
164
164
  await runConstellation({ entryId: 'BET-999' });
165
165
  const parsed = JSON.parse(stdoutOutput);
166
166
  expect(parsed.entry.entryId).toBe('BET-999');
@@ -183,7 +183,7 @@ describe('runConstellation — edge case: entry with no relations', () => {
183
183
  relationTypes: [],
184
184
  },
185
185
  };
186
- convexCallMock.mockResolvedValue(noRelationsFixture);
186
+ kernelCallMock.mockResolvedValue(noRelationsFixture);
187
187
  await runConstellation({ entryId: 'BET-999' });
188
188
  expect(stdoutOutput).toContain('No relations');
189
189
  }));
@@ -233,7 +233,7 @@ describe('runConstellation — relation types derive from server response', () =
233
233
  relationTypes: ['related_to', 'governs', 'blocks'],
234
234
  },
235
235
  };
236
- convexCallMock.mockResolvedValue(customRelationFixture);
236
+ kernelCallMock.mockResolvedValue(customRelationFixture);
237
237
  await runConstellation({ entryId: 'DEC-999' });
238
238
  const parsed = JSON.parse(stdoutOutput);
239
239
  // Verify the CLI passes through whatever the server returns
@@ -247,7 +247,7 @@ describe('runConstellation — relation types derive from server response', () =
247
247
  });
248
248
  describe('runConstellation — error handling', () => {
249
249
  it('throws CLIError when entry is not found', withTty(false, async () => {
250
- convexCallMock.mockRejectedValue(new Error('Entry "NOTEXIST-9999" not found.'));
250
+ kernelCallMock.mockRejectedValue(new Error('Entry "NOTEXIST-9999" not found.'));
251
251
  await expect(runConstellation({ entryId: 'NOTEXIST-9999' })).rejects.toThrow('NOTEXIST-9999');
252
252
  }));
253
253
  });
@@ -9,9 +9,9 @@
9
9
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
10
10
  import { runContext } from '../commands/context.js';
11
11
  import { setOutputMode } from '../lib/runner.js';
12
- const convexCallMock = vi.fn();
12
+ const kernelCallMock = vi.fn();
13
13
  vi.mock('../lib/client.js', () => ({
14
- convexCall: (...args) => convexCallMock(...args),
14
+ kernelCall: (...args) => kernelCallMock(...args),
15
15
  }));
16
16
  vi.mock('../lib/config.js', () => ({
17
17
  getConfigOrGuide: vi.fn(() => Promise.resolve({ apiKey: 'pb_sk_test', siteUrl: 'https://test.convex.site' })),
@@ -46,7 +46,7 @@ beforeEach(() => {
46
46
  stderrOutput += String(chunk);
47
47
  return true;
48
48
  });
49
- convexCallMock.mockReset();
49
+ kernelCallMock.mockReset();
50
50
  setOutputMode('pretty');
51
51
  });
52
52
  afterEach(() => {
@@ -56,21 +56,21 @@ afterEach(() => {
56
56
  });
57
57
  describe('runContext — entry-based gather (BET-205 S2 regression)', () => {
58
58
  it('calls chain.gatherContext with entryId and maxHops only', async () => {
59
- convexCallMock.mockResolvedValue(GATHER_FIXTURE);
59
+ kernelCallMock.mockResolvedValue(GATHER_FIXTURE);
60
60
  await runContext({ entryId: 'BET-205' });
61
- expect(convexCallMock).toHaveBeenCalledWith('chain.gatherContext', {
61
+ expect(kernelCallMock).toHaveBeenCalledWith('chain.gatherContext', {
62
62
  entryId: 'BET-205',
63
63
  maxHops: 2,
64
64
  });
65
65
  });
66
66
  it('does not pass strategy to chain.gatherContext', async () => {
67
- convexCallMock.mockResolvedValue(GATHER_FIXTURE);
67
+ kernelCallMock.mockResolvedValue(GATHER_FIXTURE);
68
68
  await runContext({ entryId: 'BET-205' });
69
- const callArgs = convexCallMock.mock.calls[0][1];
69
+ const callArgs = kernelCallMock.mock.calls[0][1];
70
70
  expect(callArgs).not.toHaveProperty('strategy');
71
71
  });
72
72
  it('renders context output correctly', async () => {
73
- convexCallMock.mockResolvedValue(GATHER_FIXTURE);
73
+ kernelCallMock.mockResolvedValue(GATHER_FIXTURE);
74
74
  await runContext({ entryId: 'BET-205' });
75
75
  expect(stdoutOutput).toContain('BET-205');
76
76
  expect(stdoutOutput).toContain('Vector Seed Spike');
@@ -3,7 +3,7 @@
3
3
  * BET-181 Slice 2: Verifies field discovery via chain.getCollectionFields.
4
4
  *
5
5
  * Test contract:
6
- * 1. Mock convexCall returns known field array → command outputs all field properties
6
+ * 1. Mock kernelCall returns known field array → command outputs all field properties
7
7
  * 2. Edge: collection with no fields → returns empty array, not error
8
8
  * 3. Error: invalid collection slug → actionable error message
9
9
  */
@@ -11,9 +11,9 @@ import { beforeEach, afterEach, describe, expect, it, vi } from 'vitest';
11
11
  import { runFields } from '../commands/fields.js';
12
12
  import { setOutputMode } from '../lib/runner.js';
13
13
  import { CLIError } from '../lib/errors.js';
14
- const convexCallMock = vi.fn();
14
+ const kernelCallMock = vi.fn();
15
15
  vi.mock('../lib/client.js', () => ({
16
- convexCall: (...args) => convexCallMock(...args),
16
+ kernelCall: (...args) => kernelCallMock(...args),
17
17
  }));
18
18
  vi.mock('../lib/config.js', () => ({
19
19
  getConfigOrGuide: vi.fn(() => Promise.resolve({ apiKey: 'pb_sk_test', siteUrl: 'https://test.convex.site' })),
@@ -35,7 +35,7 @@ beforeEach(() => {
35
35
  return true;
36
36
  });
37
37
  exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => { throw new Error('process.exit'); });
38
- convexCallMock.mockReset();
38
+ kernelCallMock.mockReset();
39
39
  // Force TTY mode so we get human-readable output in tests
40
40
  setOutputMode('pretty');
41
41
  });
@@ -76,7 +76,7 @@ const SAMPLE_FIELDS = [
76
76
  ];
77
77
  describe('runFields — TTY output with known field array', () => {
78
78
  it('outputs collection name and slug header', async () => {
79
- convexCallMock.mockResolvedValueOnce({
79
+ kernelCallMock.mockResolvedValueOnce({
80
80
  slug: 'work-packages',
81
81
  name: 'Work Packages',
82
82
  fields: SAMPLE_FIELDS,
@@ -85,7 +85,7 @@ describe('runFields — TTY output with known field array', () => {
85
85
  expect(stdoutOutput).toContain('Collection: Work Packages (work-packages)');
86
86
  });
87
87
  it('outputs all field keys', async () => {
88
- convexCallMock.mockResolvedValueOnce({
88
+ kernelCallMock.mockResolvedValueOnce({
89
89
  slug: 'work-packages',
90
90
  name: 'Work Packages',
91
91
  fields: SAMPLE_FIELDS,
@@ -96,7 +96,7 @@ describe('runFields — TTY output with known field array', () => {
96
96
  expect(stdoutOutput).toContain('elements');
97
97
  });
98
98
  it('outputs field type for each field', async () => {
99
- convexCallMock.mockResolvedValueOnce({
99
+ kernelCallMock.mockResolvedValueOnce({
100
100
  slug: 'work-packages',
101
101
  name: 'Work Packages',
102
102
  fields: SAMPLE_FIELDS,
@@ -107,7 +107,7 @@ describe('runFields — TTY output with known field array', () => {
107
107
  expect(stdoutOutput).toContain('rich-text');
108
108
  });
109
109
  it('outputs options for select fields', async () => {
110
- convexCallMock.mockResolvedValueOnce({
110
+ kernelCallMock.mockResolvedValueOnce({
111
111
  slug: 'work-packages',
112
112
  name: 'Work Packages',
113
113
  fields: SAMPLE_FIELDS,
@@ -116,7 +116,7 @@ describe('runFields — TTY output with known field array', () => {
116
116
  expect(stdoutOutput).toContain('small, medium, large');
117
117
  });
118
118
  it('outputs helpText when present', async () => {
119
- convexCallMock.mockResolvedValueOnce({
119
+ kernelCallMock.mockResolvedValueOnce({
120
120
  slug: 'work-packages',
121
121
  name: 'Work Packages',
122
122
  fields: SAMPLE_FIELDS,
@@ -126,7 +126,7 @@ describe('runFields — TTY output with known field array', () => {
126
126
  expect(stdoutOutput).toContain('What problem are we solving?');
127
127
  });
128
128
  it('outputs displayHint when present', async () => {
129
- convexCallMock.mockResolvedValueOnce({
129
+ kernelCallMock.mockResolvedValueOnce({
130
130
  slug: 'work-packages',
131
131
  name: 'Work Packages',
132
132
  fields: SAMPLE_FIELDS,
@@ -135,7 +135,7 @@ describe('runFields — TTY output with known field array', () => {
135
135
  expect(stdoutOutput).toContain('badge');
136
136
  });
137
137
  it('outputs zone when present', async () => {
138
- convexCallMock.mockResolvedValueOnce({
138
+ kernelCallMock.mockResolvedValueOnce({
139
139
  slug: 'work-packages',
140
140
  name: 'Work Packages',
141
141
  fields: SAMPLE_FIELDS,
@@ -145,7 +145,7 @@ describe('runFields — TTY output with known field array', () => {
145
145
  expect(stdoutOutput).toContain('body');
146
146
  });
147
147
  it('outputs semanticRole when present', async () => {
148
- convexCallMock.mockResolvedValueOnce({
148
+ kernelCallMock.mockResolvedValueOnce({
149
149
  slug: 'work-packages',
150
150
  name: 'Work Packages',
151
151
  fields: SAMPLE_FIELDS,
@@ -157,7 +157,7 @@ describe('runFields — TTY output with known field array', () => {
157
157
  expect(stdoutOutput).toContain('role: elements');
158
158
  });
159
159
  it('marks required fields', async () => {
160
- convexCallMock.mockResolvedValueOnce({
160
+ kernelCallMock.mockResolvedValueOnce({
161
161
  slug: 'work-packages',
162
162
  name: 'Work Packages',
163
163
  fields: SAMPLE_FIELDS,
@@ -167,19 +167,19 @@ describe('runFields — TTY output with known field array', () => {
167
167
  expect(stdoutOutput).toContain('appetite *');
168
168
  });
169
169
  it('calls chain.getCollectionFields with the correct slug', async () => {
170
- convexCallMock.mockResolvedValueOnce({
170
+ kernelCallMock.mockResolvedValueOnce({
171
171
  slug: 'decisions',
172
172
  name: 'Decisions',
173
173
  fields: [],
174
174
  });
175
175
  await runFields({ collectionSlug: 'decisions' });
176
- expect(convexCallMock).toHaveBeenCalledWith('chain.getCollectionFields', { slug: 'decisions' });
176
+ expect(kernelCallMock).toHaveBeenCalledWith('chain.getCollectionFields', { slug: 'decisions' });
177
177
  });
178
178
  });
179
179
  describe('runFields — JSON mode', () => {
180
180
  it('outputs JSON with full field array when piped', async () => {
181
181
  setOutputMode('json');
182
- convexCallMock.mockResolvedValueOnce({
182
+ kernelCallMock.mockResolvedValueOnce({
183
183
  slug: 'work-packages',
184
184
  name: 'Work Packages',
185
185
  fields: SAMPLE_FIELDS,
@@ -202,7 +202,7 @@ describe('runFields — JSON mode', () => {
202
202
  });
203
203
  describe('runFields — edge: empty fields array', () => {
204
204
  it('returns "No fields defined" message, does not error', async () => {
205
- convexCallMock.mockResolvedValueOnce({
205
+ kernelCallMock.mockResolvedValueOnce({
206
206
  slug: 'notes',
207
207
  name: 'Notes',
208
208
  fields: [],
@@ -215,21 +215,21 @@ describe('runFields — edge: empty fields array', () => {
215
215
  });
216
216
  describe('runFields — error: invalid collection slug', () => {
217
217
  it('throws CLIError with actionable message for invalid slug', async () => {
218
- convexCallMock.mockResolvedValueOnce(null);
218
+ kernelCallMock.mockResolvedValueOnce(null);
219
219
  const err = await runFields({ collectionSlug: 'nonexistent-slug' }).catch((e) => e);
220
220
  expect(err).toBeInstanceOf(CLIError);
221
221
  expect(err.message).toContain('nonexistent-slug');
222
222
  expect(err.message).toContain('not found');
223
223
  });
224
224
  it('includes suggestion to use a valid slug in guidance', async () => {
225
- convexCallMock.mockResolvedValueOnce(null);
225
+ kernelCallMock.mockResolvedValueOnce(null);
226
226
  const err = await runFields({ collectionSlug: 'bad-slug' }).catch((e) => e);
227
227
  expect(err).toBeInstanceOf(CLIError);
228
228
  expect(err.guidance).toContain('valid collection slug');
229
229
  });
230
230
  it('throws CLIError in JSON mode for invalid slug', async () => {
231
231
  setOutputMode('json');
232
- convexCallMock.mockResolvedValueOnce(null);
232
+ kernelCallMock.mockResolvedValueOnce(null);
233
233
  const err = await runFields({ collectionSlug: 'bad-slug' }).catch((e) => e);
234
234
  expect(err).toBeInstanceOf(CLIError);
235
235
  expect(err.message).toContain('bad-slug');
@@ -1,5 +1,5 @@
1
1
  /**
2
- * CLI ingest command — verify convexCall sequence and args.
2
+ * CLI ingest command — verify kernelCall sequence and args.
3
3
  * BET-81 Slice 1: chain.ingestDocument called with correct args, batch size.
4
4
  * BET-221 S7 (FEAT-697): --dry-run, --resume, --concurrency flags.
5
5
  */
@@ -8,9 +8,9 @@ import { mkdtempSync, writeFileSync, rmSync } from 'fs';
8
8
  import { join } from 'path';
9
9
  import { tmpdir } from 'os';
10
10
  import { runIngest } from '../commands/ingest.js';
11
- const convexCallMock = vi.fn();
11
+ const kernelCallMock = vi.fn();
12
12
  vi.mock('../lib/client.js', () => ({
13
- convexCall: (...args) => convexCallMock(...args),
13
+ kernelCall: (...args) => kernelCallMock(...args),
14
14
  }));
15
15
  vi.mock('../lib/config.js', () => ({
16
16
  getConfigOrGuide: vi.fn((retry) => Promise.resolve({ apiKey: 'pb_sk_test', siteUrl: 'https://test.convex.site' })),
@@ -20,7 +20,7 @@ describe('runIngest', () => {
20
20
  beforeEach(() => {
21
21
  vi.clearAllMocks();
22
22
  tmpDir = mkdtempSync(join(tmpdir(), 'pb-ingest-'));
23
- convexCallMock
23
+ kernelCallMock
24
24
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' }) // resolveWorkspace
25
25
  .mockResolvedValueOnce({ sessionId: 'sess-1', toolsScope: 'readwrite', workspaceName: 'Test' }) // startSession
26
26
  .mockResolvedValue({ entriesCreated: ['e1', 'e2'], skipped: 0 }); // ingestDocument, closeSession
@@ -32,15 +32,15 @@ describe('runIngest', () => {
32
32
  const f = join(tmpDir, 'doc.md');
33
33
  writeFileSync(f, '# Test\n\nContent here.');
34
34
  await runIngest({ pattern: f });
35
- expect(convexCallMock).toHaveBeenNthCalledWith(1, 'resolveWorkspace', {});
36
- expect(convexCallMock).toHaveBeenNthCalledWith(2, 'agent.startSession', {
35
+ expect(kernelCallMock).toHaveBeenNthCalledWith(1, 'resolveWorkspace', {});
36
+ expect(kernelCallMock).toHaveBeenNthCalledWith(2, 'agent.startSession', {
37
37
  workspaceId: 'ws-1',
38
38
  apiKeyId: 'key-1',
39
39
  clientKind: 'cli',
40
40
  });
41
41
  });
42
42
  it('calls chain.ingestDocument with content, sourceRef, ingestionRunId, sessionId', async () => {
43
- convexCallMock
43
+ kernelCallMock
44
44
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' })
45
45
  .mockResolvedValueOnce({ sessionId: 'sess-1', toolsScope: 'readwrite', workspaceName: 'Test' })
46
46
  .mockResolvedValue({ entriesCreated: ['e1', 'e2'], skipped: 0 });
@@ -48,7 +48,7 @@ describe('runIngest', () => {
48
48
  const content = '# Decision\n\nWe use TypeScript.';
49
49
  writeFileSync(f, content);
50
50
  await runIngest({ pattern: f });
51
- const ingestCall = convexCallMock.mock.calls.find((c) => c[0] === 'chain.ingestDocument');
51
+ const ingestCall = kernelCallMock.mock.calls.find((c) => c[0] === 'chain.ingestDocument');
52
52
  expect(ingestCall).toBeDefined();
53
53
  const [, args] = ingestCall;
54
54
  expect(args.content).toBe(content);
@@ -57,19 +57,19 @@ describe('runIngest', () => {
57
57
  expect(args.sessionId).toBe('sess-1');
58
58
  });
59
59
  it('calls agent.closeSession after ingest', async () => {
60
- convexCallMock
60
+ kernelCallMock
61
61
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' })
62
62
  .mockResolvedValueOnce({ sessionId: 'sess-1', toolsScope: 'readwrite', workspaceName: 'Test' })
63
63
  .mockResolvedValue({ entriesCreated: ['e1', 'e2'], skipped: 0 });
64
64
  const f = join(tmpDir, 'doc.md');
65
65
  writeFileSync(f, '# Test');
66
66
  await runIngest({ pattern: f });
67
- const closeCall = convexCallMock.mock.calls.find((c) => c[0] === 'agent.closeSession');
67
+ const closeCall = kernelCallMock.mock.calls.find((c) => c[0] === 'agent.closeSession');
68
68
  expect(closeCall).toBeDefined();
69
69
  expect(closeCall).toEqual(['agent.closeSession', { sessionId: 'sess-1', status: 'closed' }]);
70
70
  });
71
71
  it('processes one file per chain.ingestDocument call (no batching of content)', async () => {
72
- convexCallMock
72
+ kernelCallMock
73
73
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' })
74
74
  .mockResolvedValueOnce({ sessionId: 'sess-1', toolsScope: 'readwrite', workspaceName: 'Test' })
75
75
  .mockResolvedValue({ entriesCreated: ['e1', 'e2'], skipped: 0 });
@@ -78,7 +78,7 @@ describe('runIngest', () => {
78
78
  writeFileSync(f1, '# A');
79
79
  writeFileSync(f2, '# B');
80
80
  await runIngest({ pattern: join(tmpDir, '*.md') });
81
- const ingestCalls = convexCallMock.mock.calls.filter((c) => c[0] === 'chain.ingestDocument');
81
+ const ingestCalls = kernelCallMock.mock.calls.filter((c) => c[0] === 'chain.ingestDocument');
82
82
  expect(ingestCalls).toHaveLength(2);
83
83
  const contents = ingestCalls.map((c) => c[1].content);
84
84
  expect(contents).toContain('# A');
@@ -86,27 +86,27 @@ describe('runIngest', () => {
86
86
  });
87
87
  // ─── BET-221 S7: --dry-run ────────────────────────────────────────────────
88
88
  it('--dry-run passes dryRun: true to chain.ingestDocument', async () => {
89
- convexCallMock
89
+ kernelCallMock
90
90
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' })
91
91
  .mockResolvedValueOnce({ sessionId: 'sess-1', toolsScope: 'readwrite', workspaceName: 'Test' })
92
92
  .mockResolvedValue({ entriesCreated: ['e1'], skipped: 0 });
93
93
  const f = join(tmpDir, 'dry.md');
94
94
  writeFileSync(f, '# Dry Run Test');
95
95
  await runIngest({ pattern: f, dryRun: true });
96
- const ingestCall = convexCallMock.mock.calls.find((c) => c[0] === 'chain.ingestDocument');
96
+ const ingestCall = kernelCallMock.mock.calls.find((c) => c[0] === 'chain.ingestDocument');
97
97
  expect(ingestCall).toBeDefined();
98
98
  const [, args] = ingestCall;
99
99
  expect(args.dryRun).toBe(true);
100
100
  });
101
101
  it('--dry-run still calls agent.closeSession', async () => {
102
- convexCallMock
102
+ kernelCallMock
103
103
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' })
104
104
  .mockResolvedValueOnce({ sessionId: 'sess-1', toolsScope: 'readwrite', workspaceName: 'Test' })
105
105
  .mockResolvedValue({ entriesCreated: ['e1'], skipped: 0 });
106
106
  const f = join(tmpDir, 'dry2.md');
107
107
  writeFileSync(f, '# Dry Run 2');
108
108
  await runIngest({ pattern: f, dryRun: true });
109
- const closeCall = convexCallMock.mock.calls.find((c) => c[0] === 'agent.closeSession');
109
+ const closeCall = kernelCallMock.mock.calls.find((c) => c[0] === 'agent.closeSession');
110
110
  expect(closeCall).toBeDefined();
111
111
  });
112
112
  // ─── BET-221 S7: --resume ─────────────────────────────────────────────────
@@ -115,14 +115,14 @@ describe('runIngest', () => {
115
115
  const f2 = join(tmpDir, 'new.md');
116
116
  writeFileSync(f1, '# Already committed');
117
117
  writeFileSync(f2, '# New file');
118
- convexCallMock.mockReset();
119
- convexCallMock
118
+ kernelCallMock.mockReset();
119
+ kernelCallMock
120
120
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' }) // resolveWorkspace
121
121
  .mockResolvedValueOnce([f1]) // staging.getCommittedSourceRefs
122
122
  .mockResolvedValueOnce({ sessionId: 'sess-1', toolsScope: 'readwrite', workspaceName: 'Test' }) // startSession
123
123
  .mockResolvedValue({ entriesCreated: ['e1'], skipped: 0 }); // ingestDocument, closeSession
124
124
  await runIngest({ pattern: join(tmpDir, '*.md'), resume: true });
125
- const ingestCalls = convexCallMock.mock.calls.filter((c) => c[0] === 'chain.ingestDocument');
125
+ const ingestCalls = kernelCallMock.mock.calls.filter((c) => c[0] === 'chain.ingestDocument');
126
126
  expect(ingestCalls).toHaveLength(1);
127
127
  const [, args] = ingestCalls[0];
128
128
  expect(args.sourceRef).toBe(f2);
@@ -130,13 +130,13 @@ describe('runIngest', () => {
130
130
  it('--resume exits early when all files already committed', async () => {
131
131
  const f = join(tmpDir, 'done.md');
132
132
  writeFileSync(f, '# Done');
133
- convexCallMock.mockReset();
134
- convexCallMock
133
+ kernelCallMock.mockReset();
134
+ kernelCallMock
135
135
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' }) // resolveWorkspace
136
136
  .mockResolvedValueOnce([f]); // staging.getCommittedSourceRefs
137
137
  await runIngest({ pattern: f, resume: true });
138
138
  // Should NOT call startSession or ingestDocument — all skipped
139
- const sessionCalls = convexCallMock.mock.calls.filter((c) => c[0] === 'agent.startSession');
139
+ const sessionCalls = kernelCallMock.mock.calls.filter((c) => c[0] === 'agent.startSession');
140
140
  expect(sessionCalls).toHaveLength(0);
141
141
  });
142
142
  // ─── BET-221 S7: --concurrency ────────────────────────────────────────────
@@ -147,12 +147,12 @@ describe('runIngest', () => {
147
147
  writeFileSync(f1, '# P1');
148
148
  writeFileSync(f2, '# P2');
149
149
  writeFileSync(f3, '# P3');
150
- convexCallMock
150
+ kernelCallMock
151
151
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' })
152
152
  .mockResolvedValueOnce({ sessionId: 'sess-1', toolsScope: 'readwrite', workspaceName: 'Test' })
153
153
  .mockResolvedValue({ entriesCreated: ['e1'], skipped: 0 });
154
154
  await runIngest({ pattern: join(tmpDir, '*.md'), concurrency: 3 });
155
- const ingestCalls = convexCallMock.mock.calls.filter((c) => c[0] === 'chain.ingestDocument');
155
+ const ingestCalls = kernelCallMock.mock.calls.filter((c) => c[0] === 'chain.ingestDocument');
156
156
  expect(ingestCalls).toHaveLength(3);
157
157
  });
158
158
  it('default concurrency is 1 (sequential)', async () => {
@@ -160,25 +160,25 @@ describe('runIngest', () => {
160
160
  const f2 = join(tmpDir, 'seq2.md');
161
161
  writeFileSync(f1, '# Seq1');
162
162
  writeFileSync(f2, '# Seq2');
163
- convexCallMock
163
+ kernelCallMock
164
164
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' })
165
165
  .mockResolvedValueOnce({ sessionId: 'sess-1', toolsScope: 'readwrite', workspaceName: 'Test' })
166
166
  .mockResolvedValue({ entriesCreated: ['e1'], skipped: 0 });
167
167
  await runIngest({ pattern: join(tmpDir, '*.md') });
168
168
  // Both files processed — sequential, no concurrency option
169
- const ingestCalls = convexCallMock.mock.calls.filter((c) => c[0] === 'chain.ingestDocument');
169
+ const ingestCalls = kernelCallMock.mock.calls.filter((c) => c[0] === 'chain.ingestDocument');
170
170
  expect(ingestCalls).toHaveLength(2);
171
171
  });
172
172
  it('--concurrency is clamped to max 5', async () => {
173
173
  const f = join(tmpDir, 'clamp.md');
174
174
  writeFileSync(f, '# Clamp');
175
- convexCallMock
175
+ kernelCallMock
176
176
  .mockResolvedValueOnce({ _id: 'ws-1', keyId: 'key-1' })
177
177
  .mockResolvedValueOnce({ sessionId: 'sess-1', toolsScope: 'readwrite', workspaceName: 'Test' })
178
178
  .mockResolvedValue({ entriesCreated: ['e1'], skipped: 0 });
179
179
  // concurrency 10 should be clamped to 5 internally (no error)
180
180
  await runIngest({ pattern: f, concurrency: 10 });
181
- const ingestCalls = convexCallMock.mock.calls.filter((c) => c[0] === 'chain.ingestDocument');
181
+ const ingestCalls = kernelCallMock.mock.calls.filter((c) => c[0] === 'chain.ingestDocument');
182
182
  expect(ingestCalls).toHaveLength(1);
183
183
  });
184
184
  });
@@ -1,8 +1,8 @@
1
1
  import { beforeEach, describe, expect, it, vi } from 'vitest';
2
2
  import { runOrient } from '../commands/orient.js';
3
- const convexCallMock = vi.fn();
3
+ const kernelCallMock = vi.fn();
4
4
  vi.mock('../lib/client.js', () => ({
5
- convexCall: (...args) => convexCallMock(...args),
5
+ kernelCall: (...args) => kernelCallMock(...args),
6
6
  }));
7
7
  vi.mock('../lib/config.js', () => ({
8
8
  getConfigOrGuide: vi.fn(() => Promise.resolve({ apiKey: 'pb_sk_test', siteUrl: 'https://test.convex.site' })),
@@ -85,24 +85,24 @@ const orientViewTaskOnly = {
85
85
  describe('runOrient', () => {
86
86
  beforeEach(() => {
87
87
  vi.clearAllMocks();
88
- convexCallMock.mockResolvedValue(orientViewWithoutTask);
88
+ kernelCallMock.mockResolvedValue(orientViewWithoutTask);
89
89
  });
90
90
  it('calls chain.getOrientView without task by default', async () => {
91
91
  const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
92
92
  await runOrient();
93
93
  const output = writeSpy.mock.calls.map((call) => String(call[0])).join('');
94
94
  writeSpy.mockRestore();
95
- expect(convexCallMock).toHaveBeenCalledWith('chain.getOrientView', {});
95
+ expect(kernelCallMock).toHaveBeenCalledWith('chain.getOrientView', {});
96
96
  expect(output).toContain('Task grounding required');
97
97
  expect(output).toContain('pb orient --task');
98
98
  });
99
99
  it('passes task through to chain.getOrientView and renders task context', async () => {
100
100
  const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
101
- convexCallMock.mockResolvedValueOnce(orientView);
101
+ kernelCallMock.mockResolvedValueOnce(orientView);
102
102
  await runOrient({ task: 'harden auth startup flow' });
103
103
  const output = writeSpy.mock.calls.map((call) => String(call[0])).join('');
104
104
  writeSpy.mockRestore();
105
- expect(convexCallMock).toHaveBeenCalledWith('chain.getOrientView', {
105
+ expect(kernelCallMock).toHaveBeenCalledWith('chain.getOrientView', {
106
106
  task: 'harden auth startup flow',
107
107
  });
108
108
  expect(output).toContain('## Task grounding');
@@ -113,7 +113,7 @@ describe('runOrient', () => {
113
113
  });
114
114
  it('renders task context even when governance buckets are empty', async () => {
115
115
  const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
116
- convexCallMock.mockResolvedValueOnce(orientViewTaskOnly);
116
+ kernelCallMock.mockResolvedValueOnce(orientViewTaskOnly);
117
117
  await runOrient({ task: 'trace supporting context only' });
118
118
  const output = writeSpy.mock.calls.map((call) => String(call[0])).join('');
119
119
  writeSpy.mockRestore();
@@ -131,7 +131,7 @@ describe('runOrient', () => {
131
131
  });
132
132
  it('brief mode with task context renders startup grounding line', async () => {
133
133
  const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
134
- convexCallMock.mockResolvedValueOnce(orientView);
134
+ kernelCallMock.mockResolvedValueOnce(orientView);
135
135
  await runOrient({ brief: true, task: 'harden auth startup flow' });
136
136
  const output = writeSpy.mock.calls.map((call) => String(call[0])).join('');
137
137
  writeSpy.mockRestore();