agent-lyceum 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/README.md +3 -3
- package/README.zh-TW.md +3 -3
- package/dist/cli.js +44 -46
- package/dist/doctor.js +1 -1
- package/dist/memory-tidy.d.ts +1 -1
- package/dist/memory-tidy.js +1 -1
- package/dist/status.d.ts +1 -1
- package/dist/status.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,15 +26,15 @@ Requires Node 20+, plus `claude` and/or `codex` on your `PATH` (already logged i
|
|
|
26
26
|
|---|---|---|
|
|
27
27
|
| Project | `init [-y]` | Create the home and the global agent library. [details](docs/commands.md#init) |
|
|
28
28
|
| Project | `project add <name> --dir <repo>` | Register a project. [details](docs/commands.md#project-add) |
|
|
29
|
-
| Project | `project
|
|
29
|
+
| Project | `project` / `project remove <name> [--purge]` | List or unregister projects. [details](docs/commands.md#project-and-project-remove) |
|
|
30
30
|
| Diagnose | `doctor [-p name] [--task-file f] [--resolved] [--json]` | Check config (with enforcement levels), git, the lock and runtime CLIs without running agents; `--resolved` prints every effective setting and its source. [details](docs/commands.md#doctor) |
|
|
31
31
|
| Diagnose | `status [-p name] [--monitor]` | Show agents, mail, the current wake-up and past runs (`--json`, `--monitor`). [details](docs/commands.md#status) |
|
|
32
32
|
| Run | `run ["task"] [--task-file f] [--agent a] [-p name]` | Give the task to the lead and run until done; with `--agent`, to one member alone. [details](docs/commands.md#run) |
|
|
33
33
|
| Run | `resume [run-id] [--answer] [-p name]` | Continue an interrupted or failed run; `--answer` first answers the questions it is waiting on. [details](docs/commands.md#resume) |
|
|
34
34
|
| Run | `clear <run-id> [-p name] [--dry-run] [--keep-worktrees]` / `clear --lock --force` | Delete a run with its task memory and worktrees; or remove the lock a crashed run left behind. [details](docs/commands.md#clear) |
|
|
35
35
|
| Run | `call <agent> ["task"] [--task-file f] [--dir d]` | Call one global agent on its own, outside any project; prints its answer. [details](docs/commands.md#call) |
|
|
36
|
-
| Run | `
|
|
37
|
-
| Run | `
|
|
36
|
+
| Run | `tidy [-p name] [--agent a] [--layer project\|global] [--dry-run]` | Have agents tidy their own memory (manual only; archives, never deletes). [details](docs/commands.md#tidy) |
|
|
37
|
+
| Run | `tidy --undo <timestamp> -p name --agent a` | Undo a tidy: move its archived files back. [details](docs/commands.md#tidy) |
|
|
38
38
|
|
|
39
39
|
`agent-lyceum --help` lists each command with a one-line summary; `agent-lyceum <command> --help` prints its full description and options.
|
|
40
40
|
|
package/README.zh-TW.md
CHANGED
|
@@ -26,15 +26,15 @@ npx agent-lyceum status
|
|
|
26
26
|
|---|---|---|
|
|
27
27
|
| 專案 | `init [-y]` | 建立 home 與全域 agent 庫。 [詳細](docs/commands.zh-TW.md#init) |
|
|
28
28
|
| 專案 | `project add <name> --dir <repo>` | 註冊專案。 [詳細](docs/commands.zh-TW.md#project-add) |
|
|
29
|
-
| 專案 | `project
|
|
29
|
+
| 專案 | `project` / `project remove <name> [--purge]` | 列出或取消註冊專案。 [詳細](docs/commands.zh-TW.md#project-and-project-remove) |
|
|
30
30
|
| 診斷 | `doctor [-p name] [--task-file f] [--resolved] [--json]` | 不執行 agent,檢查設定(含防護等級)、git、鎖與 runtime CLI;`--resolved` 印出每項生效設定與其來源。 [詳細](docs/commands.zh-TW.md#doctor) |
|
|
31
31
|
| 診斷 | `status [-p name] [--monitor]` | 顯示 agent、信件、目前執行與歷次 run(支援 `--json`、`--monitor`)。 [詳細](docs/commands.zh-TW.md#status) |
|
|
32
32
|
| 執行 | `run ["task"] [--task-file f] [--agent a] [-p name]` | 把任務交給 lead 並執行到結束;加 `--agent` 則只交給某個成員單獨做。 [詳細](docs/commands.zh-TW.md#run) |
|
|
33
33
|
| 執行 | `resume [run-id] [--answer] [-p name]` | 接續被中斷或失敗的 run;`--answer` 會先回答它等待中的問題。 [詳細](docs/commands.zh-TW.md#resume) |
|
|
34
34
|
| 執行 | `clear <run-id> [-p name] [--dry-run] [--keep-worktrees]` / `clear --lock --force` | 刪除 run 與其任務記憶、worktree;或移除當機 run 留下的專案鎖。 [詳細](docs/commands.zh-TW.md#clear) |
|
|
35
35
|
| 執行 | `call <agent> ["task"] [--task-file f] [--dir d]` | 單獨呼叫一個 global agent(不需專案),印出它的回答。 [詳細](docs/commands.zh-TW.md#call) |
|
|
36
|
-
| 執行 | `
|
|
37
|
-
| 執行 | `
|
|
36
|
+
| 執行 | `tidy [-p name] [--agent a] [--layer project\|global] [--dry-run]` | 讓 agent 整理自己的記憶(只能手動觸發;封存而非刪除)。 [詳細](docs/commands.zh-TW.md#tidy) |
|
|
37
|
+
| 執行 | `tidy --undo <時間戳> -p name --agent a` | 還原一次整理:把封存的檔案搬回。 [詳細](docs/commands.zh-TW.md#tidy) |
|
|
38
38
|
|
|
39
39
|
`agent-lyceum --help` 只列出每個指令的一行簡述;`agent-lyceum <指令> --help` 會印出該指令的完整說明與選項。
|
|
40
40
|
|
package/dist/cli.js
CHANGED
|
@@ -71,7 +71,17 @@ program
|
|
|
71
71
|
console.log(` kept ${path.relative(h, f)}`);
|
|
72
72
|
console.log(`\nNext: agent-lyceum project add <name> --dir <your-repo>`);
|
|
73
73
|
});
|
|
74
|
-
const project = program
|
|
74
|
+
const project = program
|
|
75
|
+
.command("project")
|
|
76
|
+
.summary("List registered projects, or add / remove one")
|
|
77
|
+
.description("Without a subcommand, list the registered projects.\n\nSubcommands:\n - add <name> --dir <repo>: register a project\n - remove <name> [--purge]: unregister one")
|
|
78
|
+
.action(() => {
|
|
79
|
+
const list = listProjects(home());
|
|
80
|
+
if (!list.length)
|
|
81
|
+
console.log("No projects registered.");
|
|
82
|
+
for (const p of list)
|
|
83
|
+
console.log(`${p.name} -> ${p.dir}`);
|
|
84
|
+
});
|
|
75
85
|
project
|
|
76
86
|
.command("add <name>")
|
|
77
87
|
.description("Register a project (config and context live in the home, not in the repo)")
|
|
@@ -85,16 +95,6 @@ project
|
|
|
85
95
|
fail(e.message);
|
|
86
96
|
}
|
|
87
97
|
});
|
|
88
|
-
project
|
|
89
|
-
.command("list")
|
|
90
|
-
.description("List registered projects")
|
|
91
|
-
.action(() => {
|
|
92
|
-
const list = listProjects(home());
|
|
93
|
-
if (!list.length)
|
|
94
|
-
console.log("No projects registered.");
|
|
95
|
-
for (const p of list)
|
|
96
|
-
console.log(`${p.name} -> ${p.dir}`);
|
|
97
|
-
});
|
|
98
98
|
project
|
|
99
99
|
.command("remove <name>")
|
|
100
100
|
.description("Unregister a project (keeps its context unless --purge)")
|
|
@@ -507,7 +507,6 @@ program
|
|
|
507
507
|
fail(e instanceof ConfigError ? e.message : e.message);
|
|
508
508
|
}
|
|
509
509
|
});
|
|
510
|
-
const memoryCmd = program.command("memory").description("Look after the agents' long-term memory");
|
|
511
510
|
function layerOpt(v) {
|
|
512
511
|
if (v === undefined || v === "project")
|
|
513
512
|
return "project";
|
|
@@ -515,17 +514,44 @@ function layerOpt(v) {
|
|
|
515
514
|
return "global";
|
|
516
515
|
return fail(`--layer must be "project" or "global" (task memory is not tidied: \`clear\` deletes it).`);
|
|
517
516
|
}
|
|
518
|
-
|
|
517
|
+
program
|
|
519
518
|
.command("tidy")
|
|
520
|
-
.summary("Have agents tidy their own memory")
|
|
521
|
-
.description("Have agents tidy their own memory: merge duplicates, fix stale entries, archive what is obsolete (never deletes).\n\
|
|
519
|
+
.summary("Have agents tidy their own memory, or undo one tidy")
|
|
520
|
+
.description("Have agents tidy their own memory: merge duplicates, fix stale entries, archive what is obsolete (never deletes).\n\n" +
|
|
521
|
+
"Manual only; nothing triggers it automatically.\n\n" +
|
|
522
|
+
"With --undo <stamp> it tidies nothing and instead:\n" +
|
|
523
|
+
" - moves that tidy's archived files back (never overwrites)\n" +
|
|
524
|
+
" - re-adds them to MEMORY.md\n" +
|
|
525
|
+
" - needs --agent, and cannot be combined with --dry-run")
|
|
522
526
|
.option("-p, --project <name>")
|
|
523
|
-
.option("--agent <name>", "tidy only this agent (default: every agent)")
|
|
527
|
+
.option("--agent <name>", "tidy only this agent (default: every agent); required with --undo")
|
|
524
528
|
.option("--layer <layer>", "project (default) or global; global memory is shared by every project, so it is never tidied unless you ask")
|
|
525
529
|
.option("--dry-run", "only show the memory sizes and what changed in the project; wake nobody, change nothing")
|
|
530
|
+
.option("--undo <stamp>", "undo the tidy with this timestamp: move its archived files back")
|
|
526
531
|
.action(async (opts) => {
|
|
527
532
|
try {
|
|
528
533
|
const layer = layerOpt(opts.layer);
|
|
534
|
+
if (opts.undo !== undefined) {
|
|
535
|
+
if (opts.dryRun)
|
|
536
|
+
fail("--undo cannot be combined with --dry-run.");
|
|
537
|
+
if (!opts.agent)
|
|
538
|
+
fail("--undo needs --agent <name>: an archive belongs to one agent's memory.");
|
|
539
|
+
const target = loadProject(opts.project);
|
|
540
|
+
const undoLease = takeLock(target, `restore-${tidyStamp()}`);
|
|
541
|
+
try {
|
|
542
|
+
const r = restoreMemory({ project: target, agent: opts.agent, layer, stamp: opts.undo });
|
|
543
|
+
for (const f of r.restored)
|
|
544
|
+
console.log(` restored ${f}`);
|
|
545
|
+
for (const s of r.skipped)
|
|
546
|
+
console.log(` skipped ${s.rel}: ${s.reason}`);
|
|
547
|
+
if (!r.restored.length && !r.skipped.length)
|
|
548
|
+
console.log(`Archive ${opts.undo} holds no files to restore.`);
|
|
549
|
+
}
|
|
550
|
+
finally {
|
|
551
|
+
undoLease.release();
|
|
552
|
+
}
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
529
555
|
const pr = loadProject(opts.project);
|
|
530
556
|
if (opts.dryRun) {
|
|
531
557
|
const dry = await tidyMemory({ project: pr, layer, agent: opts.agent, dryRun: true });
|
|
@@ -553,7 +579,7 @@ memoryCmd
|
|
|
553
579
|
console.log(`No agent has ${layer} memory configured. ${layer === "project" ? "The template gives agents global memory only: set `memory.project` for an agent in project.yaml (or tidy global memory with --layer global)." : "Set `memory.global` for an agent."}`);
|
|
554
580
|
for (const r of results) {
|
|
555
581
|
if (r.status === "tidied")
|
|
556
|
-
console.log(` ${r.agent} (${r.layer}): tidied. Archive: ${path.join(r.dir, ".archive", r.archive ?? "")} — undo with: agent-lyceum
|
|
582
|
+
console.log(` ${r.agent} (${r.layer}): tidied. Archive: ${path.join(r.dir, ".archive", r.archive ?? "")} — undo with: agent-lyceum tidy --undo ${r.archive} -p ${pr.name} --agent ${r.agent}${r.layer === "global" ? " --layer global" : ""}`);
|
|
557
583
|
else if (r.status === "skipped")
|
|
558
584
|
console.log(` ${r.agent} (${r.layer}): skipped — ${r.problems.join("; ")}`);
|
|
559
585
|
else if (r.status === "failed") {
|
|
@@ -568,34 +594,6 @@ memoryCmd
|
|
|
568
594
|
fail(e instanceof ConfigError ? e.message : e.message);
|
|
569
595
|
}
|
|
570
596
|
});
|
|
571
|
-
memoryCmd
|
|
572
|
-
.command("restore <stamp>")
|
|
573
|
-
.description("Move the files of one tidy's archive back (nothing that exists now is overwritten) and re-add them to MEMORY.md")
|
|
574
|
-
.option("-p, --project <name>")
|
|
575
|
-
.requiredOption("--agent <name>")
|
|
576
|
-
.option("--layer <layer>", "project (default) or global")
|
|
577
|
-
.action((stamp, opts) => {
|
|
578
|
-
try {
|
|
579
|
-
const layer = layerOpt(opts.layer);
|
|
580
|
-
const pr = loadProject(opts.project);
|
|
581
|
-
const lease = takeLock(pr, `restore-${tidyStamp()}`);
|
|
582
|
-
try {
|
|
583
|
-
const r = restoreMemory({ project: pr, agent: opts.agent, layer, stamp });
|
|
584
|
-
for (const f of r.restored)
|
|
585
|
-
console.log(` restored ${f}`);
|
|
586
|
-
for (const s of r.skipped)
|
|
587
|
-
console.log(` skipped ${s.rel}: ${s.reason}`);
|
|
588
|
-
if (!r.restored.length && !r.skipped.length)
|
|
589
|
-
console.log(`Archive ${stamp} holds no files to restore.`);
|
|
590
|
-
}
|
|
591
|
-
finally {
|
|
592
|
-
lease.release();
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
catch (e) {
|
|
596
|
-
fail(e.message);
|
|
597
|
-
}
|
|
598
|
-
});
|
|
599
597
|
function useColor() {
|
|
600
598
|
if (process.env.NO_COLOR)
|
|
601
599
|
return false;
|
|
@@ -666,7 +664,7 @@ program
|
|
|
666
664
|
const HELP_LAYERS = {
|
|
667
665
|
"Project:": ["init", "project"],
|
|
668
666
|
"Diagnose:": ["doctor", "status"],
|
|
669
|
-
"Run:": ["run", "resume", "clear", "call", "
|
|
667
|
+
"Run:": ["run", "resume", "clear", "call", "tidy"],
|
|
670
668
|
};
|
|
671
669
|
for (const [heading, names] of Object.entries(HELP_LAYERS))
|
|
672
670
|
for (const c of program.commands)
|
package/dist/doctor.js
CHANGED
|
@@ -134,7 +134,7 @@ export async function diagnoseProject(project, opts = {}) {
|
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
136
|
for (const a of tidyAdvice(project))
|
|
137
|
-
checks.push({ level: "info", subject: "memory", message: `${a.agent}: ${a.reason}. Consider: agent-lyceum
|
|
137
|
+
checks.push({ level: "info", subject: "memory", message: `${a.agent}: ${a.reason}. Consider: agent-lyceum tidy -p ${project.name} --agent ${a.agent} (doctor only suggests; it never tidies).` });
|
|
138
138
|
const runtimes = await probeProjectRuntimes(project, opts);
|
|
139
139
|
checks.push(...judgeRuntimes(project, runtimes));
|
|
140
140
|
checks.push({ level: "info", subject: "login", message: "Login status is unknown: agent-lyceum does not read credentials, and the CLIs offer no read-only login check it can rely on." });
|
package/dist/memory-tidy.d.ts
CHANGED
|
@@ -88,7 +88,7 @@ export interface TidyResult {
|
|
|
88
88
|
}
|
|
89
89
|
/** Scratch space of one tidy (snapshot and the invocation's logs); outside every memory dir and every run. */
|
|
90
90
|
export declare const tidyWorkDir: (project: ResolvedProject, stamp: string, agent: string) => string;
|
|
91
|
-
/** Tidy the memory of the chosen agents, one after another. Only ever called by a person (`agent-lyceum
|
|
91
|
+
/** Tidy the memory of the chosen agents, one after another. Only ever called by a person (`agent-lyceum tidy`). */
|
|
92
92
|
export declare function tidyMemory(o: TidyOptions): Promise<TidyResult[]>;
|
|
93
93
|
export interface RestoreResult {
|
|
94
94
|
restored: string[];
|
package/dist/memory-tidy.js
CHANGED
|
@@ -255,7 +255,7 @@ async function tidyOne(o, t, stamp) {
|
|
|
255
255
|
writeTidyState(t.dir, { ...(changes?.head ? { head: changes.head } : {}), at: (o.now?.() ?? new Date()).toISOString(), archive: stamp });
|
|
256
256
|
return { ...base, status: "tidied", archive: stamp, problems: [] };
|
|
257
257
|
}
|
|
258
|
-
/** Tidy the memory of the chosen agents, one after another. Only ever called by a person (`agent-lyceum
|
|
258
|
+
/** Tidy the memory of the chosen agents, one after another. Only ever called by a person (`agent-lyceum tidy`). */
|
|
259
259
|
export async function tidyMemory(o) {
|
|
260
260
|
const say = o.say ?? ((s) => console.log(s));
|
|
261
261
|
const targets = targetsFor(o.project, { layer: o.layer, agent: o.agent });
|
package/dist/status.d.ts
CHANGED
|
@@ -110,7 +110,7 @@ export interface StatusReport {
|
|
|
110
110
|
};
|
|
111
111
|
agents: AgentReport[];
|
|
112
112
|
run?: RunReport;
|
|
113
|
-
/** Hints that a `
|
|
113
|
+
/** Hints that a `tidy` might help. Only a suggestion; nothing runs it. */
|
|
114
114
|
memory_advice?: string[];
|
|
115
115
|
}
|
|
116
116
|
export interface TaskListReport {
|
package/dist/status.js
CHANGED
|
@@ -430,6 +430,6 @@ export function formatStatusReport(report, now = Date.now(), color = false) {
|
|
|
430
430
|
if (run)
|
|
431
431
|
lines.push("", `輸出 tokens:${tokens(run.output_tokens)}`);
|
|
432
432
|
if (report.memory_advice?.length)
|
|
433
|
-
lines.push("", `記憶:${report.memory_advice.join(";")}(建議執行 agent-lyceum
|
|
433
|
+
lines.push("", `記憶:${report.memory_advice.join(";")}(建議執行 agent-lyceum tidy -p ${report.project.name};status 只提示,不會自動整理)`);
|
|
434
434
|
return lines.join("\n");
|
|
435
435
|
}
|