guardian-framework 0.1.52 → 0.1.54
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/cli.js +2174 -1207
- package/dist/exports.js +2173 -1206
- package/package.json +6 -7
- package/templates/pi/extensions/architect.ts +352 -3
- package/templates/pi/extensions/ask-user-question.ts +3 -0
- package/templates/pi/extensions/bash-guard.ts +18 -3
- package/templates/pi/extensions/config-reload.ts +3 -0
- package/templates/pi/extensions/coordinator.ts +25 -72
- package/templates/pi/extensions/curator.ts +3 -0
- package/templates/pi/extensions/filechanges.ts +3 -0
- package/templates/pi/extensions/goal-loop.ts +14 -7
- package/templates/pi/extensions/hooks.ts +3 -0
- package/templates/pi/extensions/kanban.ts +3 -0
- package/templates/pi/extensions/plan-mode.ts +3 -0
- package/templates/pi/extensions/project-scaffolder.ts +2 -15
- package/templates/pi/extensions/read-only-mode.ts +3 -0
- package/templates/pi/extensions/redaction.ts +9 -0
- package/templates/pi/extensions/session-persistence.ts +3 -0
- package/templates/pi/extensions/slash-commands.ts +3 -0
- package/templates/pi/extensions/snippets.ts +7 -1
- package/templates/pi/extensions/validation-runner.ts +66 -10
- package/templates/pi/preflight_report.json +1 -1
- package/templates/pi/validators/default.toml +11 -8
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Canonical Reference: .pi/architecture/modules/core-libraries.md
|
|
3
|
+
* Last Sync: 2026-05-31
|
|
4
|
+
|
|
2
5
|
* Goal Loop Extension for pi
|
|
3
6
|
*
|
|
4
7
|
* Persistent standing goals with validator-backed judge.
|
|
@@ -151,7 +154,10 @@ const BUILTIN_VALIDATORS: Record<string, string> = {
|
|
|
151
154
|
integration: ".pi/scripts/validate-integration.sh",
|
|
152
155
|
};
|
|
153
156
|
|
|
154
|
-
/**
|
|
157
|
+
/**
|
|
158
|
+
* Canonical Reference: .pi/architecture/modules/core-libraries.md
|
|
159
|
+
* Last Sync: 2026-05-31
|
|
160
|
+
Discover custom validators from `.pi/scripts/validate-*.sh` */
|
|
155
161
|
function discoverCustomValidators(cwd: string): Record<string, string> {
|
|
156
162
|
const scriptsDir = join(cwd, ".pi/scripts");
|
|
157
163
|
if (!existsSync(scriptsDir)) return {};
|
|
@@ -230,15 +236,16 @@ async function runLLMJudge(
|
|
|
230
236
|
|
|
231
237
|
const prompt = `Goal:\n${truncatedGoal}\n${subgoalsBlock}\n\nAgent's most recent response:\n${truncatedResponse}\n\nIs the goal satisfied?`;
|
|
232
238
|
|
|
233
|
-
//
|
|
239
|
+
// Use guardian_coordinate to run an LLM-based judgment
|
|
234
240
|
try {
|
|
235
|
-
await ctx.
|
|
241
|
+
const result = await ctx.tools.execute("guardian_scope", {});
|
|
242
|
+
// We can't directly call LLM from extension — instead return a heuristic judgment
|
|
243
|
+
// The LLM judge runs via the agent itself being prompted to self-assess
|
|
244
|
+
// For now, return continue to let the agent decide
|
|
245
|
+
return { done: false, reason: "LLM judge requires agent self-assessment turn" };
|
|
236
246
|
} catch {
|
|
237
|
-
|
|
247
|
+
return { done: false, reason: "judge unavailable, continuing" };
|
|
238
248
|
}
|
|
239
|
-
// The LLM judge runs via the agent itself being prompted to self-assess
|
|
240
|
-
// For now, return continue to let the agent decide
|
|
241
|
-
return { done: false, reason: "LLM judge requires agent self-assessment turn" };
|
|
242
249
|
}
|
|
243
250
|
|
|
244
251
|
function truncate(text: string, limit: number): string {
|
|
@@ -20,8 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import { type ExecSyncOptions, execSync } from "node:child_process";
|
|
23
|
-
import { existsSync,
|
|
24
|
-
import * as path from "node:path";
|
|
23
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
25
24
|
import { join } from "node:path";
|
|
26
25
|
|
|
27
26
|
// ── Types ──
|
|
@@ -151,19 +150,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
151
150
|
|
|
152
151
|
const lang = String(parsed.lang || parsed.language || "").toLowerCase();
|
|
153
152
|
const buildTool = String(parsed.buildTool || "").toLowerCase() || undefined;
|
|
154
|
-
|
|
155
|
-
// Read groupId from manifest if not passed via CLI (matches guardian CLI behavior)
|
|
156
|
-
let groupId = String(parsed.groupId || parsed.group || "");
|
|
157
|
-
if (!groupId) {
|
|
158
|
-
try {
|
|
159
|
-
const manifestPath = path.join(ctx.cwd, "guardian-manifest.json");
|
|
160
|
-
if (fs.existsSync(manifestPath)) {
|
|
161
|
-
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
162
|
-
groupId = manifest.groupId || "";
|
|
163
|
-
}
|
|
164
|
-
} catch { /* ignore malformed manifest */ }
|
|
165
|
-
}
|
|
166
|
-
if (!groupId) groupId = "com.example";
|
|
153
|
+
const groupId = String(parsed.groupId || parsed.group || "com.example");
|
|
167
154
|
const validators = String(parsed.validators || "ci,tests");
|
|
168
155
|
const dryRun = parsed.dryRun === true || parsed["dry-run"] === true || parsed.d === true;
|
|
169
156
|
const force = parsed.force === true || parsed.f === true;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Canonical Reference: .pi/architecture/modules/core-libraries.md
|
|
3
|
+
* Last Sync: 2026-05-31
|
|
4
|
+
|
|
2
5
|
* Redaction Extension for pi
|
|
3
6
|
*
|
|
4
7
|
* Automatically redacts sensitive data from tool results, terminal output,
|
|
@@ -40,6 +43,9 @@ const PATTERNS: Array<{ kind: string; re: RegExp }> = [
|
|
|
40
43
|
];
|
|
41
44
|
|
|
42
45
|
/**
|
|
46
|
+
* Canonical Reference: .pi/architecture/modules/core-libraries.md
|
|
47
|
+
* Last Sync: 2026-05-31
|
|
48
|
+
|
|
43
49
|
* Redact sensitive data from text. Returns the redacted string.
|
|
44
50
|
*/
|
|
45
51
|
export function redactSensitive(text: string): string {
|
|
@@ -58,6 +64,9 @@ export function redactSensitive(text: string): string {
|
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
/**
|
|
67
|
+
* Canonical Reference: .pi/architecture/modules/core-libraries.md
|
|
68
|
+
* Last Sync: 2026-05-31
|
|
69
|
+
|
|
61
70
|
* Count redactions made (for logging/telemetry-free reporting).
|
|
62
71
|
*/
|
|
63
72
|
export function countRedactions(text: string): number {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Canonical Reference: .pi/architecture/modules/core-libraries.md
|
|
3
|
+
* Last Sync: 2026-05-31
|
|
4
|
+
|
|
2
5
|
* Snippets Extension for pi
|
|
3
6
|
*
|
|
4
7
|
* Manages reusable prompt fragments (snippets) that can be referenced via
|
|
@@ -57,7 +60,10 @@ function normalizeHandle(raw: string): string {
|
|
|
57
60
|
.replace(/^-+|-+$/g, "");
|
|
58
61
|
}
|
|
59
62
|
|
|
60
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* Canonical Reference: .pi/architecture/modules/core-libraries.md
|
|
65
|
+
* Last Sync: 2026-05-31
|
|
66
|
+
Expand #handle tokens in text, returning the body with tokens stripped and snippet XML blocks. */
|
|
61
67
|
function expandSnippetTokens(
|
|
62
68
|
text: string,
|
|
63
69
|
snippets: readonly Snippet[],
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Canonical Reference: .pi/architecture/modules/core-libraries.md
|
|
3
|
+
* Last Sync: 2026-06-02
|
|
4
|
+
|
|
2
5
|
* Validation Runner Extension for pi
|
|
3
6
|
*
|
|
4
7
|
* Runs validation scripts as pi tools and commands.
|
|
8
|
+
* Supports language-specific validators from scripts/languages/{lang}/.
|
|
5
9
|
* See coordinator.ts for guardian_scope and guardian_validate tools.
|
|
6
10
|
*/
|
|
7
11
|
|
|
12
|
+
import * as fs from "node:fs";
|
|
13
|
+
import * as path from "node:path";
|
|
14
|
+
|
|
8
15
|
type ShellResult = {
|
|
9
16
|
exitCode: number;
|
|
10
17
|
stdout: string;
|
|
@@ -12,6 +19,7 @@ type ShellResult = {
|
|
|
12
19
|
};
|
|
13
20
|
|
|
14
21
|
type ExtensionContext = {
|
|
22
|
+
cwd: string;
|
|
15
23
|
ui: { notify(message: string, level?: string): void };
|
|
16
24
|
shell: { execute(command: string, options?: { signal?: AbortSignal }): Promise<ShellResult> };
|
|
17
25
|
tools: { execute(name: string, params: Record<string, unknown>): Promise<unknown> };
|
|
@@ -41,7 +49,7 @@ type ExtensionAPI = {
|
|
|
41
49
|
): void;
|
|
42
50
|
};
|
|
43
51
|
|
|
44
|
-
const
|
|
52
|
+
const BASE_VALIDATORS: Record<string, string> = {
|
|
45
53
|
architecture: ".pi/scripts/validate-architecture.sh",
|
|
46
54
|
canonical: ".pi/scripts/validate-canonical.sh",
|
|
47
55
|
ci: ".pi/scripts/validate-ci.sh",
|
|
@@ -49,34 +57,82 @@ const VALIDATORS = {
|
|
|
49
57
|
operations: ".pi/scripts/validate-operations.sh",
|
|
50
58
|
security: ".pi/scripts/validate-security.sh",
|
|
51
59
|
tests: ".pi/scripts/validate-tests.sh",
|
|
52
|
-
}
|
|
60
|
+
};
|
|
53
61
|
|
|
54
|
-
type ValidatorName =
|
|
62
|
+
type ValidatorName = string;
|
|
55
63
|
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Get the project language from the manifest, if available.
|
|
66
|
+
*/
|
|
67
|
+
function getProjectLanguage(cwd: string): string | null {
|
|
68
|
+
try {
|
|
69
|
+
const manifestPath = path.join(cwd, "guardian-manifest.json");
|
|
70
|
+
if (fs.existsSync(manifestPath)) {
|
|
71
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
72
|
+
return manifest.language || null;
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
// Ignore parse errors
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Discover language-specific validators from scripts/languages/{lang}/ directory.
|
|
82
|
+
*/
|
|
83
|
+
function getLanguageValidators(cwd: string, language: string | null): Record<string, string> {
|
|
84
|
+
if (!language) return {};
|
|
85
|
+
|
|
86
|
+
const langDir = path.join(cwd, `.pi/scripts/languages/${language}`);
|
|
87
|
+
if (!fs.existsSync(langDir)) return {};
|
|
88
|
+
|
|
89
|
+
const validators: Record<string, string> = {};
|
|
90
|
+
try {
|
|
91
|
+
const files = fs.readdirSync(langDir);
|
|
92
|
+
for (const file of files) {
|
|
93
|
+
if (file.endsWith(".sh")) {
|
|
94
|
+
const name = file.replace("validate-", "").replace(".sh", "");
|
|
95
|
+
validators[`${language}:${name}`] = `.pi/scripts/languages/${language}/${file}`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} catch {
|
|
99
|
+
// Ignore read errors
|
|
100
|
+
}
|
|
101
|
+
return validators;
|
|
58
102
|
}
|
|
59
103
|
|
|
60
104
|
export default function (pi: ExtensionAPI) {
|
|
61
|
-
|
|
105
|
+
let language: string | null = null;
|
|
106
|
+
|
|
107
|
+
// Session initialization — detect project language
|
|
62
108
|
pi.on("session_start", async (_event, ctx) => {
|
|
63
|
-
ctx.
|
|
109
|
+
language = getProjectLanguage(ctx.cwd);
|
|
110
|
+
if (language) {
|
|
111
|
+
ctx.ui.notify(`Guardian validation runner initialized (language: ${language})`, "info");
|
|
112
|
+
} else {
|
|
113
|
+
ctx.ui.notify("Guardian validation runner initialized", "info");
|
|
114
|
+
}
|
|
64
115
|
});
|
|
65
116
|
|
|
66
117
|
// Register validate command — runs scripts directly via shell
|
|
67
118
|
pi.registerCommand("validate", {
|
|
68
119
|
description: "Run all or specific validators",
|
|
69
120
|
handler: async (args, ctx) => {
|
|
121
|
+
// Build full validator map (base + language-specific)
|
|
122
|
+
const langValidators = getLanguageValidators(ctx.cwd, language);
|
|
123
|
+
const allValidators = { ...BASE_VALIDATORS, ...langValidators };
|
|
124
|
+
|
|
70
125
|
const validators =
|
|
71
126
|
args.length > 0
|
|
72
|
-
? args.filter(
|
|
73
|
-
:
|
|
127
|
+
? args.filter((v) => Object.hasOwn(allValidators, v))
|
|
128
|
+
: Object.keys(allValidators);
|
|
129
|
+
|
|
74
130
|
ctx.ui.notify(`Running validators: ${validators.join(", ")}`, "info");
|
|
75
131
|
|
|
76
132
|
const results: Record<string, { passed: boolean; output: string }> = {};
|
|
77
133
|
|
|
78
134
|
for (const validator of validators) {
|
|
79
|
-
const scriptPath =
|
|
135
|
+
const scriptPath = allValidators[validator];
|
|
80
136
|
try {
|
|
81
137
|
const result = await ctx.shell.execute(`bash ${scriptPath}`);
|
|
82
138
|
results[validator] = {
|
|
@@ -178,6 +178,17 @@ keep_lines_matching = ["FAILED", "error", "timeout", "connection refused", "asse
|
|
|
178
178
|
max_lines = 80
|
|
179
179
|
on_empty = "✅ All integration tests passed"
|
|
180
180
|
|
|
181
|
+
# ── Ubiquitous Language Validator ────────────────────────────────────────────
|
|
182
|
+
|
|
183
|
+
[filters.ubiquitous-language]
|
|
184
|
+
command = "validate-ubiquitous-language"
|
|
185
|
+
description = "Detect code drift from .pi/domain/ubiquitous-language.md glossary"
|
|
186
|
+
# Run: bash .pi/scripts/validate-ubiquitous-language.sh [src_dir]
|
|
187
|
+
strip_ansi = false
|
|
188
|
+
keep_lines_matching = ["❌ FAIL", "⚠️ WARN", "Drift:", "alias", "canonical", "Variation"]
|
|
189
|
+
max_lines = 80
|
|
190
|
+
on_empty = "✅ No drift detected"
|
|
191
|
+
|
|
181
192
|
# ── Git Status Validator ────────────────────────────────────────────────────
|
|
182
193
|
|
|
183
194
|
[filters.git-status]
|
|
@@ -199,11 +210,3 @@ strip_ansi = true
|
|
|
199
210
|
head_lines = 1
|
|
200
211
|
truncate_lines_at = 120
|
|
201
212
|
max_lines = 30
|
|
202
|
-
|
|
203
|
-
# ── Ubiquitous Language Validator ────────────────────────────────────────────
|
|
204
|
-
|
|
205
|
-
[filters.ubiquitous-language]
|
|
206
|
-
command = "validate-ubiquitous-language"
|
|
207
|
-
description = "Detect code drift from .pi/domain/ubiquitous-language.md glossary"
|
|
208
|
-
strip_ansi = false
|
|
209
|
-
keep_lines_matching = ["FAIL", "WARN", "Drift:", "alias", "canonical"]
|