@dsh-cc/claude-code-agents 0.5.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.
- package/LICENSE +201 -0
- package/README.i18n.yaml +6 -0
- package/README.md +28 -0
- package/README.zh.md +28 -0
- package/lib/bundled/dsh-cc-guide.d.ts +4 -0
- package/lib/bundled/dsh-cc-guide.d.ts.map +1 -0
- package/lib/bundled/dsh-cc-guide.js +26 -0
- package/lib/bundled/dsh-cc-guide.js.map +1 -0
- package/lib/bundled/explore.d.ts +4 -0
- package/lib/bundled/explore.d.ts.map +1 -0
- package/lib/bundled/explore.js +28 -0
- package/lib/bundled/explore.js.map +1 -0
- package/lib/bundled/index.d.ts +23 -0
- package/lib/bundled/index.d.ts.map +1 -0
- package/lib/bundled/index.js +31 -0
- package/lib/bundled/index.js.map +1 -0
- package/lib/discovery.d.ts +56 -0
- package/lib/discovery.d.ts.map +1 -0
- package/lib/discovery.js +117 -0
- package/lib/discovery.js.map +1 -0
- package/lib/index.d.ts +45 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +40 -0
- package/lib/index.js.map +1 -0
- package/lib/invariant.d.ts +16 -0
- package/lib/invariant.d.ts.map +1 -0
- package/lib/invariant.js +22 -0
- package/lib/invariant.js.map +1 -0
- package/lib/parse.d.ts +51 -0
- package/lib/parse.d.ts.map +1 -0
- package/lib/parse.js +236 -0
- package/lib/parse.js.map +1 -0
- package/lib/restrict.d.ts +42 -0
- package/lib/restrict.d.ts.map +1 -0
- package/lib/restrict.js +78 -0
- package/lib/restrict.js.map +1 -0
- package/lib/types.d.ts +94 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +34 -0
- package/lib/types.js.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/preset/claude-code-agents/README.md
|
|
5
|
+
README.md: aab03facfa4342a70f5995a2a3eb75c854fa9f62
|
|
6
|
+
README.zh.md: 1fde8ca08c577afbae6f6e3ecf145fc3d62607ea
|
package/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# dsh-claude-code-agents
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
Load Claude Code's `.claude/agents/*.md` and `*.json` sub-agent definitions as dsh agent presets. The package is a pure, filesystem-backed translation: it discovers the bundled, user, and project layers, parses and validates each agent file, and returns one typed [`AgentDefinition`](./src/types.ts) per agent — no harness runtime is involved, so the loader can be reused by a Claude Code plugin loader alongside this preset package and consumed however a deployment wires it up.
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
- **Three layers, highest wins.** The bundled layer ships in-package utility agents (`explore` and `dsh-cc-guide`, both pinning `model: haiku` with a Read/Glob/Grep allow-list) via `discoverBundledAgents()`. The project layer is the nearest `.claude/agents` directory found by walking up from the project root; the user layer is the author's own `~/.claude/agents`. A definition is keyed by its file basename, and layers shadow by rank — bundled < user < project — so a local file of the same name always overrides its bundled namesake.
|
|
10
|
+
- **Two formats.** A `.md` file's YAML frontmatter supplies the fields and its markdown body (or the `prompt` frontmatter override) supplies the system prompt. A `.json` file is a single object whose `prompt` field is the system prompt.
|
|
11
|
+
- **Loud failures.** Every bad known frontmatter value throws at load time with the file path and field name, so a broken agent is fixed rather than silently degraded. Unknown fields are ignored, so a definition authored against a newer Claude Code release ports to the supported subset.
|
|
12
|
+
- **Field translation.** `description` becomes the when-to-use guide; `tools`/`disallowedTools` compile to one effective `allow`/`deny` tool restriction whose names intersect (a name in both lists is denied); `model` (with the `inherit` sentinel normalized), `effort`, `permissionMode`, `maxTurns`, `initialPrompt`, `background`, `memory`, `skills`, `mcpServers`, `hooks`, and `isolation` are all carried through — and `background` is no longer inert: the Task tool honors it (backgrounds on omitted `run_in_background`).
|
|
13
|
+
|
|
14
|
+
## API
|
|
15
|
+
|
|
16
|
+
- `loadClaudeCodeAgents(root, options?): Promise<AgentDefinition[]>` The project layer resolved by walking up from `root`, shadowing the user layer; `options.userDir` overrides the user `.claude/agents` directory (useful for a harness with a non-default home and for hermetic tests). Throws on the first unparsable agent file.
|
|
17
|
+
- `parseAgentMarkdown(path, text, source): AgentDefinition` and `parseAgentJson(path, text, source): AgentDefinition` Parse one in-memory file; useful for unit tests and non-directory inputs.
|
|
18
|
+
- `splitFrontmatter(text): ParsedMarkdown` Split the leading YAML block out of a markdown string.
|
|
19
|
+
- `discoverBundledAgents(): AgentDefinition[]` The in-package bundled agent set (`source: 'bundled'`); a bundled document that fails to parse throws, like any broken agent file.
|
|
20
|
+
- `discoverAgents(projectRoot, userDir?): Promise<AgentDefinition[]>` The layer merge without the home-dir default.
|
|
21
|
+
- `loadAgentsDir(dir, source): Promise<AgentDefinition[]>` and `findProjectAgentsDir(start): Promise<string | undefined>` The per-directory scan and the upward walk.
|
|
22
|
+
- `resolveToolRestriction(tools, disallowedTools): ToolRestriction | undefined` and `normalizeModel(model): string | undefined` The pure restriction-merge and model-normalization helpers, exported for reuse and for testing.
|
|
23
|
+
|
|
24
|
+
`AgentDefinition` carries `agentType` (the file basename), `whenToUse`, `systemPrompt`, `source` (`user` | `project` | `bundled`), `baseDir`, `filename`, and the translated optional fields. The `toolRestriction` value is structurally identical to [`dsh-tools`](../../core/tools/README.md)'s `ToolRestriction`, so a consumer can hand it to a scoped `ctx.tools.restrict()` unchanged.
|
|
25
|
+
|
|
26
|
+
## Design
|
|
27
|
+
|
|
28
|
+
The loader is deliberately integration-free. It produces typed definitions and leaves consumption — a scoped tool restriction, a request rewrite, a permission selection — to the caller, so the model-facing parts stay reusable without dragging in the harness runtime. This mirrors [`agent-presets`](../../preset/agent-presets/README.md)'s philosophy of a self-contained vocabulary feeding an explicit consumer, rather than hiding a defaulting step inside the loader.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# dsh-claude-code-agents
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
将 Claude Code 的 `.claude/agents/*.md` 与 `*.json` 子 agent 定义加载为 dsh agent preset。本包是一个纯文件系统驱动的翻译层:它发现 bundled、user 与 project 三层、解析并校验每个 agent 文件,并为每个 agent 返回一个类型化的 [`AgentDefinition`](./src/types.ts) ——不涉及 harness 运行时,因此该 loader 既可以与这个 preset 包一同被 Claude Code 插件 loader 复用,也可以由任何部署以任意方式接入消费。
|
|
6
|
+
|
|
7
|
+
## 作用
|
|
8
|
+
|
|
9
|
+
- **三层,高者优先。** bundled 层随包内置工具 agent(`explore` 与 `dsh-cc-guide`,均钉死 `model: haiku` 并带 Read/Glob/Grep 白名单),经 `discoverBundledAgents()` 提供。project 层是从项目根向上遍历找到的最近的 `.claude/agents` 目录;user 层是作者自己的 `~/.claude/agents`。定义以其文件 basename 为键,各层按级别遮蔽——bundled < user < project——同名本地文件总是覆盖其 bundled 同名者。
|
|
10
|
+
- **两种格式。** `.md` 文件的 YAML frontmatter 提供字段,其 markdown 正文(或 `prompt` frontmatter 覆写)提供系统提示。`.json` 文件是单个对象,其 `prompt` 字段即系统提示。
|
|
11
|
+
- **响亮失败。** 每个坏掉的已知 frontmatter 值都会在加载期带着文件路径与字段名抛错,因此坏 agent 会被修复而非静默降级。未知字段被忽略,因此针对更新版本 Claude Code 编写的定义可移植到受支持子集。
|
|
12
|
+
- **字段翻译。** `description` 成为 when-to-use 指南;`tools`/`disallowedTools` 编译为单个有效的 `allow`/`deny` 工具约束,其名称求交集(同时出现在两个列表中的名称被禁用);`model`(含归一化的 `inherit` 哨兵)、`effort`、`permissionMode`、`maxTurns`、`initialPrompt`、`background`、`memory`、`skills`、`mcpServers`、`hooks` 与 `isolation` 全部透传——且 `background` 不再是死字段:Task 工具会兑现它(在 `run_in_background` 缺省时转后台)。
|
|
13
|
+
|
|
14
|
+
## API
|
|
15
|
+
|
|
16
|
+
- `loadClaudeCodeAgents(root, options?): Promise<AgentDefinition[]>` 从 `root` 向上遍历解析 project 层,遮蔽 user 层;`options.userDir` 覆写 user 的 `.claude/agents` 目录(对非默认 home 的 harness 与密封测试均有意义)。遇到第一个不可解析的 agent 文件即抛错。
|
|
17
|
+
- `parseAgentMarkdown(path, text, source): AgentDefinition` 与 `parseAgentJson(path, text, source): AgentDefinition` 解析单个内存中的文件;适用于单元测试与非目录输入。
|
|
18
|
+
- `splitFrontmatter(text): ParsedMarkdown` 从 markdown 字符串中切出开头的 YAML 块。
|
|
19
|
+
- `discoverBundledAgents(): AgentDefinition[]` 随包内置的 agent 集合(`source: 'bundled'`);bundled 文档解析失败即抛错,与任何坏掉的 agent 文件一致。
|
|
20
|
+
- `discoverAgents(projectRoot, userDir?): Promise<AgentDefinition[]>` 不含 home 目录默认值的层合并。
|
|
21
|
+
- `loadAgentsDir(dir, source): Promise<AgentDefinition[]>` 与 `findProjectAgentsDir(start): Promise<string | undefined>` 按目录扫描与向上遍历。
|
|
22
|
+
- `resolveToolRestriction(tools, disallowedTools): ToolRestriction | undefined` 与 `normalizeModel(model): string | undefined` 纯约束合并与模型归一化辅助函数,导出以供复用与测试。
|
|
23
|
+
|
|
24
|
+
`AgentDefinition` 携带 `agentType`(文件 basename)、`whenToUse`、`systemPrompt`、`source`(`user` | `project` | `bundled`)、`baseDir`、`filename`,以及翻译后的可选字段。`toolRestriction` 值在结构上与 [`dsh-tools`](../../core/tools/README.md) 的 `ToolRestriction` 完全一致,因此消费方可以原样将其交给有作用域的 `ctx.tools.restrict()`。
|
|
25
|
+
|
|
26
|
+
## 设计
|
|
27
|
+
|
|
28
|
+
该 loader 刻意与集成解耦。它产出类型化定义并将消费——作用域工具约束、请求改写、权限选择——交给调用方,因此模型侧各部分无需拖入 harness 运行时即可复用。这与 [`agent-presets`](../../preset/agent-presets/README.md) 的理念一致:自包含词表喂给显式消费方,而不是在 loader 内部隐藏默认步骤。
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The bundled `dsh-cc-guide` agent, authored as a Claude Code agent markdown. */
|
|
2
|
+
export declare const name = "dsh-cc-guide";
|
|
3
|
+
export declare const AGENT_MD = "---\nname: dsh-cc-guide\ndescription: Answers questions about dsh-cc (the Claude Code compatibility layer on DeepSeek Harness) \u2014 commands, tools, settings, known limits. Not a coding agent.\nmodel: haiku\ntools: [Read, Glob, Grep]\n---\n\nYou are a product-docs assistant for **dsh-cc**, not Claude Code and not the user's application.\n\n## Your strengths\n- Grounding answers in the repo's own docs\n- Saying \"I don't know\" when the tree has no evidence\n- Distinguishing implemented / partial / missing / won't-port rows\n\n## How to work\n1. Read before answering. Prefer `docs/cc-parity-matrix.md`, package READMEs, and `packages/preset/cc/agent.cordis.yml`.\n2. Do not invent features. If a parity-matrix row is \uD83D\uDD36 / \u274C / \uD83D\uDEAB, say so.\n3. Quote the file path you used.\n4. Never edit the user's application.\n\n## Output contract\nShort factual answers. Cite the doc path. \"I don't know\" when the tree has no evidence.\n";
|
|
4
|
+
//# sourceMappingURL=dsh-cc-guide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dsh-cc-guide.d.ts","sourceRoot":"","sources":["../../src/bundled/dsh-cc-guide.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAElF,eAAO,MAAM,IAAI,iBAAiB,CAAA;AAElC,eAAO,MAAM,QAAQ,m8BAsBpB,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** The bundled `dsh-cc-guide` agent, authored as a Claude Code agent markdown. */
|
|
2
|
+
export const name = 'dsh-cc-guide';
|
|
3
|
+
export const AGENT_MD = `---
|
|
4
|
+
name: dsh-cc-guide
|
|
5
|
+
description: Answers questions about dsh-cc (the Claude Code compatibility layer on DeepSeek Harness) — commands, tools, settings, known limits. Not a coding agent.
|
|
6
|
+
model: haiku
|
|
7
|
+
tools: [Read, Glob, Grep]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are a product-docs assistant for **dsh-cc**, not Claude Code and not the user's application.
|
|
11
|
+
|
|
12
|
+
## Your strengths
|
|
13
|
+
- Grounding answers in the repo's own docs
|
|
14
|
+
- Saying "I don't know" when the tree has no evidence
|
|
15
|
+
- Distinguishing implemented / partial / missing / won't-port rows
|
|
16
|
+
|
|
17
|
+
## How to work
|
|
18
|
+
1. Read before answering. Prefer \`docs/cc-parity-matrix.md\`, package READMEs, and \`packages/preset/cc/agent.cordis.yml\`.
|
|
19
|
+
2. Do not invent features. If a parity-matrix row is 🔶 / ❌ / 🚫, say so.
|
|
20
|
+
3. Quote the file path you used.
|
|
21
|
+
4. Never edit the user's application.
|
|
22
|
+
|
|
23
|
+
## Output contract
|
|
24
|
+
Short factual answers. Cite the doc path. "I don't know" when the tree has no evidence.
|
|
25
|
+
`;
|
|
26
|
+
//# sourceMappingURL=dsh-cc-guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dsh-cc-guide.js","sourceRoot":"","sources":["../../src/bundled/dsh-cc-guide.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAElF,MAAM,CAAC,MAAM,IAAI,GAAG,cAAc,CAAA;AAElC,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBvB,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The bundled `explore` agent, authored as a Claude Code agent markdown. */
|
|
2
|
+
export declare const name = "explore";
|
|
3
|
+
export declare const AGENT_MD = "---\nname: explore\ndescription: Fast, read-only codebase scout. Use for \"where is X?\", \"find files matching\", \"what calls this\". Returns paths and line numbers, not implementations.\nmodel: haiku\ntools: [Read, Glob, Grep, mcp__serena__find_symbol, mcp__serena__find_referencing_symbols, mcp__serena__get_symbols_overview]\n---\n\nYou are a fast, read-only codebase scout.\n\n## Your strengths\n- Thorough file search with glob and grep before reading\n- Serena symbol retrieval for definition/reference questions\n- Reporting exact paths and line numbers\n- Staying inside the question; no speculative refactors\n\n## How to work\n1. Never edit, write, or run shell commands. Never spawn Task.\n2. Symbol questions (where is X defined, what calls this, file structure): use serena `find_symbol` / `find_referencing_symbols` / `get_symbols_overview` first. Text patterns (config keys, comments, strings, file names): grep/glob.\n3. An empty serena result is NOT proof of absence \u2014 probe once with grep before concluding \"not found\". If serena tools error repeatedly, fall back to Grep/Glob and say so in your report.\n4. Prefer grep and glob; read a file only to confirm a hit.\n5. Cap excerpts; quote the smallest unique snippet.\n\n## Output contract\nA bullet list of `path:line` hits plus a 1\u20133 sentence synthesis. If nothing matches, say so and list what was searched.\n";
|
|
4
|
+
//# sourceMappingURL=explore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore.d.ts","sourceRoot":"","sources":["../../src/bundled/explore.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,eAAO,MAAM,IAAI,YAAY,CAAA;AAE7B,eAAO,MAAM,QAAQ,u3CAwBpB,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** The bundled `explore` agent, authored as a Claude Code agent markdown. */
|
|
2
|
+
export const name = 'explore';
|
|
3
|
+
export const AGENT_MD = `---
|
|
4
|
+
name: explore
|
|
5
|
+
description: Fast, read-only codebase scout. Use for "where is X?", "find files matching", "what calls this". Returns paths and line numbers, not implementations.
|
|
6
|
+
model: haiku
|
|
7
|
+
tools: [Read, Glob, Grep, mcp__serena__find_symbol, mcp__serena__find_referencing_symbols, mcp__serena__get_symbols_overview]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are a fast, read-only codebase scout.
|
|
11
|
+
|
|
12
|
+
## Your strengths
|
|
13
|
+
- Thorough file search with glob and grep before reading
|
|
14
|
+
- Serena symbol retrieval for definition/reference questions
|
|
15
|
+
- Reporting exact paths and line numbers
|
|
16
|
+
- Staying inside the question; no speculative refactors
|
|
17
|
+
|
|
18
|
+
## How to work
|
|
19
|
+
1. Never edit, write, or run shell commands. Never spawn Task.
|
|
20
|
+
2. Symbol questions (where is X defined, what calls this, file structure): use serena \`find_symbol\` / \`find_referencing_symbols\` / \`get_symbols_overview\` first. Text patterns (config keys, comments, strings, file names): grep/glob.
|
|
21
|
+
3. An empty serena result is NOT proof of absence — probe once with grep before concluding "not found". If serena tools error repeatedly, fall back to Grep/Glob and say so in your report.
|
|
22
|
+
4. Prefer grep and glob; read a file only to confirm a hit.
|
|
23
|
+
5. Cap excerpts; quote the smallest unique snippet.
|
|
24
|
+
|
|
25
|
+
## Output contract
|
|
26
|
+
A bullet list of \`path:line\` hits plus a 1–3 sentence synthesis. If nothing matches, say so and list what was searched.
|
|
27
|
+
`;
|
|
28
|
+
//# sourceMappingURL=explore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore.js","sourceRoot":"","sources":["../../src/bundled/explore.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,MAAM,CAAC,MAAM,IAAI,GAAG,SAAS,CAAA;AAE7B,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwBvB,CAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundled agents shipped with this compatible provider.
|
|
3
|
+
*
|
|
4
|
+
* A small set of read-only utility agents modeled on Claude Code's built-in
|
|
5
|
+
* sub-agents (the Explore scout and a product-docs guide), authored as
|
|
6
|
+
* Claude Code agent markdown and served directly from this package — no disk
|
|
7
|
+
* extraction. They are provided with `source: 'bundled'`, the lowest rank of
|
|
8
|
+
* the {@link AgentSource} precedence: a user-layer or project-layer
|
|
9
|
+
* `.claude/agents` file of the same name shadows its bundled namesake,
|
|
10
|
+
* matching Claude Code's precedence where local agents override built-ins.
|
|
11
|
+
*
|
|
12
|
+
* @module @dsh-cc/claude-code-agents/bundled
|
|
13
|
+
*/
|
|
14
|
+
import type { AgentDefinition } from '../types.ts';
|
|
15
|
+
/**
|
|
16
|
+
* Parse the in-package bundled agent set. A document that fails to parse
|
|
17
|
+
* throws — the same loud failure a broken project agent gets, since a bundled
|
|
18
|
+
* agent shipping malformed frontmatter is a package bug, not a user error.
|
|
19
|
+
* @returns one definition per bundled agent, in declaration order.
|
|
20
|
+
* @throws when a bundled document cannot be parsed.
|
|
21
|
+
*/
|
|
22
|
+
export declare function discoverBundledAgents(): AgentDefinition[];
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bundled/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AASlD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,EAAE,CAGzD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundled agents shipped with this compatible provider.
|
|
3
|
+
*
|
|
4
|
+
* A small set of read-only utility agents modeled on Claude Code's built-in
|
|
5
|
+
* sub-agents (the Explore scout and a product-docs guide), authored as
|
|
6
|
+
* Claude Code agent markdown and served directly from this package — no disk
|
|
7
|
+
* extraction. They are provided with `source: 'bundled'`, the lowest rank of
|
|
8
|
+
* the {@link AgentSource} precedence: a user-layer or project-layer
|
|
9
|
+
* `.claude/agents` file of the same name shadows its bundled namesake,
|
|
10
|
+
* matching Claude Code's precedence where local agents override built-ins.
|
|
11
|
+
*
|
|
12
|
+
* @module @dsh-cc/claude-code-agents/bundled
|
|
13
|
+
*/
|
|
14
|
+
import { parseAgentMarkdown } from "../parse.js";
|
|
15
|
+
import { AGENT_MD as GUIDE_MD, name as guideName } from "./dsh-cc-guide.js";
|
|
16
|
+
import { AGENT_MD as EXPLORE_MD, name as exploreName } from "./explore.js";
|
|
17
|
+
const ENTRIES = [
|
|
18
|
+
{ name: exploreName, md: EXPLORE_MD },
|
|
19
|
+
{ name: guideName, md: GUIDE_MD },
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Parse the in-package bundled agent set. A document that fails to parse
|
|
23
|
+
* throws — the same loud failure a broken project agent gets, since a bundled
|
|
24
|
+
* agent shipping malformed frontmatter is a package bug, not a user error.
|
|
25
|
+
* @returns one definition per bundled agent, in declaration order.
|
|
26
|
+
* @throws when a bundled document cannot be parsed.
|
|
27
|
+
*/
|
|
28
|
+
export function discoverBundledAgents() {
|
|
29
|
+
return ENTRIES.map(({ name, md }) => parseAgentMarkdown(`bundled:${name}/${name}.md`, md, 'bundled'));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bundled/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,EAAE,QAAQ,IAAI,QAAQ,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC3E,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1E,MAAM,OAAO,GAA8D;IACzE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE;IACrC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE;CAClC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAClC,kBAAkB,CAAC,WAAW,IAAI,IAAI,IAAI,KAAK,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAA;AACpE,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discover Claude Code agent definition files across the bundled, user, and
|
|
3
|
+
* project layers and load each into an {@link AgentDefinition}.
|
|
4
|
+
*
|
|
5
|
+
* The project layer is the nearest `.claude/agents` directory found by walking
|
|
6
|
+
* up from the project root (a `.claude` directory at any ancestor defines the
|
|
7
|
+
* project scope, exactly as Claude Code resolves it). The user layer is the
|
|
8
|
+
* author's own `~/.claude/agents`. A definition is keyed by its file basename;
|
|
9
|
+
* the layers shadow by rank — bundled (in-package, always present) is lowest,
|
|
10
|
+
* the user layer shadows bundled, and the project layer SHADOWS the user layer
|
|
11
|
+
* on a name collision (nearest wins), mirroring how a project-level agent
|
|
12
|
+
* overrides a user-level one and either overrides a built-in.
|
|
13
|
+
*
|
|
14
|
+
* Every file that looks like an agent (a `.md` or `.json` in either directory)
|
|
15
|
+
* is loaded, and a file that fails to parse raises — discovery is intentionally
|
|
16
|
+
* loud rather than silent, so a broken agent is fixed, not forgotten. Unknown
|
|
17
|
+
* files in the same directory are skipped.
|
|
18
|
+
*
|
|
19
|
+
* @module @dsh-cc/claude-code-agents/discovery
|
|
20
|
+
*/
|
|
21
|
+
import type { AgentDefinition, AgentSource } from './types.ts';
|
|
22
|
+
/** The Claude Code agents directory name inside `.claude`. */
|
|
23
|
+
export declare const AGENTS_DIR = "agents";
|
|
24
|
+
/** The `.claude` directory name beneath a project or the user home. */
|
|
25
|
+
export declare const CLAUDE_DIR = ".claude";
|
|
26
|
+
/**
|
|
27
|
+
* Resolve the nearest `.claude/agents` directory by walking upward from
|
|
28
|
+
* `start`, or the user `.claude/agents` when given as the user source.
|
|
29
|
+
* @param start - the directory to begin the upward walk from.
|
|
30
|
+
* @returns the resolved agent directory path, or `undefined` when no ancestor
|
|
31
|
+
* owns a `.claude/agents` directory.
|
|
32
|
+
*/
|
|
33
|
+
export declare function findProjectAgentsDir(start: string): Promise<string | undefined>;
|
|
34
|
+
/**
|
|
35
|
+
* Read and parse every agent file in one `.claude/agents` directory.
|
|
36
|
+
* @param dir - the `.claude/agents` directory to scan.
|
|
37
|
+
* @param source - the layer the directory belongs to.
|
|
38
|
+
* @returns one agent per `.md`/`.json` file, ordered by filename (`.md` then
|
|
39
|
+
* `.json`, each alphabetical).
|
|
40
|
+
* @throws when a file exists but cannot be read or parsed.
|
|
41
|
+
*/
|
|
42
|
+
export declare function loadAgentsDir(dir: string, source: AgentSource): Promise<AgentDefinition[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Load every agent definition visible from a project root: the project layer
|
|
45
|
+
* (nearest `.claude/agents` walking up) shadowing the user layer
|
|
46
|
+
* (`~/.claude/agents`), both shadowing the bundled in-package agents. A file
|
|
47
|
+
* that fails to parse throws; the caller keeps the project root and user home
|
|
48
|
+
* that produced a failure.
|
|
49
|
+
* @param projectRoot - the project directory to resolve the project layer from.
|
|
50
|
+
* @param userDir - the user `.claude/agents` directory; `undefined` to skip the
|
|
51
|
+
* user layer (used by callers that pass an explicit home).
|
|
52
|
+
* @returns the merged agent list, project shadowing user shadowing bundled.
|
|
53
|
+
* @throws when a discovered agent file cannot be parsed.
|
|
54
|
+
*/
|
|
55
|
+
export declare function discoverAgents(projectRoot: string, userDir?: string): Promise<AgentDefinition[]>;
|
|
56
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE9D,8DAA8D;AAC9D,eAAO,MAAM,UAAU,WAAW,CAAA;AAElC,uEAAuE;AACvE,eAAO,MAAM,UAAU,YAAY,CAAA;AAMnC;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAUrF;AAWD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAqBhG;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,EAAE,CAAC,CAU5B"}
|
package/lib/discovery.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discover Claude Code agent definition files across the bundled, user, and
|
|
3
|
+
* project layers and load each into an {@link AgentDefinition}.
|
|
4
|
+
*
|
|
5
|
+
* The project layer is the nearest `.claude/agents` directory found by walking
|
|
6
|
+
* up from the project root (a `.claude` directory at any ancestor defines the
|
|
7
|
+
* project scope, exactly as Claude Code resolves it). The user layer is the
|
|
8
|
+
* author's own `~/.claude/agents`. A definition is keyed by its file basename;
|
|
9
|
+
* the layers shadow by rank — bundled (in-package, always present) is lowest,
|
|
10
|
+
* the user layer shadows bundled, and the project layer SHADOWS the user layer
|
|
11
|
+
* on a name collision (nearest wins), mirroring how a project-level agent
|
|
12
|
+
* overrides a user-level one and either overrides a built-in.
|
|
13
|
+
*
|
|
14
|
+
* Every file that looks like an agent (a `.md` or `.json` in either directory)
|
|
15
|
+
* is loaded, and a file that fails to parse raises — discovery is intentionally
|
|
16
|
+
* loud rather than silent, so a broken agent is fixed, not forgotten. Unknown
|
|
17
|
+
* files in the same directory are skipped.
|
|
18
|
+
*
|
|
19
|
+
* @module @dsh-cc/claude-code-agents/discovery
|
|
20
|
+
*/
|
|
21
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
22
|
+
import { join, dirname } from 'node:path';
|
|
23
|
+
import { discoverBundledAgents } from "./bundled/index.js";
|
|
24
|
+
import { parseAgentJson, parseAgentMarkdown } from "./parse.js";
|
|
25
|
+
/** The Claude Code agents directory name inside `.claude`. */
|
|
26
|
+
export const AGENTS_DIR = 'agents';
|
|
27
|
+
/** The `.claude` directory name beneath a project or the user home. */
|
|
28
|
+
export const CLAUDE_DIR = '.claude';
|
|
29
|
+
/** The supported agent-definition file suffixes, saturated or `.md`. */
|
|
30
|
+
const MARKDOWN_SUFFIX = '.md';
|
|
31
|
+
const JSON_SUFFIX = '.json';
|
|
32
|
+
/**
|
|
33
|
+
* Resolve the nearest `.claude/agents` directory by walking upward from
|
|
34
|
+
* `start`, or the user `.claude/agents` when given as the user source.
|
|
35
|
+
* @param start - the directory to begin the upward walk from.
|
|
36
|
+
* @returns the resolved agent directory path, or `undefined` when no ancestor
|
|
37
|
+
* owns a `.claude/agents` directory.
|
|
38
|
+
*/
|
|
39
|
+
export async function findProjectAgentsDir(start) {
|
|
40
|
+
let current = start;
|
|
41
|
+
// eslint-disable-next-line no-constant-condition
|
|
42
|
+
while (true) {
|
|
43
|
+
const candidate = join(current, CLAUDE_DIR, AGENTS_DIR);
|
|
44
|
+
if (await isDirectory(candidate))
|
|
45
|
+
return candidate;
|
|
46
|
+
const parent = dirname(current);
|
|
47
|
+
if (parent === current)
|
|
48
|
+
return undefined;
|
|
49
|
+
current = parent;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Whether `path` names an existing directory. */
|
|
53
|
+
async function isDirectory(path) {
|
|
54
|
+
try {
|
|
55
|
+
return (await stat(path)).isDirectory();
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Read and parse every agent file in one `.claude/agents` directory.
|
|
63
|
+
* @param dir - the `.claude/agents` directory to scan.
|
|
64
|
+
* @param source - the layer the directory belongs to.
|
|
65
|
+
* @returns one agent per `.md`/`.json` file, ordered by filename (`.md` then
|
|
66
|
+
* `.json`, each alphabetical).
|
|
67
|
+
* @throws when a file exists but cannot be read or parsed.
|
|
68
|
+
*/
|
|
69
|
+
export async function loadAgentsDir(dir, source) {
|
|
70
|
+
let entries;
|
|
71
|
+
try {
|
|
72
|
+
entries = await readdir(dir);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// An absent or unreadable directory supplies no agents; the caller decides
|
|
76
|
+
// whether that is an error (a configured project layer usually is not).
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
const names = entries
|
|
80
|
+
.filter(name => name.endsWith(MARKDOWN_SUFFIX) || name.endsWith(JSON_SUFFIX))
|
|
81
|
+
.sort();
|
|
82
|
+
const agents = [];
|
|
83
|
+
for (const name of names) {
|
|
84
|
+
const path = join(dir, name);
|
|
85
|
+
const text = await readFile(path, 'utf8');
|
|
86
|
+
agents.push(name.endsWith(JSON_SUFFIX)
|
|
87
|
+
? parseAgentJson(path, text, source)
|
|
88
|
+
: parseAgentMarkdown(path, text, source));
|
|
89
|
+
}
|
|
90
|
+
return agents;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Load every agent definition visible from a project root: the project layer
|
|
94
|
+
* (nearest `.claude/agents` walking up) shadowing the user layer
|
|
95
|
+
* (`~/.claude/agents`), both shadowing the bundled in-package agents. A file
|
|
96
|
+
* that fails to parse throws; the caller keeps the project root and user home
|
|
97
|
+
* that produced a failure.
|
|
98
|
+
* @param projectRoot - the project directory to resolve the project layer from.
|
|
99
|
+
* @param userDir - the user `.claude/agents` directory; `undefined` to skip the
|
|
100
|
+
* user layer (used by callers that pass an explicit home).
|
|
101
|
+
* @returns the merged agent list, project shadowing user shadowing bundled.
|
|
102
|
+
* @throws when a discovered agent file cannot be parsed.
|
|
103
|
+
*/
|
|
104
|
+
export async function discoverAgents(projectRoot, userDir) {
|
|
105
|
+
const projectDir = await findProjectAgentsDir(projectRoot);
|
|
106
|
+
const project = projectDir === undefined ? [] : await loadAgentsDir(projectDir, 'project');
|
|
107
|
+
const user = userDir === undefined ? [] : await loadAgentsDir(userDir, 'user');
|
|
108
|
+
const byName = new Map();
|
|
109
|
+
for (const agent of discoverBundledAgents())
|
|
110
|
+
byName.set(agent.agentType, agent);
|
|
111
|
+
for (const agent of user)
|
|
112
|
+
byName.set(agent.agentType, agent);
|
|
113
|
+
for (const agent of project)
|
|
114
|
+
byName.set(agent.agentType, agent);
|
|
115
|
+
return Array.from(byName.values());
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|