guardian-framework 0.1.3 → 0.1.5

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 CHANGED
@@ -1335,7 +1335,7 @@ __export(exports_package, {
1335
1335
  bin: () => bin,
1336
1336
  author: () => author
1337
1337
  });
1338
- var name = "guardian-framework", version = "0.1.3", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
1338
+ var name = "guardian-framework", version = "0.1.5", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
1339
1339
  var init_package = __esm(() => {
1340
1340
  exports = {
1341
1341
  ".": {
package/dist/exports.js CHANGED
@@ -995,7 +995,7 @@ __export(exports_package, {
995
995
  bin: () => bin,
996
996
  author: () => author
997
997
  });
998
- var name = "guardian-framework", version = "0.1.3", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
998
+ var name = "guardian-framework", version = "0.1.5", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
999
999
  var init_package = __esm(() => {
1000
1000
  exports = {
1001
1001
  ".": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "guardian-framework",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Token-optimized agentic framework scaffolder with pi-first architecture",
5
5
  "type": "module",
6
6
  "main": "dist/exports.js",
@@ -76,6 +76,7 @@ delegation:
76
76
  3. **Architecture traceability** — Every implementation file must reference its architecture source in `.pi/architecture/modules/`.
77
77
  4. **DRY context** — Shared knowledge lives in `.pi/context/`, not scattered across agent files.
78
78
  5. **Shift-left validation** — Plans are validated before code is written.
79
+ 6. **Auto-advance pipeline** — After completing a step, immediately call `pipeline_advance` to move to the next step/item. Do NOT ask the user for permission — just advance and continue.
79
80
 
80
81
  ## Commands
81
82
 
@@ -224,12 +224,28 @@ export function readGroupId(cwd: string): string {
224
224
  export function findModuleByName(cwd: string, name: string): string | null {
225
225
  const files = discoverModules(cwd);
226
226
  const nameLower = name.toLowerCase().replace(/[^a-z0-9]/g, "");
227
+
228
+ // Pass 1: exact match only (preferred)
227
229
  for (const f of files) {
228
230
  const key = f.replace(".md", "").toLowerCase().replace(/[^a-z0-9]/g, "");
229
- if (key === nameLower || nameLower.includes(key) || key.includes(nameLower)) {
231
+ if (key === nameLower) {
230
232
  return f;
231
233
  }
232
234
  }
235
+
236
+ // Pass 2: substring match — only if unambiguous (exactly one match)
237
+ const substringMatches: string[] = [];
238
+ for (const f of files) {
239
+ const key = f.replace(".md", "").toLowerCase().replace(/[^a-z0-9]/g, "");
240
+ if (nameLower.includes(key) || key.includes(nameLower)) {
241
+ substringMatches.push(f);
242
+ }
243
+ }
244
+ if (substringMatches.length === 1) {
245
+ return substringMatches[0];
246
+ }
247
+
248
+ // Ambiguous or no match — let caller decide
233
249
  return null;
234
250
  }
235
251
 
@@ -308,12 +308,28 @@ function readGroupId(cwd: string): string {
308
308
  function findModuleByName(cwd: string, name: string): string | null {
309
309
  const files = discoverModules(cwd);
310
310
  const nameLower = name.toLowerCase().replace(/[^a-z0-9]/g, "");
311
+
312
+ // Pass 1: exact match only (preferred)
311
313
  for (const f of files) {
312
314
  const key = f.replace(".md", "").toLowerCase().replace(/[^a-z0-9]/g, "");
313
- if (key === nameLower || nameLower.includes(key) || key.includes(nameLower)) {
315
+ if (key === nameLower) {
314
316
  return f;
315
317
  }
316
318
  }
319
+
320
+ // Pass 2: substring match — only if unambiguous (exactly one match)
321
+ const substringMatches: string[] = [];
322
+ for (const f of files) {
323
+ const key = f.replace(".md", "").toLowerCase().replace(/[^a-z0-9]/g, "");
324
+ if (nameLower.includes(key) || key.includes(nameLower)) {
325
+ substringMatches.push(f);
326
+ }
327
+ }
328
+ if (substringMatches.length === 1) {
329
+ return substringMatches[0];
330
+ }
331
+
332
+ // Ambiguous or no match — let caller decide
317
333
  return null;
318
334
  }
319
335
 
@@ -1021,10 +1037,21 @@ class EpicManager {
1021
1037
  const planned = components.filter((c: ModuleComponent) => c.status === "planned");
1022
1038
  if (planned.length > 0) {
1023
1039
  slice = { module: matchedModule.replace(".md", ""), components, nextLogicalSlice: planned };
1040
+ } else {
1041
+ ctx.ui.notify(
1042
+ `Module "${matchedModule}" found for epic "${name}" but has no parseable components. ` +
1043
+ `Make sure its \`## Components\` section uses sub-headings (\`### ComponentName\`) with \`status:\` markers. ` +
1044
+ `Falling back to first module with planned components.`,
1045
+ "warn",
1046
+ );
1024
1047
  }
1025
1048
  }
1026
1049
  // Fallback: first module with planned components
1027
1050
  if (!slice) {
1051
+ ctx.ui.notify(
1052
+ `No exact module match with planned components for "${name}". Using first available module instead.`,
1053
+ "warn",
1054
+ );
1028
1055
  slice = findNextLogicalSlice(this.cwd, moduleFiles);
1029
1056
  }
1030
1057
  if (!slice) {
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-07-02T16:34:18Z",
2
+ "timestamp": "2026-07-02T18:56:48Z",
3
3
  "mode": "all",
4
4
  "stages_run": [],
5
5
  "summary": {
@@ -8,7 +8,7 @@
8
8
  "failed": 1,
9
9
  "skipped": 12
10
10
  },
11
- "duration_seconds": 1,
11
+ "duration_seconds": 0,
12
12
  "results": [
13
13
  {
14
14
  "name": "check_mr_traceability.sh",
@@ -17,6 +17,7 @@ Every issue must contain:
17
17
  - **Canonical references** — Architecture module + ADR paths
18
18
  - **Files/layers affected** — domain, application, infrastructure, api
19
19
  - **Rollout or operational notes** — When relevant
20
+ - **Auto-advance pipeline** — After completing a step, call `pipeline_advance` immediately. Do NOT ask the user for permission.
20
21
 
21
22
  ---
22
23
 
@@ -184,6 +184,7 @@ No internal dependencies. This is a root component.
184
184
 
185
185
  > **Agent:** Load this file as your complete session context. All information you need is above.
186
186
  > Start by reading the canonical reference files, then implement following the layer structure.
187
+ > **Auto-advance:** After completing each pipeline step, call `pipeline_advance` immediately — do NOT ask the user for permission.
187
188
 
188
189
  ### Steps
189
190