@mmnto/cli 1.52.0 → 1.53.1
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/dist/adapters/github-cli-pr.d.ts.map +1 -1
- package/dist/adapters/github-cli-pr.js +3 -1
- package/dist/adapters/github-cli-pr.js.map +1 -1
- package/dist/adapters/github-cli-pr.test.js +4 -4
- package/dist/adapters/github-cli-pr.test.js.map +1 -1
- package/dist/adapters/github-cli-project.d.ts +21 -0
- package/dist/adapters/github-cli-project.d.ts.map +1 -0
- package/dist/adapters/github-cli-project.js +69 -0
- package/dist/adapters/github-cli-project.js.map +1 -0
- package/dist/adapters/github-cli.d.ts +7 -1
- package/dist/adapters/github-cli.d.ts.map +1 -1
- package/dist/adapters/github-cli.js +30 -0
- package/dist/adapters/github-cli.js.map +1 -1
- package/dist/adapters/github-cli.test.js +26 -0
- package/dist/adapters/github-cli.test.js.map +1 -1
- package/dist/adapters/issue-adapter.d.ts +18 -0
- package/dist/adapters/issue-adapter.d.ts.map +1 -1
- package/dist/adapters/pr-adapter.d.ts +2 -0
- package/dist/adapters/pr-adapter.d.ts.map +1 -1
- package/dist/commands/orient-coherence.d.ts +33 -0
- package/dist/commands/orient-coherence.d.ts.map +1 -0
- package/dist/commands/orient-coherence.js +64 -0
- package/dist/commands/orient-coherence.js.map +1 -0
- package/dist/commands/orient-coherence.test.d.ts +2 -0
- package/dist/commands/orient-coherence.test.d.ts.map +1 -0
- package/dist/commands/orient-coherence.test.js +99 -0
- package/dist/commands/orient-coherence.test.js.map +1 -0
- package/dist/commands/orient.d.ts +97 -0
- package/dist/commands/orient.d.ts.map +1 -0
- package/dist/commands/orient.js +530 -0
- package/dist/commands/orient.js.map +1 -0
- package/dist/commands/orient.test.d.ts +2 -0
- package/dist/commands/orient.test.d.ts.map +1 -0
- package/dist/commands/orient.test.js +457 -0
- package/dist/commands/orient.test.js.map +1 -0
- package/dist/help.js +1 -1
- package/dist/help.js.map +1 -1
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
5
|
+
// ─── Adapter mocks (control every primitive orient fetches) ─────────────
|
|
6
|
+
const mockFetchOpenPRs = vi.fn();
|
|
7
|
+
vi.mock('../adapters/github-cli-pr.js', () => ({
|
|
8
|
+
GitHubCliPrAdapter: class {
|
|
9
|
+
fetchOpenPRs() {
|
|
10
|
+
return mockFetchOpenPRs();
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
const mockFetchOpenIssuesWithBody = vi.fn();
|
|
15
|
+
vi.mock('../adapters/github-cli.js', () => ({
|
|
16
|
+
GitHubCliAdapter: class {
|
|
17
|
+
fetchOpenIssuesWithBody() {
|
|
18
|
+
return mockFetchOpenIssuesWithBody();
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
}));
|
|
22
|
+
const mockFetchBoardItems = vi.fn();
|
|
23
|
+
vi.mock('../adapters/github-cli-project.js', async () => {
|
|
24
|
+
const actual = await vi.importActual('../adapters/github-cli-project.js');
|
|
25
|
+
return { ...actual, fetchBoardItems: () => mockFetchBoardItems() };
|
|
26
|
+
});
|
|
27
|
+
// ─── @mmnto/totem mock (gh repo view slug + freeze + registry + git root) ─
|
|
28
|
+
//
|
|
29
|
+
// CRITICAL: orient must NEVER reach the embedder. We provide a `createEmbedder`
|
|
30
|
+
// that throws if called — the structural guard that orient dodges #2018 (it
|
|
31
|
+
// runs green with `@google/genai` absent because it never touches embeddings).
|
|
32
|
+
const mockSafeExec = vi.fn();
|
|
33
|
+
const mockReadRegistry = vi.fn(() => ({}));
|
|
34
|
+
const embedderTripwire = vi.fn(() => {
|
|
35
|
+
throw new Error('orient must never reach the embedder (#2018 structural guard)');
|
|
36
|
+
});
|
|
37
|
+
// The repo root orient resolves to. Tests point it at a real temp dir so the
|
|
38
|
+
// REAL readFreezeConfig (kept un-mocked) reads a real `.totem/freeze.json` —
|
|
39
|
+
// exercising the actual fail-loud reader rather than a stub.
|
|
40
|
+
let repoRoot = '/repo/root';
|
|
41
|
+
// Spread the real core module, overriding only the primitives orient reads.
|
|
42
|
+
// Full replacement is fragile (core has many transitive exports the adapters
|
|
43
|
+
// need); status.test.ts uses this same importActual pattern. Note:
|
|
44
|
+
// `readFreezeConfig` is intentionally NOT overridden — the freeze section is
|
|
45
|
+
// tested against the real reader via a real temp `.totem/freeze.json`.
|
|
46
|
+
vi.mock('@mmnto/totem', async () => {
|
|
47
|
+
const actual = await vi.importActual('@mmnto/totem');
|
|
48
|
+
return {
|
|
49
|
+
...actual,
|
|
50
|
+
safeExec: () => mockSafeExec(),
|
|
51
|
+
readRegistry: () => mockReadRegistry(),
|
|
52
|
+
resolveGitRoot: () => repoRoot,
|
|
53
|
+
// #2018 structural tripwire: orient must never construct an embedder/store.
|
|
54
|
+
createEmbedder: embedderTripwire,
|
|
55
|
+
LanceStore: class {
|
|
56
|
+
constructor() {
|
|
57
|
+
embedderTripwire();
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
// ─── utils mock (config / project number resolution) ────────────────────
|
|
63
|
+
const mockLoadConfig = vi.fn();
|
|
64
|
+
vi.mock('../utils.js', () => ({
|
|
65
|
+
resolveConfigPath: () => '/repo/root/totem.config.ts',
|
|
66
|
+
loadConfig: () => mockLoadConfig(),
|
|
67
|
+
}));
|
|
68
|
+
import { deriveOrientReport, orientCommand, renderOrientForSession, renderReport, } from './orient.js';
|
|
69
|
+
// ─── Test harness ───────────────────────────────────────
|
|
70
|
+
let stdout;
|
|
71
|
+
let writeSpy;
|
|
72
|
+
function runJson() {
|
|
73
|
+
return orientCommand({ json: true });
|
|
74
|
+
}
|
|
75
|
+
function parseJson() {
|
|
76
|
+
return JSON.parse(stdout);
|
|
77
|
+
}
|
|
78
|
+
let tmpRoot;
|
|
79
|
+
beforeEach(() => {
|
|
80
|
+
stdout = '';
|
|
81
|
+
writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
82
|
+
stdout += chunk.toString();
|
|
83
|
+
return true;
|
|
84
|
+
});
|
|
85
|
+
// Real temp repo root so the real readFreezeConfig has a real (empty) .totem.
|
|
86
|
+
tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'totem-orient-'));
|
|
87
|
+
fs.mkdirSync(path.join(tmpRoot, '.totem'), { recursive: true });
|
|
88
|
+
repoRoot = tmpRoot;
|
|
89
|
+
// Default happy-path primitives.
|
|
90
|
+
mockSafeExec.mockReturnValue(JSON.stringify({ owner: { login: 'mmnto-ai' }, name: 'totem' }));
|
|
91
|
+
mockReadRegistry.mockReturnValue({});
|
|
92
|
+
mockFetchOpenPRs.mockReturnValue([]);
|
|
93
|
+
mockFetchOpenIssuesWithBody.mockReturnValue([]);
|
|
94
|
+
mockFetchBoardItems.mockReturnValue([]);
|
|
95
|
+
mockLoadConfig.mockResolvedValue({ orient: undefined });
|
|
96
|
+
delete process.env['TOTEM_ORIENT_PROJECT'];
|
|
97
|
+
});
|
|
98
|
+
afterEach(() => {
|
|
99
|
+
writeSpy.mockRestore();
|
|
100
|
+
vi.clearAllMocks();
|
|
101
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
102
|
+
delete process.env['TOTEM_ORIENT_PROJECT'];
|
|
103
|
+
});
|
|
104
|
+
// ─── Per-section failure isolation ──────────────────────
|
|
105
|
+
describe('orient per-section failure isolation', () => {
|
|
106
|
+
it('an issue-fetch failure does not blank the PR section', async () => {
|
|
107
|
+
mockFetchOpenPRs.mockReturnValue([
|
|
108
|
+
{ number: 5, title: 'fix', headRefName: 'fix/x', isDraft: false },
|
|
109
|
+
]);
|
|
110
|
+
mockFetchOpenIssuesWithBody.mockImplementation(() => {
|
|
111
|
+
throw new Error('gh issue list exploded');
|
|
112
|
+
});
|
|
113
|
+
await runJson();
|
|
114
|
+
const r = parseJson();
|
|
115
|
+
// PRs still derive…
|
|
116
|
+
expect(r.openPRs).toEqual([{ number: 5, title: 'fix', headRefName: 'fix/x', isDraft: false }]);
|
|
117
|
+
// …while the issue-derived sections surface as { error }.
|
|
118
|
+
expect(r.epics).toEqual({ error: 'gh issue list exploded' });
|
|
119
|
+
expect(r.otherOpenIssues).toEqual({ error: 'gh issue list exploded' });
|
|
120
|
+
});
|
|
121
|
+
it('a malformed freeze.json isolates to the parked section only ({error}, not blank)', async () => {
|
|
122
|
+
// Real malformed file → real readFreezeConfig throws TotemConfigError.
|
|
123
|
+
fs.writeFileSync(path.join(tmpRoot, '.totem', 'freeze.json'), '{ not valid json');
|
|
124
|
+
mockFetchOpenPRs.mockReturnValue([
|
|
125
|
+
{ number: 9, title: 'fix', headRefName: 'fix/y', isDraft: false },
|
|
126
|
+
]);
|
|
127
|
+
await runJson();
|
|
128
|
+
const r = parseJson();
|
|
129
|
+
expect(r.parked).toHaveProperty('error', expect.stringMatching(/freeze\.json/i));
|
|
130
|
+
// The PR section still derives — failure is isolated.
|
|
131
|
+
expect(r.openPRs).toEqual([{ number: 9, title: 'fix', headRefName: 'fix/y', isDraft: false }]);
|
|
132
|
+
});
|
|
133
|
+
it('derives real parked entries from a valid freeze.json', async () => {
|
|
134
|
+
fs.writeFileSync(path.join(tmpRoot, '.totem', 'freeze.json'), JSON.stringify({
|
|
135
|
+
frozen: [{ subsystem: 'embedder', since: '2026-01-01', reason: 'blocked. extra' }],
|
|
136
|
+
}));
|
|
137
|
+
await runJson();
|
|
138
|
+
const r = parseJson();
|
|
139
|
+
expect(r.parked).toEqual([
|
|
140
|
+
{ subsystem: 'embedder', since: '2026-01-01', reason: 'blocked. extra' },
|
|
141
|
+
]);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
// ─── Unexpected shape → {error}, never empty ────────────
|
|
145
|
+
describe('orient unexpected-shape handling', () => {
|
|
146
|
+
it('an unexpected gh repo view shape surfaces as a repo { error }, not a blank', async () => {
|
|
147
|
+
mockSafeExec.mockReturnValue(JSON.stringify({ owner: {}, name: '' }));
|
|
148
|
+
await runJson();
|
|
149
|
+
const r = parseJson();
|
|
150
|
+
expect(r.repo).toEqual({ error: 'unexpected `gh repo view` shape' });
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
// ─── Cross-repo parent guard ────────────────────────────
|
|
154
|
+
describe('orient cross-repo parent guard', () => {
|
|
155
|
+
it('a cross-repo Parent ref never attaches a child to a same-numbered LOCAL epic', async () => {
|
|
156
|
+
mockSafeExec.mockReturnValue(JSON.stringify({ owner: { login: 'mmnto-ai' }, name: 'totem' }));
|
|
157
|
+
mockFetchOpenIssuesWithBody.mockReturnValue([
|
|
158
|
+
{ number: 50, title: 'Local epic', body: '', labels: ['type: epic'] },
|
|
159
|
+
// Child points at other-repo#50 — must NOT attach to local #50.
|
|
160
|
+
{
|
|
161
|
+
number: 51,
|
|
162
|
+
title: 'Foreign child',
|
|
163
|
+
body: '**Parent:** other-owner/other-repo#50',
|
|
164
|
+
labels: [],
|
|
165
|
+
},
|
|
166
|
+
// Child points at LOCAL #50 (bare ref) — must attach.
|
|
167
|
+
{ number: 52, title: 'Local child', body: '**Parent:** #50', labels: [] },
|
|
168
|
+
]);
|
|
169
|
+
await runJson();
|
|
170
|
+
const r = parseJson();
|
|
171
|
+
expect(r.epics).toEqual([
|
|
172
|
+
{
|
|
173
|
+
number: 50,
|
|
174
|
+
title: 'Local epic',
|
|
175
|
+
labels: ['type: epic'],
|
|
176
|
+
subIssues: [{ number: 52, title: 'Local child' }],
|
|
177
|
+
},
|
|
178
|
+
]);
|
|
179
|
+
// The foreign-parent child stays in OTHER (never dropped, never mis-attached).
|
|
180
|
+
expect(r.otherOpenIssues).toEqual([{ number: 51, title: 'Foreign child', labels: [] }]);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
// ─── Board path + coherence ─────────────────────────────
|
|
184
|
+
describe('orient board + coherence', () => {
|
|
185
|
+
beforeEach(() => {
|
|
186
|
+
process.env['TOTEM_ORIENT_PROJECT'] = '1';
|
|
187
|
+
});
|
|
188
|
+
it('filters the board to active items and flags issue drift in --json', async () => {
|
|
189
|
+
mockFetchOpenIssuesWithBody.mockReturnValue([
|
|
190
|
+
{ number: 200, title: 'Open issue', body: '', labels: [] },
|
|
191
|
+
]);
|
|
192
|
+
const local = { contentRepo: 'mmnto-ai/totem', contentType: 'Issue' };
|
|
193
|
+
mockFetchBoardItems.mockReturnValue([
|
|
194
|
+
{ status: 'In Progress', title: 'Active drift', contentNumber: 100, ...local }, // not open → drift
|
|
195
|
+
{ status: 'In Review', title: 'Active ok', contentNumber: 200, ...local }, // open → ok
|
|
196
|
+
{ status: 'Done', title: 'Terminal', contentNumber: 999, ...local }, // terminal → filtered + never flagged
|
|
197
|
+
]);
|
|
198
|
+
await runJson();
|
|
199
|
+
const r = parseJson();
|
|
200
|
+
expect(r.board).toEqual([
|
|
201
|
+
{ status: 'In Progress', title: 'Active drift', contentNumber: 100 },
|
|
202
|
+
{ status: 'In Review', title: 'Active ok', contentNumber: 200 },
|
|
203
|
+
]);
|
|
204
|
+
expect(r.coherence).toEqual([
|
|
205
|
+
{
|
|
206
|
+
boardItemTitle: 'Active drift',
|
|
207
|
+
boardStatus: 'In Progress',
|
|
208
|
+
issueNumber: 100,
|
|
209
|
+
kind: 'issue-closed-or-absent',
|
|
210
|
+
},
|
|
211
|
+
]);
|
|
212
|
+
// JSON consumers can tell a configured board apart from an unconfigured one.
|
|
213
|
+
expect(r.boardConfigured).toBe(true);
|
|
214
|
+
});
|
|
215
|
+
// Regression for the #2044 controller-review bug: GH Project #1 is an org board
|
|
216
|
+
// spanning repos. A card for a (still-open) strategy issue must SHOW on the board
|
|
217
|
+
// but NEVER be flagged as drift against THIS repo's open-issue set.
|
|
218
|
+
it('shows cross-repo cards on the board but never flags them as drift', async () => {
|
|
219
|
+
mockFetchOpenIssuesWithBody.mockReturnValue([]); // this repo has no open issues
|
|
220
|
+
mockFetchBoardItems.mockReturnValue([
|
|
221
|
+
{
|
|
222
|
+
status: 'In Progress',
|
|
223
|
+
title: 'Strategy work',
|
|
224
|
+
contentNumber: 433,
|
|
225
|
+
contentRepo: 'mmnto-ai/totem-strategy', // different repo
|
|
226
|
+
contentType: 'Issue',
|
|
227
|
+
},
|
|
228
|
+
]);
|
|
229
|
+
await runJson();
|
|
230
|
+
const r = parseJson();
|
|
231
|
+
// Shown on the org board view…
|
|
232
|
+
expect(r.board).toEqual([
|
|
233
|
+
{ status: 'In Progress', title: 'Strategy work', contentNumber: 433 },
|
|
234
|
+
]);
|
|
235
|
+
// …but NOT flagged — #433 lives in another repo, not this repo's issue set.
|
|
236
|
+
expect(r.coherence).toEqual([]);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
// ─── Honest absence: no board configured ────────────────
|
|
240
|
+
describe('orient honest-absence (no board configured)', () => {
|
|
241
|
+
it('renders an honest "no board configured" line, not an error', async () => {
|
|
242
|
+
// No env, no config field → board absent (configured=false).
|
|
243
|
+
mockLoadConfig.mockResolvedValue({ orient: undefined });
|
|
244
|
+
await orientCommand({ json: false });
|
|
245
|
+
expect(stdout).toContain('no board configured (set orient.projectNumber');
|
|
246
|
+
expect(stdout).not.toContain('could not derive');
|
|
247
|
+
});
|
|
248
|
+
it('marks boardConfigured:false in --json so consumers tell it apart from an empty board', async () => {
|
|
249
|
+
// Unconfigured board and a configured-but-empty board both have `board: []`;
|
|
250
|
+
// the boolean is the only signal that disambiguates them for a JSON pipe.
|
|
251
|
+
mockLoadConfig.mockResolvedValue({ orient: undefined });
|
|
252
|
+
await runJson();
|
|
253
|
+
const r = parseJson();
|
|
254
|
+
expect(r.board).toEqual([]);
|
|
255
|
+
expect(r.boardConfigured).toBe(false);
|
|
256
|
+
});
|
|
257
|
+
it('renders "freshness unknown — not yet synced" when no registry entry matches', async () => {
|
|
258
|
+
mockReadRegistry.mockReturnValue({});
|
|
259
|
+
await orientCommand({ json: false });
|
|
260
|
+
expect(stdout).toContain('freshness unknown — not yet synced');
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
// ─── Fail loud, not silent absence: malformed board config ──
|
|
264
|
+
//
|
|
265
|
+
// A user who SET TOTEM_ORIENT_PROJECT expects a board; a non-numeric value must
|
|
266
|
+
// surface as a loud { error } (Tenet 4), NOT masquerade as "no board configured".
|
|
267
|
+
describe('orient fail-loud on invalid board config', () => {
|
|
268
|
+
it('a non-numeric TOTEM_ORIENT_PROJECT surfaces a board { error }, not honest absence', async () => {
|
|
269
|
+
process.env['TOTEM_ORIENT_PROJECT'] = 'my-project';
|
|
270
|
+
await runJson();
|
|
271
|
+
const r = parseJson();
|
|
272
|
+
expect(r.board).toHaveProperty('error', expect.stringMatching(/TOTEM_ORIENT_PROJECT/));
|
|
273
|
+
// configured:true — the user DID configure (just malformed), so it's not "no board".
|
|
274
|
+
expect(r.boardConfigured).toBe(true);
|
|
275
|
+
// Board fetch is never attempted for an invalid number (no extra gh call).
|
|
276
|
+
expect(mockFetchBoardItems).not.toHaveBeenCalled();
|
|
277
|
+
});
|
|
278
|
+
it('renders the malformed-config error loudly, not the "no board configured" line', async () => {
|
|
279
|
+
process.env['TOTEM_ORIENT_PROJECT'] = 'not-a-number';
|
|
280
|
+
await orientCommand({ json: false });
|
|
281
|
+
expect(stdout).toContain('could not derive');
|
|
282
|
+
expect(stdout).not.toContain('no board configured');
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
// ─── --json and human render share board filter + coherence ─
|
|
286
|
+
describe('orient --json and human render parity', () => {
|
|
287
|
+
beforeEach(() => {
|
|
288
|
+
process.env['TOTEM_ORIENT_PROJECT'] = '1';
|
|
289
|
+
});
|
|
290
|
+
it('both surfaces honor the same active-board filter and coherence set', async () => {
|
|
291
|
+
mockFetchOpenIssuesWithBody.mockReturnValue([]);
|
|
292
|
+
mockFetchBoardItems.mockReturnValue([
|
|
293
|
+
{
|
|
294
|
+
status: 'In Progress',
|
|
295
|
+
title: 'Drifting card',
|
|
296
|
+
contentNumber: 77,
|
|
297
|
+
contentRepo: 'mmnto-ai/totem',
|
|
298
|
+
contentType: 'Issue',
|
|
299
|
+
},
|
|
300
|
+
{ status: 'Todo', title: 'Hidden todo', contentNumber: 88 },
|
|
301
|
+
]);
|
|
302
|
+
// JSON surface
|
|
303
|
+
await runJson();
|
|
304
|
+
const r = parseJson();
|
|
305
|
+
expect(r.board).toHaveLength(1);
|
|
306
|
+
expect(r.board).toEqual([{ status: 'In Progress', title: 'Drifting card', contentNumber: 77 }]);
|
|
307
|
+
expect(r.coherence).toHaveLength(1);
|
|
308
|
+
// Human surface, rendered from the SAME report
|
|
309
|
+
const human = renderReport(r);
|
|
310
|
+
expect(human).toContain('Drifting card');
|
|
311
|
+
expect(human).not.toContain('Hidden todo'); // Todo filtered out of the active board
|
|
312
|
+
expect(human).toContain('issue #77 is closed/absent'); // same coherence flag
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
// ─── Footer + embedder tripwire ─────────────────────────
|
|
316
|
+
describe('orient footer and #2018 structural guard', () => {
|
|
317
|
+
it('always emits the snapshot-not-source + perceptual-carve-out footer', async () => {
|
|
318
|
+
await orientCommand({ json: false });
|
|
319
|
+
expect(stdout).toContain('this output is a');
|
|
320
|
+
expect(stdout).toContain('snapshot/cache, not a source');
|
|
321
|
+
expect(stdout).toContain('Deeper judgment is perceptual');
|
|
322
|
+
expect(stdout).toContain('ask the human');
|
|
323
|
+
});
|
|
324
|
+
it('never reaches the embedder (runs green with @google/genai absent)', async () => {
|
|
325
|
+
await orientCommand({ json: false });
|
|
326
|
+
expect(embedderTripwire).not.toHaveBeenCalled();
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
// ─── PR-2: programmatic entry + session-start projection (mmnto-ai/totem#2044) ──
|
|
330
|
+
describe('deriveOrientReport — one derivation, two callers (cannot diverge)', () => {
|
|
331
|
+
it('returns the SAME report `orient --json` serializes (modulo the derivedAt stamp)', async () => {
|
|
332
|
+
// A small but non-empty world so the comparison is meaningful.
|
|
333
|
+
mockFetchOpenPRs.mockReturnValue([
|
|
334
|
+
{ number: 42, title: 'do thing', headRefName: 'feat/x', isDraft: false },
|
|
335
|
+
]);
|
|
336
|
+
mockFetchOpenIssuesWithBody.mockReturnValue([
|
|
337
|
+
{ number: 7, title: 'Other Seven', body: '', labels: [] },
|
|
338
|
+
]);
|
|
339
|
+
await runJson();
|
|
340
|
+
const fromCommand = parseJson();
|
|
341
|
+
const fromApi = await deriveOrientReport(repoRoot);
|
|
342
|
+
// derivedAt is a wall-clock stamp set per call — the only field allowed to differ.
|
|
343
|
+
const { derivedAt: _a, ...cmdRest } = fromCommand;
|
|
344
|
+
const { derivedAt: _b, ...apiRest } = fromApi;
|
|
345
|
+
expect(apiRest).toEqual(cmdRest);
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
describe('renderOrientForSession — bounded Tier-A projection', () => {
|
|
349
|
+
function makeReport(overrides = {}) {
|
|
350
|
+
return {
|
|
351
|
+
repo: 'mmnto-ai/totem',
|
|
352
|
+
derivedAt: '2026-06-01T00:00:00.000Z',
|
|
353
|
+
indexFreshness: { synced: false },
|
|
354
|
+
parked: [],
|
|
355
|
+
openPRs: [],
|
|
356
|
+
board: [],
|
|
357
|
+
coherence: [],
|
|
358
|
+
epics: [],
|
|
359
|
+
otherOpenIssues: [],
|
|
360
|
+
boardConfigured: false,
|
|
361
|
+
...overrides,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
it('surfaces high-value signals (parked, open PR, coherence drift) + a counts pointer', () => {
|
|
365
|
+
const block = renderOrientForSession(makeReport({
|
|
366
|
+
parked: [{ subsystem: 'embedder', since: '2026-01-01' }],
|
|
367
|
+
openPRs: [{ number: 42, title: 'do thing', headRefName: 'feat/x', isDraft: false }],
|
|
368
|
+
coherence: [
|
|
369
|
+
{
|
|
370
|
+
boardItemTitle: 'Stale card',
|
|
371
|
+
boardStatus: 'In Progress',
|
|
372
|
+
issueNumber: 99,
|
|
373
|
+
kind: 'issue-closed-or-absent',
|
|
374
|
+
},
|
|
375
|
+
],
|
|
376
|
+
epics: [{ number: 1, title: 'Epic One', labels: ['type: epic'], subIssues: [] }],
|
|
377
|
+
otherOpenIssues: [{ number: 7, title: 'Other Seven', labels: [] }],
|
|
378
|
+
}));
|
|
379
|
+
expect(block).toContain('embedder'); // parked subsystem
|
|
380
|
+
expect(block).toContain('#42'); // open PR
|
|
381
|
+
expect(block).toContain('do thing');
|
|
382
|
+
expect(block).toContain('#99'); // coherence drift
|
|
383
|
+
expect(block).toContain('1 epic · 1 other open issue'); // counts pointer
|
|
384
|
+
expect(block).toContain('run `totem orient`');
|
|
385
|
+
});
|
|
386
|
+
it('NEVER enumerates epics / children / other issues (the #467 Tier-A-lean guard)', () => {
|
|
387
|
+
const block = renderOrientForSession(makeReport({
|
|
388
|
+
epics: [
|
|
389
|
+
{
|
|
390
|
+
number: 1,
|
|
391
|
+
title: 'Epic One',
|
|
392
|
+
labels: ['type: epic'],
|
|
393
|
+
subIssues: [{ number: 2, title: 'Child Two' }],
|
|
394
|
+
},
|
|
395
|
+
],
|
|
396
|
+
otherOpenIssues: [{ number: 7, title: 'Other Seven', labels: [] }],
|
|
397
|
+
}));
|
|
398
|
+
// Counts only — the titles must not appear (pointers not bodies).
|
|
399
|
+
expect(block).toContain('1 epic · 1 other open issue');
|
|
400
|
+
expect(block).not.toContain('Epic One');
|
|
401
|
+
expect(block).not.toContain('Child Two');
|
|
402
|
+
expect(block).not.toContain('Other Seven');
|
|
403
|
+
});
|
|
404
|
+
it('an {error} section renders a fail-loud `⚠ could not derive` line, never a silent omit', () => {
|
|
405
|
+
const parkedErr = renderOrientForSession(makeReport({ parked: { error: 'freeze.json unreadable' } }));
|
|
406
|
+
expect(parkedErr).toContain('⚠ could not derive');
|
|
407
|
+
expect(parkedErr).toContain('freeze.json unreadable');
|
|
408
|
+
// epics + otherOpenIssues share deriveIssues → one issues error line.
|
|
409
|
+
const issuesErr = renderOrientForSession(makeReport({
|
|
410
|
+
epics: { error: 'gh issue list exploded' },
|
|
411
|
+
otherOpenIssues: { error: 'gh issue list exploded' },
|
|
412
|
+
}));
|
|
413
|
+
expect(issuesErr).toContain('issues: ⚠ could not derive: gh issue list exploded');
|
|
414
|
+
});
|
|
415
|
+
it('surfaces an otherOpenIssues error that splits independently from epics (Tenet 4 type-gap)', () => {
|
|
416
|
+
// toReport couples these today, but the type permits the split — a derived
|
|
417
|
+
// `epics` with an errored `otherOpenIssues` must still fail loud, not coerce
|
|
418
|
+
// the count to 0 silently.
|
|
419
|
+
const block = renderOrientForSession(makeReport({
|
|
420
|
+
epics: [{ number: 1, title: 'Epic One', labels: ['type: epic'], subIssues: [] }],
|
|
421
|
+
otherOpenIssues: { error: 'gh issue list (others) exploded' },
|
|
422
|
+
}));
|
|
423
|
+
expect(block).toContain('other open issues: ⚠ could not derive: gh issue list (others) exploded');
|
|
424
|
+
expect(block).toContain('1 epic'); // epics still surface
|
|
425
|
+
});
|
|
426
|
+
it('returns "" when there is nothing high-signal (so the hook omits the block)', () => {
|
|
427
|
+
expect(renderOrientForSession(makeReport())).toBe('');
|
|
428
|
+
// A zero count must NOT emit a "0 epics" pointer line.
|
|
429
|
+
expect(renderOrientForSession(makeReport({ epics: [], otherOpenIssues: [] }))).toBe('');
|
|
430
|
+
});
|
|
431
|
+
it('is HARD-BOUNDED — long content cannot blow past the char cap (net-neutral-truncation guardrail)', () => {
|
|
432
|
+
// Within the per-section item cap (10) but with long titles, so the CHAR
|
|
433
|
+
// ceiling — not the item cap — is what bounds the block.
|
|
434
|
+
const longTitle = 'x'.repeat(300);
|
|
435
|
+
const prs = Array.from({ length: 10 }, (_, i) => ({
|
|
436
|
+
number: i,
|
|
437
|
+
title: longTitle,
|
|
438
|
+
headRefName: `feat/branch-${i}`,
|
|
439
|
+
isDraft: false,
|
|
440
|
+
}));
|
|
441
|
+
const block = renderOrientForSession(makeReport({ openPRs: prs }));
|
|
442
|
+
// Bounded: ≤ SESSION_BLOCK_MAX_CHARS (1500) plus the short truncation marker.
|
|
443
|
+
expect(block.length).toBeLessThanOrEqual(1500 + 32);
|
|
444
|
+
expect(block).toContain('…(orient block truncated)');
|
|
445
|
+
});
|
|
446
|
+
it('caps per-section item counts with a "… and N more" overflow line', () => {
|
|
447
|
+
const flood = Array.from({ length: 25 }, (_, i) => ({
|
|
448
|
+
number: i,
|
|
449
|
+
title: `t${i}`,
|
|
450
|
+
headRefName: `b${i}`,
|
|
451
|
+
isDraft: false,
|
|
452
|
+
}));
|
|
453
|
+
const block = renderOrientForSession(makeReport({ openPRs: flood }));
|
|
454
|
+
expect(block).toContain('more open PRs');
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
//# sourceMappingURL=orient.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orient.test.js","sourceRoot":"","sources":["../../src/commands/orient.test.ts"],"names":[],"mappings":"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"}
|
package/dist/help.js
CHANGED
|
@@ -26,7 +26,7 @@ export const COMMAND_GROUPS = [
|
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
name: 'Setup',
|
|
29
|
-
commands: ['init', 'sync', 'hooks', 'doctor', 'status', 'eject'],
|
|
29
|
+
commands: ['init', 'sync', 'hooks', 'doctor', 'status', 'orient', 'eject'],
|
|
30
30
|
},
|
|
31
31
|
];
|
|
32
32
|
export class TotemHelp extends Help {
|
package/dist/help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,IAAI,EAAE,MAAM,WAAW,CAAC;AAO1C,gDAAgD;AAChD,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAClC,QAAQ;IACR,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,cAAc;IACd,QAAQ;IACR,WAAW;CACZ,CAAC,CAAC;AAEH,qCAAqC;AACrC,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD;QACE,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC;KAC9C;IACD;QACE,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC;KACpD;IACD;QACE,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,CAAC;KAC1D;IACD;QACE,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -402,6 +402,22 @@ program
|
|
|
402
402
|
handleError(err);
|
|
403
403
|
}
|
|
404
404
|
});
|
|
405
|
+
program
|
|
406
|
+
.command('orient')
|
|
407
|
+
.description('Derive session orientation from primitives (open PRs/issues/board/freeze) — zero LLM')
|
|
408
|
+
.option('--json', 'Output the OrientReport as structured JSON')
|
|
409
|
+
.action(async (opts) => {
|
|
410
|
+
requireGhCli();
|
|
411
|
+
try {
|
|
412
|
+
const { orientCommand } = await import('./commands/orient.js');
|
|
413
|
+
await orientCommand(opts);
|
|
414
|
+
}
|
|
415
|
+
catch (err) {
|
|
416
|
+
handleError(err);
|
|
417
|
+
// totem-context: handleError returns `never` (process.exit), so the throw is unreachable but required to satisfy the Tenet 4 fail-loud rule that bans bare-catch silent-degrade. Mirrors the mail/verify-badges pattern.
|
|
418
|
+
throw err;
|
|
419
|
+
}
|
|
420
|
+
});
|
|
405
421
|
program
|
|
406
422
|
.command('handoff')
|
|
407
423
|
.description('Scaffold a structured journal entry for end-of-session handoff')
|