guardian-framework 0.1.105 → 0.1.109
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/README.md +11 -2
- package/dist/cli.js +232 -16
- package/dist/exports.js +232 -16
- package/package.json +1 -1
- package/templates/languages/rust-patterns.md +5 -2
- package/templates/pi/context/checklists.md +15 -1
- package/templates/pi/domain/exploration.md +9 -0
- package/templates/pi/domain/ubiquitous-language.md +12 -0
- package/templates/pi/extensions/architect-lib/generators.ts +158 -7
- package/templates/pi/extensions/architect-lib/helpers.ts +49 -0
- package/templates/pi/extensions/architect-lib/types.ts +44 -2
- package/templates/pi/extensions/architect.ts +102 -42
- package/templates/pi/extensions/ask-user-question.ts +2 -2
- package/templates/pi/extensions/bash-guard.ts +2 -2
- package/templates/pi/extensions/config-reload.ts +12 -5
- package/templates/pi/extensions/coordinator.ts +2 -2
- package/templates/pi/extensions/curator.ts +1 -1
- package/templates/pi/extensions/domain-explorer.ts +50 -3
- package/templates/pi/extensions/filechanges.ts +2 -2
- package/templates/pi/extensions/goal-loop.ts +3 -3
- package/templates/pi/extensions/hooks.ts +1 -1
- package/templates/pi/extensions/pi-env.d.ts +96 -0
- package/templates/pi/extensions/pipeline.ts +1 -1
- package/templates/pi/extensions/project-scaffolder.ts +1 -1
- package/templates/pi/extensions/read-only-mode.ts +5 -1
- package/templates/pi/extensions/tsconfig.json +9 -2
- package/templates/pi/preflight_report.json +1 -1
- package/templates/pi/prompts/ci-blueprint.md +2 -2
- package/templates/pi/scripts/check_model_judgment.sh +28 -0
- package/templates/pi/scripts/ci/check_judgment_contracts.sh +93 -0
- package/templates/pi/scripts/ci/run_preflight.sh +3 -3
- package/templates/pi/scripts/ci/run_stage.sh +1 -1
- package/templates/pi/scripts/ci/stage_lint.sh +1 -1
- package/templates/pi/scripts/coverage.sh +58 -0
- package/templates/pi/scripts/install_coverage_tools.sh +43 -0
- package/templates/pi/scripts/languages/go/check_model_judgment.sh +70 -0
- package/templates/pi/scripts/languages/go/check_runtime_reachability.sh +34 -0
- package/templates/pi/scripts/languages/go/coverage.sh +78 -0
- package/templates/pi/scripts/languages/go/install_coverage_tools.sh +17 -0
- package/templates/pi/scripts/languages/java/check_model_judgment.sh +142 -0
- package/templates/pi/scripts/languages/java/check_runtime_reachability.sh +31 -0
- package/templates/pi/scripts/languages/java/coverage.sh +103 -0
- package/templates/pi/scripts/languages/java/install_coverage_tools.sh +40 -0
- package/templates/pi/scripts/languages/java/validate-architecture.sh +20 -0
- package/templates/pi/scripts/languages/python/check_model_judgment.sh +67 -0
- package/templates/pi/scripts/languages/python/check_runtime_reachability.sh +34 -0
- package/templates/pi/scripts/languages/python/coverage.sh +88 -0
- package/templates/pi/scripts/languages/python/install_coverage_tools.sh +22 -0
- package/templates/pi/scripts/languages/rust/check_model_judgment.sh +61 -0
- package/templates/pi/scripts/languages/rust/check_runtime_reachability.sh +40 -0
- package/templates/pi/scripts/languages/rust/coverage.sh +79 -0
- package/templates/pi/scripts/languages/rust/install_coverage_tools.sh +20 -0
- package/templates/pi/scripts/languages/rust/validate-tests.sh +9 -6
- package/templates/pi/scripts/languages/typescript/check_model_judgment.sh +81 -0
- package/templates/pi/scripts/languages/typescript/check_runtime_reachability.sh +41 -0
- package/templates/pi/scripts/languages/typescript/coverage.sh +154 -0
- package/templates/pi/scripts/languages/typescript/install_coverage_tools.sh +41 -0
- package/templates/pi/scripts/languages/typescript/validate-canonical.sh +6 -2
- package/templates/pi/scripts/languages/typescript/validate-ci.sh +2 -2
- package/templates/pi/scripts/validate-architecture-readiness.sh +29 -0
- package/templates/pi/scripts/validate-exploration-depth.sh +112 -0
- package/templates/pi/scripts/validate-runtime-wiring.sh +35 -0
- package/templates/pi/skills/agents/architecture-validator.md +28 -0
- package/templates/pi/skills/agents/test-validator.md +1 -1
- package/templates/pi/skills/go-enterprise-codegen.md +46 -0
- package/templates/pi/skills/java-spring-enterprise-codegen.md +50 -0
- package/templates/pi/skills/python-enterprise-codegen.md +46 -0
- package/templates/pi/skills/rust-enterprise-codegen.md +46 -0
- package/templates/pi/skills/typescript-enterprise-codegen.md +46 -0
|
@@ -182,7 +182,7 @@ async function askSingleChoice(
|
|
|
182
182
|
{ id: "other", label: otherLabel, value: "__other__", isOther: true },
|
|
183
183
|
];
|
|
184
184
|
|
|
185
|
-
return ctx.ui.custom
|
|
185
|
+
return (ctx.ui as any).custom(
|
|
186
186
|
(tui: any, theme: any, _kb: any, done: (r: AskAnswer | null) => void) => {
|
|
187
187
|
let optionIndex = 0;
|
|
188
188
|
let editMode = false;
|
|
@@ -306,7 +306,7 @@ async function askMultiChoice(
|
|
|
306
306
|
{ id: "submit", label: "Submit", value: "__submit__", isSubmit: true },
|
|
307
307
|
];
|
|
308
308
|
|
|
309
|
-
return ctx.ui.custom
|
|
309
|
+
return (ctx.ui as any).custom(
|
|
310
310
|
(tui: any, theme: any, _kb: any, done: (r: AskAnswer[] | null) => void) => {
|
|
311
311
|
let optionIndex = 0;
|
|
312
312
|
let editMode = false;
|
|
@@ -65,7 +65,7 @@ function tokenizeCommand(cmd: string): { parts: string[]; ops: string[] } {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
// Operators: |, ||, &&, ;, >, >>, <
|
|
68
|
-
if (ch === "|" || ch === ";" || ch === "<" || ch === ">") {
|
|
68
|
+
if (ch === "|" || ch === ";" || ch === "<" || ch === ">" || ch === "&") {
|
|
69
69
|
if (current.trim()) parts.push(current.trim());
|
|
70
70
|
current = "";
|
|
71
71
|
|
|
@@ -304,7 +304,7 @@ async function promptRunOrAbort(ctx: any, command: string, risk: Risk): Promise<
|
|
|
304
304
|
{ value: "abort", label: "Abort", description: "Block this command" },
|
|
305
305
|
];
|
|
306
306
|
|
|
307
|
-
const choice = await ctx.ui.custom
|
|
307
|
+
const choice = await (ctx.ui as any).custom(
|
|
308
308
|
(tui, theme, _kb, done) => {
|
|
309
309
|
const container = new Container();
|
|
310
310
|
container.addChild(
|
|
@@ -14,12 +14,12 @@ import * as fs from "node:fs";
|
|
|
14
14
|
import * as path from "node:path";
|
|
15
15
|
|
|
16
16
|
type ExtensionAPI = {
|
|
17
|
-
on(event: string, handler: (event: unknown, ctx:
|
|
17
|
+
on(event: string, handler: (event: unknown, ctx: ReloadCtx) => void | Promise<void>): void;
|
|
18
18
|
registerCommand(
|
|
19
19
|
name: string,
|
|
20
20
|
options: {
|
|
21
21
|
description: string;
|
|
22
|
-
handler(args: string[], ctx:
|
|
22
|
+
handler(args: string[], ctx: ReloadCtx): unknown | Promise<unknown>;
|
|
23
23
|
},
|
|
24
24
|
): void;
|
|
25
25
|
};
|
|
@@ -35,11 +35,18 @@ function parseFrontMatter(text: string): string {
|
|
|
35
35
|
return text.slice(4, end);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
type ReloadUi = {
|
|
39
|
+
notify(message: string, level?: string): void;
|
|
40
|
+
setStatus(key: string, message: string | null): void;
|
|
41
|
+
theme?: { fg(role: string, text: string): string };
|
|
42
|
+
};
|
|
43
|
+
type ReloadCtx = { ui?: ReloadUi };
|
|
44
|
+
|
|
38
45
|
let lastKnownConfig = "";
|
|
39
46
|
let watcher: fs.FSWatcher | undefined;
|
|
40
47
|
let reloadCount = 0;
|
|
41
48
|
|
|
42
|
-
function startWatching(ctx:
|
|
49
|
+
function startWatching(ctx: ReloadCtx): void {
|
|
43
50
|
if (!fs.existsSync(CONFIG_FILE)) return;
|
|
44
51
|
|
|
45
52
|
lastKnownConfig = fs.readFileSync(CONFIG_FILE, "utf-8");
|
|
@@ -82,7 +89,7 @@ function stopWatching(): void {
|
|
|
82
89
|
}
|
|
83
90
|
|
|
84
91
|
export default function (pi: ExtensionAPI) {
|
|
85
|
-
pi.on("session_start", async (_event: unknown, ctx:
|
|
92
|
+
pi.on("session_start", async (_event: unknown, ctx: ReloadCtx) => {
|
|
86
93
|
stopWatching();
|
|
87
94
|
startWatching(ctx);
|
|
88
95
|
});
|
|
@@ -93,7 +100,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
93
100
|
|
|
94
101
|
pi.registerCommand("reload-config", {
|
|
95
102
|
description: "Manually reload workflow config from AGENTS.md",
|
|
96
|
-
handler: async (_args: string[], ctx:
|
|
103
|
+
handler: async (_args: string[], ctx: ReloadCtx) => {
|
|
97
104
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
98
105
|
ctx?.ui?.notify("No .pi/agent/AGENTS.md found.", "warning");
|
|
99
106
|
return;
|
|
@@ -24,7 +24,7 @@ type ExtensionContext = {
|
|
|
24
24
|
type ToolCallEvent = { toolName: string; toolCallId: string; input: { command: string } };
|
|
25
25
|
|
|
26
26
|
type ExtensionAPI = {
|
|
27
|
-
on(event: string, handler: (event: unknown, ctx: ExtensionContext) =>
|
|
27
|
+
on(event: string, handler: (event: unknown, ctx: ExtensionContext) => unknown | Promise<unknown>): void;
|
|
28
28
|
registerTool(options: {
|
|
29
29
|
name: string;
|
|
30
30
|
label: string;
|
|
@@ -34,7 +34,7 @@ type ExtensionAPI = {
|
|
|
34
34
|
toolCallId: string,
|
|
35
35
|
params: Record<string, unknown>,
|
|
36
36
|
signal: AbortSignal,
|
|
37
|
-
onUpdate: (update: { type
|
|
37
|
+
onUpdate: (update: { type?: string; message?: string; content?: unknown }) => void,
|
|
38
38
|
ctx: ExtensionContext,
|
|
39
39
|
): unknown | Promise<unknown>;
|
|
40
40
|
}): void;
|
|
@@ -464,6 +464,26 @@ export default function (pi: ExtensionAPI) {
|
|
|
464
464
|
addCheck("Glossary file", false, "Not found");
|
|
465
465
|
}
|
|
466
466
|
|
|
467
|
+
// 4b. ADR-008 modeling-depth rules (deterministic, over raw session JSON)
|
|
468
|
+
const depthRawPath = sessionPath.replace(/\.md$/, "") + ".raw.json";
|
|
469
|
+
const depthScript = path.join(ctx.cwd, ".pi", "scripts", "validate-exploration-depth.sh");
|
|
470
|
+
if (fs.existsSync(depthRawPath) && fs.existsSync(depthScript)) {
|
|
471
|
+
try {
|
|
472
|
+
const depthResult = await shellExec(ctx, "bash " + depthScript + " " + depthRawPath);
|
|
473
|
+
const lines = depthResult.stdout.trim().split("\n").filter((l) => l.trim() !== "");
|
|
474
|
+
const violations = lines.filter((l) => l.includes("[") && l.includes("] error:"));
|
|
475
|
+
addCheck(
|
|
476
|
+
"Modeling depth rules (ADR-008)",
|
|
477
|
+
depthResult.exitCode === 0,
|
|
478
|
+
violations.length > 0 ? violations.join(" | ") : lines.slice(-1)[0] || "",
|
|
479
|
+
);
|
|
480
|
+
} catch (err) {
|
|
481
|
+
addCheck("Modeling depth rules (ADR-008)", false, "Error: " + String(err));
|
|
482
|
+
}
|
|
483
|
+
} else {
|
|
484
|
+
addCheck("Modeling depth rules (ADR-008) - skipped", true, "no session raw.json");
|
|
485
|
+
}
|
|
486
|
+
|
|
467
487
|
// 4. Source code drift
|
|
468
488
|
const scriptPath = path.join(ctx.cwd, ".pi", "scripts", "validate-ubiquitous-language.sh");
|
|
469
489
|
if (fs.existsSync(scriptPath)) {
|
|
@@ -988,8 +1008,35 @@ export default function (pi: ExtensionAPI) {
|
|
|
988
1008
|
"- Current ADR-001: `.pi/architecture/decisions/ADR-001-architecture-pattern.md`",
|
|
989
1009
|
"- System diagram: `.pi/architecture/diagrams/system-context.md`",
|
|
990
1010
|
"- Module stubs: `.pi/architecture/modules/` (" + moduleFiles.length + " files)",
|
|
1011
|
+
"- ADR-008 modeling depth: `.pi/architecture/decisions/ADR-008-proportional-modeling-depth.md`",
|
|
1012
|
+
"- Structured session JSON (depth fields): `.pi/domain/exploration/" + sessionId + ".raw.json`",
|
|
991
1013
|
"",
|
|
992
|
-
"### STEP
|
|
1014
|
+
"### STEP 0: ADR-008 Modeling Depth (read first, applies everywhere)",
|
|
1015
|
+
"",
|
|
1016
|
+
"Read the `**Modeling Depth:**` header of EVERY module doc plus the structured",
|
|
1017
|
+
"session JSON (`.raw.json`). Enrich PROPORTIONALLY — never rewrite the depth header,",
|
|
1018
|
+
"never delete an existing `Modeling Depth Note (ADR-008)` section, and never invent",
|
|
1019
|
+
"modeling the exploration did not capture:",
|
|
1020
|
+
"",
|
|
1021
|
+
"- **tactical** (core subdomain): full DDD enrichment — aggregates as consistency",
|
|
1022
|
+
" boundaries with the exploration invariants (`rule` + illegalStatePrevented),",
|
|
1023
|
+
" behavior methods not setters, repository interface owned by the domain layer,",
|
|
1024
|
+
" value objects with entity-vs-VO justification, triaged domain events with payloads,",
|
|
1025
|
+
" and explicit domain / application / infrastructure service classification.",
|
|
1026
|
+
"- **service** (supporting subdomain): enrich to a Service + Persistence Contract.",
|
|
1027
|
+
" Do NOT expand aggregates, value objects, domain events, or API surfaces beyond",
|
|
1028
|
+
" what the exploration captured.",
|
|
1029
|
+
"- **adapter** (generic subdomain): enrich to an Interface + Anti-Corruption Layer —",
|
|
1030
|
+
" the narrow interface the domain consumes, the vendor/OSS choice, the ACL",
|
|
1031
|
+
" translation and its context-map edge. NO domain entities or aggregates.",
|
|
1032
|
+
"",
|
|
1033
|
+
"Language judgment: for Java/Spring modules apply the decision tables in the",
|
|
1034
|
+
"`java-spring-enterprise-codegen` skill section 10 (entity-vs-VO, service classifier,",
|
|
1035
|
+
"event triage, transaction placement — `@Transactional` only in application services).",
|
|
1036
|
+
"Diagrams and section breadth follow each module's depth (full module-level diagram",
|
|
1037
|
+
"set only for tactical; service = data-flow + sequence; adapter = ACL/integration).",
|
|
1038
|
+
"",
|
|
1039
|
+
"### STEP 1: Generate All ADRs",
|
|
993
1040
|
"",
|
|
994
1041
|
"**Do this first, before touching any module docs.** Module enrichment needs ADR references.",
|
|
995
1042
|
"",
|
|
@@ -1035,8 +1082,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
1035
1082
|
"1. **## Related ADRs** — Links to ADR files with descriptions of relevance",
|
|
1036
1083
|
"2. **## Diagrams** — Embed the 4 mermaid diagrams from Step 2",
|
|
1037
1084
|
"3. **## Acceptance Criteria** — Add a table row for each component: | # | Component | Criterion | Verify In | with specific, testable acceptance criteria",
|
|
1038
|
-
"5. **## Components** —
|
|
1039
|
-
"6. **Domain Events** — Table: Event, Description, Trigger, Payload, Published By",
|
|
1085
|
+
"5. **## Components** — depth-aware: for tactical modules expand aggregates with " + lang + " stubs, methods, exploration invariants, VO justifications and a domain/-owned repository interface; for service/adapter modules keep only what the Modeling Depth Note permits (no invented aggregates/VOs). Always keep `status:` and `depends:` markers",
|
|
1086
|
+
"6. **Domain Events** (tactical modules only) — Table: Event, Description, Trigger, Payload, Published By; include ADR-008 triage flags (domain expert cares / crosses boundary / audit trail)",
|
|
1040
1087
|
"7. **API Endpoints** — Table: Method, Path, Handler, Input, Output, Auth",
|
|
1041
1088
|
"8. **Ubiquitous Language** — Terms for this context from `.pi/domain/ubiquitous-language.md`",
|
|
1042
1089
|
"9. **Dependencies** — Depends On + Used By",
|
|
@@ -493,7 +493,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
493
493
|
})),
|
|
494
494
|
];
|
|
495
495
|
|
|
496
|
-
const picked = await ctx.ui.custom
|
|
496
|
+
const picked = await (ctx.ui as any).custom(
|
|
497
497
|
(tui, theme, _kb, done) => {
|
|
498
498
|
const container = new Container();
|
|
499
499
|
container.addChild(new DynamicBorder((s) => theme.fg("accent", s)));
|
|
@@ -546,7 +546,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
546
546
|
}
|
|
547
547
|
|
|
548
548
|
const md = `\`\`\`diff\n${t.diff.trimEnd() || "(no diff)"}\n\`\`\``;
|
|
549
|
-
await ctx.ui.custom
|
|
549
|
+
await (ctx.ui as any).custom(
|
|
550
550
|
(tui, theme, _kb, done) => {
|
|
551
551
|
const container = new Container();
|
|
552
552
|
container.addChild(new DynamicBorder((s) => theme.fg("accent", s)));
|
|
@@ -285,9 +285,9 @@ class GoalManager {
|
|
|
285
285
|
|
|
286
286
|
clear(): void {
|
|
287
287
|
if (!this.state) return;
|
|
288
|
-
this.
|
|
289
|
-
saveGoalState(this.cwd, this.
|
|
290
|
-
this.
|
|
288
|
+
this._state.status = "cleared";
|
|
289
|
+
saveGoalState(this.cwd, this._state);
|
|
290
|
+
this._state = null;
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
addSubgoal(textIn: string): string {
|
|
@@ -52,7 +52,7 @@ type ExtensionContext = {
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
type ExtensionAPI = {
|
|
55
|
-
on(event: string, handler: (event: unknown, ctx: ExtensionContext) =>
|
|
55
|
+
on(event: string, handler: (event: unknown, ctx: ExtensionContext) => unknown | Promise<unknown>): void;
|
|
56
56
|
registerTool(options: {
|
|
57
57
|
name: string;
|
|
58
58
|
label: string;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Ambient declarations for the pi runtime SDK. The host provides these at
|
|
2
|
+
// runtime with real types; not vendored here. Auto-generated names from
|
|
3
|
+
// actual imports across the extension sources so tsc type-checks cleanly.
|
|
4
|
+
|
|
5
|
+
declare module "@mariozechner/pi-coding-agent" {
|
|
6
|
+
export const DynamicBorder: any;
|
|
7
|
+
export type DynamicBorder = any;
|
|
8
|
+
export const ExtensionAPI: any;
|
|
9
|
+
export type ExtensionAPI = any;
|
|
10
|
+
export const ExtensionCommandContext: any;
|
|
11
|
+
export type ExtensionCommandContext = any;
|
|
12
|
+
export const ExtensionContext: any;
|
|
13
|
+
export type ExtensionContext = any;
|
|
14
|
+
export const createFindTool: any;
|
|
15
|
+
export type createFindTool = any;
|
|
16
|
+
export const createGrepTool: any;
|
|
17
|
+
export type createGrepTool = any;
|
|
18
|
+
export const createLsTool: any;
|
|
19
|
+
export type createLsTool = any;
|
|
20
|
+
export const createReadTool: any;
|
|
21
|
+
export type createReadTool = any;
|
|
22
|
+
export const getMarkdownTheme: any;
|
|
23
|
+
export type getMarkdownTheme = any;
|
|
24
|
+
export const isEditToolResult: any;
|
|
25
|
+
export type isEditToolResult = any;
|
|
26
|
+
export const isToolCallEventType: any;
|
|
27
|
+
export type isToolCallEventType = any;
|
|
28
|
+
export const isWriteToolResult: any;
|
|
29
|
+
export type isWriteToolResult = any;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare module "@mariozechner/pi-tui" {
|
|
33
|
+
export const Container: any;
|
|
34
|
+
export type Container = any;
|
|
35
|
+
export const Editor: any;
|
|
36
|
+
export type Editor = any;
|
|
37
|
+
export const EditorTheme: any;
|
|
38
|
+
export type EditorTheme = any;
|
|
39
|
+
export const Key: any;
|
|
40
|
+
export type Key = any;
|
|
41
|
+
export const Markdown: any;
|
|
42
|
+
export type Markdown = any;
|
|
43
|
+
export const SelectItem: any;
|
|
44
|
+
export type SelectItem = any;
|
|
45
|
+
export const SelectList: any;
|
|
46
|
+
export type SelectList = any;
|
|
47
|
+
export const Text: any;
|
|
48
|
+
export type Text = any;
|
|
49
|
+
export const matchesKey: any;
|
|
50
|
+
export type matchesKey = any;
|
|
51
|
+
export const truncateToWidth: any;
|
|
52
|
+
export type truncateToWidth = any;
|
|
53
|
+
export const wrapTextWithAnsi: any;
|
|
54
|
+
export type wrapTextWithAnsi = any;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
declare module "@earendil-works/pi-coding-agent" {
|
|
58
|
+
export const ExecResult: any;
|
|
59
|
+
export type ExecResult = any;
|
|
60
|
+
export const ExtensionAPI: any;
|
|
61
|
+
export type ExtensionAPI = any;
|
|
62
|
+
export const ExtensionContext: any;
|
|
63
|
+
export type ExtensionContext = any;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
declare module "typebox" {
|
|
67
|
+
export const Type: any;
|
|
68
|
+
export type Type = any;
|
|
69
|
+
export const Static: any;
|
|
70
|
+
export type Static = any;
|
|
71
|
+
export const TObject: any;
|
|
72
|
+
export type TObject = any;
|
|
73
|
+
export const TSchema: any;
|
|
74
|
+
export type TSchema = any;
|
|
75
|
+
export const TProperties: any;
|
|
76
|
+
export type TProperties = any;
|
|
77
|
+
export const TString: any;
|
|
78
|
+
export type TString = any;
|
|
79
|
+
export const TArray: any;
|
|
80
|
+
export type TArray = any;
|
|
81
|
+
export const TOptional: any;
|
|
82
|
+
export type TOptional = any;
|
|
83
|
+
export const TBoolean: any;
|
|
84
|
+
export type TBoolean = any;
|
|
85
|
+
export const TNumber: any;
|
|
86
|
+
export type TNumber = any;
|
|
87
|
+
export const TUnion: any;
|
|
88
|
+
export type TUnion = any;
|
|
89
|
+
export const TLiteral: any;
|
|
90
|
+
export type TLiteral = any;
|
|
91
|
+
export const TRecord: any;
|
|
92
|
+
export type TRecord = any;
|
|
93
|
+
export const TAny: any;
|
|
94
|
+
export type TAny = any;
|
|
95
|
+
}
|
|
96
|
+
declare module "@sinclair/typebox" { export const Type: any; export type Static = any; }
|
|
@@ -256,7 +256,7 @@ class PipelineManager {
|
|
|
256
256
|
* Reload pipeline state from disk, discarding any cached in-memory state.
|
|
257
257
|
* Use this when another extension (e.g., architect) may have written state directly.
|
|
258
258
|
*/
|
|
259
|
-
|
|
259
|
+
reloadFromDisk(): void {
|
|
260
260
|
this.state = loadPipelineState(this.cwd);
|
|
261
261
|
}
|
|
262
262
|
|
|
@@ -25,6 +25,8 @@ import {
|
|
|
25
25
|
const COMMAND_NAME = "read-only";
|
|
26
26
|
const STATUS_KEY = "read-only-mode";
|
|
27
27
|
const WIDGET_KEY = "read-only-mode";
|
|
28
|
+
let readOnlyActive = false;
|
|
29
|
+
|
|
28
30
|
const READ_ONLY_TOOL_NAMES = ["read", "grep", "find", "ls"] as const;
|
|
29
31
|
|
|
30
32
|
function getReadOnlyToolNames(pi: ExtensionAPI): string[] {
|
|
@@ -95,6 +97,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
95
97
|
});
|
|
96
98
|
|
|
97
99
|
function enable(ctx: ExtensionContext): void {
|
|
100
|
+
readOnlyActive = true;
|
|
98
101
|
if (enabled) {
|
|
99
102
|
updateUi(pi, ctx, enabled);
|
|
100
103
|
ctx.ui.notify("Read-only mode is already enabled.", "info");
|
|
@@ -111,6 +114,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
111
114
|
}
|
|
112
115
|
|
|
113
116
|
function disable(ctx: ExtensionContext): void {
|
|
117
|
+
readOnlyActive = false;
|
|
114
118
|
if (!enabled) {
|
|
115
119
|
updateUi(pi, ctx, enabled);
|
|
116
120
|
ctx.ui.notify("Read-only mode is already disabled.", "info");
|
|
@@ -130,7 +134,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
130
134
|
switch (action) {
|
|
131
135
|
case "":
|
|
132
136
|
case "toggle":
|
|
133
|
-
|
|
137
|
+
if (readOnlyActive) disable(ctx); else enable(ctx);
|
|
134
138
|
return;
|
|
135
139
|
case "on":
|
|
136
140
|
case "enable":
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
"types": [
|
|
3
|
+
"types": [
|
|
4
|
+
"bun-types"
|
|
5
|
+
],
|
|
4
6
|
"strict": true,
|
|
7
|
+
"noImplicitAny": false,
|
|
8
|
+
"strictNullChecks": false,
|
|
5
9
|
"target": "ES2022",
|
|
6
10
|
"module": "ESNext",
|
|
7
11
|
"moduleResolution": "bundler",
|
|
@@ -11,5 +15,8 @@
|
|
|
11
15
|
"isolatedModules": true,
|
|
12
16
|
"allowImportingTsExtensions": true
|
|
13
17
|
},
|
|
14
|
-
"include": [
|
|
18
|
+
"include": [
|
|
19
|
+
"**/*.ts",
|
|
20
|
+
"**/*.d.ts"
|
|
21
|
+
]
|
|
15
22
|
}
|
|
@@ -72,7 +72,7 @@ Language-specific linting.
|
|
|
72
72
|
| `unit_application` | `pytest tests/unit/application` | No |
|
|
73
73
|
| `unit_contract` | `pytest tests/contract` | No |
|
|
74
74
|
| `unit_verification` | `pytest tests/verification` | No |
|
|
75
|
-
| `
|
|
75
|
+
| `coverage_gate` | `bash .pi/scripts/install_coverage_tools.sh && bash .pi/scripts/coverage.sh --gate --lcov` | No |
|
|
76
76
|
|
|
77
77
|
## Stage 6: Integration
|
|
78
78
|
|
|
@@ -119,7 +119,7 @@ Language-specific linting.
|
|
|
119
119
|
| Rule | Jobs Using It |
|
|
120
120
|
|------|---------------|
|
|
121
121
|
| `rules_default` (MRs or main branch) | Most jobs |
|
|
122
|
-
| `rules_sonar` (requires `$SONAR_TOKEN` + `$SONAR_HOST_URL`) |
|
|
122
|
+
| `rules_sonar` (requires `$SONAR_TOKEN` + `$SONAR_HOST_URL`) | coverage_gate (uploads lcov artifact), sonar_quality_gate |
|
|
123
123
|
| `rules_main_only` | `package_build` |
|
|
124
124
|
| `rules_migration_changes` (migration file changes only) | `migration_verify` stage |
|
|
125
125
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# check_model_judgment.sh — ADR-008/009 dispatcher
|
|
4
|
+
# Runs the language-scoped model-judgment hard gates (dip-domain,
|
|
5
|
+
# interface-ownership, adapter-purity, transaction placement per language).
|
|
6
|
+
# Usage: bash .pi/scripts/check_model_judgment.sh [--root <dir>]
|
|
7
|
+
# ============================================================================
|
|
8
|
+
set -uo pipefail
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
10
|
+
ROOT="$(pwd)"
|
|
11
|
+
if [ "${1:-}" = "--root" ] && [ -n "${2:-}" ]; then ROOT="$2"; fi
|
|
12
|
+
cd "$ROOT" || exit 1
|
|
13
|
+
|
|
14
|
+
detect_language() {
|
|
15
|
+
if [ -f "Cargo.lock" ] || [ -f "Cargo.toml" ]; then echo "rust"
|
|
16
|
+
elif [ -f "package.json" ]; then echo "typescript"
|
|
17
|
+
elif [ -f "go.mod" ]; then echo "go"
|
|
18
|
+
elif [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then echo "python"
|
|
19
|
+
elif [ -f "pom.xml" ] || [ -f "build.gradle" ]; then echo "java"
|
|
20
|
+
else echo "unknown"; fi
|
|
21
|
+
}
|
|
22
|
+
LANG="$(detect_language)"
|
|
23
|
+
SCRIPT="${SCRIPT_DIR}/languages/${LANG}/check_model_judgment.sh"
|
|
24
|
+
if [ -f "$SCRIPT" ]; then
|
|
25
|
+
exec bash "$SCRIPT" --root "$ROOT"
|
|
26
|
+
fi
|
|
27
|
+
echo "model-judgment: no gate script for language '${LANG}'"
|
|
28
|
+
exit 0
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# check_judgment_contracts.sh — proofing for ADR-008 P1 (judgment-aware
|
|
4
|
+
# modeling). Deterministic proof that each frozen contract (§1–§7 of
|
|
5
|
+
# .pi/architecture/contracts/judgment-aware-modeling-p1.md) is implemented
|
|
6
|
+
# in the framework sources.
|
|
7
|
+
#
|
|
8
|
+
# Checks:
|
|
9
|
+
# 1. exploration prompt emits ADR-008 schema markers (src)
|
|
10
|
+
# 2. validate-exploration-depth.sh exists + executable
|
|
11
|
+
# 3. java model-judgment gate exists + executable
|
|
12
|
+
# 4. module-doc scaffold emits 'Modeling Depth' header (src)
|
|
13
|
+
# 5. java-spring codegen skill carries 'Judgment Tables (ADR-008)'
|
|
14
|
+
# 6. architecture-validator skill carries Model Judgment Review R1-R4
|
|
15
|
+
# 7. modeling contracts: ModuleComponent type carries the ADR-008 fields
|
|
16
|
+
# 8. exploration.md template carries the Modeling Judgment section
|
|
17
|
+
#
|
|
18
|
+
# Exit 0 = all contracts proven; 1 = at least one missing.
|
|
19
|
+
# ============================================================================
|
|
20
|
+
set -uo pipefail
|
|
21
|
+
|
|
22
|
+
ROOT="$(pwd)"
|
|
23
|
+
if [ "${1:-}" = "--root" ] && [ -n "${2:-}" ]; then ROOT="$2"; fi
|
|
24
|
+
cd "$ROOT" || exit 1
|
|
25
|
+
|
|
26
|
+
FAILED=0
|
|
27
|
+
PASSED=0
|
|
28
|
+
|
|
29
|
+
check() { # label, file-or-dir, grep pattern
|
|
30
|
+
local label="$1" path="$2" pattern="$3"
|
|
31
|
+
if [ -n "$path" ] && [ -e "$path" ] && grep -qE "$pattern" "$path" 2>/dev/null; then
|
|
32
|
+
echo " PASS: $label"
|
|
33
|
+
PASSED=$((PASSED + 1))
|
|
34
|
+
else
|
|
35
|
+
echo " FAIL: $label (missing: $path / $pattern)" >&2
|
|
36
|
+
FAILED=$((FAILED + 1))
|
|
37
|
+
fi
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
check_file() { # label file
|
|
41
|
+
if [ -f "$2" ] && [ -x "$2" ]; then
|
|
42
|
+
echo " PASS: $1"
|
|
43
|
+
PASSED=$((PASSED + 1))
|
|
44
|
+
else
|
|
45
|
+
echo " FAIL: $1 (not found/executable: $2)" >&2
|
|
46
|
+
FAILED=$((FAILED + 1))
|
|
47
|
+
fi
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
echo "Judgment contracts proofing (ADR-008 P1)"
|
|
51
|
+
echo "----------------------------------------"
|
|
52
|
+
|
|
53
|
+
# 1. exploration prompt schema markers
|
|
54
|
+
check "exploration prompt: subdomainType/invariants/triage/contextMap/conflicts" \
|
|
55
|
+
"src/lib/domain-explorer.ts" 'subdomainType|"invariants"|"triage"|"contextMap"|"conflicts"'
|
|
56
|
+
|
|
57
|
+
# 2. depth validator present + executable
|
|
58
|
+
check_file "validate-exploration-depth.sh executable" ".pi/scripts/validate-exploration-depth.sh"
|
|
59
|
+
check_file "validate-exploration-depth.sh (templates copy)" "templates/pi/scripts/validate-exploration-depth.sh"
|
|
60
|
+
|
|
61
|
+
# 3. java model-judgment gate present + executable
|
|
62
|
+
check_file "java model-judgment gate" ".pi/scripts/languages/java/check_model_judgment.sh"
|
|
63
|
+
check_file "java model-judgment gate (templates copy)" "templates/pi/scripts/languages/java/check_model_judgment.sh"
|
|
64
|
+
|
|
65
|
+
# 4. scaffold emits Modeling Depth header + invariants + depth note
|
|
66
|
+
check "scaffold: Modeling Depth header" "src/lib/domain-explorer.ts" 'Modeling Depth'
|
|
67
|
+
check "scaffold: depth note for service/adapter" "src/lib/domain-explorer.ts" 'Modeling Depth Note \(ADR-008\)'
|
|
68
|
+
|
|
69
|
+
# 5. java-spring codegen skill: judgment tables
|
|
70
|
+
check "java-spring skill: Judgment Tables (ADR-008)" \
|
|
71
|
+
".pi/skills/java-spring-enterprise-codegen.md" 'Judgment Tables \(ADR-008\)'
|
|
72
|
+
|
|
73
|
+
# 6. architecture-validator skill: R1-R4 review questions
|
|
74
|
+
check "architecture-validator skill: Model Judgment Review" \
|
|
75
|
+
".pi/skills/agents/architecture-validator.md" 'Model Judgment Review'
|
|
76
|
+
|
|
77
|
+
# 7. ModuleComponent modeling-contract fields
|
|
78
|
+
check "architect-lib types: modelingDepth/aggregateRoot/invariants/events" \
|
|
79
|
+
".pi/extensions/architect-lib/types.ts" 'modelingDepth|aggregateRoot|invariants|publishes'
|
|
80
|
+
check "generators: Modeling Contract emission" \
|
|
81
|
+
".pi/extensions/architect-lib/generators.ts" 'Modeling Contract \(ADR-008\)'
|
|
82
|
+
|
|
83
|
+
# 8. exploration.md template: Modeling Judgment section
|
|
84
|
+
check "exploration.md template: Modeling Judgment section" \
|
|
85
|
+
"templates/pi/domain/exploration.md" 'Modeling Judgment \(ADR-008\)'
|
|
86
|
+
|
|
87
|
+
echo ""
|
|
88
|
+
echo " Passed: $PASSED Failed: $FAILED"
|
|
89
|
+
if [ "$FAILED" -gt 0 ]; then
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
echo "All judgment contracts proven."
|
|
93
|
+
exit 0
|
|
@@ -255,10 +255,10 @@ run_stage_lint() {
|
|
|
255
255
|
log_fail "biome check" "lint errors found" "$(( $(date +%s) - t ))"
|
|
256
256
|
fi
|
|
257
257
|
t=$(date +%s)
|
|
258
|
-
if biome
|
|
259
|
-
log_pass "biome
|
|
258
|
+
if biome ci . >/dev/null 2>&1; then
|
|
259
|
+
log_pass "biome ci" "$(( $(date +%s) - t ))"
|
|
260
260
|
else
|
|
261
|
-
log_fail "biome
|
|
261
|
+
log_fail "biome ci" "format errors found" "$(( $(date +%s) - t ))"
|
|
262
262
|
fi
|
|
263
263
|
else
|
|
264
264
|
log_skip "biome" "not installed"
|
|
@@ -76,7 +76,7 @@ case "$STAGE" in
|
|
|
76
76
|
ruff check . && ruff format --check .
|
|
77
77
|
elif [[ -f "package.json" ]]; then
|
|
78
78
|
echo "TypeScript project detected"
|
|
79
|
-
biome check . && biome
|
|
79
|
+
biome check . && biome ci .
|
|
80
80
|
elif [[ -f "Cargo.toml" ]]; then
|
|
81
81
|
echo "Rust project detected"
|
|
82
82
|
cargo clippy -- -D warnings && cargo fmt --check
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# coverage.sh — Real project coverage measurement + gate (dispatcher)
|
|
4
|
+
#
|
|
5
|
+
# Runs the project's REAL coverage tool for the detected language and reports
|
|
6
|
+
# line coverage. This is the honest replacement for the old per-module
|
|
7
|
+
# heuristic `*_coverage.sh` checks (coverage-theater — they counted test
|
|
8
|
+
# functions via grep, never a real percentage).
|
|
9
|
+
#
|
|
10
|
+
# Delegates to languages/<lang>/coverage.sh. Real coverage tool per language:
|
|
11
|
+
# rust — cargo llvm-cov (workspace line coverage, lcov artifact)
|
|
12
|
+
# python — coverage.py (pytest/unittest)
|
|
13
|
+
# typescript — vitest / jest / bun test --coverage (istanbul text)
|
|
14
|
+
# go — go test -coverprofile + go tool cover
|
|
15
|
+
# java — JaCoCo (maven/gradle)
|
|
16
|
+
#
|
|
17
|
+
# Usage:
|
|
18
|
+
# bash .pi/scripts/coverage.sh # measure + print summary
|
|
19
|
+
# bash .pi/scripts/coverage.sh --gate # exit 1 if lines < COVERAGE_THRESHOLD
|
|
20
|
+
# bash .pi/scripts/coverage.sh --lcov # also emit the tool's report artifact
|
|
21
|
+
#
|
|
22
|
+
# Env:
|
|
23
|
+
# COVERAGE_THRESHOLD minimum line-coverage % (default: 60 — a conservative
|
|
24
|
+
# floor; set it to the threshold your CI actually enforces)
|
|
25
|
+
#
|
|
26
|
+
# Exit codes:
|
|
27
|
+
# 0 — measured and (with --gate) meets threshold, or language not applicable
|
|
28
|
+
# 1 — coverage tool missing / below threshold / could not measure (honest
|
|
29
|
+
# fail — never fake-pass)
|
|
30
|
+
# 2 — unknown argument
|
|
31
|
+
# ============================================================================
|
|
32
|
+
set -uo pipefail
|
|
33
|
+
|
|
34
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
35
|
+
|
|
36
|
+
detect_language() {
|
|
37
|
+
if [ -f "Cargo.lock" ] || [ -f "Cargo.toml" ]; then echo "rust"
|
|
38
|
+
elif [ -f "poetry.lock" ] || [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then echo "python"
|
|
39
|
+
elif [ -f "go.mod" ]; then echo "go"
|
|
40
|
+
elif [ -f "package.json" ]; then echo "typescript"
|
|
41
|
+
elif [ -f "pom.xml" ] || [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then echo "java"
|
|
42
|
+
else echo "unknown"; fi
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
LANG="$(detect_language)"
|
|
46
|
+
|
|
47
|
+
if [ "$LANG" = "unknown" ]; then
|
|
48
|
+
echo "⚠️ No project language detected — no real coverage gate applies." >&2
|
|
49
|
+
exit 0
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
LANG_SCRIPT="${SCRIPT_DIR}/languages/${LANG}/coverage.sh"
|
|
53
|
+
if [ ! -f "$LANG_SCRIPT" ]; then
|
|
54
|
+
echo "⚠️ No coverage gate script for '${LANG}' yet (${LANG_SCRIPT})." >&2
|
|
55
|
+
exit 0
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
exec bash "$LANG_SCRIPT" "$@"
|