@agntk/agent-harness 0.1.1

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 (212) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +41 -0
  3. package/README.md +445 -0
  4. package/defaults/agents/summarizer.md +49 -0
  5. package/defaults/instincts/lead-with-answer.md +24 -0
  6. package/defaults/instincts/qualify-before-recommending.md +40 -0
  7. package/defaults/instincts/read-before-edit.md +23 -0
  8. package/defaults/instincts/search-before-create.md +23 -0
  9. package/defaults/playbooks/ship-feature.md +31 -0
  10. package/defaults/rules/ask-before-assuming.md +35 -0
  11. package/defaults/rules/operations.md +35 -0
  12. package/defaults/rules/respect-the-user.md +39 -0
  13. package/defaults/skills/business-analyst.md +181 -0
  14. package/defaults/skills/content-marketer.md +184 -0
  15. package/defaults/skills/research.md +34 -0
  16. package/defaults/tools/example-web-search.md +60 -0
  17. package/defaults/workflows/daily-reflection.md +54 -0
  18. package/dist/agent-framework-K4GUIICH.js +344 -0
  19. package/dist/agent-framework-K4GUIICH.js.map +1 -0
  20. package/dist/analytics-RPT73WNM.js +12 -0
  21. package/dist/analytics-RPT73WNM.js.map +1 -0
  22. package/dist/auto-processor-OLE45UI3.js +13 -0
  23. package/dist/auto-processor-OLE45UI3.js.map +1 -0
  24. package/dist/chunk-274RV3YO.js +162 -0
  25. package/dist/chunk-274RV3YO.js.map +1 -0
  26. package/dist/chunk-4CWAGBNS.js +168 -0
  27. package/dist/chunk-4CWAGBNS.js.map +1 -0
  28. package/dist/chunk-4FDUOGSZ.js +69 -0
  29. package/dist/chunk-4FDUOGSZ.js.map +1 -0
  30. package/dist/chunk-5H34JPMB.js +199 -0
  31. package/dist/chunk-5H34JPMB.js.map +1 -0
  32. package/dist/chunk-6EMOEYGU.js +102 -0
  33. package/dist/chunk-6EMOEYGU.js.map +1 -0
  34. package/dist/chunk-A7BJPQQ6.js +236 -0
  35. package/dist/chunk-A7BJPQQ6.js.map +1 -0
  36. package/dist/chunk-AGAAFJEO.js +76 -0
  37. package/dist/chunk-AGAAFJEO.js.map +1 -0
  38. package/dist/chunk-BSKDOFRT.js +65 -0
  39. package/dist/chunk-BSKDOFRT.js.map +1 -0
  40. package/dist/chunk-CHJ5GNZC.js +100 -0
  41. package/dist/chunk-CHJ5GNZC.js.map +1 -0
  42. package/dist/chunk-CSL3ERUI.js +307 -0
  43. package/dist/chunk-CSL3ERUI.js.map +1 -0
  44. package/dist/chunk-DA7IKHC4.js +229 -0
  45. package/dist/chunk-DA7IKHC4.js.map +1 -0
  46. package/dist/chunk-DGUM43GV.js +11 -0
  47. package/dist/chunk-DGUM43GV.js.map +1 -0
  48. package/dist/chunk-DTTXPHFW.js +211 -0
  49. package/dist/chunk-DTTXPHFW.js.map +1 -0
  50. package/dist/chunk-FD55B3IO.js +204 -0
  51. package/dist/chunk-FD55B3IO.js.map +1 -0
  52. package/dist/chunk-FLZU44SV.js +230 -0
  53. package/dist/chunk-FLZU44SV.js.map +1 -0
  54. package/dist/chunk-GJNNR2RA.js +200 -0
  55. package/dist/chunk-GJNNR2RA.js.map +1 -0
  56. package/dist/chunk-GNUSHD2Y.js +111 -0
  57. package/dist/chunk-GNUSHD2Y.js.map +1 -0
  58. package/dist/chunk-GUJTBGVS.js +2212 -0
  59. package/dist/chunk-GUJTBGVS.js.map +1 -0
  60. package/dist/chunk-IZ6UZ3ZL.js +207 -0
  61. package/dist/chunk-IZ6UZ3ZL.js.map +1 -0
  62. package/dist/chunk-JKMGYWXB.js +197 -0
  63. package/dist/chunk-JKMGYWXB.js.map +1 -0
  64. package/dist/chunk-KFX54TQM.js +165 -0
  65. package/dist/chunk-KFX54TQM.js.map +1 -0
  66. package/dist/chunk-M7NXUK55.js +199 -0
  67. package/dist/chunk-M7NXUK55.js.map +1 -0
  68. package/dist/chunk-MPZ3BPUI.js +374 -0
  69. package/dist/chunk-MPZ3BPUI.js.map +1 -0
  70. package/dist/chunk-OC6YSTDX.js +119 -0
  71. package/dist/chunk-OC6YSTDX.js.map +1 -0
  72. package/dist/chunk-RC6MEZB6.js +469 -0
  73. package/dist/chunk-RC6MEZB6.js.map +1 -0
  74. package/dist/chunk-RY3ZFII7.js +3440 -0
  75. package/dist/chunk-RY3ZFII7.js.map +1 -0
  76. package/dist/chunk-TAT6JU3X.js +167 -0
  77. package/dist/chunk-TAT6JU3X.js.map +1 -0
  78. package/dist/chunk-UDZIS2AQ.js +79 -0
  79. package/dist/chunk-UDZIS2AQ.js.map +1 -0
  80. package/dist/chunk-UPLBF4RZ.js +115 -0
  81. package/dist/chunk-UPLBF4RZ.js.map +1 -0
  82. package/dist/chunk-UWQTZMNI.js +154 -0
  83. package/dist/chunk-UWQTZMNI.js.map +1 -0
  84. package/dist/chunk-W4T7PGI2.js +346 -0
  85. package/dist/chunk-W4T7PGI2.js.map +1 -0
  86. package/dist/chunk-XTBKL5BI.js +111 -0
  87. package/dist/chunk-XTBKL5BI.js.map +1 -0
  88. package/dist/chunk-YIJY5DBV.js +399 -0
  89. package/dist/chunk-YIJY5DBV.js.map +1 -0
  90. package/dist/chunk-YUFNYN2H.js +242 -0
  91. package/dist/chunk-YUFNYN2H.js.map +1 -0
  92. package/dist/chunk-Z2PUCXTZ.js +94 -0
  93. package/dist/chunk-Z2PUCXTZ.js.map +1 -0
  94. package/dist/chunk-ZZJOFKAT.js +13 -0
  95. package/dist/chunk-ZZJOFKAT.js.map +1 -0
  96. package/dist/cli/index.js +3661 -0
  97. package/dist/cli/index.js.map +1 -0
  98. package/dist/config-WVMRUOCA.js +13 -0
  99. package/dist/config-WVMRUOCA.js.map +1 -0
  100. package/dist/context-loader-3ORBPMHJ.js +13 -0
  101. package/dist/context-loader-3ORBPMHJ.js.map +1 -0
  102. package/dist/conversation-QDEIDQPH.js +22 -0
  103. package/dist/conversation-QDEIDQPH.js.map +1 -0
  104. package/dist/cost-tracker-RS3W7SVY.js +24 -0
  105. package/dist/cost-tracker-RS3W7SVY.js.map +1 -0
  106. package/dist/delegate-VJCJLYEK.js +29 -0
  107. package/dist/delegate-VJCJLYEK.js.map +1 -0
  108. package/dist/emotional-state-VQVRA6ED.js +206 -0
  109. package/dist/emotional-state-VQVRA6ED.js.map +1 -0
  110. package/dist/env-discovery-2BLVMAIM.js +251 -0
  111. package/dist/env-discovery-2BLVMAIM.js.map +1 -0
  112. package/dist/export-6GCYHEHQ.js +165 -0
  113. package/dist/export-6GCYHEHQ.js.map +1 -0
  114. package/dist/graph-YUIPOSOO.js +14 -0
  115. package/dist/graph-YUIPOSOO.js.map +1 -0
  116. package/dist/harness-LCHA3DWP.js +10 -0
  117. package/dist/harness-LCHA3DWP.js.map +1 -0
  118. package/dist/harness-WE4SLCML.js +26 -0
  119. package/dist/harness-WE4SLCML.js.map +1 -0
  120. package/dist/health-NZ6WNIMV.js +23 -0
  121. package/dist/health-NZ6WNIMV.js.map +1 -0
  122. package/dist/index.d.ts +3612 -0
  123. package/dist/index.js +13501 -0
  124. package/dist/index.js.map +1 -0
  125. package/dist/indexer-LONANRRM.js +16 -0
  126. package/dist/indexer-LONANRRM.js.map +1 -0
  127. package/dist/instinct-learner-SRM72DHF.js +20 -0
  128. package/dist/instinct-learner-SRM72DHF.js.map +1 -0
  129. package/dist/intake-4M3HNU43.js +21 -0
  130. package/dist/intake-4M3HNU43.js.map +1 -0
  131. package/dist/intelligence-HJOCA4SJ.js +1081 -0
  132. package/dist/intelligence-HJOCA4SJ.js.map +1 -0
  133. package/dist/journal-WANJL3MI.js +24 -0
  134. package/dist/journal-WANJL3MI.js.map +1 -0
  135. package/dist/loader-C3TKIKZR.js +23 -0
  136. package/dist/loader-C3TKIKZR.js.map +1 -0
  137. package/dist/mcp-WTQJJZAO.js +15 -0
  138. package/dist/mcp-WTQJJZAO.js.map +1 -0
  139. package/dist/mcp-discovery-WPAQFL6S.js +377 -0
  140. package/dist/mcp-discovery-WPAQFL6S.js.map +1 -0
  141. package/dist/mcp-installer-6O2XXD3V.js +394 -0
  142. package/dist/mcp-installer-6O2XXD3V.js.map +1 -0
  143. package/dist/metrics-KXGNFAAB.js +20 -0
  144. package/dist/metrics-KXGNFAAB.js.map +1 -0
  145. package/dist/primitive-registry-I6VTIR4W.js +512 -0
  146. package/dist/primitive-registry-I6VTIR4W.js.map +1 -0
  147. package/dist/project-discovery-C4UMD7JI.js +246 -0
  148. package/dist/project-discovery-C4UMD7JI.js.map +1 -0
  149. package/dist/provider-LQHQX7Z7.js +26 -0
  150. package/dist/provider-LQHQX7Z7.js.map +1 -0
  151. package/dist/provider-SXPQZ74H.js +28 -0
  152. package/dist/provider-SXPQZ74H.js.map +1 -0
  153. package/dist/rate-limiter-RLRVM325.js +22 -0
  154. package/dist/rate-limiter-RLRVM325.js.map +1 -0
  155. package/dist/rule-engine-YGQ3RYZM.js +182 -0
  156. package/dist/rule-engine-YGQ3RYZM.js.map +1 -0
  157. package/dist/scaffold-A3VRRCBV.js +347 -0
  158. package/dist/scaffold-A3VRRCBV.js.map +1 -0
  159. package/dist/scheduler-XHHIVHRI.js +397 -0
  160. package/dist/scheduler-XHHIVHRI.js.map +1 -0
  161. package/dist/search-V3W5JMJG.js +75 -0
  162. package/dist/search-V3W5JMJG.js.map +1 -0
  163. package/dist/semantic-search-2DTOO5UX.js +241 -0
  164. package/dist/semantic-search-2DTOO5UX.js.map +1 -0
  165. package/dist/serve-DTQ3HENY.js +291 -0
  166. package/dist/serve-DTQ3HENY.js.map +1 -0
  167. package/dist/sessions-CZGVXKQE.js +21 -0
  168. package/dist/sessions-CZGVXKQE.js.map +1 -0
  169. package/dist/sources-RW5DT56F.js +32 -0
  170. package/dist/sources-RW5DT56F.js.map +1 -0
  171. package/dist/starter-packs-76YUVHEU.js +893 -0
  172. package/dist/starter-packs-76YUVHEU.js.map +1 -0
  173. package/dist/state-GMXILIHW.js +13 -0
  174. package/dist/state-GMXILIHW.js.map +1 -0
  175. package/dist/state-merge-NKO5FRBA.js +174 -0
  176. package/dist/state-merge-NKO5FRBA.js.map +1 -0
  177. package/dist/telemetry-UC6PBXC7.js +22 -0
  178. package/dist/telemetry-UC6PBXC7.js.map +1 -0
  179. package/dist/tool-executor-MJ7IG7PQ.js +28 -0
  180. package/dist/tool-executor-MJ7IG7PQ.js.map +1 -0
  181. package/dist/tools-DZ4KETET.js +20 -0
  182. package/dist/tools-DZ4KETET.js.map +1 -0
  183. package/dist/types-EW7AIB3R.js +18 -0
  184. package/dist/types-EW7AIB3R.js.map +1 -0
  185. package/dist/types-WGDLSPO6.js +16 -0
  186. package/dist/types-WGDLSPO6.js.map +1 -0
  187. package/dist/universal-installer-QGS4SJGX.js +578 -0
  188. package/dist/universal-installer-QGS4SJGX.js.map +1 -0
  189. package/dist/validator-7WXMDIHH.js +22 -0
  190. package/dist/validator-7WXMDIHH.js.map +1 -0
  191. package/dist/verification-gate-FYXUX6LH.js +246 -0
  192. package/dist/verification-gate-FYXUX6LH.js.map +1 -0
  193. package/dist/versioning-Z3XNE2Q2.js +271 -0
  194. package/dist/versioning-Z3XNE2Q2.js.map +1 -0
  195. package/dist/watcher-ISJC7YKL.js +109 -0
  196. package/dist/watcher-ISJC7YKL.js.map +1 -0
  197. package/dist/web-server-DD7ZOP46.js +28 -0
  198. package/dist/web-server-DD7ZOP46.js.map +1 -0
  199. package/package.json +76 -0
  200. package/sources.yaml +121 -0
  201. package/templates/assistant/CORE.md +24 -0
  202. package/templates/assistant/SYSTEM.md +24 -0
  203. package/templates/assistant/config.yaml +51 -0
  204. package/templates/base/CORE.md +17 -0
  205. package/templates/base/SYSTEM.md +24 -0
  206. package/templates/base/config.yaml +51 -0
  207. package/templates/claude-opus/config.yaml +51 -0
  208. package/templates/code-reviewer/CORE.md +25 -0
  209. package/templates/code-reviewer/SYSTEM.md +30 -0
  210. package/templates/code-reviewer/config.yaml +51 -0
  211. package/templates/gpt4/config.yaml +51 -0
  212. package/templates/local/config.yaml +51 -0
