portable-agent-layer 0.37.0 → 0.38.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "portable-agent-layer",
3
- "version": "0.37.0",
3
+ "version": "0.38.0",
4
4
  "description": "PAL — Portable Agent Layer: persistent personal context for AI coding assistants",
5
5
  "type": "module",
6
6
  "bin": {
@@ -41,7 +41,8 @@
41
41
  "check": "biome check",
42
42
  "check-write": "biome check --write",
43
43
  "knip": "knip-bun",
44
- "arch-check": "bun flint/cli.ts",
44
+ "arch-check": "bun klint/cli.ts",
45
+ "klint:schema": "bun klint/tools/generate-schema.ts",
45
46
  "lint-staged": "lint-staged",
46
47
  "prepare": "bun .husky/install.mjs",
47
48
  "install:all": "bun run src/cli/index.ts cli install",
@@ -80,6 +81,7 @@
80
81
  "@clack/prompts": "^1.3.0",
81
82
  "adm-zip": "^0.5.17",
82
83
  "marked": "^15.0.12",
83
- "playwright": "^1.59.1"
84
+ "playwright": "^1.59.1",
85
+ "zod": "^4.4.3"
84
86
  }
85
87
  }
package/src/cli/index.ts CHANGED
@@ -455,9 +455,7 @@ function checkHookHealth(home: string): HookHealth {
455
455
 
456
456
  const lastError =
457
457
  recentErrors.length > 0
458
- ? recentErrors[recentErrors.length - 1]
459
- .replace(/^\[.*?\] ERROR /, "")
460
- .slice(0, 120)
458
+ ? (recentErrors.at(-1) ?? "").replace(/^\[.*?\] ERROR /, "").slice(0, 120)
461
459
  : null;
462
460
 
463
461
  return { totalErrors: recentErrors.length, lastError };
@@ -126,7 +126,7 @@ function toAnalysisEntries(
126
126
 
127
127
  function isActionable(text: string): boolean {
128
128
  const trimmed = text.trim();
129
- if (/\?[\s]*$/.test(trimmed)) return false;
129
+ if (/\?\s*$/.test(trimmed)) return false;
130
130
  if (extractKeywords(trimmed).size < 4) return false;
131
131
  return true;
132
132
  }
@@ -72,7 +72,7 @@ export function extractArtifacts(
72
72
  if (msg.role !== "assistant") continue;
73
73
  const text = typeof msg.content === "string" ? msg.content : "";
74
74
  // Match file paths: /absolute/paths and relative/paths with extensions
75
- const pathMatches = text.match(/(?:\/[\w./-]+\.[\w]+|[\w./-]+\/[\w.-]+\.[\w]+)/g);
75
+ const pathMatches = text.match(/(?:\/[\w./-]+\.\w+|[\w./-]+\/[\w.-]+\.\w+)/g);
76
76
  if (!pathMatches) continue;
77
77
  for (const p of pathMatches) {
78
78
  // Skip URLs, common noise
@@ -97,10 +97,10 @@ function cleanForHandoff(text: string): string {
97
97
  // Remove inline code
98
98
  .replace(/`[^`]+`/g, "")
99
99
  // Remove file paths
100
- .replace(/(?:\/[\w./-]+\.[\w]+)/g, "")
100
+ .replace(/(?:\/[\w./-]+\.\w+)/g, "")
101
101
  // Remove markdown formatting
102
102
  .replace(/\*\*([^*]+)\*\*/g, "$1")
103
- .replace(/^[#]+\s*/gm, "")
103
+ .replace(/^#+\s*/gm, "")
104
104
  // Remove tool call artifacts
105
105
  .replace(/^\s*[-*]\s*`[^`]+`.*$/gm, "")
106
106
  // Collapse whitespace
@@ -131,7 +131,8 @@ export function extractHandoff(lastAssistant: string): string {
131
131
  .filter((p) => p.length >= 15 && p.length <= 300);
132
132
 
133
133
  if (closingMatch) return closingMatch[0].trim();
134
- if (paragraphs.length > 0) return paragraphs[paragraphs.length - 1];
134
+ const last = paragraphs.at(-1);
135
+ if (last !== undefined) return last;
135
136
  if (cleaned.length > 200) return cleaned.slice(-200).trim();
136
137
  return cleaned;
137
138
  }