Pin the extension roadmap and downstream spike
Why: Downstream products need a published extension surface, contract checks, and a sample plugin that does not modify the base. Evidence: scripts/lint-boundaries.sh printed boundaries ok. examples/downstream-rdm go test passed. Submodule pointers record the core, documents, backend, ui, and frontend commits for this roadmap. Impact: make test runs the boundary lint first. make plugin-new scaffolds a declaration plugin. Version tags and remote downstream repositories are not created. Refs: .task/feature-base-extension-roadmap.md Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
# 依赖边界:公开扩展 SDK 与示例不得导入后端 internal。
|
||||
# pkg/extension/link 是唯一例外:下游空白导入它才能把 extension.Main 接到产品组合根。
|
||||
set -euo pipefail
|
||||
root=$(cd "$(dirname "$0")/.." && pwd)
|
||||
fail=0
|
||||
|
||||
check() {
|
||||
local path="$1"
|
||||
if [ -d "$path" ] && grep -R -n --include='*.go' --include='*.ts' --include='*.tsx' 'agent-system-backend/internal' "$path" >/dev/null; then
|
||||
echo "boundary: $path imports agent-system-backend/internal" >&2
|
||||
grep -R -n --include='*.go' --include='*.ts' --include='*.tsx' 'agent-system-backend/internal' "$path" >&2
|
||||
fail=1
|
||||
fi
|
||||
}
|
||||
|
||||
sdk="$root/modules/backend/pkg/extension"
|
||||
if [ -d "$sdk" ]; then
|
||||
hits=$(grep -R -n --include='*.go' 'agent-system-backend/internal' "$sdk" | grep -v '/link/' || true)
|
||||
if [ -n "$hits" ]; then
|
||||
echo "boundary: pkg/extension imports agent-system-backend/internal" >&2
|
||||
echo "$hits" >&2
|
||||
fail=1
|
||||
fi
|
||||
fi
|
||||
check "$root/examples"
|
||||
if [ "$fail" -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
echo "boundaries ok"
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
# 生成声明式插件骨架:make plugin-new NAME=<id>
|
||||
set -euo pipefail
|
||||
name="${1:-}"
|
||||
if [ -z "$name" ]; then
|
||||
echo "usage: plugin-new.sh <id>" >&2
|
||||
exit 2
|
||||
fi
|
||||
root=$(cd "$(dirname "$0")/.." && pwd)
|
||||
dest="$root/examples/plugins/$name"
|
||||
if [ -e "$dest" ]; then
|
||||
echo "exists: $dest" >&2
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p "$dest/tools" "$dest/skills" "$dest/pages"
|
||||
cat > "$dest/plugin.json" <<EOF
|
||||
{
|
||||
"id": "$name",
|
||||
"name": "$name",
|
||||
"version": "0.1.0",
|
||||
"apiVersion": "2.0-experimental",
|
||||
"requires": { "network": [] },
|
||||
"provides": { "skills": ["welcome"], "pages": ["home"] }
|
||||
}
|
||||
EOF
|
||||
printf '# %s\n\n描述这个技能做什么、何时使用。\n' "$name" > "$dest/skills/welcome.md"
|
||||
cat > "$dest/pages/home.json" <<EOF
|
||||
{ "id": "home", "title": "$name", "module": "./page.mjs" }
|
||||
EOF
|
||||
cat > "$dest/page.mjs" <<'EOF'
|
||||
export function mount(el, bridge) {
|
||||
el.textContent = '插件页面'
|
||||
el.dataset.bridge = bridge ? 'ready' : ''
|
||||
}
|
||||
export function unmount() {}
|
||||
EOF
|
||||
echo "wrote $dest"
|
||||
Reference in New Issue
Block a user