@p4r4d0xb0x/opencode-dcp 3.0.5 → 3.1.12

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 (217) hide show
  1. package/README.md +31 -26
  2. package/dist/index.d.ts +2 -2
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +7909 -76
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/commands/compression-targets.d.ts +14 -0
  7. package/dist/lib/commands/compression-targets.d.ts.map +1 -0
  8. package/dist/lib/commands/context.d.ts.map +1 -1
  9. package/dist/lib/commands/decompress.d.ts.map +1 -1
  10. package/dist/lib/commands/index.d.ts +8 -0
  11. package/dist/lib/commands/index.d.ts.map +1 -0
  12. package/dist/lib/commands/manual.d.ts +1 -0
  13. package/dist/lib/commands/manual.d.ts.map +1 -1
  14. package/dist/lib/commands/recompress.d.ts.map +1 -1
  15. package/dist/lib/commands/stats.d.ts.map +1 -1
  16. package/dist/lib/commands/sweep.d.ts.map +1 -1
  17. package/dist/lib/compress/index.d.ts +4 -0
  18. package/dist/lib/compress/index.d.ts.map +1 -0
  19. package/dist/lib/compress/message-utils.d.ts +8 -0
  20. package/dist/lib/compress/message-utils.d.ts.map +1 -0
  21. package/dist/lib/compress/message.d.ts +4 -0
  22. package/dist/lib/compress/message.d.ts.map +1 -0
  23. package/dist/lib/compress/pipeline.d.ts +29 -0
  24. package/dist/lib/compress/pipeline.d.ts.map +1 -0
  25. package/dist/lib/compress/protected-content.d.ts +7 -0
  26. package/dist/lib/compress/protected-content.d.ts.map +1 -0
  27. package/dist/lib/compress/range-utils.d.ts +10 -0
  28. package/dist/lib/compress/range-utils.d.ts.map +1 -0
  29. package/dist/lib/compress/range.d.ts +4 -0
  30. package/dist/lib/compress/range.d.ts.map +1 -0
  31. package/dist/lib/compress/search.d.ts +11 -0
  32. package/dist/lib/compress/search.d.ts.map +1 -0
  33. package/dist/lib/compress/state.d.ts +9 -0
  34. package/dist/lib/compress/state.d.ts.map +1 -0
  35. package/dist/lib/compress/timing.d.ts +18 -0
  36. package/dist/lib/compress/timing.d.ts.map +1 -0
  37. package/dist/lib/compress/types.d.ts +94 -0
  38. package/dist/lib/compress/types.d.ts.map +1 -0
  39. package/dist/lib/{shared-utils.d.ts → compress-permission.d.ts} +2 -4
  40. package/dist/lib/compress-permission.d.ts.map +1 -0
  41. package/dist/lib/config.d.ts +7 -7
  42. package/dist/lib/config.d.ts.map +1 -1
  43. package/dist/lib/hooks.d.ts +4 -1
  44. package/dist/lib/hooks.d.ts.map +1 -1
  45. package/dist/lib/message-ids.d.ts +1 -1
  46. package/dist/lib/message-ids.d.ts.map +1 -1
  47. package/dist/lib/messages/index.d.ts +2 -0
  48. package/dist/lib/messages/index.d.ts.map +1 -1
  49. package/dist/lib/messages/inject/inject.d.ts +3 -2
  50. package/dist/lib/messages/inject/inject.d.ts.map +1 -1
  51. package/dist/lib/messages/inject/utils.d.ts +2 -3
  52. package/dist/lib/messages/inject/utils.d.ts.map +1 -1
  53. package/dist/lib/messages/priority.d.ts +13 -0
  54. package/dist/lib/messages/priority.d.ts.map +1 -0
  55. package/dist/lib/messages/prune.d.ts.map +1 -1
  56. package/dist/lib/messages/query.d.ts +7 -0
  57. package/dist/lib/messages/query.d.ts.map +1 -0
  58. package/dist/lib/messages/shape.d.ts +5 -0
  59. package/dist/lib/messages/shape.d.ts.map +1 -0
  60. package/dist/lib/messages/utils.d.ts +10 -4
  61. package/dist/lib/messages/utils.d.ts.map +1 -1
  62. package/dist/lib/prompts/compress-message.d.ts +2 -0
  63. package/dist/lib/prompts/compress-message.d.ts.map +1 -0
  64. package/dist/lib/prompts/compress-range.d.ts +2 -0
  65. package/dist/lib/prompts/compress-range.d.ts.map +1 -0
  66. package/dist/lib/prompts/context-limit-nudge.d.ts +1 -1
  67. package/dist/lib/prompts/context-limit-nudge.d.ts.map +1 -1
  68. package/dist/lib/prompts/extensions/nudge.d.ts +5 -0
  69. package/dist/lib/prompts/extensions/nudge.d.ts.map +1 -0
  70. package/dist/lib/prompts/extensions/system.d.ts +4 -0
  71. package/dist/lib/prompts/extensions/system.d.ts.map +1 -0
  72. package/dist/lib/prompts/extensions/tool.d.ts +3 -0
  73. package/dist/lib/prompts/extensions/tool.d.ts.map +1 -0
  74. package/dist/lib/prompts/index.d.ts +2 -1
  75. package/dist/lib/prompts/index.d.ts.map +1 -1
  76. package/dist/lib/prompts/iteration-nudge.d.ts +1 -1
  77. package/dist/lib/prompts/iteration-nudge.d.ts.map +1 -1
  78. package/dist/lib/prompts/store.d.ts +5 -4
  79. package/dist/lib/prompts/store.d.ts.map +1 -1
  80. package/dist/lib/prompts/system.d.ts +1 -1
  81. package/dist/lib/prompts/system.d.ts.map +1 -1
  82. package/dist/lib/prompts/turn-nudge.d.ts +1 -1
  83. package/dist/lib/prompts/turn-nudge.d.ts.map +1 -1
  84. package/dist/lib/state/index.d.ts +1 -0
  85. package/dist/lib/state/index.d.ts.map +1 -1
  86. package/dist/lib/state/persistence.d.ts +1 -0
  87. package/dist/lib/state/persistence.d.ts.map +1 -1
  88. package/dist/lib/state/state.d.ts.map +1 -1
  89. package/dist/lib/state/types.d.ts +10 -1
  90. package/dist/lib/state/types.d.ts.map +1 -1
  91. package/dist/lib/state/utils.d.ts +9 -5
  92. package/dist/lib/state/utils.d.ts.map +1 -1
  93. package/dist/lib/strategies/index.d.ts +0 -1
  94. package/dist/lib/strategies/index.d.ts.map +1 -1
  95. package/dist/lib/{strategies/utils.d.ts → token-utils.d.ts} +6 -8
  96. package/dist/lib/token-utils.d.ts.map +1 -0
  97. package/dist/lib/ui/notification.d.ts +8 -1
  98. package/dist/lib/ui/notification.d.ts.map +1 -1
  99. package/dist/lib/ui/utils.d.ts +1 -1
  100. package/dist/lib/ui/utils.d.ts.map +1 -1
  101. package/dist/lib/update.d.ts +22 -0
  102. package/dist/lib/update.d.ts.map +1 -0
  103. package/package.json +26 -15
  104. package/dist/lib/auth.js +0 -32
  105. package/dist/lib/auth.js.map +0 -1
  106. package/dist/lib/commands/context.js +0 -241
  107. package/dist/lib/commands/context.js.map +0 -1
  108. package/dist/lib/commands/decompress.js +0 -159
  109. package/dist/lib/commands/decompress.js.map +0 -1
  110. package/dist/lib/commands/help.js +0 -52
  111. package/dist/lib/commands/help.js.map +0 -1
  112. package/dist/lib/commands/manual.js +0 -48
  113. package/dist/lib/commands/manual.js.map +0 -1
  114. package/dist/lib/commands/recompress.js +0 -137
  115. package/dist/lib/commands/recompress.js.map +0 -1
  116. package/dist/lib/commands/stats.js +0 -62
  117. package/dist/lib/commands/stats.js.map +0 -1
  118. package/dist/lib/commands/sweep.js +0 -194
  119. package/dist/lib/commands/sweep.js.map +0 -1
  120. package/dist/lib/config.js +0 -766
  121. package/dist/lib/config.js.map +0 -1
  122. package/dist/lib/hooks.js +0 -195
  123. package/dist/lib/hooks.js.map +0 -1
  124. package/dist/lib/host-permissions.js +0 -58
  125. package/dist/lib/host-permissions.js.map +0 -1
  126. package/dist/lib/logger.js +0 -204
  127. package/dist/lib/logger.js.map +0 -1
  128. package/dist/lib/message-ids.js +0 -112
  129. package/dist/lib/message-ids.js.map +0 -1
  130. package/dist/lib/messages/index.js +0 -7
  131. package/dist/lib/messages/index.js.map +0 -1
  132. package/dist/lib/messages/inject/inject.js +0 -131
  133. package/dist/lib/messages/inject/inject.js.map +0 -1
  134. package/dist/lib/messages/inject/subagent-results.js +0 -58
  135. package/dist/lib/messages/inject/subagent-results.js.map +0 -1
  136. package/dist/lib/messages/inject/utils.js +0 -198
  137. package/dist/lib/messages/inject/utils.js.map +0 -1
  138. package/dist/lib/messages/prune.js +0 -177
  139. package/dist/lib/messages/prune.js.map +0 -1
  140. package/dist/lib/messages/reasoning-strip.js +0 -33
  141. package/dist/lib/messages/reasoning-strip.js.map +0 -1
  142. package/dist/lib/messages/sync.js +0 -93
  143. package/dist/lib/messages/sync.js.map +0 -1
  144. package/dist/lib/messages/utils.js +0 -118
  145. package/dist/lib/messages/utils.js.map +0 -1
  146. package/dist/lib/prompts/compress.d.ts +0 -2
  147. package/dist/lib/prompts/compress.d.ts.map +0 -1
  148. package/dist/lib/prompts/compress.js +0 -85
  149. package/dist/lib/prompts/compress.js.map +0 -1
  150. package/dist/lib/prompts/context-limit-nudge.js +0 -25
  151. package/dist/lib/prompts/context-limit-nudge.js.map +0 -1
  152. package/dist/lib/prompts/index.js +0 -19
  153. package/dist/lib/prompts/index.js.map +0 -1
  154. package/dist/lib/prompts/internal-overlays.d.ts +0 -5
  155. package/dist/lib/prompts/internal-overlays.d.ts.map +0 -1
  156. package/dist/lib/prompts/internal-overlays.js +0 -43
  157. package/dist/lib/prompts/internal-overlays.js.map +0 -1
  158. package/dist/lib/prompts/iteration-nudge.js +0 -9
  159. package/dist/lib/prompts/iteration-nudge.js.map +0 -1
  160. package/dist/lib/prompts/store.js +0 -346
  161. package/dist/lib/prompts/store.js.map +0 -1
  162. package/dist/lib/prompts/system.js +0 -30
  163. package/dist/lib/prompts/system.js.map +0 -1
  164. package/dist/lib/prompts/turn-nudge.js +0 -12
  165. package/dist/lib/prompts/turn-nudge.js.map +0 -1
  166. package/dist/lib/protected-patterns.js +0 -107
  167. package/dist/lib/protected-patterns.js.map +0 -1
  168. package/dist/lib/shared-utils.d.ts.map +0 -1
  169. package/dist/lib/shared-utils.js +0 -30
  170. package/dist/lib/shared-utils.js.map +0 -1
  171. package/dist/lib/state/index.js +0 -4
  172. package/dist/lib/state/index.js.map +0 -1
  173. package/dist/lib/state/persistence.js +0 -174
  174. package/dist/lib/state/persistence.js.map +0 -1
  175. package/dist/lib/state/state.js +0 -134
  176. package/dist/lib/state/state.js.map +0 -1
  177. package/dist/lib/state/tool-cache.js +0 -69
  178. package/dist/lib/state/tool-cache.js.map +0 -1
  179. package/dist/lib/state/types.js +0 -2
  180. package/dist/lib/state/types.js.map +0 -1
  181. package/dist/lib/state/utils.js +0 -196
  182. package/dist/lib/state/utils.js.map +0 -1
  183. package/dist/lib/strategies/deduplication.js +0 -100
  184. package/dist/lib/strategies/deduplication.js.map +0 -1
  185. package/dist/lib/strategies/index.js +0 -4
  186. package/dist/lib/strategies/index.js.map +0 -1
  187. package/dist/lib/strategies/purge-errors.js +0 -62
  188. package/dist/lib/strategies/purge-errors.js.map +0 -1
  189. package/dist/lib/strategies/supersede-writes.d.ts +0 -13
  190. package/dist/lib/strategies/supersede-writes.d.ts.map +0 -1
  191. package/dist/lib/strategies/supersede-writes.js +0 -94
  192. package/dist/lib/strategies/supersede-writes.js.map +0 -1
  193. package/dist/lib/strategies/utils.d.ts.map +0 -1
  194. package/dist/lib/strategies/utils.js +0 -128
  195. package/dist/lib/strategies/utils.js.map +0 -1
  196. package/dist/lib/subagents/subagent-results.js +0 -52
  197. package/dist/lib/subagents/subagent-results.js.map +0 -1
  198. package/dist/lib/tools/compress.d.ts +0 -4
  199. package/dist/lib/tools/compress.d.ts.map +0 -1
  200. package/dist/lib/tools/compress.js +0 -110
  201. package/dist/lib/tools/compress.js.map +0 -1
  202. package/dist/lib/tools/index.d.ts +0 -3
  203. package/dist/lib/tools/index.d.ts.map +0 -1
  204. package/dist/lib/tools/index.js +0 -2
  205. package/dist/lib/tools/index.js.map +0 -1
  206. package/dist/lib/tools/types.d.ts +0 -13
  207. package/dist/lib/tools/types.d.ts.map +0 -1
  208. package/dist/lib/tools/types.js +0 -2
  209. package/dist/lib/tools/types.js.map +0 -1
  210. package/dist/lib/tools/utils.d.ts +0 -80
  211. package/dist/lib/tools/utils.d.ts.map +0 -1
  212. package/dist/lib/tools/utils.js +0 -675
  213. package/dist/lib/tools/utils.js.map +0 -1
  214. package/dist/lib/ui/notification.js +0 -182
  215. package/dist/lib/ui/notification.js.map +0 -1
  216. package/dist/lib/ui/utils.js +0 -255
  217. package/dist/lib/ui/utils.js.map +0 -1
