@maci0/dsh-caveman 0.16.2
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 +22 -0
- package/README.md +192 -0
- package/cordis.patch.yml +13 -0
- package/icon.svg +6 -0
- package/lib/client.js +488 -0
- package/lib/compress-detect.js +98 -0
- package/lib/compress-files.js +155 -0
- package/lib/compress-pipeline.js +109 -0
- package/lib/compress-rules.js +308 -0
- package/lib/compress-validate.js +227 -0
- package/lib/frontmatter.js +347 -0
- package/lib/host.js +15 -0
- package/lib/index.js +616 -0
- package/lib/modes.js +126 -0
- package/lib/skills.js +177 -0
- package/lib/types/compress-detect.d.ts +18 -0
- package/lib/types/compress-files.d.ts +76 -0
- package/lib/types/compress-pipeline.d.ts +32 -0
- package/lib/types/compress-rules.d.ts +65 -0
- package/lib/types/compress-validate.d.ts +36 -0
- package/lib/types/frontmatter.d.ts +57 -0
- package/lib/types/host.d.ts +201 -0
- package/lib/types/index.d.ts +87 -0
- package/lib/types/modes.d.ts +102 -0
- package/lib/types/skills.d.ts +56 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +112 -0
- package/scripts/sync-upstream.mjs +158 -0
- package/skills/cavecrew/SKILL.md +91 -0
- package/skills/cavecrew/cavecrew-builder.md +46 -0
- package/skills/cavecrew/cavecrew-investigator.md +56 -0
- package/skills/cavecrew/cavecrew-reviewer.md +47 -0
- package/skills/caveman/SKILL.md +103 -0
- package/skills/caveman-commit/SKILL.md +63 -0
- package/skills/caveman-compress/SKILL.md +105 -0
- package/skills/caveman-explore/SKILL.md +42 -0
- package/skills/caveman-help/SKILL.md +68 -0
- package/skills/caveman-review/SKILL.md +53 -0
- package/skills/caveman-stats/SKILL.md +30 -0
- package/skills/investigate-first/SKILL.md +16 -0
- package/skills/lean-build/SKILL.md +18 -0
- package/skills/migration/SKILL.md +17 -0
- package/skills/safe-refactor/SKILL.md +16 -0
- package/skills/surgical-patch/SKILL.md +16 -0
- package/skills/verify-and-stop/SKILL.md +16 -0
- package/sync.manifest.json +25 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-caveman contributors
|
|
4
|
+
Copyright (c) 2026 Julius Brussee (https://github.com/JuliusBrussee/caveman)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# dsh-caveman
|
|
2
|
+
|
|
3
|
+
Your agent writes three paragraphs where one line would do. This plugin makes it
|
|
4
|
+
talk like a caveman: same meaning, fewer tokens. Code, commands, file paths, and
|
|
5
|
+
exact error strings are never compressed, only the prose around them. Adapted
|
|
6
|
+
from [JuliusBrussee/caveman](https://github.com/JuliusBrussee/caveman) (MIT):
|
|
7
|
+
"why use many token when few do trick".
|
|
8
|
+
|
|
9
|
+
## What you get
|
|
10
|
+
|
|
11
|
+
- **A talking style on every request.** While any level except `off` is active,
|
|
12
|
+
the mode-filtered ruleset joins the system prompt.
|
|
13
|
+
- **Fourteen skills** the `skill` tool can load, so they also appear as
|
|
14
|
+
`/caveman-review`, `/caveman-commit`, … in the composer: `caveman`, `cavecrew`,
|
|
15
|
+
`caveman-commit`, `caveman-review`, `caveman-compress`, `caveman-explore`,
|
|
16
|
+
`caveman-stats`, `caveman-help`, plus six work patterns (`investigate-first`,
|
|
17
|
+
`lean-build`, `surgical-patch`, `safe-refactor`, `migration`, `verify-and-stop`).
|
|
18
|
+
- **Two ways to switch level.** The model calls the `caveman` tool; you type
|
|
19
|
+
`/caveman <level>` or just say **stop caveman**.
|
|
20
|
+
- **A settings card and a composer chip**, so the active level is visible without
|
|
21
|
+
opening Settings.
|
|
22
|
+
- **`/caveman-compress <file>`** shrinks a memory file or todo list with local
|
|
23
|
+
rules. No model call, original backed up out of tree. A relative path resolves
|
|
24
|
+
against the session's working directory. The model-facing `caveman-compress`
|
|
25
|
+
tool only rewrites files inside that workspace (symlinks resolved); the
|
|
26
|
+
command you type is not confined.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
> **Install it as a bundle.** `dsh plugin add …` mounts the row from the
|
|
31
|
+
> package's own patch layer, which is what the settings editor can write to. A
|
|
32
|
+
> row added with `--patch` is an overlay: it disappears at the next start, and
|
|
33
|
+
> the Plugins card cannot save into it (the editor refuses a write an overlay
|
|
34
|
+
> would win).
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
dsh plugin --profile web add @maci0/dsh-caveman@0.16.2
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This installs the public npm package; no GitHub token or `~/.secrets` setup is needed.
|
|
41
|
+
The version is pinned. To upgrade, run the same command with a newer version,
|
|
42
|
+
then restart `dsh web` (bundle layers compose at boot).
|
|
43
|
+
|
|
44
|
+
## Use it
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
/caveman ultra -> Caveman level: ultra (was full).
|
|
48
|
+
/caveman wenyan -> Caveman level: wenyan-full (was ultra).
|
|
49
|
+
/caveman -> Caveman level: wenyan-full.
|
|
50
|
+
/caveman off -> Caveman off (was wenyan-full). Normal behavior.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Typing **stop caveman** or **normal mode** as an ordinary message has the same
|
|
54
|
+
effect as `/caveman off`, and it lands on the turn that carried it. Only the
|
|
55
|
+
human's own words count: injected context riding the same event stream cannot
|
|
56
|
+
toggle the level, and the message must *be* the command, so "add a normal mode
|
|
57
|
+
toggle" is left alone.
|
|
58
|
+
|
|
59
|
+
Model side, the tool takes `mode` (persist a level), `once` (this call only, not
|
|
60
|
+
persisted), and `usage` (session token totals). `{"usage": true}` appends input,
|
|
61
|
+
output, cache read, and cache write totals from the harness's `tokenUsage`
|
|
62
|
+
projection: counts only, never a saving.
|
|
63
|
+
|
|
64
|
+
### Levels
|
|
65
|
+
|
|
66
|
+
| Level | Behavior | Persisted |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `lite` | Drop filler. Keep sentence structure. | yes |
|
|
69
|
+
| `full` | Drop articles, filler, pleasantries, hedging. Fragments OK. Default. | yes |
|
|
70
|
+
| `ultra` | Extreme compression. Bare fragments. | yes |
|
|
71
|
+
| `wenyan-lite` | Classical Chinese style, light compression. | yes |
|
|
72
|
+
| `wenyan-full` | Full 文言文. Maximum classical terseness. (`/caveman wenyan` shorthand.) | yes |
|
|
73
|
+
| `wenyan-ultra` | Extreme. Ancient scholar on a budget. | yes |
|
|
74
|
+
| `off` | No injection. Normal behavior. | yes |
|
|
75
|
+
|
|
76
|
+
Every level persists, so the card, the chip, the tool, and `/caveman` agree and
|
|
77
|
+
the choice survives a restart. The card and the chip show the level the host is
|
|
78
|
+
using: one that came from `CAVEMAN_DEFAULT_MODE` or `~/.config/caveman/config.json`
|
|
79
|
+
is labelled as such (choosing a level on the card overrides it), and so is a level
|
|
80
|
+
held only for this session because the settings write failed. Security warnings, irreversible-action
|
|
81
|
+
confirmations, and anything where compression would change the meaning drop back
|
|
82
|
+
to full sentences.
|
|
83
|
+
|
|
84
|
+
## Configure
|
|
85
|
+
|
|
86
|
+
| Field | Default | Meaning |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `defaultMode` | unset | Startup level. Absent means "ask the chain below". One of the seven levels when set. |
|
|
89
|
+
| `maxFileSize` | `500000` | Size cap in bytes for `/caveman-compress`. Positive number, editable from the card, and read on every compress call. |
|
|
90
|
+
|
|
91
|
+
The row schema declares no default for `defaultMode` and the bundle's row sets
|
|
92
|
+
none, so an absent field stays absent and the level resolves in this order: the
|
|
93
|
+
row's `defaultMode`, then `CAVEMAN_DEFAULT_MODE`, then
|
|
94
|
+
`~/.config/caveman/config.json`'s `defaultMode`, then `full`. The env and the
|
|
95
|
+
file are read once at mount; the row is read at every use, so the card's Reset
|
|
96
|
+
falls back to them. An invalid value
|
|
97
|
+
fails while the plugin loads rather than silently doing the wrong thing.
|
|
98
|
+
|
|
99
|
+
Override the row from your profile's own `cordis.patch.yml` with a
|
|
100
|
+
`- id: caveman` row, which replaces the row's whole `config`. Do **not** paste
|
|
101
|
+
the bundle's `insert` of that row there: `insert` does not dedupe ids, and a
|
|
102
|
+
second row mounts the plugin twice.
|
|
103
|
+
|
|
104
|
+
## How it works
|
|
105
|
+
|
|
106
|
+
The package declares `dsh.bundle`, so `dsh plugin add` appends it to
|
|
107
|
+
`dsh.profile.bundles` and the row in its own `cordis.patch.yml` applies as a layer.
|
|
108
|
+
|
|
109
|
+
The host half mounts through public Cordis extension points: `systemPrompt.section`,
|
|
110
|
+
`skills.registerProvider`, `tools.register`, `commands.register`,
|
|
111
|
+
`loader/volatile-update` (the settings document writes the row's volatile
|
|
112
|
+
`defaultMode`), `session/event` for the message switch, and `webServer` for
|
|
113
|
+
`GET /caveman/level`, which answers `{ mode, source }` (`settings`, `env`,
|
|
114
|
+
`config-file`, `default`, or `session`) behind the `connection` trust fence. The
|
|
115
|
+
browser half reads that route on every settings change and every 5 seconds, draws
|
|
116
|
+
its card into the public `plugins.row.config` slot from `configForms`, registers its
|
|
117
|
+
copy through `locale.register`, and draws its chip into `conversation.input.left`, so
|
|
118
|
+
this plugin needs no client change of its own.
|
|
119
|
+
|
|
120
|
+
The entry point is the built `lib/index.js` (declarations in `lib/types/`); `bun run
|
|
121
|
+
build` regenerates it from `src/`. `lib/client.js` is hand-authored plain JavaScript:
|
|
122
|
+
the client module system serves it as a lazy-CJS factory on `window.__ModuleLoader__`
|
|
123
|
+
because the package exports `./client`, and it is not built. Skills come from
|
|
124
|
+
`skills/<name>/SKILL.md` with frontmatter parsed by `yaml`; the provider takes its rank
|
|
125
|
+
and name grammar from `@deepseek-ai/dsh-skill`, projects `disable-model-invocation`,
|
|
126
|
+
`user-invocable`, and `whenToUse`, and settles on the lookup's abort signal. Tools use
|
|
127
|
+
`defineTool` from `@deepseek-ai/dsh-tools` and forward `exec.signal`. Only
|
|
128
|
+
`skills/caveman/SKILL.md` is the source of truth for the ruleset; this README keeps no
|
|
129
|
+
second copy.
|
|
130
|
+
|
|
131
|
+
## Limits
|
|
132
|
+
|
|
133
|
+
- **No proxy, no CLI verbs, no Cloud engine.** Upstream's
|
|
134
|
+
`caveman-setup/-discover/-learn/-manage/-optimize/-evidence-review` need an
|
|
135
|
+
external runtime the harness has no extension point for, so they are not bundled.
|
|
136
|
+
- **Savings are not measured.** `/caveman-stats` reports what the provider reported this
|
|
137
|
+
session, never a percentage, and it says unavailable when the host mounts no token meter.
|
|
138
|
+
- **The level is process-wide.** One prompt section, one namespace value: every
|
|
139
|
+
agent in the process shares it.
|
|
140
|
+
- **External subagents ignore it.** In-process children inherit the ruleset, but
|
|
141
|
+
`subagent-claude-code`/`subagent-codex` spawn their own CLI with its own prompt.
|
|
142
|
+
- **Two locales.** The card and the chip ship `en` and `zh`; any other locale
|
|
143
|
+
falls back through the service's own chain.
|
|
144
|
+
- **Host source edits need `bun run build` and a restart**; browser-half edits need a page refresh.
|
|
145
|
+
|
|
146
|
+
## Development
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
bun install # the client packages are optional peers and stay uninstalled
|
|
150
|
+
bun run build # tsc -p tsconfig.build.json -> lib/index.js + lib/types/
|
|
151
|
+
bun test # every tests/*.test.ts, no build step
|
|
152
|
+
bun run typecheck # tsc -p tsconfig.json
|
|
153
|
+
bun run sync:check # diff bundled files against upstream main (needs network)
|
|
154
|
+
bun run sync # overwrite stale verbatim files (refuses dirty tree w/o --force)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
dsh loads plugins on Node ^22.19.0 || >=24.0.0; development and tests run on bun.
|
|
158
|
+
|
|
159
|
+
The harness packages this plugin imports at runtime (`@deepseek-ai/dsh-tools`,
|
|
160
|
+
`@deepseek-ai/dsh-skill`, `@deepseek-ai/schemastery`) are **dependencies
|
|
161
|
+
pinned to the harness's own versions**, so the profile resolves one physical
|
|
162
|
+
copy; `yaml` is the only non-harness dependency. The pin is deliberate.
|
|
163
|
+
`@deepseek-ai/dsh-tools` keys its runtime scheduler on a module-level `Symbol`,
|
|
164
|
+
so a second physical copy in the profile hands the tool layer a different
|
|
165
|
+
symbol than the host's and every tool call dies with
|
|
166
|
+
`Cannot read properties of undefined (reading 'prepare')`.
|
|
167
|
+
|
|
168
|
+
For local development, install the checkout into a profile with
|
|
169
|
+
`dsh plugin --profile <name> add <path-to-checkout>`.
|
|
170
|
+
|
|
171
|
+
The suite covers level normalization and filtering, the fake-host surface, the skills
|
|
172
|
+
provider, the compress pipeline, and a real Cordis composition mount next to the real
|
|
173
|
+
skill registry. `sync:check` exits 1 and lists stale files (2 on a usage or fetch error); `sync` rewrites verbatim
|
|
174
|
+
copies and leaves adapted ones for manual re-adaptation. Both accept `--ref <tag|sha>`
|
|
175
|
+
(default `main`). The network assertion runs only with `DSH_SYNC_CHECK=1`; plain
|
|
176
|
+
`bun test` stays offline. To uninstall, run `dsh plugin --profile web remove @maci0/dsh-caveman`
|
|
177
|
+
and drop any `id: caveman` override from `~/.dsh/profiles/<profile>/cordis.patch.yml`.
|
|
178
|
+
|
|
179
|
+
## Attribution and license
|
|
180
|
+
|
|
181
|
+
MIT. Skill content: © JuliusBrussee
|
|
182
|
+
([caveman](https://github.com/JuliusBrussee/caveman)). DSH port: see `LICENSE`.
|
|
183
|
+
|
|
184
|
+
The fourteen `skills/*/SKILL.md` files track upstream; nine are verbatim copies
|
|
185
|
+
and five carry small DSH adaptations (`caveman`, `caveman-compress`, `cavecrew`,
|
|
186
|
+
`caveman-stats`, `caveman-help`). The `cavecrew-*.md` prompts are verbatim too.
|
|
187
|
+
The compress pipeline (`src/compress-*.ts`) is a port, not a copy: same behavior,
|
|
188
|
+
local rules instead of a model call, no `python3` needed.
|
|
189
|
+
|
|
190
|
+
Upstream's numbers (JetBrains: 8.5% fewer output tokens, skill only; Adobe CAVEWOMAN:
|
|
191
|
+
1.4–2.4× output-side cost cut; proxy: −33.2% input tokens) are upstream's, not this
|
|
192
|
+
package's: this port ships the skill half only, so only the skill-side figures apply.
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# The dsh-caveman bundle patch: applied automatically when a profile lists
|
|
2
|
+
# this bundle (`dsh plugin add`/`update` appends the package to
|
|
3
|
+
# dsh.profile.bundles). Users override this row from their profile's own
|
|
4
|
+
# cordis.patch.yml (live-watched; dsh.profile.bundles is frozen at boot) with a
|
|
5
|
+
# `- id: caveman` row, which replaces the row's whole `config`.
|
|
6
|
+
# `name` stays a bare package specifier: the browser half is served by the
|
|
7
|
+
# client module system, which resolves the Loader entry's package, reads its
|
|
8
|
+
# `dsh.client` manifest, and serves `exports["./client"]`.
|
|
9
|
+
# Do not also insert this same row into the profile patch: insert does not
|
|
10
|
+
# dedupe ids, and a second row would register the plugin twice.
|
|
11
|
+
- insert:
|
|
12
|
+
- id: caveman
|
|
13
|
+
name: '@maci0/dsh-caveman'
|
package/icon.svg
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M8 22.5c1.2-6.2 5.4-10 10-10 3.2 0 5.6 1.6 7.2 4.2" stroke="#8C6239" stroke-width="2.2" stroke-linecap="round"/>
|
|
3
|
+
<circle cx="23.5" cy="13.2" r="5.4" fill="#C4A574"/>
|
|
4
|
+
<circle cx="23.5" cy="13.2" r="5.4" stroke="#8C6239" stroke-width="1.5"/>
|
|
5
|
+
<path d="M10 24.5h9.5" stroke="#8C6239" stroke-width="2.2" stroke-linecap="round"/>
|
|
6
|
+
</svg>
|