claude-plugin-dsh 0.0.0-stage → 0.2.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.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +178 -2
  3. package/dist/bin/cli.d.ts +3 -0
  4. package/dist/bin/cli.d.ts.map +1 -0
  5. package/dist/bin/cli.js +107 -0
  6. package/dist/bin/cli.js.map +1 -0
  7. package/dist/bin/inspect.d.ts +2 -0
  8. package/dist/bin/inspect.d.ts.map +1 -0
  9. package/dist/bin/inspect.js +45 -0
  10. package/dist/bin/inspect.js.map +1 -0
  11. package/dist/bin/runtime.d.ts +2 -0
  12. package/dist/bin/runtime.d.ts.map +1 -0
  13. package/dist/bin/runtime.js +4 -0
  14. package/dist/bin/runtime.js.map +1 -0
  15. package/dist/bin/scaffold.d.ts +2 -0
  16. package/dist/bin/scaffold.d.ts.map +1 -0
  17. package/dist/bin/scaffold.js +44 -0
  18. package/dist/bin/scaffold.js.map +1 -0
  19. package/dist/bin/sync.d.ts +2 -0
  20. package/dist/bin/sync.d.ts.map +1 -0
  21. package/dist/bin/sync.js +24 -0
  22. package/dist/bin/sync.js.map +1 -0
  23. package/dist/bin/update.d.ts +27 -0
  24. package/dist/bin/update.d.ts.map +1 -0
  25. package/dist/bin/update.js +183 -0
  26. package/dist/bin/update.js.map +1 -0
  27. package/dist/claude-compat.js +825 -0
  28. package/dist/src/claude-compat.d.ts +8 -0
  29. package/dist/src/claude-compat.d.ts.map +1 -0
  30. package/dist/src/claude-compat.js +7 -0
  31. package/dist/src/claude-compat.js.map +1 -0
  32. package/dist/src/dsh-types.d.ts +252 -0
  33. package/dist/src/dsh-types.d.ts.map +1 -0
  34. package/dist/src/dsh-types.js +6 -0
  35. package/dist/src/dsh-types.js.map +1 -0
  36. package/dist/src/hooks.d.ts +38 -0
  37. package/dist/src/hooks.d.ts.map +1 -0
  38. package/dist/src/hooks.js +136 -0
  39. package/dist/src/hooks.js.map +1 -0
  40. package/dist/src/plugin-files.d.ts +92 -0
  41. package/dist/src/plugin-files.d.ts.map +1 -0
  42. package/dist/src/plugin-files.js +198 -0
  43. package/dist/src/plugin-files.js.map +1 -0
  44. package/dist/src/plugin.d.ts +35 -0
  45. package/dist/src/plugin.d.ts.map +1 -0
  46. package/dist/src/plugin.js +422 -0
  47. package/dist/src/plugin.js.map +1 -0
  48. package/dist/src/transcript.d.ts +25 -0
  49. package/dist/src/transcript.d.ts.map +1 -0
  50. package/dist/src/transcript.js +198 -0
  51. package/dist/src/transcript.js.map +1 -0
  52. package/package.json +54 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mariusz Rakus
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,179 @@
1
- # Temporary Holding Version
1
+ # claude-plugin-dsh
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Run an unmodified [Claude Code](https://docs.claude.com/en/docs/claude-code) plugin inside
4
+ [DeepSeek Harness](https://github.com/deepseek-ai) (DSH).
5
+
6
+ You add a `dsh/` directory next to the plugin's `.claude-plugin/`. It holds a small DSH
7
+ bundle and a copy of `claude-compat.js`. The bundle reads the plugin's own skills, commands,
8
+ agents, hooks and instruction files and wires them into DSH. Claude Code never reads `dsh/`,
9
+ so the same tree keeps working in both harnesses. The vendored runtime is refreshed with
10
+ `sync`, not by hand.
11
+
12
+ TypeScript sources, compiled JavaScript and declarations. The vendored runtime is one file
13
+ with no runtime dependencies. Node 20 or newer; hooks require a POSIX shell.
14
+
15
+ Install the package:
16
+
17
+ ```sh
18
+ bun add claude-plugin-dsh
19
+ ```
20
+
21
+ `bun x claude-plugin-dsh` runs the CLI without installing it.
22
+ The old `claude-plugins-dsh` command name still works as an alias.
23
+
24
+ Adapters may import `createPlugin` and `rootFrom` directly, or vendor the built runtime as
25
+ shown below. Direct imports receive types; vendored copies stay self-contained and must be
26
+ updated with `sync`.
27
+
28
+ ## What maps to what
29
+
30
+ | Claude Code | DSH |
31
+ |---|---|
32
+ | `skills/<n>/SKILL.md` | skill at rank 450, so a same-named skill in `~/.dsh/skills` still wins |
33
+ | `commands/<n>.md` | `/<plugin>-<n>` slash command (prefix configurable); the body, with `$ARGUMENTS` and `$1` to `$9`, becomes the next turn |
34
+ | `agents/<n>.md` | skill `<plugin>-agent-<n>`: a role brief to pass to `subagent` or `spawn_teammate` |
35
+ | `CLAUDE.md`-style files you list | system prompt section, with `<!--harness:claude-only-->` blocks removed |
36
+ | `PreToolUse` hook | `tools/pre-execute`; `ask` becomes a DSH approval, `deny` or exit 2 denies, `updatedInput` is denied because DSH cannot rewrite arguments |
37
+ | `PostToolUse` hook | `tools/post-execute`; exit 2 blocks the result and its stderr becomes the feedback, `additionalContext` rides on the decision |
38
+ | `SessionStart` hook | `agent/created` of a root agent (subagents skipped, as in Claude Code) |
39
+ | `UserPromptSubmit` hook | a step carrying a user message; a block keeps the prompt from the model |
40
+ | `Stop`, `SubagentStop` hooks | `agent/turn-stopping`; `{"decision":"block"}` steers one more step |
41
+ | `SessionEnd` hook | `agent/disposed` |
42
+ | `.mcp.json` | not handled here: add `@deepseek-ai/dsh-mcp-client` rows to the bundle patch |
43
+
44
+ Hooks get Claude Code's stdin JSON: `session_id`, `cwd`, `hook_event_name`, `tool_name` using
45
+ Claude names such as `Bash`, `tool_input`, `stop_hook_active` and `transcript_path`.
46
+ `tool_response` uses Claude's per-tool shape: `stdout` and `stderr` for Bash, `file.content`
47
+ for Read, `filePath` plus edit strings for Write and Edit, and `filenames` for Glob. Their
48
+ environment has `CLAUDE_PLUGIN_ROOT` and `CLAUDE_PROJECT_DIR`, plus `CLAUDE_HARNESS=dsh` so a
49
+ script can tell the two harnesses apart. A hook with `args` runs in exec form, as in Claude Code: `command` is spawned directly with those arguments and no shell, and `${CLAUDE_PLUGIN_ROOT}` and `${CLAUDE_PROJECT_DIR}` are replaced inside each argument as plain text. `onFailure: "block"` makes a crash, a timeout or an exit code other than 0 and 2 count as a block. Matching hooks run in parallel, each in its own process
50
+ group. A timeout or a cancelled turn kills the whole group.
51
+
52
+ `transcript_path` points at a Claude-shaped JSONL export of the DSH session under
53
+ `$DSH_HOME/state/claude-compat/transcripts/`. It is mode 0600, grows by appending, and is
54
+ deleted when the agent is disposed.
55
+
56
+ Not mapped: function hooks (`hooks.json` `modules`), `PreCompact`, `Notification`, LSP
57
+ servers, and per-agent model pins.
58
+
59
+ ## Add it to a plugin
60
+
61
+ ```sh
62
+ bun x claude-plugin-dsh scaffold --scope @you /path/to/plugin
63
+ ```
64
+
65
+ `scaffold` writes `dsh/package.json` (package `@you/<plugin>-dsh`, or `<plugin>-dsh` without
66
+ `--scope`), `dsh/locale/en.json` and the runtime copy. You write two small files yourself.
67
+
68
+ `dsh/index.js`:
69
+
70
+ ```js
71
+ import { createPlugin, rootFrom } from './claude-compat.js'
72
+
73
+ const plugin = createPlugin({
74
+ root: rootFrom(import.meta.url),
75
+ // all optional:
76
+ instructions: ['CLAUDE.md'], // files to put in the system prompt
77
+ skills: { exclude: [], prefix: '' }, // prefix renames x to <prefix>-x; '' keeps x
78
+ commands: { exclude: [], prefix: '' },// default is the plugin name; '' gives /<n>
79
+ agents: { exclude: [], extraDirs: [] },
80
+ hooks: { events: ['PreToolUse'] }, // limit which hook events run
81
+ disableByDefault: [], // skills | commands | agents | instructions | hooks
82
+ })
83
+ export const { name, apply } = plugin
84
+ export default plugin
85
+ ```
86
+
87
+ `dsh/cordis.patch.yml`:
88
+
89
+ ```yaml
90
+ - insert:
91
+ - id: claude-compat-my-plugin
92
+ name: '@you/my-plugin-dsh' # the name in dsh/package.json
93
+ ```
94
+
95
+ Check what it registers without starting DSH:
96
+
97
+ ```sh
98
+ bun x claude-plugin-dsh inspect /path/to/plugin
99
+ ```
100
+
101
+ ## Install into DSH
102
+
103
+ Through DSH's plugin manager:
104
+
105
+ ```sh
106
+ dsh plugin --profile web add file:/abs/path/to/plugin/dsh
107
+ ```
108
+
109
+ Or for every profile, add a row to `~/.dsh/cordis.patch.yml`. DSH picks it up without a restart:
110
+
111
+ ```yaml
112
+ - insert:
113
+ - id: claude-compat-my-plugin
114
+ name: "file:///abs/path/to/plugin/dsh/index.js"
115
+ ```
116
+
117
+ A row config can turn parts off: `config: { disable: [hooks] }`.
118
+
119
+ ## Updating installed plugins
120
+
121
+ When adapters are loaded from git checkouts under `$DSH_HOME/plugins-src` (one row per
122
+ checkout in `~/.dsh/cordis.patch.yml`), `update` brings them to their upstream branch:
123
+
124
+ ```sh
125
+ bun x claude-plugin-dsh update # every checkout under $DSH_HOME/plugins-src
126
+ bun x claude-plugin-dsh update --check # report what is behind, write nothing, exit 1 if any
127
+ bun x claude-plugin-dsh update ~/.dsh/plugins-src/design-studio
128
+ ```
129
+
130
+ For each checkout it fetches, fast-forwards the current branch onto its tracking ref
131
+ (`origin/<branch>` when none is configured), runs `bun install --frozen-lockfile` in every
132
+ tracked `dsh/` directory, and rewrites the `# <dir> <branch> <hash>` comment above the
133
+ checkout's row in the patch file. That comment is a note for people; DSH loads the checkout
134
+ as it is on disk. A dirty working tree stops the update for that checkout.
135
+
136
+ When the remote history was rewritten and the branch cannot be fast-forwarded, `update`
137
+ refuses and prints the undo command. `--reset` moves the branch onto the upstream with
138
+ `git reset --hard` instead; local commits that are not upstream are dropped from the branch
139
+ but stay in the reflog. `--patch <file>` rewrites pins in a different file.
140
+
141
+ Restart DSH afterwards so it loads the new version.
142
+
143
+ ## Keeping vendored copies current
144
+
145
+ ```sh
146
+ bun x claude-plugin-dsh sync plugin-a plugin-b
147
+ bun x claude-plugin-dsh sync --check plugin-a plugin-b
148
+ ```
149
+
150
+ ## Development
151
+
152
+ ```sh
153
+ bun install --frozen-lockfile
154
+ bun run typecheck
155
+ bun run test
156
+ bun pm pack
157
+ ```
158
+
159
+ `bun run build` compiles the typed modules and CLI, emits declarations, and bundles
160
+ `dist/claude-compat.js` for existing adapters. Generated files are not committed.
161
+ `bun run test` runs the Node compatibility suite against the compiled runtime and CLI.
162
+ `prepack` builds before packaging.
163
+
164
+ Publishing requires npm access to the `claude-plugin-dsh` package:
165
+
166
+ ```sh
167
+ bun publish
168
+ ```
169
+
170
+ `prepublishOnly` runs type checking and tests before publication. Do not put registry tokens
171
+ in the repository. Run `inspect` only on trusted plugins: it imports their JavaScript.
172
+
173
+ ## Used by
174
+
175
+ The [kolezka](https://github.com/kolezka/marketplace) Claude Code plugins.
176
+
177
+ ## License
178
+
179
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env node
2
+ import { inspect } from './inspect.js';
3
+ import { scaffold } from './scaffold.js';
4
+ import { sync } from './sync.js';
5
+ import { discoverCheckouts, update } from './update.js';
6
+ const usage = `Usage: claude-plugin-dsh <command> [options] <plugin-dir>...
7
+
8
+ Commands:
9
+ scaffold [--scope @you] <plugin-dir>... Generate manifest, locale and runtime
10
+ inspect <plugin-dir>... List plugin registrations (loads plugin code)
11
+ sync [--check] <plugin-dir>... Copy runtime, or check for drift
12
+ update [--check] [--reset] [--patch <file>] [<checkout-dir>...]
13
+ Pull adapter checkouts, install their dsh/ dependencies and
14
+ refresh the pin comments in cordis.patch.yml. Without directories,
15
+ every checkout under $DSH_HOME/plugins-src is updated.
16
+
17
+ Options:
18
+ -h, --help Show help
19
+ `;
20
+ class UsageError extends Error {
21
+ }
22
+ async function main(args) {
23
+ const [command, ...rest] = args;
24
+ if ((command === '-h' || command === '--help') && rest.length === 0) {
25
+ console.log(usage);
26
+ return 0;
27
+ }
28
+ if (command !== 'scaffold' && command !== 'inspect' && command !== 'sync' && command !== 'update') {
29
+ throw new UsageError(command ? `Unknown command: ${command}` : 'A command is required');
30
+ }
31
+ if (rest.length === 1 && (rest[0] === '-h' || rest[0] === '--help')) {
32
+ console.log(usage);
33
+ return 0;
34
+ }
35
+ let scope;
36
+ let check = false;
37
+ let reset = false;
38
+ let patch;
39
+ let positional = false;
40
+ const directories = [];
41
+ for (let index = 0; index < rest.length; index++) {
42
+ const arg = rest[index];
43
+ if (arg === undefined)
44
+ continue;
45
+ if (!positional && arg === '--') {
46
+ positional = true;
47
+ }
48
+ else if (!positional && arg === '--scope' && command === 'scaffold') {
49
+ if (scope !== undefined)
50
+ throw new UsageError('--scope may only be supplied once');
51
+ scope = rest[++index];
52
+ if (scope === undefined || !/^@[a-z0-9][a-z0-9._-]*$/.test(scope)) {
53
+ throw new UsageError(`--scope must look like @name, got ${JSON.stringify(scope)}`);
54
+ }
55
+ }
56
+ else if (!positional && arg === '--check' && (command === 'sync' || command === 'update')) {
57
+ if (check)
58
+ throw new UsageError('--check may only be supplied once');
59
+ check = true;
60
+ }
61
+ else if (!positional && arg === '--reset' && command === 'update') {
62
+ if (reset)
63
+ throw new UsageError('--reset may only be supplied once');
64
+ reset = true;
65
+ }
66
+ else if (!positional && arg === '--patch' && command === 'update') {
67
+ if (patch !== undefined)
68
+ throw new UsageError('--patch may only be supplied once');
69
+ patch = rest[++index];
70
+ if (patch === undefined || patch.startsWith('-'))
71
+ throw new UsageError('--patch requires a file path');
72
+ }
73
+ else if (!positional && arg.startsWith('-')) {
74
+ throw new UsageError(`Unknown option for ${command}: ${arg}`);
75
+ }
76
+ else {
77
+ directories.push(arg);
78
+ }
79
+ }
80
+ if (command === 'update') {
81
+ if (check && reset)
82
+ throw new UsageError('--check and --reset cannot be combined');
83
+ const targets = directories.length ? directories : discoverCheckouts();
84
+ if (!targets.length)
85
+ throw new UsageError('update found no checkouts under $DSH_HOME/plugins-src; pass directories explicitly');
86
+ return update(targets, { check, reset, patch });
87
+ }
88
+ if (!directories.length)
89
+ throw new UsageError(`${command} requires at least one plugin directory`);
90
+ if (command === 'scaffold') {
91
+ scaffold(directories, scope ?? '');
92
+ return 0;
93
+ }
94
+ if (command === 'sync')
95
+ return sync(directories, check);
96
+ return inspect(directories);
97
+ }
98
+ try {
99
+ process.exitCode = await main(process.argv.slice(2));
100
+ }
101
+ catch (error) {
102
+ console.error(error instanceof Error ? error.message : String(error));
103
+ if (error instanceof UsageError)
104
+ console.error(usage);
105
+ process.exitCode = error instanceof UsageError ? 64 : 1;
106
+ }
107
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function inspect(directories: readonly string[]): Promise<number>;
2
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../bin/inspect.ts"],"names":[],"mappings":"AAIA,wBAAsB,OAAO,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyC7E"}
@@ -0,0 +1,45 @@
1
+ import { resolve } from 'node:path';
2
+ import { pathToFileURL } from 'node:url';
3
+ export async function inspect(directories) {
4
+ let failed = false;
5
+ for (const directory of directories) {
6
+ const entry = pathToFileURL(resolve(directory, 'dsh', 'index.js')).href;
7
+ const plugin = await import(entry);
8
+ if (typeof plugin !== 'object' || plugin === null || !('apply' in plugin) || typeof plugin.apply !== 'function') {
9
+ throw new Error(`${entry}: expected a plugin exporting apply`);
10
+ }
11
+ const seen = {
12
+ skills: [], commands: [], sections: [], events: [],
13
+ };
14
+ const ctx = {
15
+ logger: { warn: (message) => console.warn(' warn:', message) },
16
+ skills: { registerProvider: (create) => seen.skills.push(create({ signal: new AbortController().signal, invalidate() { } })) },
17
+ commands: { register: (definition) => seen.commands.push(definition.name) },
18
+ systemPrompt: { section: (section) => seen.sections.push(section) },
19
+ workingDirectory: { get: () => process.cwd() },
20
+ inject: (_services, callback) => callback(ctx),
21
+ effect() { },
22
+ on: (event) => seen.events.push(event),
23
+ };
24
+ await plugin.apply(ctx, {});
25
+ const skills = [];
26
+ for (const provider of seen.skills) {
27
+ for (const candidate of await provider.list({})) {
28
+ const body = await provider.get(candidate, {});
29
+ if (!body?.content) {
30
+ failed = true;
31
+ console.error(` ${candidate.name}: empty body`);
32
+ }
33
+ skills.push(candidate.name);
34
+ }
35
+ }
36
+ const prompt = seen.sections.map((section) => typeof section.text === 'string' ? section.text : section.text({})).join('');
37
+ console.log('name' in plugin ? String(plugin.name) : directory);
38
+ console.log(` skills: ${skills.join(', ') || '-'}`);
39
+ console.log(` commands: ${seen.commands.map((command) => '/' + command).join(' ') || '-'}`);
40
+ console.log(` prompt: ${prompt ? `${prompt.length} chars, claude-only left: ${/harness:claude-only/.test(prompt)}` : '-'}`);
41
+ console.log(` events: ${[...new Set(seen.events)].join(', ') || '-'}`);
42
+ }
43
+ return failed ? 1 : 0;
44
+ }
45
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../bin/inspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const runtimePath: string;
2
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../bin/runtime.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,QAAiE,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ // The CLI lives in dist/bin; the vendorable bundle lives directly in dist.
3
+ export const runtimePath = fileURLToPath(new URL('../claude-compat.js', import.meta.url));
4
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../bin/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,2EAA2E;AAC3E,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,qBAAqB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare function scaffold(directories: readonly string[], scope: string): void;
2
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../bin/scaffold.ts"],"names":[],"mappings":"AAsBA,wBAAgB,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAyB5E"}
@@ -0,0 +1,44 @@
1
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join, resolve } from 'node:path';
3
+ import { runtimePath } from './runtime.js';
4
+ function readManifest(root) {
5
+ const value = JSON.parse(readFileSync(join(root, '.claude-plugin', 'plugin.json'), 'utf8'));
6
+ if (typeof value !== 'object' || value === null || !('name' in value) || typeof value.name !== 'string' || !value.name) {
7
+ throw new Error(`${root}: plugin manifest must contain a name`);
8
+ }
9
+ const version = 'version' in value ? value.version : undefined;
10
+ const description = 'description' in value ? value.description : undefined;
11
+ if (version !== undefined && typeof version !== 'string')
12
+ throw new Error(`${root}: plugin version must be a string`);
13
+ if (description !== undefined && typeof description !== 'string')
14
+ throw new Error(`${root}: plugin description must be a string`);
15
+ return { name: value.name, version: version ?? '0.0.0', description: description ?? '' };
16
+ }
17
+ export function scaffold(directories, scope) {
18
+ for (const directory of directories) {
19
+ const root = resolve(directory);
20
+ const manifest = readManifest(root);
21
+ const dsh = join(root, 'dsh');
22
+ mkdirSync(join(dsh, 'locale'), { recursive: true });
23
+ copyFileSync(runtimePath, join(dsh, 'claude-compat.js'));
24
+ const pkg = {
25
+ name: `${scope ? scope + '/' : ''}${manifest.name}-dsh`,
26
+ version: manifest.version,
27
+ private: true,
28
+ description: `DeepSeek Harness adapter for the ${manifest.name} Claude Code plugin`,
29
+ type: 'module',
30
+ exports: { '.': './index.js', './locale/*.json': './locale/*.json' },
31
+ files: ['index.js', 'claude-compat.js', 'cordis.patch.yml', 'locale/*.json'],
32
+ dsh: { bundle: { patch: './cordis.patch.yml' } },
33
+ };
34
+ writeFileSync(join(dsh, 'package.json'), JSON.stringify(pkg, null, 2) + '\n');
35
+ const locale = { meta: { title: manifest.name, description: manifest.description } };
36
+ writeFileSync(join(dsh, 'locale', 'en.json'), JSON.stringify(locale, null, 2) + '\n');
37
+ for (const required of ['index.js', 'cordis.patch.yml']) {
38
+ if (!existsSync(join(dsh, required)))
39
+ console.warn(`${manifest.name}: dsh/${required} is missing, write it by hand`);
40
+ }
41
+ console.log(`scaffolded ${dsh}`);
42
+ }
43
+ }
44
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../bin/scaffold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function sync(directories: readonly string[], check: boolean): number;
2
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../bin/sync.ts"],"names":[],"mappings":"AAIA,wBAAgB,IAAI,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAkB3E"}
@@ -0,0 +1,24 @@
1
+ import { copyFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
2
+ import { join, resolve } from 'node:path';
3
+ import { runtimePath } from './runtime.js';
4
+ export function sync(directories, check) {
5
+ const canonical = readFileSync(runtimePath);
6
+ let status = 0;
7
+ for (const directory of directories) {
8
+ const dsh = resolve(directory, 'dsh');
9
+ const destination = join(dsh, 'claude-compat.js');
10
+ if (check) {
11
+ if (!existsSync(destination) || !canonical.equals(readFileSync(destination))) {
12
+ console.log(`drift: ${destination}`);
13
+ status = 1;
14
+ }
15
+ }
16
+ else {
17
+ mkdirSync(dsh, { recursive: true });
18
+ copyFileSync(runtimePath, destination);
19
+ console.log(`synced: ${destination}`);
20
+ }
21
+ }
22
+ return status;
23
+ }
24
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../bin/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC3E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,MAAM,UAAU,IAAI,CAAC,WAA8B,EAAE,KAAc;IACjE,MAAM,SAAS,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;IAC3C,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,KAAK,MAAM,SAAS,IAAI,WAAW,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QACrC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAA;QACjD,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;gBAC7E,OAAO,CAAC,GAAG,CAAC,UAAU,WAAW,EAAE,CAAC,CAAA;gBACpC,MAAM,GAAG,CAAC,CAAA;YACZ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YACnC,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;YACtC,OAAO,CAAC,GAAG,CAAC,WAAW,WAAW,EAAE,CAAC,CAAA;QACvC,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,27 @@
1
+ export interface UpdateOptions {
2
+ /** Report what would change and exit 1 when behind, without writing. */
3
+ check: boolean;
4
+ /** When the branch cannot be fast-forwarded, `git reset --hard` it onto the upstream. */
5
+ reset: boolean;
6
+ /** Patch file whose pin comments are rewritten; undefined uses $DSH_HOME/cordis.patch.yml. */
7
+ patch: string | undefined;
8
+ }
9
+ interface Checkout {
10
+ root: string;
11
+ /** Directory name: the pin comments in cordis.patch.yml are keyed by it. */
12
+ name: string;
13
+ upstream: string;
14
+ branch: string;
15
+ }
16
+ export declare function defaultPatchFile(env?: NodeJS.ProcessEnv): string;
17
+ /** Every git checkout directly under $DSH_HOME/plugins-src. */
18
+ export declare function discoverCheckouts(env?: NodeJS.ProcessEnv): string[];
19
+ /**
20
+ * Rewrite the `# <dir> <branch> <hash>` pin comment above the checkout's insert row.
21
+ * The comment is documentation only; DSH loads whatever the checkout contains.
22
+ * Returns false when the patch file has no pin for this checkout.
23
+ */
24
+ export declare function rewritePin(patchFile: string, checkout: Checkout, hash: string, write: boolean): boolean;
25
+ export declare function update(directories: readonly string[], options: UpdateOptions): number;
26
+ export {};
27
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../bin/update.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,KAAK,EAAE,OAAO,CAAA;IACd,yFAAyF;IACzF,KAAK,EAAE,OAAO,CAAA;IACd,8FAA8F;IAC9F,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1B;AAED,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAoBD,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE7E;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,EAAE,CAOhF;AAoDD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAiBvG;AAED,wBAAgB,MAAM,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAYrF"}