@roomi-fields/grillhouse 0.23.1 → 0.24.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/.claude-plugin/plugin.json +1 -1
- package/METACADRE.md +1 -1
- package/agents/explorateur.md +4 -2
- package/agents/questionneur.md +1 -1
- package/bin/grillhouse.mjs +3 -58
- package/cadre/templates/projet/CLAUDE.md +5 -1
- package/cadre/templates/projet/docs/agents/issue-tracker.md +4 -4
- package/charte.md +23 -6
- package/docs/ARCHITECTURE.md +127 -1
- package/hooks/register.tsx +3 -13
- package/package.json +13 -1
- package/scripts/bilan.mjs +134 -88
- package/scripts/circuit.mjs +1547 -2248
- package/scripts/composants-affectes.mjs +27 -108
- package/scripts/consommateurs-arbitres.mjs +15 -21
- package/scripts/consommateurs.d.ts +8 -0
- package/scripts/consommateurs.mjs +5 -1
- package/scripts/dette.d.ts +23 -0
- package/scripts/dette.mjs +76 -13
- package/scripts/droits.mjs +38 -44
- package/scripts/elements-du-lot.mjs +246 -0
- package/scripts/enveloppe/enveloppe.mjs +105 -232
- package/scripts/enveloppe/lancer.sh +79 -49
- package/scripts/enveloppe/paquets-du-plan.mjs +49 -0
- package/scripts/etapes.mjs +148 -213
- package/scripts/gardes-du-cadre.mjs +8 -6
- package/scripts/grillhouse-maj.mjs +31 -9
- package/scripts/index-interfaces.mjs +21 -1
- package/scripts/integration/integrer.mjs +2 -2
- package/scripts/interfaces-contre-code.mjs +25 -17
- package/scripts/migrations/0.23.0-config-vitest.mjs +26 -23
- package/scripts/migrations/0.23.2-copies-du-cadre.mjs +201 -0
- package/scripts/migrations/0.24.0-circuit-simplifie.mjs +231 -0
- package/scripts/migrations.mjs +41 -6
- package/scripts/paquets.d.ts +5 -0
- package/scripts/paquets.mjs +3 -0
- package/scripts/references-par-les-types.mjs +55 -36
- package/scripts/registre.mjs +7 -15
- package/scripts/resultats.mjs +283 -142
- package/scripts/resumes.mjs +1 -1
- package/scripts/session-start.sh +1 -2
- package/scripts/sources.mjs +28 -0
- package/scripts/sous-commandes.mjs +62 -0
- package/scripts/tableau.mjs +85 -191
- package/scripts/tests.mjs +19 -17
- package/scripts/verifier.mjs +5 -4
- package/scripts/verrou-de-machine.mjs +131 -24
- package/scripts/verrous/verrou.mjs +66 -5
- package/skills/developpeur/SKILL.md +60 -50
- package/skills/explorateur/SKILL.md +90 -64
- package/skills/grill/SKILL.md +1 -1
- package/skills/mesure/SKILL.md +2 -1
- package/skills/pitmaster/SKILL.md +132 -118
- package/skills/pitmaster/references/consigne-agent.md +54 -148
- package/skills/questionneur/SKILL.md +18 -18
- package/skills/relecteur/SKILL.md +69 -23
- package/skills/testwriter/SKILL.md +46 -35
- package/types/index.d.ts +1 -3
- package/agents/referent-technique.md +0 -9
- package/agents/regulateur.md +0 -11
- package/scripts/enveloppe/composant.mjs +0 -11
- package/scripts/etat-du-circuit.mjs +0 -104
- package/skills/referent-technique/SKILL.md +0 -145
- package/skills/regulateur/SKILL.md +0 -220
package/scripts/migrations.mjs
CHANGED
|
@@ -4,21 +4,37 @@
|
|
|
4
4
|
//
|
|
5
5
|
// - A migration exports `version` (the version of the package that brings the change of form),
|
|
6
6
|
// `nom` and `migrer(projet)`, which brings the project at <projet> to the new form and returns
|
|
7
|
-
// the lines of what it changed: none when the project already has it.
|
|
8
|
-
//
|
|
7
|
+
// the lines of what it changed: none when the project already has it. A line `{ aFaire }` is
|
|
8
|
+
// what it leaves to the project (a copy of the frame the project modified), which the update
|
|
9
|
+
// writes on its error stream, its exit code non-zero, as `@turbo/codemod` fails on a file it
|
|
10
|
+
// could not transform. It is replayable without effect: a second pass changes no byte and
|
|
11
|
+
// returns no line.
|
|
9
12
|
// - MIGRATIONS lists them, each imported by its module; the update plays those newer than the
|
|
10
13
|
// version the project recorded (`grillhouse.version` of its package.json), in the order of their
|
|
11
14
|
// versions; a project that recorded none plays them all. The package carries no migration newer
|
|
12
15
|
// than itself once released, so the range ends with the package.
|
|
16
|
+
// - A migration may also export `restes(projet)`: the lines of what stays to the project once the
|
|
17
|
+
// update is done, which the update plays after its own update and its regeneration, for each
|
|
18
|
+
// migration it played, and reports (« reste au projet ») without holding back the version, as a
|
|
19
|
+
// codemod reports what it leaves without failing (restesAuProjet).
|
|
13
20
|
// - Each migration has its test, tests/unit/migration.<nom>.spec.ts.
|
|
14
21
|
import semver from 'semver';
|
|
15
22
|
import * as charteImportee from './migrations/0.23.0-charte-importee.mjs';
|
|
16
23
|
import * as configVitest from './migrations/0.23.0-config-vitest.mjs';
|
|
17
24
|
import * as crochetsDeSeance from './migrations/0.23.0-crochets-de-seance.mjs';
|
|
18
25
|
import * as marcheDuProjet from './migrations/0.23.0-marche-du-projet.mjs';
|
|
26
|
+
import * as copiesDuCadre from './migrations/0.23.2-copies-du-cadre.mjs';
|
|
27
|
+
import * as circuitSimplifie from './migrations/0.24.0-circuit-simplifie.mjs';
|
|
19
28
|
|
|
20
29
|
/** The migrations of the package. */
|
|
21
|
-
export const MIGRATIONS = [
|
|
30
|
+
export const MIGRATIONS = [
|
|
31
|
+
crochetsDeSeance,
|
|
32
|
+
configVitest,
|
|
33
|
+
marcheDuProjet,
|
|
34
|
+
charteImportee,
|
|
35
|
+
copiesDuCadre,
|
|
36
|
+
circuitSimplifie,
|
|
37
|
+
];
|
|
22
38
|
|
|
23
39
|
/**
|
|
24
40
|
* The migrations of <liste> newer than <depuis> (all of them when it is null), in the order of
|
|
@@ -32,12 +48,31 @@ export function migrationsAJouer(depuis, liste = MIGRATIONS) {
|
|
|
32
48
|
.map(({ m }) => m);
|
|
33
49
|
}
|
|
34
50
|
|
|
51
|
+
/**
|
|
52
|
+
* What stays to the project at <projet> after the update, for each migration newer than <depuis>
|
|
53
|
+
* that exports `restes` and names something: `{ version, nom, lignes }`.
|
|
54
|
+
*/
|
|
55
|
+
export function restesAuProjet(projet, depuis, liste = MIGRATIONS) {
|
|
56
|
+
return migrationsAJouer(depuis, liste)
|
|
57
|
+
.filter(m => typeof m.restes === 'function')
|
|
58
|
+
.map(m => ({ version: m.version, nom: m.nom, lignes: m.restes(projet) }))
|
|
59
|
+
.filter(r => r.lignes.length > 0);
|
|
60
|
+
}
|
|
61
|
+
|
|
35
62
|
/**
|
|
36
63
|
* Plays on the project at <projet> each migration newer than <depuis>; returns, for each one that
|
|
37
|
-
* changed something, `{ version, nom, lignes }`.
|
|
64
|
+
* changed something or left something to do, `{ version, nom, lignes, aFaire }`.
|
|
38
65
|
*/
|
|
39
66
|
export function migrer(projet, depuis, liste = MIGRATIONS) {
|
|
40
67
|
return migrationsAJouer(depuis, liste)
|
|
41
|
-
.map(m =>
|
|
42
|
-
|
|
68
|
+
.map(m => {
|
|
69
|
+
const tout = m.migrer(projet);
|
|
70
|
+
return {
|
|
71
|
+
version: m.version,
|
|
72
|
+
nom: m.nom,
|
|
73
|
+
lignes: tout.filter(l => typeof l === 'string'),
|
|
74
|
+
aFaire: tout.filter(l => typeof l !== 'string').map(l => l.aFaire),
|
|
75
|
+
};
|
|
76
|
+
})
|
|
77
|
+
.filter(r => r.lignes.length > 0 || r.aFaire.length > 0);
|
|
43
78
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// The types of ./paquets.mjs as the entry `@roomi-fields/grillhouse/paquets` publishes it, for a
|
|
2
|
+
// project's guard that leaves out the packages out of the frame.
|
|
3
|
+
|
|
4
|
+
/** The names listed in `racine`'s `docs/agents/hors-cadre.txt`: empty without the file. */
|
|
5
|
+
export function horsCadre(racine: string): Set<string>;
|
package/scripts/paquets.mjs
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
//
|
|
13
13
|
// This module and the ones it imports use Node alone: the update runs them from a source checkout
|
|
14
14
|
// of the frame that installs no dependency.
|
|
15
|
+
//
|
|
16
|
+
// A project's guard imports `horsCadre` by the package's entry `@roomi-fields/grillhouse/paquets`,
|
|
17
|
+
// its types in ./paquets.d.ts (docs/ARCHITECTURE.md, the package's named entries).
|
|
15
18
|
import { existsSync, globSync, readFileSync } from 'node:fs';
|
|
16
19
|
import path from 'node:path';
|
|
17
20
|
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
// repository's code (a declaration of a package, a member of a type, a function internal to a
|
|
4
4
|
// package), and its references are those the language service resolves to that symbol, never a
|
|
5
5
|
// text that happens to bear its name. scripts/composants-affectes.mjs runs it beside its survey
|
|
6
|
-
// by the names.
|
|
6
|
+
// by the names; scripts/elements-du-lot.mjs reads the declarations and the exports of a lot
|
|
7
|
+
// through the same service (`leService`).
|
|
7
8
|
//
|
|
8
9
|
// - The code read is the files of each component's `tsconfig.json` (its `include`), in one
|
|
9
10
|
// language service, so that a reference crosses packages. A workspace package's import resolves
|
|
@@ -100,14 +101,15 @@ function entreeDe(c, sous = '.') {
|
|
|
100
101
|
);
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
// Whether the file <f> (absolute) of the component <c> is a test: a test's name, or a test folder.
|
|
105
|
+
export const estTest = (c, f) =>
|
|
104
106
|
NOM_DE_TEST.test(path.basename(f)) ||
|
|
105
107
|
path
|
|
106
108
|
.relative(c.dir, f)
|
|
107
109
|
.split(path.sep)
|
|
108
110
|
.some(d => DOSSIERS_DE_TEST.has(d));
|
|
109
111
|
|
|
110
|
-
// The language service over the components <tous> of <racine>: {
|
|
112
|
+
// The language service over the components <tous> of <racine>: { ls, programme, composantDe }
|
|
111
113
|
// or { raison } when it cannot run.
|
|
112
114
|
function service(ts, racine, tous) {
|
|
113
115
|
const hote = { ...ts.sys, onUnRecoverableConfigFileDiagnostic: () => {} };
|
|
@@ -209,6 +211,51 @@ function service(ts, racine, tous) {
|
|
|
209
211
|
return { ls, programme, composantDe };
|
|
210
212
|
}
|
|
211
213
|
|
|
214
|
+
// The language service over the components <tous> of <racine>, and what it says of their
|
|
215
|
+
// declarations: `{ ts, ls, programme, checker, composantDe, sources, entree, publie }`, `sources`
|
|
216
|
+
// the production sources it reads (each `{ sf, c }`, the tests and the declaration files left
|
|
217
|
+
// out), `entree(c)` the source of the entry of the component <c> (or null), `publie(c, noeud)`
|
|
218
|
+
// whether that entry exports the symbol whose name is the node <noeud>; or `{ raison }` when it
|
|
219
|
+
// cannot run. scripts/elements-du-lot.mjs reads it.
|
|
220
|
+
export function leService(racine, tous) {
|
|
221
|
+
const ts = requis('typescript');
|
|
222
|
+
const s = service(ts, racine, tous);
|
|
223
|
+
if (s.raison) {
|
|
224
|
+
return s;
|
|
225
|
+
}
|
|
226
|
+
const { programme, composantDe } = s;
|
|
227
|
+
const checker = programme.getTypeChecker();
|
|
228
|
+
const sources = programme.getSourceFiles().flatMap(sf => {
|
|
229
|
+
const c = composantDe(sf.fileName);
|
|
230
|
+
return !c || estTest(c, sf.fileName) || DECLARATION.test(sf.fileName) ? [] : [{ sf, c }];
|
|
231
|
+
});
|
|
232
|
+
const exportes = new Map();
|
|
233
|
+
const reel = sym => {
|
|
234
|
+
let x = sym;
|
|
235
|
+
if (x && x.flags & ts.SymbolFlags.Alias) {
|
|
236
|
+
x = checker.getAliasedSymbol(x);
|
|
237
|
+
}
|
|
238
|
+
return x ? checker.getExportSymbolOfSymbol(x) : x;
|
|
239
|
+
};
|
|
240
|
+
const exportsDe = c => {
|
|
241
|
+
if (!exportes.has(c)) {
|
|
242
|
+
const f = entreeDe(c);
|
|
243
|
+
const sf = f ? programme.getSourceFile(f) : undefined;
|
|
244
|
+
const mod = sf ? checker.getSymbolAtLocation(sf) : undefined;
|
|
245
|
+
exportes.set(
|
|
246
|
+
c,
|
|
247
|
+
mod ? checker.getExportsOfModule(mod).map(x => ({ nom: x.name, sym: reel(x) })) : []
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
return exportes.get(c);
|
|
251
|
+
};
|
|
252
|
+
const publie = (c, noeud) => {
|
|
253
|
+
const sym = reel(checker.getSymbolAtLocation(noeud));
|
|
254
|
+
return Boolean(sym) && exportsDe(c).some(x => x.sym === sym);
|
|
255
|
+
};
|
|
256
|
+
return { ts, ...s, checker, sources, entree: c => entreeDe(c), publie };
|
|
257
|
+
}
|
|
258
|
+
|
|
212
259
|
// The survey by the types of the elements <ecrits> (`elementsEcrits`) in the components <tous> of
|
|
213
260
|
// <racine>, an element that resolves to several declarations kept to those of the files and the
|
|
214
261
|
// components the ticket names (<contexte>: `{ fichiers, composants }`, Sets of file names and of
|
|
@@ -224,13 +271,11 @@ export function parLesTypes(racine, tous, ecrits, contexte = {}) {
|
|
|
224
271
|
}
|
|
225
272
|
|
|
226
273
|
function releveParLesTypes(racine, tous, ecrits, { fichiers = new Set(), composants = new Set() }) {
|
|
227
|
-
const
|
|
228
|
-
const s = service(ts, racine, tous);
|
|
274
|
+
const s = leService(racine, tous);
|
|
229
275
|
if (s.raison) {
|
|
230
276
|
return { etat: 'impossible', raison: s.raison, elements: [] };
|
|
231
277
|
}
|
|
232
|
-
const { ls, programme, composantDe } = s;
|
|
233
|
-
const checker = programme.getTypeChecker();
|
|
278
|
+
const { ts, ls, programme, composantDe } = s;
|
|
234
279
|
|
|
235
280
|
// The declarations of the components' sources, at their top and as members of their types.
|
|
236
281
|
const hauts = [];
|
|
@@ -244,11 +289,7 @@ function releveParLesTypes(racine, tous, ecrits, { fichiers = new Set(), composa
|
|
|
244
289
|
}
|
|
245
290
|
}
|
|
246
291
|
};
|
|
247
|
-
for (const sf of
|
|
248
|
-
const c = composantDe(sf.fileName);
|
|
249
|
-
if (!c || estTest(c, sf.fileName) || DECLARATION.test(sf.fileName)) {
|
|
250
|
-
continue;
|
|
251
|
-
}
|
|
292
|
+
for (const { sf, c } of s.sources) {
|
|
252
293
|
for (const st of sf.statements) {
|
|
253
294
|
const decls = ts.isVariableStatement(st)
|
|
254
295
|
? st.declarationList.declarations.filter(d => ts.isIdentifier(d.name))
|
|
@@ -270,32 +311,10 @@ function releveParLesTypes(racine, tous, ecrits, { fichiers = new Set(), composa
|
|
|
270
311
|
}
|
|
271
312
|
}
|
|
272
313
|
|
|
273
|
-
//
|
|
274
|
-
const exportes = new Map();
|
|
275
|
-
const reel = sym => {
|
|
276
|
-
let x = sym;
|
|
277
|
-
if (x && x.flags & ts.SymbolFlags.Alias) {
|
|
278
|
-
x = checker.getAliasedSymbol(x);
|
|
279
|
-
}
|
|
280
|
-
return x ? checker.getExportSymbolOfSymbol(x) : x;
|
|
281
|
-
};
|
|
282
|
-
const exportsDe = c => {
|
|
283
|
-
if (!exportes.has(c)) {
|
|
284
|
-
const f = entreeDe(c);
|
|
285
|
-
const sf = f ? programme.getSourceFile(f) : undefined;
|
|
286
|
-
const mod = sf ? checker.getSymbolAtLocation(sf) : undefined;
|
|
287
|
-
exportes.set(
|
|
288
|
-
c,
|
|
289
|
-
mod ? checker.getExportsOfModule(mod).map(x => ({ nom: x.name, sym: reel(x) })) : []
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
return exportes.get(c);
|
|
293
|
-
};
|
|
294
|
-
const symDe = d => reel(checker.getSymbolAtLocation(d.noeud));
|
|
314
|
+
// Whether the entry of its component exports a declaration (a member, when its type is).
|
|
295
315
|
const publie = d => {
|
|
296
316
|
const h = d.haut ?? d;
|
|
297
|
-
|
|
298
|
-
return Boolean(sym) && exportsDe(h.c).some(x => x.sym === sym);
|
|
317
|
+
return s.publie(h.c, h.noeud);
|
|
299
318
|
};
|
|
300
319
|
|
|
301
320
|
// The references of the declaration <d>: [{ c, appel }], its own declarations left out.
|
package/scripts/registre.mjs
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
// role agent launched in a shell included). An agent resumed by a message has one line per stop; the board
|
|
5
5
|
// reads an agent's latest line, and the transcripts of running ones. The circuit of a ticket
|
|
6
6
|
// (scripts/circuit.mjs) writes a line at the end of each step it leads itself, with no agent
|
|
7
|
-
// (`ligneDEtape`: its role `circuit`, its step
|
|
7
|
+
// (`ligneDEtape`: its role `circuit`, its step, one turn, no tokens).
|
|
8
8
|
//
|
|
9
9
|
// - The line: the project (the main tree of the directory the session opened in, which the hook
|
|
10
|
-
// reads in CLAUDE_PROJECT_DIR, else in its input's `cwd`), the agent, its ticket (« TON TICKET :
|
|
11
|
-
//
|
|
10
|
+
// reads in CLAUDE_PROJECT_DIR, else in its input's `cwd`), the agent, its ticket (« TON TICKET : »),
|
|
11
|
+
// its role,
|
|
12
12
|
// its start and end, its working time and the turns it sums (start and end in milliseconds, the
|
|
13
13
|
// waits for a message left out), its tokens, its cache reads and its cost when the session wrote
|
|
14
14
|
// one. All of it is read from the agent's transcript; the agent declares nothing.
|
|
@@ -36,14 +36,7 @@ import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync } from
|
|
|
36
36
|
import os from 'node:os';
|
|
37
37
|
import path from 'node:path';
|
|
38
38
|
import { pathToFileURL } from 'node:url';
|
|
39
|
-
import {
|
|
40
|
-
lireFichier,
|
|
41
|
-
ROLE_DU_CIRCUIT,
|
|
42
|
-
roleDeLAgent,
|
|
43
|
-
roleDuMeta,
|
|
44
|
-
ticketDuRegulateur,
|
|
45
|
-
tourne,
|
|
46
|
-
} from './tableau.mjs';
|
|
39
|
+
import { lireFichier, ROLE_DU_CIRCUIT, roleDeLAgent, roleDuMeta, tourne } from './tableau.mjs';
|
|
47
40
|
import { lacherVerrou, prendreVerrou } from './verrou-de-fichier.mjs';
|
|
48
41
|
|
|
49
42
|
const REGISTRE =
|
|
@@ -87,14 +80,14 @@ export function source(input) {
|
|
|
87
80
|
// The register's line for this hook input and the reading `t` of its transcript (`lireFichier` or
|
|
88
81
|
// `lireTranscription`), or null. `projet` is the main tree of the session.
|
|
89
82
|
export function ligne(input, t, projet) {
|
|
90
|
-
const {
|
|
83
|
+
const { role, agent } = source(input);
|
|
91
84
|
if (t.premier === null) {
|
|
92
85
|
return null;
|
|
93
86
|
}
|
|
94
87
|
return {
|
|
95
88
|
projet,
|
|
96
89
|
agent,
|
|
97
|
-
ticket: t.ticket ??
|
|
90
|
+
ticket: t.ticket ?? null,
|
|
98
91
|
role: role ?? t.role,
|
|
99
92
|
debut: new Date(t.premier).toISOString(),
|
|
100
93
|
fin: new Date(t.dernier).toISOString(),
|
|
@@ -108,7 +101,7 @@ export function ligne(input, t, projet) {
|
|
|
108
101
|
|
|
109
102
|
// The register's line of a step the circuit of <ticket> leads itself (scripts/circuit.mjs), from
|
|
110
103
|
// <debut> to <fin> (ISO dates): one agent per step, its role `circuit`, one turn, no tokens.
|
|
111
|
-
export function ligneDEtape({ projet, ticket, etape,
|
|
104
|
+
export function ligneDEtape({ projet, ticket, etape, debut, fin }) {
|
|
112
105
|
const [d, f] = [Date.parse(debut), Date.parse(fin)];
|
|
113
106
|
return {
|
|
114
107
|
projet,
|
|
@@ -116,7 +109,6 @@ export function ligneDEtape({ projet, ticket, etape, composant, debut, fin }) {
|
|
|
116
109
|
ticket,
|
|
117
110
|
role: ROLE_DU_CIRCUIT,
|
|
118
111
|
etape,
|
|
119
|
-
composant,
|
|
120
112
|
debut,
|
|
121
113
|
fin,
|
|
122
114
|
travail: f - d,
|