@amaster.ai/dsh-subagent-filesystem 0.0.0-stage → 0.1.23
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 +21 -0
- package/README.md +71 -2
- package/cordis.patch.yml +3 -0
- package/lib/index.js +239 -0
- package/lib/types/index.d.ts +29 -0
- package/package.json +67 -3
- package/preview.png +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-plugins contributors
|
|
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,72 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-subagent-filesystem
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Markdown roles for dsh
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
Discover specialist roles from the agent workspace's `agents/*.md` and expose named delegation tools. Each Markdown body becomes a separate child system section, preserving Harness instructions, the application persona, and native permissions. The delegated task remains user content. Files are read exclusively through the caller's scoped `ctx.fs`, including remote and sandbox providers, with no host-filesystem fallback.
|
|
8
|
+
|
|
9
|
+
## Install and configure
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
dsh plugin --profile my-agent add @amaster.ai/dsh-subagent-filesystem
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Enable the bundle in the profile's `cordis.patch.yml`:
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
- id: subagent-filesystem
|
|
19
|
+
config:
|
|
20
|
+
enabled: true
|
|
21
|
+
root: agents
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Disabled by default. `root` defaults to `agents`, relative to the agent's initial workspace directory; sandbox deployments can explicitly select `/agents`. Discovery scans direct `*.md` children only. A missing root produces an empty catalog. Files are loaded when the agent is created; create a new agent to pick up changes. Watching and hot reload are outside the initial scope.
|
|
25
|
+
|
|
26
|
+
Requires the `fs`, `tools`, `subagents`, `systemPrompt`, and `sessionQuery` services, plus the native in-process provider registered as `spawn`. The standard headless profile supplies these capabilities. DSH peer floor: `>=0.2.0-rc.1`; tested DSH: `0.2.0-rc.2`; tested Cordis: `4.0.4`.
|
|
27
|
+
|
|
28
|
+
## Definition format
|
|
29
|
+
|
|
30
|
+
`agents/inventory-analyst.md`:
|
|
31
|
+
|
|
32
|
+
```markdown
|
|
33
|
+
---
|
|
34
|
+
name: inventory-analyst
|
|
35
|
+
description: Investigate inventory discrepancies and explain their causes.
|
|
36
|
+
---
|
|
37
|
+
You are the inventory analyst. Compare posted movements with current balances,
|
|
38
|
+
identify discrepancies, and report evidence before recommending changes.
|
|
39
|
+
Read references/inventory-rules.md relative to this definition before analysis.
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Only `name` and `description` are supported in YAML frontmatter. Names must be lowercase kebab-case, start with a letter, and contain at most 55 characters. Description and body must be nonempty. Definitions must be valid UTF-8 and at most 1 MiB. Unsupported fields, duplicate YAML keys, duplicate role names, and tool-name collisions fail that agent's catalog load with a `[dsh-subagent-filesystem]` error. No partial catalog is published; existing application tools are preserved.
|
|
43
|
+
|
|
44
|
+
`{{…}}` in the body stays literal. Child instructions include the definition's resource directory. The child opens supporting references, scripts, and assets with its own tools, resolving relative paths against that directory. This plugin does not download or execute resources.
|
|
45
|
+
|
|
46
|
+
## Delegation
|
|
47
|
+
|
|
48
|
+
The example exposes `subagent_inventory_analyst`; its description tells the parent when to delegate.
|
|
49
|
+
|
|
50
|
+
| Parameter | Meaning |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `prompt` | Required: a complete, self-contained task delivered as the child's user message |
|
|
53
|
+
| `description` | Required: the native subagent's short task label |
|
|
54
|
+
| `run_in_background` | Default false: wait for a report; true: return a continuable child id |
|
|
55
|
+
|
|
56
|
+
Background children use native completion notifications and `send_message` for follow-up. Native subagent services retain model defaults, delegation depth, sandbox boundaries, and approval rules. Definition files cannot override models, tools, or permissions. Foreground failures become tool errors; accepted runs always reach native cleanup.
|
|
57
|
+
|
|
58
|
+
Named tools belong only to the consuming parent agent. They do not leak into other agents or workspaces, or automatically copy to children. A `subagent-filesystem/role` session event stores the child's role instructions and resource path. Cold restoration reinstalls the original snapshot rather than changing an existing role when its source file changes. Protect these instruction snapshots through the consuming application's existing session storage and access controls.
|
|
59
|
+
|
|
60
|
+
Unloading cancels outstanding delegations, removes registrations and listeners, and releases background children started by the plugin. Role restoration requires the plugin to remain enabled. The initial version supports native in-process spawn; external ACP/Codex/Claude providers and application configuration downloads are outside its scope.
|
|
61
|
+
|
|
62
|
+
## Tests
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
pnpm --filter @amaster.ai/dsh-subagent-filesystem test
|
|
66
|
+
pnpm --filter @amaster.ai/dsh-subagent-filesystem typecheck
|
|
67
|
+
pnpm --filter @amaster.ai/dsh-subagent-filesystem build
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`.github/scripts/integration/dsh-subagent-filesystem.mjs` automatically joins the repository E2E matrix. It installs the packed bundle, starts real dsh, delegates through the integration model, and verifies the actual child system instructions, user task, and resource-file evidence. A local forwarding gateway inspects protocol requests, so system/user separation is verified independently of the model's claims.
|
|
71
|
+
|
|
72
|
+
Required: `DSH_PKG_TARBALL`, `DSH_INTEGRATION_BASE_URL`, and `DSH_INTEGRATION_API_KEY`. Optional: `DSH_CLI`, `DSH_HOME`, and `DSH_INTEGRATION_MODEL`. For local development, set `DSH_SUBAGENT_E2E_FAKE=1` to use deterministic Messages responses while still running real dsh, native children, and file tools. This mode does not validate real-model behavior.
|
package/cordis.patch.yml
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { settleRun } from '@deepseek-ai/dsh-subagent';
|
|
4
|
+
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
5
|
+
import Schema from '@deepseek-ai/schemastery';
|
|
6
|
+
import { parseDocument } from 'yaml';
|
|
7
|
+
export const name = 'dsh-subagent-filesystem';
|
|
8
|
+
export const inject = ['fs', 'tools', 'subagents', 'systemPrompt', 'sessionQuery'];
|
|
9
|
+
export const Config = Schema.object({
|
|
10
|
+
enabled: Schema.boolean().default(false),
|
|
11
|
+
root: Schema.string().default('agents'),
|
|
12
|
+
});
|
|
13
|
+
class DefinitionError extends Error {
|
|
14
|
+
}
|
|
15
|
+
function assertRole(value) {
|
|
16
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
17
|
+
throw new DefinitionError('Invalid role snapshot');
|
|
18
|
+
}
|
|
19
|
+
const { version, name, description, body, path } = value;
|
|
20
|
+
if (version !== 1)
|
|
21
|
+
throw new DefinitionError('Unsupported role snapshot version');
|
|
22
|
+
if (typeof name !== 'string' ||
|
|
23
|
+
!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(name) ||
|
|
24
|
+
name.length > 55) {
|
|
25
|
+
throw new DefinitionError('Expected a kebab-case name of at most 55 characters');
|
|
26
|
+
}
|
|
27
|
+
if (typeof description !== 'string' ||
|
|
28
|
+
!description.trim() ||
|
|
29
|
+
typeof body !== 'string' ||
|
|
30
|
+
!body.trim() ||
|
|
31
|
+
typeof path !== 'string' ||
|
|
32
|
+
!path) {
|
|
33
|
+
throw new DefinitionError('Expected a nonempty description, role body and definition path');
|
|
34
|
+
}
|
|
35
|
+
if (Buffer.byteLength(body) + Buffer.byteLength(description) > 1024 * 1024) {
|
|
36
|
+
throw new DefinitionError('Role definition exceeds 1 MiB');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function parseRole(text, path) {
|
|
40
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text);
|
|
41
|
+
if (!match)
|
|
42
|
+
throw new DefinitionError('Expected YAML frontmatter');
|
|
43
|
+
const doc = parseDocument(match[1]);
|
|
44
|
+
if (doc.errors.length)
|
|
45
|
+
throw new DefinitionError('Invalid YAML frontmatter');
|
|
46
|
+
const metadata = doc.toJS({ maxAliasCount: 0 });
|
|
47
|
+
if (!metadata || typeof metadata !== 'object' || Array.isArray(metadata)) {
|
|
48
|
+
throw new DefinitionError('Expected name and description');
|
|
49
|
+
}
|
|
50
|
+
if (Object.keys(metadata).some((key) => key !== 'name' && key !== 'description')) {
|
|
51
|
+
throw new DefinitionError('Only name and description are supported');
|
|
52
|
+
}
|
|
53
|
+
const { name, description } = metadata;
|
|
54
|
+
const body = text.slice(match[0].length).trim();
|
|
55
|
+
const role = { version: 1, name, description, body, path };
|
|
56
|
+
assertRole(role);
|
|
57
|
+
return { ...role, description: role.description.trim() };
|
|
58
|
+
}
|
|
59
|
+
export function apply(ctx, config) {
|
|
60
|
+
if (!config.enabled)
|
|
61
|
+
return;
|
|
62
|
+
if (!(config.root ?? 'agents').trim())
|
|
63
|
+
throw new Error('root must not be empty');
|
|
64
|
+
const lifecycle = new AbortController();
|
|
65
|
+
const delegation = new AsyncLocalStorage();
|
|
66
|
+
const registrations = new Map();
|
|
67
|
+
const children = new Map();
|
|
68
|
+
const pending = new Set();
|
|
69
|
+
function track(work) {
|
|
70
|
+
pending.add(work);
|
|
71
|
+
void work.finally(() => pending.delete(work)).catch(() => { });
|
|
72
|
+
return work;
|
|
73
|
+
}
|
|
74
|
+
const own = (agent, dispose) => {
|
|
75
|
+
const rows = registrations.get(agent) ?? [];
|
|
76
|
+
rows.push(dispose);
|
|
77
|
+
registrations.set(agent, rows);
|
|
78
|
+
};
|
|
79
|
+
const remove = (agent) => {
|
|
80
|
+
for (const dispose of registrations.get(agent) ?? [])
|
|
81
|
+
dispose();
|
|
82
|
+
registrations.delete(agent);
|
|
83
|
+
children.delete(agent);
|
|
84
|
+
};
|
|
85
|
+
// Verified against dsh-agent@0.2.0-rc.1: this serial event precedes the first prompt.
|
|
86
|
+
ctx.on('agent/created', ({ agent, source, signal }) => {
|
|
87
|
+
return track(initialize(agent, source, signal)).then(() => undefined, (error) => {
|
|
88
|
+
console.error('[dsh-subagent-filesystem] Child role initialization failed');
|
|
89
|
+
throw error;
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
ctx.on('agent/disposed', ({ agent }) => remove(agent));
|
|
93
|
+
ctx.effect(() => async () => {
|
|
94
|
+
lifecycle.abort();
|
|
95
|
+
await Promise.allSettled([...pending]);
|
|
96
|
+
const released = await Promise.allSettled([...children].map(([parent, ids]) => ctx.subagents.drainContinuableChildren(parent, ids)));
|
|
97
|
+
for (const result of released) {
|
|
98
|
+
if (result.status === 'rejected')
|
|
99
|
+
console.error('[dsh-subagent-filesystem] Child cleanup failed');
|
|
100
|
+
}
|
|
101
|
+
for (const agent of registrations.keys())
|
|
102
|
+
remove(agent);
|
|
103
|
+
});
|
|
104
|
+
async function initialize(agent, source, requestedSignal) {
|
|
105
|
+
const signal = AbortSignal.any([
|
|
106
|
+
lifecycle.signal,
|
|
107
|
+
...(requestedSignal ? [requestedSignal] : []),
|
|
108
|
+
]);
|
|
109
|
+
const inherited = delegation.getStore();
|
|
110
|
+
if (agent.session.header.parentSession) {
|
|
111
|
+
let role;
|
|
112
|
+
if (inherited?.parent.id === agent.session.header.parentSession) {
|
|
113
|
+
role = inherited.role;
|
|
114
|
+
agent.session.append('subagent-filesystem/role', role);
|
|
115
|
+
}
|
|
116
|
+
else if (source !== 'startup') {
|
|
117
|
+
const log = await agent.ctx.get('sessionQuery').readSession(agent.id);
|
|
118
|
+
for (const event of log.events.slice(log.inheritedEventCount)) {
|
|
119
|
+
if (event.type === 'subagent-filesystem/role') {
|
|
120
|
+
assertRole(event.data);
|
|
121
|
+
role = event.data;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const parent = ctx.get('agents')?.get(agent.session.header.parentSession);
|
|
125
|
+
if (role && parent) {
|
|
126
|
+
const ids = children.get(parent) ?? [];
|
|
127
|
+
if (!ids.includes(agent.id))
|
|
128
|
+
ids.push(agent.id);
|
|
129
|
+
children.set(parent, ids);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (role) {
|
|
133
|
+
signal.throwIfAborted();
|
|
134
|
+
own(agent, agent.ctx.get('systemPrompt').section({
|
|
135
|
+
name: 'subagent-filesystem:role',
|
|
136
|
+
order: agent.ctx.get('systemPrompt').getSectionOrder('DEPLOYMENT_PERSONA_PREFIX') + 1,
|
|
137
|
+
interpolate: false,
|
|
138
|
+
text: `${role.body}\n\nRole definition: ${JSON.stringify(role.path)}. Resolve supporting references and scripts relative to ${JSON.stringify(dirname(role.path))} in your filesystem.`,
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
const cwd = agent.session.header.cwd;
|
|
145
|
+
if (!cwd)
|
|
146
|
+
throw new Error('The agent needs a workspace directory');
|
|
147
|
+
const fs = agent.ctx.get('fs');
|
|
148
|
+
const root = await fs.resolve(config.root ?? 'agents', { cwd, signal });
|
|
149
|
+
const info = await fs.stat(root, signal);
|
|
150
|
+
if (!info)
|
|
151
|
+
return;
|
|
152
|
+
if (info.type !== 'directory')
|
|
153
|
+
throw new DefinitionError('root must be a directory');
|
|
154
|
+
const roles = [];
|
|
155
|
+
const names = new Set();
|
|
156
|
+
for (const entry of await fs.listDir(root, signal)) {
|
|
157
|
+
if (entry.type !== 'file' || !entry.name.endsWith('.md'))
|
|
158
|
+
continue;
|
|
159
|
+
if ((entry.size ?? 0) > 1024 * 1024)
|
|
160
|
+
throw new DefinitionError('Role file exceeds 1 MiB');
|
|
161
|
+
const bytes = await fs.readBytes(entry.target, signal, 1024 * 1024);
|
|
162
|
+
const text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
163
|
+
const role = parseRole(text, entry.target.displayPath);
|
|
164
|
+
const toolName = `subagent_${role.name.replaceAll('-', '_')}`;
|
|
165
|
+
if (names.has(toolName) || agent.ctx.get('tools').get(toolName, agent))
|
|
166
|
+
throw new DefinitionError('Duplicate role or tool name');
|
|
167
|
+
names.add(toolName);
|
|
168
|
+
roles.push(role);
|
|
169
|
+
}
|
|
170
|
+
signal.throwIfAborted();
|
|
171
|
+
for (const role of roles) {
|
|
172
|
+
own(agent, agent.ctx.get('tools').register(defineTool({
|
|
173
|
+
name: `subagent_${role.name.replaceAll('-', '_')}`,
|
|
174
|
+
description: `${role.description} Delegate a self-contained task to this specialist. Foreground calls return its report; background calls return a continuable child id.`,
|
|
175
|
+
parameters: {
|
|
176
|
+
prompt: {
|
|
177
|
+
type: 'string',
|
|
178
|
+
required: true,
|
|
179
|
+
description: 'The complete delegated task.',
|
|
180
|
+
},
|
|
181
|
+
description: { type: 'string', required: true, description: 'Short task label.' },
|
|
182
|
+
run_in_background: {
|
|
183
|
+
type: 'boolean',
|
|
184
|
+
description: 'Return a child id instead of waiting. Defaults to false; use send_message for follow-up.',
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
output: {
|
|
188
|
+
schema: { type: 'string' },
|
|
189
|
+
render: (_args, value) => [{ type: 'text', text: value }],
|
|
190
|
+
},
|
|
191
|
+
isConcurrencySafe: () => true,
|
|
192
|
+
async execute(args, exec) {
|
|
193
|
+
if (exec.agent !== agent)
|
|
194
|
+
throw new Error('Role belongs to a different agent');
|
|
195
|
+
const provider = agent.ctx.get('subagents').getProvider('spawn');
|
|
196
|
+
if (!provider?.prepareContinuable || provider.inheritsParentContext)
|
|
197
|
+
throw new Error('Roles require the native in-process spawn provider');
|
|
198
|
+
const signal = AbortSignal.any([exec.signal, lifecycle.signal]);
|
|
199
|
+
signal.throwIfAborted();
|
|
200
|
+
return track(delegation.run({ parent: agent, role }, async () => {
|
|
201
|
+
const request = {
|
|
202
|
+
parent: agent,
|
|
203
|
+
prompt: [{ type: 'text', text: args.prompt }],
|
|
204
|
+
maxDepth: agent.ctx.get('subagents').resolveMaxDepth(),
|
|
205
|
+
};
|
|
206
|
+
if (args.run_in_background) {
|
|
207
|
+
const child = await agent.ctx.get('subagents').startContinuable({
|
|
208
|
+
provider: 'spawn',
|
|
209
|
+
label: args.description,
|
|
210
|
+
request,
|
|
211
|
+
signal,
|
|
212
|
+
});
|
|
213
|
+
const ids = children.get(agent) ?? [];
|
|
214
|
+
ids.push(child.childId);
|
|
215
|
+
children.set(agent, ids);
|
|
216
|
+
return `started subagent ${child.childId}; use send_message to continue it`;
|
|
217
|
+
}
|
|
218
|
+
const outcome = await settleRun(await agent.ctx
|
|
219
|
+
.get('subagents')
|
|
220
|
+
.start('spawn', { ...request, label: args.description, signal }));
|
|
221
|
+
if (outcome.status !== 'completed')
|
|
222
|
+
throw new Error(outcome.detail ?? `Subagent ${outcome.status}`);
|
|
223
|
+
return outcome.result ?? '';
|
|
224
|
+
}));
|
|
225
|
+
},
|
|
226
|
+
})));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
remove(agent);
|
|
231
|
+
if (!signal.aborted)
|
|
232
|
+
console.error('[dsh-subagent-filesystem] Role discovery failed', error instanceof DefinitionError
|
|
233
|
+
? error.message
|
|
234
|
+
: error instanceof Error
|
|
235
|
+
? error.name
|
|
236
|
+
: 'Error');
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import Schema from '@deepseek-ai/schemastery';
|
|
3
|
+
export declare const name = "dsh-subagent-filesystem";
|
|
4
|
+
export declare const inject: string[];
|
|
5
|
+
export declare const Config: Schema<Schemastery.ObjectS<NoInfer<{
|
|
6
|
+
enabled: Schema<boolean, boolean, "defined">;
|
|
7
|
+
root: Schema<string, string, "defined">;
|
|
8
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
9
|
+
enabled: Schema<boolean, boolean, "defined">;
|
|
10
|
+
root: Schema<string, string, "defined">;
|
|
11
|
+
}>>, "plain">;
|
|
12
|
+
export interface Config {
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
root?: string;
|
|
15
|
+
}
|
|
16
|
+
interface Role {
|
|
17
|
+
version: 1;
|
|
18
|
+
name: string;
|
|
19
|
+
description: string;
|
|
20
|
+
body: string;
|
|
21
|
+
path: string;
|
|
22
|
+
}
|
|
23
|
+
declare module '@deepseek-ai/dsh-session' {
|
|
24
|
+
interface SessionEventMap {
|
|
25
|
+
'subagent-filesystem/role': Role;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
29
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,70 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amaster.ai/dsh-subagent-filesystem",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.23",
|
|
4
|
+
"description": "Discover Markdown specialist roles through the DSH filesystem and delegate through native in-process subagents.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/types/index.d.ts",
|
|
11
|
+
"default": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"lib",
|
|
17
|
+
"cordis.patch.yml",
|
|
18
|
+
"preview.png"
|
|
19
|
+
],
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/TGYD-helige/dsh-plugins.git",
|
|
27
|
+
"directory": "packages/dsh-subagent-filesystem"
|
|
28
|
+
},
|
|
29
|
+
"dsh": {
|
|
30
|
+
"bundle": {
|
|
31
|
+
"patch": "./cordis.patch.yml"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@deepseek-ai/schemastery": "^3.18.1",
|
|
36
|
+
"yaml": "^2.8.1"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@deepseek-ai/cordis": "^4.0.4",
|
|
40
|
+
"@deepseek-ai/dsh-agent": ">=0.2.0-rc.1",
|
|
41
|
+
"@deepseek-ai/dsh-fs": ">=0.2.0-rc.1",
|
|
42
|
+
"@deepseek-ai/dsh-session": ">=0.2.0-rc.1",
|
|
43
|
+
"@deepseek-ai/dsh-session-query": ">=0.2.0-rc.1",
|
|
44
|
+
"@deepseek-ai/dsh-subagent": ">=0.2.0-rc.1",
|
|
45
|
+
"@deepseek-ai/dsh-system-prompt": ">=0.2.0-rc.1",
|
|
46
|
+
"@deepseek-ai/dsh-tools": ">=0.2.0-rc.1"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@deepseek-ai/cordis": "^4.0.4",
|
|
50
|
+
"@deepseek-ai/dsh-agent": "0.2.0-rc.2",
|
|
51
|
+
"@deepseek-ai/dsh-fs": "0.2.0-rc.2",
|
|
52
|
+
"@deepseek-ai/dsh-session": "0.2.0-rc.2",
|
|
53
|
+
"@deepseek-ai/dsh-session-query": "0.2.0-rc.2",
|
|
54
|
+
"@deepseek-ai/dsh-subagent": "0.2.0-rc.2",
|
|
55
|
+
"@deepseek-ai/dsh-system-prompt": "0.2.0-rc.2",
|
|
56
|
+
"@deepseek-ai/dsh-tools": "0.2.0-rc.2",
|
|
57
|
+
"@deepseek-ai/dsh-scope": "0.2.0-rc.2",
|
|
58
|
+
"@types/node": "^22.0.0",
|
|
59
|
+
"typescript": "^5.6.3",
|
|
60
|
+
"vitest": "^4.1.11"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": "^20.19 || ^22.12 || >=24.0"
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"build": "tsc -p tsconfig.build.json",
|
|
67
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
68
|
+
"test": "vitest run"
|
|
69
|
+
}
|
|
6
70
|
}
|
package/preview.png
ADDED
|
Binary file
|