@mmnto/cli 2.4.0 → 2.6.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/dist/commands/agents-floor-sterility.test.d.ts +25 -0
- package/dist/commands/agents-floor-sterility.test.d.ts.map +1 -0
- package/dist/commands/agents-floor-sterility.test.js +217 -0
- package/dist/commands/agents-floor-sterility.test.js.map +1 -0
- package/dist/commands/config-drift.test.js +5 -3
- package/dist/commands/config-drift.test.js.map +1 -1
- package/dist/commands/eject.d.ts +20 -0
- package/dist/commands/eject.d.ts.map +1 -1
- package/dist/commands/eject.js +131 -0
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/eject.test.js +280 -2
- package/dist/commands/eject.test.js.map +1 -1
- package/dist/commands/init-templates.d.ts +74 -2
- package/dist/commands/init-templates.d.ts.map +1 -1
- package/dist/commands/init-templates.js +298 -6
- package/dist/commands/init-templates.js.map +1 -1
- package/dist/commands/init.d.ts +36 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +172 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/init.test.js +380 -3
- package/dist/commands/init.test.js.map +1 -1
- package/dist/commands/signoff-table-sync.test.d.ts +2 -0
- package/dist/commands/signoff-table-sync.test.d.ts.map +1 -0
- package/dist/commands/signoff-table-sync.test.js +126 -0
- package/dist/commands/signoff-table-sync.test.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signoff-table-sync.test.d.ts","sourceRoot":"","sources":["../../src/commands/signoff-table-sync.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The signoff skill's step-2a cohort table and core's `COHORT_AGENT_MAP` are
|
|
3
|
+
* two copies of one bootstrap fallback (Proposal 282 § Scope item 3), and each
|
|
4
|
+
* says it is kept in sync with the other. Nothing held them to it: the three
|
|
5
|
+
* Kimi seats read "not seated" in the table for weeks after they were seated
|
|
6
|
+
* (mmnto-ai/totem#2865). This lock holds the two RENDERINGS in this repository
|
|
7
|
+
* to each other so a seat added to one copy alone fails here rather than in a
|
|
8
|
+
* poll — and holds the ASSOCIATIONS, not just the id sets: a seat in the wrong
|
|
9
|
+
* repository row or the wrong vendor column fails too (the Greptile P2 on the
|
|
10
|
+
* first cut: a flat set comparison let a mis-filed seat through green).
|
|
11
|
+
*
|
|
12
|
+
* TODAY the table LEADS the map by exactly the four Kimi seats the roster of
|
|
13
|
+
* record seats (`doctrine/cohort-roles.md` § 1.1 in the strategy repository,
|
|
14
|
+
* which this test cannot read and does not claim to): the map's Kimi
|
|
15
|
+
* propagation moves the mail-accounting fixtures and is its own change,
|
|
16
|
+
* mmnto-ai/totem#2875. When the map gains them, `tableOnly` below becomes
|
|
17
|
+
* empty and the pinned `KIMI_SEATS` assertion goes RED on purpose — the
|
|
18
|
+
* tripwire that issue's second ask names: a human then empties `KIMI_SEATS`
|
|
19
|
+
* and the lock becomes an equality. Nothing tightens by itself.
|
|
20
|
+
*/
|
|
21
|
+
import { describe, expect, it } from 'vitest';
|
|
22
|
+
import { knownCohortAgents } from '@mmnto/totem';
|
|
23
|
+
import { SIGNOFF_SKILL_CONTENT } from './init-templates.js';
|
|
24
|
+
/**
|
|
25
|
+
* The repo → seat-id shorthand of § 1.2 of the roster (`<shorthand>-<vendor>`),
|
|
26
|
+
* which is how a flat id set is grouped back into repositories. `totem` must
|
|
27
|
+
* be matched as a whole shorthand, never as a prefix of `totem-strategy`'s
|
|
28
|
+
* seats — the grouping below splits on the LAST hyphen.
|
|
29
|
+
*/
|
|
30
|
+
const SHORTHAND = {
|
|
31
|
+
totem: 'totem',
|
|
32
|
+
'totem-strategy': 'strategy',
|
|
33
|
+
'liquid-city': 'lc',
|
|
34
|
+
arhgap11: 'arhgap11',
|
|
35
|
+
'totem-status': 'status',
|
|
36
|
+
'totem-playground': 'playground',
|
|
37
|
+
};
|
|
38
|
+
/** The vendor each column of the table renders, in column order. */
|
|
39
|
+
const COLUMNS = ['claude', 'gemini', 'kimi'];
|
|
40
|
+
/** The table rows of step 2a: `| \`repo\` | cell | cell | cell |`, one per repo. */
|
|
41
|
+
function tableRows() {
|
|
42
|
+
const rows = [];
|
|
43
|
+
for (const line of SIGNOFF_SKILL_CONTENT.split('\n')) {
|
|
44
|
+
const match = /^\s*\|\s*`([^`]+)`\s*\|(.*)\|\s*$/.exec(line);
|
|
45
|
+
if (match === null)
|
|
46
|
+
continue;
|
|
47
|
+
// The header row's first cell is a prose label with a code span in it,
|
|
48
|
+
// not a bare repo name; the data rows carry exactly the repo name.
|
|
49
|
+
if (match[1].includes(' '))
|
|
50
|
+
continue;
|
|
51
|
+
rows.push({
|
|
52
|
+
repo: match[1],
|
|
53
|
+
cells: match[2].split('|').map((c) => c.trim()),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return rows;
|
|
57
|
+
}
|
|
58
|
+
/** A cell that names a seat is a code span; an italic cell is "no seat here". */
|
|
59
|
+
function seatOf(cell) {
|
|
60
|
+
const match = /^`([^`]+)`$/.exec(cell);
|
|
61
|
+
return match === null ? null : match[1];
|
|
62
|
+
}
|
|
63
|
+
/** `<shorthand>-<vendor>` split on the LAST hyphen. */
|
|
64
|
+
function splitSeat(seat) {
|
|
65
|
+
const at = seat.lastIndexOf('-');
|
|
66
|
+
return { shorthand: seat.slice(0, at), vendor: seat.slice(at + 1) };
|
|
67
|
+
}
|
|
68
|
+
const KIMI_SEATS = ['lc-kimi', 'status-kimi', 'strategy-kimi', 'totem-kimi'];
|
|
69
|
+
describe('signoff step 2a table ↔ COHORT_AGENT_MAP (mmnto-ai/totem#2865)', () => {
|
|
70
|
+
const rows = tableRows();
|
|
71
|
+
it('parses the table: one row per cohort repo, three vendor cells each', () => {
|
|
72
|
+
expect(rows.map((r) => r.repo)).toEqual(Object.keys(SHORTHAND));
|
|
73
|
+
for (const row of rows) {
|
|
74
|
+
expect(row.cells, row.repo).toHaveLength(3);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
it('every seat sits in ITS repository row and ITS vendor column', () => {
|
|
78
|
+
// A seat filed under the wrong repo or the wrong column keeps a flat set
|
|
79
|
+
// unchanged; the association is what a session reads off the table.
|
|
80
|
+
for (const row of rows) {
|
|
81
|
+
row.cells.forEach((cell, column) => {
|
|
82
|
+
const seat = seatOf(cell);
|
|
83
|
+
if (seat === null)
|
|
84
|
+
return;
|
|
85
|
+
const { shorthand, vendor } = splitSeat(seat);
|
|
86
|
+
expect(shorthand, `${row.repo} column ${COLUMNS[column]}: ${seat}`).toBe(SHORTHAND[row.repo]);
|
|
87
|
+
expect(vendor, `${row.repo} column ${COLUMNS[column]}: ${seat}`).toBe(COLUMNS[column]);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
it('per repository, the map seats ⊆ the row, and the row leads the map by exactly its Kimi seat', () => {
|
|
92
|
+
// `knownCohortAgents()` with no workspace is exactly the map's union — no
|
|
93
|
+
// seat dir on this machine can widen it — grouped back by shorthand.
|
|
94
|
+
const mapByRepo = new Map();
|
|
95
|
+
for (const seat of knownCohortAgents()) {
|
|
96
|
+
const { shorthand } = splitSeat(seat);
|
|
97
|
+
const repo = Object.entries(SHORTHAND).find(([, s]) => s === shorthand)?.[0];
|
|
98
|
+
expect(repo, `map seat with no table row: ${seat}`).toBeDefined();
|
|
99
|
+
if (!mapByRepo.has(repo))
|
|
100
|
+
mapByRepo.set(repo, new Set());
|
|
101
|
+
mapByRepo.get(repo).add(seat);
|
|
102
|
+
}
|
|
103
|
+
const tableOnly = [];
|
|
104
|
+
for (const row of rows) {
|
|
105
|
+
const inRow = new Set(row.cells.map(seatOf).filter((s) => s !== null));
|
|
106
|
+
const inMap = mapByRepo.get(row.repo) ?? new Set();
|
|
107
|
+
const mapOnly = [...inMap].filter((s) => !inRow.has(s));
|
|
108
|
+
expect(mapOnly, `${row.repo}: map seats the row does not carry`).toEqual([]);
|
|
109
|
+
tableOnly.push(...[...inRow].filter((s) => !inMap.has(s)));
|
|
110
|
+
}
|
|
111
|
+
// The one-directional gap, named: closes to [] when the map's Kimi
|
|
112
|
+
// propagation lands (mmnto-ai/totem#2875), at which point a human empties
|
|
113
|
+
// KIMI_SEATS and this becomes an equality lock.
|
|
114
|
+
expect(tableOnly.sort(), 'seats the table names that the map does not').toEqual(KIMI_SEATS);
|
|
115
|
+
});
|
|
116
|
+
it('the Kimi column names the four seats the roster of record seats (2026-07-18 and 2026-07-29)', () => {
|
|
117
|
+
const kimi = Object.fromEntries(rows.map((r) => [r.repo, seatOf(r.cells[2])]));
|
|
118
|
+
expect(kimi).toMatchObject({
|
|
119
|
+
totem: 'totem-kimi',
|
|
120
|
+
'totem-strategy': 'strategy-kimi',
|
|
121
|
+
'liquid-city': 'lc-kimi',
|
|
122
|
+
'totem-status': 'status-kimi',
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
//# sourceMappingURL=signoff-table-sync.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signoff-table-sync.test.js","sourceRoot":"","sources":["../../src/commands/signoff-table-sync.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmnto/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Totem: local-first toolkit that keeps AI-agent work queryable, enforceable, and derivable as plain files in your codebase",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"smol-toml": "^1.6.1",
|
|
29
29
|
"yaml": "^2.4.0",
|
|
30
30
|
"zod": "^3.24.0",
|
|
31
|
-
"@mmnto/totem": "2.
|
|
31
|
+
"@mmnto/totem": "2.6.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@anthropic-ai/sdk": "^0.98.0",
|