@bossmissing/agent-meta 0.1.0 → 0.3.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/README.md +61 -2
- package/assets/skills/deploy-ansible/deploy-ansible/SKILL.md +71 -0
- package/assets/skills/deploy-cloudflare/deploy-cloudflare/SKILL.md +51 -0
- package/assets/skills/deploy-github-actions/deploy-github-actions/SKILL.md +50 -0
- package/assets/skills/ironbank/ironbank-citations/SKILL.md +197 -0
- package/assets/skills/ironbank/ironbank-docs-research/SKILL.md +205 -0
- package/assets/skills/ironbank/ironbank-mcp-reference/SKILL.md +414 -0
- package/assets/skills/ironbank/ironbank-note-links/SKILL.md +87 -0
- package/dist/cli.js +74 -2
- package/dist/commands/config.d.ts +5 -0
- package/dist/commands/config.js +50 -0
- package/dist/commands/doctor.d.ts +14 -0
- package/dist/commands/doctor.js +187 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +57 -1
- package/dist/commands/new-adr.js +2 -1
- package/dist/commands/new-change.d.ts +12 -0
- package/dist/commands/new-change.js +125 -0
- package/dist/commands/new-domain.js +2 -0
- package/dist/commands/preflight.d.ts +14 -0
- package/dist/commands/preflight.js +103 -0
- package/dist/commands/review.d.ts +18 -0
- package/dist/commands/review.js +102 -0
- package/dist/commands/sync.js +11 -2
- package/dist/core/checklist.d.ts +31 -0
- package/dist/core/checklist.js +43 -0
- package/dist/core/deploy-packs.d.ts +11 -0
- package/dist/core/deploy-packs.js +42 -0
- package/dist/core/doc-scopes.d.ts +18 -0
- package/dist/core/doc-scopes.js +55 -0
- package/dist/core/filesystem.js +9 -1
- package/dist/core/frontmatter.d.ts +7 -0
- package/dist/core/frontmatter.js +45 -9
- package/dist/core/mcp-packs.d.ts +26 -0
- package/dist/core/mcp-packs.js +86 -0
- package/dist/generators/adr-generator.js +3 -1
- package/dist/generators/hook-generator.d.ts +14 -0
- package/dist/generators/hook-generator.js +55 -0
- package/dist/generators/index-generator.d.ts +2 -2
- package/dist/generators/index-generator.js +15 -8
- package/dist/generators/mcp-generator.d.ts +9 -0
- package/dist/generators/mcp-generator.js +68 -0
- package/dist/schemas/config.schema.d.ts +0 -10
- package/dist/schemas/config.schema.js +0 -2
- package/dist/templates/index.d.ts +7 -2
- package/dist/templates/index.js +125 -9
- package/dist/validators/adr-validator.js +4 -4
- package/dist/validators/domain-validator.js +30 -1
- package/dist/validators/openspec-validator.js +33 -4
- package/package.json +9 -15
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ironbank-mcp-reference
|
|
3
|
+
description: IronBank MCP 强制参考指南。只要请求涉及 IronBank,或可能调用任意 ironbank_* 工具(含 board/看板、task/任务、recent task/最近任务、task relation/任务关系、channel/频道、activity/动态、note/笔记、comment/评论、attachment/附件、portal、fileId、附件下载解密),都必须先加载并遵循此 skill。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# IronBank 任务 MCP 工具使用指南
|
|
7
|
+
|
|
8
|
+
## 强制触发规则(最高优先级)
|
|
9
|
+
|
|
10
|
+
- 只要将要调用任意 `ironbank_*` 工具,必须先使用本 skill,不允许跳过。
|
|
11
|
+
- 只要用户提到 IronBank / ironbank mcp,或提到看板(board)、任务(task)、最近任务(recent task)、任务关系(relation/mention)、频道(channel)、动态(activity)、笔记(note)、评论(comment)、附件(attachment)、`portal`、`fileId` 中任一关键词,默认触发本 skill。
|
|
12
|
+
- 上下文中出现 `hillinsight://ib_note?...` 深链时,先加载 `ironbank-note-links` skill 解析出 `portal` / `task_id` / `note_id`,再按本 skill 的参数约定调用工具(链接已带齐三个 ID,可直接调 `ironbank_get_note_detail`,无需逐级定位)。
|
|
13
|
+
- 下载附件时,必须先调用 `ironbank_get_file_download_info` 获取 `download_url`、`file_key`、`digest`、`size`,再调用 `decrypt-attachment` skill 解密。
|
|
14
|
+
- 如果不确定是否属于 IronBank 场景,按“属于”处理,先触发本 skill。
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 数据模型
|
|
19
|
+
|
|
20
|
+
IronBank 的文档关系是严格的层级结构,操作时必须按层级从上往下获取 ID:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Board(看板)
|
|
24
|
+
└── Task(任务) ← 由 template 创建
|
|
25
|
+
└── Channel(频道)
|
|
26
|
+
└── Note(笔记) ← 文档主体,含附件
|
|
27
|
+
└── Comment(评论)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**重要**:IronBank 支持多租户(portal),许多工具需要传入 `portal` 参数来指定工作空间。
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 工具速查
|
|
35
|
+
|
|
36
|
+
| 工具名 | 用途 | 必填参数 |
|
|
37
|
+
|--------|------|---------|
|
|
38
|
+
| `ironbank_get_board_list` | 获取当前用户可见的看板列表,支持分页和扩展字段 | 无 |
|
|
39
|
+
| `ironbank_get_board_filter_template` | 获取指定看板可用的筛选模板,供后续任务查询复用 | `board_id`, `portal` |
|
|
40
|
+
| `ironbank_get_tasks_by_board` | 获取某个看板下的任务列表,支持 filter/task_ids/分页/扩展字段 | `board_id`, `portal` |
|
|
41
|
+
| `ironbank_get_task_info` | 获取某个任务的详细信息,默认含 information 和 members;`portal` 可用于补齐成员 | `task_id` |
|
|
42
|
+
| `ironbank_get_task_relations` | 获取任务所在看板与 mention 关系(`in_board`/`mentioned_here`/`mentioned_in`) | `task_id`, `portal` |
|
|
43
|
+
| `ironbank_get_recent_tasks` | 获取当前用户最近可见任务,不需要 portal,适合不知道 board 时先定位任务 | 无 |
|
|
44
|
+
| `ironbank_get_channels` | 获取某个任务下的频道列表,支持分页和扩展字段 | `task_id`, `portal` |
|
|
45
|
+
| `ironbank_get_channel_info` | 获取指定频道基础信息和成员/负责人 | `channel_id`, `portal` |
|
|
46
|
+
| `ironbank_get_channel_activities` | 获取指定频道动态列表,动态正文会从 HTML 转 Markdown | `task_id`, `channel_id`, `portal` |
|
|
47
|
+
| `ironbank_get_notes` | 获取某个频道下的笔记列表,列表只返回摘要;`channel_id` 必填 | `task_id`, `channel_id`, `portal` |
|
|
48
|
+
| `ironbank_list_recent_notes` | **跨任务**获取整个看板下的笔记(可选 update_time 时间窗筛选),适合"找最近一周的所有笔记"场景 | `board_id`, `portal` |
|
|
49
|
+
| `ironbank_get_note_detail` | 获取某条笔记的完整内容(Markdown 正文 + 结构化字段 + 附件 + 元数据) | `note_id`, `task_id`, `portal` |
|
|
50
|
+
| `ironbank_get_file_download_info` | 获取笔记/评论附件的下载与解密信息(`download_url`/`file_key`/`digest`/`size`) | `file_ids`, `comment_id`, `portal` |
|
|
51
|
+
| `ironbank_create_note` | 在频道下创建草稿笔记(不通知订阅者) | `task_id`, `channel_id`, `portal`, `content` |
|
|
52
|
+
| `ironbank_publish_note` | 发布已有笔记并通知订阅者(草稿 → 已发布) | `comment_id`, `policy_id`, `channel_id`, `portal`, `word_number` |
|
|
53
|
+
| `ironbank_get_note_comments` | 获取某条笔记的所有评论 | `note_id`, `portal` |
|
|
54
|
+
| `ironbank_create_comment` | 在笔记下创建评论 | `note_id`, `content`(`portal` 仅跨 portal 评论时需要传) |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 统一参数和返回约定
|
|
59
|
+
|
|
60
|
+
优先用 `response_format: "json"` 获取可解析的结构化结果;只有直接给用户阅读时才改成 `"markdown"`。
|
|
61
|
+
|
|
62
|
+
高频列表工具统一支持:
|
|
63
|
+
|
|
64
|
+
- `limit`:默认 10,通常最大 100
|
|
65
|
+
- `cursor`:翻页游标;大多数列表是数字 offset 字符串,`ironbank_get_notes` 是 `"<page_token>:<offset>"` 或纯 page token,`ironbank_list_recent_notes` 是页码字符串(从 `"0"` 开始)
|
|
66
|
+
- `fields`:默认返回最小字段集;需要更多字段时只传工具支持的字段名,传错会报 unsupported fields
|
|
67
|
+
- `response_format`:默认 `"json"`,返回紧凑 ai-json
|
|
68
|
+
|
|
69
|
+
列表工具通常返回:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"items": [],
|
|
74
|
+
"total": 0,
|
|
75
|
+
"has_more": false,
|
|
76
|
+
"next_cursor": "",
|
|
77
|
+
"coverage": "full"
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
详情工具通常返回 `{ "item": {}, "coverage": "full" }`。`coverage: "partial"` 表示部分字段因权限、受限笔记/附件或上游分区失败被隐藏,不能当成完整事实。
|
|
82
|
+
|
|
83
|
+
## 标准工作流
|
|
84
|
+
|
|
85
|
+
### 流程零:不知道 board/channel,只知道“我最近看过/处理过的任务”
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
Step 1 ironbank_get_recent_tasks → 获取最近任务(不需要 portal)
|
|
89
|
+
Step 2 从返回的 task.portal / task.id 定位目标任务
|
|
90
|
+
Step 3 ironbank_get_task_info → 获取任务详情(可传 portal 补齐成员)
|
|
91
|
+
Step 4 需要笔记时继续走“流程一”
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
适用场景:
|
|
95
|
+
|
|
96
|
+
- 用户只说“最近那个任务”“我最近打开的 IronBank 任务”
|
|
97
|
+
- 不知道 board_id,但可能能通过最近任务名定位
|
|
98
|
+
- 需要快速找到 `task_id` 和 `portal`
|
|
99
|
+
|
|
100
|
+
### 流程一:查找任务下的笔记内容
|
|
101
|
+
|
|
102
|
+
当用户说"帮我看看 XX 任务的笔记",按以下顺序操作:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
Step 1 ironbank_get_board_list → 找到对应 board_id
|
|
106
|
+
Step 2 ironbank_get_tasks_by_board → 找到对应 task_id(可用 filter 或 task_ids 精确定位)
|
|
107
|
+
Step 3 ironbank_get_channels → 找到对应 channel_id(注意传 portal)
|
|
108
|
+
Step 4 ironbank_get_notes → 获取笔记列表,找到目标 note_id
|
|
109
|
+
Step 5 ironbank_get_note_detail → 获取笔记完整内容
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**已知 task_id 与 portal_id 时**可跳过 Step 1-2,直接从 Step 3 开始。
|
|
113
|
+
**已知 channel_id 时**仍需给 `ironbank_get_notes` 同时传 `task_id`、`channel_id`、`portal`。
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
### 流程一补充:按筛选条件查询某个看板
|
|
118
|
+
|
|
119
|
+
当用户说“帮我看某个 board 里状态为 XX 的任务”、“按赛道筛一下任务”时,按以下顺序操作:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
Step 1 ironbank_get_board_filter_template → 获取该 board 的完整筛选模板
|
|
123
|
+
Step 2 在返回的 filter_template 中定位目标筛选项
|
|
124
|
+
Step 3 修改该项的 value / select_value(必要时参考 option_catalogs)
|
|
125
|
+
Step 4 ironbank_get_tasks_by_board → 将整个 filter_template 数组传入 filter
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
使用原则:
|
|
129
|
+
- `ironbank_get_board_filter_template` 返回的是可直接复用的模板,不是只读说明
|
|
130
|
+
- 传给 `ironbank_get_tasks_by_board.filter` 时,要传**完整数组**
|
|
131
|
+
- 不要只传某一项,也不要自行拼 `{ key: value }`
|
|
132
|
+
- 级联选项(如一级/二级赛道)优先看 `filter_template[*].list`,需要子级映射时再看 `option_catalogs`
|
|
133
|
+
|
|
134
|
+
常见修改方式:
|
|
135
|
+
- 文本搜索:修改该筛选项的 `value`
|
|
136
|
+
- 单选 / 多选:按模板现有结构修改 `value`
|
|
137
|
+
- 日期筛选:优先改 `select_value` 或 `value`,并参考模板里的 `list`
|
|
138
|
+
- 数值区间:保留模板结构,只修改范围值和组合字段
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
### 流程二:查看笔记的评论
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
Step 1 (按流程一定位到 note_id)
|
|
146
|
+
Step 2 ironbank_get_note_comments → 传入 note_id、portal,可用 limit/cursor 翻页
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### 流程三:下载并解密笔记附件
|
|
152
|
+
|
|
153
|
+
当用户说“下载这条 note 的附件”“打开 note 里的 Excel/PDF 附件”时,按以下顺序操作:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
Step 1 (按流程一定位到 note_id,并调用 ironbank_get_note_detail 拿到正文)
|
|
157
|
+
Step 2 从正文中的 `fileId:` 链接提取 file_id(可一次提取多个)
|
|
158
|
+
Step 3 ironbank_get_file_download_info → 传 file_ids、comment_id、portal
|
|
159
|
+
Step 4 调用 decrypt-attachment skill → 用返回的 download_url/file_key/digest/size 解密文件
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
参数说明:
|
|
163
|
+
- `comment_id` 是附件归属的 note/comment ID;note 正文附件通常传 `note_id`
|
|
164
|
+
- 评论附件场景下,`comment_id` 传对应评论 ID
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
### 流程四:在指定频道创建笔记
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
Step 1 (确认 task_id、channel_id 和 portal_id)
|
|
172
|
+
Step 2 ironbank_create_note → 传 task_id、channel_id、portal、content(HTML 格式)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
`content` 必须是 HTML 字符串,例如:
|
|
176
|
+
```html
|
|
177
|
+
<p>这是笔记内容</p>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### 流程五:回复笔记评论
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
Step 1 ironbank_create_comment → 传 note_id、content
|
|
186
|
+
如需回复某条评论,传 parent_id = 父评论的 ID
|
|
187
|
+
如果是跨 portal 评论(note 在别人的 portal),加传 portal = note 的 portal
|
|
188
|
+
同 portal 场景下可省略 portal — 评论始终用调用者自己的 portal 写入
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### 流程六:跨任务/时间窗发现某看板的笔记
|
|
194
|
+
|
|
195
|
+
当用户说"看一下 XX 看板这一周的新笔记"、"扫一下整个 board 最近的更新",按以下顺序操作:
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
Step 1 ironbank_list_recent_notes → 传 board_id、portal、可选 update_time_start / update_time_end、limit、cursor
|
|
199
|
+
Step 2 得到 note 引用列表(含 comment_id / task_id / update_time)
|
|
200
|
+
Step 3 对感兴趣的 note 调用 ironbank_get_note_detail 读正文(已是 Markdown)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
适用场景:
|
|
204
|
+
|
|
205
|
+
- 不知道笔记在哪个 task / channel,只知道在某个看板下
|
|
206
|
+
- 想按更新时间筛一段时间内的笔记
|
|
207
|
+
- 想跨任务统计或汇总笔记
|
|
208
|
+
|
|
209
|
+
时间窗格式:`'YYYY-MM-DD HH:mm:ss'`(含两端)。
|
|
210
|
+
`cursor` 是页码字符串,从 `"0"` 开始;`limit` 默认 20,最大 100。
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### 流程七:发布草稿笔记
|
|
215
|
+
|
|
216
|
+
`ironbank_create_note` 创建的是**草稿**,订阅者不会收到通知,且某些后续操作(如对该笔记加评论)可能因 note 未发布而失败。需要正式发布时:
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
Step 1 ironbank_create_note → 创建草稿,拿到 comment_id(=新笔记 ID)
|
|
220
|
+
Step 2 ironbank_publish_note → 传 comment_id、policy_id、channel_id、portal、word_number
|
|
221
|
+
可选 content(发布时刻的快照)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
参数说明:
|
|
225
|
+
|
|
226
|
+
- `comment_id`:上一步创建出的笔记 ID
|
|
227
|
+
- `policy_id`:笔记的可见性策略 ID。本指南的工具没有直接的发现路径,需从客户端 / 业务上下文获取,或与用户确认
|
|
228
|
+
- `word_number`:笔记字数(用于通知展示)
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
### 流程八:查看任务关系和被提及上下文
|
|
233
|
+
|
|
234
|
+
当用户问“这个任务在哪些 board 里”“它提到了谁/被谁提到”“关联任务有哪些”时:
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
Step 1 ironbank_get_task_relations → 传 task_id、portal
|
|
238
|
+
Step 2 如只需要某类关系,传 relation_types 缩小到 in_board / mentioned_here / mentioned_in
|
|
239
|
+
Step 3 对关系中的目标任务再调 ironbank_get_task_info 或走笔记流程
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
注意:
|
|
243
|
+
|
|
244
|
+
- 某个关系分区失败时,工具会返回已成功分区并把 `coverage` 标为 `partial`
|
|
245
|
+
- `mentioned_here` / `mentioned_in` 里可能包含 comment/note 线索,必要时再读取相关笔记详情
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
### 流程九:查看频道成员或频道动态
|
|
250
|
+
|
|
251
|
+
当用户问频道成员、负责人、频道设置:
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
Step 1 ironbank_get_channel_info → 传 channel_id、portal
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
当用户问“这个频道最近发生了什么”“频道动态/更新时间线”:
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
Step 1 ironbank_get_channel_activities → 传 task_id、channel_id、portal
|
|
261
|
+
Step 2 如需更丰富上下文,在 fields 中加 task_name / note_id / summary_title / summary_text / activity_content
|
|
262
|
+
Step 3 若动态指向 note_id,再调用 ironbank_get_note_detail 读取完整笔记
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 关键参数说明
|
|
268
|
+
|
|
269
|
+
### `portal`(工作空间)
|
|
270
|
+
|
|
271
|
+
- 大多数读类工具(channels、notes、note_detail、list_recent_notes、get_file_download_info、comments)以及 `create_note` / `publish_note` 都需要 `portal`,且应传**资源所在的 portal**
|
|
272
|
+
- 如果用户未提供 portal,可先用 `ironbank_get_board_list` 查看用户有权限的看板,通常能推断出 portal
|
|
273
|
+
- 跨 portal 操作会返回 403 或空结果,遇到此情况需确认用户的 portal 值
|
|
274
|
+
|
|
275
|
+
**`ironbank_create_comment` 例外**:
|
|
276
|
+
|
|
277
|
+
- 评论始终在调用者自己的 portal(自动从 JWT 派生)下创建,无论 note 在哪个 portal
|
|
278
|
+
- 因此 `portal` 是**可选**的,且语义是"note 的 portal",仅用于受限笔记的权限检查
|
|
279
|
+
- 同 portal 评论(最常见):直接省略 `portal`
|
|
280
|
+
- 跨 portal 评论(评论别人 portal 里的 note):把 note 的 portal 传给 `portal` 参数,让权限检查走对租户的规则
|
|
281
|
+
|
|
282
|
+
### `response_format`
|
|
283
|
+
|
|
284
|
+
- 默认为 `json`(紧凑 ai-json),最适合提取 ID、分页、判断 `coverage`
|
|
285
|
+
- 只有直接展示给用户阅读时,才改用 `markdown`
|
|
286
|
+
|
|
287
|
+
### `fields`
|
|
288
|
+
|
|
289
|
+
- 列表和部分详情工具用 `fields` 控制扩展返回字段;默认是最小字段集
|
|
290
|
+
- 传入字段会在默认字段基础上追加,不需要重复传默认字段
|
|
291
|
+
- 传入不支持的字段会报错,应根据工具默认/可选字段调整后重试
|
|
292
|
+
|
|
293
|
+
常用可选字段:
|
|
294
|
+
|
|
295
|
+
- `ironbank_get_board_list`:`created_at`, `updated_at`, `owner_name`, `status`
|
|
296
|
+
- `ironbank_get_tasks_by_board`:`updated_at`, `portal`, `deadline`, `priority`
|
|
297
|
+
- `ironbank_get_task_info`:`board_id`
|
|
298
|
+
- `ironbank_get_recent_tasks`:`relation_id`, `icon`, `template_id`, `bg_color`, `is_external`, `company_name`
|
|
299
|
+
- `ironbank_get_channels`:`portal`, `channel_type`
|
|
300
|
+
- `ironbank_get_channel_activities`:`task_name`, `activity_timestamp`, `note_id`, `summary_title`, `summary_text`, `activity_content`
|
|
301
|
+
- `ironbank_get_notes`:`author_name`, `task_id`, `is_restricted`
|
|
302
|
+
- `ironbank_get_note_comments`:`type`, `note_id`, `updated_at`
|
|
303
|
+
|
|
304
|
+
### `filter`(任务过滤)
|
|
305
|
+
|
|
306
|
+
`ironbank_get_tasks_by_board` 的 `filter` 不是简单字符串,也不是状态枚举。
|
|
307
|
+
|
|
308
|
+
正确用法:
|
|
309
|
+
- 先调用 `ironbank_get_board_filter_template`
|
|
310
|
+
- 使用返回的 `filter_template` 作为基础模板
|
|
311
|
+
- 在模板中修改目标筛选项的 `value` / `select_value`
|
|
312
|
+
- 把**整个数组**传回 `ironbank_get_tasks_by_board.filter`
|
|
313
|
+
|
|
314
|
+
返回内容说明:
|
|
315
|
+
- `filter_template`:可直接传给 `ironbank_get_tasks_by_board.filter` 的完整模板
|
|
316
|
+
- `option_catalogs`:后端分类数据整理出的辅助选项表,便于理解级联或补充选项
|
|
317
|
+
|
|
318
|
+
不要:
|
|
319
|
+
- 不要传 `"all"`、`"processing"`、`"done"` 这类旧格式
|
|
320
|
+
- 不要自行构造简化版对象,除非明确知道后端接受的完整结构
|
|
321
|
+
|
|
322
|
+
### `task_ids`(精确获取任务)
|
|
323
|
+
|
|
324
|
+
当已知 task_id 列表时,传入 `ironbank_get_tasks_by_board` 的 `task_ids` 参数可精确获取,无需遍历全部任务。
|
|
325
|
+
|
|
326
|
+
### `sort_by` 和 `sort_rule`(笔记排序)
|
|
327
|
+
|
|
328
|
+
`ironbank_get_notes` 支持:
|
|
329
|
+
- `sort_by`:`"updated_date"` 或 `"created_date"`
|
|
330
|
+
- `sort_rule`:`"desc"` 或 `"asc"`
|
|
331
|
+
|
|
332
|
+
默认按更新时间倒序,最新内容在前。
|
|
333
|
+
|
|
334
|
+
### `next_token`(分页)
|
|
335
|
+
|
|
336
|
+
列表响应统一看 `has_more` 和 `next_cursor`:
|
|
337
|
+
|
|
338
|
+
- `ironbank_get_notes` 的 `cursor` 格式是 `"<page_token>:<offset>"` 或纯 page token;直接把上一页返回的 `next_cursor` 传回去
|
|
339
|
+
- `ironbank_list_recent_notes` 的 `cursor` 是页码字符串,从 `"0"` 开始;直接把 `next_cursor` 传回去
|
|
340
|
+
- 其他列表工具通常用数字 offset 字符串;直接把 `next_cursor` 传回去
|
|
341
|
+
|
|
342
|
+
### `file_ids` 和 `comment_id`(附件下载解密)
|
|
343
|
+
|
|
344
|
+
`ironbank_get_file_download_info` 用于把附件 ID 转换为可下载并可解密的元信息。
|
|
345
|
+
|
|
346
|
+
正确用法:
|
|
347
|
+
- `file_ids`:从 `ironbank_get_note_detail` 返回内容中的 `fileId:` 链接提取
|
|
348
|
+
- `comment_id`:附件归属的 note/comment ID(note 附件通常传 `note_id`)
|
|
349
|
+
- `portal`:与 note 所在工作空间一致
|
|
350
|
+
- 返回 `download_url`、`file_key`、`digest`、`size` 后,必须交给 `decrypt-attachment` skill 进行解密
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## 注意事项
|
|
355
|
+
|
|
356
|
+
### ⚠️ 层级 ID 不可跨级使用
|
|
357
|
+
|
|
358
|
+
- `channel_id` 属于特定 `task_id` 下,不同任务的频道 ID 不可混用
|
|
359
|
+
- `note_id` 属于特定 `task_id` 和 `channel_id`,获取笔记详情时必须同时传 `note_id` 和 `task_id`
|
|
360
|
+
|
|
361
|
+
### ⚠️ 笔记内容是 HTML
|
|
362
|
+
|
|
363
|
+
- `ironbank_get_note_detail` 会将 HTML 自动转换为 Markdown 返回(在 `content.content` 字段),方便阅读
|
|
364
|
+
- `ironbank_create_note` 的 `content` 参数必须传入 HTML 格式,不要传纯文本或 Markdown
|
|
365
|
+
|
|
366
|
+
### ⚠️ 列表工具返回摘要,详情需单独获取
|
|
367
|
+
|
|
368
|
+
- `ironbank_get_notes` 返回某频道下的笔记列表,内容是摘要
|
|
369
|
+
- `ironbank_list_recent_notes` 返回的也是 note 引用(不含正文)
|
|
370
|
+
- 需要完整内容时调 `ironbank_get_note_detail`(包含 Markdown 正文、附件、元数据)
|
|
371
|
+
|
|
372
|
+
### ⚠️ create_note 创建的是草稿
|
|
373
|
+
|
|
374
|
+
- `ironbank_create_note` 写入的笔记不会通知订阅者,状态为草稿
|
|
375
|
+
- 正式发布需要紧接着调 `ironbank_publish_note`(需要 `policy_id`,得从业务上下文获取)
|
|
376
|
+
- 草稿笔记上的某些操作(如对其加评论)可能因 note 未发布而失败
|
|
377
|
+
|
|
378
|
+
### ⚠️ 并行调用加速
|
|
379
|
+
|
|
380
|
+
对多个频道或多个笔记的查询,可以并行调用工具,无需串行等待。例如:同时获取多个 channel 的笔记列表。
|
|
381
|
+
|
|
382
|
+
### ⚠️ 附件下载后仍是加密文件
|
|
383
|
+
|
|
384
|
+
- `ironbank_get_file_download_info` 返回的是“下载地址 + 解密材料”,不是明文文件
|
|
385
|
+
- 必须使用 `decrypt-attachment` skill(`scripts/decrypt.py`)完成解密后再读取文件内容
|
|
386
|
+
- 若下载失败或 URL 过期,重新调用 `ironbank_get_file_download_info` 获取新参数再重试
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## MCP 连接检查
|
|
391
|
+
|
|
392
|
+
在调用任何 `ironbank_*` 工具之前,如果工具不可用或调用失败并提示工具不存在,可能有以下两种原因:
|
|
393
|
+
|
|
394
|
+
**情况一:IronBank MCP 尚未安装**
|
|
395
|
+
|
|
396
|
+
> **IronBank MCP 未安装**,请前往 Claude 客户端(如 Claude Desktop)的 MCP 设置页面,搜索并安装 IronBank MCP 服务,安装完成后重新发起请求。
|
|
397
|
+
|
|
398
|
+
**情况二:IronBank MCP 已安装但未连接**
|
|
399
|
+
|
|
400
|
+
> **IronBank MCP 未连接**,请在 Claude 客户端的 MCP 设置中,找到 IronBank MCP 服务并点击「Connect」使其处于连接状态,连接成功后再重新发起请求。
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## 常见错误处理
|
|
405
|
+
|
|
406
|
+
| 错误情况 | 处理方式 |
|
|
407
|
+
|---------|---------|
|
|
408
|
+
| MCP 未安装 / 工具不存在 | 提示用户前往 Claude MCP 设置安装 IronBank MCP |
|
|
409
|
+
| MCP 已安装但未连接 | 提示用户在 Claude MCP 设置中点击「Connect」连接 IronBank 服务 |
|
|
410
|
+
| 401 未授权 | token 过期,提示用户重新授权 |
|
|
411
|
+
| 403 无权限 | 确认 portal 参数是否正确,或用户是否有该资源的访问权 |
|
|
412
|
+
| 404 资源不存在 | 确认 ID 是否正确,资源是否已被删除 |
|
|
413
|
+
| 429 限流 | 稍后重试,减少并行请求数量 |
|
|
414
|
+
| 返回空列表 | 先确认 filter 参数,再确认 portal 和 board_id 是否正确 |
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ironbank-note-links
|
|
3
|
+
description: |
|
|
4
|
+
解析与生成 IronBank 笔记深链(`hillinsight://ib_note?...`)。本项目的文档和 bug 都记录在 IronBank 中,仓库内文档(docs/、ADR、openspec、issue、commit message)以及与 LLM 的对话里,统一用这种链接引用 IronBank 笔记。触发条件(任一命中即必须使用本 skill):
|
|
5
|
+
- 上下文中出现 `hillinsight://` 开头的链接(用户消息、文件内容、搜索结果中均算)
|
|
6
|
+
- 用户要求"打开/看看/读一下这个链接"且链接是 hillinsight 深链
|
|
7
|
+
- 需要在项目文档或回答中引用某条 IronBank 笔记(生成链接)
|
|
8
|
+
- 用户提到"把这个 bug/文档记到 IronBank 并留个链接"
|
|
9
|
+
解析链接需要 IronBank MCP(ironbank_* 工具),调用前先加载 ironbank-mcp-reference skill。
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# IronBank 笔记深链(hillinsight://)解析与生成
|
|
13
|
+
|
|
14
|
+
## 背景
|
|
15
|
+
|
|
16
|
+
本项目的项目文档和 bug 记录都放在 IronBank。仓库内引用这些内容时,不复制正文,而是留一条深链:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
hillinsight://ib_note?portal=<portal>&task=<task_id>&id=<note_id>&view=detail
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
示例:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
hillinsight://ib_note?portal=v9owxx8o&task=83a5a825-d9a7-4114-ad63-08c26fb1a3b8&id=5a14a6da-210a-4d1c-8033-785d93412b47&view=detail
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
人类在 HLink / hillinsight 客户端里点击即可打开;Agent 遇到时必须通过 IronBank MCP 把正文读出来,**不允许**因为链接协议陌生而跳过、也不允许猜测其内容。
|
|
29
|
+
|
|
30
|
+
## 链接结构 → MCP 参数映射
|
|
31
|
+
|
|
32
|
+
| Query 参数 | 含义 | 对应 MCP 参数 |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `portal` | 工作空间(多租户) | `portal` |
|
|
35
|
+
| `task` | 笔记所属任务 ID | `task_id` |
|
|
36
|
+
| `id` | 笔记 ID | `note_id` |
|
|
37
|
+
| `view` | 客户端视图(通常 `detail`) | 无需传给 MCP,忽略 |
|
|
38
|
+
|
|
39
|
+
三个 ID 一条链接全带齐了,**不需要**再走 board → task → channel 的逐级定位流程。
|
|
40
|
+
|
|
41
|
+
## 流程一:解析(读)一条链接
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Step 1 从链接中提取 portal / task / id 三个参数
|
|
45
|
+
Step 2 ironbank_get_note_detail → note_id=id, task_id=task, portal=portal
|
|
46
|
+
(返回 Markdown 正文 + 附件 + 元数据)
|
|
47
|
+
Step 3 如需讨论上下文:ironbank_get_note_comments → note_id, portal
|
|
48
|
+
Step 4 如正文含 `fileId:` 附件链接且用户需要附件内容:
|
|
49
|
+
ironbank_get_file_download_info → 再交给 decrypt-attachment skill 解密
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
注意:
|
|
53
|
+
|
|
54
|
+
- 一次出现多条链接时,可**并行**调用 `ironbank_get_note_detail`
|
|
55
|
+
- 返回 `coverage: "partial"` 时要说明部分内容因权限被隐藏,不能当完整事实
|
|
56
|
+
- 403 / 404 时如实告知链接不可访问或已删除,不要编造内容
|
|
57
|
+
|
|
58
|
+
## 流程二:生成(写)一条链接
|
|
59
|
+
|
|
60
|
+
当需要在项目文档、ADR、openspec change、bug 记录或回答中引用某条 IronBank 笔记时:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Step 1 确认该笔记的 portal、task_id、note_id
|
|
64
|
+
(来自 ironbank_get_notes / ironbank_list_recent_notes / ironbank_get_note_detail
|
|
65
|
+
/ ironbank_create_note 的返回,或用户提供)
|
|
66
|
+
Step 2 按固定格式拼接:
|
|
67
|
+
hillinsight://ib_note?portal=<portal>&task=<task_id>&id=<note_id>&view=detail
|
|
68
|
+
Step 3 在 Markdown 中带上笔记标题作为可读文本:
|
|
69
|
+
[笔记标题](hillinsight://ib_note?portal=...&task=...&id=...&view=detail)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
规则:
|
|
73
|
+
|
|
74
|
+
- **只对真实存在的笔记生成链接**——三个 ID 必须来自工具返回或用户输入,禁止拼造
|
|
75
|
+
- 参数顺序固定为 `portal` → `task` → `id` → `view`,`view` 固定填 `detail`
|
|
76
|
+
- 在 docs/、ADR、openspec 里引用 IronBank 内容时,优先留链接而不是复制大段正文;需要摘录时附上链接作为出处
|
|
77
|
+
- 用 `ironbank_create_note` 新建了 bug / 文档笔记后,把生成的链接回填到相关文档或回复里
|
|
78
|
+
|
|
79
|
+
## 与其他 skill 的配合
|
|
80
|
+
|
|
81
|
+
- 调用任何 `ironbank_*` 工具前,先加载 **ironbank-mcp-reference**(工具参数与层级模型)
|
|
82
|
+
- 基于链接解析出的内容作答时,按 **ironbank-citations** 的角标格式标注来源;来源为笔记时,来源列表中的标题直接使用上面的深链 Markdown 链接
|
|
83
|
+
- 需要在笔记正文里做语义定位时,转 **ironbank-docs-research** 的 notes 链路(`ironbank_notes_search_single` 等)
|
|
84
|
+
|
|
85
|
+
## MCP 不可用时
|
|
86
|
+
|
|
87
|
+
如果 `ironbank_*` 工具不存在或未连接,不要假装解析:明确告知用户 IronBank MCP 未安装 / 未连接(处理方式见 ironbank-mcp-reference 的「MCP 连接检查」),并原样保留链接。
|
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,11 @@ import { runNewAdr } from "./commands/new-adr.js";
|
|
|
9
9
|
import { runCheck, printCheckResult, checkExitCode, toJsonOutput } from "./commands/check.js";
|
|
10
10
|
import { runAudit } from "./commands/audit.js";
|
|
11
11
|
import { runSync } from "./commands/sync.js";
|
|
12
|
-
import { runConfigList, runConfigSet } from "./commands/config.js";
|
|
12
|
+
import { runConfigList, runConfigSet, runConfigHooks } from "./commands/config.js";
|
|
13
|
+
import { runNewChange } from "./commands/new-change.js";
|
|
14
|
+
import { runDoctor } from "./commands/doctor.js";
|
|
15
|
+
import { runReview } from "./commands/review.js";
|
|
16
|
+
import { runPreflight } from "./commands/preflight.js";
|
|
13
17
|
const require = createRequire(import.meta.url);
|
|
14
18
|
const pkg = require("../package.json");
|
|
15
19
|
const program = new Command();
|
|
@@ -46,6 +50,8 @@ program
|
|
|
46
50
|
.description("Initialize agent metadata infrastructure in the current project")
|
|
47
51
|
.option("-y, --yes", "non-interactive mode, accept all defaults")
|
|
48
52
|
.option("--type <type>", "project type: node | monorepo | nextjs | cocos | backend | other")
|
|
53
|
+
.option("--with-mcp <pack>", "install an MCP pack (.mcp.json + .claude/skills/), e.g. ironbank")
|
|
54
|
+
.option("--with-deploy <target>", "install a deploy skill: cloudflare | ansible | github-actions | none")
|
|
49
55
|
.option("--dry-run", "show what would be created without writing files")
|
|
50
56
|
.action(async (opts) => {
|
|
51
57
|
try {
|
|
@@ -93,6 +99,33 @@ program
|
|
|
93
99
|
handleError(e);
|
|
94
100
|
}
|
|
95
101
|
});
|
|
102
|
+
program
|
|
103
|
+
.command("new-change")
|
|
104
|
+
.description("Create an OpenSpec-compatible change directory linked to a domain")
|
|
105
|
+
.argument("<name>", "change name, e.g. add-withdrawal-review")
|
|
106
|
+
.option("--domain <domain>", "related domain, e.g. withdrawal")
|
|
107
|
+
.option("--schema <schema>", "change schema, e.g. payment-risk (adds risk-review.md and .openspec.yaml)")
|
|
108
|
+
.option("--dry-run", "show what would be created without writing files")
|
|
109
|
+
.action((name, opts) => {
|
|
110
|
+
try {
|
|
111
|
+
runNewChange(cwd, name, opts);
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
handleError(e);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
program
|
|
118
|
+
.command("doctor")
|
|
119
|
+
.description("Check the environment: runtime, config, paths, git hooks and OpenSpec")
|
|
120
|
+
.option("--json", "machine-readable JSON output")
|
|
121
|
+
.action((opts) => {
|
|
122
|
+
try {
|
|
123
|
+
process.exit(runDoctor(cwd, opts));
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
handleError(e);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
96
129
|
program
|
|
97
130
|
.command("check")
|
|
98
131
|
.description("Run deterministic metadata checks (for local dev, git hooks and CI)")
|
|
@@ -117,6 +150,32 @@ program
|
|
|
117
150
|
handleError(e);
|
|
118
151
|
}
|
|
119
152
|
});
|
|
153
|
+
program
|
|
154
|
+
.command("review")
|
|
155
|
+
.description("Periodic repository review checklist: docs, code, tests and security")
|
|
156
|
+
.option("--pick-docs", "interactively confirm which documentation scopes to tidy this round")
|
|
157
|
+
.option("--json", "machine-readable JSON output")
|
|
158
|
+
.action(async (opts) => {
|
|
159
|
+
try {
|
|
160
|
+
await runReview(cwd, opts);
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
handleError(e);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
program
|
|
167
|
+
.command("preflight")
|
|
168
|
+
.description("Pre-release checklist; --confirm requires a human to sign off each item")
|
|
169
|
+
.option("--confirm", "interactively confirm each manual item (exit 1 unless all confirmed)")
|
|
170
|
+
.option("--json", "machine-readable JSON output")
|
|
171
|
+
.action(async (opts) => {
|
|
172
|
+
try {
|
|
173
|
+
process.exit(await runPreflight(cwd, opts));
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
handleError(e);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
120
179
|
program
|
|
121
180
|
.command("audit")
|
|
122
181
|
.description("Governance-oriented analysis report (never blocks, never edits files)")
|
|
@@ -164,7 +223,7 @@ configCmd
|
|
|
164
223
|
configCmd
|
|
165
224
|
.command("set")
|
|
166
225
|
.description("Set a configuration value, e.g. meta config set defaults.agents_max_lines 220")
|
|
167
|
-
.argument("<key>", "dot-separated key, e.g.
|
|
226
|
+
.argument("<key>", "dot-separated key, e.g. validation.stale_review_days.active")
|
|
168
227
|
.argument("<value>", "value")
|
|
169
228
|
.action((key, value) => {
|
|
170
229
|
try {
|
|
@@ -174,4 +233,17 @@ configCmd
|
|
|
174
233
|
handleError(e);
|
|
175
234
|
}
|
|
176
235
|
});
|
|
236
|
+
configCmd
|
|
237
|
+
.command("hooks")
|
|
238
|
+
.description("Generate git hook configuration that runs `meta check` on pre-commit")
|
|
239
|
+
.argument("<tool>", "hook tool, currently only: lefthook")
|
|
240
|
+
.option("--dry-run", "show what would be written without writing files")
|
|
241
|
+
.action((tool, opts) => {
|
|
242
|
+
try {
|
|
243
|
+
runConfigHooks(cwd, tool, opts);
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
handleError(e);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
177
249
|
program.parseAsync(process.argv).catch(handleError);
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
export declare function runConfigList(root: string): void;
|
|
2
2
|
export declare function runConfigSet(root: string, key: string, value: string): void;
|
|
3
|
+
export interface ConfigHooksOptions {
|
|
4
|
+
dryRun?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/** `meta config hooks lefthook` — generate or extend the lefthook config. */
|
|
7
|
+
export declare function runConfigHooks(root: string, tool: string, opts?: ConfigHooksOptions): void;
|