agentsmesh 0.24.0 → 0.26.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/CHANGELOG.md +45 -0
- package/README.md +104 -456
- package/dist/canonical.js +199 -147
- package/dist/canonical.js.map +1 -1
- package/dist/cli.js +249 -201
- package/dist/engine.js +213 -147
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +286 -207
- package/dist/index.js.map +1 -1
- package/dist/{init-YKxF2zpQ.d.ts → init-B0aI-g8W.d.ts} +1 -1
- package/dist/lessons.d.ts +2 -2
- package/dist/lessons.js +73 -60
- package/dist/lessons.js.map +1 -1
- package/dist/targets.js +111 -59
- package/dist/targets.js.map +1 -1
- package/package.json +3 -2
|
@@ -457,7 +457,7 @@ declare function toRelPath(projectRoot: string, absolute: string): string;
|
|
|
457
457
|
* survives generate → import → generate round-trip; only the wording inside each
|
|
458
458
|
* block is tightened for maximum agent compliance.
|
|
459
459
|
*/
|
|
460
|
-
declare const LESSONS_PROCEDURAL_RULE = "## Lessons (BLOCKING
|
|
460
|
+
declare const LESSONS_PROCEDURAL_RULE = "## Lessons (BLOCKING)\n\nGraph `.agentsmesh/lessons/lessons.json` is canonical; never hand-edit it. Manual: `lessons` skill.\n\n**Recall:** before every file edit or state-changing command, MUST run `agentsmesh lessons query --file <path> --cmd <command>` and obey matches. Pure-read commands and recall itself are exempt.\n\n**Capture:** after any failure, user correction, regression, wrong assumption, useful surprise, repeated friction, or non-obvious fix, MUST self-critique and run `agentsmesh lessons add \"<imperative rule>\" --topic <id> --trigger-file <glob> --evidence <sha|lesson-id>`.\n\n**Before final:** report `Lesson: captured <id>` or `Lesson: none`. No recall/capture gate = task incomplete. No shell: use `lessons_query` / `lessons_add`.";
|
|
461
461
|
|
|
462
462
|
interface ScaffoldLessonsResult {
|
|
463
463
|
readonly created: string[];
|
package/dist/lessons.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { o as RankedLesson, A as AddLessonInput, a as AddLessonOptions, b as AddLessonResult, j as LessonsQuery } from './init-
|
|
2
|
-
export { c as AddLessonTriggers, D as DEFAULT_RECALL_LIMIT, X as DEFAULT_RECALL_MAX_TOKENS, I as ImportLegacyOptions, d as ImportLegacyReport, Y as LESSONS_LOCK_FILENAME, L as LESSONS_PROCEDURAL_RULE, e as Lesson, f as LessonStatus, g as LessonsGraph, Z as LessonsGraphExistsError, h as LessonsGraphSchema, i as LessonsPaths, M as MatchedLesson, k as MergeLessonsOptions, l as MergeLessonsResult, m as MutateOptions, R as RankOptions, n as RankReason, S as ScaffoldLessonsResult, p as StripMarkersOptions, q as StripMarkersReport, T as Topic, r as Trigger, s as TriggerKind, U as UnknownTopicError, V as ValidationFinding, t as ValidationLevel, u as ValidationReport, v as acquireLessonsLock, w as addLesson, x as graphFilePath, y as importLegacyLessons, _ as lessonsLockPath, z as lessonsPaths, B as loadLessonsGraph, C as mergeLessons, E as mutateLessonsGraph, F as parseGraph, G as queryLessons, H as rankLessons, J as scaffoldLessons, K as serializeGraph, N as stripLegacyMarkers, O as stripMarkersInGraph, P as toRelPath, Q as tryLoadLessonsGraph, W as validateLessonsGraph } from './init-
|
|
1
|
+
import { o as RankedLesson, A as AddLessonInput, a as AddLessonOptions, b as AddLessonResult, j as LessonsQuery } from './init-B0aI-g8W.js';
|
|
2
|
+
export { c as AddLessonTriggers, D as DEFAULT_RECALL_LIMIT, X as DEFAULT_RECALL_MAX_TOKENS, I as ImportLegacyOptions, d as ImportLegacyReport, Y as LESSONS_LOCK_FILENAME, L as LESSONS_PROCEDURAL_RULE, e as Lesson, f as LessonStatus, g as LessonsGraph, Z as LessonsGraphExistsError, h as LessonsGraphSchema, i as LessonsPaths, M as MatchedLesson, k as MergeLessonsOptions, l as MergeLessonsResult, m as MutateOptions, R as RankOptions, n as RankReason, S as ScaffoldLessonsResult, p as StripMarkersOptions, q as StripMarkersReport, T as Topic, r as Trigger, s as TriggerKind, U as UnknownTopicError, V as ValidationFinding, t as ValidationLevel, u as ValidationReport, v as acquireLessonsLock, w as addLesson, x as graphFilePath, y as importLegacyLessons, _ as lessonsLockPath, z as lessonsPaths, B as loadLessonsGraph, C as mergeLessons, E as mutateLessonsGraph, F as parseGraph, G as queryLessons, H as rankLessons, J as scaffoldLessons, K as serializeGraph, N as stripLegacyMarkers, O as stripMarkersInGraph, P as toRelPath, Q as tryLoadLessonsGraph, W as validateLessonsGraph } from './init-B0aI-g8W.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/lessons.js
CHANGED
|
@@ -571,15 +571,15 @@ function lessonsPaths(projectRoot) {
|
|
|
571
571
|
function toRelPath(projectRoot, absolute) {
|
|
572
572
|
return relative(projectRoot, absolute).split(sep).join("/");
|
|
573
573
|
}
|
|
574
|
-
var LESSONS_PROCEDURAL_RULE = `## Lessons (BLOCKING
|
|
574
|
+
var LESSONS_PROCEDURAL_RULE = `## Lessons (BLOCKING)
|
|
575
575
|
|
|
576
|
-
Graph \`.agentsmesh/lessons/lessons.json\` is canonical
|
|
576
|
+
Graph \`.agentsmesh/lessons/lessons.json\` is canonical; never hand-edit it. Manual: \`lessons\` skill.
|
|
577
577
|
|
|
578
|
-
**Recall
|
|
578
|
+
**Recall:** before every file edit or state-changing command, MUST run \`agentsmesh lessons query --file <path> --cmd <command>\` and obey matches. Pure-read commands and recall itself are exempt.
|
|
579
579
|
|
|
580
|
-
**Capture
|
|
580
|
+
**Capture:** after any failure, user correction, regression, wrong assumption, useful surprise, repeated friction, or non-obvious fix, MUST self-critique and run \`agentsmesh lessons add "<imperative rule>" --topic <id> --trigger-file <glob> --evidence <sha|lesson-id>\`.
|
|
581
581
|
|
|
582
|
-
|
|
582
|
+
**Before final:** report \`Lesson: captured <id>\` or \`Lesson: none\`. No recall/capture gate = task incomplete. No shell: use \`lessons_query\` / \`lessons_add\`.`;
|
|
583
583
|
|
|
584
584
|
// src/lessons/import-legacy.ts
|
|
585
585
|
var LessonsGraphExistsError = class extends Error {
|
|
@@ -1618,15 +1618,27 @@ function validateLessonsGraph(graph, options = {}) {
|
|
|
1618
1618
|
function emptyGraph() {
|
|
1619
1619
|
return { version: 1, lessons: {}, topics: {}, triggers: {} };
|
|
1620
1620
|
}
|
|
1621
|
+
function findingKey(f) {
|
|
1622
|
+
return `${f.code}|${f.triggerId ?? ""}|${f.lessonId ?? ""}`;
|
|
1623
|
+
}
|
|
1624
|
+
function errorSignatures(report) {
|
|
1625
|
+
return new Set(report.findings.filter((f) => f.level === "error").map(findingKey));
|
|
1626
|
+
}
|
|
1621
1627
|
async function mutateLessonsGraphLocked(projectRoot, mutator, options = {}) {
|
|
1622
1628
|
const release = await acquireLessonsLock(projectRoot, { retries: options.retries });
|
|
1623
1629
|
try {
|
|
1624
1630
|
const graph = tryLoadLessonsGraph(projectRoot) ?? emptyGraph();
|
|
1631
|
+
const baseline = errorSignatures(validateLessonsGraph(graph));
|
|
1625
1632
|
const result = await mutator(graph);
|
|
1626
1633
|
const report = validateLessonsGraph(graph);
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1634
|
+
const introduced = report.findings.filter(
|
|
1635
|
+
(f) => f.level === "error" && !baseline.has(findingKey(f))
|
|
1636
|
+
);
|
|
1637
|
+
if (introduced.length > 0) {
|
|
1638
|
+
const errors = introduced.map((f) => `${f.code}: ${f.message}`).join("; ");
|
|
1639
|
+
throw new Error(
|
|
1640
|
+
`mutateLessonsGraph: refusing to write \u2014 this change introduces ${errors}. (Pre-existing graph issues are not blocking; run \`agentsmesh lessons validate\` to review and \`lessons untrigger\`/\`prune\` to repair them.)`
|
|
1641
|
+
);
|
|
1630
1642
|
}
|
|
1631
1643
|
saveLessonsGraph(projectRoot, graph);
|
|
1632
1644
|
return result;
|
|
@@ -2586,6 +2598,17 @@ ${placed}` : placed;
|
|
|
2586
2598
|
}
|
|
2587
2599
|
|
|
2588
2600
|
// src/targets/projection/lessons-paragraph.ts
|
|
2601
|
+
var LEGACY_RAW_FORMS = [
|
|
2602
|
+
`## Lessons (BLOCKING REQUIREMENT \u2014 MUST run both, no exceptions; the user will check)
|
|
2603
|
+
|
|
2604
|
+
Graph \`.agentsmesh/lessons/lessons.json\` is canonical \u2014 never hand-edit. Manual: the \`lessons\` skill.
|
|
2605
|
+
|
|
2606
|
+
**Recall \u2014 MUST run before every file edit and every state-changing command** (build/test/install/migrate/git-write): \`agentsmesh lessons query --file <path> --cmd <command>\`, then apply every rule. Pure-read commands (cat/ls/grep/git-log) and the recall query itself are exempt.
|
|
2607
|
+
|
|
2608
|
+
**Capture \u2014 MUST run immediately after any failure** (a failing test/CI/lint/typecheck, a code review, a user correction, a regression, or a wrong assumption \u2014 yours or anyone's): \`agentsmesh lessons add "<rule>" --topic <id> --trigger-file <glob> --evidence <sha|lesson-id>\`.
|
|
2609
|
+
|
|
2610
|
+
No shell? Use the \`lessons_query\` / \`lessons_add\` MCP tools. Skip either and the system does not exist.`
|
|
2611
|
+
];
|
|
2589
2612
|
var LESSONS_PARAGRAPH_BLOCK = `${LESSONS_CONTRACT_START}
|
|
2590
2613
|
${LESSONS_PROCEDURAL_RULE}
|
|
2591
2614
|
${LESSONS_CONTRACT_END}`;
|
|
@@ -2598,9 +2621,12 @@ function stripLessonsParagraph(content) {
|
|
|
2598
2621
|
return stripRawProceduralRule(withoutBlock).trim();
|
|
2599
2622
|
}
|
|
2600
2623
|
function stripRawProceduralRule(content) {
|
|
2601
|
-
return
|
|
2624
|
+
return [LESSONS_PROCEDURAL_RULE, ...LEGACY_RAW_FORMS].reduce(
|
|
2625
|
+
(next, rule) => next.replace(`
|
|
2602
2626
|
|
|
2603
|
-
${
|
|
2627
|
+
${rule}`, "").replace(rule, ""),
|
|
2628
|
+
content
|
|
2629
|
+
);
|
|
2604
2630
|
}
|
|
2605
2631
|
function serializeFrontmatter(frontmatter, body) {
|
|
2606
2632
|
const keys = Object.keys(frontmatter);
|
|
@@ -2615,68 +2641,55 @@ ${body}`;
|
|
|
2615
2641
|
|
|
2616
2642
|
// src/lessons/skill.ts
|
|
2617
2643
|
var LESSONS_SKILL_NAME = "lessons";
|
|
2618
|
-
var LESSONS_SKILL_DESCRIPTION = "
|
|
2619
|
-
var LESSONS_SKILL_BODY = `# Lessons \u2014 operating manual
|
|
2620
|
-
|
|
2621
|
-
Two commands: **Recall** before you act, **Capture** after any failure. The graph
|
|
2622
|
-
\`.agentsmesh/lessons/lessons.json\` is canonical \u2014 never hand-edit.
|
|
2623
|
-
|
|
2624
|
-
## Recall \u2014 before each file edit and each state-changing command
|
|
2644
|
+
var LESSONS_SKILL_DESCRIPTION = "Use when about to edit a file or run a state-changing command, or after any failure, correction, or surprising result.";
|
|
2645
|
+
var LESSONS_SKILL_BODY = `# Lessons \u2014 operating manual (Iron Law)
|
|
2625
2646
|
|
|
2626
|
-
|
|
2627
|
-
match by task), then apply every rule returned. Scope is MUTATING actions: file edits
|
|
2628
|
-
and state-changing commands (build/test/install/migrate/git-write). Pure-read commands
|
|
2629
|
-
(cat/ls/grep/git-log; read-only) and the recall query itself are **exempt** \u2014 no
|
|
2630
|
-
infinite regress. A predicate-less query is rejected; **keyword-only recall is the
|
|
2631
|
-
anti-pattern** \u2014 most lessons are keyed to a \`file_glob\`/\`command_pattern\` and won't
|
|
2632
|
-
surface (the CLI warns). Excuses ("small edit", "I already know this", "later") all
|
|
2633
|
-
mean: query first \u2014 skipping recall on a mutating action is a process violation, and
|
|
2634
|
-
the user will check.
|
|
2647
|
+
## The Iron Law
|
|
2635
2648
|
|
|
2636
|
-
|
|
2649
|
+
**NO MUTATION WITHOUT RECALL. NO COMPLETION WITHOUT A CAPTURE DECISION.**
|
|
2637
2650
|
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
\`
|
|
2651
|
+
Violating the letter is violating the spirit. Edited a file or ran a state-changing
|
|
2652
|
+
command without recall? Process violation. Did the turn hit a failure / correction /
|
|
2653
|
+
regression / wrong assumption / surprise and you have not captured (nor stated
|
|
2654
|
+
\`Lesson: none\`)? The task is INCOMPLETE \u2014 and the user will check. The graph
|
|
2655
|
+
\`.agentsmesh/lessons/lessons.json\` is canonical \u2014 never hand-edit.
|
|
2642
2656
|
|
|
2643
|
-
|
|
2644
|
-
(\`UNRECALLABLE_LESSON\`) when EVERY trigger is dead on the mandatory \`--file\`/\`--cmd\`
|
|
2645
|
-
recall path \u2014 a stopword-only keyword ("state of the art"), or an invalid/ReDoS
|
|
2646
|
-
command regex \u2014 because the lesson could never be recalled there. Prefer
|
|
2647
|
-
\`--trigger-file\`: the most reliable trigger, it fires on \`--file\` recall. A keyword
|
|
2648
|
-
alone is discouraged (\`KEYWORD_ONLY_LESSON\`); paraphrasing an existing rule warns
|
|
2649
|
-
(\`NEAR_DUPLICATE_LESSON\` \u2014 update that lesson instead).
|
|
2650
|
-
- **One imperative sentence.** A rule over 2000 chars is rejected (\`OVERSIZED_RULE\`) \u2014
|
|
2651
|
-
trim it or split into separate lessons; don't paste a log/diff.
|
|
2652
|
-
- Widen with \`--trigger-cmd <regex>\` / \`--trigger-kw <text>\`. New area:
|
|
2653
|
-
\`--new-topic --topic-summary "<line>"\` (list ids with \`agentsmesh lessons topics\`).
|
|
2657
|
+
## Recall \u2014 before each file edit and each state-changing command
|
|
2654
2658
|
|
|
2655
|
-
|
|
2659
|
+
\`agentsmesh lessons query --file <path> --cmd <command>\`, then apply every rule.
|
|
2660
|
+
Pure-read commands (read-only) and the query itself are exempt. **keyword-only recall
|
|
2661
|
+
is the anti-pattern** \u2014 lessons are keyed to a \`file_glob\`/\`command_pattern\`.
|
|
2656
2662
|
|
|
2657
|
-
|
|
2658
|
-
\`lessons_deprecate\` (retire). validate / prune / merge / import-md are CLI-only.
|
|
2663
|
+
## Capture \u2014 Gate Function (before any completion claim)
|
|
2659
2664
|
|
|
2660
|
-
|
|
2665
|
+
1. **SELF-CRITIQUE**: any failure, correction, regression, wrong assumption,
|
|
2666
|
+
useful surprise, repeated friction, or non-obvious fix? Failing
|
|
2667
|
+
tests/lint/typecheck and user/review corrections \u2014 yours or anyone's \u2014 all count.
|
|
2668
|
+
2. **CAPTURE** a reusable imperative rule with an effective trigger (else say so):
|
|
2669
|
+
\`agentsmesh lessons add "<rule>" --topic <id> --trigger-file <glob>\`
|
|
2670
|
+
3. **RECEIPT**: emit \`Lesson: captured <id>\` or \`Lesson: none\`.
|
|
2661
2671
|
|
|
2662
|
-
|
|
2663
|
-
\`
|
|
2664
|
-
|
|
2665
|
-
|
|
2672
|
+
At least one _effective_ trigger is required or the capture is rejected
|
|
2673
|
+
(\`UNRECALLABLE_LESSON\`); prefer \`--trigger-file\`. No shell \u2192 MCP \`lessons_query\`,
|
|
2674
|
+
\`lessons_add\`, \`lessons_topics\`, \`lessons_show\`, \`lessons_deprecate\`. Run
|
|
2675
|
+
\`agentsmesh lessons --help\` for every subcommand and flag: query, add, topics, show,
|
|
2676
|
+
deprecate, merge, untrigger, strip-markers, prune, journal, validate, stats, import-md.
|
|
2666
2677
|
|
|
2667
|
-
|
|
2678
|
+
### Rationalization Prevention \u2014 these excuses mean STOP
|
|
2668
2679
|
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2680
|
+
| Excuse | Reality |
|
|
2681
|
+
| --- | --- |
|
|
2682
|
+
| "Small edit / I already know this / later" | Query first \u2014 skipping recall is a process violation |
|
|
2683
|
+
| "Nothing reusable here" | You hit a failure/surprise \u2014 name it or capture it |
|
|
2684
|
+
| "My own TDD red, not a real failure" | A red you did not predict IS a lesson |
|
|
2685
|
+
| "I fixed one site; the twin is obvious" | Capture it \u2014 the unfixed twin is what gets missed |
|
|
2686
|
+
| "Different words, so the rule doesn't apply" | Spirit over letter |
|
|
2674
2687
|
|
|
2675
|
-
##
|
|
2688
|
+
## Lesson gate \u2014 before final response
|
|
2676
2689
|
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2690
|
+
The final response MUST carry the receipt: \`Lesson: captured <id>\` or \`Lesson: none\`.
|
|
2691
|
+
No receipt = task incomplete. Do not capture one-off facts, task summaries, or project
|
|
2692
|
+
context \u2014 only reusable imperative rules with an effective trigger.`;
|
|
2680
2693
|
var LESSONS_SKILL_FILE = serializeFrontmatter(
|
|
2681
2694
|
{ name: LESSONS_SKILL_NAME, description: LESSONS_SKILL_DESCRIPTION },
|
|
2682
2695
|
LESSONS_SKILL_BODY
|