@mmnto/totem 1.34.1 → 1.34.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.
@@ -4,8 +4,14 @@ export declare const SENTINEL_END = "<!-- totem:generated:end -->";
4
4
  /**
5
5
  * Format parsed lessons as a markdown block for injection into AI config files.
6
6
  * Always generates sentinel markers (even for empty lessons) to preserve idempotency.
7
+ *
8
+ * When `archivedReasonByHash` is provided, lessons whose content-hash is in the
9
+ * map get an `_(archived: <reason>)_` suffix so a reading agent can weight the
10
+ * guidance appropriately. Empty / missing reasons fall back to a plain bullet
11
+ * (Tenet 4 spirit — surface the rule loudly even with degraded metadata).
12
+ * Per mmnto-ai/totem#1873.
7
13
  */
8
- export declare function formatLessonsAsMarkdown(lessons: ParsedLesson[]): string;
14
+ export declare function formatLessonsAsMarkdown(lessons: ParsedLesson[], archivedReasonByHash?: ReadonlyMap<string, string>): string;
9
15
  /**
10
16
  * Inject a generated block between sentinel markers in file content.
11
17
  * - If sentinels exist: replaces content between them (inclusive)
@@ -16,6 +22,10 @@ export declare function injectSentinelBlock(existingContent: string, generatedBl
16
22
  /**
17
23
  * Export formatted lessons to a target file path.
18
24
  * Creates directories if needed. Uses sentinel-based injection for idempotent updates.
25
+ *
26
+ * When `archivedReasonByHash` is provided, lessons whose content-hash appears
27
+ * in the map render with an `_(archived: <reason>)_` annotation suffix
28
+ * (mmnto-ai/totem#1873).
19
29
  */
20
- export declare function exportLessons(lessons: ParsedLesson[], targetPath: string): void;
30
+ export declare function exportLessons(lessons: ParsedLesson[], targetPath: string, archivedReasonByHash?: ReadonlyMap<string, string>): void;
21
31
  //# sourceMappingURL=exporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAKxD,eAAO,MAAM,cAAc,mCAAmC,CAAC;AAC/D,eAAO,MAAM,YAAY,iCAAiC,CAAC;AAI3D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAoBvE;AAID;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CA6B3F;AAID;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAe/E"}
1
+ {"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAKxD,eAAO,MAAM,cAAc,mCAAmC,CAAC;AAC/D,eAAO,MAAM,YAAY,iCAAiC,CAAC;AAI3D;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,YAAY,EAAE,EACvB,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACjD,MAAM,CA6BR;AAID;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CA6B3F;AAID;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,YAAY,EAAE,EACvB,UAAU,EAAE,MAAM,EAClB,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACjD,IAAI,CAeN"}
package/dist/exporter.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
+ import { hashLesson } from './compiler.js';
3
4
  import { TotemParseError } from './errors.js';
4
5
  // ─── Constants ─────────────────────────────────────────
5
6
  export const SENTINEL_START = '<!-- totem:generated:start -->';
@@ -8,8 +9,14 @@ export const SENTINEL_END = '<!-- totem:generated:end -->';
8
9
  /**
9
10
  * Format parsed lessons as a markdown block for injection into AI config files.
10
11
  * Always generates sentinel markers (even for empty lessons) to preserve idempotency.
12
+ *
13
+ * When `archivedReasonByHash` is provided, lessons whose content-hash is in the
14
+ * map get an `_(archived: <reason>)_` suffix so a reading agent can weight the
15
+ * guidance appropriately. Empty / missing reasons fall back to a plain bullet
16
+ * (Tenet 4 spirit — surface the rule loudly even with degraded metadata).
17
+ * Per mmnto-ai/totem#1873.
11
18
  */