package/README.md CHANGED
@@ -9,18 +9,13 @@ Automatically reduces token usage in OpenCode by managing conversation context.
9
9
 
10
10
  ## Installation
11
11
 
12
- Add to your OpenCode config:
12
+ Install from the CLI:
13
13
 
14
- ```jsonc
15
- // opencode.jsonc
16
- {
17
- "plugin": ["@tarquinen/opencode-dcp@latest"],
18
- }
14
+ ```bash
15
+ opencode plugin @tarquinen/opencode-dcp@latest --global
19
16
  ```
20
17
 
21
- Using `@latest` ensures you always get the newest version automatically when OpenCode starts.
22
-
23
- Restart OpenCode. The plugin will automatically start optimizing your sessions.
18
+ This installs the package and adds it to your global OpenCode config.
24
19
 
25
20
  ## How It Works
26
21
 
@@ -28,9 +23,14 @@ DCP reduces context size through a compress tool and automatic cleanup. Your ses
28
23
 
29
24
  ### Compress
30
25
 
31
- Compress is a tool exposed to your model that selects a conversation range and replaces it with a technical summary. You can think of this as a much smarter version of Opencode's compaction process. Instead of triggering statically when your session reaches its maximum context and on the entire coding session, Compress allows the model to pick when to activate based on task completion, and to only compress a subset of messages containing the completed task. This allows the summaries replacing the session content to be much more focused and precise than Opencode's native compaction.
26
+ Compress is a tool exposed to your model that replaces closed, stale conversation content with high-fidelity technical summaries. You can think of this as a much smarter version of Opencode's compaction process. Instead of triggering statically when your session reaches its maximum context and on the entire coding session, Compress allows the model to pick when to activate based on task completion, and to only compress the specific messages that are no longer needed verbatim.
27
+
28
+ DCP supports two compression modes:
29
+
30
+ - `range` mode compresses contiguous spans of conversation into one or more summaries.
31
+ - `message` mode (experimental) compresses individual raw messages independently, letting the model manage context much more surgically.
32
32
 
33
- When a new compression overlaps an earlier one, the earlier summary is nested inside the new one so information is preserved through layers of compression rather than diluted away. Additionally, protected tool outputs (such as subagents and skills) and protected file patterns are always kept in compression summaries, ensuring that the most important information is never lost. You can also enable `protectUserMessages` to preserve your messages verbatim during compression, though note that large prompts (e.g. copy-pasting log files in the prompt) will then never be compressed away.
33
+ In `range` mode, when a new compression overlaps an earlier one, the earlier summary is nested inside the new one so information is preserved through layers of compression rather than diluted away. In both modes, protected tool outputs (such as subagents and skills) and protected file patterns are kept in compression summaries, ensuring that the most important information is never lost. You can also enable `protectUserMessages` to preserve your messages verbatim during compression, though note that large prompts (e.g. copy-pasting log files in the prompt) will then never be compressed away.
34
34
 
35
35
  ### Deduplication
36
36
 
@@ -50,6 +50,9 @@ DCP uses its own config file, searched in order:
50
50
 
51
51
  Each level overrides the previous, so project settings take priority over global. Restart OpenCode after making config changes.
52
52
 
53
+ > [!NOTE]
54
+ > If you use models with smaller context windows, such as GitHub Copilot models or local models, lower `compress.minContextLimit` and `compress.maxContextLimit` in your configuration to match the available context.
55
+
53
56
  > [!IMPORTANT]
54
57
  > Defaults are applied automatically. Expand this if you want to review or override settings.
55
58
 
@@ -61,6 +64,9 @@ Each level overrides the previous, so project settings take priority over global
61
64
  "$schema": "https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json",
62
65
  // Enable or disable the plugin
63
66
  "enabled": true,
67
+ // Automatically update npm-installed DCP when a newer npm latest is available.
68
+ // Version-locked plugin specs are not updated.
69
+ "autoUpdate": true,
64
70
  // Enable debug logging to ~/.config/opencode/logs/dcp/
65
71
  "debug": false,
66
72
  // Notification display: "off", "minimal", or "detailed"
@@ -99,14 +105,19 @@ Each level overrides the previous, so project settings take priority over global
99
105
  "protectedFilePatterns": [],
100
106
  // Unified context compression tool and behavior settings
101
107
  "compress": {
108
+ // Compression mode: "range" (compress spans into block summaries)
109
+ // or experimental "message" (compress individual raw messages)
110
+ "mode": "range",
102
111
  // Permission mode: "allow" (no prompt), "ask" (prompt), "deny" (tool not registered)
103
112
  "permission": "allow",
104
113
  // Show compression content in a chat notification
105
114
  "showCompression": false,
115
+ // Let active summary tokens extend the effective maxContextLimit
116
+ "summaryBuffer": true,
106
117
  // Soft upper threshold: above this, DCP keeps injecting strong
107
118
  // compression nudges (based on nudgeFrequency), so compression is
108
119
  // much more likely. Accepts: number or "X%" of model context window.
109
- "maxContextLimit": 150000,
120
+ "maxContextLimit": 100000,
110
121
  // Soft lower threshold for reminder nudges: below this, turn/iteration
111
122
  // reminders are off (compression less likely). At/above this, reminders
112
123
  // are on. Accepts: number or "X%" of model context window.
@@ -133,10 +144,10 @@ Each level overrides the previous, so project settings take priority over global
133
144
  // Controls how likely compression is after user messages
134
145
  // ("strong" = more likely, "soft" = less likely)
135
146
  "nudgeForce": "soft",
136
- // Flat tool schema: improves tool call reliability but uglier in the TUI
137
- "flatSchema": false,
138
147
  // Tool names whose completed outputs are appended to the compression
139
148
  "protectedTools": [],
149
+ // Preserve text wrapped in <protect>...</protect> when compressed
150
+ "protectTags": false,
140
151
  // Preserve your messages during compression.
141
152
  // Warning: large copy-pasted prompts will never be compressed away
142
153
  "protectUserMessages": false,
@@ -149,10 +160,6 @@ Each level overrides the previous, so project settings take priority over global
149
160
  // Additional tools to protect from pruning
150
161
  "protectedTools": [],
151
162
  },
152
- // Prune write tool inputs when the file has been subsequently read
153
- "supersedeWrites": {
154
- "enabled": true,
155
- },
156
163
  // Prune tool inputs for errored tools after X turns
157
164
  "purgeErrors": {
158
165
  "enabled": true,
@@ -176,16 +183,17 @@ DCP provides a `/dcp` slash command:
176
183
  - `/dcp stats` — Shows cumulative pruning statistics across all sessions.
177
184
  - `/dcp sweep` — Prunes all tools since the last user message. Accepts an optional count: `/dcp sweep 10` prunes the last 10 tools. Respects `commands.protectedTools`.
178
185
  - `/dcp manual [on|off]` — Toggle manual mode or set explicit state. When on, the AI will not autonomously use context management tools.
179
- - `/dcp compress [focus]` — Trigger a single compress tool execution. Optional focus text directs what range to compress.
186
+ - `/dcp compress [focus]` — Trigger a single compress tool execution. Optional focus text directs what content to compress, following the active `compress.mode`.
180
187
  - `/dcp decompress <n>` — Restore a specific active compression by ID (for example `/dcp decompress 2`). Running without an argument shows available compression IDs, token sizes, and topics.
181
188
  - `/dcp recompress <n>` — Re-apply a user-decompressed compression by ID (for example `/dcp recompress 2`). Running without an argument shows recompressible IDs, token sizes, and topics.
182
189
 
183
190
  ### Prompt Overrides
184
191
 
185
- DCP exposes five editable prompts:
192
+ DCP exposes six editable prompts:
186
193
 
187
194
  - `system`
188
- - `compress`
195
+ - `compress-range`
196
+ - `compress-message`
189
197
  - `context-limit-nudge`
190
198
  - `turn-nudge`
191
199
  - `iteration-nudge`
@@ -198,17 +206,14 @@ To customize behavior, add a file with the same name under an overrides director
198
206
 
199
207
  To reset an override, delete the matching file from your overrides directory.
200
208
 
201
- > [!NOTE]
202
- > `compress` prompt changes apply after plugin restart because tool descriptions are registered at startup.
203
-
204
209
  ### Protected Tools
205
210
 
206
211
  By default, these tools are always protected from pruning:
207
- `task`, `skill`, `todowrite`, `todoread`, `compress`, `batch`, `plan_enter`, `plan_exit`
212
+ `task`, `skill`, `todowrite`, `todoread`, `compress`, `batch`, `plan_enter`, `plan_exit`, `write`, `edit`
208
213
 
209
214
  The `protectedTools` arrays in `commands` and `strategies` add to this default list.
210
215
 
211
- For the `compress` tool, `compress.protectedTools` ensures specific tool outputs are appended to the compressed summary. It defaults to an empty array `[]` but always inherently protects `task`, `skill`, `todowrite`, and `todoread`.
216
+ For the `compress` tool, `compress.protectedTools` ensures specific tool outputs are appended to the compressed summary. By default it includes `task`, `skill`, `todowrite`, and `todoread`.
212
217
 
213
218
  ## Impact on Prompt Caching
214
219
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import type { Plugin } from "@opencode-ai/plugin";
2
- declare const plugin: Plugin;
3
- export default plugin;
2
+ declare const server: Plugin;
3
+ export default server;
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAmBjD,QAAA,MAAM,MAAM,EAAE,MAwHK,CAAA;AAEnB,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAqBjD,QAAA,MAAM,MAAM,EAAE,MAiHK,CAAA;AAEnB,eAAe,MAAM,CAAA"}