@zosmaai/pi-llm-wiki 0.9.1 → 0.9.2
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/CHANGELOG.md +1 -0
- package/README.de.md +2 -2
- package/README.es.md +2 -2
- package/README.fr.md +2 -2
- package/README.hi.md +2 -2
- package/README.ja.md +2 -2
- package/README.ko.md +2 -2
- package/README.md +25 -2
- package/README.pt.md +2 -2
- package/README.ru.md +2 -2
- package/README.zh.md +2 -2
- package/docs/api.md +123 -10
- package/docs/architecture.md +38 -1
- package/docs/commands.md +21 -1
- package/extensions/llm-wiki/index.ts +49 -14
- package/extensions/llm-wiki/lib/metadata.ts +34 -1
- package/extensions/llm-wiki/lib/recall.ts +107 -8
- package/extensions/llm-wiki/lib/task-config.ts +85 -13
- package/extensions/llm-wiki/lib/tools.ts +120 -15
- package/extensions/llm-wiki/lib/trajectories-command.ts +67 -0
- package/extensions/llm-wiki/lib/trajectory.ts +613 -0
- package/extensions/llm-wiki/lib/utils.ts +20 -3
- package/extensions/llm-wiki/lib/visible-status.ts +51 -0
- package/package.json +1 -1
- package/prompts/wiki-record.md +36 -0
- package/prompts/wiki-run.md +4 -2
- package/prompts/wiki-skills.md +26 -0
- package/skills/llm-wiki/SKILL.md +70 -4
|
@@ -513,7 +513,8 @@ export function registerWikiEnsurePage(pi: ExtensionAPI, runtime?: Runtime): voi
|
|
|
513
513
|
],
|
|
514
514
|
parameters: Type.Object({
|
|
515
515
|
type: Type.String({
|
|
516
|
-
description:
|
|
516
|
+
description:
|
|
517
|
+
"Page type: entity | concept | synthesis | analysis | requirement | skill | case",
|
|
517
518
|
}),
|
|
518
519
|
title: Type.String({ description: "Page title" }),
|
|
519
520
|
content: Type.Optional(
|
|
@@ -531,7 +532,14 @@ export function registerWikiEnsurePage(pi: ExtensionAPI, runtime?: Runtime): voi
|
|
|
531
532
|
};
|
|
532
533
|
}
|
|
533
534
|
|
|
534
|
-
const type = params.type as
|
|
535
|
+
const type = params.type as
|
|
536
|
+
| "entity"
|
|
537
|
+
| "concept"
|
|
538
|
+
| "synthesis"
|
|
539
|
+
| "analysis"
|
|
540
|
+
| "requirement"
|
|
541
|
+
| "skill"
|
|
542
|
+
| "case";
|
|
535
543
|
const slug = params.title
|
|
536
544
|
.toLowerCase()
|
|
537
545
|
.replace(/[^a-z0-9\s-]/g, "")
|
|
@@ -545,6 +553,8 @@ export function registerWikiEnsurePage(pi: ExtensionAPI, runtime?: Runtime): voi
|
|
|
545
553
|
synthesis: "syntheses",
|
|
546
554
|
analysis: "analyses",
|
|
547
555
|
requirement: "requirements",
|
|
556
|
+
skill: "skills",
|
|
557
|
+
case: "cases",
|
|
548
558
|
};
|
|
549
559
|
const folder = folderMap[type] || "concepts";
|
|
550
560
|
const pagePath = join(paths.wiki, folder, `${slug}.md`);
|
|
@@ -622,6 +632,76 @@ function buildPageTemplate(
|
|
|
622
632
|
"Durable answer from a query.\n\n## Question\n\n[Original question]",
|
|
623
633
|
);
|
|
624
634
|
}
|
|
635
|
+
if (type === "skill") {
|
|
636
|
+
return [
|
|
637
|
+
"---",
|
|
638
|
+
"type: skill",
|
|
639
|
+
`created: ${date}`,
|
|
640
|
+
`updated: ${date}`,
|
|
641
|
+
"status: draft",
|
|
642
|
+
"trajectories: []",
|
|
643
|
+
"tags: []",
|
|
644
|
+
"---",
|
|
645
|
+
"",
|
|
646
|
+
`# ${title}`,
|
|
647
|
+
"",
|
|
648
|
+
"_One-line summary of the reusable pattern this skill captures._",
|
|
649
|
+
"",
|
|
650
|
+
"## When to Use",
|
|
651
|
+
"",
|
|
652
|
+
"[Trigger conditions — when this pattern applies]",
|
|
653
|
+
"",
|
|
654
|
+
"## Procedure",
|
|
655
|
+
"",
|
|
656
|
+
"1. [Step 1]",
|
|
657
|
+
"2. [Step 2]",
|
|
658
|
+
"",
|
|
659
|
+
"## Pitfalls",
|
|
660
|
+
"",
|
|
661
|
+
"- [Known failure mode or caveat]",
|
|
662
|
+
"",
|
|
663
|
+
"## Distilled From",
|
|
664
|
+
"",
|
|
665
|
+
"_Trajectories this skill was generalized from._",
|
|
666
|
+
"",
|
|
667
|
+
"- [[trajectories/TRJ-...]]",
|
|
668
|
+
"",
|
|
669
|
+
].join("\n");
|
|
670
|
+
}
|
|
671
|
+
if (type === "case") {
|
|
672
|
+
return [
|
|
673
|
+
"---",
|
|
674
|
+
"type: case",
|
|
675
|
+
`created: ${date}`,
|
|
676
|
+
`updated: ${date}`,
|
|
677
|
+
"status: draft",
|
|
678
|
+
"outcome: success",
|
|
679
|
+
"trajectory_id: ",
|
|
680
|
+
"tags: []",
|
|
681
|
+
"---",
|
|
682
|
+
"",
|
|
683
|
+
`# ${title}`,
|
|
684
|
+
"",
|
|
685
|
+
"_One-line summary of the specific task this case records._",
|
|
686
|
+
"",
|
|
687
|
+
"## Task",
|
|
688
|
+
"",
|
|
689
|
+
"[What was requested]",
|
|
690
|
+
"",
|
|
691
|
+
"## Approach",
|
|
692
|
+
"",
|
|
693
|
+
"[How the agent solved it — key steps and decisions]",
|
|
694
|
+
"",
|
|
695
|
+
"## Outcome",
|
|
696
|
+
"",
|
|
697
|
+
"[Result, and anything worth reusing or avoiding next time]",
|
|
698
|
+
"",
|
|
699
|
+
"## Trajectory",
|
|
700
|
+
"",
|
|
701
|
+
"- [[trajectories/TRJ-...]] — captured tool-call run",
|
|
702
|
+
"",
|
|
703
|
+
].join("\n");
|
|
704
|
+
}
|
|
625
705
|
if (type === "requirement") {
|
|
626
706
|
return [
|
|
627
707
|
"---",
|
|
@@ -1117,10 +1197,12 @@ export function registerWikiWatch(pi: ExtensionAPI): void {
|
|
|
1117
1197
|
pi.registerTool({
|
|
1118
1198
|
name: "wiki_watch",
|
|
1119
1199
|
label: "Wiki Watch",
|
|
1120
|
-
description:
|
|
1200
|
+
description:
|
|
1201
|
+
"Print a ready-to-paste crontab line for scheduling automatic wiki updates (discover → ingest → lint). Does NOT schedule anything itself — it returns the command for the user to install.",
|
|
1121
1202
|
promptSnippet: "Schedule auto-updates for the wiki",
|
|
1122
1203
|
promptGuidelines: [
|
|
1123
1204
|
"Use wiki_watch when the user wants the wiki to stay current automatically.",
|
|
1205
|
+
"wiki_watch only PRINTS a cron line — surface the output to the user verbatim so they can install it. Do not claim the schedule is active.",
|
|
1124
1206
|
],
|
|
1125
1207
|
parameters: Type.Object({
|
|
1126
1208
|
interval: Type.String({ description: "daily, weekly, hourly, or stop" }),
|
|
@@ -1132,15 +1214,16 @@ export function registerWikiWatch(pi: ExtensionAPI): void {
|
|
|
1132
1214
|
{
|
|
1133
1215
|
type: "text",
|
|
1134
1216
|
text: [
|
|
1135
|
-
"🛑 To stop wiki auto-updates:",
|
|
1217
|
+
"🛑 To stop wiki auto-updates, remove the cron line you installed earlier:",
|
|
1136
1218
|
"",
|
|
1219
|
+
"```bash",
|
|
1220
|
+
"crontab -e # then delete the line tagged '# llm-wiki-autoupdate'",
|
|
1137
1221
|
"```",
|
|
1138
|
-
"schedule_prompt action=list",
|
|
1139
|
-
"```",
|
|
1140
|
-
"Find the wiki job IDs, then:",
|
|
1141
1222
|
"",
|
|
1142
|
-
"
|
|
1143
|
-
"
|
|
1223
|
+
"Or list current jobs to confirm:",
|
|
1224
|
+
"",
|
|
1225
|
+
"```bash",
|
|
1226
|
+
"crontab -l | grep llm-wiki-autoupdate",
|
|
1144
1227
|
"```",
|
|
1145
1228
|
].join("\n"),
|
|
1146
1229
|
},
|
|
@@ -1149,10 +1232,11 @@ export function registerWikiWatch(pi: ExtensionAPI): void {
|
|
|
1149
1232
|
};
|
|
1150
1233
|
}
|
|
1151
1234
|
|
|
1235
|
+
// 5-field POSIX crontab expressions (min hour dom month dow).
|
|
1152
1236
|
const intervals: Record<string, { cron: string; label: string }> = {
|
|
1153
|
-
daily: { cron: "0
|
|
1154
|
-
weekly: { cron: "0
|
|
1155
|
-
hourly: { cron: "0
|
|
1237
|
+
daily: { cron: "0 8 * * *", label: "Daily at 8:00 AM" },
|
|
1238
|
+
weekly: { cron: "0 9 * * 1", label: "Weekly on Monday at 9:00 AM" },
|
|
1239
|
+
hourly: { cron: "0 * * * *", label: "Every hour" },
|
|
1156
1240
|
};
|
|
1157
1241
|
|
|
1158
1242
|
const config = intervals[params.interval];
|
|
@@ -1169,18 +1253,37 @@ export function registerWikiWatch(pi: ExtensionAPI): void {
|
|
|
1169
1253
|
};
|
|
1170
1254
|
}
|
|
1171
1255
|
|
|
1256
|
+
// Robustness for global crontab environments:
|
|
1257
|
+
// * `/bin/bash -lc` runs a LOGIN shell that sources /etc/profile +
|
|
1258
|
+
// ~/.profile / ~/.bash_profile, so npm-global / bun / nvm PATH
|
|
1259
|
+
// additions are imported — cron's default PATH is only
|
|
1260
|
+
// `/usr/bin:/bin` and would not find `pi`.
|
|
1261
|
+
// * `mkdir -p` makes the log dir self-healing for users with only
|
|
1262
|
+
// a project vault (no `~/.llm-wiki/` yet).
|
|
1263
|
+
// * All `$HOME` references are double-quoted to survive paths with spaces.
|
|
1264
|
+
// * `# llm-wiki-autoupdate` tags the line so the user can find and
|
|
1265
|
+
// remove it via `crontab -e` later (see `interval=stop`).
|
|
1266
|
+
const cronLine = `${config.cron} /bin/bash -lc 'mkdir -p "$HOME/.llm-wiki" && pi -p "/wiki-run" >> "$HOME/.llm-wiki/cron.log" 2>&1' # llm-wiki-autoupdate`;
|
|
1267
|
+
|
|
1172
1268
|
return {
|
|
1173
1269
|
content: [
|
|
1174
1270
|
{
|
|
1175
1271
|
type: "text",
|
|
1176
1272
|
text: [
|
|
1177
|
-
`⏰ To set up ${config.label} wiki updates,
|
|
1273
|
+
`⏰ To set up ${config.label} wiki updates, add this line to your crontab.`,
|
|
1274
|
+
"**This tool only prints the line — it does not install it.**",
|
|
1178
1275
|
"",
|
|
1276
|
+
"```bash",
|
|
1277
|
+
"crontab -e",
|
|
1179
1278
|
"```",
|
|
1180
|
-
|
|
1279
|
+
"",
|
|
1280
|
+
"Then append:",
|
|
1281
|
+
"",
|
|
1282
|
+
"```cron",
|
|
1283
|
+
cronLine,
|
|
1181
1284
|
"```",
|
|
1182
1285
|
"",
|
|
1183
|
-
|
|
1286
|
+
`The line uses \`/bin/bash -lc\` so your shell profile (and the \`pi\` binary on npm-global / bun PATH) is loaded. Output goes to \`~/.llm-wiki/cron.log\`. If your system has no \`/bin/bash\`, replace with \`/bin/sh -c\` and ensure \`pi\` is in cron's PATH yourself.`,
|
|
1184
1287
|
].join("\n"),
|
|
1185
1288
|
},
|
|
1186
1289
|
],
|
|
@@ -1188,6 +1291,8 @@ export function registerWikiWatch(pi: ExtensionAPI): void {
|
|
|
1188
1291
|
interval: params.interval,
|
|
1189
1292
|
cronSchedule: config.cron,
|
|
1190
1293
|
label: config.label,
|
|
1294
|
+
cronLine,
|
|
1295
|
+
installed: false,
|
|
1191
1296
|
} as Record<string, unknown>,
|
|
1192
1297
|
};
|
|
1193
1298
|
},
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { loadTaskConfig, persistTrajectoriesEnabled, trajectoriesEnabled } from "./task-config.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Activation surface for agent-trajectory working-memory (issue #80).
|
|
6
|
+
*
|
|
7
|
+
* The feature is opt-in / default-off. The trajectory tools
|
|
8
|
+
* (`wiki_capture_trajectory`, `wiki_distill_skills`, `wiki_recall_skill`) are
|
|
9
|
+
* registered conditionally at extension-load time (see index.ts) based on the
|
|
10
|
+
* `llm-wiki.trajectories` setting. Because pi has no runtime add/remove-tool
|
|
11
|
+
* API — the extension factory runs once at load — flipping the flag can only
|
|
12
|
+
* change the registered tool set by RELOADING extensions. This command does
|
|
13
|
+
* exactly that: persist the setting, then `ctx.reload()` so the gate
|
|
14
|
+
* re-evaluates and the tools appear (or disappear) immediately.
|
|
15
|
+
*
|
|
16
|
+
* /wiki-trajectories → show current state
|
|
17
|
+
* /wiki-trajectories on → enable + reload
|
|
18
|
+
* /wiki-trajectories off → disable + reload
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const ON_WORDS = new Set(["on", "true", "enable", "enabled", "yes", "1"]);
|
|
22
|
+
const OFF_WORDS = new Set(["off", "false", "disable", "disabled", "no", "0"]);
|
|
23
|
+
|
|
24
|
+
export function registerWikiTrajectoriesCommand(pi: ExtensionAPI): void {
|
|
25
|
+
pi.registerCommand("wiki-trajectories", {
|
|
26
|
+
description:
|
|
27
|
+
"Enable or disable agent-trajectory working-memory (capture/distill/recall). Off by default.",
|
|
28
|
+
handler: async (args, ctx) => {
|
|
29
|
+
const arg = args.trim().toLowerCase();
|
|
30
|
+
const current = trajectoriesEnabled(loadTaskConfig(ctx.cwd));
|
|
31
|
+
|
|
32
|
+
if (!arg) {
|
|
33
|
+
ctx.ui.notify(
|
|
34
|
+
`LLM Wiki trajectories are ${current ? "ON" : "OFF"}. Use \`/wiki-trajectories on\` or \`off\`.`,
|
|
35
|
+
"info",
|
|
36
|
+
);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let next: boolean;
|
|
41
|
+
if (ON_WORDS.has(arg)) next = true;
|
|
42
|
+
else if (OFF_WORDS.has(arg)) next = false;
|
|
43
|
+
else {
|
|
44
|
+
ctx.ui.notify(
|
|
45
|
+
`LLM Wiki: could not parse "${args.trim()}". Use \`on\` or \`off\`.`,
|
|
46
|
+
"error",
|
|
47
|
+
);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (next === current) {
|
|
52
|
+
ctx.ui.notify(`LLM Wiki trajectories already ${current ? "ON" : "OFF"}.`, "info");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
persistTrajectoriesEnabled(ctx.cwd, next);
|
|
57
|
+
ctx.ui.notify(
|
|
58
|
+
`LLM Wiki: trajectory tools ${next ? "enabled" : "disabled"} — reloading extensions…`,
|
|
59
|
+
"info",
|
|
60
|
+
);
|
|
61
|
+
// pi has no runtime register/unregister-tool API: reload re-runs the
|
|
62
|
+
// extension factory so the conditional registration re-evaluates and the
|
|
63
|
+
// tool set (and status line) reflect the new state.
|
|
64
|
+
await ctx.reload();
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|