@te-river/opencode-team-mode 1.5.5 → 1.5.6

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.
Files changed (158) hide show
  1. package/README.md +732 -634
  2. package/README.zh-CN.md +655 -576
  3. package/dist/agents.d.ts +6 -1
  4. package/dist/agents.d.ts.map +1 -1
  5. package/dist/agents.js +103 -531
  6. package/dist/agents.js.map +1 -1
  7. package/dist/approval-gate.d.ts +16 -0
  8. package/dist/approval-gate.d.ts.map +1 -1
  9. package/dist/approval-gate.js +8 -1
  10. package/dist/approval-gate.js.map +1 -1
  11. package/dist/blackboard.d.ts.map +1 -1
  12. package/dist/blackboard.js +3 -2
  13. package/dist/blackboard.js.map +1 -1
  14. package/dist/commands.d.ts.map +1 -1
  15. package/dist/commands.js +7 -6
  16. package/dist/commands.js.map +1 -1
  17. package/dist/envprotect/bash-classify.d.ts +42 -0
  18. package/dist/envprotect/bash-classify.d.ts.map +1 -0
  19. package/dist/envprotect/bash-classify.js +221 -0
  20. package/dist/envprotect/bash-classify.js.map +1 -0
  21. package/dist/envprotect/gate-predicates.d.ts +57 -0
  22. package/dist/envprotect/gate-predicates.d.ts.map +1 -0
  23. package/dist/envprotect/gate-predicates.js +174 -0
  24. package/dist/envprotect/gate-predicates.js.map +1 -0
  25. package/dist/envprotect/hook.d.ts +45 -0
  26. package/dist/envprotect/hook.d.ts.map +1 -0
  27. package/dist/envprotect/hook.js +158 -0
  28. package/dist/envprotect/hook.js.map +1 -0
  29. package/dist/envprotect/path-classify.d.ts +16 -0
  30. package/dist/envprotect/path-classify.d.ts.map +1 -0
  31. package/dist/envprotect/path-classify.js +72 -0
  32. package/dist/envprotect/path-classify.js.map +1 -0
  33. package/dist/envprotect/patterns.d.ts +77 -0
  34. package/dist/envprotect/patterns.d.ts.map +1 -0
  35. package/dist/envprotect/patterns.js +182 -0
  36. package/dist/envprotect/patterns.js.map +1 -0
  37. package/dist/envprotect.d.ts +19 -217
  38. package/dist/envprotect.d.ts.map +1 -1
  39. package/dist/envprotect.js +18 -803
  40. package/dist/envprotect.js.map +1 -1
  41. package/dist/fs-safe.d.ts +16 -0
  42. package/dist/fs-safe.d.ts.map +1 -0
  43. package/dist/fs-safe.js +56 -0
  44. package/dist/fs-safe.js.map +1 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +22 -6
  47. package/dist/index.js.map +1 -1
  48. package/dist/prompts/lead.d.ts +7 -0
  49. package/dist/prompts/lead.d.ts.map +1 -0
  50. package/dist/prompts/lead.js +230 -0
  51. package/dist/prompts/lead.js.map +1 -0
  52. package/dist/prompts/shared.d.ts +8 -0
  53. package/dist/prompts/shared.d.ts.map +1 -0
  54. package/dist/prompts/shared.js +118 -0
  55. package/dist/prompts/shared.js.map +1 -0
  56. package/dist/prompts/specialists.d.ts +12 -0
  57. package/dist/prompts/specialists.d.ts.map +1 -0
  58. package/dist/prompts/specialists.js +218 -0
  59. package/dist/prompts/specialists.js.map +1 -0
  60. package/dist/shell-text.d.ts +14 -0
  61. package/dist/shell-text.d.ts.map +1 -0
  62. package/dist/shell-text.js +16 -0
  63. package/dist/shell-text.js.map +1 -0
  64. package/dist/tm/args-schema.d.ts +36 -0
  65. package/dist/tm/args-schema.d.ts.map +1 -0
  66. package/dist/tm/args-schema.js +191 -0
  67. package/dist/tm/args-schema.js.map +1 -0
  68. package/dist/tm/browser.d.ts +52 -0
  69. package/dist/tm/browser.d.ts.map +1 -0
  70. package/dist/tm/browser.js +361 -0
  71. package/dist/tm/browser.js.map +1 -0
  72. package/dist/tm/client-unwrap.d.ts +38 -0
  73. package/dist/tm/client-unwrap.d.ts.map +1 -0
  74. package/dist/tm/client-unwrap.js +113 -0
  75. package/dist/tm/client-unwrap.js.map +1 -0
  76. package/dist/tm/config.d.ts +46 -18
  77. package/dist/tm/config.d.ts.map +1 -1
  78. package/dist/tm/config.js +60 -17
  79. package/dist/tm/config.js.map +1 -1
  80. package/dist/tm/guard.d.ts.map +1 -1
  81. package/dist/tm/guard.js +4 -7
  82. package/dist/tm/guard.js.map +1 -1
  83. package/dist/tm/index.d.ts +15 -5
  84. package/dist/tm/index.d.ts.map +1 -1
  85. package/dist/tm/index.js +95 -19
  86. package/dist/tm/index.js.map +1 -1
  87. package/dist/tm/memory.d.ts +82 -0
  88. package/dist/tm/memory.d.ts.map +1 -0
  89. package/dist/tm/memory.js +350 -0
  90. package/dist/tm/memory.js.map +1 -0
  91. package/dist/tm/pipelines.d.ts +58 -0
  92. package/dist/tm/pipelines.d.ts.map +1 -0
  93. package/dist/tm/pipelines.js +301 -0
  94. package/dist/tm/pipelines.js.map +1 -0
  95. package/dist/tm/preview.d.ts +6 -1
  96. package/dist/tm/preview.d.ts.map +1 -1
  97. package/dist/tm/preview.js +31 -8
  98. package/dist/tm/preview.js.map +1 -1
  99. package/dist/tm/ptc/budgets.d.ts +38 -0
  100. package/dist/tm/ptc/budgets.d.ts.map +1 -0
  101. package/dist/tm/ptc/budgets.js +59 -0
  102. package/dist/tm/ptc/budgets.js.map +1 -0
  103. package/dist/tm/ptc/contract.d.ts +131 -0
  104. package/dist/tm/ptc/contract.d.ts.map +1 -0
  105. package/dist/tm/ptc/contract.js +47 -0
  106. package/dist/tm/ptc/contract.js.map +1 -0
  107. package/dist/tm/ptc/driver.d.ts +37 -0
  108. package/dist/tm/ptc/driver.d.ts.map +1 -0
  109. package/dist/tm/ptc/driver.js +181 -0
  110. package/dist/tm/ptc/driver.js.map +1 -0
  111. package/dist/tm/ptc/engines.d.ts +32 -0
  112. package/dist/tm/ptc/engines.d.ts.map +1 -0
  113. package/dist/tm/ptc/engines.js +201 -0
  114. package/dist/tm/ptc/engines.js.map +1 -0
  115. package/dist/tm/ptc/gate.d.ts +28 -0
  116. package/dist/tm/ptc/gate.d.ts.map +1 -0
  117. package/dist/tm/ptc/gate.js +127 -0
  118. package/dist/tm/ptc/gate.js.map +1 -0
  119. package/dist/tm/ptc/index.d.ts +19 -0
  120. package/dist/tm/ptc/index.d.ts.map +1 -0
  121. package/dist/tm/ptc/index.js +15 -0
  122. package/dist/tm/ptc/index.js.map +1 -0
  123. package/dist/tm/ptc/pscan.d.ts +11 -0
  124. package/dist/tm/ptc/pscan.d.ts.map +1 -0
  125. package/dist/tm/ptc/pscan.js +27 -0
  126. package/dist/tm/ptc/pscan.js.map +1 -0
  127. package/dist/tm/ptc/summary.d.ts +17 -0
  128. package/dist/tm/ptc/summary.d.ts.map +1 -0
  129. package/dist/tm/ptc/summary.js +107 -0
  130. package/dist/tm/ptc/summary.js.map +1 -0
  131. package/dist/tm/ptc/tool.d.ts +35 -0
  132. package/dist/tm/ptc/tool.d.ts.map +1 -0
  133. package/dist/tm/ptc/tool.js +135 -0
  134. package/dist/tm/ptc/tool.js.map +1 -0
  135. package/dist/tm/ptc.d.ts +45 -26
  136. package/dist/tm/ptc.d.ts.map +1 -1
  137. package/dist/tm/ptc.js +71 -45
  138. package/dist/tm/ptc.js.map +1 -1
  139. package/dist/tm/result.d.ts +34 -0
  140. package/dist/tm/result.d.ts.map +1 -0
  141. package/dist/tm/result.js +87 -0
  142. package/dist/tm/result.js.map +1 -0
  143. package/dist/tm/shell-bridge.d.ts +22 -0
  144. package/dist/tm/shell-bridge.d.ts.map +1 -0
  145. package/dist/tm/shell-bridge.js +70 -0
  146. package/dist/tm/shell-bridge.js.map +1 -0
  147. package/dist/tm/store.d.ts.map +1 -1
  148. package/dist/tm/store.js +2 -1
  149. package/dist/tm/store.js.map +1 -1
  150. package/dist/tm/tools.d.ts +13 -71
  151. package/dist/tm/tools.d.ts.map +1 -1
  152. package/dist/tm/tools.js +21 -655
  153. package/dist/tm/tools.js.map +1 -1
  154. package/dist/tm/webfetch.d.ts +94 -0
  155. package/dist/tm/webfetch.d.ts.map +1 -0
  156. package/dist/tm/webfetch.js +225 -0
  157. package/dist/tm/webfetch.js.map +1 -0
  158. package/package.json +2 -2
