@duckmind/dm-windows-x64 0.62.3 → 0.62.9
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/dm.exe +0 -0
- package/extensions/.dm-extensions.json +43 -183
- package/extensions/dm-context/src/context.js +1 -2
- package/extensions/dm-context/src/index.js +1 -2
- package/extensions/{greedysearch-dm/bin/cdp.mjs → dm-cua/bin/browser-cdp.mjs} +3 -3
- package/extensions/dm-cua/bin/browser-cua.mjs +1 -1
- package/extensions/{greedysearch-dm/bin/launch.mjs → dm-cua/bin/browser-launch.mjs} +12 -11
- package/extensions/dm-cua/index.js +1 -1
- package/extensions/dm-cua/src/browser-cua-lib.mjs +17 -12
- package/extensions/{greedysearch-dm/src/search → dm-cua/src/browser-helpers}/constants.mjs +11 -11
- package/extensions/{greedysearch-dm/src/utils → dm-cua/src/browser-helpers}/node-runtime.mjs +1 -1
- package/extensions/{greedysearch-dm/src/search → dm-cua/src/browser-helpers}/port-pid.mjs +1 -1
- package/extensions/dm-ponytail/extensions/ponytail.mjs +186 -0
- package/extensions/dm-ponytail/hooks/claude-codex-hooks.json +41 -0
- package/extensions/dm-ponytail/hooks/copilot-hooks.json +21 -0
- package/extensions/dm-ponytail/hooks/ponytail-activate.js +59 -0
- package/extensions/dm-ponytail/hooks/ponytail-config.js +116 -0
- package/extensions/dm-ponytail/hooks/ponytail-instructions.js +81 -0
- package/extensions/dm-ponytail/hooks/ponytail-mode-tracker.js +96 -0
- package/extensions/dm-ponytail/hooks/ponytail-runtime.js +79 -0
- package/extensions/dm-ponytail/hooks/ponytail-statusline.ps1 +24 -0
- package/extensions/dm-ponytail/hooks/ponytail-statusline.sh +18 -0
- package/extensions/dm-ponytail/hooks/ponytail-subagent.js +50 -0
- package/extensions/dm-ponytail/hooks/qoder-hooks.json +26 -0
- package/extensions/dm-ponytail/package.json +19 -0
- package/extensions/dm-ponytail/pi-extension/index.js +186 -0
- package/extensions/dm-ponytail/pi-extension/package.json +8 -0
- package/extensions/dm-ponytail/skills/ponytail/SKILL.md +120 -0
- package/extensions/dm-ponytail/skills/ponytail-audit/SKILL.md +41 -0
- package/extensions/dm-ponytail/skills/ponytail-debt/SKILL.md +44 -0
- package/extensions/dm-ponytail/skills/ponytail-gain/SKILL.md +50 -0
- package/extensions/dm-ponytail/skills/ponytail-help/SKILL.md +71 -0
- package/extensions/dm-ponytail/skills/ponytail-review/SKILL.md +57 -0
- package/package.json +2 -6
- package/extensions/dm-caveman/extensions/caveman.js +0 -300
- package/extensions/dm-caveman/package.json +0 -20
- package/extensions/dm-goal/package.json +0 -23
- package/extensions/dm-goal/src/goal.js +0 -914
- package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +0 -40
- package/extensions/greedysearch-dm/bin/cdp-headless.mjs +0 -5
- package/extensions/greedysearch-dm/bin/cdp-visible.mjs +0 -5
- package/extensions/greedysearch-dm/bin/gschrome.mjs +0 -30
- package/extensions/greedysearch-dm/bin/kill-visible.mjs +0 -7
- package/extensions/greedysearch-dm/bin/launch-visible.mjs +0 -13
- package/extensions/greedysearch-dm/bin/mcp.mjs +0 -400
- package/extensions/greedysearch-dm/bin/search.mjs +0 -635
- package/extensions/greedysearch-dm/bin/visible.mjs +0 -22
- package/extensions/greedysearch-dm/extractors/bing-copilot.mjs +0 -344
- package/extensions/greedysearch-dm/extractors/chatgpt.mjs +0 -354
- package/extensions/greedysearch-dm/extractors/common.mjs +0 -794
- package/extensions/greedysearch-dm/extractors/consensus.mjs +0 -527
- package/extensions/greedysearch-dm/extractors/consent.mjs +0 -449
- package/extensions/greedysearch-dm/extractors/gemini.mjs +0 -291
- package/extensions/greedysearch-dm/extractors/google-ai.mjs +0 -86
- package/extensions/greedysearch-dm/extractors/logically.mjs +0 -589
- package/extensions/greedysearch-dm/extractors/perplexity.mjs +0 -370
- package/extensions/greedysearch-dm/extractors/selectors.mjs +0 -32
- package/extensions/greedysearch-dm/extractors/semantic-scholar.mjs +0 -199
- package/extensions/greedysearch-dm/index.js +0 -123
- package/extensions/greedysearch-dm/package.json +0 -27
- package/extensions/greedysearch-dm/skills/greedy-search/skill.md +0 -18
- package/extensions/greedysearch-dm/src/fetcher.mjs +0 -577
- package/extensions/greedysearch-dm/src/formatters/results.js +0 -95
- package/extensions/greedysearch-dm/src/formatters/sources.js +0 -57
- package/extensions/greedysearch-dm/src/formatters/synthesis.js +0 -49
- package/extensions/greedysearch-dm/src/github.mjs +0 -228
- package/extensions/greedysearch-dm/src/reddit.mjs +0 -154
- package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +0 -340
- package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +0 -156
- package/extensions/greedysearch-dm/src/search/chrome.mjs +0 -510
- package/extensions/greedysearch-dm/src/search/defaults.mjs +0 -10
- package/extensions/greedysearch-dm/src/search/engines.mjs +0 -79
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +0 -470
- package/extensions/greedysearch-dm/src/search/file-sources.mjs +0 -31
- package/extensions/greedysearch-dm/src/search/output.mjs +0 -51
- package/extensions/greedysearch-dm/src/search/paths.mjs +0 -48
- package/extensions/greedysearch-dm/src/search/pdf.mjs +0 -64
- package/extensions/greedysearch-dm/src/search/progress.mjs +0 -109
- package/extensions/greedysearch-dm/src/search/query.mjs +0 -21
- package/extensions/greedysearch-dm/src/search/recovery.mjs +0 -49
- package/extensions/greedysearch-dm/src/search/research.mjs +0 -2255
- package/extensions/greedysearch-dm/src/search/scale-aware.mjs +0 -61
- package/extensions/greedysearch-dm/src/search/simple-research.mjs +0 -418
- package/extensions/greedysearch-dm/src/search/sources.mjs +0 -412
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +0 -127
- package/extensions/greedysearch-dm/src/search/synthesis.mjs +0 -202
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +0 -209
- package/extensions/greedysearch-dm/src/tools/shared.js +0 -226
- package/extensions/greedysearch-dm/src/types.js +0 -0
- package/extensions/greedysearch-dm/src/utils/content.mjs +0 -38
- package/extensions/greedysearch-dm/src/utils/helpers.js +0 -22
- /package/extensions/{greedysearch-dm/src/search → dm-cua/src/browser-helpers}/minimize.mjs +0 -0
- /package/extensions/{greedysearch-dm/src/utils → dm-cua/src/browser-helpers}/system-cmds.mjs +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ponytail-review
|
|
3
|
+
description: >
|
|
4
|
+
Code review focused exclusively on over-engineering. Finds what to delete:
|
|
5
|
+
reinvented standard library, unneeded dependencies, speculative abstractions,
|
|
6
|
+
dead flexibility. One line per finding: location, what to cut, what replaces
|
|
7
|
+
it. Use when the user says "review for over-engineering", "what can we
|
|
8
|
+
delete", "is this over-engineered", "simplify review", or invokes
|
|
9
|
+
/ponytail-review. Complements correctness-focused review, this one only
|
|
10
|
+
hunts complexity.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
Review diffs for unnecessary complexity. One line per finding: location, what
|
|
14
|
+
to cut, what replaces it. The diff's best outcome is getting shorter.
|
|
15
|
+
|
|
16
|
+
## Format
|
|
17
|
+
|
|
18
|
+
`L<line>: <tag> <what>. <replacement>.`, or `<file>:L<line>: ...` for
|
|
19
|
+
multi-file diffs.
|
|
20
|
+
|
|
21
|
+
Tags:
|
|
22
|
+
|
|
23
|
+
- `delete:` dead code, unused flexibility, speculative feature. Replacement: nothing.
|
|
24
|
+
- `stdlib:` hand-rolled thing the standard library ships. Name the function.
|
|
25
|
+
- `native:` dependency or code doing what the platform already does. Name the feature.
|
|
26
|
+
- `yagni:` abstraction with one implementation, config nobody sets, layer with one caller.
|
|
27
|
+
- `shrink:` same logic, fewer lines. Show the shorter form.
|
|
28
|
+
|
|
29
|
+
## Examples
|
|
30
|
+
|
|
31
|
+
❌ "This EmailValidator class might be more complex than necessary, have you
|
|
32
|
+
considered whether all these validation rules are needed at this stage?"
|
|
33
|
+
|
|
34
|
+
✅ `L12-38: stdlib: 27-line validator class. "@" in email, 1 line, real validation is the confirmation mail.`
|
|
35
|
+
|
|
36
|
+
✅ `L4: native: moment.js imported for one format call. Intl.DateTimeFormat, 0 deps.`
|
|
37
|
+
|
|
38
|
+
✅ `repo.py:L88: yagni: AbstractRepository with one implementation. Inline it until a second one exists.`
|
|
39
|
+
|
|
40
|
+
✅ `L52-71: delete: retry wrapper around an idempotent local call. Nothing replaces it.`
|
|
41
|
+
|
|
42
|
+
✅ `L30-44: shrink: manual loop builds dict. dict(zip(keys, values)), 1 line.`
|
|
43
|
+
|
|
44
|
+
## Scoring
|
|
45
|
+
|
|
46
|
+
End with the only metric that matters: `net: -<N> lines possible.`
|
|
47
|
+
|
|
48
|
+
If there is nothing to cut, say `Lean already. Ship.` and stop.
|
|
49
|
+
|
|
50
|
+
## Boundaries
|
|
51
|
+
|
|
52
|
+
Scope: over-engineering and complexity only. Correctness bugs, security holes,
|
|
53
|
+
and performance are explicitly out of scope. Route them to a normal review
|
|
54
|
+
pass, not this one. A single smoke test or `assert`-based
|
|
55
|
+
self-check is the ponytail minimum, not bloat, never flag it for deletion.
|
|
56
|
+
Does not apply the fixes, only lists them.
|
|
57
|
+
"stop ponytail-review" or "normal mode": revert to verbose review style.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@duckmind/dm-windows-x64",
|
|
3
|
-
"version": "0.62.
|
|
3
|
+
"version": "0.62.9",
|
|
4
4
|
"description": "DuckMind (dm) binary payload for windows x64",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"os": [
|
|
@@ -31,10 +31,6 @@
|
|
|
31
31
|
"jiti": "2.7.0",
|
|
32
32
|
"typebox": "^1.1.34",
|
|
33
33
|
"yaml": "2.8.3",
|
|
34
|
-
"@
|
|
35
|
-
"@sinclair/typebox": "^0.34.48",
|
|
36
|
-
"jsdom": "^29.1.1",
|
|
37
|
-
"pdf-parse": "^2.4.5",
|
|
38
|
-
"turndown": "^7.1.2"
|
|
34
|
+
"@sinclair/typebox": "^0.34.48"
|
|
39
35
|
}
|
|
40
36
|
}
|
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { getSettingsListTheme } from "@duckmind/dm-coding-agent";
|
|
5
|
-
import { Container, SettingsList, Text } from "@duckmind/dm-tui";
|
|
6
|
-
const LEVELS = ["off", "lite", "full", "ultra", "wenyan-lite", "wenyan", "wenyan-ultra", "micro"];
|
|
7
|
-
const STOP_ALIASES = new Set(["off", "stop", "quit"]);
|
|
8
|
-
const CAVEMAN_COMMAND_OPTIONS = [
|
|
9
|
-
{ value: "lite", label: "lite", description: "Professional, no fluff" },
|
|
10
|
-
{ value: "full", label: "full", description: "Classic caveman" },
|
|
11
|
-
{ value: "ultra", label: "ultra", description: "Maximum compression" },
|
|
12
|
-
{ value: "wenyan-lite", label: "wenyan-lite", description: "Semi-classical Chinese" },
|
|
13
|
-
{ value: "wenyan", label: "wenyan", description: "Full 文言文" },
|
|
14
|
-
{ value: "wenyan-ultra", label: "wenyan-ultra", description: "Extreme 文言文" },
|
|
15
|
-
{ value: "micro", label: "micro", description: "Experimental prompt-minimized mode" },
|
|
16
|
-
{ value: "off", label: "off", description: "Disable caveman mode" },
|
|
17
|
-
{ value: "stop", label: "stop", description: "Disable caveman mode" },
|
|
18
|
-
{ value: "quit", label: "quit", description: "Disable caveman mode" },
|
|
19
|
-
{ value: "config", label: "config", description: "Open settings dialog" }
|
|
20
|
-
];
|
|
21
|
-
const CONFIG_PATH = join(homedir(), ".dm", "agent", "caveman.json");
|
|
22
|
-
const DEFAULT_CONFIG = { defaultLevel: "full", showStatus: true };
|
|
23
|
-
let saveConfigQueue = Promise.resolve();
|
|
24
|
-
async function loadConfig() {
|
|
25
|
-
try {
|
|
26
|
-
const raw = await readFile(CONFIG_PATH, "utf8");
|
|
27
|
-
const parsed = JSON.parse(raw);
|
|
28
|
-
return {
|
|
29
|
-
defaultLevel: LEVELS.includes(parsed.defaultLevel) ? parsed.defaultLevel : DEFAULT_CONFIG.defaultLevel,
|
|
30
|
-
showStatus: typeof parsed.showStatus === "boolean" ? parsed.showStatus : DEFAULT_CONFIG.showStatus
|
|
31
|
-
};
|
|
32
|
-
} catch {
|
|
33
|
-
return { ...DEFAULT_CONFIG };
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
async function saveConfig(config) {
|
|
37
|
-
const snapshot = JSON.stringify(config, null, 2) + `
|
|
38
|
-
`;
|
|
39
|
-
saveConfigQueue = saveConfigQueue.then(async () => {
|
|
40
|
-
await mkdir(join(homedir(), ".dm", "agent"), { recursive: true });
|
|
41
|
-
await writeFile(CONFIG_PATH, snapshot, "utf8");
|
|
42
|
-
});
|
|
43
|
-
return saveConfigQueue;
|
|
44
|
-
}
|
|
45
|
-
const R = "\x1B[38;5;196m";
|
|
46
|
-
const O = "\x1B[38;5;208m";
|
|
47
|
-
const Y = "\x1B[38;5;220m";
|
|
48
|
-
const W = "\x1B[38;5;230m";
|
|
49
|
-
const E = "\x1B[38;5;52m";
|
|
50
|
-
const X = "\x1B[0m";
|
|
51
|
-
const FIRE_FRAMES = [
|
|
52
|
-
`${R}⠠${O}⠄${X}`,
|
|
53
|
-
`${O}⠔${Y}⠂${X}`,
|
|
54
|
-
`${Y}⠊${W}⠑${X}`,
|
|
55
|
-
`${W}⠑${Y}⠊${X}`,
|
|
56
|
-
`${Y}⠂${O}⠔${X}`,
|
|
57
|
-
`${O}⠄${R}⠠${X}`,
|
|
58
|
-
`${R}⠠${E}⠄${X}`,
|
|
59
|
-
`${E}⠔${R}⠂${X}`
|
|
60
|
-
];
|
|
61
|
-
const ANIMATIONS = {
|
|
62
|
-
lite: { frames: FIRE_FRAMES, label: "LITE", interval: 300 },
|
|
63
|
-
full: { frames: FIRE_FRAMES, label: "FULL", interval: 200 },
|
|
64
|
-
ultra: { frames: FIRE_FRAMES, label: "ULTRA", interval: 100 },
|
|
65
|
-
"wenyan-lite": { frames: FIRE_FRAMES, label: "文言", interval: 300 },
|
|
66
|
-
wenyan: { frames: FIRE_FRAMES, label: "文言文", interval: 200 },
|
|
67
|
-
"wenyan-ultra": { frames: FIRE_FRAMES, label: "文言文極", interval: 100 },
|
|
68
|
-
micro: { frames: FIRE_FRAMES, label: "MICRO", interval: 120 }
|
|
69
|
-
};
|
|
70
|
-
const BASE = `IMPORTANT: You are in CAVEMAN MODE. Respond terse like smart caveman. All technical substance stay. Only fluff die.
|
|
71
|
-
|
|
72
|
-
Rules:
|
|
73
|
-
- Drop articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries, hedging
|
|
74
|
-
- Fragments OK. Short synonyms preferred. Technical terms exact
|
|
75
|
-
- Code blocks unchanged. Errors quoted exact
|
|
76
|
-
- Pattern: [thing] [action] [reason]. [next step].
|
|
77
|
-
|
|
78
|
-
Bad: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..."
|
|
79
|
-
Good: "Bug in auth middleware. Token expiry check use \`<\` not \`<=\`. Fix:"`;
|
|
80
|
-
const MICRO_PROMPT = `# Token efficiency
|
|
81
|
-
Respond like smart caveman. Cut all filler, keep technical substance.
|
|
82
|
-
- Drop articles (a, an, the), filler (just, really, basically, actually).
|
|
83
|
-
- Drop pleasantries (sure, certainly, happy to).
|
|
84
|
-
- No hedging. Fragments fine. Short synonyms.
|
|
85
|
-
- Technical terms stay exact. Code blocks unchanged.
|
|
86
|
-
- Pattern: [thing] [action] [reason]. [next step].`;
|
|
87
|
-
const INTENSITY = {
|
|
88
|
-
lite: `No filler/hedging. Keep articles + full sentences. Professional but tight.
|
|
89
|
-
Example: "Your component re-renders because you create a new object reference each render. Wrap it in \`useMemo\`."`,
|
|
90
|
-
full: `Drop articles, fragments OK, short synonyms.
|
|
91
|
-
Example: "New object ref each render. Inline object prop = new ref = re-render. Wrap in \`useMemo\`."`,
|
|
92
|
-
ultra: `Abbreviate (DB/auth/config/req/res/fn/impl), strip conjunctions, arrows for causality (X → Y).
|
|
93
|
-
Example: "Inline obj prop → new ref → re-render. \`useMemo\`."`,
|
|
94
|
-
"wenyan-lite": `Semi-classical Chinese. Grammar intact, filler gone. Technical terms in English.
|
|
95
|
-
Example: "組件頻重繪,以每繪新生對象參照故。以 useMemo 包之。"`,
|
|
96
|
-
wenyan: `Maximum classical terseness. 80-90% character reduction. Technical terms in English.
|
|
97
|
-
Example: "物出新參照,致重繪。useMemo Wrap之。"`,
|
|
98
|
-
"wenyan-ultra": `Extreme classical compression. Technical terms in English.
|
|
99
|
-
Example: "新參照→重繪。useMemo Wrap。"`
|
|
100
|
-
};
|
|
101
|
-
const SAFETY = `Auto-clarity: drop caveman for security warnings, irreversible action confirmations, or when user is confused. Resume after.
|
|
102
|
-
Boundaries: write normal code. Only compress explanations. "stop caveman" or "normal mode" reverts.`;
|
|
103
|
-
export default function caveman(dm) {
|
|
104
|
-
let level = "off";
|
|
105
|
-
let config = { ...DEFAULT_CONFIG };
|
|
106
|
-
let timer = null;
|
|
107
|
-
let frameIndex = 0;
|
|
108
|
-
let isActive = false;
|
|
109
|
-
let configLoadPromise = null;
|
|
110
|
-
const ensureConfigLoaded = async () => {
|
|
111
|
-
if (!configLoadPromise) {
|
|
112
|
-
configLoadPromise = (async () => {
|
|
113
|
-
config = await loadConfig();
|
|
114
|
-
if (level === "off" && config.defaultLevel !== "off") {
|
|
115
|
-
level = config.defaultLevel;
|
|
116
|
-
}
|
|
117
|
-
})();
|
|
118
|
-
}
|
|
119
|
-
await configLoadPromise;
|
|
120
|
-
};
|
|
121
|
-
function stopAnimation() {
|
|
122
|
-
if (timer) {
|
|
123
|
-
clearInterval(timer);
|
|
124
|
-
timer = null;
|
|
125
|
-
}
|
|
126
|
-
frameIndex = 0;
|
|
127
|
-
}
|
|
128
|
-
function syncStatus(ctx) {
|
|
129
|
-
stopAnimation();
|
|
130
|
-
const theme = ctx.ui.theme;
|
|
131
|
-
if (level === "off" || !config.showStatus) {
|
|
132
|
-
ctx.ui.setStatus("caveman", "");
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
const anim = ANIMATIONS[level];
|
|
136
|
-
const setFrame = (frame) => {
|
|
137
|
-
ctx.ui.setStatus("caveman", frame + " " + theme.fg("muted", "caveman level: ") + theme.fg("text", anim.label));
|
|
138
|
-
};
|
|
139
|
-
if (!isActive) {
|
|
140
|
-
setFrame(anim.frames[0]);
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
const renderFrame = () => {
|
|
144
|
-
setFrame(anim.frames[frameIndex % anim.frames.length]);
|
|
145
|
-
frameIndex++;
|
|
146
|
-
};
|
|
147
|
-
renderFrame();
|
|
148
|
-
timer = setInterval(renderFrame, anim.interval);
|
|
149
|
-
}
|
|
150
|
-
dm.on("session_start", async (_event, ctx) => {
|
|
151
|
-
await ensureConfigLoaded();
|
|
152
|
-
let sessionLevel = null;
|
|
153
|
-
for (const entry of ctx.sessionManager.getEntries()) {
|
|
154
|
-
if (entry.type === "custom" && entry.customType === "caveman-level") {
|
|
155
|
-
sessionLevel = entry.data?.level ?? null;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
if (sessionLevel !== null) {
|
|
159
|
-
level = sessionLevel;
|
|
160
|
-
} else if (config.defaultLevel !== "off") {
|
|
161
|
-
level = config.defaultLevel;
|
|
162
|
-
dm.appendEntry("caveman-level", { level });
|
|
163
|
-
}
|
|
164
|
-
syncStatus(ctx);
|
|
165
|
-
});
|
|
166
|
-
dm.on("agent_start", async (_event, ctx) => {
|
|
167
|
-
isActive = true;
|
|
168
|
-
syncStatus(ctx);
|
|
169
|
-
});
|
|
170
|
-
dm.on("agent_end", async (_event, ctx) => {
|
|
171
|
-
isActive = false;
|
|
172
|
-
syncStatus(ctx);
|
|
173
|
-
});
|
|
174
|
-
dm.on("session_shutdown", async () => {
|
|
175
|
-
stopAnimation();
|
|
176
|
-
isActive = false;
|
|
177
|
-
});
|
|
178
|
-
dm.registerCommand("caveman", {
|
|
179
|
-
description: "Toggle caveman mode, set level, use stop/off/quit to disable, or 'config' to open settings",
|
|
180
|
-
getArgumentCompletions: (prefix) => {
|
|
181
|
-
const normalized = prefix.trim().toLowerCase();
|
|
182
|
-
const items = CAVEMAN_COMMAND_OPTIONS.filter((item) => item.value.startsWith(normalized));
|
|
183
|
-
return items.length > 0 ? items : null;
|
|
184
|
-
},
|
|
185
|
-
handler: async (args, ctx) => {
|
|
186
|
-
const arg = args?.trim().toLowerCase();
|
|
187
|
-
if (arg === "config") {
|
|
188
|
-
await openConfig(ctx);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
if (!arg) {
|
|
192
|
-
level = level === "off" ? "full" : "off";
|
|
193
|
-
} else if (STOP_ALIASES.has(arg)) {
|
|
194
|
-
level = "off";
|
|
195
|
-
} else if (LEVELS.includes(arg)) {
|
|
196
|
-
level = arg;
|
|
197
|
-
} else {
|
|
198
|
-
ctx.ui.notify(`Unknown: "${arg}". Use: ${LEVELS.join(", ")}, stop, quit, or config`, "error");
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
dm.appendEntry("caveman-level", { level });
|
|
202
|
-
syncStatus(ctx);
|
|
203
|
-
ctx.ui.notify(level === "off" ? "Caveman mode off." : `Caveman: ${ANIMATIONS[level].label}`, "info");
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
async function openConfig(ctx) {
|
|
207
|
-
await ensureConfigLoaded();
|
|
208
|
-
await ctx.ui.custom((_tui, theme, _kb, done) => {
|
|
209
|
-
const items = [
|
|
210
|
-
{
|
|
211
|
-
id: "defaultLevel",
|
|
212
|
-
label: "Default level for new sessions",
|
|
213
|
-
currentValue: config.defaultLevel,
|
|
214
|
-
values: [...LEVELS]
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
id: "showStatus",
|
|
218
|
-
label: "Show animated status bar",
|
|
219
|
-
currentValue: config.showStatus ? "on" : "off",
|
|
220
|
-
values: ["on", "off"]
|
|
221
|
-
}
|
|
222
|
-
];
|
|
223
|
-
const container = new Container;
|
|
224
|
-
container.addChild(new Text(theme.fg("accent", theme.bold(" Caveman Config")), 0, 0));
|
|
225
|
-
container.addChild(new Text(theme.fg("dim", " Saved to ~/.dm/agent/caveman.json"), 0, 0));
|
|
226
|
-
container.addChild(new Text(theme.fg("dim", " Default level applies to future sessions."), 0, 0));
|
|
227
|
-
container.addChild(new Text("", 0, 0));
|
|
228
|
-
const applySettingChange = (id, newValue) => {
|
|
229
|
-
if (id === "defaultLevel" && LEVELS.includes(newValue)) {
|
|
230
|
-
config.defaultLevel = newValue;
|
|
231
|
-
} else if (id === "showStatus") {
|
|
232
|
-
config.showStatus = newValue === "on";
|
|
233
|
-
}
|
|
234
|
-
saveConfig(config);
|
|
235
|
-
syncStatus(ctx);
|
|
236
|
-
};
|
|
237
|
-
const settingsList = new SettingsList(items, Math.min(items.length + 2, 10), getSettingsListTheme(), applySettingChange, () => done(undefined));
|
|
238
|
-
container.addChild(settingsList);
|
|
239
|
-
container.addChild(new Text(theme.fg("dim", " ←→/hl/tab change • ↑↓/jk move • esc close"), 0, 0));
|
|
240
|
-
const cycleSelectedValue = (direction) => {
|
|
241
|
-
const selectedIndex = settingsList.selectedIndex;
|
|
242
|
-
const item = items[selectedIndex];
|
|
243
|
-
if (!item?.values?.length)
|
|
244
|
-
return;
|
|
245
|
-
const currentIndex = item.values.indexOf(item.currentValue);
|
|
246
|
-
const nextIndex = (currentIndex + direction + item.values.length) % item.values.length;
|
|
247
|
-
const newValue = item.values[nextIndex];
|
|
248
|
-
item.currentValue = newValue;
|
|
249
|
-
settingsList.updateValue(item.id, newValue);
|
|
250
|
-
applySettingChange(item.id, newValue);
|
|
251
|
-
};
|
|
252
|
-
return {
|
|
253
|
-
render: (w) => container.render(w),
|
|
254
|
-
invalidate: () => container.invalidate(),
|
|
255
|
-
handleInput: (data) => {
|
|
256
|
-
if (data === "j")
|
|
257
|
-
data = "\x1B[B";
|
|
258
|
-
else if (data === "k")
|
|
259
|
-
data = "\x1B[A";
|
|
260
|
-
else if (data === "h") {
|
|
261
|
-
cycleSelectedValue(-1);
|
|
262
|
-
_tui.requestRender();
|
|
263
|
-
return;
|
|
264
|
-
} else if (data === "l" || data === "\x1B[C" || data === "\t") {
|
|
265
|
-
cycleSelectedValue(1);
|
|
266
|
-
_tui.requestRender();
|
|
267
|
-
return;
|
|
268
|
-
} else if (data === "\x1B[D") {
|
|
269
|
-
cycleSelectedValue(-1);
|
|
270
|
-
_tui.requestRender();
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
settingsList.handleInput?.(data);
|
|
274
|
-
_tui.requestRender();
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
dm.on("before_agent_start", async (event) => {
|
|
280
|
-
await ensureConfigLoaded();
|
|
281
|
-
if (level === "off")
|
|
282
|
-
return;
|
|
283
|
-
if (level === "micro") {
|
|
284
|
-
return {
|
|
285
|
-
systemPrompt: `${event.systemPrompt}
|
|
286
|
-
|
|
287
|
-
${MICRO_PROMPT}`
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
return {
|
|
291
|
-
systemPrompt: `${event.systemPrompt}
|
|
292
|
-
|
|
293
|
-
${BASE}
|
|
294
|
-
|
|
295
|
-
${INTENSITY[level]}
|
|
296
|
-
|
|
297
|
-
${SAFETY}`
|
|
298
|
-
};
|
|
299
|
-
});
|
|
300
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dm-caveman",
|
|
3
|
-
"version": "1.0.7",
|
|
4
|
-
"description": "DM extension for concise, token-efficient assistant responses",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"keywords": [
|
|
7
|
-
"duckmind",
|
|
8
|
-
"dm",
|
|
9
|
-
"dm-extension",
|
|
10
|
-
"caveman",
|
|
11
|
-
"token-saving"
|
|
12
|
-
],
|
|
13
|
-
"license": "MIT",
|
|
14
|
-
"author": "jonjonrankin",
|
|
15
|
-
"dm": {
|
|
16
|
-
"extensions": [
|
|
17
|
-
"./extensions/caveman.js"
|
|
18
|
-
]
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dm-goal",
|
|
3
|
-
"version": "0.11.0",
|
|
4
|
-
"description": "DM extension for long-running objective tracking and completion proof",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"author": null,
|
|
7
|
-
"license": "MIT",
|
|
8
|
-
"main": "src/goal.js",
|
|
9
|
-
"keywords": [
|
|
10
|
-
"duckmind",
|
|
11
|
-
"dm",
|
|
12
|
-
"goal",
|
|
13
|
-
"objective",
|
|
14
|
-
"continuation"
|
|
15
|
-
],
|
|
16
|
-
"dm": {
|
|
17
|
-
"extensions": [
|
|
18
|
-
"./src/goal.js"
|
|
19
|
-
]
|
|
20
|
-
},
|
|
21
|
-
"peerDependenciesMeta": {},
|
|
22
|
-
"engines": {}
|
|
23
|
-
}
|