@dotdotgod/claude-code 0.6.5 → 0.6.7
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/README.md +11 -1
- package/commands/dd/init.md +6 -1
- package/commands/dd/plan.md +5 -1
- package/hooks/README.md +5 -0
- package/hooks/runtime.mjs +24 -9
- package/mcp/cli.mjs +534 -299
- package/mcp/parsers/TYPESCRIPT_LICENSE +21 -0
- package/mcp/parsers/tree-sitter-tsx.wasm +0 -0
- package/mcp/parsers/tree-sitter-typescript.wasm +0 -0
- package/mcp/server.mjs +245 -86
- package/package.json +2 -2
- package/skills/doc-first-planning/SKILL.md +5 -1
- package/skills/project-initializer/SKILL.md +5 -0
- package/skills/project-initializer/references/agent-docs.md +1 -0
package/README.md
CHANGED
|
@@ -76,7 +76,7 @@ Projects can customize memory roles with `memory.areas`, select traceability-enf
|
|
|
76
76
|
|
|
77
77
|
## Bundled MCP And Hooks
|
|
78
78
|
|
|
79
|
-
The plugin starts a local stdio MCP server. It exposes `execute` and `execute_file`; context index, search, fetch, session resume, durable ingestion-job lifecycle, explicit healing, stats, doctor, and purge tools; plus `
|
|
79
|
+
The plugin starts a local stdio MCP server. It exposes `execute` and `execute_file`; context index, search, fetch, session resume, durable ingestion-job lifecycle, explicit healing, stats, doctor, and purge tools; plus `project_load`, `project_impact`, `impact_status`, `project_initialize`, `embedding_status`, and confirmation-gated `embedding_install`. Individual names have no `dotdotgod_` prefix; discover the host-qualified names. Reload existing sessions after upgrading; legacy names are not aliases.
|
|
80
80
|
|
|
81
81
|
Dotdotgod execution tools share a 10 MiB stdout/stderr capture ceiling per command. Crossing that ceiling terminates the child process and reports `captureLimitExceeded`; direct stdout and stderr excerpts are each capped at 1 MiB. Their child environments preserve compatibility-oriented inheritance after filtering runtime injection variables; this reports filtered names without values but does not isolate ordinary inherited credentials. Large output is indexed before retrieval in the ignored project-local `.dotdotgod/context/context.sqlite` FTS5 store, and searches return bounded excerpts. The store uses WAL, a bounded busy timeout, and transactional source replacement, expiry, and purge. Structural Markdown/JSON chunks, bounded typo-tolerant trigram candidates, reciprocal-rank fusion, and title/path/proximity signals improve retrieval while provenance and `instructionAuthority: "none"` identify retrieved text as non-authoritative data.
|
|
82
82
|
|
|
@@ -84,6 +84,16 @@ The MCP `index` tool accepts files or explicitly requested bounded directories,
|
|
|
84
84
|
|
|
85
85
|
Bundled hooks mark project load as required at session start, record successful source/config edits, and deny broad verification or handoff commands until matching graph impact succeeds. Denial asks Claude to call the required MCP tool and retry; hooks do not silently change one tool type into another. See [`hooks/README.md`](https://github.com/dotdotgod/dotdotgod-kit/blob/main/packages/claude-code/hooks/README.md) for lifecycle and trust boundaries.
|
|
86
86
|
|
|
87
|
+
## Native Plan Directory
|
|
88
|
+
|
|
89
|
+
After opting in, run `dotdotgod init . --claude-plans --dry-run`, then repeat
|
|
90
|
+
without `--dry-run` to add project `.claude/settings.json` `plansDirectory`.
|
|
91
|
+
Use `node <plugin>/mcp/cli.mjs init . --claude-plans` if the CLI is unavailable.
|
|
92
|
+
Existing values and other settings are preserved; global settings and permissions
|
|
93
|
+
are untouched. Native filenames remain Claude Code-owned, while shared task plans
|
|
94
|
+
use `docs/plan/<task-slug>/README.md` when the mode permits. No Mods are required.
|
|
95
|
+
Actual native storage was verified on Claude Code 2.1.308 with an offline fixture.
|
|
96
|
+
|
|
87
97
|
## Local Development
|
|
88
98
|
|
|
89
99
|
```bash
|
package/commands/dd/init.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Initialize dotdotgod project memory and config
|
|
3
|
-
argument-hint: [project-root] [--dotdot-setting] [--dry-run]
|
|
3
|
+
argument-hint: [project-root] [--dotdot-setting] [--claude-plans] [--dry-run]
|
|
4
4
|
allowed-tools: [Read, Glob, Grep, Bash, Write, Edit]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -38,3 +38,8 @@ Create a non-destructive dotdotgod baseline with canonical agent instructions, t
|
|
|
38
38
|
3. The POSIX fallback supports bundled templates only. If a custom template was selected and the CLI is unavailable, stop and explain that custom templates require the CLI; do not silently substitute another template.
|
|
39
39
|
4. Validate the initialized project with `dotdotgod validate <project-root>` when available.
|
|
40
40
|
5. Report created and skipped files, the selected template, validation failures, and unresolved instruction conflicts.
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
## Native Plan Storage
|
|
44
|
+
|
|
45
|
+
Only after the user opts in, add `--claude-plans` to the CLI initialization command. It adds project-local `plansDirectory` without replacing an existing value or changing permissions. Preview with `--dry-run`. The shell fallback does not support this option: use the bundled CLI at `$CLAUDE_PLUGIN_ROOT/mcp/cli.mjs` instead. Native file names remain Claude Code-owned; shared task plans still use task directories and README.md.
|
package/commands/dd/plan.md
CHANGED
|
@@ -16,6 +16,10 @@ Task request: `$ARGUMENTS`
|
|
|
16
16
|
|
|
17
17
|
For focused documentation routing, run `dotdotgod query <root> "<focus>" --limit 30 --json`. Run `dotdotgod config <root> --json` when memory-area policy or documentation routing/exclusions affect the plan. If the CLI is unavailable, continue from README indexes and focused file reads.
|
|
18
18
|
|
|
19
|
+
## Native Plan Mode
|
|
20
|
+
|
|
21
|
+
Claude Code owns its native plan file and naming. An opt-in plansDirectory setting can place native files under the project documentation plan directory; it does not grant arbitrary task README writes in native Plan Mode. Follow the native allowed path and permissions. Create the shared task README when the active mode permits it; never bypass restrictions through MCP or hooks.
|
|
22
|
+
|
|
19
23
|
## Goal
|
|
20
24
|
|
|
21
25
|
Create an implementation plan from maintained repository documentation before substantial source or configuration changes.
|
|
@@ -28,7 +32,7 @@ Use `docs/plan/<task-slug>/README.md` for substantial, risky, or resumable work;
|
|
|
28
32
|
2. Reuse loaded memory and the documentation map, then use focused query and README indexes to select maintained docs and verify conclusions in them.
|
|
29
33
|
3. Inspect the source needed to confirm targets and constraints.
|
|
30
34
|
4. Run impact review on likely changed files and refine targets, risks, and verification.
|
|
31
|
-
5.
|
|
35
|
+
5. When the active mode and permissions allow it, write and present the task README with scope, targets, executable steps, verification, and required completion gates.
|
|
32
36
|
6. Resolve blocking decisions and stop until the user asks to execute the plan.
|
|
33
37
|
|
|
34
38
|
## Quality Rules
|
package/hooks/README.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## Packaged Defaults
|
|
4
4
|
|
|
5
|
+
Local planning Markdown under the configured documentation plan directory does
|
|
6
|
+
not create source-impact pending state. Native plan paths and permissions remain
|
|
7
|
+
host-owned; hooks do not grant plan writes. Hook runtime state and MCP caches
|
|
8
|
+
have separate process permissions from the model's native tools.
|
|
9
|
+
|
|
5
10
|
The adapter packages `hooks/hooks.json` and `hooks/runtime.mjs`. They inject a bounded project-load requirement at session start, record successful `Edit`/`Write` paths, and deny broad verification or handoff shell commands while graph impact is pending. A denial names the required dotdotgod MCP tool; Claude calls it and retries the original operation. MCP tools bypass their own guards to prevent recursion.
|
|
6
11
|
|
|
7
12
|
Runtime state is local to `.dotdotgod/context/runtime/`. A successful impact call clears only paths whose current fingerprints match recorded edit state. Hooks run local commands with user permissions; review plugin resources before enabling them.
|
package/hooks/runtime.mjs
CHANGED
|
@@ -90,7 +90,12 @@ function toolInput(input) {
|
|
|
90
90
|
return input.tool_input || input.toolInput || {};
|
|
91
91
|
}
|
|
92
92
|
function mcpTool(name, suffix) {
|
|
93
|
-
return name === suffix ||
|
|
93
|
+
return name === suffix || [
|
|
94
|
+
"mcp__dotdotgod_context__",
|
|
95
|
+
"mcp__dotdotgod-context__",
|
|
96
|
+
"mcp__plugin_dotdotgod_dotdotgod-context__",
|
|
97
|
+
"mcp__plugin_dotdotgod_dotdotgod_context__"
|
|
98
|
+
].some((prefix) => name === `${prefix}${suffix}`);
|
|
94
99
|
}
|
|
95
100
|
function deny(reason) {
|
|
96
101
|
return { hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: reason } };
|
|
@@ -111,6 +116,16 @@ function changedPath(input, root) {
|
|
|
111
116
|
const path = value.file_path || value.path;
|
|
112
117
|
return normalizeProjectPath(root, path);
|
|
113
118
|
}
|
|
119
|
+
function isPlanDocument(root, path) {
|
|
120
|
+
let documentationRoot = "docs";
|
|
121
|
+
try {
|
|
122
|
+
const config = JSON.parse(readFileSync(join(root, "dotdotgod.config.json"), "utf8"));
|
|
123
|
+
if (typeof config.documentation?.root === "string") documentationRoot = config.documentation.root;
|
|
124
|
+
} catch {
|
|
125
|
+
}
|
|
126
|
+
const plan = normalizeProjectPath(root, join(documentationRoot, "plan"));
|
|
127
|
+
return plan && isInsideRoot(plan, path) && /\.md$/i.test(path);
|
|
128
|
+
}
|
|
114
129
|
function hasFailedToolResult(input) {
|
|
115
130
|
const response = input.tool_response || input.toolResponse || input.tool_result || input.toolResult || input.result;
|
|
116
131
|
if (!response || typeof response !== "object") return false;
|
|
@@ -132,19 +147,19 @@ function runHook(event) {
|
|
|
132
147
|
if (!context) return {};
|
|
133
148
|
state.loadRequired = true;
|
|
134
149
|
writeState(context.path, state);
|
|
135
|
-
return { hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: "Dotdotgod project memory has not been loaded for this session. Before substantive shell or write work, call
|
|
150
|
+
return { hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: "Dotdotgod project memory has not been loaded for this session. Before substantive shell or write work, call project_load from the dotdotgod-context MCP server once with a concise task-specific focus." } };
|
|
136
151
|
}
|
|
137
152
|
if (event === "pretooluse") {
|
|
138
|
-
if (mcpTool(name, "
|
|
139
|
-
if (state.loadRequired && isSubstantive(name)) return deny("Project memory is required first. Call
|
|
153
|
+
if (mcpTool(name, "project_load") || mcpTool(name, "project_impact")) return {};
|
|
154
|
+
if (state.loadRequired && isSubstantive(name)) return deny("Project memory is required first. Call project_load from the dotdotgod-context MCP server with the current project root and a concise task-specific focus, then retry this tool.");
|
|
140
155
|
const pendingPaths = Object.keys(state.pending);
|
|
141
|
-
if (pendingPaths.length && isImpactGate(name, input)) return deny(`Graph impact is pending. Call
|
|
156
|
+
if (pendingPaths.length && isImpactGate(name, input)) return deny(`Graph impact is pending. Call project_impact from the dotdotgod-context MCP server with paths=${JSON.stringify(pendingPaths)} and then retry this tool.`);
|
|
142
157
|
return {};
|
|
143
158
|
}
|
|
144
159
|
if (event === "posttooluse") {
|
|
145
160
|
if (!context) return {};
|
|
146
|
-
if (mcpTool(name, "
|
|
147
|
-
else if (mcpTool(name, "
|
|
161
|
+
if (mcpTool(name, "project_load")) state.loadRequired = false;
|
|
162
|
+
else if (mcpTool(name, "project_impact")) {
|
|
148
163
|
const checked = toolInput(input).paths;
|
|
149
164
|
let cleared = 0;
|
|
150
165
|
if (Array.isArray(checked)) for (const path of checked) {
|
|
@@ -155,11 +170,11 @@ function runHook(event) {
|
|
|
155
170
|
}
|
|
156
171
|
}
|
|
157
172
|
writeState(context.path, state);
|
|
158
|
-
if (cleared > 0 && hasFailedToolResult(input)) return { hookSpecificOutput: { hookEventName: "PostToolUse", additionalContext: `
|
|
173
|
+
if (cleared > 0 && hasFailedToolResult(input)) return { hookSpecificOutput: { hookEventName: "PostToolUse", additionalContext: `project_impact reported a failure, but dotdotgod cleared pending graph impact for ${cleared} requested path(s) to avoid a blocking retry loop. Review the impact error before broad operations.` } };
|
|
159
174
|
return {};
|
|
160
175
|
} else if (/^(Edit|Write|apply_patch)$/i.test(name)) {
|
|
161
176
|
const path = changedPath(input, context.root);
|
|
162
|
-
if (path) state.pending[path] = fileHash(path);
|
|
177
|
+
if (path && !isPlanDocument(context.root, path)) state.pending[path] = fileHash(path);
|
|
163
178
|
}
|
|
164
179
|
writeState(context.path, state);
|
|
165
180
|
return {};
|