portable-agent-layer 0.22.0 → 0.23.1
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/assets/agents/gemini-researcher.md +17 -3
- package/assets/agents/grok-researcher.md +19 -5
- package/assets/agents/multi-perspective-researcher.md +16 -2
- package/assets/agents/perplexity-researcher.md +17 -3
- package/assets/skills/analyze-pdf/SKILL.md +1 -1
- package/assets/skills/analyze-youtube/SKILL.md +1 -1
- package/assets/skills/extract-entities/SKILL.md +1 -1
- package/assets/skills/fyzz-chat-api/SKILL.md +3 -3
- package/assets/skills/reflect/SKILL.md +2 -2
- package/assets/skills/telos/SKILL.md +6 -6
- package/assets/templates/AGENTS.md.template +2 -2
- package/assets/templates/PAL/ALGORITHM.md +93 -10
- package/assets/templates/PAL/CONTEXT_ROUTING.md +17 -17
- package/assets/templates/PAL/MEMORY_SYSTEM.md +5 -5
- package/assets/templates/PAL/README.md +12 -9
- package/assets/templates/PAL/SYSTEM_ARCHITECTURE.md +1 -1
- package/assets/templates/pal-settings.json +6 -3
- package/assets/templates/settings.claude.json +2 -2
- package/package.json +3 -1
- package/src/cli/index.ts +4 -11
- package/src/hooks/handlers/failure.ts +3 -1
- package/src/hooks/handlers/rating.ts +17 -2
- package/src/hooks/handlers/reflect-trigger.ts +4 -4
- package/src/hooks/handlers/relationship.ts +1 -1
- package/src/hooks/handlers/session-intelligence.ts +324 -0
- package/src/hooks/handlers/session-name.ts +2 -2
- package/src/hooks/handlers/synthesis.ts +36 -0
- package/src/hooks/handlers/update-check.ts +2 -2
- package/src/hooks/handlers/work-learning.ts +1 -1
- package/src/hooks/lib/context.ts +119 -2
- package/src/hooks/lib/paths.ts +4 -12
- package/src/hooks/lib/security.ts +39 -28
- package/src/hooks/lib/stop.ts +56 -7
- package/src/hooks/lib/token-usage.ts +1 -0
- package/src/targets/claude/install.ts +1 -1
- package/src/targets/cursor/install.ts +7 -1
- package/src/targets/cursor/uninstall.ts +7 -0
- package/src/targets/lib.ts +125 -115
- package/src/targets/opencode/install.ts +4 -4
- package/src/tools/agent/algorithm-reflect.ts +2 -0
- package/src/tools/agent/synthesize.ts +361 -0
- package/src/tools/agent/thread.ts +162 -0
package/src/targets/lib.ts
CHANGED
|
@@ -253,11 +253,13 @@ export function scaffoldPalSettings(): void {
|
|
|
253
253
|
|
|
254
254
|
// --- PAL docs (modular context routing files) ---
|
|
255
255
|
|
|
256
|
-
const PAL_DOCS_DIR = resolve(
|
|
256
|
+
const PAL_DOCS_DIR = resolve(palHome(), "docs");
|
|
257
|
+
const PAL_TOOLS_DIR = resolve(palHome(), "tools");
|
|
257
258
|
|
|
258
259
|
/**
|
|
259
|
-
* Install PAL system docs into ~/.
|
|
260
|
+
* Install PAL system docs into ~/.pal/docs/.
|
|
260
261
|
* Always overwrites — these are engine-managed, not user-editable.
|
|
262
|
+
* Also creates ~/.pal/tools/ → repo agent tools (symlink).
|
|
261
263
|
*/
|
|
262
264
|
export function copyPalDocs(): number {
|
|
263
265
|
const srcDir = assets.palDocs();
|
|
@@ -273,28 +275,25 @@ export function copyPalDocs(): number {
|
|
|
273
275
|
count++;
|
|
274
276
|
}
|
|
275
277
|
|
|
276
|
-
//
|
|
278
|
+
// ~/.pal/tools/ → repo agent tools
|
|
277
279
|
const linkType = process.platform === "win32" ? "junction" : "dir";
|
|
278
|
-
ensureSymlink(
|
|
279
|
-
ensureSymlink(resolve(PAL_DOCS_DIR, "memory"), resolve(palHome(), "memory"), linkType);
|
|
280
|
-
ensureSymlink(resolve(PAL_DOCS_DIR, "tools"), assets.agentTools(), linkType);
|
|
280
|
+
ensureSymlink(PAL_TOOLS_DIR, assets.agentTools(), linkType);
|
|
281
281
|
|
|
282
282
|
return count;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
/** Remove PAL system docs from ~/.
|
|
285
|
+
/** Remove PAL system docs from ~/.pal/docs/ */
|
|
286
286
|
export function removePalDocs(): void {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
/* gone */
|
|
293
|
-
}
|
|
287
|
+
// Remove tools symlink
|
|
288
|
+
try {
|
|
289
|
+
unlinkSync(PAL_TOOLS_DIR);
|
|
290
|
+
} catch {
|
|
291
|
+
/* gone */
|
|
294
292
|
}
|
|
293
|
+
if (!existsSync(PAL_DOCS_DIR)) return;
|
|
295
294
|
try {
|
|
296
295
|
rmSync(PAL_DOCS_DIR, { recursive: true });
|
|
297
|
-
log.info("Removed ~/.
|
|
296
|
+
log.info("Removed ~/.pal/docs/");
|
|
298
297
|
} catch {
|
|
299
298
|
/* gone */
|
|
300
299
|
}
|
|
@@ -302,12 +301,12 @@ export function removePalDocs(): void {
|
|
|
302
301
|
|
|
303
302
|
// --- Skills ---
|
|
304
303
|
|
|
305
|
-
const
|
|
304
|
+
const PAL_SKILLS_DIR = resolve(palHome(), "skills");
|
|
306
305
|
|
|
307
306
|
/**
|
|
308
307
|
* Install PAL skills by symlinking:
|
|
309
|
-
* ~/.
|
|
310
|
-
* ~/.claude/skills/<name> → ~/.
|
|
308
|
+
* ~/.pal/skills/<name> → <repo>/assets/skills/<name> (source of truth)
|
|
309
|
+
* ~/.claude/skills/<name> → ~/.pal/skills/<name> (agent discovery)
|
|
311
310
|
*
|
|
312
311
|
* Symlinks mean tools inside skills can import from the repo (src/hooks/lib/*)
|
|
313
312
|
* and everything resolves naturally. Additive — skips skills already installed.
|
|
@@ -316,7 +315,7 @@ export function copySkills(claudeSkillsDir: string): number {
|
|
|
316
315
|
const skillsDir = assets.skills();
|
|
317
316
|
if (!existsSync(skillsDir)) return 0;
|
|
318
317
|
|
|
319
|
-
mkdirSync(
|
|
318
|
+
mkdirSync(PAL_SKILLS_DIR, { recursive: true });
|
|
320
319
|
mkdirSync(claudeSkillsDir, { recursive: true });
|
|
321
320
|
const linkType = process.platform === "win32" ? "junction" : "dir";
|
|
322
321
|
let count = 0;
|
|
@@ -325,17 +324,22 @@ export function copySkills(claudeSkillsDir: string): number {
|
|
|
325
324
|
const srcDir = resolve(skillsDir, name);
|
|
326
325
|
if (!existsSync(resolve(srcDir, "SKILL.md"))) continue;
|
|
327
326
|
|
|
328
|
-
// ~/.
|
|
329
|
-
const
|
|
330
|
-
ensureSymlink(
|
|
327
|
+
// ~/.pal/skills/<name> → <repo>/assets/skills/<name>
|
|
328
|
+
const palLink = resolve(PAL_SKILLS_DIR, name);
|
|
329
|
+
ensureSymlink(palLink, srcDir, linkType);
|
|
331
330
|
|
|
332
|
-
// ~/.claude/skills/<name> → ~/.
|
|
331
|
+
// ~/.claude/skills/<name> → ~/.pal/skills/<name>
|
|
333
332
|
const claudeLink = resolve(claudeSkillsDir, name);
|
|
334
|
-
ensureSymlink(claudeLink,
|
|
333
|
+
ensureSymlink(claudeLink, palLink, linkType);
|
|
335
334
|
|
|
336
335
|
log.info(`Linked skill: ${name}`);
|
|
337
336
|
count++;
|
|
338
337
|
}
|
|
338
|
+
|
|
339
|
+
// ~/.agents/skills/ → ~/.pal/skills/
|
|
340
|
+
mkdirSync(platform.agentsDir(), { recursive: true });
|
|
341
|
+
ensureSymlink(resolve(platform.agentsDir(), "skills"), PAL_SKILLS_DIR, linkType);
|
|
342
|
+
|
|
339
343
|
return count;
|
|
340
344
|
}
|
|
341
345
|
|
|
@@ -356,7 +360,7 @@ function ensureSymlink(link: string, target: string, type: "dir" | "junction"):
|
|
|
356
360
|
symlinkSync(target, link, type);
|
|
357
361
|
}
|
|
358
362
|
|
|
359
|
-
/** Remove PAL skill symlinks from ~/.
|
|
363
|
+
/** Remove PAL skill symlinks from ~/.pal/skills/ and ~/.claude/skills/ */
|
|
360
364
|
export function removeSkills(claudeSkillsDir: string): string[] {
|
|
361
365
|
const skillsDir = assets.skills();
|
|
362
366
|
if (!existsSync(skillsDir)) return [];
|
|
@@ -365,10 +369,7 @@ export function removeSkills(claudeSkillsDir: string): string[] {
|
|
|
365
369
|
for (const name of readdirSync(skillsDir)) {
|
|
366
370
|
if (!existsSync(resolve(skillsDir, name, "SKILL.md"))) continue;
|
|
367
371
|
|
|
368
|
-
for (const link of [
|
|
369
|
-
resolve(AGENTS_SKILLS_DIR, name),
|
|
370
|
-
resolve(claudeSkillsDir, name),
|
|
371
|
-
]) {
|
|
372
|
+
for (const link of [resolve(PAL_SKILLS_DIR, name), resolve(claudeSkillsDir, name)]) {
|
|
372
373
|
try {
|
|
373
374
|
unlinkSync(link);
|
|
374
375
|
} catch {
|
|
@@ -378,6 +379,14 @@ export function removeSkills(claudeSkillsDir: string): string[] {
|
|
|
378
379
|
removed.push(name);
|
|
379
380
|
log.info(`Removed skill: ${name}`);
|
|
380
381
|
}
|
|
382
|
+
|
|
383
|
+
// Remove ~/.agents/skills/ → ~/.pal/skills/ symlink
|
|
384
|
+
try {
|
|
385
|
+
unlinkSync(resolve(platform.agentsDir(), "skills"));
|
|
386
|
+
} catch {
|
|
387
|
+
/* gone */
|
|
388
|
+
}
|
|
389
|
+
|
|
381
390
|
return removed;
|
|
382
391
|
}
|
|
383
392
|
|
|
@@ -387,28 +396,10 @@ const CLAUDE_AGENTS_DIR = resolve(platform.claudeDir(), "agents");
|
|
|
387
396
|
|
|
388
397
|
/**
|
|
389
398
|
* Install PAL agent definitions into ~/.claude/agents/.
|
|
390
|
-
*
|
|
399
|
+
* Always overwrites — engine-managed, not user-editable.
|
|
391
400
|
*/
|
|
392
401
|
export function copyAgents(): number {
|
|
393
|
-
|
|
394
|
-
if (!existsSync(agentsDir)) return 0;
|
|
395
|
-
|
|
396
|
-
mkdirSync(CLAUDE_AGENTS_DIR, { recursive: true });
|
|
397
|
-
let count = 0;
|
|
398
|
-
|
|
399
|
-
for (const file of readdirSync(agentsDir).filter((f) => f.endsWith(".md"))) {
|
|
400
|
-
const src = resolve(agentsDir, file);
|
|
401
|
-
const dst = resolve(CLAUDE_AGENTS_DIR, file);
|
|
402
|
-
|
|
403
|
-
if (!existsSync(dst)) {
|
|
404
|
-
copyFileSync(src, dst);
|
|
405
|
-
log.info(`Added agent: ${file.replace(/\.md$/, "")}`);
|
|
406
|
-
count++;
|
|
407
|
-
} else {
|
|
408
|
-
log.warn(`Agent exists, skipping: ${file.replace(/\.md$/, "")}`);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
return count;
|
|
402
|
+
return installAgents(CLAUDE_AGENTS_DIR, "claude");
|
|
412
403
|
}
|
|
413
404
|
|
|
414
405
|
/** Remove PAL agents from ~/.claude/agents/ */
|
|
@@ -439,103 +430,122 @@ export function countAgents(): number {
|
|
|
439
430
|
}
|
|
440
431
|
}
|
|
441
432
|
|
|
442
|
-
// ---
|
|
433
|
+
// --- Agent platform extraction ---
|
|
443
434
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
WebSearch: "webfetch",
|
|
447
|
-
WebFetch: "webfetch",
|
|
448
|
-
Read: "read",
|
|
449
|
-
Grep: "read",
|
|
450
|
-
Glob: "read",
|
|
451
|
-
Write: "edit",
|
|
452
|
-
Edit: "edit",
|
|
453
|
-
Bash: "bash",
|
|
454
|
-
};
|
|
435
|
+
const AGENT_PLATFORMS = ["claude", "opencode", "cursor"] as const;
|
|
436
|
+
type AgentPlatform = (typeof AGENT_PLATFORMS)[number];
|
|
455
437
|
|
|
456
438
|
/**
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
439
|
+
* Extract a platform-specific agent file from the unified agent format.
|
|
440
|
+
*
|
|
441
|
+
* Each agent .md defines platform blocks at the top level:
|
|
442
|
+
* claude: → fields for Claude Code
|
|
443
|
+
* opencode: → fields for opencode
|
|
444
|
+
* cursor: → fields for Cursor
|
|
445
|
+
*
|
|
446
|
+
* Global fields (name, description) are always included.
|
|
447
|
+
* The target platform block is un-indented and merged into the root.
|
|
448
|
+
* All other platform blocks are stripped.
|
|
461
449
|
*/
|
|
462
|
-
export function
|
|
450
|
+
export function extractAgentForPlatform(
|
|
451
|
+
content: string,
|
|
452
|
+
platform: AgentPlatform
|
|
453
|
+
): string {
|
|
463
454
|
const parts = content.split(/^---\s*$/m);
|
|
464
455
|
if (parts.length < 3) return content;
|
|
465
456
|
|
|
466
457
|
const frontmatter = parts[1];
|
|
467
458
|
const body = parts.slice(2).join("---");
|
|
468
459
|
|
|
469
|
-
|
|
470
|
-
const
|
|
471
|
-
|
|
460
|
+
const globalLines: string[] = [];
|
|
461
|
+
const platformLines: Record<AgentPlatform, string[]> = {
|
|
462
|
+
claude: [],
|
|
463
|
+
opencode: [],
|
|
464
|
+
cursor: [],
|
|
465
|
+
};
|
|
466
|
+
let currentPlatform: AgentPlatform | null = null;
|
|
472
467
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
for (const tool of tools) {
|
|
476
|
-
const perm = TOOL_TO_PERMISSION[tool];
|
|
477
|
-
if (perm) perms.add(perm);
|
|
478
|
-
}
|
|
468
|
+
for (const line of frontmatter.split("\n")) {
|
|
469
|
+
if (!line.trim()) continue;
|
|
479
470
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
.
|
|
488
|
-
|
|
489
|
-
|
|
471
|
+
const platformMatch = line.match(/^(claude|opencode|cursor):\s*$/);
|
|
472
|
+
if (platformMatch) {
|
|
473
|
+
currentPlatform = platformMatch[1] as AgentPlatform;
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (currentPlatform) {
|
|
478
|
+
if (line.match(/^ {2}/)) {
|
|
479
|
+
platformLines[currentPlatform].push(line.slice(2)); // un-indent one level
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
currentPlatform = null; // end of platform block
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
globalLines.push(line);
|
|
490
486
|
}
|
|
491
487
|
|
|
488
|
+
const newFrontmatter = [...globalLines, ...platformLines[platform]]
|
|
489
|
+
.filter((l) => l.trim())
|
|
490
|
+
.join("\n");
|
|
491
|
+
|
|
492
492
|
return `---\n${newFrontmatter}\n---\n${body}`;
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
-
/**
|
|
496
|
-
|
|
497
|
-
* Translates frontmatter from Claude Code format to opencode format.
|
|
498
|
-
*/
|
|
499
|
-
export function copyAgentsForOpencode(ocAgentsDir: string): number {
|
|
495
|
+
/** Install agents for a platform into a target directory. Always overwrites. */
|
|
496
|
+
function installAgents(targetDir: string, platform: AgentPlatform): number {
|
|
500
497
|
const agentsDir = assets.agents();
|
|
501
498
|
if (!existsSync(agentsDir)) return 0;
|
|
502
499
|
|
|
503
|
-
mkdirSync(
|
|
500
|
+
mkdirSync(targetDir, { recursive: true });
|
|
504
501
|
let count = 0;
|
|
505
502
|
|
|
506
503
|
for (const file of readdirSync(agentsDir).filter((f) => f.endsWith(".md"))) {
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
log.warn(`Opencode agent exists, skipping: ${file.replace(/\.md$/, "")}`);
|
|
516
|
-
}
|
|
504
|
+
const content = readFileSync(resolve(agentsDir, file), "utf-8");
|
|
505
|
+
writeFileSync(
|
|
506
|
+
resolve(targetDir, file),
|
|
507
|
+
extractAgentForPlatform(content, platform),
|
|
508
|
+
"utf-8"
|
|
509
|
+
);
|
|
510
|
+
log.info(`Installed ${platform} agent: ${file.replace(/\.md$/, "")}`);
|
|
511
|
+
count++;
|
|
517
512
|
}
|
|
518
513
|
return count;
|
|
519
514
|
}
|
|
520
515
|
|
|
521
|
-
/** Remove PAL agents from
|
|
522
|
-
|
|
516
|
+
/** Remove PAL agents from a directory. */
|
|
517
|
+
function uninstallAgents(targetDir: string, label: string): string[] {
|
|
523
518
|
const agentsDir = assets.agents();
|
|
524
519
|
if (!existsSync(agentsDir)) return [];
|
|
525
520
|
|
|
526
521
|
const removed: string[] = [];
|
|
527
522
|
for (const file of readdirSync(agentsDir).filter((f) => f.endsWith(".md"))) {
|
|
528
|
-
const dst = resolve(
|
|
523
|
+
const dst = resolve(targetDir, file);
|
|
529
524
|
if (existsSync(dst)) {
|
|
530
525
|
unlinkSync(dst);
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
log.info(`Removed opencode agent: ${name}`);
|
|
526
|
+
removed.push(file.replace(/\.md$/, ""));
|
|
527
|
+
log.info(`Removed ${label} agent: ${file.replace(/\.md$/, "")}`);
|
|
534
528
|
}
|
|
535
529
|
}
|
|
536
530
|
return removed;
|
|
537
531
|
}
|
|
538
532
|
|
|
533
|
+
export function copyAgentsForOpencode(ocAgentsDir: string): number {
|
|
534
|
+
return installAgents(ocAgentsDir, "opencode");
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
export function removeAgentsFromOpencode(ocAgentsDir: string): string[] {
|
|
538
|
+
return uninstallAgents(ocAgentsDir, "opencode");
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
export function copyAgentsForCursor(cursorAgentsDir: string): number {
|
|
542
|
+
return installAgents(cursorAgentsDir, "cursor");
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
export function removeAgentsFromCursor(cursorAgentsDir: string): string[] {
|
|
546
|
+
return uninstallAgents(cursorAgentsDir, "cursor");
|
|
547
|
+
}
|
|
548
|
+
|
|
539
549
|
// --- Skill Index ---
|
|
540
550
|
|
|
541
551
|
interface SkillIndexEntry {
|
|
@@ -580,11 +590,11 @@ function extractTriggers(description: string): string[] {
|
|
|
580
590
|
}
|
|
581
591
|
|
|
582
592
|
/**
|
|
583
|
-
* Generate skill-index.json from installed skills in ~/.
|
|
593
|
+
* Generate skill-index.json from installed skills in ~/.pal/skills/.
|
|
584
594
|
* Called during install after skills are symlinked.
|
|
585
595
|
*/
|
|
586
596
|
export function generateSkillIndex(): number {
|
|
587
|
-
if (!existsSync(
|
|
597
|
+
if (!existsSync(PAL_SKILLS_DIR)) return 0;
|
|
588
598
|
|
|
589
599
|
const index: SkillIndex = {
|
|
590
600
|
generated: new Date().toISOString(),
|
|
@@ -592,8 +602,8 @@ export function generateSkillIndex(): number {
|
|
|
592
602
|
skills: {},
|
|
593
603
|
};
|
|
594
604
|
|
|
595
|
-
for (const name of readdirSync(
|
|
596
|
-
const skillMd = resolve(
|
|
605
|
+
for (const name of readdirSync(PAL_SKILLS_DIR)) {
|
|
606
|
+
const skillMd = resolve(PAL_SKILLS_DIR, name, "SKILL.md");
|
|
597
607
|
if (!existsSync(skillMd)) continue;
|
|
598
608
|
|
|
599
609
|
try {
|
|
@@ -629,12 +639,12 @@ export function generateSkillIndex(): number {
|
|
|
629
639
|
return index.totalSkills;
|
|
630
640
|
}
|
|
631
641
|
|
|
632
|
-
/** Count skill subdirectories in ~/.
|
|
642
|
+
/** Count skill subdirectories in ~/.pal/skills/ */
|
|
633
643
|
export function countSkills(): number {
|
|
634
|
-
if (!existsSync(
|
|
644
|
+
if (!existsSync(PAL_SKILLS_DIR)) return 0;
|
|
635
645
|
try {
|
|
636
|
-
return readdirSync(
|
|
637
|
-
existsSync(resolve(
|
|
646
|
+
return readdirSync(PAL_SKILLS_DIR).filter((f) =>
|
|
647
|
+
existsSync(resolve(PAL_SKILLS_DIR, f, "SKILL.md"))
|
|
638
648
|
).length;
|
|
639
649
|
} catch {
|
|
640
650
|
return 0;
|
|
@@ -52,11 +52,11 @@ try {
|
|
|
52
52
|
log.warn(`Could not install plugin deps — run 'bun install' in ${OC_PLUGINS_DIR}`);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
// --- 3. Install skills into ~/.
|
|
55
|
+
// --- 3. Install skills into ~/.pal/skills/ ---
|
|
56
56
|
const claudeSkillsDir = resolve(platform.claudeDir(), "skills");
|
|
57
57
|
copySkills(claudeSkillsDir);
|
|
58
58
|
generateSkillIndex();
|
|
59
|
-
log.success("Installed skills to ~/.
|
|
59
|
+
log.success("Installed skills to ~/.pal/skills/");
|
|
60
60
|
|
|
61
61
|
// --- 4. Install agents into ~/.config/opencode/agents/ ---
|
|
62
62
|
const ocAgentsDir = resolve(OC_GLOBAL_DIR, "agents");
|
|
@@ -64,7 +64,7 @@ copyAgentsForOpencode(ocAgentsDir);
|
|
|
64
64
|
|
|
65
65
|
// --- 5. Copy PAL system docs ---
|
|
66
66
|
const palDocsCount = copyPalDocs();
|
|
67
|
-
log.success(`Installed ${palDocsCount} PAL docs to ~/.
|
|
67
|
+
log.success(`Installed ${palDocsCount} PAL docs to ~/.pal/docs/`);
|
|
68
68
|
|
|
69
69
|
// --- 6. Generate ~/.config/opencode/AGENTS.md ---
|
|
70
70
|
regenerateIfNeeded();
|
|
@@ -73,4 +73,4 @@ log.success("Generated ~/.config/opencode/AGENTS.md");
|
|
|
73
73
|
log.success("opencode installation complete");
|
|
74
74
|
console.log("");
|
|
75
75
|
log.info(`Plugin: ${pluginDst}`);
|
|
76
|
-
log.info(`Skills: ${countSkills()} (native via ~/.
|
|
76
|
+
log.info(`Skills: ${countSkills()} (native via ~/.pal/skills/)`);
|
|
@@ -21,6 +21,7 @@ import { paths } from "../../hooks/lib/paths";
|
|
|
21
21
|
|
|
22
22
|
interface AlgorithmReflection {
|
|
23
23
|
timestamp: string;
|
|
24
|
+
cwd: string;
|
|
24
25
|
task: string;
|
|
25
26
|
criteria_count: number;
|
|
26
27
|
criteria_passed: number;
|
|
@@ -103,6 +104,7 @@ Output: algorithm-reflections.jsonl in memory/learning/reflections/
|
|
|
103
104
|
|
|
104
105
|
const reflection: AlgorithmReflection = {
|
|
105
106
|
timestamp: new Date().toISOString(),
|
|
107
|
+
cwd: process.cwd(),
|
|
106
108
|
task: values.task,
|
|
107
109
|
criteria_count: parseInt(values.criteria || "0", 10),
|
|
108
110
|
criteria_passed: parseInt(values.passed || "0", 10),
|