guardian-framework 0.1.38 → 0.1.40

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.38", 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.40", 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.38", 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.40", 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.38",
3
+ "version": "0.1.40",
4
4
  "description": "Token-optimized agentic framework scaffolder with pi-first architecture",
5
5
  "type": "module",
6
6
  "main": "dist/exports.js",
@@ -88,6 +88,34 @@ export function commandExists(cmd: string): boolean {
88
88
 
89
89
  // Try to create a remote GitHub/GitLab issue via the shell script wrapper.
90
90
  // Uses execFileSync to avoid shell quoting issues with nested commands.
91
+ function execSyncWithRetry(
92
+ args: string[],
93
+ cwd: string,
94
+ opts: { timeout?: number; maxRetries?: number; delayMs?: number } = {},
95
+ ): { exitCode: number; stdout: string } {
96
+ const maxRetries = opts.maxRetries ?? 2;
97
+ const delayMs = opts.delayMs ?? 2000;
98
+ let lastError = "";
99
+
100
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
101
+ if (attempt > 0) {
102
+ const wait = delayMs * Math.pow(2, attempt - 1);
103
+ const waitSec = Math.ceil(wait / 1000);
104
+ try {
105
+ execFileSync("sleep", [String(waitSec)], { cwd, timeout: 30_000, encoding: "utf-8" });
106
+ } catch { /* ignore */ }
107
+ }
108
+ try {
109
+ const stdout = execFileSync("bash", args, { cwd, timeout: opts.timeout ?? 120_000, encoding: "utf-8" });
110
+ return { exitCode: 0, stdout };
111
+ } catch (e: unknown) {
112
+ const err = e as { status?: number; stdout?: string; message?: string };
113
+ lastError = err.stdout ?? err.message ?? "";
114
+ }
115
+ }
116
+ return { exitCode: 1, stdout: lastError };
117
+ }
118
+
91
119
  export function createRemoteIssue(
92
120
  cwd: string,
93
121
  title: string,
@@ -111,19 +139,7 @@ export function createRemoteIssue(
111
139
  ];
112
140
  if (repository) args.push("--repo", repository);
113
141
 
114
- let stdout = "";
115
- let exitCode = 0;
116
- try {
117
- stdout = execFileSync("bash", args, {
118
- cwd,
119
- timeout: 120_000,
120
- encoding: "utf-8",
121
- });
122
- } catch (e: unknown) {
123
- const err = e as { status?: number; stdout?: string; message?: string };
124
- exitCode = err.status ?? 1;
125
- stdout = err.stdout ?? err.message ?? "";
126
- }
142
+ const { exitCode, stdout } = execSyncWithRetry(args, cwd, { maxRetries: 2, delayMs: 2000 });
127
143
 
128
144
  if (exitCode !== 0) {
129
145
  return { success: false, issueNumber: null, error: stdout };
@@ -221,54 +237,32 @@ export function readGroupId(cwd: string): string {
221
237
  return "com.example";
222
238
  }
223
239
 
224
- export function readLanguage(cwd: string): string {
225
- const manifestPath = join(cwd, "guardian-manifest.json");
226
- try {
227
- const raw = readFileSync(manifestPath, "utf-8");
228
- const manifest = JSON.parse(raw) as { language?: string };
229
- if (manifest.language) return manifest.language;
230
- } catch {}
231
- return "typescript";
232
- }
233
-
234
- export function codegenSkillName(language: string): string {
235
- const map: Record<string, string> = {
236
- "rust": "rust-codegen",
237
- "go": "go-codegen",
238
- "python": "python-codegen",
239
- "typescript": "typescript-codegen",
240
- "java": "java-codegen",
241
- "nextjs": "nextjs-codegen",
242
- "angular": "angular-codegen",
243
- };
244
- return map[language] || "typescript-codegen";
245
- }
246
-
247
240
  export function findModuleByName(cwd: string, name: string): string | null {
248
241
  const files = discoverModules(cwd);
249
242
  const nameLower = name.toLowerCase().replace(/[^a-z0-9]/g, "");
250
243
 
251
- // Pass 1: exact match only (preferred)
244
+ // Pass 1: exact match
252
245
  for (const f of files) {
253
246
  const key = f.replace(".md", "").toLowerCase().replace(/[^a-z0-9]/g, "");
254
- if (key === nameLower) {
255
- return f;
256
- }
247
+ if (key === nameLower) return f;
257
248
  }
258
249
 
259
- // Pass 2: substring match only if unambiguous (exactly one match)
260
- const substringMatches: string[] = [];
250
+ // Pass 2: prefix match ("audit" audit-ingestion over audit-query, audit-export)
251
+ const prefix: string[] = [];
261
252
  for (const f of files) {
262
253
  const key = f.replace(".md", "").toLowerCase().replace(/[^a-z0-9]/g, "");
263
- if (nameLower.includes(key) || key.includes(nameLower)) {
264
- substringMatches.push(f);
265
- }
254
+ if (key.startsWith(nameLower) && key.length > nameLower.length) prefix.push(f);
266
255
  }
267
- if (substringMatches.length === 1) {
268
- return substringMatches[0];
256
+ if (prefix.length === 1) return prefix[0];
257
+
258
+ // Pass 3: unambiguous substring match
259
+ const subs: string[] = [];
260
+ for (const f of files) {
261
+ const key = f.replace(".md", "").toLowerCase().replace(/[^a-z0-9]/g, "");
262
+ if (key.includes(nameLower)) subs.push(f);
269
263
  }
264
+ if (subs.length === 1) return subs[0];
270
265
 
271
- // Ambiguous or no match — let caller decide
272
266
  return null;
273
267
  }
274
268
 
@@ -312,8 +306,8 @@ export function parseModuleFile(filePath: string): ModuleComponent[] {
312
306
  for (const line of lines) {
313
307
  const trimmed = line.trim();
314
308
 
315
- // Enter component section (supports "## Components", "## Component Details", "## Component")
316
- if (trimmed.match(/^##\s+Components?/i) || trimmed.match(/^##\s+Component\s+Details/i)) {
309
+ // Enter component section (supports "## Components", "## Aggregates", "## Component Details")
310
+ if (trimmed.match(/^##\s+Components?/i) || trimmed.match(/^##\s+Component\s+Details/i) || trimmed.match(/^##\s+Aggregates?/i)) {
317
311
  inComponentSection = true;
318
312
  continue;
319
313
  }