devmethod-ai 0.2.0 → 0.3.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.
Files changed (60) hide show
  1. package/.agents/skills/decision-architecture/SKILL.md +10 -0
  2. package/.agents/skills/decision-architecture/assets/ADR.md +6 -3
  3. package/.agents/skills/project-foundation/SKILL.md +2 -0
  4. package/.agents/skills/project-foundation/assets/CADRAGE.md +11 -0
  5. package/.agents/skills/project-foundation/assets/EXISTANT.md +14 -0
  6. package/.agents/skills/project-foundation/assets/OPPORTUNITES.md +10 -0
  7. package/.agents/skills/project-foundation/assets/PROJECT_PROFILE.md +3 -2
  8. package/.agents/skills/project-foundation/assets/REGLES.md +6 -0
  9. package/.agents/skills/project-foundation/assets/START_HERE.md +2 -0
  10. package/.agents/skills/project-foundation/references/delivery-planning.md +11 -0
  11. package/.agents/skills/project-foundation/references/exploration.md +11 -0
  12. package/.agents/skills/project-foundation/references/mission-context.md +31 -4
  13. package/.agents/skills/project-foundation/references/operating-commands.md +12 -4
  14. package/.agents/skills/project-foundation/references/work-sizing.md +1 -1
  15. package/.agents/skills/scoped-delivery/SKILL.md +5 -1
  16. package/.agents/skills/scoped-delivery/assets/MISSION.md +1 -1
  17. package/.agents/skills/scoped-delivery/assets/PLAN.md +20 -0
  18. package/.agents/skills/scoped-delivery/assets/REPRISE.md +10 -0
  19. package/.agents/skills/scoped-delivery/assets/REVIEW.md +34 -0
  20. package/.agents/skills/scoped-delivery/assets/SLICE.md +5 -0
  21. package/.agents/skills/scoped-delivery/assets/TICKET.md +21 -0
  22. package/.agents/skills/scoped-delivery/references/review-workflow.md +29 -0
  23. package/COMPATIBILITY.md +1 -1
  24. package/README.md +20 -10
  25. package/START_HERE.md +2 -0
  26. package/dist/cli.js +122 -90
  27. package/dist/review-app.js +462 -0
  28. package/dist/review-browser.js +567 -0
  29. package/dist/review-cli.js +68 -0
  30. package/dist/review-model.js +101 -0
  31. package/dist/review-open.js +19 -0
  32. package/dist/review-ui.css +782 -0
  33. package/dist/review.js +13 -0
  34. package/docs/ADR-007-conversation-and-mission-ownership.md +13 -0
  35. package/docs/ADR-008-review-presentation.md +13 -0
  36. package/docs/MISSIONS.md +1 -1
  37. package/docs/RELEASE-0.2.0.md +14 -3
  38. package/docs/RELEASE-0.3.0.md +24 -0
  39. package/docs/REVIEW-SOURCES.md +13 -0
  40. package/docs/REVIEW-VALIDATION.md +34 -0
  41. package/docs/REVIEWS.md +75 -0
  42. package/docs/VISUAL-WORKFLOW.md +1 -1
  43. package/docs/WORKFLOW-0.3-VALIDATION.md +32 -0
  44. package/docs/WORKFLOW-0.3.md +34 -0
  45. package/docs/images/review-interface-desktop.jpg +0 -0
  46. package/docs/images/review-interface-mobile.jpg +0 -0
  47. package/docs/missions/workflow-0.3-reviews/interface/REVIEW.md +109 -0
  48. package/docs/missions/workflow-0.3-reviews/interface/review.json +255 -0
  49. package/docs/missions/workflow-0.3.md +17 -0
  50. package/examples/mission-dialogue/PROJECT_PROFILE.md +9 -0
  51. package/examples/mission-dialogue/architecture/decisions/001-storage.md +7 -0
  52. package/examples/mission-dialogue/docs/missions/first-save/PLAN.md +13 -0
  53. package/examples/mission-dialogue/docs/missions/first-save/REPRISE.md +6 -0
  54. package/examples/mission-dialogue/docs/missions/first-save/tickets/SAVE-1.md +14 -0
  55. package/examples/mission-dialogue/docs/missions/legacy-copy.md +9 -0
  56. package/examples/mission-dialogue/docs/produit/REGLES.md +5 -0
  57. package/examples/review/review.json +199 -0
  58. package/package.json +2 -2
  59. package/scripts/build-review.mjs +8 -0
  60. package/scripts/package-smoke.mjs +16 -3