12
- export function formatLessonsAsMarkdown(lessons) {
19
+ export function formatLessonsAsMarkdown(lessons, archivedReasonByHash) {
13
20
  const lines = [
14
21
  SENTINEL_START,
15
22
  '<!-- Auto-generated by `totem compile --export`. Do not edit between these markers. -->',
@@ -17,12 +24,22 @@ export function formatLessonsAsMarkdown(lessons) {
17
24
  '## Totem Project Rules',
18
25
  '',
19
26
  ];
27
+ const escapeMarkdown = (s) => s.replace(/[*_]/g, '\\$&');
28
+ // Strip C0 control bytes (incl. CR/LF/TAB) so an archivedReason copied
29
+ // from an operator's terminal session cannot break the bullet shape or
30
+ // bleed across lines. Mirrors the sanitizing discipline applied to
31
+ // lesson body content above (per CR mmnto-ai/totem#1878).
32
+ const sanitizeReason = (s) => escapeMarkdown(s.replace(/[\x00-\x1F\x7F]/g, ' ').trim());
20
33
  for (const lesson of lessons) {
21
- const escapeMarkdown = (s) => s.replace(/[*_]/g, '\\$&');
22
34
  const heading = escapeMarkdown(lesson.heading);
23
35
  const bodyOneLine = escapeMarkdown(lesson.body.replace(/\n+/g, ' ').trim());
24
- const suffix = lesson.tags.length > 0 ? ` ${bodyOneLine} _(${lesson.tags.join(', ')})_` : ` ${bodyOneLine}`;
25
- lines.push(`- **${heading}** -${suffix}`);
36
+ const tagSuffix = lesson.tags.length > 0 ? ` _(${lesson.tags.join(', ')})_` : '';
37
+ const rawReason = archivedReasonByHash
38
+ ? archivedReasonByHash.get(hashLesson(lesson.heading, lesson.body))
39
+ : undefined;
40
+ const cleanedReason = rawReason ? sanitizeReason(rawReason) : '';
41
+ const archivedSuffix = cleanedReason ? ` _(archived: ${cleanedReason})_` : '';
42
+ lines.push(`- **${heading}** - ` + bodyOneLine + tagSuffix + archivedSuffix);
26
43
  }
27
44
  lines.push('', SENTINEL_END);
28
45
  return lines.join('\n');
@@ -60,13 +77,17 @@ export function injectSentinelBlock(existingContent, generatedBlock) {
60
77
  /**
61
78
  * Export formatted lessons to a target file path.
62
79
  * Creates directories if needed. Uses sentinel-based injection for idempotent updates.
80
+ *
81
+ * When `archivedReasonByHash` is provided, lessons whose content-hash appears
82
+ * in the map render with an `_(archived: <reason>)_` annotation suffix
83
+ * (mmnto-ai/totem#1873).
63
84
  */
64
- export function exportLessons(lessons, targetPath) {
85
+ export function exportLessons(lessons, targetPath, archivedReasonByHash) {
65
86
  const dir = path.dirname(targetPath);
66
87
  if (!fs.existsSync(dir)) {
67
88
  fs.mkdirSync(dir, { recursive: true });
68
89
  }
69
- const generatedBlock = formatLessonsAsMarkdown(lessons);
90
+ const generatedBlock = formatLessonsAsMarkdown(lessons, archivedReasonByHash);
70
91
  if (fs.existsSync(targetPath)) {
71
92
  const existing = fs.readFileSync(targetPath, 'utf-8');
72
93
  const updated = injectSentinelBlock(existing, generatedBlock);
@@ -1 +1 @@
1
- {"version":3,"file":"exporter.js","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,0DAA0D;AAE1D,MAAM,CAAC,MAAM,cAAc,GAAG,gCAAgC,CAAC;AAC/D,MAAM,CAAC,MAAM,YAAY,GAAG,8BAA8B,CAAC;AAE3D,wDAAwD;AAExD;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAuB;IAC7D,MAAM,KAAK,GAAa;QACtB,cAAc;QACd,yFAAyF;QACzF,EAAE;QACF,wBAAwB;QACxB,EAAE;KACH,CAAC;IAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,cAAc,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5E,MAAM,MAAM,GACV,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC;QAC/F,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,OAAO,MAAM,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,wDAAwD;AAExD;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,eAAuB,EAAE,cAAsB;IACjF,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAErD,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,eAAe,CACvB,SAAS,cAAc,qBAAqB,YAAY,GAAG,EAC3D,gGAAgG,CACjG,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC1D,MAAM,IAAI,eAAe,CACvB,SAAS,YAAY,WAAW,cAAc,GAAG,EACjD,qFAAqF,CACtF,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAClE,OAAO,MAAM,GAAG,cAAc,GAAG,KAAK,CAAC;IACzC,CAAC;IAED,4DAA4D;IAC5D,IAAI,cAAc,KAAK,EAAE;QAAE,OAAO,eAAe,CAAC;IAClD,IAAI,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,cAAc,GAAG,IAAI,CAAC;IAChE,MAAM,SAAS,GAAG,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACjE,OAAO,eAAe,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,CAAC;AAC7D,CAAC;AAED,yDAAyD;AAEzD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAuB,EAAE,UAAkB;IACvE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,cAAc,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAExD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC9D,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"exporter.js","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmnto/totem",
3
- "version": "1.34.1",
3
+ "version": "1.34.2",
4
4
  "description": "Persistent memory and context layer for AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",