portable-agent-layer 0.75.1 → 0.76.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 +1 -1
- package/assets/agents/grok-researcher.md +3 -3
- package/assets/agents/perplexity-researcher.md +1 -1
- package/assets/skills/analyze-pdf/SKILL.md +2 -2
- package/assets/skills/analyze-youtube/SKILL.md +1 -1
- package/assets/skills/consulting-report/SKILL.md +5 -5
- package/assets/skills/consulting-report/tools/dev.ts +1 -1
- package/assets/skills/consulting-report/tools/generate-pdf.ts +1 -1
- package/assets/skills/consulting-report/tools/scaffold.ts +2 -2
- package/assets/skills/create-pdf/SKILL.md +3 -3
- package/assets/skills/create-pdf/tools/md-to-html-pdf.ts +1 -1
- package/assets/skills/fyzz-chat-api/SKILL.md +3 -3
- package/assets/skills/onboarding/SKILL.md +1 -1
- package/assets/skills/pal-analyze/SKILL.md +1 -1
- package/assets/skills/pal-reflect/SKILL.md +2 -2
- package/assets/skills/playwright/SKILL.md +1 -1
- package/assets/skills/playwright/tools/shot.ts +1 -1
- package/assets/skills/presentation/README.md +3 -3
- package/assets/skills/presentation/SKILL.md +8 -8
- package/assets/skills/presentation/template/README.md +1 -1
- package/assets/skills/presentation/tools/new-deck.ts +1 -1
- package/assets/skills/presentation/tools/setup-template.ts +1 -1
- package/assets/skills/projects/SKILL.md +17 -8
- package/assets/skills/telos/SKILL.md +1 -1
- package/assets/templates/AGENTS.md.template +1 -1
- package/assets/templates/PAL/ALGORITHM.md +18 -18
- package/assets/templates/PAL/PROJECT_LIFECYCLE.md +1 -1
- package/assets/templates/PAL/WORK_TRACKING.md +1 -1
- package/assets/templates/rules.codex.rules +65 -0
- package/assets/templates/settings.claude.json +11 -1
- package/package.json +1 -1
- package/src/cli/builtin-tools.ts +30 -0
- package/src/cli/index.ts +17 -9
- package/src/cli/knowledge.ts +2 -1
- package/src/cli/migrate.ts +135 -1
- package/src/cli/skill.ts +56 -4
- package/src/cli/subagent.ts +1 -1
- package/src/hooks/lib/bindings.ts +2 -2
- package/src/hooks/lib/context.ts +2 -4
- package/src/hooks/lib/paths.ts +49 -8
- package/src/hooks/lib/projects.ts +1 -1
- package/src/hooks/lib/work-tracking.ts +19 -14
- package/src/tools/agent/algorithm-reflect.ts +3 -2
- package/src/tools/agent/algorithm-synthesize.ts +5 -2
- package/src/tools/agent/analyze.ts +2 -1
- package/src/tools/agent/handoff-note.ts +7 -6
- package/src/tools/agent/project.ts +21 -20
- package/src/tools/agent/relationship-note.ts +11 -8
- package/src/tools/agent/synthesize.ts +4 -3
- package/src/tools/agent/thread.ts +6 -5
- package/src/tools/agent/wisdom-frame.ts +3 -2
- package/src/tools/lib/script-args.ts +4 -0
- package/src/tools/lib/skill-doctor.ts +2 -2
- package/src/tools/self-model.ts +1 -1
- package/src/tools/skill-doctor.ts +1 -1
- package/src/tools/subagent-doctor.ts +4 -4
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { appendFileSync, existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
|
-
import { resolve } from "node:path";
|
|
7
|
+
import { dirname, resolve } from "node:path";
|
|
8
8
|
import { ensureDir, paths } from "./paths";
|
|
9
|
+
import { defaultSlug, readAllProjects, resolveProjectFromCwd } from "./projects";
|
|
9
10
|
|
|
10
11
|
// ── Session Records ──────────────────────────────────────────────
|
|
11
12
|
|
|
@@ -146,25 +147,29 @@ interface ProjectHistoryEntry {
|
|
|
146
147
|
insights: string;
|
|
147
148
|
}
|
|
148
149
|
|
|
149
|
-
/**
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
/**
|
|
151
|
+
* A directory under `memory/projects/` is what `list`, `resume` and the export
|
|
152
|
+
* read as a project, so only a registered one may own a folder there. Writer and
|
|
153
|
+
* readers share this resolver: keying them apart is what filed a project's
|
|
154
|
+
* history under its parent directory's name.
|
|
155
|
+
*/
|
|
156
|
+
function historyFileFor(cwd: string): string {
|
|
157
|
+
const project = resolveProjectFromCwd(cwd, readAllProjects());
|
|
158
|
+
return project
|
|
159
|
+
? resolve(paths.projectHistory(), project.name, "history.jsonl")
|
|
160
|
+
: resolve(paths.unboundHistory(), `${defaultSlug(cwd)}.jsonl`);
|
|
153
161
|
}
|
|
154
162
|
|
|
155
|
-
/** Append a learning entry to the
|
|
163
|
+
/** Append a learning entry to the history file owning this cwd */
|
|
156
164
|
export function appendProjectHistory(cwd: string, entry: ProjectHistoryEntry): void {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const line = `${JSON.stringify(entry)}\n`;
|
|
161
|
-
appendFileSync(historyPath, line, "utf-8");
|
|
165
|
+
const historyPath = historyFileFor(cwd);
|
|
166
|
+
ensureDir(dirname(historyPath));
|
|
167
|
+
appendFileSync(historyPath, `${JSON.stringify(entry)}\n`, "utf-8");
|
|
162
168
|
}
|
|
163
169
|
|
|
164
|
-
/** Read the
|
|
170
|
+
/** Read the session history for a given cwd */
|
|
165
171
|
export function readProjectHistory(cwd: string, limit = 15): ProjectHistoryEntry[] {
|
|
166
|
-
const
|
|
167
|
-
const historyPath = resolve(paths.projectHistory(), slug, "history.jsonl");
|
|
172
|
+
const historyPath = historyFileFor(cwd);
|
|
168
173
|
if (!existsSync(historyPath)) return [];
|
|
169
174
|
try {
|
|
170
175
|
const lines = readFileSync(historyPath, "utf-8").trim().split("\n").filter(Boolean);
|
|
@@ -18,6 +18,7 @@ import { parseArgs } from "node:util";
|
|
|
18
18
|
import { paths } from "../../hooks/lib/paths";
|
|
19
19
|
import { buildReflection, intOr, reflectionLine } from "../lib/algorithm-reflect";
|
|
20
20
|
import { emit } from "../lib/emit";
|
|
21
|
+
import { scriptArgs } from "../lib/script-args";
|
|
21
22
|
|
|
22
23
|
const HELP = `
|
|
23
24
|
AlgorithmReflect — Log algorithm performance after LEARN phase
|
|
@@ -45,9 +46,9 @@ function reflectionsPath(): string {
|
|
|
45
46
|
return paths.reflectionsFile();
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
function run() {
|
|
49
|
+
export function run(argv: string[] = scriptArgs()) {
|
|
49
50
|
const { values } = parseArgs({
|
|
50
|
-
args:
|
|
51
|
+
args: argv,
|
|
51
52
|
options: {
|
|
52
53
|
task: { type: "string" },
|
|
53
54
|
criteria: { type: "string" },
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import { parseArgs } from "node:util";
|
|
21
21
|
import { readReflections } from "../../hooks/lib/learning-store";
|
|
22
22
|
import { paths } from "../../hooks/lib/paths";
|
|
23
|
+
import { scriptArgs } from "../lib/script-args";
|
|
23
24
|
|
|
24
25
|
/** Algorithm areas a Q2 idea can target, mapped to ALGORITHM.md structure. */
|
|
25
26
|
const BUCKETS: { key: string; label: string; patterns: RegExp }[] = [
|
|
@@ -202,9 +203,9 @@ export function formatAlgorithmReport(s: AlgorithmSynthesis): string {
|
|
|
202
203
|
return lines.join("\n");
|
|
203
204
|
}
|
|
204
205
|
|
|
205
|
-
|
|
206
|
+
export function run(argv: string[] = scriptArgs()) {
|
|
206
207
|
const { values } = parseArgs({
|
|
207
|
-
args:
|
|
208
|
+
args: argv,
|
|
208
209
|
options: {
|
|
209
210
|
since: { type: "string" },
|
|
210
211
|
json: { type: "boolean", default: false },
|
|
@@ -216,3 +217,5 @@ if (import.meta.main) {
|
|
|
216
217
|
values.json ? JSON.stringify(result, null, 2) : formatAlgorithmReport(result)
|
|
217
218
|
);
|
|
218
219
|
}
|
|
220
|
+
|
|
221
|
+
if (import.meta.main) run();
|
|
@@ -14,6 +14,7 @@ import { parseArgs } from "node:util";
|
|
|
14
14
|
import { writeLastAnalyzeDate } from "../../hooks/lib/analyze-nudge";
|
|
15
15
|
import { analyze } from "../../hooks/lib/graduation";
|
|
16
16
|
import { reportLines } from "../lib/analyze-report";
|
|
17
|
+
import { scriptArgs } from "../lib/script-args";
|
|
17
18
|
|
|
18
19
|
const HELP = `
|
|
19
20
|
PAL Learning Analysis — unified graduation + ratings report
|
|
@@ -36,7 +37,7 @@ const HELP = `
|
|
|
36
37
|
Usage: pal cli analyze [--actionable]
|
|
37
38
|
`;
|
|
38
39
|
|
|
39
|
-
export async function run(argv: string[] =
|
|
40
|
+
export async function run(argv: string[] = scriptArgs()) {
|
|
40
41
|
const { values } = parseArgs({
|
|
41
42
|
args: argv,
|
|
42
43
|
options: {
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* Written by Claude in-session — no inference call needed.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* pal cli handoff-note --title "what we were doing" --text "what remains + next steps"
|
|
10
|
+
* pal cli handoff-note --done # mark completed, suppress next-session injection
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { writeFileSync } from "node:fs";
|
|
@@ -20,13 +20,14 @@ import {
|
|
|
20
20
|
recordNote,
|
|
21
21
|
statusOf,
|
|
22
22
|
} from "../lib/handoff-note";
|
|
23
|
+
import { scriptArgs } from "../lib/script-args";
|
|
23
24
|
|
|
24
25
|
const HELP = `
|
|
25
26
|
HandoffNote — Write a handoff note for the current project
|
|
26
27
|
|
|
27
28
|
Usage:
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
pal cli handoff-note --title "what we were doing" --text "what remains"
|
|
30
|
+
pal cli handoff-note --done # mark session completed
|
|
30
31
|
|
|
31
32
|
Arguments:
|
|
32
33
|
--title Brief title of what was being worked on (5-10 words)
|
|
@@ -44,9 +45,9 @@ function saveNote(note: NoteInput): void {
|
|
|
44
45
|
emit.receipt(file, { status: statusOf(note), entries: Object.keys(store).length });
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
function run() {
|
|
48
|
+
export function run(argv: string[] = scriptArgs()) {
|
|
48
49
|
const { values } = parseArgs({
|
|
49
|
-
args:
|
|
50
|
+
args: argv,
|
|
50
51
|
options: {
|
|
51
52
|
title: { type: "string" },
|
|
52
53
|
text: { type: "string" },
|
|
@@ -6,27 +6,27 @@
|
|
|
6
6
|
* Frontmatter holds operational state; body holds ISA spec sections.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
9
|
+
* pal cli project list
|
|
10
|
+
* pal cli project create [name] [--path PATH] [--objectives "..."] [--serves goal|revenue|fun]
|
|
11
|
+
* pal cli project serves <name> <goal|revenue|fun> [note]
|
|
12
|
+
* pal cli project resume <name>
|
|
13
|
+
* pal cli project complete | archive | pause | unpause <name>
|
|
14
|
+
* pal cli project add-next <name> "text"
|
|
15
|
+
* pal cli project add-blocker <name> "text"
|
|
16
|
+
* pal cli project add-decision <name> "decision" "rationale"
|
|
17
|
+
* pal cli project add-handoff <name> "text"
|
|
18
|
+
* pal cli project rm-next | rm-blocker <name> <index>
|
|
19
|
+
* pal cli project update-section <name> <section> "content"
|
|
20
|
+
* pal cli project criteria <name>
|
|
21
|
+
* pal cli project isa-init <name>
|
|
22
|
+
* pal cli project migrate
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
26
26
|
import { resolve } from "node:path";
|
|
27
27
|
import { parseArgs } from "node:util";
|
|
28
28
|
import { writeBinding } from "../../hooks/lib/bindings";
|
|
29
|
-
import { paths } from "../../hooks/lib/paths";
|
|
29
|
+
import { paths, toPath } from "../../hooks/lib/paths";
|
|
30
30
|
import {
|
|
31
31
|
defaultSlug,
|
|
32
32
|
deleteProject,
|
|
@@ -55,6 +55,7 @@ import {
|
|
|
55
55
|
selectIscs,
|
|
56
56
|
taskSlug,
|
|
57
57
|
} from "../lib/project-isc";
|
|
58
|
+
import { scriptArgs } from "../lib/script-args";
|
|
58
59
|
|
|
59
60
|
function now(): string {
|
|
60
61
|
return new Date().toISOString();
|
|
@@ -106,7 +107,7 @@ function cmdCreate(args: string[]): void {
|
|
|
106
107
|
allowPositionals: true,
|
|
107
108
|
});
|
|
108
109
|
|
|
109
|
-
const path =
|
|
110
|
+
const path = toPath(values.path ?? process.cwd());
|
|
110
111
|
const name = (values.name ?? positionals[0] ?? defaultSlug(path)).trim();
|
|
111
112
|
|
|
112
113
|
if (!/^[a-z0-9_-]+$/.test(name)) {
|
|
@@ -271,7 +272,7 @@ function addHandoff(name: string, text: string): void {
|
|
|
271
272
|
function cmdSetPath(args: string[]): void {
|
|
272
273
|
const [name, ...rest] = args;
|
|
273
274
|
if (!name || rest.length === 0) fail("Usage: set-path <name> <new-path>");
|
|
274
|
-
const newPath =
|
|
275
|
+
const newPath = toPath(rest.join(" ").trim());
|
|
275
276
|
const p = requireProject(name);
|
|
276
277
|
writeBinding(p.name, newPath);
|
|
277
278
|
p.updated = now();
|
|
@@ -693,8 +694,8 @@ Commands:
|
|
|
693
694
|
`);
|
|
694
695
|
}
|
|
695
696
|
|
|
696
|
-
function run(): void {
|
|
697
|
-
const [cmd, ...rest] =
|
|
697
|
+
export function run(argv: string[] = scriptArgs()): void {
|
|
698
|
+
const [cmd, ...rest] = argv;
|
|
698
699
|
if (!cmd || cmd === "help" || cmd === "--help" || cmd === "-h") {
|
|
699
700
|
help();
|
|
700
701
|
return;
|
|
@@ -810,7 +811,7 @@ function run(): void {
|
|
|
810
811
|
cmdRm(rest);
|
|
811
812
|
return;
|
|
812
813
|
default:
|
|
813
|
-
fail(`Unknown command "${cmd}". Run 'project
|
|
814
|
+
fail(`Unknown command "${cmd}". Run 'pal cli project help' for usage.`);
|
|
814
815
|
}
|
|
815
816
|
}
|
|
816
817
|
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* the user (O, W) and session diary entries (--b).
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* pal cli relationship-note --o "User prefers X" --confidence 0.80
|
|
10
|
+
* pal cli relationship-note --w "User is building X in TypeScript"
|
|
11
|
+
* pal cli relationship-note --b "Debugged the cache split logic"
|
|
12
12
|
*
|
|
13
13
|
* Note types:
|
|
14
14
|
* --o Opinion/behavioral observation about the user (requires --confidence)
|
|
@@ -22,14 +22,15 @@ import { parseArgs } from "node:util";
|
|
|
22
22
|
import { appendNotes } from "../../hooks/lib/relationship";
|
|
23
23
|
import { emit } from "../lib/emit";
|
|
24
24
|
import { notesFromFlags } from "../lib/note-flags";
|
|
25
|
+
import { scriptArgs } from "../lib/script-args";
|
|
25
26
|
|
|
26
27
|
const HELP = `
|
|
27
28
|
RelationshipNote — Append W/O/Session entries to today's relationship log
|
|
28
29
|
|
|
29
30
|
Usage:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
pal cli relationship-note --o "User prefers X" --confidence 0.80
|
|
32
|
+
pal cli relationship-note --w "User is building X in TypeScript"
|
|
33
|
+
pal cli relationship-note --b "Debugged the cache split logic"
|
|
33
34
|
|
|
34
35
|
Flags:
|
|
35
36
|
--o TEXT Opinion/behavioral observation about the user
|
|
@@ -42,9 +43,9 @@ Multiple flags may be combined in one call. At least one of --o, --w, --b is req
|
|
|
42
43
|
Output: appends to memory/relationship/YYYY-MM/YYYY-MM-DD.md
|
|
43
44
|
`;
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
export function run(argv: string[] = scriptArgs()) {
|
|
46
47
|
const { values } = parseArgs({
|
|
47
|
-
args:
|
|
48
|
+
args: argv,
|
|
48
49
|
options: {
|
|
49
50
|
o: { type: "string", multiple: true },
|
|
50
51
|
w: { type: "string", multiple: true },
|
|
@@ -68,3 +69,5 @@ if (import.meta.main) {
|
|
|
68
69
|
const { file, written } = appendNotes(result.notes);
|
|
69
70
|
emit.receipt(file, { written, deduped: result.notes.length - written });
|
|
70
71
|
}
|
|
72
|
+
|
|
73
|
+
if (import.meta.main) run();
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* reads and formats with behavioral guidance.
|
|
8
8
|
*
|
|
9
9
|
* Usage:
|
|
10
|
-
*
|
|
10
|
+
* pal cli synthesize [--days 7] [--force]
|
|
11
11
|
*
|
|
12
12
|
* Guards: skips if last synthesis was < 24h ago (unless --force).
|
|
13
13
|
* Output: ~/.pal/memory/state/synthesis.json
|
|
@@ -17,6 +17,7 @@ import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
17
17
|
import { resolve } from "node:path";
|
|
18
18
|
import { parseArgs } from "node:util";
|
|
19
19
|
import { ensureDir, paths } from "../../hooks/lib/paths";
|
|
20
|
+
import { scriptArgs } from "../lib/script-args";
|
|
20
21
|
import { readJsonl } from "../lib/self-model";
|
|
21
22
|
|
|
22
23
|
// ── Config ──
|
|
@@ -303,9 +304,9 @@ export function synthesize(days: number): SynthesisState {
|
|
|
303
304
|
|
|
304
305
|
// ── CLI ──
|
|
305
306
|
|
|
306
|
-
function run() {
|
|
307
|
+
export function run(argv: string[] = scriptArgs()) {
|
|
307
308
|
const { values } = parseArgs({
|
|
308
|
-
args:
|
|
309
|
+
args: argv,
|
|
309
310
|
options: {
|
|
310
311
|
days: { type: "string", default: "7" },
|
|
311
312
|
force: { type: "boolean" },
|
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
* Stored in memory/state/threads.jsonl as structured records.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* pal cli thread --add --title "..." [--context "..."]
|
|
10
|
+
* pal cli thread --resolve --id <id>
|
|
11
|
+
* pal cli thread --list [--all]
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { parseArgs } from "node:util";
|
|
15
15
|
import { emit } from "../lib/emit";
|
|
16
|
+
import { scriptArgs } from "../lib/script-args";
|
|
16
17
|
import {
|
|
17
18
|
addThread,
|
|
18
19
|
readThreads,
|
|
@@ -59,9 +60,9 @@ function markResolved(id: string | undefined) {
|
|
|
59
60
|
emit.receipt(file, { id, status: "resolved", title: resolution.thread.title });
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
function run() {
|
|
63
|
+
export function run(argv: string[] = scriptArgs()) {
|
|
63
64
|
const { values } = parseArgs({
|
|
64
|
-
args:
|
|
65
|
+
args: argv,
|
|
65
66
|
options: {
|
|
66
67
|
add: { type: "boolean" },
|
|
67
68
|
resolve: { type: "boolean" },
|
|
@@ -20,6 +20,7 @@ import { resolve } from "node:path";
|
|
|
20
20
|
import { parseArgs } from "node:util";
|
|
21
21
|
import { paths } from "../../hooks/lib/paths";
|
|
22
22
|
import { emit } from "../lib/emit";
|
|
23
|
+
import { scriptArgs } from "../lib/script-args";
|
|
23
24
|
|
|
24
25
|
// ── Types ──
|
|
25
26
|
|
|
@@ -192,9 +193,9 @@ ${antiPatternEntry}
|
|
|
192
193
|
|
|
193
194
|
// ── CLI ──
|
|
194
195
|
|
|
195
|
-
function run() {
|
|
196
|
+
export function run(argv: string[] = scriptArgs()) {
|
|
196
197
|
const { values } = parseArgs({
|
|
197
|
-
args:
|
|
198
|
+
args: argv,
|
|
198
199
|
options: {
|
|
199
200
|
domain: { type: "string", short: "d" },
|
|
200
201
|
observation: { type: "string", short: "o" },
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
14
14
|
import { basename, extname, relative, resolve } from "node:path";
|
|
15
|
-
import { palHome } from "../../hooks/lib/paths";
|
|
15
|
+
import { palHome, toPath } from "../../hooks/lib/paths";
|
|
16
16
|
import { declaredTriggers } from "../../hooks/lib/skill-triggers";
|
|
17
17
|
|
|
18
18
|
type Level = "pass" | "warn" | "error";
|
|
@@ -449,7 +449,7 @@ export function formatReport(r: DoctorReport): string {
|
|
|
449
449
|
* report names the directory the caller meant rather than a guess.
|
|
450
450
|
*/
|
|
451
451
|
export function resolveSkillDir(arg: string): string {
|
|
452
|
-
const asPath =
|
|
452
|
+
const asPath = toPath(arg);
|
|
453
453
|
if (existsSync(resolve(asPath, "SKILL.md"))) return asPath;
|
|
454
454
|
const byName = resolve(palHome(), "skills", arg);
|
|
455
455
|
if (existsSync(resolve(byName, "SKILL.md"))) return byName;
|
package/src/tools/self-model.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* ~/.pal/memory/self-model/current.md that is injected at session start.
|
|
10
10
|
*
|
|
11
11
|
* Usage:
|
|
12
|
-
* bun
|
|
12
|
+
* bun src/tools/self-model.ts [--days 30] [--force] [--dry-run]
|
|
13
13
|
*
|
|
14
14
|
* Every decision this makes lives in ./lib/self-model.ts, where the suite
|
|
15
15
|
* reaches it directly; what stays here is paths, inference and the writes.
|
|
@@ -15,7 +15,7 @@ import { formatReport, lintSkill, resolveSkillDir } from "./lib/skill-doctor";
|
|
|
15
15
|
if (import.meta.main) {
|
|
16
16
|
const arg = process.argv[2];
|
|
17
17
|
if (!arg) {
|
|
18
|
-
console.error("Usage:
|
|
18
|
+
console.error("Usage: pal cli skill doctor <skill-dir-or-name>");
|
|
19
19
|
process.exit(2);
|
|
20
20
|
}
|
|
21
21
|
const report = lintSkill(resolveSkillDir(arg));
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
15
15
|
import { basename, resolve } from "node:path";
|
|
16
|
-
import { assets, palHome } from "../hooks/lib/paths";
|
|
16
|
+
import { assets, namesAPath, palHome, toPath } from "../hooks/lib/paths";
|
|
17
17
|
|
|
18
18
|
type Level = "pass" | "warn" | "error";
|
|
19
19
|
|
|
@@ -396,16 +396,16 @@ export function formatSubagentReport(r: SubagentReport): string {
|
|
|
396
396
|
|
|
397
397
|
/** Resolve a doctor argument to a subagent .md path (a path, or a name in the store). */
|
|
398
398
|
export function resolveSubagentFile(arg: string): string {
|
|
399
|
-
|
|
400
|
-
const direct = resolve(arg);
|
|
399
|
+
const direct = toPath(arg);
|
|
401
400
|
if (existsSync(direct) && direct.endsWith(".md")) return direct;
|
|
401
|
+
if (namesAPath(arg)) return direct.endsWith(".md") ? direct : `${direct}.md`;
|
|
402
402
|
return resolve(palHome(), "agents", arg.endsWith(".md") ? arg : `${arg}.md`);
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
if (import.meta.main) {
|
|
406
406
|
const arg = process.argv[2];
|
|
407
407
|
if (!arg) {
|
|
408
|
-
console.error("Usage:
|
|
408
|
+
console.error("Usage: pal cli subagent doctor <file-or-name>");
|
|
409
409
|
process.exit(2);
|
|
410
410
|
}
|
|
411
411
|
const report = lintSubagent(resolveSubagentFile(arg));
|