@@ -0,0 +1,347 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ writeDefaultConfig
5
+ } from "./chunk-CHJ5GNZC.js";
6
+ import "./chunk-4CWAGBNS.js";
7
+ import "./chunk-ZZJOFKAT.js";
8
+
9
+ // src/cli/scaffold.ts
10
+ import { mkdirSync, writeFileSync, readFileSync, readdirSync, existsSync } from "fs";
11
+ import { join, dirname } from "path";
12
+ import { fileURLToPath } from "url";
13
+ var DIRECTORIES = [
14
+ "rules",
15
+ "instincts",
16
+ "skills",
17
+ "playbooks",
18
+ "workflows",
19
+ "tools",
20
+ "agents",
21
+ "intake",
22
+ "memory/sessions",
23
+ "memory/journal"
24
+ ];
25
+ function getPackageRoot() {
26
+ let dir = dirname(fileURLToPath(import.meta.url));
27
+ for (let i = 0; i < 5; i++) {
28
+ if (existsSync(join(dir, "package.json"))) return dir;
29
+ dir = dirname(dir);
30
+ }
31
+ return dirname(dirname(fileURLToPath(import.meta.url)));
32
+ }
33
+ function applyTemplate(content, vars) {
34
+ const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
35
+ const defaultPurpose = `I am ${vars.agentName}, an autonomous AI agent. My purpose is to help my creator build, think, and ship.`;
36
+ const purpose = vars.purpose ? `I am ${vars.agentName}. ${vars.purpose}` : defaultPurpose;
37
+ return content.replace(/\{\{AGENT_NAME\}\}/g, vars.agentName).replace(/\{\{PURPOSE\}\}/g, purpose).replace(/\{\{DATE\}\}/g, date);
38
+ }
39
+ function copyDefaults(targetDir, vars) {
40
+ const defaultsDir = join(getPackageRoot(), "defaults");
41
+ if (!existsSync(defaultsDir)) return;
42
+ const primitiveDirs = ["rules", "instincts", "skills", "playbooks", "agents", "tools", "workflows"];
43
+ for (const dir of primitiveDirs) {
44
+ const srcDir = join(defaultsDir, dir);
45
+ if (!existsSync(srcDir)) continue;
46
+ const files = readdirSync(srcDir).filter((f) => f.endsWith(".md"));
47
+ for (const file of files) {
48
+ const content = readFileSync(join(srcDir, file), "utf-8");
49
+ writeFileSync(join(targetDir, dir, file), applyTemplate(content, vars), "utf-8");
50
+ }
51
+ }
52
+ }
53
+ function loadTemplate(templateName, fileName, vars) {
54
+ const templatePath = join(getPackageRoot(), "templates", templateName, fileName);
55
+ if (!existsSync(templatePath)) return null;
56
+ return applyTemplate(readFileSync(templatePath, "utf-8"), vars);
57
+ }
58
+ function scaffoldHarness(targetDir, agentName, options) {
59
+ if (existsSync(targetDir)) {
60
+ throw new Error(`Directory already exists: ${targetDir}`);
61
+ }
62
+ const template = options?.template ?? "base";
63
+ const vars = { agentName, purpose: options?.purpose };
64
+ mkdirSync(targetDir, { recursive: true });
65
+ for (const dir of DIRECTORIES) {
66
+ mkdirSync(join(targetDir, dir), { recursive: true });
67
+ }
68
+ if (options?.coreContent) {
69
+ writeFileSync(join(targetDir, "CORE.md"), options.coreContent);
70
+ } else {
71
+ const templateContent = loadTemplate(template, "CORE.md", vars);
72
+ writeFileSync(
73
+ join(targetDir, "CORE.md"),
74
+ templateContent ?? applyTemplate(`# {{AGENT_NAME}}
75
+
76
+ ## Purpose
77
+ {{PURPOSE}}
78
+
79
+ ## Values
80
+ - **Honesty**: I tell the truth, even when it's uncomfortable.
81
+ - **Action**: I bias toward doing, not discussing.
82
+ - **Autonomy**: I act independently within my boundaries.
83
+ - **Growth**: I learn from every interaction.
84
+ - **Protection**: I guard my creator's time, money, and reputation.
85
+
86
+ ## Ethics
87
+ - I never deceive my creator or others.
88
+ - I never take irreversible actions without confirmation.
89
+ - I never expose secrets, credentials, or private information.
90
+ - I escalate when uncertain rather than guessing.
91
+ `, vars)
92
+ );
93
+ }
94
+ const systemContent = loadTemplate(template, "SYSTEM.md", vars);
95
+ writeFileSync(
96
+ join(targetDir, "SYSTEM.md"),
97
+ systemContent ?? `# System
98
+
99
+ You are ${vars.agentName}. This file defines how you boot and operate.
100
+
101
+ ## Boot Sequence
102
+ 1. Load CORE.md \u2014 your identity (never changes)
103
+ 2. Load state.md \u2014 where you left off
104
+ 3. Load memory/scratch.md \u2014 current working memory
105
+ 4. Load indexes \u2014 scan all primitive directories
106
+ 5. Load relevant files based on current task
107
+
108
+ ## File Ownership
109
+ | Owner | Files | Can Modify |
110
+ |-------|-------|------------|
111
+ | Human | CORE.md, rules/*, config.yaml | Only human edits |
112
+ | Agent | instincts/*, memory/sessions/*, state.md (goals) | During/after interactions |
113
+ | Infrastructure | */_index.md, memory/journal/* | Auto-scripts only |
114
+
115
+ ## Context Loading Strategy
116
+ - L0 (~5 tokens): One-line summary \u2014 decides relevance
117
+ - L1 (~50-100 tokens): Paragraph \u2014 enough to work with
118
+ - L2 (full body): Complete content \u2014 loaded only when actively needed
119
+ - Always load CORE + state + scratch first
120
+ - Load primitives at the appropriate level based on token budget
121
+ `
122
+ );
123
+ const configContent = loadTemplate(template, "config.yaml", vars);
124
+ writeFileSync(join(targetDir, "config.yaml"), configContent ?? writeDefaultConfig(targetDir, agentName));
125
+ writeFileSync(
126
+ join(targetDir, "state.md"),
127
+ `# Agent State
128
+
129
+ ## Mode
130
+ idle
131
+
132
+ ## Goals
133
+
134
+ ## Active Workflows
135
+
136
+ ## Last Interaction
137
+ ${(/* @__PURE__ */ new Date()).toISOString()}
138
+
139
+ ## Unfinished Business
140
+ `
141
+ );
142
+ writeFileSync(join(targetDir, "memory", "scratch.md"), "");
143
+ copyDefaults(targetDir, vars);
144
+ writeFileSync(
145
+ join(targetDir, "README.md"),
146
+ `# ${agentName}
147
+
148
+ You just created an agent. The agent IS this folder \u2014 every file is part
149
+ of its identity, behavior, knowledge, and memory.
150
+
151
+ ## Try these in order
152
+
153
+ \`\`\`bash
154
+ harness run "What can you do?" # see what's loaded
155
+ harness run "Help me decide between two options: A or B"
156
+ harness run "Plan a weekend project for me" # watch it qualify before answering
157
+ \`\`\`
158
+
159
+ Use it for a few days with varied prompts. Then:
160
+
161
+ \`\`\`bash
162
+ harness journal # synthesize today's sessions and find patterns
163
+ harness learn --install # promote learned patterns into instincts
164
+ \`\`\`
165
+
166
+ The agent gets measurably better the more you use it. Every interaction
167
+ is journaled, patterns become instincts, and instincts change behavior
168
+ on the next run. **No retraining, no fine-tuning, no code.** You're
169
+ editing markdown.
170
+
171
+ ## What's in this folder
172
+
173
+ | File / dir | Owner | What it is |
174
+ |---|---|---|
175
+ | \`CORE.md\` | human | Identity. Who is this agent? Frozen. |
176
+ | \`SYSTEM.md\` | human | Boot instructions. How does it operate? |
177
+ | \`config.yaml\` | human | Model, runtime, MCP servers, budgets |
178
+ | \`state.md\` | mixed | Live state: mode, goals, last interaction |
179
+ | \`rules/\` | human | Hard boundaries the agent must respect |
180
+ | \`skills/\` | mixed | Capabilities + how to think about using them |
181
+ | \`playbooks/\` | mixed | Adaptive guidance for outcomes |
182
+ | \`instincts/\` | agent | Reflexive behaviors learned from sessions |
183
+ | \`workflows/\` | infra | Cron-driven automations |
184
+ | \`tools/\` | extern | HTTP/API tool definitions |
185
+ | \`agents/\` | extern | Sub-agent roster |
186
+ | \`memory/sessions/\` | agent | Auto-captured interaction records |
187
+ | \`memory/journal/\` | infra | Daily synthesized reflections |
188
+
189
+ Open any file and edit it. Save. Run \`harness run "..."\` again and the
190
+ agent reads your change. That's the loop.
191
+
192
+ ## Going further
193
+
194
+ \`\`\`bash
195
+ harness doctor # check scaffold health
196
+ harness graph # see how primitives reference each other
197
+ harness info # what's loaded in the context budget right now
198
+ harness mcp discover # find MCP tools already installed on your machine
199
+ harness mcp search <q> # browse the MCP registry for new tools
200
+ harness install <url> # install a skill, agent, or rule from a URL
201
+ \`\`\`
202
+
203
+ Tools come from MCP servers \u2014 install one with \`harness mcp install\`.
204
+
205
+ ## When something feels off
206
+
207
+ - \`harness validate\` \u2014 check the harness structure for errors
208
+ - \`harness doctor\` \u2014 same, but auto-fix what it can
209
+ - \`harness contradictions\` \u2014 check rules and instincts for conflicts
210
+ - \`harness dead-primitives\` \u2014 find files you haven't used in a while
211
+
212
+ The agent journal in \`memory/journal/\` is the most interesting place
213
+ to look \u2014 it's where the agent reflects on what you've been doing
214
+ together. Read it once a week.
215
+ `
216
+ );
217
+ writeFileSync(
218
+ join(targetDir, ".gitignore"),
219
+ `memory/scratch.md
220
+ memory/context.jsonl
221
+ memory/context.md
222
+ memory/sessions/*
223
+ memory/journal/*
224
+ !memory/sessions/.gitkeep
225
+ !memory/journal/.gitkeep
226
+ .env
227
+ `
228
+ );
229
+ writeFileSync(join(targetDir, "memory", "sessions", ".gitkeep"), "");
230
+ writeFileSync(join(targetDir, "memory", "journal", ".gitkeep"), "");
231
+ }
232
+ function generateSystemMd(harnessDir, agentName) {
233
+ const primitiveDirs = ["rules", "instincts", "skills", "playbooks", "workflows", "tools", "agents"];
234
+ const sections = [];
235
+ sections.push(`# System
236
+ `);
237
+ sections.push(`You are ${agentName}. This file defines how you boot and operate.
238
+ `);
239
+ sections.push(`## Boot Sequence
240
+ 1. Load CORE.md \u2014 your identity (never changes)
241
+ 2. Load state.md \u2014 where you left off
242
+ 3. Load memory/scratch.md \u2014 current working memory
243
+ 4. Load indexes \u2014 scan all primitive directories
244
+ 5. Load relevant files based on current task
245
+ `);
246
+ sections.push(`## Directory Structure
247
+ `);
248
+ for (const dir of primitiveDirs) {
249
+ const dirPath = join(harnessDir, dir);
250
+ if (!existsSync(dirPath)) continue;
251
+ const files = readdirSync(dirPath).filter((f) => f.endsWith(".md") && !f.startsWith("_"));
252
+ if (files.length === 0) {
253
+ sections.push(`- \`${dir}/\` \u2014 (empty)`);
254
+ } else {
255
+ sections.push(`- \`${dir}/\` \u2014 ${files.length} file(s): ${files.map((f) => f.replace(".md", "")).join(", ")}`);
256
+ }
257
+ }
258
+ const sessionsDir = join(harnessDir, "memory", "sessions");
259
+ const journalDir = join(harnessDir, "memory", "journal");
260
+ const sessionCount = existsSync(sessionsDir) ? readdirSync(sessionsDir).filter((f) => f.endsWith(".md")).length : 0;
261
+ const journalCount = existsSync(journalDir) ? readdirSync(journalDir).filter((f) => f.endsWith(".md")).length : 0;
262
+ sections.push(`- \`memory/sessions/\` \u2014 ${sessionCount} session(s)`);
263
+ sections.push(`- \`memory/journal/\` \u2014 ${journalCount} entry/entries`);
264
+ sections.push("");
265
+ sections.push(`## File Ownership
266
+ | Owner | Files | Can Modify |
267
+ |-------|-------|------------|
268
+ | Human | CORE.md, rules/*, config.yaml | Only human edits |
269
+ | Agent | instincts/*, memory/sessions/*, state.md (goals) | During/after interactions |
270
+ | Infrastructure | */_index.md, memory/journal/* | Auto-scripts only |
271
+ `);
272
+ sections.push(`## Context Loading Strategy
273
+ - L0 (~5 tokens): One-line summary \u2014 decides relevance
274
+ - L1 (~50-100 tokens): Paragraph \u2014 enough to work with
275
+ - L2 (full body): Complete content \u2014 loaded only when actively needed
276
+ - Always load CORE + state + scratch first
277
+ - Load primitives at the appropriate level based on token budget
278
+ `);
279
+ return sections.join("\n");
280
+ }
281
+ async function generateCoreMd(agentName, purpose, options) {
282
+ try {
283
+ const { generate, getModel } = await import("./provider-SXPQZ74H.js");
284
+ const { HarnessConfigSchema } = await import("./types-EW7AIB3R.js");
285
+ const config = HarnessConfigSchema.parse({
286
+ agent: { name: agentName, version: "0.1.0" },
287
+ model: {
288
+ provider: options.provider ?? "openrouter",
289
+ id: options.modelId ?? "anthropic/claude-sonnet-4"
290
+ }
291
+ });
292
+ const model = getModel(config, options.apiKey);
293
+ const result = await generate({
294
+ model,
295
+ system: `You are a technical writer creating an identity document for an AI agent.
296
+ The document defines who the agent is, what it does, its values, and its ethical boundaries.
297
+ Write in first person from the agent's perspective. Be specific and practical, not generic.
298
+ Output ONLY the markdown content, no code fences.`,
299
+ prompt: `Create a CORE.md identity document for an AI agent with:
300
+ - Name: ${agentName}
301
+ - Purpose: ${purpose}
302
+
303
+ The document should have these sections:
304
+ # ${agentName}
305
+
306
+ ## Purpose
307
+ (Detailed purpose based on the description \u2014 be specific to what this agent does)
308
+
309
+ ## Values
310
+ (5-7 values tailored to this agent's purpose \u2014 not generic platitudes)
311
+
312
+ ## Ethics
313
+ (4-6 ethical boundaries specific to this agent's domain)
314
+
315
+ ## Capabilities
316
+ (3-5 key capabilities this agent should have based on its purpose)
317
+
318
+ ## Boundaries
319
+ (3-5 things this agent should NOT do or areas where it should escalate)`,
320
+ maxOutputTokens: 2e3,
321
+ maxRetries: 1,
322
+ timeoutMs: 3e4
323
+ });
324
+ return result.text.trim();
325
+ } catch (err) {
326
+ if (err instanceof Error) throw err;
327
+ throw new Error(String(err));
328
+ }
329
+ }
330
+ function listTemplates() {
331
+ const templatesDir = join(getPackageRoot(), "templates");
332
+ if (!existsSync(templatesDir)) return [];
333
+ return readdirSync(templatesDir).filter((f) => {
334
+ try {
335
+ return readdirSync(join(templatesDir, f)).length > 0;
336
+ } catch {
337
+ return false;
338
+ }
339
+ });
340
+ }
341
+ export {
342
+ generateCoreMd,
343
+ generateSystemMd,
344
+ listTemplates,
345
+ scaffoldHarness
346
+ };
347
+ //# sourceMappingURL=scaffold-A3VRRCBV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/scaffold.ts"],"sourcesContent":["import { mkdirSync, writeFileSync, readFileSync, readdirSync, existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { writeDefaultConfig } from '../core/config.js';\n\nconst DIRECTORIES = [\n 'rules',\n 'instincts',\n 'skills',\n 'playbooks',\n 'workflows',\n 'tools',\n 'agents',\n 'intake',\n 'memory/sessions',\n 'memory/journal',\n];\n\n/**\n * Resolve the package root directory by walking up from import.meta.url\n * until we find package.json. Works in both dev (src/) and prod (dist/).\n */\nfunction getPackageRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url));\n for (let i = 0; i < 5; i++) {\n if (existsSync(join(dir, 'package.json'))) return dir;\n dir = dirname(dir);\n }\n // Fallback: assume 2 levels up from source\n return dirname(dirname(fileURLToPath(import.meta.url)));\n}\n\ninterface TemplateVars {\n agentName: string;\n purpose?: string;\n}\n\n/**\n * Apply template variables to a string.\n */\nfunction applyTemplate(content: string, vars: TemplateVars): string {\n const date = new Date().toISOString().split('T')[0];\n const defaultPurpose = `I am ${vars.agentName}, an autonomous AI agent. My purpose is to help my creator build, think, and ship.`;\n const purpose = vars.purpose\n ? `I am ${vars.agentName}. ${vars.purpose}`\n : defaultPurpose;\n return content\n .replace(/\\{\\{AGENT_NAME\\}\\}/g, vars.agentName)\n .replace(/\\{\\{PURPOSE\\}\\}/g, purpose)\n .replace(/\\{\\{DATE\\}\\}/g, date);\n}\n\n/**\n * Copy default primitives from defaults/ directory into the target harness.\n */\nfunction copyDefaults(targetDir: string, vars: TemplateVars): void {\n const defaultsDir = join(getPackageRoot(), 'defaults');\n if (!existsSync(defaultsDir)) return;\n\n const primitiveDirs = ['rules', 'instincts', 'skills', 'playbooks', 'agents', 'tools', 'workflows'];\n for (const dir of primitiveDirs) {\n const srcDir = join(defaultsDir, dir);\n if (!existsSync(srcDir)) continue;\n const files = readdirSync(srcDir).filter((f) => f.endsWith('.md'));\n for (const file of files) {\n const content = readFileSync(join(srcDir, file), 'utf-8');\n writeFileSync(join(targetDir, dir, file), applyTemplate(content, vars), 'utf-8');\n }\n }\n}\n\n/**\n * Load a template file and apply substitutions. Returns null if not found.\n */\nfunction loadTemplate(templateName: string, fileName: string, vars: TemplateVars): string | null {\n const templatePath = join(getPackageRoot(), 'templates', templateName, fileName);\n if (!existsSync(templatePath)) return null;\n return applyTemplate(readFileSync(templatePath, 'utf-8'), vars);\n}\n\nexport interface ScaffoldOptions {\n template?: string;\n /** Custom CORE.md content — overrides template */\n coreContent?: string;\n /** Agent purpose description (stored as comment in CORE.md when no LLM generation) */\n purpose?: string;\n}\n\nexport function scaffoldHarness(targetDir: string, agentName: string, options?: ScaffoldOptions): void {\n if (existsSync(targetDir)) {\n throw new Error(`Directory already exists: ${targetDir}`);\n }\n\n const template = options?.template ?? 'base';\n const vars: TemplateVars = { agentName, purpose: options?.purpose };\n\n // Create directory structure\n mkdirSync(targetDir, { recursive: true });\n for (const dir of DIRECTORIES) {\n mkdirSync(join(targetDir, dir), { recursive: true });\n }\n\n // --- CORE.md (custom > template > inline fallback) ---\n if (options?.coreContent) {\n writeFileSync(join(targetDir, 'CORE.md'), options.coreContent);\n } else {\n const templateContent = loadTemplate(template, 'CORE.md', vars);\n writeFileSync(\n join(targetDir, 'CORE.md'),\n templateContent ?? applyTemplate(`# {{AGENT_NAME}}\n\n## Purpose\n{{PURPOSE}}\n\n## Values\n- **Honesty**: I tell the truth, even when it's uncomfortable.\n- **Action**: I bias toward doing, not discussing.\n- **Autonomy**: I act independently within my boundaries.\n- **Growth**: I learn from every interaction.\n- **Protection**: I guard my creator's time, money, and reputation.\n\n## Ethics\n- I never deceive my creator or others.\n- I never take irreversible actions without confirmation.\n- I never expose secrets, credentials, or private information.\n- I escalate when uncertain rather than guessing.\n`, vars)\n );\n }\n\n // --- SYSTEM.md (from template, or inline fallback) ---\n const systemContent = loadTemplate(template, 'SYSTEM.md', vars);\n writeFileSync(\n join(targetDir, 'SYSTEM.md'),\n systemContent ?? `# System\n\nYou are ${vars.agentName}. This file defines how you boot and operate.\n\n## Boot Sequence\n1. Load CORE.md — your identity (never changes)\n2. Load state.md — where you left off\n3. Load memory/scratch.md — current working memory\n4. Load indexes — scan all primitive directories\n5. Load relevant files based on current task\n\n## File Ownership\n| Owner | Files | Can Modify |\n|-------|-------|------------|\n| Human | CORE.md, rules/*, config.yaml | Only human edits |\n| Agent | instincts/*, memory/sessions/*, state.md (goals) | During/after interactions |\n| Infrastructure | */_index.md, memory/journal/* | Auto-scripts only |\n\n## Context Loading Strategy\n- L0 (~5 tokens): One-line summary — decides relevance\n- L1 (~50-100 tokens): Paragraph — enough to work with\n- L2 (full body): Complete content — loaded only when actively needed\n- Always load CORE + state + scratch first\n- Load primitives at the appropriate level based on token budget\n`\n );\n\n // --- config.yaml (from template, or use writeDefaultConfig) ---\n const configContent = loadTemplate(template, 'config.yaml', vars);\n writeFileSync(join(targetDir, 'config.yaml'), configContent ?? writeDefaultConfig(targetDir, agentName));\n\n // --- state.md ---\n writeFileSync(\n join(targetDir, 'state.md'),\n `# Agent State\n\n## Mode\nidle\n\n## Goals\n\n## Active Workflows\n\n## Last Interaction\n${new Date().toISOString()}\n\n## Unfinished Business\n`\n );\n\n // --- memory/scratch.md ---\n writeFileSync(join(targetDir, 'memory', 'scratch.md'), '');\n\n // --- Copy default primitives from defaults/ directory ---\n copyDefaults(targetDir, vars);\n\n // --- README.md (the in-scaffold quickstart, the FIRST thing a non-coder reads) ---\n writeFileSync(\n join(targetDir, 'README.md'),\n `# ${agentName}\n\nYou just created an agent. The agent IS this folder — every file is part\nof its identity, behavior, knowledge, and memory.\n\n## Try these in order\n\n\\`\\`\\`bash\nharness run \"What can you do?\" # see what's loaded\nharness run \"Help me decide between two options: A or B\"\nharness run \"Plan a weekend project for me\" # watch it qualify before answering\n\\`\\`\\`\n\nUse it for a few days with varied prompts. Then:\n\n\\`\\`\\`bash\nharness journal # synthesize today's sessions and find patterns\nharness learn --install # promote learned patterns into instincts\n\\`\\`\\`\n\nThe agent gets measurably better the more you use it. Every interaction\nis journaled, patterns become instincts, and instincts change behavior\non the next run. **No retraining, no fine-tuning, no code.** You're\nediting markdown.\n\n## What's in this folder\n\n| File / dir | Owner | What it is |\n|---|---|---|\n| \\`CORE.md\\` | human | Identity. Who is this agent? Frozen. |\n| \\`SYSTEM.md\\` | human | Boot instructions. How does it operate? |\n| \\`config.yaml\\` | human | Model, runtime, MCP servers, budgets |\n| \\`state.md\\` | mixed | Live state: mode, goals, last interaction |\n| \\`rules/\\` | human | Hard boundaries the agent must respect |\n| \\`skills/\\` | mixed | Capabilities + how to think about using them |\n| \\`playbooks/\\` | mixed | Adaptive guidance for outcomes |\n| \\`instincts/\\` | agent | Reflexive behaviors learned from sessions |\n| \\`workflows/\\` | infra | Cron-driven automations |\n| \\`tools/\\` | extern | HTTP/API tool definitions |\n| \\`agents/\\` | extern | Sub-agent roster |\n| \\`memory/sessions/\\` | agent | Auto-captured interaction records |\n| \\`memory/journal/\\` | infra | Daily synthesized reflections |\n\nOpen any file and edit it. Save. Run \\`harness run \"...\"\\` again and the\nagent reads your change. That's the loop.\n\n## Going further\n\n\\`\\`\\`bash\nharness doctor # check scaffold health\nharness graph # see how primitives reference each other\nharness info # what's loaded in the context budget right now\nharness mcp discover # find MCP tools already installed on your machine\nharness mcp search <q> # browse the MCP registry for new tools\nharness install <url> # install a skill, agent, or rule from a URL\n\\`\\`\\`\n\nTools come from MCP servers — install one with \\`harness mcp install\\`.\n\n## When something feels off\n\n- \\`harness validate\\` — check the harness structure for errors\n- \\`harness doctor\\` — same, but auto-fix what it can\n- \\`harness contradictions\\` — check rules and instincts for conflicts\n- \\`harness dead-primitives\\` — find files you haven't used in a while\n\nThe agent journal in \\`memory/journal/\\` is the most interesting place\nto look — it's where the agent reflects on what you've been doing\ntogether. Read it once a week.\n`,\n );\n\n // --- .gitignore ---\n writeFileSync(\n join(targetDir, '.gitignore'),\n `memory/scratch.md\nmemory/context.jsonl\nmemory/context.md\nmemory/sessions/*\nmemory/journal/*\n!memory/sessions/.gitkeep\n!memory/journal/.gitkeep\n.env\n`\n );\n\n // Create .gitkeep files\n writeFileSync(join(targetDir, 'memory', 'sessions', '.gitkeep'), '');\n writeFileSync(join(targetDir, 'memory', 'journal', '.gitkeep'), '');\n}\n\n/**\n * Generate SYSTEM.md content from the actual directory structure of a harness.\n * Scans for primitives and reflects the real structure.\n */\nexport function generateSystemMd(harnessDir: string, agentName: string): string {\n const primitiveDirs = ['rules', 'instincts', 'skills', 'playbooks', 'workflows', 'tools', 'agents'];\n const sections: string[] = [];\n\n sections.push(`# System\\n`);\n sections.push(`You are ${agentName}. This file defines how you boot and operate.\\n`);\n\n // Boot sequence\n sections.push(`## Boot Sequence\n1. Load CORE.md — your identity (never changes)\n2. Load state.md — where you left off\n3. Load memory/scratch.md — current working memory\n4. Load indexes — scan all primitive directories\n5. Load relevant files based on current task\\n`);\n\n // Directory structure\n sections.push(`## Directory Structure\\n`);\n\n for (const dir of primitiveDirs) {\n const dirPath = join(harnessDir, dir);\n if (!existsSync(dirPath)) continue;\n\n const files = readdirSync(dirPath).filter((f) => f.endsWith('.md') && !f.startsWith('_'));\n if (files.length === 0) {\n sections.push(`- \\`${dir}/\\` — (empty)`);\n } else {\n sections.push(`- \\`${dir}/\\` — ${files.length} file(s): ${files.map((f) => f.replace('.md', '')).join(', ')}`);\n }\n }\n\n // Memory\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n const journalDir = join(harnessDir, 'memory', 'journal');\n const sessionCount = existsSync(sessionsDir)\n ? readdirSync(sessionsDir).filter((f) => f.endsWith('.md')).length\n : 0;\n const journalCount = existsSync(journalDir)\n ? readdirSync(journalDir).filter((f) => f.endsWith('.md')).length\n : 0;\n\n sections.push(`- \\`memory/sessions/\\` — ${sessionCount} session(s)`);\n sections.push(`- \\`memory/journal/\\` — ${journalCount} entry/entries`);\n sections.push('');\n\n // File ownership\n sections.push(`## File Ownership\n| Owner | Files | Can Modify |\n|-------|-------|------------|\n| Human | CORE.md, rules/*, config.yaml | Only human edits |\n| Agent | instincts/*, memory/sessions/*, state.md (goals) | During/after interactions |\n| Infrastructure | */_index.md, memory/journal/* | Auto-scripts only |\\n`);\n\n // Context loading strategy\n sections.push(`## Context Loading Strategy\n- L0 (~5 tokens): One-line summary — decides relevance\n- L1 (~50-100 tokens): Paragraph — enough to work with\n- L2 (full body): Complete content — loaded only when actively needed\n- Always load CORE + state + scratch first\n- Load primitives at the appropriate level based on token budget\n`);\n\n return sections.join('\\n');\n}\n\n/**\n * Generate a rich CORE.md using an LLM, given an agent name and purpose description.\n * Returns the generated markdown content, or throws on failure.\n */\nexport async function generateCoreMd(\n agentName: string,\n purpose: string,\n options: { provider?: string; modelId?: string; apiKey?: string },\n): Promise<string> {\n try {\n const { generate, getModel } = await import('../llm/provider.js');\n const { HarnessConfigSchema } = await import('../core/types.js');\n\n const config = HarnessConfigSchema.parse({\n agent: { name: agentName, version: '0.1.0' },\n model: {\n provider: options.provider ?? 'openrouter',\n id: options.modelId ?? 'anthropic/claude-sonnet-4',\n },\n });\n\n const model = getModel(config, options.apiKey);\n const result = await generate({\n model,\n system: `You are a technical writer creating an identity document for an AI agent.\nThe document defines who the agent is, what it does, its values, and its ethical boundaries.\nWrite in first person from the agent's perspective. Be specific and practical, not generic.\nOutput ONLY the markdown content, no code fences.`,\n prompt: `Create a CORE.md identity document for an AI agent with:\n- Name: ${agentName}\n- Purpose: ${purpose}\n\nThe document should have these sections:\n# ${agentName}\n\n## Purpose\n(Detailed purpose based on the description — be specific to what this agent does)\n\n## Values\n(5-7 values tailored to this agent's purpose — not generic platitudes)\n\n## Ethics\n(4-6 ethical boundaries specific to this agent's domain)\n\n## Capabilities\n(3-5 key capabilities this agent should have based on its purpose)\n\n## Boundaries\n(3-5 things this agent should NOT do or areas where it should escalate)`,\n maxOutputTokens: 2000,\n maxRetries: 1,\n timeoutMs: 30000,\n });\n\n return result.text.trim();\n } catch (err: unknown) {\n if (err instanceof Error) throw err;\n throw new Error(String(err));\n }\n}\n\n/**\n * List available templates.\n */\nexport function listTemplates(): string[] {\n const templatesDir = join(getPackageRoot(), 'templates');\n if (!existsSync(templatesDir)) return [];\n return readdirSync(templatesDir).filter((f) => {\n try {\n return readdirSync(join(templatesDir, f)).length > 0;\n } catch {\n return false;\n }\n });\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,WAAW,eAAe,cAAc,aAAa,kBAAkB;AAChF,SAAS,MAAM,eAAe;AAC9B,SAAS,qBAAqB;AAG9B,IAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMA,SAAS,iBAAyB;AAChC,MAAI,MAAM,QAAQ,cAAc,YAAY,GAAG,CAAC;AAChD,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,QAAI,WAAW,KAAK,KAAK,cAAc,CAAC,EAAG,QAAO;AAClD,UAAM,QAAQ,GAAG;AAAA,EACnB;AAEA,SAAO,QAAQ,QAAQ,cAAc,YAAY,GAAG,CAAC,CAAC;AACxD;AAUA,SAAS,cAAc,SAAiB,MAA4B;AAClE,QAAM,QAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAClD,QAAM,iBAAiB,QAAQ,KAAK,SAAS;AAC7C,QAAM,UAAU,KAAK,UACjB,QAAQ,KAAK,SAAS,KAAK,KAAK,OAAO,KACvC;AACJ,SAAO,QACJ,QAAQ,uBAAuB,KAAK,SAAS,EAC7C,QAAQ,oBAAoB,OAAO,EACnC,QAAQ,iBAAiB,IAAI;AAClC;AAKA,SAAS,aAAa,WAAmB,MAA0B;AACjE,QAAM,cAAc,KAAK,eAAe,GAAG,UAAU;AACrD,MAAI,CAAC,WAAW,WAAW,EAAG;AAE9B,QAAM,gBAAgB,CAAC,SAAS,aAAa,UAAU,aAAa,UAAU,SAAS,WAAW;AAClG,aAAW,OAAO,eAAe;AAC/B,UAAM,SAAS,KAAK,aAAa,GAAG;AACpC,QAAI,CAAC,WAAW,MAAM,EAAG;AACzB,UAAM,QAAQ,YAAY,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC;AACjE,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,aAAa,KAAK,QAAQ,IAAI,GAAG,OAAO;AACxD,oBAAc,KAAK,WAAW,KAAK,IAAI,GAAG,cAAc,SAAS,IAAI,GAAG,OAAO;AAAA,IACjF;AAAA,EACF;AACF;AAKA,SAAS,aAAa,cAAsB,UAAkB,MAAmC;AAC/F,QAAM,eAAe,KAAK,eAAe,GAAG,aAAa,cAAc,QAAQ;AAC/E,MAAI,CAAC,WAAW,YAAY,EAAG,QAAO;AACtC,SAAO,cAAc,aAAa,cAAc,OAAO,GAAG,IAAI;AAChE;AAUO,SAAS,gBAAgB,WAAmB,WAAmB,SAAiC;AACrG,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,IAAI,MAAM,6BAA6B,SAAS,EAAE;AAAA,EAC1D;AAEA,QAAM,WAAW,SAAS,YAAY;AACtC,QAAM,OAAqB,EAAE,WAAW,SAAS,SAAS,QAAQ;AAGlE,YAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AACxC,aAAW,OAAO,aAAa;AAC7B,cAAU,KAAK,WAAW,GAAG,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EACrD;AAGA,MAAI,SAAS,aAAa;AACxB,kBAAc,KAAK,WAAW,SAAS,GAAG,QAAQ,WAAW;AAAA,EAC/D,OAAO;AACL,UAAM,kBAAkB,aAAa,UAAU,WAAW,IAAI;AAC9D;AAAA,MACE,KAAK,WAAW,SAAS;AAAA,MACzB,mBAAmB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAiBpC,IAAI;AAAA,IACH;AAAA,EACF;AAGA,QAAM,gBAAgB,aAAa,UAAU,aAAa,IAAI;AAC9D;AAAA,IACE,KAAK,WAAW,WAAW;AAAA,IAC3B,iBAAiB;AAAA;AAAA,UAEX,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBtB;AAGA,QAAM,gBAAgB,aAAa,UAAU,eAAe,IAAI;AAChE,gBAAc,KAAK,WAAW,aAAa,GAAG,iBAAiB,mBAAmB,WAAW,SAAS,CAAC;AAGvG;AAAA,IACE,KAAK,WAAW,UAAU;AAAA,IAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAUF,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA,EAIxB;AAGA,gBAAc,KAAK,WAAW,UAAU,YAAY,GAAG,EAAE;AAGzD,eAAa,WAAW,IAAI;AAG5B;AAAA,IACE,KAAK,WAAW,WAAW;AAAA,IAC3B,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsEhB;AAGA;AAAA,IACE,KAAK,WAAW,YAAY;AAAA,IAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASF;AAGA,gBAAc,KAAK,WAAW,UAAU,YAAY,UAAU,GAAG,EAAE;AACnE,gBAAc,KAAK,WAAW,UAAU,WAAW,UAAU,GAAG,EAAE;AACpE;AAMO,SAAS,iBAAiB,YAAoB,WAA2B;AAC9E,QAAM,gBAAgB,CAAC,SAAS,aAAa,UAAU,aAAa,aAAa,SAAS,QAAQ;AAClG,QAAM,WAAqB,CAAC;AAE5B,WAAS,KAAK;AAAA,CAAY;AAC1B,WAAS,KAAK,WAAW,SAAS;AAAA,CAAiD;AAGnF,WAAS,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAK+B;AAG7C,WAAS,KAAK;AAAA,CAA0B;AAExC,aAAW,OAAO,eAAe;AAC/B,UAAM,UAAU,KAAK,YAAY,GAAG;AACpC,QAAI,CAAC,WAAW,OAAO,EAAG;AAE1B,UAAM,QAAQ,YAAY,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,KAAK,CAAC,EAAE,WAAW,GAAG,CAAC;AACxF,QAAI,MAAM,WAAW,GAAG;AACtB,eAAS,KAAK,OAAO,GAAG,oBAAe;AAAA,IACzC,OAAO;AACL,eAAS,KAAK,OAAO,GAAG,cAAS,MAAM,MAAM,aAAa,MAAM,IAAI,CAAC,MAAM,EAAE,QAAQ,OAAO,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,IAC/G;AAAA,EACF;AAGA,QAAM,cAAc,KAAK,YAAY,UAAU,UAAU;AACzD,QAAM,aAAa,KAAK,YAAY,UAAU,SAAS;AACvD,QAAM,eAAe,WAAW,WAAW,IACvC,YAAY,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,EAAE,SAC1D;AACJ,QAAM,eAAe,WAAW,UAAU,IACtC,YAAY,UAAU,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,EAAE,SACzD;AAEJ,WAAS,KAAK,iCAA4B,YAAY,aAAa;AACnE,WAAS,KAAK,gCAA2B,YAAY,gBAAgB;AACrE,WAAS,KAAK,EAAE;AAGhB,WAAS,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAKyD;AAGvE,WAAS,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAMf;AAEC,SAAO,SAAS,KAAK,IAAI;AAC3B;AAMA,eAAsB,eACpB,WACA,SACA,SACiB;AACjB,MAAI;AACF,UAAM,EAAE,UAAU,SAAS,IAAI,MAAM,OAAO,wBAAoB;AAChE,UAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,qBAAkB;AAE/D,UAAM,SAAS,oBAAoB,MAAM;AAAA,MACvC,OAAO,EAAE,MAAM,WAAW,SAAS,QAAQ;AAAA,MAC3C,OAAO;AAAA,QACL,UAAU,QAAQ,YAAY;AAAA,QAC9B,IAAI,QAAQ,WAAW;AAAA,MACzB;AAAA,IACF,CAAC;AAED,UAAM,QAAQ,SAAS,QAAQ,QAAQ,MAAM;AAC7C,UAAM,SAAS,MAAM,SAAS;AAAA,MAC5B;AAAA,MACA,QAAQ;AAAA;AAAA;AAAA;AAAA,MAIR,QAAQ;AAAA,UACJ,SAAS;AAAA,aACN,OAAO;AAAA;AAAA;AAAA,IAGhB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAgBP,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,WAAW;AAAA,IACb,CAAC;AAED,WAAO,OAAO,KAAK,KAAK;AAAA,EAC1B,SAAS,KAAc;AACrB,QAAI,eAAe,MAAO,OAAM;AAChC,UAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAAA,EAC7B;AACF;AAKO,SAAS,gBAA0B;AACxC,QAAM,eAAe,KAAK,eAAe,GAAG,WAAW;AACvD,MAAI,CAAC,WAAW,YAAY,EAAG,QAAO,CAAC;AACvC,SAAO,YAAY,YAAY,EAAE,OAAO,CAAC,MAAM;AAC7C,QAAI;AACF,aAAO,YAAY,KAAK,cAAc,CAAC,CAAC,EAAE,SAAS;AAAA,IACrD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}