iterate-plugin 2.3.6
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 +143 -0
- package/cordis.patch.yml +9 -0
- package/package.json +59 -0
- package/src/config-loader.ts +162 -0
- package/src/index.ts +50 -0
- package/src/meta-review.ts +289 -0
- package/src/review.ts +360 -0
- package/src/skill-prompt.ts +227 -0
- package/src/tools/config.ts +90 -0
- package/src/tools/context.ts +170 -0
- package/src/tools/decision-log.ts +163 -0
- package/src/tools/review.ts +174 -0
- package/src/tools/validate.ts +159 -0
- package/src/types.ts +100 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 iterate-skill 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
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# iterate-plugin for DeepSeek Harness (dsh)
|
|
2
|
+
|
|
3
|
+
`iterate-plugin` 是 [iterate](https://github.com/iterate-skill/iterate-skill) 技能的 [DeepSeek Harness (dsh)](https://github.com/deepseek-ai/deepseek-harness) 插件,提供**自治闭环代码迭代**和**dry-run 纯多轮审查**能力。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
| 功能 | dry-run 模式 | normal 模式 |
|
|
8
|
+
|------|-------------|------------|
|
|
9
|
+
| 多轮收敛反复审查 | ✅ | ✅ |
|
|
10
|
+
| 并行维度评审 | ✅ | ✅ |
|
|
11
|
+
| 确定性聚合去重/排序 | ✅ | ✅ |
|
|
12
|
+
| meta-review 报告一致性审计 | ✅ | ✅ |
|
|
13
|
+
| 零文件修改(只读) | ✅ | ❌ |
|
|
14
|
+
| 原子问题自动修复 | ❌ | ✅ |
|
|
15
|
+
| 每轮修复后验证 | ❌ | ✅ |
|
|
16
|
+
| 达标自停 | ✅ | ✅ |
|
|
17
|
+
| 只修改 atomic 问题,保留 architectural 留待后续 | ❌ | ✅ |
|
|
18
|
+
|
|
19
|
+
## 安装
|
|
20
|
+
|
|
21
|
+
### 从 npm 安装(发布后)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
dsh plugin --profile web add iterate-plugin
|
|
25
|
+
# 或
|
|
26
|
+
pnpm add iterate-plugin
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 本地开发 / 源码挂载
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dsh plugin --profile web add /Volumes/Eng-Dev/iterate-skill/harness/iterate-plugin
|
|
33
|
+
# 或
|
|
34
|
+
pnpm add /path/to/iterate-skill/harness/iterate-plugin
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
然后在你的 profile `cordis.patch.yml` 添加:
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
- insert:
|
|
41
|
+
- id: iterate-plugin
|
|
42
|
+
name: 'iterate-plugin'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 使用
|
|
46
|
+
|
|
47
|
+
### dry-run 模式(纯反复审查,不修改文件)
|
|
48
|
+
|
|
49
|
+
当你想要 "只是反复审查,不修改文件",prompt 示例:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
dry-run review this project, find all issues across all dimensions
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
插件会自动触发 iterate 工作流:
|
|
56
|
+
1. `plan` → 读取配置,生成评审计划
|
|
57
|
+
2. `loop` → 每轮并行评审,只找新问题 → 确定性聚合去重 → 统计收敛 → 无新问题则停止
|
|
58
|
+
3. `meta-review` → 审计报告一致性
|
|
59
|
+
4. `report` → 输出最终结果
|
|
60
|
+
|
|
61
|
+
### normal 模式(自治闭环迭代)
|
|
62
|
+
|
|
63
|
+
当你想要 "iterate this project / fix the issues found",prompt 示例:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
iterate on this project, fix all atomic issues
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
工作流:
|
|
70
|
+
1. `plan` → 读取配置
|
|
71
|
+
2. `loop` → 并行评审 → 聚合去重 → 原子问题并行修复 → 执行验证命令 → 记录日志 → 无新问题则停止
|
|
72
|
+
3. `report` → 输出修复统计
|
|
73
|
+
|
|
74
|
+
## 项目配置
|
|
75
|
+
|
|
76
|
+
在项目根目录放 `iterate.config.yaml`:
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
# 评审目标(例如 "提高代码质量,修复潜在bug,改善可维护性")
|
|
80
|
+
goal: "Improve code quality of the project"
|
|
81
|
+
# 评审维度(从本插件预定义维度选或自定义)
|
|
82
|
+
dimensions:
|
|
83
|
+
- correctness
|
|
84
|
+
- security
|
|
85
|
+
- performance
|
|
86
|
+
- maintainability
|
|
87
|
+
- code-style
|
|
88
|
+
# 最大评审轮次
|
|
89
|
+
max_rounds: 3
|
|
90
|
+
# 评审范围
|
|
91
|
+
review:
|
|
92
|
+
scope: full # full = 全项目,changed-only = 只看变更文件
|
|
93
|
+
# 已知故意不修复的问题(评审会过滤掉,不再重复报告)
|
|
94
|
+
personalization:
|
|
95
|
+
known_intentional:
|
|
96
|
+
- file: src/example.ts
|
|
97
|
+
line: 42
|
|
98
|
+
dimension: security
|
|
99
|
+
reason: "Intentional for demonstration"
|
|
100
|
+
# 验证命令(修复后自动跑,结果记入日志)
|
|
101
|
+
validation:
|
|
102
|
+
commands:
|
|
103
|
+
- npm test
|
|
104
|
+
- npm run typecheck
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## 注册工具
|
|
108
|
+
|
|
109
|
+
插件注册了 5 个工具:
|
|
110
|
+
|
|
111
|
+
| 工具 | 功能 |
|
|
112
|
+
|------|------|
|
|
113
|
+
| `iterate_config` | 读取并验证 `iterate.config.yaml` |
|
|
114
|
+
| `iterate_validate` | 运行白名单验证命令,返回结果 |
|
|
115
|
+
| `iterate_decision_log` | 追加决策日志(只追加,不改旧) |
|
|
116
|
+
| `iterate_context` | 读取 `SKILL.md` / `ITERATE.md` 上下文 |
|
|
117
|
+
| `iterate_review` | 确定性评审引擎:`plan` 生成计划,`aggregate` 聚合结论,`meta-review` 审计报告 |
|
|
118
|
+
|
|
119
|
+
## 设计
|
|
120
|
+
|
|
121
|
+
插件遵循 dsh "everything-is-a-plugin" 架构:
|
|
122
|
+
- 只做一件事:注入系统 prompt 教模型写 iterate workflow + 注册 5 个纯函数工具
|
|
123
|
+
- 所有 orchestration 通过 dsh 原生 `workflow` + `agent` + `parallel` 完成
|
|
124
|
+
- 核心逻辑(去重/过滤/排序/收敛/meta-audit)全部纯函数,可单元测试,无 I/O
|
|
125
|
+
- 遵循 iterate 原技能的设计原则:确定性收敛,可审计,最小权限
|
|
126
|
+
|
|
127
|
+
## 运行测试
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
cd harness/iterate-plugin
|
|
131
|
+
npm install
|
|
132
|
+
npm run typecheck
|
|
133
|
+
npm test
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
所有测试通过:
|
|
137
|
+
- 31 个单元测试全绿
|
|
138
|
+
- 覆盖去重、过滤、排序、多轮收敛、meta-review 审计
|
|
139
|
+
- 类型检查通过
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# iterate-plugin bundle layer — applied when a profile lists this bundle.
|
|
2
|
+
# package.json declares `dsh.bundle.patch` pointing at this file.
|
|
3
|
+
#
|
|
4
|
+
# `name` is a PACKAGE NAME (resolved through the profile's node_modules or the
|
|
5
|
+
# installation fallback $DSH_HOME/profiles/node_modules), NOT a relative path.
|
|
6
|
+
# `iterate-plugin` is this package's main entry (→ src/index.ts).
|
|
7
|
+
- insert:
|
|
8
|
+
- id: iterate-plugin
|
|
9
|
+
name: iterate-plugin
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "iterate-plugin",
|
|
3
|
+
"version": "2.3.6",
|
|
4
|
+
"description": "dsh plugin that turns the iterate skill into an autonomous closed-loop harness: plan -> parallel review xN -> atomic fixes -> validate -> loop -> auto-stop, plus a dry-run pure-review mode with multi-round convergence and a meta-review that audits the report and emits a final review report.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"dsh-plugin",
|
|
9
|
+
"deepseek-harness",
|
|
10
|
+
"dsh",
|
|
11
|
+
"iterate",
|
|
12
|
+
"code-review",
|
|
13
|
+
"autonomous",
|
|
14
|
+
"dry-run",
|
|
15
|
+
"cordis"
|
|
16
|
+
],
|
|
17
|
+
"dsh": {
|
|
18
|
+
"bundle": {
|
|
19
|
+
"patch": "./cordis.patch.yml"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"src",
|
|
24
|
+
"cordis.patch.yml",
|
|
25
|
+
"README.md",
|
|
26
|
+
"LICENSE"
|
|
27
|
+
],
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./src/index.ts",
|
|
31
|
+
"default": "./src/index.ts"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"test": "tsx --test test/*.test.ts",
|
|
37
|
+
"test:script": "tsx --test test/script.test.ts",
|
|
38
|
+
"test:runtime": "tsx --test test/runtime.test.ts",
|
|
39
|
+
"test:loader": "tsx --test test/loader.test.ts",
|
|
40
|
+
"test:decisions": "tsx --test test/decisions.test.ts",
|
|
41
|
+
"test:validate": "tsx --test test/validate.test.ts"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@deepseek-ai/cordis": "4.0.1",
|
|
45
|
+
"@deepseek-ai/dsh-tools": "0.1.0-rc.6",
|
|
46
|
+
"@deepseek-ai/dsh-workflow": "0.1.0-rc.6",
|
|
47
|
+
"@deepseek-ai/schemastery": "3.18.1",
|
|
48
|
+
"js-yaml": "4.3.1"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/js-yaml": "4.0.9",
|
|
52
|
+
"@types/node": "22.15.0",
|
|
53
|
+
"tsx": "4.20.3",
|
|
54
|
+
"typescript": "5.9.3"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=20"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { join } from 'node:path'
|
|
3
|
+
import yaml from 'js-yaml'
|
|
4
|
+
import type { IterateConfig } from './types.ts'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Load and parse iterate.config.yaml from the project root.
|
|
8
|
+
* Returns null if the file is missing or invalid.
|
|
9
|
+
*/
|
|
10
|
+
export function loadConfig(projectRoot: string): IterateConfig | null {
|
|
11
|
+
try {
|
|
12
|
+
const content = readFileSync(join(projectRoot, 'iterate.config.yaml'), 'utf-8')
|
|
13
|
+
const parsed = yaml.load(content) as Record<string, unknown>
|
|
14
|
+
if (!parsed || typeof parsed !== 'object') return null
|
|
15
|
+
return parsed as unknown as IterateConfig
|
|
16
|
+
} catch {
|
|
17
|
+
return null
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Sensible defaults for every config field. These are the "Master" config:
|
|
23
|
+
* when a project has no iterate.config.yaml (or only partial overrides), every
|
|
24
|
+
* missing key is filled from here so the plugin is usable out of the box while
|
|
25
|
+
* never inventing trusted validation commands (they must be configured).
|
|
26
|
+
*/
|
|
27
|
+
export function defaultConfig(): IterateConfig {
|
|
28
|
+
return {
|
|
29
|
+
goal: 'Improve code quality and maintainability',
|
|
30
|
+
max_rounds: 7,
|
|
31
|
+
language: 'en',
|
|
32
|
+
dimensions: [
|
|
33
|
+
'correctness',
|
|
34
|
+
'security',
|
|
35
|
+
'performance',
|
|
36
|
+
'architecture',
|
|
37
|
+
'style-tests',
|
|
38
|
+
'tech-debt',
|
|
39
|
+
'spec-compliance',
|
|
40
|
+
'frontend-backend',
|
|
41
|
+
'ui-ux',
|
|
42
|
+
],
|
|
43
|
+
review: { scope: 'full' },
|
|
44
|
+
atomic: { max_lines: 20, max_adjacent_methods: 3 },
|
|
45
|
+
git: {
|
|
46
|
+
target_branch: 'main',
|
|
47
|
+
use_worktree: false,
|
|
48
|
+
push_per_round: false,
|
|
49
|
+
auto_merge: false,
|
|
50
|
+
},
|
|
51
|
+
validation: { command_whitelist: [], commands: {} },
|
|
52
|
+
reviewer: { output_schema_validation: true },
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Recursively merge `override` on top of `base`.
|
|
58
|
+
* - Missing keys in `base` are added from `override`.
|
|
59
|
+
* - Present keys in `override` win.
|
|
60
|
+
* - Plain objects are merged recursively; arrays and scalars are replaced
|
|
61
|
+
* wholesale by the override (arrays are NOT concatenated).
|
|
62
|
+
* Returns a NEW object; neither input is mutated.
|
|
63
|
+
*/
|
|
64
|
+
export function mergeConfig(
|
|
65
|
+
base: Record<string, unknown>,
|
|
66
|
+
override: Record<string, unknown> | undefined,
|
|
67
|
+
): Record<string, unknown> {
|
|
68
|
+
if (!override || typeof override !== 'object') return { ...base }
|
|
69
|
+
const out: Record<string, unknown> = { ...base }
|
|
70
|
+
for (const [key, value] of Object.entries(override)) {
|
|
71
|
+
if (value === undefined) continue
|
|
72
|
+
const baseValue = out[key]
|
|
73
|
+
if (
|
|
74
|
+
baseValue &&
|
|
75
|
+
typeof baseValue === 'object' &&
|
|
76
|
+
!Array.isArray(baseValue) &&
|
|
77
|
+
value &&
|
|
78
|
+
typeof value === 'object' &&
|
|
79
|
+
!Array.isArray(value)
|
|
80
|
+
) {
|
|
81
|
+
out[key] = mergeConfig(
|
|
82
|
+
baseValue as Record<string, unknown>,
|
|
83
|
+
value as Record<string, unknown>,
|
|
84
|
+
)
|
|
85
|
+
} else {
|
|
86
|
+
out[key] = value
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return out
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Load the EFFECTIVE config for a project: project-root overrides merged on top
|
|
94
|
+
* of the built-in defaults ("Master + Overrides"). Never returns null — a
|
|
95
|
+
* project without a config file simply runs on the defaults (with an empty
|
|
96
|
+
* validation command set, so nothing untrusted can ever execute).
|
|
97
|
+
*/
|
|
98
|
+
export function loadEffectiveConfig(projectRoot: string): {
|
|
99
|
+
config: IterateConfig
|
|
100
|
+
source: 'defaults' | 'override'
|
|
101
|
+
override: IterateConfig | null
|
|
102
|
+
} {
|
|
103
|
+
const override = loadConfig(projectRoot)
|
|
104
|
+
if (!override) {
|
|
105
|
+
return { config: defaultConfig(), source: 'defaults', override: null }
|
|
106
|
+
}
|
|
107
|
+
const merged = mergeConfig(
|
|
108
|
+
defaultConfig() as unknown as Record<string, unknown>,
|
|
109
|
+
override as unknown as Record<string, unknown>,
|
|
110
|
+
) as unknown as IterateConfig
|
|
111
|
+
return { config: merged, source: 'override', override }
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Check whether a command is in the predefined commands list.
|
|
116
|
+
* A command is allowed if it is EXACTLY (after trim) listed in any
|
|
117
|
+
* module's command array in `validation.commands`.
|
|
118
|
+
* This replaces the old prefix-based whitelist at runtime — the
|
|
119
|
+
* `command_whitelist` is still used for config-time validation only.
|
|
120
|
+
*/
|
|
121
|
+
export function isCommandAllowed(command: string, predefinedCommands: string[]): boolean {
|
|
122
|
+
const trimmed = command.trim()
|
|
123
|
+
return predefinedCommands.includes(trimmed)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Flatten all commands from `validation.commands` into a single string array.
|
|
128
|
+
* Used for runtime exact-match checking.
|
|
129
|
+
*/
|
|
130
|
+
export function flattenCommands(
|
|
131
|
+
commands: Record<string, string[]> | undefined,
|
|
132
|
+
): string[] {
|
|
133
|
+
if (!commands || typeof commands !== 'object') return []
|
|
134
|
+
const out: string[] = []
|
|
135
|
+
for (const v of Object.values(commands)) {
|
|
136
|
+
if (Array.isArray(v)) out.push(...v)
|
|
137
|
+
}
|
|
138
|
+
return out
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Validate that the config has all required fields.
|
|
143
|
+
* Returns an array of missing field paths.
|
|
144
|
+
*/
|
|
145
|
+
export function validateConfig(config: unknown): string[] {
|
|
146
|
+
const errors: string[] = []
|
|
147
|
+
if (!config || typeof config !== 'object') {
|
|
148
|
+
errors.push('root')
|
|
149
|
+
return errors
|
|
150
|
+
}
|
|
151
|
+
const c = config as Record<string, unknown>
|
|
152
|
+
if (!c.goal) errors.push('goal')
|
|
153
|
+
if (!Array.isArray(c.dimensions)) errors.push('dimensions')
|
|
154
|
+
if (!c.validation || typeof c.validation !== 'object') {
|
|
155
|
+
errors.push('validation')
|
|
156
|
+
} else {
|
|
157
|
+
const v = c.validation as Record<string, unknown>
|
|
158
|
+
if (!Array.isArray(v.command_whitelist)) errors.push('validation.command_whitelist')
|
|
159
|
+
if (!v.commands || typeof v.commands !== 'object') errors.push('validation.commands')
|
|
160
|
+
}
|
|
161
|
+
return errors
|
|
162
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iterate-plugin — dsh plugin for the iterate autonomous closed-loop workflow
|
|
3
|
+
*
|
|
4
|
+
* Architecture:
|
|
5
|
+
* - The plugin registers 4 tools (config, validate, decision-log, context)
|
|
6
|
+
* - The plugin injects a system prompt section teaching the iterate workflow pattern
|
|
7
|
+
* - The model (prompted by the skill) writes a workflow script using dsh's `workflow` tool
|
|
8
|
+
* - The workflow script uses `agent()` / `parallel()` / `phase()` / `log()` to orchestrate
|
|
9
|
+
* - Subagents use the 4 tools to do real work (read config, run validation, log decisions)
|
|
10
|
+
*
|
|
11
|
+
* Tool invocation model:
|
|
12
|
+
* - Workflow script CANNOT call tools directly (sandboxed vm, no Node API)
|
|
13
|
+
* - Workflow script spawns subagents via `agent(prompt, opts)`
|
|
14
|
+
* - Subagents are full agent sessions with access to all registered tools
|
|
15
|
+
* - The script is pure orchestration: fan-out, aggregate, loop, stop
|
|
16
|
+
*
|
|
17
|
+
* Key files:
|
|
18
|
+
* - src/index.ts — Plugin entry: register tools + inject skill prompt
|
|
19
|
+
* - src/tools/ — 4 tool implementations
|
|
20
|
+
* - src/config-loader.ts — YAML config loading
|
|
21
|
+
* - src/types.ts — Shared types
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import type { Context } from '@deepseek-ai/cordis'
|
|
25
|
+
import { registerConfigTool } from './tools/config.ts'
|
|
26
|
+
import { registerValidateTool } from './tools/validate.ts'
|
|
27
|
+
import { registerDecisionLogTool } from './tools/decision-log.ts'
|
|
28
|
+
import { registerContextTool } from './tools/context.ts'
|
|
29
|
+
import { registerReviewTool } from './tools/review.ts'
|
|
30
|
+
import { ITERATE_SKILL_PROMPT } from './skill-prompt.ts'
|
|
31
|
+
|
|
32
|
+
export const name = 'iterate-plugin'
|
|
33
|
+
export const inject = ['tools', 'systemPrompt']
|
|
34
|
+
|
|
35
|
+
export function apply(ctx: Context): void {
|
|
36
|
+
// 1. Register the 5 core tools
|
|
37
|
+
registerConfigTool(ctx)
|
|
38
|
+
registerValidateTool(ctx)
|
|
39
|
+
registerDecisionLogTool(ctx)
|
|
40
|
+
registerContextTool(ctx)
|
|
41
|
+
registerReviewTool(ctx)
|
|
42
|
+
|
|
43
|
+
// 2. Inject the iterate skill prompt as a system prompt section
|
|
44
|
+
// This teaches the model how to write iterate workflow scripts using the tools.
|
|
45
|
+
ctx.systemPrompt.section({
|
|
46
|
+
name: 'iterate-skill',
|
|
47
|
+
order: 100,
|
|
48
|
+
text: ITERATE_SKILL_PROMPT,
|
|
49
|
+
})
|
|
50
|
+
}
|