@@ -0,0 +1,82 @@
1
+ /**
2
+ * tm_memory — project/global memory mirror (Qoder-inspired, re-implemented
3
+ * from mechanism analysis; no code reused).
4
+ *
5
+ * Design: memories are plain Markdown files with a small YAML-ish
6
+ * frontmatter (title / usage_scenario / keywords) — git-diffable, human-
7
+ * editable, injectable into context without any database. The store lives
8
+ * under the git-aware base (<repo>/.git/opencode-team/memories/ or tmpdir
9
+ * fallback), mirroring the run-store philosophy: never pollute the working
10
+ * tree, TTL-free (memories are long-lived by design; forget is explicit).
11
+ *
12
+ * Layout:
13
+ * <storeBase>/memories/global/<category>/<title>.md
14
+ * <storeBase>/memories/projects/<project-slug>/<category>/<title>.md
15
+ *
16
+ * The project slug is derived from the workspace path (drive letter + path
17
+ * segments dashed, lowercased) so two checkouts never share a memory set.
18
+ * Injection is PULL-based for now: agents search via this tool; the lead
19
+ * distills relevant memories into dispatches (see SHARED_RULES).
20
+ */
21
+ import type { ToolResult } from "../types.js";
22
+ import { type TmConfig } from "./config.js";
23
+ import type { TmPipelines } from "./pipelines.js";
24
+ /** Hard caps — a memory that cannot fit a context budget is a doc, not a memory. */
25
+ export declare const MEMORY_TITLE_MAX = 120;
26
+ export declare const MEMORY_CONTENT_MAX = 4000;
27
+ export declare const MEMORY_SEARCH_RESULTS = 5;
28
+ export declare const MEMORY_EXCERPT_MAX = 600;
29
+ /** Seeded category taxonomy (Qoder's seven, reused as the starting point). */
30
+ export declare const MEMORY_CATEGORIES: readonly string[];
31
+ /** Path → project slug ("D:\Github\App" -> "d-github-app"). */
32
+ export declare function projectSlug(directory: string): string;
33
+ /** Title → safe file stem (collapsed dashes, capped). */
34
+ export declare function titleSlug(title: string): string;
35
+ export declare function renderMemoryMarkdown(m: {
36
+ title: string;
37
+ usageScenario: string[];
38
+ keywords: string[];
39
+ content: string;
40
+ }): string;
41
+ /** Parse a memory file; null when the file is not ours (foreign md). */
42
+ export declare function parseMemoryMarkdown(raw: string, filePath: string): {
43
+ title: string;
44
+ usageScenario: string[];
45
+ keywords: string[];
46
+ content: string;
47
+ filePath: string;
48
+ category: string;
49
+ } | null;
50
+ export interface MemoryHit {
51
+ title: string;
52
+ category: string;
53
+ scope: "project" | "global";
54
+ filePath: string;
55
+ keywords: string[];
56
+ usageScenario: string[];
57
+ content: string;
58
+ score: number;
59
+ }
60
+ /**
61
+ * Substring scoring — no embeddings, deterministic: title ×5, keywords ×4,
62
+ * usage_scenario ×3, category ×2, body ×1 (query tokenized on whitespace).
63
+ */
64
+ export declare function scoreMemory(m: {
65
+ title: string;
66
+ keywords: string[];
67
+ usageScenario: string[];
68
+ category: string;
69
+ content: string;
70
+ }, query: string): number;
71
+ export declare function buildTmMemoryTool(deps: {
72
+ storeBase: string;
73
+ directory: string;
74
+ cfg: TmConfig;
75
+ pipelines: TmPipelines;
76
+ args?: Record<string, unknown>;
77
+ }): {
78
+ description: string;
79
+ args: Record<string, unknown>;
80
+ execute: (rawArgs: Record<string, unknown>, ctx: unknown) => Promise<ToolResult>;
81
+ };
82
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/tm/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAA;AAGpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,oFAAoF;AACpF,eAAO,MAAM,gBAAgB,MAAM,CAAA;AACnC,eAAO,MAAM,kBAAkB,OAAO,CAAA;AACtC,eAAO,MAAM,qBAAqB,IAAI,CAAA;AACtC,eAAO,MAAM,kBAAkB,MAAM,CAAA;AAErC,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAQ9C,CAAA;AAID,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAUrD;AAED,yDAAyD;AACzD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO/C;AA0BD,wBAAgB,oBAAoB,CAAC,CAAC,EAAE;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAChB,GAAG,MAAM,CAST;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;IAClE,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,IAAI,CA8BP;AAID,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAA;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AA4BD;;;GAGG;AACH,wBAAgB,WAAW,CACzB,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EACpG,KAAK,EAAE,MAAM,GACZ,MAAM,CAiBR;AAqCD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,QAAQ,CAAA;IACb,SAAS,EAAE,WAAW,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B,GAAG;IACF,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;CACjF,CAuHA"}
@@ -0,0 +1,350 @@
1
+ /**
2
+ * tm_memory — project/global memory mirror (Qoder-inspired, re-implemented
3
+ * from mechanism analysis; no code reused).
4
+ *
5
+ * Design: memories are plain Markdown files with a small YAML-ish
6
+ * frontmatter (title / usage_scenario / keywords) — git-diffable, human-
7
+ * editable, injectable into context without any database. The store lives
8
+ * under the git-aware base (<repo>/.git/opencode-team/memories/ or tmpdir
9
+ * fallback), mirroring the run-store philosophy: never pollute the working
10
+ * tree, TTL-free (memories are long-lived by design; forget is explicit).
11
+ *
12
+ * Layout:
13
+ * <storeBase>/memories/global/<category>/<title>.md
14
+ * <storeBase>/memories/projects/<project-slug>/<category>/<title>.md
15
+ *
16
+ * The project slug is derived from the workspace path (drive letter + path
17
+ * segments dashed, lowercased) so two checkouts never share a memory set.
18
+ * Injection is PULL-based for now: agents search via this tool; the lead
19
+ * distills relevant memories into dispatches (see SHARED_RULES).
20
+ */
21
+ import * as fs from "node:fs";
22
+ import * as path from "node:path";
23
+ import { shorten } from "./config.js";
24
+ import { tmError, toToolResult } from "./result.js";
25
+ import { rmForceSafe } from "../fs-safe.js";
26
+ /** Hard caps — a memory that cannot fit a context budget is a doc, not a memory. */
27
+ export const MEMORY_TITLE_MAX = 120;
28
+ export const MEMORY_CONTENT_MAX = 4000;
29
+ export const MEMORY_SEARCH_RESULTS = 5;
30
+ export const MEMORY_EXCERPT_MAX = 600;
31
+ /** Seeded category taxonomy (Qoder's seven, reused as the starting point). */
32
+ export const MEMORY_CATEGORIES = [
33
+ "project_introduction",
34
+ "project_tech_stack",
35
+ "project_build_configuration",
36
+ "project_dependency_configuration",
37
+ "project_environment_configuration",
38
+ "development_code_specification",
39
+ "task_summary_experience",
40
+ ];
41
+ // ---------- slugs + paths ----------------------------------------------------
42
+ /** Path → project slug ("D:\Github\App" -> "d-github-app"). */
43
+ export function projectSlug(directory) {
44
+ const raw = String(directory ?? "").trim().toLowerCase();
45
+ const slug = raw
46
+ .split(/[\\/]+/)
47
+ .filter(Boolean)
48
+ .join("-")
49
+ .replace(/[^a-z0-9.-]+/g, "-")
50
+ .replace(/-{2,}/g, "-")
51
+ .replace(/^-|-$/g, "");
52
+ return slug || "default";
53
+ }
54
+ /** Title → safe file stem (collapsed dashes, capped). */
55
+ export function titleSlug(title) {
56
+ return String(title ?? "")
57
+ .toLowerCase()
58
+ .replace(/[^a-z0-9\u4e00-\u9fff]+/g, "-")
59
+ .replace(/-{2,}/g, "-")
60
+ .replace(/^-|-$/g, "")
61
+ .slice(0, 80) || "untitled";
62
+ }
63
+ function categorySlug(category) {
64
+ return String(category ?? "")
65
+ .trim()
66
+ .toLowerCase()
67
+ .replace(/[^a-z0-9_-]+/g, "_")
68
+ .replace(/^_+|_+$/g, "") || "notes";
69
+ }
70
+ function memoriesRoot(storeBase) {
71
+ return path.join(storeBase, "memories");
72
+ }
73
+ function scopeRoot(storeBase, scope, directory) {
74
+ return scope === "global"
75
+ ? path.join(memoriesRoot(storeBase), "global")
76
+ : path.join(memoriesRoot(storeBase), "projects", projectSlug(directory));
77
+ }
78
+ // ---------- frontmatter (minimal writer/parser, no YAML dep) ------------------
79
+ function yamlList(items) {
80
+ return items.map((s) => ` - ${JSON.stringify(s)}`).join("\n");
81
+ }
82
+ export function renderMemoryMarkdown(m) {
83
+ const parts = [
84
+ "---",
85
+ `title: ${JSON.stringify(m.title)}`,
86
+ ];
87
+ if (m.usageScenario.length)
88
+ parts.push("usage_scenario:", yamlList(m.usageScenario));
89
+ if (m.keywords.length)
90
+ parts.push("keywords:", yamlList(m.keywords));
91
+ parts.push("---", "", m.content.trim(), "");
92
+ return parts.join("\n");
93
+ }
94
+ /** Parse a memory file; null when the file is not ours (foreign md). */
95
+ export function parseMemoryMarkdown(raw, filePath) {
96
+ const text = String(raw ?? "");
97
+ if (!text.startsWith("---"))
98
+ return null;
99
+ const end = text.indexOf("\n---", 3);
100
+ if (end === -1)
101
+ return null;
102
+ const head = text.slice(3, end);
103
+ const body = text.slice(text.indexOf("\n", end + 1) + 1).trim();
104
+ let title = "";
105
+ let section = "";
106
+ const usageScenario = [];
107
+ const keywords = [];
108
+ for (const line of head.split(/\r?\n/)) {
109
+ if (/^\s+-\s/.test(line) && section) {
110
+ let v = line.trim().slice(2).trim();
111
+ try {
112
+ v = String(JSON.parse(v));
113
+ }
114
+ catch { /* keep raw */ }
115
+ if (section === "usage_scenario" && v)
116
+ usageScenario.push(v);
117
+ if (section === "keywords" && v)
118
+ keywords.push(v);
119
+ continue;
120
+ }
121
+ const kv = /^([a-z_]+)\s*:\s*(.*)$/.exec(line);
122
+ if (!kv)
123
+ continue;
124
+ const [, key, rest] = kv;
125
+ section = key === "usage_scenario" || key === "keywords" ? key : "";
126
+ if (key === "title") {
127
+ try {
128
+ title = String(JSON.parse(rest));
129
+ }
130
+ catch {
131
+ title = rest.replace(/^"|"$/g, "");
132
+ }
133
+ }
134
+ }
135
+ if (!title)
136
+ return null;
137
+ const category = path.basename(path.dirname(filePath));
138
+ return { title, usageScenario, keywords, content: body, filePath, category };
139
+ }
140
+ function walkMemories(dir, out) {
141
+ let entries;
142
+ try {
143
+ entries = fs.readdirSync(dir, { withFileTypes: true });
144
+ }
145
+ catch {
146
+ return;
147
+ }
148
+ for (const e of entries) {
149
+ const p = path.join(dir, e.name);
150
+ if (e.isDirectory())
151
+ walkMemories(p, out);
152
+ else if (e.isFile() && e.name.endsWith(".md"))
153
+ out.push(p);
154
+ }
155
+ }
156
+ function listMemoryFiles(storeBase, directory, scope) {
157
+ const files = [];
158
+ if (!scope || scope === "project")
159
+ walkMemories(scopeRoot(storeBase, "project", directory), files);
160
+ if (!scope || scope === "global")
161
+ walkMemories(scopeRoot(storeBase, "global", directory), files);
162
+ return files;
163
+ }
164
+ function scopeOf(storeBase, directory, filePath) {
165
+ return filePath.startsWith(path.join(memoriesRoot(storeBase), "projects") + path.sep)
166
+ ? "project" : "global";
167
+ }
168
+ /**
169
+ * Substring scoring — no embeddings, deterministic: title ×5, keywords ×4,
170
+ * usage_scenario ×3, category ×2, body ×1 (query tokenized on whitespace).
171
+ */
172
+ export function scoreMemory(m, query) {
173
+ const tokens = String(query ?? "").toLowerCase().split(/\s+/).filter(Boolean);
174
+ if (!tokens.length)
175
+ return 0;
176
+ const title = m.title.toLowerCase();
177
+ const keywords = m.keywords.join("\n").toLowerCase();
178
+ const scenarios = m.usageScenario.join("\n").toLowerCase();
179
+ const category = m.category.toLowerCase();
180
+ const content = m.content.toLowerCase();
181
+ let score = 0;
182
+ for (const t of tokens) {
183
+ if (title.includes(t))
184
+ score += 5;
185
+ if (keywords.includes(t))
186
+ score += 4;
187
+ if (scenarios.includes(t))
188
+ score += 3;
189
+ if (category.includes(t))
190
+ score += 2;
191
+ if (content.includes(t))
192
+ score += 1;
193
+ }
194
+ return score;
195
+ }
196
+ function readAllMemories(storeBase, directory, scope) {
197
+ const hits = [];
198
+ for (const file of listMemoryFiles(storeBase, directory, scope)) {
199
+ try {
200
+ const m = parseMemoryMarkdown(fs.readFileSync(file, "utf8"), file);
201
+ if (!m)
202
+ continue;
203
+ hits.push({
204
+ title: m.title,
205
+ category: m.category,
206
+ scope: scopeOf(storeBase, directory, file),
207
+ filePath: file,
208
+ keywords: m.keywords,
209
+ usageScenario: m.usageScenario,
210
+ content: m.content,
211
+ score: 0,
212
+ });
213
+ }
214
+ catch {
215
+ /* unreadable foreign file — skip */
216
+ }
217
+ }
218
+ return hits;
219
+ }
220
+ // ---------- tool ----------------------------------------------------------------
221
+ function asStringArray(v) {
222
+ if (Array.isArray(v))
223
+ return v.map((x) => String(x).trim()).filter(Boolean);
224
+ if (typeof v === "string")
225
+ return v.split(/[,;]/).map((s) => s.trim()).filter(Boolean);
226
+ return [];
227
+ }
228
+ function normalizeScope(v) {
229
+ return String(v ?? "").trim().toLowerCase() === "global" ? "global" : "project";
230
+ }
231
+ export function buildTmMemoryTool(deps) {
232
+ const { storeBase, directory, pipelines } = deps;
233
+ const tool = "tm_memory";
234
+ const traj = (e) => pipelines.store.appendTrajectory({ tool, ...e });
235
+ const execute = async (rawArgs) => {
236
+ try {
237
+ const args = rawArgs ?? {};
238
+ const action = String(args.action ?? "").trim();
239
+ if (action === "add") {
240
+ const title = String(args.title ?? "").trim();
241
+ const content = String(args.content ?? "").trim();
242
+ if (!title)
243
+ return tmError(tool, "args", "缺少 title 参数");
244
+ if (!content)
245
+ return tmError(tool, "args", "缺少 content 参数(一段浓缩事实,不要长文)");
246
+ if (content.length > MEMORY_CONTENT_MAX) {
247
+ return tmError(tool, "args", `content 超过 ${MEMORY_CONTENT_MAX} 字符上限(实际 ${content.length})——记忆应当精炼`);
248
+ }
249
+ const scope = normalizeScope(args.scope);
250
+ const category = categorySlug(String(args.category ?? "notes"));
251
+ const usageScenario = asStringArray(args.usage_scenario).slice(0, 8);
252
+ const keywords = asStringArray(args.keywords).slice(0, 10);
253
+ const file = path.join(scopeRoot(storeBase, scope, directory), category, `${titleSlug(title)}.md`);
254
+ const existed = fs.existsSync(file);
255
+ fs.mkdirSync(path.dirname(file), { recursive: true });
256
+ const md = renderMemoryMarkdown({
257
+ title: title.slice(0, MEMORY_TITLE_MAX),
258
+ usageScenario,
259
+ keywords,
260
+ content,
261
+ });
262
+ fs.writeFileSync(file, md, "utf8");
263
+ traj({ step_id: "memory", event: "add", scope, category, title: shorten(title, 80) });
264
+ return `记忆已${existed ? "更新" : "保存"}(${scope}):${file}\n分类: ${category}\n标题: ${shorten(title, 80)}\n注入时机: 该项目的 lead/researcher 通过 tm_memory search 检索后进入派发上下文。`;
265
+ }
266
+ if (action === "search") {
267
+ const query = String(args.query ?? "").trim();
268
+ if (!query)
269
+ return tmError(tool, "args", "缺少 query 参数");
270
+ const scope = args.scope ? normalizeScope(args.scope) : undefined;
271
+ const all = readAllMemories(storeBase, directory, scope);
272
+ for (const m of all)
273
+ m.score = scoreMemory(m, query);
274
+ const top = all
275
+ .filter((m) => m.score > 0)
276
+ .sort((a, b) => b.score - a.score || a.title.localeCompare(b.title))
277
+ .slice(0, MEMORY_SEARCH_RESULTS);
278
+ traj({ step_id: "memory", event: "search", query: shorten(query, 80), hits: top.length });
279
+ if (!top.length)
280
+ return `无匹配记忆(query: ${shorten(query, 80)})。可用 tm_memory list 查看 existing 记忆。`;
281
+ const blocks = top.map((m) => [
282
+ `[score ${m.score}] ${m.title} (${m.scope}/${m.category})`,
283
+ m.keywords.length ? `keywords: ${m.keywords.join(", ")}` : "",
284
+ `--- 内容 ---`,
285
+ shorten(m.content, MEMORY_EXCERPT_MAX),
286
+ ].filter(Boolean).join("\n"));
287
+ return `命中 ${top.length}/${all.length} 条记忆(按相关度,取前 ${MEMORY_SEARCH_RESULTS}):\n\n${blocks.join("\n\n")}`;
288
+ }
289
+ if (action === "list") {
290
+ const scope = args.scope ? normalizeScope(args.scope) : undefined;
291
+ const all = readAllMemories(storeBase, directory, scope);
292
+ traj({ step_id: "memory", event: "list", count: all.length });
293
+ if (!all.length)
294
+ return "当前没有任何记忆。用 tm_memory add 保存第一条。";
295
+ const byScope = new Map();
296
+ for (const m of all) {
297
+ const key = `${m.scope}/${m.category}`;
298
+ byScope.set(key, [...(byScope.get(key) ?? []), m.title]);
299
+ }
300
+ const lines = [`共 ${all.length} 条记忆:`];
301
+ for (const [key, titles] of [...byScope.entries()].sort()) {
302
+ lines.push(`${key}:`);
303
+ for (const t of titles)
304
+ lines.push(` - ${t}`);
305
+ }
306
+ lines.push("", "检索用 tm_memory search;删除用 tm_memory forget。");
307
+ return lines.join("\n");
308
+ }
309
+ if (action === "forget") {
310
+ const title = String(args.title ?? "").trim();
311
+ if (!title)
312
+ return tmError(tool, "args", "缺少 title 参数");
313
+ const stem = titleSlug(title);
314
+ const scope = args.scope ? normalizeScope(args.scope) : undefined;
315
+ const files = listMemoryFiles(storeBase, directory, scope).filter((f) => path.basename(f, ".md") === stem);
316
+ if (!files.length)
317
+ return tmError(tool, "args", `没有找到标题为 "${shorten(title, 80)}" 的记忆(可用 tm_memory list 确认)`);
318
+ for (const f of files)
319
+ rmForceSafe(f);
320
+ traj({ step_id: "memory", event: "forget", count: files.length, title: shorten(title, 80) });
321
+ return `已删除 ${files.length} 条记忆:${files.join(", ")}`;
322
+ }
323
+ return tmError(tool, "args", `未知 action "${shorten(action, 30)}"——可用: add | search | list | forget`);
324
+ }
325
+ catch (err) {
326
+ return tmError(tool, "execute", String(err?.message ?? err ?? "memory 操作失败"));
327
+ }
328
+ };
329
+ const DESCRIPTION = `Project/global memory store (Markdown files with frontmatter — persistent across conversations). Actions: add | search | list | forget.
330
+ - add: { title, content (≤4000 chars, one condensed fact), category?, keywords?, usage_scenario?, scope? ("project" default | "global") }. Seeded categories: ${MEMORY_CATEGORIES.join(" / ")}; free-form allowed.
331
+ - search: { query } — deterministic substring scoring (title > keywords > usage_scenario > body), top ${MEMORY_SEARCH_RESULTS}. Use BEFORE assuming project conventions.
332
+ - list: { scope? } — everything, grouped.
333
+ - forget: { title } — delete by title.
334
+ - What belongs here: durable project facts (build commands, environment quirks, architecture decisions, user-stated conventions that outlive one conversation). What does NOT: task state (todo list owns that), oversized docs (board files own those).`;
335
+ return {
336
+ description: DESCRIPTION,
337
+ args: deps.args ?? {
338
+ action: { descriptor: "action: add|search|list|forget (required)" },
339
+ title: { descriptor: "title: string (add/forget)" },
340
+ content: { descriptor: "content: string (add, ≤4000 chars)" },
341
+ category: { descriptor: "category: string (add, optional)" },
342
+ keywords: { descriptor: "keywords: string[] or comma string (add, optional)" },
343
+ usage_scenario: { descriptor: "usage_scenario: string[] or comma string (add, optional)" },
344
+ query: { descriptor: "query: string (search)" },
345
+ scope: { descriptor: "scope: project|global (optional, default project)" },
346
+ },
347
+ execute: async (rawArgs) => toToolResult(await execute(rawArgs)),
348
+ };
349
+ }
350
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/tm/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAG3C,oFAAoF;AACpF,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA;AACnC,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAA;AACtC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAA;AACtC,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;AAErC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,sBAAsB;IACtB,oBAAoB;IACpB,6BAA6B;IAC7B,kCAAkC;IAClC,mCAAmC;IACnC,gCAAgC;IAChC,yBAAyB;CAC1B,CAAA;AAED,gFAAgF;AAEhF,+DAA+D;AAC/D,MAAM,UAAU,WAAW,CAAC,SAAiB;IAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACxD,MAAM,IAAI,GAAG,GAAG;SACb,KAAK,CAAC,QAAQ,CAAC;SACf,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC;SACT,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC;SAC7B,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IACxB,OAAO,IAAI,IAAI,SAAS,CAAA;AAC1B,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;SACvB,WAAW,EAAE;SACb,OAAO,CAAC,0BAA0B,EAAE,GAAG,CAAC;SACxC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,UAAU,CAAA;AAC/B,CAAC;AAED,SAAS,YAAY,CAAC,QAAgB;IACpC,OAAO,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;SAC1B,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC;SAC7B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAA;AACvC,CAAC;AAED,SAAS,YAAY,CAAC,SAAiB;IACrC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;AACzC,CAAC;AAED,SAAS,SAAS,CAAC,SAAiB,EAAE,KAA2B,EAAE,SAAiB;IAClF,OAAO,KAAK,KAAK,QAAQ;QACvB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC;QAC9C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC,CAAA;AAC5E,CAAC;AAED,iFAAiF;AAEjF,SAAS,QAAQ,CAAC,KAAe;IAC/B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAClE,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,CAKpC;IACC,MAAM,KAAK,GAAG;QACZ,KAAK;QACL,UAAU,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;KACpC,CAAA;IACD,IAAI,CAAC,CAAC,aAAa,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAA;IACpF,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;IACpE,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IAC3C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,QAAgB;IAQ/D,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAA;IAC9B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IACpC,IAAI,GAAG,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC/D,IAAI,KAAK,GAAG,EAAE,CAAA;IACd,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,MAAM,aAAa,GAAa,EAAE,CAAA;IAClC,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;YACpC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;YACnC,IAAI,CAAC;gBAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;YAC1D,IAAI,OAAO,KAAK,gBAAgB,IAAI,CAAC;gBAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC5D,IAAI,OAAO,KAAK,UAAU,IAAI,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjD,SAAQ;QACV,CAAC;QACD,MAAM,EAAE,GAAG,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9C,IAAI,CAAC,EAAE;YAAE,SAAQ;QACjB,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAA;QACxB,OAAO,GAAG,GAAG,KAAK,gBAAgB,IAAI,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;QACnE,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC;gBAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;YAAC,CAAC;QACvF,CAAC;IACH,CAAC;IACD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;IACtD,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;AAC9E,CAAC;AAeD,SAAS,YAAY,CAAC,GAAW,EAAE,GAAa;IAC9C,IAAI,OAAoB,CAAA;IACxB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAM;IACR,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;QAChC,IAAI,CAAC,CAAC,WAAW,EAAE;YAAE,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;aACpC,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC5D,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB,EAAE,SAAiB,EAAE,KAA4B;IACzF,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,SAAS;QAAE,YAAY,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,CAAA;IAClG,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,QAAQ;QAAE,YAAY,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,CAAA;IAChG,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,OAAO,CAAC,SAAiB,EAAE,SAAiB,EAAE,QAAgB;IACrE,OAAO,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;QACnF,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CACzB,CAAoG,EACpG,KAAa;IAEb,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC7E,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,CAAC,CAAA;IAC5B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAA;IACnC,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IACpD,MAAM,SAAS,GAAG,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IAC1D,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAA;IACzC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA;IACvC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,KAAK,IAAI,CAAC,CAAA;QACjC,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,KAAK,IAAI,CAAC,CAAA;QACpC,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,KAAK,IAAI,CAAC,CAAA;QACrC,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,KAAK,IAAI,CAAC,CAAA;QACpC,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,KAAK,IAAI,CAAC,CAAA;IACrC,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB,EAAE,SAAiB,EAAE,KAA4B;IACzF,MAAM,IAAI,GAAgB,EAAE,CAAA;IAC5B,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;QAChE,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,mBAAmB,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAA;YAClE,IAAI,CAAC,CAAC;gBAAE,SAAQ;YAChB,IAAI,CAAC,IAAI,CAAC;gBACR,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC;gBAC1C,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,aAAa,EAAE,CAAC,CAAC,aAAa;gBAC9B,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,KAAK,EAAE,CAAC;aACT,CAAC,CAAA;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,mFAAmF;AAEnF,SAAS,aAAa,CAAC,CAAU;IAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC3E,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACtF,OAAO,EAAE,CAAA;AACX,CAAC;AAED,SAAS,cAAc,CAAC,CAAU;IAChC,OAAO,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;AACjF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAMjC;IAKC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAChD,MAAM,IAAI,GAAG,WAAW,CAAA;IACxB,MAAM,IAAI,GAAG,CAAC,CAA0B,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;IAE7F,MAAM,OAAO,GAAG,KAAK,EAAE,OAAgC,EAAoB,EAAE;QAC3E,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAA;YAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;YAC/C,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;gBACrB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;gBAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;gBACjD,IAAI,CAAC,KAAK;oBAAE,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,CAAA;gBACvD,IAAI,CAAC,OAAO;oBAAE,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,4BAA4B,CAAC,CAAA;gBACxE,IAAI,OAAO,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;oBACxC,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,kBAAkB,YAAY,OAAO,CAAC,MAAM,WAAW,CAAC,CAAA;gBACrG,CAAC;gBACD,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBACxC,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAA;gBAC/D,MAAM,aAAa,GAAG,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;gBACpE,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;gBAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,SAAS,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,EACtC,QAAQ,EACR,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CACzB,CAAA;gBACD,MAAM,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;gBACnC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;gBACrD,MAAM,EAAE,GAAG,oBAAoB,CAAC;oBAC9B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC;oBACvC,aAAa;oBACb,QAAQ;oBACR,OAAO;iBACR,CAAC,CAAA;gBACF,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;gBAClC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;gBACrF,OAAO,MAAM,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,KAAK,KAAK,IAAI,SAAS,QAAQ,SAAS,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,8DAA8D,CAAA;YAChK,CAAC;YACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;gBAC7C,IAAI,CAAC,KAAK;oBAAE,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,CAAA;gBACvD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;gBACjE,MAAM,GAAG,GAAG,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;gBACxD,KAAK,MAAM,CAAC,IAAI,GAAG;oBAAE,CAAC,CAAC,KAAK,GAAG,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;gBACpD,MAAM,GAAG,GAAG,GAAG;qBACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;qBAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;qBACnE,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAA;gBAClC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;gBACzF,IAAI,CAAC,GAAG,CAAC,MAAM;oBAAE,OAAO,gBAAgB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,qCAAqC,CAAA;gBAC/F,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3B;oBACE,UAAU,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,QAAQ,GAAG;oBAC3D,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;oBAC7D,YAAY;oBACZ,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,kBAAkB,CAAC;iBACvC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC7B,CAAA;gBACD,OAAO,MAAM,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,gBAAgB,qBAAqB,SAAS,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAA;YAC1G,CAAC;YACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;gBACjE,MAAM,GAAG,GAAG,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;gBACxD,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;gBAC7D,IAAI,CAAC,GAAG,CAAC,MAAM;oBAAE,OAAO,iCAAiC,CAAA;gBACzD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAA;gBAC3C,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;oBACpB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAA;oBACtC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;gBAC1D,CAAC;gBACD,MAAM,KAAK,GAAa,CAAC,KAAK,GAAG,CAAC,MAAM,OAAO,CAAC,CAAA;gBAChD,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;oBAC1D,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;oBACrB,KAAK,MAAM,CAAC,IAAI,MAAM;wBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;gBAChD,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,4CAA4C,CAAC,CAAA;gBAC5D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACzB,CAAC;YACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;gBAC7C,IAAI,CAAC,KAAK;oBAAE,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,CAAA;gBACvD,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;gBAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;gBACjE,MAAM,KAAK,GAAG,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACtE,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,IAAI,CACjC,CAAA;gBACD,IAAI,CAAC,KAAK,CAAC,MAAM;oBAAE,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,6BAA6B,CAAC,CAAA;gBAC5G,KAAK,MAAM,CAAC,IAAI,KAAK;oBAAE,WAAW,CAAC,CAAC,CAAC,CAAA;gBACrC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;gBAC5F,OAAO,OAAO,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;YACtD,CAAC;YACD,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,qCAAqC,CAAC,CAAA;QACtG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,IAAI,aAAa,CAAC,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC,CAAA;IAED,MAAM,WAAW,GAAG;iKAC2I,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;wGACtF,qBAAqB;;;0PAG6H,CAAA;IAExP,OAAO;QACL,WAAW,EAAE,WAAW;QACxB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI;YACjB,MAAM,EAAE,EAAE,UAAU,EAAE,2CAA2C,EAAE;YACnE,KAAK,EAAE,EAAE,UAAU,EAAE,4BAA4B,EAAE;YACnD,OAAO,EAAE,EAAE,UAAU,EAAE,oCAAoC,EAAE;YAC7D,QAAQ,EAAE,EAAE,UAAU,EAAE,kCAAkC,EAAE;YAC5D,QAAQ,EAAE,EAAE,UAAU,EAAE,oDAAoD,EAAE;YAC9E,cAAc,EAAE,EAAE,UAAU,EAAE,0DAA0D,EAAE;YAC1F,KAAK,EAAE,EAAE,UAAU,EAAE,wBAAwB,EAAE;YAC/C,KAAK,EAAE,EAAE,UAAU,EAAE,mDAAmD,EAAE;SAC3E;QACD,OAAO,EAAE,KAAK,EAAE,OAAgC,EAAuB,EAAE,CACvE,YAAY,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;KACvC,CAAA;AACH,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * tm layer — the four governed pipelines (T1.2 + T1.3 + T1.4). Split out of
3
+ * the former tools.ts hub; behavior unchanged. Assembly lives in tools.ts.
4
+ *
5
+ * tm_read — governed passthrough of client.file.read (T0.4-verified API)
6
+ * tm_grep — governed passthrough of client.find.text (T0.4-verified API)
7
+ * tm_bash — read-only allowlisted shell via the host `$` bridge
8
+ * tm_fetch — paged/structured retrieval of offloaded payloads (handles)
9
+ *
10
+ * Shared governance (every tool): threshold offload (TM_OFFLOAD_THRESHOLD,
11
+ * == threshold offloads), R6 reuse (same envprotect matchers as the global
12
+ * hook — anti-backdoor), structured errors (never a bare throw), and store
13
+ * failure degradation (governance faults never fail the task).
14
+ */
15
+ import type * as crypto from "node:crypto";
16
+ import { type EnvProtectMode } from "../envprotect.js";
17
+ import { type TmConfig } from "./config.js";
18
+ import type { RunStore } from "./store.js";
19
+ import { detectContentType } from "./preview.js";
20
+ export interface TmDeps {
21
+ client: unknown;
22
+ $: unknown;
23
+ cfg: TmConfig;
24
+ store: RunStore;
25
+ runId: string;
26
+ /** Process-random HMAC key — used to VERIFY handle tokens in tm_fetch. */
27
+ hmacKey: crypto.BinaryLike;
28
+ accessToken: string;
29
+ expireAt: number;
30
+ mode: EnvProtectMode;
31
+ extra: RegExp[];
32
+ /**
33
+ * Step-id namespace prefix for SECONDARY pipeline instances. A second
34
+ * buildPipelines instance (PTC's) starts its counter at s0001 again —
35
+ * without a distinct prefix its offloaded payloads would collide with
36
+ * the main pipeline's same-numbered steps inside the shared run store
37
+ * (refs ignore seq, so tm_fetch's last-append-wins would return the
38
+ * WRONG payload). PTC passes "ptc-"; the main instance stays "".
39
+ */
40
+ stepPrefix?: string;
41
+ }
42
+ interface GovernOptions {
43
+ contentType: ReturnType<typeof detectContentType>;
44
+ clue?: string;
45
+ }
46
+ export declare function buildPipelines(deps: TmDeps): {
47
+ nextStepId: () => string;
48
+ govern: (stepId: string, tool: string, content: string, opts: GovernOptions) => unknown;
49
+ tmRead: (rawArgs: Record<string, unknown>, ctx: unknown) => Promise<unknown>;
50
+ tmGrep: (rawArgs: Record<string, unknown>, ctx: unknown) => Promise<unknown>;
51
+ tmBash: (rawArgs: Record<string, unknown>, ctx: unknown) => Promise<unknown>;
52
+ tmFetch: (rawArgs: Record<string, unknown>, _ctx: unknown) => Promise<unknown>;
53
+ store: RunStore;
54
+ };
55
+ /** The four governed pipelines + shared step-counter/govern (PTC bridge seam). */
56
+ export type TmPipelines = ReturnType<typeof buildPipelines>;
57
+ export {};
58
+ //# sourceMappingURL=pipelines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipelines.d.ts","sourceRoot":"","sources":["../../src/tm/pipelines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,KAAK,MAAM,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAgE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACpH,OAAO,EAA0C,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEnF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAIL,iBAAiB,EAClB,MAAM,cAAc,CAAA;AAmBrB,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,OAAO,CAAA;IACf,CAAC,EAAE,OAAO,CAAA;IACV,GAAG,EAAE,QAAQ,CAAA;IACb,KAAK,EAAE,QAAQ,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC,UAAU,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAID,UAAU,aAAa;IACrB,WAAW,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;IACjD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM;;qBAejB,MAAM,QAAQ,MAAM,WAAW,MAAM,QAAQ,aAAa,KAAG,OAAO;sBAsD7D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;sBAyCxD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;sBA4CxD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;uBAiCvD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;;EAgF1F;AAED,kFAAkF;AAClF,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAA"}