patchwork-os 1.1.0-beta.4.canary.511 → 1.1.0-beta.4.canary.512

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.
@@ -23,6 +23,7 @@ import type { ButlerFact } from "./types.js";
23
23
  export declare const MAX_CARD_BYTES = 2048;
24
24
  export declare const MAX_FACT_CHARS = 80;
25
25
  export declare const DEFAULT_MAX_FACTS = 12;
26
+ export declare function sanitizeForPrompt(s: string): string;
26
27
  export interface MemoryCardOpts {
27
28
  now: number;
28
29
  maxFacts?: number;
@@ -38,6 +38,34 @@ function age(recordedAt, now) {
38
38
  return `${mo}mo ago`;
39
39
  return `${Math.floor(d / 365)}y ago`;
40
40
  }
41
+ /**
42
+ * Collapse anything that could forge structure in the instructions block.
43
+ *
44
+ * This card renders fact text straight into a SYSTEM PROMPT. The store
45
+ * deliberately accepts any UTF-8 except NUL (a belief is arbitrary text), so
46
+ * the safety boundary has to be here, at the point of rendering — and it has
47
+ * to be here rather than at write time, because rows written before this
48
+ * existed are already on disk.
49
+ *
50
+ * Stripped:
51
+ * - C0/C1 controls including \n and \r — a newline lets a value emit a
52
+ * second line and impersonate a real instruction heading; a lone \r
53
+ * rewrites the line in a terminal render.
54
+ * - U+2028/U+2029 — Unicode line/paragraph separators, newlines by another
55
+ * name in most renderers.
56
+ * - U+202A–U+202E, U+2066–U+2069 — bidi overrides, which reorder displayed
57
+ * text without changing the bytes, so a value can appear to say something
58
+ * other than what is stored.
59
+ *
60
+ * Replaced with a space, not removed: deleting them would silently join words
61
+ * that were separate, which changes the meaning of the belief.
62
+ */
63
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: stripping control
64
+ // characters is the entire purpose of this expression.
65
+ const UNSAFE_IN_PROMPT = /[\u0000-\u001F\u007F-\u009F\u2028\u2029\u202A-\u202E\u2066-\u2069]/g;
66
+ export function sanitizeForPrompt(s) {
67
+ return s.replace(UNSAFE_IN_PROMPT, " ").replace(/\s+/g, " ").trim();
68
+ }
41
69
  function truncate(s, max) {
42
70
  return s.length <= max ? s : `${s.slice(0, max - 1)}…`;
43
71
  }
@@ -61,7 +89,10 @@ export function buildMemoryCard(facts, opts) {
61
89
  const lines = [
62
90
  "WHAT YOU KNOW ABOUT THE USER (Butler memory):",
63
91
  ...shown.map((f) => {
64
- const body = truncate(`${f.subject} ${f.predicate}: ${f.object}`, MAX_FACT_CHARS);
92
+ // Sanitise BEFORE truncating: truncation must not be able to leave a
93
+ // dangling half-escape, and the length budget should count the text
94
+ // that is actually rendered.
95
+ const body = truncate(sanitizeForPrompt(`${f.subject} ${f.predicate}: ${f.object}`), MAX_FACT_CHARS);
65
96
  return ` • ${body} (${age(f.recordedAt, opts.now)})`;
66
97
  }),
67
98
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"memoryCard.js","sourceRoot":"","sources":["../../src/butler/memoryCard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,sEAAsE;AACtE,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC;AACpC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,MAAM,GAAG,GAAG,UAAU,CAAC;AAEvB,8EAA8E;AAC9E,SAAS,GAAG,CAAC,UAAkB,EAAE,GAAW;IAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;IAC/C,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC;IAC3B,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC/B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9B,IAAI,EAAE,GAAG,EAAE;QAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;IAClC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;AACvC,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS,EAAE,GAAW;IACtC,OAAO,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;AACzD,CAAC;AAYD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,KAA4B,EAC5B,IAAoB;IAEpB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,mBAAmB,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,cAAc,CAAC;IAEjD,MAAM,QAAQ,GAAG,KAAK;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC;QACnC,sEAAsE;SACrE,KAAK,EAAE;SACP,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;IAE/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG;QACZ,+CAA+C;QAC/C,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACjB,MAAM,IAAI,GAAG,QAAQ,CACnB,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,MAAM,EAAE,EAC1C,cAAc,CACf,CAAC;YACF,OAAO,OAAO,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QACxD,CAAC,CAAC;KACH,CAAC;IAEF,IAAI,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAE7C,0EAA0E;IAC1E,yDAAyD;IACzD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,QAAQ,EAAE,CAAC;QAC9D,KAAK,CAAC,GAAG,EAAE,CAAC;QACZ,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,2EAA2E;IAC3E,0BAA0B;IAC1B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CACR,MAAM,OAAO,uDAAuD,CACrE,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CACR,kFAAkF,CACnF,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,yEAAyE;AACzE,SAAS,OAAO,CAAC,KAAe,EAAE,OAAe;IAC/C,MAAM,KAAK,GACT,OAAO,GAAG,CAAC;QACT,CAAC,CAAC,MAAM,OAAO,yDAAyD;aACnE,MAAM;QACX,CAAC,CAAC,CAAC,CAAC;IACR,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;AAC7D,CAAC"}
1
+ {"version":3,"file":"memoryCard.js","sourceRoot":"","sources":["../../src/butler/memoryCard.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchwork-os",
3
- "version": "1.1.0-beta.4.canary.511",
3
+ "version": "1.1.0-beta.4.canary.512",
4
4
  "description": "Your personal AI runtime, local-first. Patchwork OS gives any AI model a consistent set of tools, YAML recipes, a delegation policy with approval queue, and a durable trace memory — all on your machine, all under your policy.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",