@dsh-cc/memory 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.i18n.yaml +6 -0
- package/README.md +158 -0
- package/README.zh.md +125 -0
- package/lib/index.d.ts +75 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +91 -0
- package/lib/index.js.map +1 -0
- package/lib/invariant.d.ts +16 -0
- package/lib/invariant.d.ts.map +1 -0
- package/lib/invariant.js +22 -0
- package/lib/invariant.js.map +1 -0
- package/lib/parser.d.ts +30 -0
- package/lib/parser.d.ts.map +1 -0
- package/lib/parser.js +96 -0
- package/lib/parser.js.map +1 -0
- package/lib/paths.d.ts +98 -0
- package/lib/paths.d.ts.map +1 -0
- package/lib/paths.js +236 -0
- package/lib/paths.js.map +1 -0
- package/lib/recall.d.ts +91 -0
- package/lib/recall.d.ts.map +1 -0
- package/lib/recall.js +253 -0
- package/lib/recall.js.map +1 -0
- package/lib/save.d.ts +53 -0
- package/lib/save.d.ts.map +1 -0
- package/lib/save.js +180 -0
- package/lib/save.js.map +1 -0
- package/lib/scan.d.ts +29 -0
- package/lib/scan.d.ts.map +1 -0
- package/lib/scan.js +70 -0
- package/lib/scan.js.map +1 -0
- package/lib/section.d.ts +129 -0
- package/lib/section.d.ts.map +1 -0
- package/lib/section.js +353 -0
- package/lib/section.js.map +1 -0
- package/lib/team.d.ts +90 -0
- package/lib/team.d.ts.map +1 -0
- package/lib/team.js +167 -0
- package/lib/team.js.map +1 -0
- package/lib/truncate.d.ts +35 -0
- package/lib/truncate.d.ts.map +1 -0
- package/lib/truncate.js +52 -0
- package/lib/truncate.js.map +1 -0
- package/lib/types.d.ts +34 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +18 -0
- package/lib/types.js.map +1 -0
- package/lib/writeback.d.ts +85 -0
- package/lib/writeback.d.ts.map +1 -0
- package/lib/writeback.js +121 -0
- package/lib/writeback.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/memory/memory/README.md
|
|
5
|
+
README.md: e3d00ee79cf9394465b6022485a6a32442a90322
|
|
6
|
+
README.zh.md: 2a052e4fe0493f782b5acf29b44786d321b04952
|
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# dsh-memory
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
Claude Code-style file-based memory for the DeepSeek Harness: a durable memdir
|
|
6
|
+
format, a `memory` system-prompt section, the `memory_save` write channel, and
|
|
7
|
+
dynamic recall by a forked side-query. All file access goes through the
|
|
8
|
+
optional `ctx.fs` seam, so a remote or sandboxed backend works unchanged (a
|
|
9
|
+
providerless host mounts memory read-only).
|
|
10
|
+
|
|
11
|
+
## What this package provides
|
|
12
|
+
|
|
13
|
+
- **Memdir format** — a memory home (default the harness home's `memory/`)
|
|
14
|
+
holding an always-loaded `MEMORY.md` entrypoint (capped at 200 lines / 25 KB)
|
|
15
|
+
per layer, each a one-line index of `.md` topic files. Each topic file
|
|
16
|
+
carries `name`, `description`, and `type` (`user` / `feedback` / `project` /
|
|
17
|
+
`reference`) frontmatter plus a Markdown body. The parser is independently
|
|
18
|
+
exported.
|
|
19
|
+
- **Per-workspace isolation with a global layer** — memories are scoped to the
|
|
20
|
+
git repository (Claude Code auto-memory identity): `canonicalMemoryRoot`
|
|
21
|
+
collapses linked worktrees and subdirectories onto the main checkout, then
|
|
22
|
+
the slug is the upstream `projectKey` dash-encoding of that root, so the
|
|
23
|
+
workspace directory is `<memoryHome>/projects/<slug>/`. Worktrees of one
|
|
24
|
+
repo — and the opt-in `<workspaceDir>/team` layer — share one store. The
|
|
25
|
+
home root itself is the global layer shared by every workspace. Sessions
|
|
26
|
+
of different repositories never see each other's private memories; facts
|
|
27
|
+
useful everywhere are saved with `scope: "global"`. Session transcripts
|
|
28
|
+
still group by raw cwd (`sessions/--<cwd-slug>--`); memory no longer
|
|
29
|
+
matches that grouping for worktree sessions.
|
|
30
|
+
- **`memory` system-prompt section** — save-channel guidance, each layer's
|
|
31
|
+
entrypoint content (truncated), a scope-tagged combined index of topic
|
|
32
|
+
files, and grep search guidance. The section ALWAYS renders (a memoryless
|
|
33
|
+
layer shows a placeholder) so the save guidance never disappears. One global
|
|
34
|
+
registration serves every agent: the text callback renders the assembling
|
|
35
|
+
agent's own workspace layer (the agent arrives via the assemble scope).
|
|
36
|
+
Delegated children (`delegationDepth > 0`) render an empty string so the
|
|
37
|
+
section drops out of the child prompt — matching Claude Code, auto-memory is
|
|
38
|
+
not shared with non-fork subagents; the parent prompt must pass any facts the
|
|
39
|
+
child needs. Directory scans run in the background through `ctx.fs`; rendered
|
|
40
|
+
per-layer fragments are cached and `system-prompt/change` fires only when a
|
|
41
|
+
fragment actually changed; a turn-end listener re-scans so host-side writes
|
|
42
|
+
surface without a restart.
|
|
43
|
+
- **`memory_save` tool** — the ONLY working save channel. Memory directories
|
|
44
|
+
live outside every session workspace, so direct `write`/`edit` calls
|
|
45
|
+
against them are fenced by the fs sandbox and always fail; the section says
|
|
46
|
+
so explicitly. The tool takes structured fields (`name`, `type`,
|
|
47
|
+
`description`, `body`, optional `scope`: `workspace` (default) or `global`),
|
|
48
|
+
resolves the target directory from the calling agent's canonical git root,
|
|
49
|
+
generates the frontmatter host-side, upserts the `MEMORY.md` pointer, and
|
|
50
|
+
writes via the `ctx.fs` seam under a per-call policy of
|
|
51
|
+
`{ mode: 'workspace-write', workspaceRoot: <memory dir> }` — confinement is
|
|
52
|
+
kept, the writable root IS the memory directory. Validation (kebab-case
|
|
53
|
+
slugs, the four types, size caps) shares the `writeback` boundary with
|
|
54
|
+
`dsh-memory-consolidation`'s fork write-back. Registration is opportunistic:
|
|
55
|
+
hosts without a tools service skip it and stay read-only.
|
|
56
|
+
- **Dynamic recall** — an `agent/pre-step` listener asks a small-model side
|
|
57
|
+
query (a forked subagent via `ctx.subagents`) which topic files are relevant
|
|
58
|
+
to the turn, then injects their bodies through `agent.inject()`. Recall
|
|
59
|
+
scans both layers (the agent's workspace directory plus the global one) and
|
|
60
|
+
deduplicates: topic files already shown this session are never re-injected.
|
|
61
|
+
Tools used earlier in the session are tracked (`tools/post-execute`) and
|
|
62
|
+
passed to the selector so reference-doc memories for an actively-used tool
|
|
63
|
+
are suppressed (warnings/gotchas about it are still surfaced). Absence of the
|
|
64
|
+
subagent service or provider skips recall without error.
|
|
65
|
+
- **Team memory (opt-in)** — when `teamEnabled` is `true`, a shared
|
|
66
|
+
per-workspace team directory (`<workspaceDir>/team`) is layered on the
|
|
67
|
+
workspace's private memdir and the `memory` section renders a combined
|
|
68
|
+
workspace + team + global prompt. Every team-memory access runs a
|
|
69
|
+
seam-native validation chain (pure-string key sanitization first, then
|
|
70
|
+
`lstat` final-segment symlink rejection, then `resolve` + `contains` prefix
|
|
71
|
+
containment).
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
Load the plugin with `@dsh-cc/memory`. Configuration knobs:
|
|
76
|
+
|
|
77
|
+
| Key | Default | Meaning |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| `memoryHome` | harness home `memory/` | memory home root: the global layer, and the parent of each repository's `projects/<slug>/` directory |
|
|
80
|
+
| `sectionEnabled` | `true` | register the `memory` system-prompt section |
|
|
81
|
+
| `recallEnabled` | `true` | run dynamic recall on pre-step |
|
|
82
|
+
| `recallProviderName` | `fork` | one-shot subagent provider for the recall query |
|
|
83
|
+
| `recallAgentOptions` | unset | raw `agentOptions` stamped onto the recall fork; wins over `recallUseSmallFast` and is NOT alias-resolved (pass a resolved route, not `{ model: 'haiku' }`) |
|
|
84
|
+
| `recallUseSmallFast` | `false` | opt the recall fork into the cheap lane: stamp `resolve('haiku')` from `ccModelRoutes` (inherit when unconfigured). Opt-in so configuring `haiku` for typed agents doesn't silently flip every recall onto a cross-model, prefix-inheriting fork |
|
|
85
|
+
| `teamEnabled` | `false` | enable the per-workspace team memory directory + combined section |
|
|
86
|
+
|
|
87
|
+
> **`teamEnabled` is off by default.** Enabling it changes the persisted
|
|
88
|
+
> memory layout (creates and reads `<workspaceDir>/team/`), changes what the
|
|
89
|
+
> model writes (workspace vs `team` scope), and points team-memory reads at a
|
|
90
|
+
> shared directory. It is intended for single-tenant, trusted-writer projects:
|
|
91
|
+
> the per-access validation closes traversal, but the *intermediate*-component
|
|
92
|
+
> TOCTOU window is not fully closed (only the final segment is `lstat`-checked,
|
|
93
|
+
> and the resolve/containment check and the read are not atomic). Do not enable
|
|
94
|
+
> `teamEnabled` in multi-tenant or untrusted-writer deployments.
|
|
95
|
+
|
|
96
|
+
> **Layout change.** Before per-workspace isolation, all memories lived flat
|
|
97
|
+
> in `memoryHome/`. Those top-level files are not migrated: they now serve as
|
|
98
|
+
> the global layer (visible to every workspace). A pre-isolation team
|
|
99
|
+
> directory at `<memoryHome>/team/` is inert — team memory now lives at
|
|
100
|
+
> `<workspaceDir>/team/`; move its files manually if you had `teamEnabled`
|
|
101
|
+
> on. Pre-collapse worktree-cwd slugs (`projects/<slug-of-the-worktree-path>/`)
|
|
102
|
+
> are likewise not migrated: they stay on disk unused; new writes land in the
|
|
103
|
+
> main-checkout bucket.
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import memory from '@dsh-cc/memory'
|
|
107
|
+
await ctx.plugin(memory, { memoryHome: '/tmp/mem' })
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Model Experience
|
|
111
|
+
|
|
112
|
+
Baseline cost: one synchronous render of the cached section text per step (no
|
|
113
|
+
I/O). The cheapest path additionally scans the memory directory — when it
|
|
114
|
+
contains topics, recall may spend one small-model subagent call per turn until
|
|
115
|
+
all topics have been shown, then stops. Token growth is bounded by the
|
|
116
|
+
entrypoint truncation caps and the five-file recall ceiling.
|
|
117
|
+
|
|
118
|
+
## API
|
|
119
|
+
|
|
120
|
+
- `parseMemoryFile(raw)` — split a topic file into frontmatter + body.
|
|
121
|
+
- `scanMemoryDirectory(fs, dir, signal?)` — read the entrypoint and topic index.
|
|
122
|
+
- `renderMemorySection(globalDir, workspaceDir, ...)` /
|
|
123
|
+
`renderTeamMemorySection(...)` / `renderLayers(layers)` /
|
|
124
|
+
`saveGuidance(workspaceDir, globalDir)` — the section text builders.
|
|
125
|
+
- `MemorySection` — background-refresh cache holder for the section (one
|
|
126
|
+
registration, per-agent workspace layers).
|
|
127
|
+
- `registerMemorySaveTool(ctx, home, section)` / `MEMORY_SAVE_TOOL` /
|
|
128
|
+
`MEMORY_SAVE_SCOPES` — the model-facing save channel.
|
|
129
|
+
- `validateMemoryWrites(input)` / `writeMemoryFiles(fs, dir, writes)` /
|
|
130
|
+
`memoryWritePolicy(dir)` / `MEMORY_WRITES_SCHEMA` — the host-side write-back
|
|
131
|
+
shared with `dsh-memory-consolidation`.
|
|
132
|
+
- `MemoryRecall` — the pre-step recall coordinator.
|
|
133
|
+
- `truncateEntrypointContent(raw)` — apply the line/byte caps.
|
|
134
|
+
- `resolveMemoryHome`, `resolveWorkspaceMemoryDir`, `canonicalMemoryRoot`,
|
|
135
|
+
`projectSlug`, `cwdOf`, `resolveProjectMemoryRoot` — memdir root and
|
|
136
|
+
workspace helpers. `canonicalMemoryRoot` is the git-repo collapse
|
|
137
|
+
(worktrees → main checkout); `cwdOf` stays the live working copy.
|
|
138
|
+
- `sanitizePathKey(key)`, `validateTeamMemKey(fs, teamDir, relativeKey)`,
|
|
139
|
+
`resolveTeamMemoryRoot(workspaceDir)` — the team-memory security chain and
|
|
140
|
+
path helpers.
|
|
141
|
+
|
|
142
|
+
## Known Limitations and Deferred Work
|
|
143
|
+
|
|
144
|
+
- The `ctx.fs` seam exposes no mtime, so recall deduplication tracks shown
|
|
145
|
+
paths per session rather than mtime+path; content is re-read fresh each
|
|
146
|
+
injection, which still reflects on-disk changes. CC's `memoryAge` freshness
|
|
147
|
+
weighting is therefore deferred until the seam carries mtime (see
|
|
148
|
+
`docs/cc-parity-matrix.md`).
|
|
149
|
+
- The recall side-query relies on a registered one-shot subagent provider; no
|
|
150
|
+
provider ships with this package (compose `fork` or `spawn`).
|
|
151
|
+
- `memory_save` writes the workspace and global layers only; a team-scope save
|
|
152
|
+
channel and a delete channel are deferred (as is CC's direct-Write parity,
|
|
153
|
+
which the fs sandbox makes impossible for session tools).
|
|
154
|
+
- Team memory (`teamEnabled`) reversibility and safety: enabling it is a
|
|
155
|
+
persisted-format change, and the intermediate-component TOCTOU window (only
|
|
156
|
+
the final segment is `lstat`-checked; resolve/containment and the read are
|
|
157
|
+
not atomic) means it must not be enabled in multi-tenant or untrusted-writer
|
|
158
|
+
deployments.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# dsh-memory
|
|
2
|
+
|
|
3
|
+
中文 | [English](README.md)
|
|
4
|
+
|
|
5
|
+
面向 DeepSeek Harness 的 Claude Code 风格文件记忆:可持久化的 memdir 格式、
|
|
6
|
+
`memory` 系统提示词 section、`memory_save` 写入通道,以及通过 fork 的
|
|
7
|
+
side-query 进行动态召回。所有文件访问都走可选的 `ctx.fs` 缝,因此远程或沙箱
|
|
8
|
+
后端可无改动使用(无 provider 的宿主将记忆挂载为只读)。
|
|
9
|
+
|
|
10
|
+
## 本包提供的能力
|
|
11
|
+
|
|
12
|
+
- **Memdir 格式** —— 一个记忆 home(默认为 harness home 的 `memory/`),每层
|
|
13
|
+
包含始终加载的 `MEMORY.md` 入口(上限 200 行 / 25 KB,是 `.md` 主题文件的
|
|
14
|
+
一行式索引)。每个主题文件带 `name`、`description` 与 `type`(`user` /
|
|
15
|
+
`feedback` / `project` / `reference`)frontmatter 以及 Markdown 正文。解析器
|
|
16
|
+
已独立导出。
|
|
17
|
+
- **按仓库隔离 + 全局层** —— 记忆按 git 仓库划分(对齐 Claude Code auto memory):
|
|
18
|
+
`canonicalMemoryRoot` 把 linked worktree 和子目录折叠到主 checkout,再对这个
|
|
19
|
+
根做上游 `projectKey` 的 dash 编码,工作区目录即为 `<memoryHome>/projects/<slug>/`。
|
|
20
|
+
同一仓库的 worktree —— 以及可选的 `<workspaceDir>/team` 层 —— 共用一份存储。
|
|
21
|
+
home 根本身是所有工作区共享的全局层。不同仓库的会话互相看不到对方的私有记忆;
|
|
22
|
+
到处都用得上的事实以 `scope: "global"` 保存。会话转录仍按原始 cwd 分组
|
|
23
|
+
(`sessions/--<cwd-slug>--`);worktree 会话的记忆目录不再与之对齐。
|
|
24
|
+
- **`memory` 系统提示词 section** —— 保存通道指引、各层入口内容(截断)、按
|
|
25
|
+
scope 标注的合并主题索引、以及 grep 搜索指引。section 始终渲染(无记忆的层显示
|
|
26
|
+
占位符),保存指引永不缺席。一次全局注册服务所有 agent:text 回调渲染发起组装
|
|
27
|
+
的 agent 自己的工作区层(agent 经 assemble scope 传入)。委派 child
|
|
28
|
+
(`delegationDepth > 0`)渲染空串,section 从 child 提示词中消失——对齐 Claude
|
|
29
|
+
Code:自动记忆不与非 fork 子代理共享,父 prompt 必须自行传递 child 需要的事实。
|
|
30
|
+
目录扫描经 `ctx.fs` 在后台进行;各层渲染片段缓存,仅当片段实际变化时才发出
|
|
31
|
+
`system-prompt/change`;轮末监听器会重新扫描,host 侧写入无需重启即可进入提示词。
|
|
32
|
+
- **`memory_save` 工具** —— 唯一可用的保存通道。记忆目录在所有会话 workspace
|
|
33
|
+
之外,直接的 `write`/`edit` 调用会被 fs sandbox 拦截、必然失败,section 文案
|
|
34
|
+
对此有明确说明。工具接收结构化字段(`name`、`type`、`description`、`body`、可选
|
|
35
|
+
`scope`:`workspace`(默认)或 `global`),按调用 agent 的规范 git 根解析目标
|
|
36
|
+
目录,由 host 侧生成 frontmatter、upsert `MEMORY.md` 指针行,并经 `ctx.fs` 缝以
|
|
37
|
+
`{ mode: 'workspace-write', workspaceRoot: <记忆目录> }` 的 per-call 策略
|
|
38
|
+
落盘——围栏保留,可写根恰好是记忆目录。校验(kebab-case slug、四种类型、大小
|
|
39
|
+
上限)与 `dsh-memory-consolidation` 的 fork 写回共用同一 `writeback` 边界。
|
|
40
|
+
注册是机会式的:宿主无 tools 服务时跳过并保持只读。
|
|
41
|
+
- **动态召回** —— `agent/pre-step` 监听器用小型模型 side-query(通过
|
|
42
|
+
`ctx.subagents` fork)判断哪些主题文件与当前轮相关,再通过 `agent.inject()`
|
|
43
|
+
注入其正文。召回扫描两层(agent 的工作区目录加上全局目录)并去重:本会话已
|
|
44
|
+
展示过的主题文件不会重复注入。会跟踪本会话早期使用过的工具
|
|
45
|
+
(`tools/post-execute`)并传给 selector,从而抑制正在使用工具的参考文档类记忆
|
|
46
|
+
(其警告/坑点仍会呈现)。subagent 服务或 provider 缺失时跳过召回,不报错。
|
|
47
|
+
- **团队记忆(可选)** —— 当 `teamEnabled` 为 `true` 时,在工作区私有 memdir 之内
|
|
48
|
+
叠加该工作区共享的团队目录(`<workspaceDir>/team`),`memory` section 渲染合并的
|
|
49
|
+
工作区 + 团队 + 全局提示词。每次团队记忆访问都走 seam 原生校验链(先纯字符串键
|
|
50
|
+
sanitization,再 `lstat` 末段 symlink 拒绝,最后 `resolve` + `contains` 前缀
|
|
51
|
+
包含校验)。
|
|
52
|
+
|
|
53
|
+
## 使用
|
|
54
|
+
|
|
55
|
+
以 `@dsh-cc/memory` 加载插件。配置项:
|
|
56
|
+
|
|
57
|
+
| Key | 默认值 | 含义 |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `memoryHome` | harness home `memory/` | 记忆 home 根:全局层本身,也是各仓库 `projects/<slug>/` 目录的父级 |
|
|
60
|
+
| `sectionEnabled` | `true` | 注册 `memory` 系统提示词 section |
|
|
61
|
+
| `recallEnabled` | `true` | 在 pre-step 上运行动态召回 |
|
|
62
|
+
| `recallProviderName` | `fork` | 召回查询的一次性子 agent provider |
|
|
63
|
+
| `recallAgentOptions` | 未设置 | 直接盖到召回 fork 上的原始 `agentOptions`;优先于 `recallUseSmallFast` 且**不做** alias 解析(传已解析路由,别传 `{ model: 'haiku' }`) |
|
|
64
|
+
| `recallUseSmallFast` | `false` | 让召回 fork 走低价车道:盖 `ccModelRoutes` 的 `resolve('haiku')` 路由(未配置则继承父路由)。默认关闭——为 typed agent 配置 `haiku` 不应悄悄把每次召回变成跨模型、继承前缀的 fork |
|
|
65
|
+
| `teamEnabled` | `false` | 启用 per-workspace 团队记忆目录与合并 section |
|
|
66
|
+
|
|
67
|
+
> **`teamEnabled` 默认关闭。** 开启会改变持久化记忆布局(创建并读取
|
|
68
|
+
> `<workspaceDir>/team/`)、改变模型写入内容(workspace 与 `team` 两种 scope),
|
|
69
|
+
> 并把团队记忆读取指向共享目录。适用于单租户、受信写者项目:逐次访问校验关闭了
|
|
70
|
+
> 穿越,但*中间组件* TOCTOU 窗口并未完全关闭(仅末段做 `lstat` 校验,且
|
|
71
|
+
> resolve/包含校验与读取并非原子)。不得在**多租户或不可信写者**场景启用
|
|
72
|
+
> `teamEnabled`。
|
|
73
|
+
|
|
74
|
+
> **布局变更。** 按工作区隔离之前,所有记忆平铺在 `memoryHome/`。这些顶层文件不做
|
|
75
|
+
> 迁移:它们现在充当全局层(对所有工作区可见)。隔离前的 `<memoryHome>/team/` 团队
|
|
76
|
+
> 目录已失效——团队记忆现在位于 `<workspaceDir>/team/`;若你开启过 `teamEnabled`,
|
|
77
|
+
> 请手动搬移其中的文件。折叠前按 worktree cwd 编码的 `projects/<slug>/` 同样不迁移:
|
|
78
|
+
> 留在磁盘上不再写入;新写入落在主 checkout 的桶里。
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import memory from '@dsh-cc/memory'
|
|
82
|
+
await ctx.plugin(memory, { memoryHome: '/tmp/mem' })
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Model Experience
|
|
86
|
+
|
|
87
|
+
基准开销:每步一次同步渲染缓存的 section 文本(无 I/O)。最便宜路径还会扫描
|
|
88
|
+
记忆目录——当存在主题时,召回每轮可能花费一次小型模型 subagent 调用,直到所有
|
|
89
|
+
主题均已展示为止。token 增长受入口截断上限与五文件召回上限约束。
|
|
90
|
+
|
|
91
|
+
## API
|
|
92
|
+
|
|
93
|
+
- `parseMemoryFile(raw)` —— 将主题文件拆分为 frontmatter 与正文。
|
|
94
|
+
- `scanMemoryDirectory(fs, dir, signal?)` —— 读取入口与主题索引。
|
|
95
|
+
- `renderMemorySection(globalDir, workspaceDir, ...)` /
|
|
96
|
+
`renderTeamMemorySection(...)` / `renderLayers(layers)` /
|
|
97
|
+
`saveGuidance(workspaceDir, globalDir)` —— section 文本构建器。
|
|
98
|
+
- `MemorySection` —— section 的后台刷新缓存持有者(一次注册,按 agent 呈现
|
|
99
|
+
工作区层)。
|
|
100
|
+
- `registerMemorySaveTool(ctx, home, section)` / `MEMORY_SAVE_TOOL` /
|
|
101
|
+
`MEMORY_SAVE_SCOPES` —— 面向模型的保存通道。
|
|
102
|
+
- `validateMemoryWrites(input)` / `writeMemoryFiles(fs, dir, writes)` /
|
|
103
|
+
`memoryWritePolicy(dir)` / `MEMORY_WRITES_SCHEMA` —— 与
|
|
104
|
+
`dsh-memory-consolidation` 共用的 host 侧写回。
|
|
105
|
+
- `MemoryRecall` —— pre-step 召回协调器。
|
|
106
|
+
- `truncateEntrypointContent(raw)` —— 施加行/字节上限。
|
|
107
|
+
- `resolveMemoryHome`、`resolveWorkspaceMemoryDir`、`canonicalMemoryRoot`、
|
|
108
|
+
`projectSlug`、`cwdOf`、`resolveProjectMemoryRoot` —— memdir 根与工作区解析辅助。
|
|
109
|
+
`canonicalMemoryRoot` 是 git 仓库折叠(worktree → 主 checkout);`cwdOf` 仍是
|
|
110
|
+
现场工作副本。
|
|
111
|
+
- `sanitizePathKey(key)`、`validateTeamMemKey(fs, teamDir, relativeKey)`、
|
|
112
|
+
`resolveTeamMemoryRoot(workspaceDir)` —— 团队记忆安全链与路径辅助。
|
|
113
|
+
|
|
114
|
+
## 已知限制与延期工作
|
|
115
|
+
|
|
116
|
+
- `ctx.fs` 缝不暴露 mtime,因此召回去重按会话记录已展示路径,而非 mtime+path;
|
|
117
|
+
每次注入都会重新读取内容,仍能反映磁盘变更。CC 的 `memoryAge` 新鲜度加权
|
|
118
|
+
因此推迟,直到 seam 携带 mtime(见 `docs/cc-parity-matrix.md`)。
|
|
119
|
+
- 召回 side-query 依赖已注册的一次性子 agent provider;本包不内置 provider
|
|
120
|
+
(请组合 `fork` 或 `spawn`)。
|
|
121
|
+
- `memory_save` 只写工作区层与全局层;团队 scope 的保存通道与删除通道已延期(CC 的
|
|
122
|
+
直接 Write 语义同样推迟——fs sandbox 使会话工具无法直接写记忆目录)。
|
|
123
|
+
- 团队记忆(`teamEnabled`)的可逆性与安全性:启用即改变持久化格式,且中间组件
|
|
124
|
+
TOCTOU 窗口(仅末段做 `lstat` 校验;resolve/包含校验与读取并非原子)意味着
|
|
125
|
+
不得在**多租户或不可信写者**场景启用。
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code-style file-based memory: the memdir format and parser, the
|
|
3
|
+
* `memory` system-prompt section, and dynamic recall by a forked side-query.
|
|
4
|
+
*
|
|
5
|
+
* All file access goes through the optional `ctx.fs` seam, so a remote or
|
|
6
|
+
* sandboxed backend works unchanged; a providerless host mounts memory as a
|
|
7
|
+
* no-op. Recall needs `ctx.subagents` and a registered one-shot provider;
|
|
8
|
+
* absence of either skips recall without error.
|
|
9
|
+
*
|
|
10
|
+
* @module @dsh-cc/memory
|
|
11
|
+
*/
|
|
12
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
13
|
+
import z from '@deepseek-ai/schemastery';
|
|
14
|
+
export { parseMemoryFile } from './parser.ts';
|
|
15
|
+
export type { ParsedMemoryFile } from './parser.ts';
|
|
16
|
+
export { truncateEntrypointContent, ENTRYPOINT_NAME, MAX_ENTRYPOINT_LINES, MAX_ENTRYPOINT_BYTES } from './truncate.ts';
|
|
17
|
+
export type { EntrypointTruncation } from './truncate.ts';
|
|
18
|
+
export { MEMORY_TYPES, parseMemoryType } from './types.ts';
|
|
19
|
+
export type { MemoryType, MemoryFrontmatter, MemoryIndexEntry } from './types.ts';
|
|
20
|
+
export { scanMemoryDirectory } from './scan.ts';
|
|
21
|
+
export type { MemoryDirectoryState } from './scan.ts';
|
|
22
|
+
export { resolveMemoryHome, resolveProjectMemoryRoot, resolveWorkspaceMemoryDir, canonicalMemoryRoot, projectSlug, cwdOf, gitExecSync, PROJECT_MEMORY_DIR, PROJECTS_DIR, GIT_PROBE_TIMEOUT_MS, } from './paths.ts';
|
|
23
|
+
export type { MemoryGitExec, MemoryGitExecResult } from './paths.ts';
|
|
24
|
+
export { MemorySection, renderMemorySection, renderTeamMemorySection, renderLayers, saveGuidance, MEMORY_SECTION_NAME, MEMORY_SECTION_ORDER } from './section.ts';
|
|
25
|
+
export type { MemoryLayer } from './section.ts';
|
|
26
|
+
export { MemoryRecall, SubagentMemorySelector, extractSelectedNames, MAX_RECALL_MEMORIES } from './recall.ts';
|
|
27
|
+
export type { MemorySelector, RecallCandidate } from './recall.ts';
|
|
28
|
+
export { TeamMemoryError, sanitizePathKey, resolveTeamMemoryRoot, validateTeamMemKey, readTeamMemFile, TEAM_MEMORY_DIR, TEAM_ENTRYPOINT_NAME } from './team.ts';
|
|
29
|
+
export { MEMORY_SAVE_TOOL, MEMORY_SAVE_SCOPES, MemorySaveError, pointerLine, registerMemorySaveTool, renderTopicFile, upsertPointer, } from './save.ts';
|
|
30
|
+
export type { MemorySaveArgs } from './save.ts';
|
|
31
|
+
export { MEMORY_WRITES_SCHEMA, WRITEBACK_MAX_FILE_BYTES, WRITEBACK_MAX_FILES, WRITEBACK_MAX_TOTAL_BYTES, memoryWritePolicy, validateMemoryWrites, writeMemoryFiles, } from './writeback.ts';
|
|
32
|
+
export type { MemoryWrite, MemoryWritePolicy } from './writeback.ts';
|
|
33
|
+
export declare const name = "memory";
|
|
34
|
+
/** Core services required for section registration and event listeners. */
|
|
35
|
+
export declare const inject: string[];
|
|
36
|
+
/** Memory plugin configuration. */
|
|
37
|
+
export interface Config {
|
|
38
|
+
/**
|
|
39
|
+
* Memory home root. Defaults to the harness home `memory/`. The home IS the
|
|
40
|
+
* global layer; each repository's private layer lives at
|
|
41
|
+
* `<home>/projects/<slug>` (slug encodes the canonical git root).
|
|
42
|
+
*/
|
|
43
|
+
memoryHome?: string;
|
|
44
|
+
/** Whether the `memory` system-prompt section is registered (default true). */
|
|
45
|
+
sectionEnabled?: boolean;
|
|
46
|
+
/** Whether dynamic recall runs on pre-step (default true). */
|
|
47
|
+
recallEnabled?: boolean;
|
|
48
|
+
/** One-shot subagent provider used by recall (default `fork`). */
|
|
49
|
+
recallProviderName?: string;
|
|
50
|
+
/** Optional small-model selection passed to the recall subagent. */
|
|
51
|
+
recallAgentOptions?: unknown;
|
|
52
|
+
/**
|
|
53
|
+
* Opt the recall selector into `resolve('haiku')`. Default false so
|
|
54
|
+
* configuring `haiku` for typed agents does not silently cross-model
|
|
55
|
+
* every recall fork. Ignored when `recallAgentOptions` is set.
|
|
56
|
+
*/
|
|
57
|
+
recallUseSmallFast?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Whether team memory is enabled (default false). Enables a shared
|
|
60
|
+
* per-workspace team directory (`<workspaceDir>/team`), renders the
|
|
61
|
+
* triple-layer section, and validates all team-memory access. Off by
|
|
62
|
+
* default: onboarding a team directory changes the persisted format and is
|
|
63
|
+
* not safe in multi-tenant or untrusted-writer deployments (see README
|
|
64
|
+
* residual).
|
|
65
|
+
*/
|
|
66
|
+
teamEnabled?: boolean;
|
|
67
|
+
}
|
|
68
|
+
export declare const Config: z<Config>;
|
|
69
|
+
/**
|
|
70
|
+
* Register the `memory` system-prompt section and recall listener.
|
|
71
|
+
* @param ctx - the host context carrying the system-prompt and agent seams.
|
|
72
|
+
* @param config - memory behavior knobs.
|
|
73
|
+
*/
|
|
74
|
+
export declare function apply(ctx: Context, config?: Config): void;
|
|
75
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAQxC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACtH,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC1D,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAC/C,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AACrD,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EACnB,WAAW,EACX,KAAK,EACL,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,GACrB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACjK,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAC7G,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAC/J,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,aAAa,GACd,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,yBAAyB,EACzB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAEpE,eAAO,MAAM,IAAI,WAAW,CAAA;AAC5B,2EAA2E;AAC3E,eAAO,MAAM,MAAM,UAAmB,CAAA;AAEtC,mCAAmC;AACnC,MAAM,WAAW,MAAM;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAQ3B,CAAA;AAkBF;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,MAAW,GAAG,IAAI,CAiC7D"}
|