@devcxl/opencode-cabbage 0.1.0 → 0.2.1
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 +57 -54
- package/README.zh.md +91 -0
- package/assets/agents/dev-lifecycle.md +23 -15
- package/assets/agents/team/backend.md +8 -0
- package/assets/agents/team/frontend.md +8 -0
- package/assets/agents/team/reviewer.md +29 -13
- package/assets/skills/flow-code/SKILL.md +78 -9
- package/assets/skills/flow-design/SKILL.md +55 -6
- package/assets/skills/flow-handoff/SKILL.md +29 -0
- package/assets/skills/flow-release/SKILL.md +37 -1
- package/assets/skills/flow-requirements/SKILL.md +34 -0
- package/assets/skills/flow-review/SKILL.md +76 -5
- package/assets/skills/flow-setup/SKILL.md +32 -0
- package/assets/skills/flow-tasks/SKILL.md +43 -3
- package/assets/skills/flow-test/SKILL.md +31 -0
- package/dist/plugin/agents.d.ts +10 -0
- package/dist/plugin/agents.js +13 -0
- package/dist/plugin/agents.js.map +1 -1
- package/dist/plugin/goal.js +8 -2
- package/dist/plugin/goal.js.map +1 -1
- package/dist/plugin/prompt-lint.d.ts +10 -0
- package/dist/plugin/prompt-lint.js +160 -0
- package/dist/plugin/prompt-lint.js.map +1 -0
- package/dist/plugin/server.d.ts +8 -0
- package/dist/plugin/server.js +18 -3
- package/dist/plugin/server.js.map +1 -1
- package/dist/plugin/skills.d.ts +1 -1
- package/dist/plugin/skills.js +7 -1
- package/dist/plugin/skills.js.map +1 -1
- package/package.json +5 -1
|
@@ -25,8 +25,9 @@ git log $(git describe --tags --abbrev=0)..HEAD --oneline
|
|
|
25
25
|
npm version <major|minor|patch> --no-git-tag-version
|
|
26
26
|
# 更新 CHANGELOG.md
|
|
27
27
|
git commit -m "chore(release): v<version>"
|
|
28
|
+
BASE=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')
|
|
28
29
|
git tag v<version>
|
|
29
|
-
git push origin
|
|
30
|
+
git push origin $BASE --tags
|
|
30
31
|
```
|
|
31
32
|
|
|
32
33
|
### 3. Release 草稿(自动)
|
|
@@ -48,3 +49,38 @@ GitHub Releases 页面 → 检查 Release 草稿 → 点击 **Publish release**
|
|
|
48
49
|
|
|
49
50
|
## 后续
|
|
50
51
|
无需后续阶段。Flow 完成。
|
|
52
|
+
|
|
53
|
+
## Contract
|
|
54
|
+
|
|
55
|
+
### Trigger
|
|
56
|
+
由 `/release` 命令触发。**仅手动触发**,不包含在自动流程中。
|
|
57
|
+
|
|
58
|
+
### Inputs
|
|
59
|
+
- 版本号类型(patch/minor/major,来源:用户指定)
|
|
60
|
+
|
|
61
|
+
### Preconditions
|
|
62
|
+
- 所有 PR 已合并
|
|
63
|
+
- 默认分支最新
|
|
64
|
+
- 所有测试通过
|
|
65
|
+
|
|
66
|
+
### Procedure
|
|
67
|
+
1. 确认版本号
|
|
68
|
+
2. 更新版本(npm version)
|
|
69
|
+
3. 生成 Changelog
|
|
70
|
+
4. 创建 git tag → push → 触发 Release 草稿
|
|
71
|
+
5. 人工审核发布 → npm publish
|
|
72
|
+
|
|
73
|
+
### Outputs
|
|
74
|
+
- GitHub Release
|
|
75
|
+
- npm 包已发布
|
|
76
|
+
|
|
77
|
+
### Failure
|
|
78
|
+
- npm publish 失败 → 检查 npm 认证
|
|
79
|
+
- tag 已存在 → 提示版本冲突
|
|
80
|
+
|
|
81
|
+
### Idempotency
|
|
82
|
+
- 相同版本号 → 阻止
|
|
83
|
+
|
|
84
|
+
### Prohibited Actions
|
|
85
|
+
- 不在自动模式中执行
|
|
86
|
+
- 不跳过测试直接发布
|
|
@@ -46,3 +46,37 @@ gh issue create \
|
|
|
46
46
|
|
|
47
47
|
## 下一阶段
|
|
48
48
|
- **/design** — 基于此 PRD 进行技术设计
|
|
49
|
+
|
|
50
|
+
## Contract
|
|
51
|
+
|
|
52
|
+
### Trigger
|
|
53
|
+
由 `/requirements` 命令或 `@dev-lifecycle` Phase 0 触发。
|
|
54
|
+
|
|
55
|
+
### Inputs
|
|
56
|
+
- 用户提供的功能描述(来自消息文本)
|
|
57
|
+
|
|
58
|
+
### Preconditions
|
|
59
|
+
- `/setup` 已完成(gh CLI 可用,docs 目录就绪)
|
|
60
|
+
|
|
61
|
+
### Procedure
|
|
62
|
+
1. 按 interview-guide 进行需求访谈
|
|
63
|
+
2. 输出 PRD 到 `docs/prd/<title>.md`
|
|
64
|
+
3. 记录 Out of Scope 到 `docs/dev/out-of-scope.md`
|
|
65
|
+
4. 创建 Parent GitHub Issue
|
|
66
|
+
|
|
67
|
+
### Outputs
|
|
68
|
+
- `docs/prd/<title>.md` — PRD 文档
|
|
69
|
+
- `docs/dev/out-of-scope.md` — 排除范围记录
|
|
70
|
+
- GitHub Parent Issue
|
|
71
|
+
|
|
72
|
+
### Failure
|
|
73
|
+
- gh CLI 不可用 → 提示先执行 /setup
|
|
74
|
+
- Issue 创建失败 → 记录错误,不阻塞 PRD 写入
|
|
75
|
+
|
|
76
|
+
### Idempotency
|
|
77
|
+
- 如果 PRD 文件已存在 → 更新而非覆盖
|
|
78
|
+
- 如果 Parent Issue 已创建 → 追加评论而非重复创建
|
|
79
|
+
|
|
80
|
+
### Prohibited Actions
|
|
81
|
+
- 不跳过访谈直接输出 PRD
|
|
82
|
+
- 不省略 Out of Scope 记录
|
|
@@ -68,15 +68,50 @@ gh issue close <issue-num> --comment "已完成,已合并至 main"
|
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
### 9. 清理 Worktree
|
|
71
|
-
PR
|
|
71
|
+
PR 合并后,安全清理对应的 worktree 和分支:
|
|
72
72
|
|
|
73
73
|
```bash
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
WORKTREE=".worktree/<task-slug>"
|
|
75
|
+
BRANCH="feat/<task-slug>"
|
|
76
|
+
|
|
77
|
+
# Preflight 检查
|
|
78
|
+
echo "=== Worktree 清理 Preflight ==="
|
|
79
|
+
|
|
80
|
+
# 1. 确认 PR 已合并
|
|
81
|
+
PR_NUM=<pr-number>
|
|
82
|
+
if ! gh pr view "$PR_NUM" --json merged --jq '.merged' 2>/dev/null | grep -q true; then
|
|
83
|
+
echo "ERROR: PR #$PR_NUM 未合并,跳过清理"
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# 2. 确认分支已推送到远程
|
|
88
|
+
if git ls-remote --exit-code origin "$BRANCH" >/dev/null 2>&1; then
|
|
89
|
+
echo "分支 $BRANCH 已推送到远程"
|
|
90
|
+
else
|
|
91
|
+
echo "WARNING: 分支 $BRANCH 未推送到远程,但 PR 已合并,继续清理"
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# 3. 检查 worktree 是否干净
|
|
95
|
+
if [ -d "$WORKTREE" ]; then
|
|
96
|
+
DIRTY=$(git -C "$WORKTREE" status --porcelain)
|
|
97
|
+
if [ -n "$DIRTY" ]; then
|
|
98
|
+
echo "WARNING: Worktree 有未提交变更:"
|
|
99
|
+
echo "$DIRTY"
|
|
100
|
+
echo "暂停。如需强制清理请手动执行 --force"
|
|
101
|
+
exit 1
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# 4. 全部通过 → 清理
|
|
105
|
+
git worktree remove "$WORKTREE"
|
|
106
|
+
git branch -D "$BRANCH" 2>/dev/null || true
|
|
107
|
+
echo "Worktree 已清理:$WORKTREE"
|
|
108
|
+
else
|
|
109
|
+
echo "Worktree 不存在,跳过清理"
|
|
110
|
+
fi
|
|
77
111
|
```
|
|
78
112
|
|
|
79
|
-
>
|
|
113
|
+
> 清理前必须验证 PR 已合并、worktree 干净。只有在所有 preflight 检查通过后才删除。
|
|
114
|
+
> 如果 PR 已合并但 worktree 仍有未提交变更,暂停并通知用户,不自动 --force。
|
|
80
115
|
|
|
81
116
|
## Output
|
|
82
117
|
- PR 已审查
|
|
@@ -86,3 +121,39 @@ git branch -D feat/<task-slug>
|
|
|
86
121
|
|
|
87
122
|
## 后续
|
|
88
123
|
- **/release** — 发布(如所有 PR 已合并)
|
|
124
|
+
|
|
125
|
+
## Contract
|
|
126
|
+
|
|
127
|
+
### Trigger
|
|
128
|
+
由 `/review` 命令或 `@dev-lifecycle` Phase 3 审查步骤触发。
|
|
129
|
+
|
|
130
|
+
### Inputs
|
|
131
|
+
- PR 编号(来源:`/code` 产出)
|
|
132
|
+
|
|
133
|
+
### Preconditions
|
|
134
|
+
- `/code` 已完成 → PR 已创建
|
|
135
|
+
|
|
136
|
+
### Procedure
|
|
137
|
+
1. 获取 PR diff 和元数据
|
|
138
|
+
2. 双轴审查(规范轴 + 规格轴)
|
|
139
|
+
3. 输出结构化审查报告
|
|
140
|
+
4. 编排器发布审查结果
|
|
141
|
+
5. 等待 CI 通过后合并
|
|
142
|
+
6. 关闭关联 Sub Issue
|
|
143
|
+
7. 安全清理 Worktree(Preflight)
|
|
144
|
+
|
|
145
|
+
### Outputs
|
|
146
|
+
- 结构化审查报告(APPROVED / CHANGES_REQUESTED)
|
|
147
|
+
- PR 已合并(条件满足时)
|
|
148
|
+
|
|
149
|
+
### Failure
|
|
150
|
+
- Critical/High → Request Changes
|
|
151
|
+
- Worktree 清理失败 → 记录警告,不阻塞
|
|
152
|
+
|
|
153
|
+
### Idempotency
|
|
154
|
+
- 已合并的 PR → 跳过
|
|
155
|
+
- 已审查的 PR → 更新结论
|
|
156
|
+
|
|
157
|
+
### Prohibited Actions
|
|
158
|
+
- 不使用默认 --force 清理
|
|
159
|
+
- 不直接执行 gh pr merge(Orchestrator 执行)
|
|
@@ -41,3 +41,35 @@ echo "setup-complete" > .opencode/opencode-cabbage/setup-complete
|
|
|
41
41
|
- `docs/` 目录已就绪
|
|
42
42
|
- 开发环境已验证
|
|
43
43
|
- 可开始 `/requirements`
|
|
44
|
+
|
|
45
|
+
## Contract
|
|
46
|
+
|
|
47
|
+
### Trigger
|
|
48
|
+
由 `/setup` 命令触发。首次使用插件或切换新项目时执行。
|
|
49
|
+
|
|
50
|
+
### Inputs
|
|
51
|
+
无外部输入。从当前工作目录检测项目状态。
|
|
52
|
+
|
|
53
|
+
### Preconditions
|
|
54
|
+
无。不要求任何前置阶段。
|
|
55
|
+
|
|
56
|
+
### Procedure
|
|
57
|
+
1. 创建 docs 目录结构
|
|
58
|
+
2. 验证 gh CLI 和 GitHub 远程
|
|
59
|
+
3. 写入完成标记
|
|
60
|
+
|
|
61
|
+
### Outputs
|
|
62
|
+
- `docs/` 目录树(prd, adr, dev/specs, dev/tasks, dev/api, dev/db, dev/guides, dev/handoff)
|
|
63
|
+
- `.opencode/opencode-cabbage/setup-complete` 标记文件
|
|
64
|
+
|
|
65
|
+
### Failure
|
|
66
|
+
- 目录创建失败 → 报告错误并退出
|
|
67
|
+
- gh auth 失败 → 提示用户执行 `gh auth login`
|
|
68
|
+
|
|
69
|
+
### Idempotency
|
|
70
|
+
- 已存在的目录跳过
|
|
71
|
+
- 已存在 `setup-complete` 标记则跳过全部步骤
|
|
72
|
+
|
|
73
|
+
### Prohibited Actions
|
|
74
|
+
- 不删除已有目录或文件
|
|
75
|
+
- 不修改项目代码
|
|
@@ -79,18 +79,23 @@ gh issue create \
|
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
### 4. 提交任务文件
|
|
82
|
-
|
|
82
|
+
任务定义文件通过 Planning PR 合入默认分支:
|
|
83
83
|
|
|
84
84
|
```bash
|
|
85
|
+
# 探测默认分支
|
|
86
|
+
BASE=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' 2>/dev/null || echo "main")
|
|
87
|
+
|
|
88
|
+
git checkout -b chore/plan-tasks-<slug> $BASE
|
|
85
89
|
git add docs/dev/tasks/<YYYY-MM-DD-NNN-slug>/
|
|
86
90
|
git commit -m "docs: <title> — 任务定义"
|
|
87
|
-
git push origin
|
|
91
|
+
git push origin chore/plan-tasks-<slug>
|
|
92
|
+
gh pr create --title "docs: <title> — 任务定义" --base $BASE
|
|
88
93
|
```
|
|
89
94
|
|
|
90
95
|
## Output
|
|
91
96
|
- `docs/dev/tasks/*.md` — 独立任务文件
|
|
92
97
|
- GitHub Sub Issues 已创建(依赖关系在 body 中声明)
|
|
93
|
-
-
|
|
98
|
+
- 任务文件通过 Planning PR 合入默认分支
|
|
94
99
|
|
|
95
100
|
## Sub Issue 关闭时机
|
|
96
101
|
Sub Issue 不在 `/tasks` 阶段关闭,而是在对应 PR 合并后自动关闭:
|
|
@@ -102,3 +107,38 @@ Sub Issue 不在 `/tasks` 阶段关闭,而是在对应 PR 合并后自动关
|
|
|
102
107
|
|
|
103
108
|
## 后续
|
|
104
109
|
- **/code** — 认领 Sub Issue 开始编码
|
|
110
|
+
|
|
111
|
+
## Contract
|
|
112
|
+
|
|
113
|
+
### Trigger
|
|
114
|
+
由 `/tasks` 命令或 `@dev-lifecycle` Phase 2 触发。
|
|
115
|
+
|
|
116
|
+
### Inputs
|
|
117
|
+
- `docs/dev/specs/<title>.md` — 技术方案
|
|
118
|
+
- Parent Issue 编号
|
|
119
|
+
|
|
120
|
+
### Preconditions
|
|
121
|
+
- `/design` 已完成 → 技术方案和 ADR 存在
|
|
122
|
+
|
|
123
|
+
### Procedure
|
|
124
|
+
1. 基于技术方案拆解 DAG
|
|
125
|
+
2. 创建 Task Manifest (`manifest.yaml`) 和任务文件
|
|
126
|
+
3. 为每个任务创建 GitHub Sub Issue
|
|
127
|
+
4. 通过 Planning PR 提交任务文件
|
|
128
|
+
|
|
129
|
+
### Outputs
|
|
130
|
+
- `docs/dev/tasks/<feature-slug>/manifest.yaml` — 任务清单
|
|
131
|
+
- `docs/dev/tasks/<feature-slug>/*.md` — 任务文件
|
|
132
|
+
- GitHub Sub Issues(含依赖声明)
|
|
133
|
+
|
|
134
|
+
### Failure
|
|
135
|
+
- DAG 存在环形依赖 → 阻止并报告
|
|
136
|
+
- Sub Issue 创建失败 → 记录失败项
|
|
137
|
+
|
|
138
|
+
### Idempotency
|
|
139
|
+
- 任务文件已存在 → 读取并更新
|
|
140
|
+
- Sub Issue 已创建 → 更新而非重复创建
|
|
141
|
+
|
|
142
|
+
### Prohibited Actions
|
|
143
|
+
- 不跳过 DAG 依赖检查
|
|
144
|
+
- 不直接 push 到默认分支
|
|
@@ -42,3 +42,34 @@ gh pr checks <pr-number> --watch
|
|
|
42
42
|
|
|
43
43
|
## 后续
|
|
44
44
|
- **/review** — 审查 PR
|
|
45
|
+
|
|
46
|
+
## Contract
|
|
47
|
+
|
|
48
|
+
### Trigger
|
|
49
|
+
由 `/test` 命令触发。在已创建的 PR 上运行 CI 测试。
|
|
50
|
+
|
|
51
|
+
### Inputs
|
|
52
|
+
- PR 编号(来源:`/code` 产出)
|
|
53
|
+
|
|
54
|
+
### Preconditions
|
|
55
|
+
- `/code` 已完成 → PR 已创建
|
|
56
|
+
|
|
57
|
+
### Procedure
|
|
58
|
+
1. 检查 CI 配置是否存在
|
|
59
|
+
2. 触发 CI 运行
|
|
60
|
+
3. 监控运行状态
|
|
61
|
+
4. 汇报结果
|
|
62
|
+
|
|
63
|
+
### Outputs
|
|
64
|
+
- CI 运行结果摘要
|
|
65
|
+
|
|
66
|
+
### Failure
|
|
67
|
+
- CI 失败 → 分析日志并建议修复
|
|
68
|
+
- 无 CI 配置 → 引导用户创建 .github/workflows/ci.yml
|
|
69
|
+
|
|
70
|
+
### Idempotency
|
|
71
|
+
- 重复触发同一 PR → 覆盖前一次运行
|
|
72
|
+
|
|
73
|
+
### Prohibited Actions
|
|
74
|
+
- 不修改 CI 配置
|
|
75
|
+
- 不触发非当前 PR 的 CI
|
package/dist/plugin/agents.d.ts
CHANGED
|
@@ -4,12 +4,22 @@ export interface AgentTools {
|
|
|
4
4
|
write?: boolean;
|
|
5
5
|
edit?: boolean;
|
|
6
6
|
}
|
|
7
|
+
export interface AgentCapabilities {
|
|
8
|
+
create_pr: boolean;
|
|
9
|
+
merge_pr: boolean;
|
|
10
|
+
modify_files: boolean;
|
|
11
|
+
run_tests: boolean;
|
|
12
|
+
push_branch: boolean;
|
|
13
|
+
approve_review: boolean;
|
|
14
|
+
complete_goal: boolean;
|
|
15
|
+
}
|
|
7
16
|
export interface AgentEntry {
|
|
8
17
|
key: string;
|
|
9
18
|
description?: string;
|
|
10
19
|
mode?: "subagent" | "primary" | "all";
|
|
11
20
|
color?: string;
|
|
12
21
|
tools?: AgentTools;
|
|
22
|
+
capabilities?: AgentCapabilities;
|
|
13
23
|
prompt: string;
|
|
14
24
|
}
|
|
15
25
|
export declare function loadAgents(agentsDir: string): AgentEntry[];
|
package/dist/plugin/agents.js
CHANGED
|
@@ -29,12 +29,25 @@ function parseAgentFile(filePath) {
|
|
|
29
29
|
edit: Boolean(toolsRaw.edit),
|
|
30
30
|
}
|
|
31
31
|
: undefined;
|
|
32
|
+
const capabilitiesRaw = parsed.capabilities;
|
|
33
|
+
const capabilities = capabilitiesRaw && typeof capabilitiesRaw === "object" && !Array.isArray(capabilitiesRaw)
|
|
34
|
+
? {
|
|
35
|
+
create_pr: Boolean(capabilitiesRaw.create_pr),
|
|
36
|
+
merge_pr: Boolean(capabilitiesRaw.merge_pr),
|
|
37
|
+
modify_files: Boolean(capabilitiesRaw.modify_files),
|
|
38
|
+
run_tests: Boolean(capabilitiesRaw.run_tests),
|
|
39
|
+
push_branch: Boolean(capabilitiesRaw.push_branch),
|
|
40
|
+
approve_review: Boolean(capabilitiesRaw.approve_review),
|
|
41
|
+
complete_goal: Boolean(capabilitiesRaw.complete_goal),
|
|
42
|
+
}
|
|
43
|
+
: undefined;
|
|
32
44
|
return {
|
|
33
45
|
key: name,
|
|
34
46
|
description: parsed.description,
|
|
35
47
|
mode: parsed.mode,
|
|
36
48
|
color: parsed.color,
|
|
37
49
|
tools,
|
|
50
|
+
capabilities,
|
|
38
51
|
prompt: body,
|
|
39
52
|
};
|
|
40
53
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/plugin/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAC/D,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/plugin/agents.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin/goal.js
CHANGED
|
@@ -40,7 +40,9 @@ Work from evidence — inspect the current state before relying on anything.
|
|
|
40
40
|
If the work is not done, just keep working. Do not narrate that you are continuing — execute.`;
|
|
41
41
|
}
|
|
42
42
|
export function verifyAgentPrompt() {
|
|
43
|
-
return `You are
|
|
43
|
+
return `You are the goal-verify agent. Your ONLY job is to determine whether a goal has been fully achieved by inspecting the current state.
|
|
44
|
+
|
|
45
|
+
You are the only agent authorized to call goal({op:"complete"}). Other agents (reviewer, backend, frontend, architect) cannot complete the goal.
|
|
44
46
|
|
|
45
47
|
You start with a FRESH context — do not assume any prior work was done correctly.
|
|
46
48
|
|
|
@@ -58,7 +60,7 @@ First step: Call goal({op:"get"}) to retrieve the objective and completion crite
|
|
|
58
60
|
- Check imports, exports, types resolve correctly
|
|
59
61
|
4. Classify each finding: SATISFIED / NOT SATISFIED / UNCERTAIN
|
|
60
62
|
5. If ALL requirements are SATISFIED:
|
|
61
|
-
Call goal({op:"complete"})
|
|
63
|
+
Call goal({op:"complete"}) — only you can do this
|
|
62
64
|
6. If ANY requirement is NOT SATISFIED or UNCERTAIN:
|
|
63
65
|
Do NOT call goal({op:"complete"}). Return a detailed report.
|
|
64
66
|
|
|
@@ -121,6 +123,10 @@ Use a single op field:
|
|
|
121
123
|
return `Error: sub-agents cannot call goal({op:"${args.op}"}). Goal lifecycle operations are restricted to the main session.`;
|
|
122
124
|
}
|
|
123
125
|
if (isSubAgent && args.op === "complete") {
|
|
126
|
+
const agentName = ctx.agent;
|
|
127
|
+
if (agentName !== "goal-verify") {
|
|
128
|
+
return `Error: only the goal-verify agent can complete the goal. Agent "${agentName}" is not authorized.`;
|
|
129
|
+
}
|
|
124
130
|
const parent = await readGoal(client, targetSessionID);
|
|
125
131
|
if (!parent.goal)
|
|
126
132
|
return "No goal to complete in the parent session.";
|
package/dist/plugin/goal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal.js","sourceRoot":"","sources":["../../src/plugin/goal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAY1D,SAAS,UAAU,CAAC,SAAiB,EAAE,mBAA2B;IAChE,OAAO;QACL,SAAS,EAAE,SAAS,CAAC,IAAI,EAAE;QAC3B,mBAAmB,EAAE,mBAAmB,CAAC,IAAI,EAAE;QAC/C,MAAM,EAAE,QAAQ;QAChB,iBAAiB,EAAE,CAAC;KACrB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAc,EAAE,MAAkB;IAChE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAA;QAC9C,KAAK,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAA;QAC9C,KAAK,UAAU,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAA;QAChD,OAAO,CAAC,CAAC,OAAO,KAAK,CAAA;IACvB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAc;IACvC,OAAO;QACL,SAAS,IAAI,CAAC,SAAS,EAAE;QACzB,yBAAyB,IAAI,CAAC,mBAAmB,EAAE;QACnD,WAAW,IAAI,CAAC,MAAM,EAAE;KACzB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAEnC,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,mBAA2B;IAC/E,OAAO;;;EAGP,SAAS;;;;EAIT,mBAAmB;;;;;8FAKyE,CAAA;AAC9F,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO
|
|
1
|
+
{"version":3,"file":"goal.js","sourceRoot":"","sources":["../../src/plugin/goal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { globSync } from "node:fs";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const CONTRACT_SECTIONS = [
|
|
5
|
+
"Trigger", "Inputs", "Preconditions", "Procedure",
|
|
6
|
+
"Outputs", "Failure", "Idempotency", "Prohibited Actions",
|
|
7
|
+
];
|
|
8
|
+
const FORBIDDEN_PATTERNS = [
|
|
9
|
+
// Only flag direct pushes to hardcoded branches, not tag pushes
|
|
10
|
+
{ pattern: /\bgit push origin main\b(?!\s+--tags)/, rule: "no-hardcoded-default-branch", message: "contains hardcoded 'git push origin main'" },
|
|
11
|
+
{ pattern: /\bgit push origin master\b(?!\s+--tags)/, rule: "no-hardcoded-default-branch", message: "contains hardcoded 'git push origin master'" },
|
|
12
|
+
{ pattern: /\bgit push origin dev\b(?!\s+--tags)/, rule: "no-hardcoded-default-branch", message: "contains hardcoded 'git push origin dev'" },
|
|
13
|
+
{ pattern: /^\s*git add \.\s*$/m, rule: "no-blanket-git-add", message: "contains blanket 'git add .' without context" },
|
|
14
|
+
{ pattern: /git worktree remove.*--force/, rule: "no-default-force-cleanup", message: "contains default --force worktree cleanup" },
|
|
15
|
+
];
|
|
16
|
+
function findMdFiles(root, dirs) {
|
|
17
|
+
const results = [];
|
|
18
|
+
for (const dir of dirs) {
|
|
19
|
+
const full = path.join(root, dir);
|
|
20
|
+
if (!existsSync(full))
|
|
21
|
+
continue;
|
|
22
|
+
const pattern = path.join(full, "**", "*.md").replace(/\\/g, "/");
|
|
23
|
+
results.push(...globSync(pattern));
|
|
24
|
+
}
|
|
25
|
+
return results;
|
|
26
|
+
}
|
|
27
|
+
function checkRelativeRefs(content, filePath) {
|
|
28
|
+
const findings = [];
|
|
29
|
+
const refPattern = /`([^`]*\.md)`/g;
|
|
30
|
+
let match;
|
|
31
|
+
while ((match = refPattern.exec(content)) !== null) {
|
|
32
|
+
const ref = match[1];
|
|
33
|
+
if (ref.startsWith("/") || ref.startsWith("http"))
|
|
34
|
+
continue;
|
|
35
|
+
if (ref.includes("_prompts/") || ref.includes("_context/"))
|
|
36
|
+
continue;
|
|
37
|
+
if (ref.includes("<") && ref.includes(">"))
|
|
38
|
+
continue;
|
|
39
|
+
// only flag paths starting with ../ or ./
|
|
40
|
+
if (!ref.startsWith("."))
|
|
41
|
+
continue;
|
|
42
|
+
const dir = path.dirname(filePath);
|
|
43
|
+
const resolved = path.resolve(dir, ref);
|
|
44
|
+
if (!existsSync(resolved)) {
|
|
45
|
+
findings.push({
|
|
46
|
+
severity: "error",
|
|
47
|
+
file: filePath,
|
|
48
|
+
rule: "broken-reference",
|
|
49
|
+
message: `references non-existent file: \`${ref}\``,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return findings;
|
|
54
|
+
}
|
|
55
|
+
function checkContractCompleteness(content, filePath) {
|
|
56
|
+
const findings = [];
|
|
57
|
+
for (const section of CONTRACT_SECTIONS) {
|
|
58
|
+
const headingRegex = new RegExp(`^### ${section}$`, "m");
|
|
59
|
+
if (!headingRegex.test(content)) {
|
|
60
|
+
findings.push({
|
|
61
|
+
severity: "warn",
|
|
62
|
+
file: filePath,
|
|
63
|
+
rule: "missing-contract-section",
|
|
64
|
+
message: `missing Contract section: ### ${section}`,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return findings;
|
|
69
|
+
}
|
|
70
|
+
function checkForbiddenPatterns(content, filePath) {
|
|
71
|
+
const findings = [];
|
|
72
|
+
for (const { pattern, rule, message } of FORBIDDEN_PATTERNS) {
|
|
73
|
+
if (pattern.test(content)) {
|
|
74
|
+
findings.push({
|
|
75
|
+
severity: "error",
|
|
76
|
+
file: filePath,
|
|
77
|
+
rule,
|
|
78
|
+
message,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return findings;
|
|
83
|
+
}
|
|
84
|
+
function checkAgentCapabilityConsistency(content, filePath) {
|
|
85
|
+
const findings = [];
|
|
86
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
87
|
+
if (!frontmatterMatch)
|
|
88
|
+
return findings;
|
|
89
|
+
const fm = frontmatterMatch[1];
|
|
90
|
+
const body = content.slice(frontmatterMatch[0].length);
|
|
91
|
+
// Check reviewer: complete_goal must be false, and must not contain positive directive
|
|
92
|
+
if (filePath.includes("reviewer")) {
|
|
93
|
+
if (/complete_goal:\s*true/.test(fm)) {
|
|
94
|
+
findings.push({
|
|
95
|
+
severity: "error",
|
|
96
|
+
file: filePath,
|
|
97
|
+
rule: "reviewer-capability-conflict",
|
|
98
|
+
message: "reviewer agent declares complete_goal: true (should be false)",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
// Only flag goal({op:"complete"}) if it's not in a negation/prohibition context
|
|
102
|
+
if (/\bgoal\(\{op:"complete"\}\)/.test(body)) {
|
|
103
|
+
// Check if the surrounding context is a prohibition
|
|
104
|
+
const idx = body.indexOf("goal({op:\"complete\"})");
|
|
105
|
+
const before = body.slice(Math.max(0, idx - 100), idx);
|
|
106
|
+
const isNegation = /不调用|不.*complete|not.*complete|cannot complete|blocked/i.test(before);
|
|
107
|
+
if (!isNegation) {
|
|
108
|
+
findings.push({
|
|
109
|
+
severity: "error",
|
|
110
|
+
file: filePath,
|
|
111
|
+
rule: "reviewer-capability-conflict",
|
|
112
|
+
message: "reviewer prompt contains positive goal({op:'complete'}) directive",
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Check worker agents: create_pr must be false
|
|
118
|
+
if (filePath.includes("backend") || filePath.includes("frontend")) {
|
|
119
|
+
if (/create_pr:\s*true/.test(fm)) {
|
|
120
|
+
findings.push({
|
|
121
|
+
severity: "error",
|
|
122
|
+
file: filePath,
|
|
123
|
+
rule: "worker-capability-conflict",
|
|
124
|
+
message: "worker agent declares create_pr: true (should be false)",
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (body.includes("gh pr create")) {
|
|
128
|
+
findings.push({
|
|
129
|
+
severity: "error",
|
|
130
|
+
file: filePath,
|
|
131
|
+
rule: "worker-capability-conflict",
|
|
132
|
+
message: "worker prompt contains 'gh pr create' directive",
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return findings;
|
|
137
|
+
}
|
|
138
|
+
export function lintAll(projectRoot) {
|
|
139
|
+
const assetDirs = ["assets/agents", "assets/skills", "assets/commands", "assets/prompts"];
|
|
140
|
+
const files = findMdFiles(projectRoot, assetDirs);
|
|
141
|
+
const allFindings = [];
|
|
142
|
+
for (const file of files) {
|
|
143
|
+
const content = readFileSync(file, "utf8");
|
|
144
|
+
if (file.includes("SKILL.md")) {
|
|
145
|
+
allFindings.push(...checkContractCompleteness(content, file));
|
|
146
|
+
}
|
|
147
|
+
allFindings.push(...checkForbiddenPatterns(content, file));
|
|
148
|
+
allFindings.push(...checkRelativeRefs(content, file));
|
|
149
|
+
if (file.includes("agents/")) {
|
|
150
|
+
allFindings.push(...checkAgentCapabilityConsistency(content, file));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const errors = allFindings.filter(f => f.severity === "error");
|
|
154
|
+
const warnings = allFindings.filter(f => f.severity === "warn");
|
|
155
|
+
return {
|
|
156
|
+
findings: allFindings,
|
|
157
|
+
passed: errors.length === 0,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=prompt-lint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-lint.js","sourceRoot":"","sources":["../../src/plugin/prompt-lint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,IAAI,MAAM,WAAW,CAAA;AAS5B,MAAM,iBAAiB,GAAG;IACxB,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW;IACjD,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,oBAAoB;CAC1D,CAAA;AAED,MAAM,kBAAkB,GAA8D;IACpF,gEAAgE;IAChE,EAAE,OAAO,EAAE,uCAAuC,EAAE,IAAI,EAAE,6BAA6B,EAAE,OAAO,EAAE,2CAA2C,EAAE;IAC/I,EAAE,OAAO,EAAE,yCAAyC,EAAE,IAAI,EAAE,6BAA6B,EAAE,OAAO,EAAE,6CAA6C,EAAE;IACnJ,EAAE,OAAO,EAAE,sCAAsC,EAAE,IAAI,EAAE,6BAA6B,EAAE,OAAO,EAAE,0CAA0C,EAAE;IAC7I,EAAE,OAAO,EAAE,qBAAqB,EAAE,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,8CAA8C,EAAE;IACvH,EAAE,OAAO,EAAE,8BAA8B,EAAE,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,2CAA2C,EAAE;CACpI,CAAA;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,IAAc;IAC/C,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAQ;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACjE,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;IACpC,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAe,EAAE,QAAgB;IAC1D,MAAM,QAAQ,GAAkB,EAAE,CAAA;IAClC,MAAM,UAAU,GAAG,gBAAgB,CAAA;IACnC,IAAI,KAAK,CAAA;IACT,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACnD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACpB,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,SAAQ;QAC3D,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,SAAQ;QACpE,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAQ;QACpD,0CAA0C;QAC1C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QACvC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,kBAAkB;gBACxB,OAAO,EAAE,mCAAmC,GAAG,IAAI;aACpD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,yBAAyB,CAAC,OAAe,EAAE,QAAgB;IAClE,MAAM,QAAQ,GAAkB,EAAE,CAAA;IAClC,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACxC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,QAAQ,OAAO,GAAG,EAAE,GAAG,CAAC,CAAA;QACxD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,0BAA0B;gBAChC,OAAO,EAAE,iCAAiC,OAAO,EAAE;aACpD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAe,EAAE,QAAgB;IAC/D,MAAM,QAAQ,GAAkB,EAAE,CAAA;IAClC,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,kBAAkB,EAAE,CAAC;QAC5D,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,QAAQ;gBACd,IAAI;gBACJ,OAAO;aACR,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,+BAA+B,CAAC,OAAe,EAAE,QAAgB;IACxE,MAAM,QAAQ,GAAkB,EAAE,CAAA;IAClC,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAC/D,IAAI,CAAC,gBAAgB;QAAE,OAAO,QAAQ,CAAA;IAEtC,MAAM,EAAE,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAA;IAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;IAEtD,uFAAuF;IACvF,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,IAAI,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACrC,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,8BAA8B;gBACpC,OAAO,EAAE,+DAA+D;aACzE,CAAC,CAAA;QACJ,CAAC;QACD,gFAAgF;QAChF,IAAI,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,oDAAoD;YACpD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAA;YACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;YACtD,MAAM,UAAU,GAAG,wDAAwD,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACxF,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,QAAQ,CAAC,IAAI,CAAC;oBACZ,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,8BAA8B;oBACpC,OAAO,EAAE,mEAAmE;iBAC7E,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAClE,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACjC,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,4BAA4B;gBAClC,OAAO,EAAE,yDAAyD;aACnE,CAAC,CAAA;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,4BAA4B;gBAClC,OAAO,EAAE,iDAAiD;aAC3D,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,WAAmB;IACzC,MAAM,SAAS,GAAG,CAAC,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAA;IACzF,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IACjD,MAAM,WAAW,GAAkB,EAAE,CAAA;IAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAE1C,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,WAAW,CAAC,IAAI,CAAC,GAAG,yBAAyB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;QAC/D,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;QAC1D,WAAW,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;QAErD,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,WAAW,CAAC,IAAI,CAAC,GAAG,+BAA+B,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;QACrE,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAA;IAC9D,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAA;IAE/D,OAAO;QACL,QAAQ,EAAE,WAAW;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;KAC5B,CAAA;AACH,CAAC"}
|
package/dist/plugin/server.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
2
|
+
interface AgentToolConfig {
|
|
3
|
+
tools?: Record<string, boolean>;
|
|
4
|
+
}
|
|
5
|
+
interface GoalToolConfig extends AgentToolConfig {
|
|
6
|
+
agent?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export declare function configureGoalTools(config: GoalToolConfig): void;
|
|
2
9
|
export declare function createOpencodeCabbage(packageRoot: string): Plugin;
|
|
10
|
+
export {};
|