@@ -0,0 +1,255 @@
1
+ {
2
+ "format": 1,
3
+ "id": "REVIEW-UI-1",
4
+ "title": "Review de l’interface DevMethod",
5
+ "project": "DevMethod",
6
+ "mission": "workflow-0.3",
7
+ "tickets": [
8
+ {
9
+ "id": "PR-19",
10
+ "title": "Livraison du workflow et de la review",
11
+ "url": "https://github.com/montassarkhalloufi/DevMethod/pull/19"
12
+ }
13
+ ],
14
+ "date": "2026-09-13",
15
+ "scope": [
16
+ "Format de review, rendu sécurisé, navigation clavier/mobile et exports du candidat en cours."
17
+ ],
18
+ "exclusions": [
19
+ "Audit exhaustif WCAG avec lecteur d’écran",
20
+ "Exécution native du workflow conversationnel sur les trois hôtes"
21
+ ],
22
+ "revision": {
23
+ "commit": "8d7cd3584c891c04d983f85279e14a2070ab621d + working changes",
24
+ "dirty": [
25
+ "src/review-app.ts",
26
+ "src/review-model.ts",
27
+ "src/review-cli.ts",
28
+ "src/review.ts",
29
+ "src/review-ui.css",
30
+ "src/cli.ts"
31
+ ]
32
+ },
33
+ "technologies": [
34
+ {
35
+ "name": "TypeScript",
36
+ "version": "5.9.3",
37
+ "detectedFrom": "package-lock.json"
38
+ },
39
+ {
40
+ "name": "Node.js",
41
+ "version": "24.18.0 local / >=22 package",
42
+ "detectedFrom": "node --version / package.json"
43
+ }
44
+ ],
45
+ "sources": [
46
+ {
47
+ "id": "WAI-TABS",
48
+ "title": "Tabs Pattern",
49
+ "kind": "documentation",
50
+ "publisher": "W3C WAI",
51
+ "technology": "ARIA / DOM",
52
+ "version": "APG consulted 2026-09-13",
53
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/tabs/",
54
+ "consultedAt": "2026-09-13",
55
+ "access": "consulted",
56
+ "usage": "Clavier, focus et association des onglets/panneaux.",
57
+ "compatibility": "Guide de conception ; ne certifie pas une conformité WCAG complète.",
58
+ "provenance": "Page du site officiel W3C consultée pendant cette session."
59
+ }
60
+ ],
61
+ "checks": [
62
+ {
63
+ "id": "UI-KEYBOARD",
64
+ "title": "Clavier et retour mobile",
65
+ "domain": "Interface",
66
+ "kind": "manual",
67
+ "status": "passed",
68
+ "result": "Focus après correction et conservation des filtres observés.",
69
+ "reason": null,
70
+ "evidenceIds": [
71
+ "E-FOCUS-AFTER"
72
+ ],
73
+ "revision": "8d7cd3584c891c04d983f85279e14a2070ab621d + working changes",
74
+ "targets": [
75
+ "finding-selection",
76
+ "tabs"
77
+ ]
78
+ },
79
+ {
80
+ "id": "UI-EXPORT",
81
+ "title": "Contenu de l’export HTML",
82
+ "domain": "Interface",
83
+ "kind": "manual",
84
+ "status": "passed",
85
+ "result": "Résultats, état de sélection et empreinte CSP vérifiés dans le dernier export Chrome.",
86
+ "reason": null,
87
+ "evidenceIds": [
88
+ "E-EXPORT"
89
+ ],
90
+ "revision": "8d7cd3584c891c04d983f85279e14a2070ab621d + working changes",
91
+ "targets": [
92
+ "export"
93
+ ]
94
+ },
95
+ {
96
+ "id": "UI-REOPEN",
97
+ "title": "Réouverture file://",
98
+ "domain": "Interface",
99
+ "kind": "manual",
100
+ "status": "blocked",
101
+ "result": "Non vérifiée dans le navigateur automatisé.",
102
+ "reason": "La politique de l’outil interdit cette navigation ; aucun contournement effectué.",
103
+ "evidenceIds": [],
104
+ "revision": "8d7cd3584c891c04d983f85279e14a2070ab621d + working changes",
105
+ "targets": [
106
+ "export"
107
+ ]
108
+ },
109
+ {
110
+ "id": "SEC-REDACTION",
111
+ "title": "Masquage des formats courants",
112
+ "domain": "Confidentialité",
113
+ "kind": "automated",
114
+ "status": "passed",
115
+ "result": "Régression Bearer, variable préfixée et valeur entre guillemets réussie.",
116
+ "reason": null,
117
+ "evidenceIds": [
118
+ "E-REDACTION"
119
+ ],
120
+ "revision": "fa84208 + redaction working changes",
121
+ "targets": [
122
+ "review-redaction"
123
+ ]
124
+ }
125
+ ],
126
+ "findings": [
127
+ {
128
+ "id": "FOCUS-01",
129
+ "title": "La sélection d’un constat perdait le focus clavier",
130
+ "domain": "Accessibilité",
131
+ "severity": "moderate",
132
+ "severityReason": "La navigation clavier quittait le contenu attendu et rendait la poursuite du parcours difficile.",
133
+ "confidence": "confirmed",
134
+ "resolution": "resolved",
135
+ "location": {
136
+ "path": "src/review-app.ts",
137
+ "line": null,
138
+ "component": "Sélection du constat et gestion de hashchange"
139
+ },
140
+ "trigger": "Activer un constat avec Enter quand le fragment de lien doit changer.",
141
+ "expected": "Le focus arrive sur le titre du détail et permet de poursuivre au clavier.",
142
+ "observed": "Avant correction, le rendu immédiat était suivi d’un deuxième rendu lors de hashchange ; le titre focalisé était remplacé.",
143
+ "impact": "L’utilisateur au clavier perdait son point de navigation.",
144
+ "reproduction": [
145
+ "Activer R-01 avec Enter depuis la liste.",
146
+ "Inspecter le focus après le changement du fragment."
147
+ ],
148
+ "evidenceIds": [
149
+ "E-FOCUS-BEFORE"
150
+ ],
151
+ "correction": "Mettre à jour le fragment avec history.pushState, rendre une seule fois, puis focaliser le titre. Restaurer aussi le focus après un changement d’onglet.",
152
+ "tradeoffs": "Écouter popstate séparément pour les navigations historiques.",
153
+ "sourceIds": [
154
+ "WAI-TABS"
155
+ ],
156
+ "ticketIds": [
157
+ "PR-19"
158
+ ],
159
+ "verification": "Enter conserve le focus sur detail-title ; ArrowRight cible Correction ; le retour mobile restaure la liste filtrée.",
160
+ "resolutionEvidenceIds": [
161
+ "E-FOCUS-AFTER"
162
+ ],
163
+ "targets": [
164
+ "finding-selection",
165
+ "tabs"
166
+ ]
167
+ },
168
+ {
169
+ "id": "REDACT-01",
170
+ "title": "Certains formats courants d’identifiants étaient partiellement masqués",
171
+ "domain": "Confidentialité",
172
+ "severity": "major",
173
+ "severityReason": "Un rapport distribué pouvait conserver une valeur sensible dans un header standard ou un champ entre guillemets. Aucun identifiant réel n’a été exposé dans ce test.",
174
+ "confidence": "confirmed",
175
+ "resolution": "resolved",
176
+ "location": {
177
+ "path": "src/review-model.ts",
178
+ "line": null,
179
+ "component": "redactReviewText"
180
+ },
181
+ "trigger": "Importer une preuve contenant un header Bearer ou une valeur sensible avec espaces.",
182
+ "expected": "Masquer la valeur complète des formats courants pris en charge.",
183
+ "observed": "La première règle arrêtait le masquage au premier espace et ne reconnaissait pas certains préfixes de variables.",
184
+ "impact": "Risque de divulguer une valeur sensible dans une copie de rapport si la revue de confidentialité ne la détecte pas.",
185
+ "reproduction": [
186
+ "Utiliser exclusivement les cas synthétiques du test de régression du masquage."
187
+ ],
188
+ "evidenceIds": [
189
+ "E-REDACTION"
190
+ ],
191
+ "correction": "Reconnaître les schémas Bearer/Basic, les valeurs entre guillemets et les clés préfixées avant de produire la copie distribuée.",
192
+ "tradeoffs": "Le masquage reste heuristique ; la confidentialité des images et des formats inconnus exige une inspection avant partage.",
193
+ "sourceIds": [],
194
+ "ticketIds": [
195
+ "PR-19"
196
+ ],
197
+ "verification": "Les valeurs synthétiques de ces trois formats sont absentes de sanitizedReview ; le document original reste inchangé.",
198
+ "resolutionEvidenceIds": [
199
+ "E-REDACTION"
200
+ ],
201
+ "targets": [
202
+ "review-redaction"
203
+ ]
204
+ }
205
+ ],
206
+ "evidence": [
207
+ {
208
+ "id": "E-FOCUS-BEFORE",
209
+ "title": "Observation réelle avant correction",
210
+ "kind": "log",
211
+ "content": "Navigateur intégré, 2026-09-13 : activation clavier du constat R-01 puis lecture du focus. Résultat observé : document.activeElement.id vide après le second rendu déclenché par hashchange. Le lien direct devenait #finding=R-01. Observation manuelle de cette session, pas un journal de test CI.",
212
+ "url": null,
213
+ "image": null
214
+ },
215
+ {
216
+ "id": "E-FOCUS-AFTER",
217
+ "title": "Vérification réelle après correction",
218
+ "kind": "log",
219
+ "content": "Navigateur intégré, 2026-09-13 : Enter sur le constat => focus detail-title. ArrowRight sur Preuve => focus detail-content-correction. En mobile 390x844, retour => focus sur le constat choisi ; query=silencieux et confidence=confirmed conservés ; aucun débordement horizontal.",
220
+ "url": null,
221
+ "image": null
222
+ },
223
+ {
224
+ "id": "E-EXPORT",
225
+ "title": "Export Chrome inspecté sur disque",
226
+ "kind": "text",
227
+ "content": "Le dernier export Chrome possède review format 1, uiState.selected=R-01, filters.query=silencieux et section=correction. Les données ont été validées et l’empreinte SHA-256 du programme correspond à la CSP. Réouverture navigateur file:// non exécutée : politique de l’outil.",
228
+ "url": null,
229
+ "image": null
230
+ },
231
+ {
232
+ "id": "E-REDACTION",
233
+ "title": "Régression automatisée du masquage des identifiants",
234
+ "kind": "log",
235
+ "content": "Cas synthétiques : header Authorization avec Bearer, variable NPM_TOKEN et mot de passe entre guillemets contenant des espaces. Avant correction, la règle masquait seulement une partie de certaines valeurs. Le test dédié vérifie maintenant que les trois valeurs synthétiques sont totalement absentes de la source distribuée. Exécuté dans npm test : réussite.",
236
+ "url": null,
237
+ "image": null
238
+ }
239
+ ],
240
+ "limits": [
241
+ "La réouverture directe file:// est bloquée par la politique du navigateur de test ; elle n’est pas annoncée comme vérifiée.",
242
+ "Les tests de format ne prouvent ni la vérité des preuves fournies ni le comportement d’un agent de review.",
243
+ "Le mode d’ouverture final reste à choisir avant publication."
244
+ ],
245
+ "policy": {
246
+ "blockingSeverities": [
247
+ "critical",
248
+ "major",
249
+ "moderate"
250
+ ],
251
+ "requireAllChecks": true,
252
+ "rationale": "Corriger les défauts confirmés affectant le parcours et vérifier les contrôles de livraison avant publication."
253
+ },
254
+ "summary": "Le défaut de focus observé a été corrigé et revérifié. La validation de livraison reste incomplète, avec ses limites explicites."
255
+ }
@@ -0,0 +1,17 @@
1
+ # Workflow and review delivery — 0.3.0
2
+
3
+ Owner: current implementation session. Authorized scope: improve explore, architecture, plan, mission ownership and review; deliver a functional browser review interface, package, PR, merge after checks, GitHub release and npm publication. Preserve approved design behavior, existing project conventions and user files. The user supplied a validated visual direction for the review screen; its example findings are not real evidence.
4
+
5
+ This repository already uses single-file mission records, so retain that convention for this delivery. The user added the review scope before publication; PR #19 remains the same delivery. Existing checks for the earlier commit are historical, not validation of the added interface.
6
+
7
+ ## Executable scope and ownership
8
+
9
+ - Workflow guidance and mission templates: implemented; evidence and migration details in [workflow validation](../WORKFLOW-0.3-VALIDATION.md) and [migration](../WORKFLOW-0.3.md).
10
+ - Review record, derived report, browser interface and CLI: active. Acceptance: validated versioned records; consistent counters/filters; finding/check separation; evidence and official-source provenance; safe rendering; list/detail and direct links; export/reopen; explicit empty/invalid/partial/historical states; responsive keyboard use; distribution independent of the source checkout.
11
+ - Delivery: [PR #19](https://github.com/montassarkhalloufi/DevMethod/pull/19). CI/package proofs belong in the PR and release record. The actual review results are owned by [review.json](workflow-0.3-reviews/interface/review.json), with a generated report; do not duplicate finding status here.
12
+
13
+ Exclusions: whole-project dashboard, remote hosting, automatic discovery/installation/execution of third-party skills, automatic code review execution, arbitrary filesystem browsing, destructive migration, changes to the approved design workflow.
14
+
15
+ Current architecture question: static self-contained HTML versus loopback server; recommended static report under the dependency-free offline contract, presented to the user before dependent implementation. Preserve their forthcoming choice/delegation in the relevant ADR.
16
+
17
+ Next action: verify the final delegated offline-opening integration, merge and publish under current authorization. The user explicitly delegated the opening-mode choice on 2026-09-13; ADR 008 records the selected standalone HTML and optional OS opening command. Shared model, report/export, CLI presentation and browser UI are implemented. The file:// browser reopening limitation remains documented; do not bypass the browser tool policy or claim that check passed.
@@ -0,0 +1,9 @@
1
+ # Reading list — fictional workflow fixture
2
+
3
+ Outcome: let a reader save a title and retrieve it later. This is an illustrative authored fixture, not a delivered product or a real conversation transcript.
4
+ Cross-cutting constraints: one maintainer, modest operating budget, hosting undecided.
5
+ Active mission: [first save](docs/missions/first-save/PLAN.md).
6
+ Product rules: [rules](docs/produit/REGLES.md).
7
+ Open architecture: [storage](architecture/decisions/001-storage.md).
8
+ Research: not executed; no market or price claims are made.
9
+ Read the mission, then the active ticket and only its linked rules/decision. A legacy record is also [illustrated](docs/missions/legacy-copy.md); it is a separate mission, not another tracker of first-save.
@@ -0,0 +1,7 @@
1
+ # Storage decision
2
+
3
+ Status: PROPOSED. No choice or delegation has been received in this fixture.
4
+ Constraints: single maintainer; hosting and multi-device requirement unresolved.
5
+ Conversation brief to present: local storage offers a small single-device slice; server persistence can support multiple devices but adds hosting and operation. Recommendation depends on the multi-device requirement and data-loss tolerance. No current price claim.
6
+ Ask the user to challenge, offer an alternative, choose or delegate. Evaluate any alternative against the same durability, operations, cost and access criteria.
7
+ Dependent architecture stays open. Revisit after the requirement or budget changes. Record the actual choice/delegation and rationale here before detailing dependent architecture.
@@ -0,0 +1,13 @@
1
+ # First useful save
2
+
3
+ Owner: fictional maintainer. Outcome: save one title and find it again. Learning: whether this smallest journey is useful enough to extend.
4
+ Proposed scope: one title field and retrieval; exclude accounts, tagging and sharing. No artificial second delivery option is needed until a real competing priority emerges.
5
+ Effort: not estimated until runtime and persistence are chosen; main uncertainty is multi-device storage and deployment.
6
+ Scope conversation pending: invite the user to add, remove, move or split scope. No priorities have been accepted in this authored fixture.
7
+ Conditional dependency: [storage decision](../../../architecture/decisions/001-storage.md).
8
+
9
+ | Milestone | Demonstration | Exit criteria | Continuation conditions | Ordered tickets |
10
+ |---|---|---|---|---|
11
+ | First useful save | Save and retrieve one title; reject blank input | Ticket criteria pass on the selected persistence contract | Continue only agreed scope; reassess after a changed storage decision | [SAVE-1](tickets/SAVE-1.md) |
12
+
13
+ Ticket owns current execution state and evidence. [Latest handoff](REPRISE.md).
@@ -0,0 +1,6 @@
1
+ # Latest handoff
2
+
3
+ Captured: 2026-09-13, authored fixture, no implementation revision.
4
+ Read [profile](../../../PROJECT_PROFILE.md), [mission](PLAN.md), then [active ticket](tickets/SAVE-1.md).
5
+ Last action: prepared a conditional milestone and acceptance examples; no tests executed.
6
+ Next action: resume the [storage exchange](../../../architecture/decisions/001-storage.md). Ticket owns the blocker; reconcile it before dependent implementation. This snapshot grants no new authorization.
@@ -0,0 +1,14 @@
1
+ # SAVE-1
2
+
3
+ Owner: fictional maintainer. [Milestone](../PLAN.md).
4
+ Outcome/value: retain a title for later retrieval.
5
+ Included: save and retrieve a title. Excluded: accounts, tags, sharing.
6
+ Status: conditional.
7
+ Dependencies/blocker: [storage choice](../../../../architecture/decisions/001-storage.md), owned by the maintainer, unresolved.
8
+ Rule: [R-01](../../../produit/REGLES.md#r-01--save-a-title).
9
+ Screen: no approved screen required by this nonvisual fixture; resolve design if visual scope is added.
10
+ Contract: persistence contract awaits the storage decision.
11
+ Acceptance AC-01: a valid saved title is retrievable. AC-02: whitespace-only input is rejected.
12
+ Verification: not run; there is no implementation or inspected code revision. Proposed check is a save/retrieve and blank-input test under the selected contract.
13
+ Review/integration/deployment: not performed.
14
+ Next action: resume the storage decision exchange in architecture; independent work may refine input examples.
@@ -0,0 +1,9 @@
1
+ # Legacy mission — improve copy
2
+
3
+ This separate, fictional single-file mission remains usable without moving it into a directory.
4
+ Outcome/scope: clarify one empty-state message; exclude behavior changes.
5
+ Task COPY-1 / owner: maintainer / status: proposed.
6
+ Criterion COPY-AC1: the message explains the next available action.
7
+ Evidence: not run, no implementation revision.
8
+ Next action: inspect the current wording and apply the authorized text edit.
9
+ Latest handoff: 2026-09-13, fixture prepared; this section references the task above rather than duplicating its status.
@@ -0,0 +1,5 @@
1
+ # Reading list rules
2
+
3
+ ## R-01 — Save a title
4
+
5
+ A non-empty title can be saved and retrieved; whitespace-only input is rejected. This is an assumed fixture requirement, not user research.
@@ -0,0 +1,199 @@
1
+ {
2
+ "format": 1,
3
+ "id": "DEMO-REVIEW",
4
+ "title": "Review de la bibliothèque",
5
+ "project": "Atelier de lecture",
6
+ "mission": "Première sauvegarde",
7
+ "tickets": [
8
+ {
9
+ "id": "DEMO-12",
10
+ "title": "PR de l’interface (lien de démonstration)",
11
+ "url": "https://github.com/montassarkhalloufi/DevMethod/pull/19"
12
+ }
13
+ ],
14
+ "date": "2026-09-13",
15
+ "scope": [
16
+ "Démonstration fictive de consultation, sans audit du projet illustré."
17
+ ],
18
+ "exclusions": [
19
+ "Aucun résultat réel de sécurité ou de performance."
20
+ ],
21
+ "revision": {
22
+ "commit": "demo-revision-1",
23
+ "dirty": []
24
+ },
25
+ "technologies": [
26
+ {
27
+ "name": "HTML / DOM",
28
+ "version": "Living Standard",
29
+ "detectedFrom": "Fixture authored for the viewer"
30
+ }
31
+ ],
32
+ "sources": [
33
+ {
34
+ "id": "WAI",
35
+ "title": "Messages de statut accessibles",
36
+ "kind": "documentation",
37
+ "publisher": "W3C WAI",
38
+ "technology": "Web accessibility",
39
+ "version": "WCAG 2.2",
40
+ "url": "https://www.w3.org/WAI/WCAG22/Understanding/status-messages.html",
41
+ "consultedAt": null,
42
+ "access": "unverified",
43
+ "usage": "Référence proposée pour cette démonstration, non consultée dans une review réelle.",
44
+ "compatibility": "À vérifier pour le parcours cible.",
45
+ "provenance": "Domaine w3.org ; cette fixture ne constitue pas une vérification de provenance."
46
+ }
47
+ ],
48
+ "checks": [
49
+ {
50
+ "id": "C-01",
51
+ "title": "Annonce après sauvegarde",
52
+ "domain": "Accessibilité",
53
+ "kind": "manual",
54
+ "status": "failed",
55
+ "result": "Exemple fictif : le changement de statut ne serait pas annoncé.",
56
+ "reason": null,
57
+ "evidenceIds": [
58
+ "E-01"
59
+ ],
60
+ "revision": "demo-revision-1",
61
+ "targets": [
62
+ "save-status"
63
+ ]
64
+ },
65
+ {
66
+ "id": "C-02",
67
+ "title": "Conservation du titre",
68
+ "domain": "Données",
69
+ "kind": "automated",
70
+ "status": "passed",
71
+ "result": "Exemple fictif : la valeur enregistrée correspond à la saisie.",
72
+ "reason": null,
73
+ "evidenceIds": [
74
+ "E-02"
75
+ ],
76
+ "revision": "demo-revision-1",
77
+ "targets": [
78
+ "save-title"
79
+ ]
80
+ },
81
+ {
82
+ "id": "C-03",
83
+ "title": "Temps de réponse sur liste longue",
84
+ "domain": "Performance",
85
+ "kind": "automated",
86
+ "status": "not-run",
87
+ "result": "Aucune mesure disponible dans cette fixture.",
88
+ "reason": "Jeu de données représentatif indisponible.",
89
+ "evidenceIds": [],
90
+ "revision": "demo-revision-1",
91
+ "targets": [
92
+ "list-view"
93
+ ]
94
+ }
95
+ ],
96
+ "findings": [
97
+ {
98
+ "id": "R-01",
99
+ "title": "Le retour de sauvegarde reste silencieux",
100
+ "domain": "Accessibilité",
101
+ "severity": "moderate",
102
+ "severityReason": "Exemple fictif : le lecteur pourrait ignorer que son action a réussi.",
103
+ "confidence": "confirmed",
104
+ "resolution": "open",
105
+ "location": {
106
+ "path": "save-status (composant fictif)",
107
+ "line": null,
108
+ "component": "Confirmation de sauvegarde"
109
+ },
110
+ "trigger": "Sauvegarder un titre en utilisant un lecteur d’écran.",
111
+ "expected": "Le succès est annoncé sans déplacer le focus.",
112
+ "observed": "Dans ce scénario fictif, seul le texte visuel change.",
113
+ "impact": "Le lecteur ne sait pas si son titre a été conservé.",
114
+ "reproduction": [
115
+ "Scénario illustratif, non exécuté.",
116
+ "Saisir un titre, activer Sauvegarder et écouter le retour."
117
+ ],
118
+ "evidenceIds": [
119
+ "E-01"
120
+ ],
121
+ "correction": "Exposer le message de succès comme statut accessible, puis vérifier son annonce.",
122
+ "tradeoffs": "Éviter les annonces répétées ; conserver le focus dans le parcours.",
123
+ "sourceIds": [
124
+ "WAI"
125
+ ],
126
+ "ticketIds": [
127
+ "DEMO-12"
128
+ ],
129
+ "verification": "Inspecter avec un lecteur d’écran réel et vérifier le maintien du focus.",
130
+ "resolutionEvidenceIds": [],
131
+ "targets": [
132
+ "save-status"
133
+ ]
134
+ },
135
+ {
136
+ "id": "R-02",
137
+ "title": "Une grande liste pourrait ralentir la recherche",
138
+ "domain": "Performance",
139
+ "severity": "minor",
140
+ "severityReason": "Impact supposé limité aux collections volumineuses.",
141
+ "confidence": "suspected",
142
+ "resolution": "open",
143
+ "location": {
144
+ "path": "list-view (composant fictif)",
145
+ "line": null,
146
+ "component": "Liste de titres"
147
+ },
148
+ "trigger": "Rechercher dans une collection volumineuse.",
149
+ "expected": "La saisie reste réactive.",
150
+ "observed": "Aucune mesure ; risque hypothétique seulement.",
151
+ "impact": "Un délai pourrait gêner la saisie ; cela reste à vérifier.",
152
+ "reproduction": [
153
+ "Préparer un jeu représentatif puis mesurer ; non exécuté."
154
+ ],
155
+ "evidenceIds": [],
156
+ "correction": "Mesurer avant de décider d’une optimisation.",
157
+ "tradeoffs": "Éviter une complexité non justifiée par des mesures.",
158
+ "sourceIds": [],
159
+ "ticketIds": [],
160
+ "verification": "Mesurer latence et réactivité sur le matériel cible.",
161
+ "resolutionEvidenceIds": [],
162
+ "targets": [
163
+ "list-view"
164
+ ]
165
+ }
166
+ ],
167
+ "evidence": [
168
+ {
169
+ "id": "E-01",
170
+ "title": "Flux du retour utilisateur — schéma explicatif",
171
+ "kind": "diagram",
172
+ "content": "Saisie du titre → Sauvegarder → Titre conservé → Message visuel\n ↳ Annonce vocale manquante (hypothèse de fixture)\nSchéma explicatif fictif, pas une capture ni un journal d’exécution.",
173
+ "url": null,
174
+ "image": null
175
+ },
176
+ {
177
+ "id": "E-02",
178
+ "title": "Résultat illustratif de conservation",
179
+ "kind": "log",
180
+ "content": "DÉMONSTRATION — journal rédigé, test non exécuté.\nEntrée « Un titre » → valeur conservée « Un titre ».",
181
+ "url": null,
182
+ "image": null
183
+ }
184
+ ],
185
+ "limits": [
186
+ "DÉMONSTRATION : données fictives, sans validation d’un produit réel.",
187
+ "Le contrôle de performance n’a pas été exécuté."
188
+ ],
189
+ "policy": {
190
+ "blockingSeverities": [
191
+ "critical",
192
+ "major",
193
+ "moderate"
194
+ ],
195
+ "requireAllChecks": true,
196
+ "rationale": "Politique illustrative : corriger les problèmes confirmés modérés ou plus graves avant intégration."
197
+ },
198
+ "summary": "Démonstration de l’interface. Les constats et contrôles ci-dessous sont fictifs."
199
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devmethod-ai",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "From idea to delivery with your AI coding agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -28,7 +28,7 @@
28
28
  "url": "git+https://github.com/montassarkhalloufi/DevMethod.git"
29
29
  },
30
30
  "scripts": {
31
- "build": "tsc",
31
+ "build": "tsc && node scripts/build-review.mjs",
32
32
  "test": "npm run build && node --test tests/*.test.mjs",
33
33
  "test:fixtures": "node --test tests/evaluation.test.mjs",
34
34
  "check:docs": "node scripts/check-docs.mjs",
@@ -0,0 +1,8 @@
1
+ // The two browser modules have no runtime dependencies. Keep this bundle explicit.
2
+ import fs from 'node:fs';
3
+ const model = fs.readFileSync('dist/review-model.js', 'utf8').replace(/\r\n/g, '\n');
4
+ const app = fs.readFileSync('dist/review-app.js', 'utf8').replace(/\r\n/g, '\n');
5
+ if (/^import /m.test(model) || (app.match(/^import /gm) || []).length !== 1 || !app.includes("from './review-model.js'")) throw new Error('Review browser dependencies changed; inspect bundling.');
6
+ const code = `(function () {\n'use strict';\n${model.replace(/^export /gm, '')}\n${app.replace(/^import .*;\n/m, '')}\n})();\n`;
7
+ fs.writeFileSync('dist/review-browser.js', code);
8
+ fs.copyFileSync('src/review-ui.css', 'dist/review-ui.css');
@@ -15,8 +15,21 @@ try {
15
15
  run('tar', ['-xzf', '-'], root, 0, fs.readFileSync(path.resolve(archive)));
16
16
  const pkg = path.join(root, 'package'); const cli = path.join(pkg, 'dist/cli.js');
17
17
  const call = (args, expected = 0) => run(process.execPath, [cli, ...args], root, expected);
18
- assert.equal(JSON.parse(fs.readFileSync(path.join(pkg, 'package.json'))).version, '0.2.0');
18
+ assert.equal(JSON.parse(fs.readFileSync(path.join(pkg, 'package.json'))).version, '0.3.0');
19
19
  run(process.execPath, ['scripts/check-docs.mjs'], pkg);
20
+ assert.match(call(['--help']), /Markdown PLAN\/tickets and legacy missions/);
21
+ for (const resource of ['project-foundation/references/exploration.md', 'project-foundation/references/delivery-planning.md', 'project-foundation/assets/EXISTANT.md', 'project-foundation/assets/OPPORTUNITES.md', 'project-foundation/assets/CADRAGE.md', 'project-foundation/assets/REGLES.md', 'scoped-delivery/assets/PLAN.md', 'scoped-delivery/assets/TICKET.md', 'scoped-delivery/assets/REPRISE.md', 'scoped-delivery/assets/MISSION.md', 'scoped-delivery/assets/REVIEW.md', 'scoped-delivery/references/review-workflow.md']) {
22
+ assert.ok(fs.statSync(path.join(pkg, '.agents/skills', resource)).size > 0, resource);
23
+ }
24
+ assert.ok(fs.existsSync(path.join(pkg, 'examples/mission-dialogue/docs/missions/first-save/tickets/SAVE-1.md')));
25
+ for (const file of ['review.js', 'review-cli.js', 'review-model.js', 'review-browser.js', 'review-ui.css']) assert.ok(fs.statSync(path.join(pkg, 'dist', file)).size > 0, file);
26
+ const reviewRoot = path.join(root, 'review-output');
27
+ const reviewResult = JSON.parse(call(['review', '--demo', '--dest', reviewRoot, '--output', 'review.html', '--markdown', 'REVIEW.md', '--json']));
28
+ assert.equal(reviewResult.status, 'corrections');
29
+ assert.ok(fs.readFileSync(path.join(reviewRoot, 'review.html'), 'utf8').includes('Content-Security-Policy'));
30
+ assert.ok(fs.readFileSync(path.join(reviewRoot, 'REVIEW.md'), 'utf8').includes('R-01'));
31
+ call(['review', '--demo', '--dest', reviewRoot, '--output', 'review.html'], 2);
32
+
20
33
  for (const testFile of [...fs.readdirSync(path.join(pkg, 'examples/pocket-tasks/tests')).filter(f => f.endsWith('.test.mjs')).map(f => `examples/pocket-tasks/tests/${f}`), 'evaluation/greenfield/acceptance.test.mjs', 'evaluation/greenfield/security.test.mjs']) {
21
34
  run(process.execPath, ['--test', testFile], pkg);
22
35
  }
@@ -55,10 +68,10 @@ try {
55
68
  const before = [fs.readFileSync(customized), fs.readFileSync(profile)];
56
69
  const preview = JSON.parse(call(['update-preview', '--dest', adopted, '--json']));
57
70
  assert.equal(preview.entries.find(e => e.path === '.agents/skills/project-foundation/SKILL.md').classification, 'conflict');
58
- assert.equal(preview.provenance, 'unknown');
71
+ assert.equal(preview.provenance, JSON.parse(fs.readFileSync(path.join(adopted, 'kit-manifest.json'))).provenance ? 'recorded' : 'unknown');
59
72
  call(['init', '--tool', 'codex', '--dest', adopted], 2);
60
73
  assert.deepEqual([fs.readFileSync(customized), fs.readFileSync(profile)], before);
61
74
  console.log('Actual legacy tarball: local/upstream conflict detected and filled profile/custom skill preserved.');
62
75
  }
63
- console.log('Packed 0.2.0: three host installs, subset, customization preservation, mission/context/staleness/planning and documentation links passed. No native host execution.');
76
+ console.log('Packed 0.3.0: three host installs, subset, customization preservation, mission/context/staleness/planning and documentation links passed. No native host execution.');
64
77
  } finally { fs.rmSync(root, { recursive: true, force: true }); }