create-agentic-dev-env 0.2.5 → 0.2.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/lib/runner.js
CHANGED
|
@@ -8,10 +8,12 @@ const END = '<!-- ADE:END -->'
|
|
|
8
8
|
|
|
9
9
|
function run(cmd, pkgDir) {
|
|
10
10
|
try {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const i = process.argv.indexOf('--workspaces')
|
|
12
|
+
const ws = i !== -1 ? process.argv[i + 1] : undefined
|
|
13
|
+
if (cmd === 'init') init(process.cwd(), pkgDir, ws)
|
|
14
|
+
else if (cmd === 'update') update(process.cwd(), ws)
|
|
13
15
|
else {
|
|
14
|
-
console.error('Usage: init | update')
|
|
16
|
+
console.error('Usage: init | update [--workspaces <path>]')
|
|
15
17
|
process.exit(1)
|
|
16
18
|
}
|
|
17
19
|
} catch (e) {
|
|
@@ -20,15 +22,15 @@ function run(cmd, pkgDir) {
|
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
function init(cwd, srcDir) {
|
|
25
|
+
function init(cwd, srcDir, ws) {
|
|
24
26
|
if (fs.existsSync(path.join(cwd, '.ade.json'))) {
|
|
25
27
|
throw new Error('Already initialized here; run update instead')
|
|
26
28
|
}
|
|
27
|
-
install(cwd, srcDir)
|
|
29
|
+
install(cwd, srcDir, ws)
|
|
28
30
|
console.log('ADE init done')
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
function update(cwd) {
|
|
33
|
+
function update(cwd, ws) {
|
|
32
34
|
const cfgPath = path.join(cwd, '.ade.json')
|
|
33
35
|
if (!fs.existsSync(cfgPath)) throw new Error('Not initialized here; run init first')
|
|
34
36
|
const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8'))
|
|
@@ -40,7 +42,7 @@ function update(cwd) {
|
|
|
40
42
|
try {
|
|
41
43
|
execSync(`git clone --depth 1 "${cfg.source}" "${path.join(tmp, 'repo')}"`, { stdio: 'inherit' })
|
|
42
44
|
removeManaged(cwd)
|
|
43
|
-
install(cwd, path.join(tmp, 'repo'))
|
|
45
|
+
install(cwd, path.join(tmp, 'repo'), ws)
|
|
44
46
|
} finally {
|
|
45
47
|
fs.rmSync(tmp, { recursive: true, force: true })
|
|
46
48
|
}
|
|
@@ -57,7 +59,7 @@ function removeManaged(cwd) {
|
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
function install(cwd, srcDir) {
|
|
62
|
+
function install(cwd, srcDir, wsOverride) {
|
|
61
63
|
// 先驗證再動手:update 只清理 ade- 前綴,非前綴 skill 裝了就清不掉
|
|
62
64
|
const srcSkills = path.join(srcDir, 'skills')
|
|
63
65
|
const skillDirs = fs.existsSync(srcSkills)
|
|
@@ -90,15 +92,20 @@ function install(cwd, srcDir) {
|
|
|
90
92
|
}
|
|
91
93
|
fs.writeFileSync(claudePath, md)
|
|
92
94
|
|
|
93
|
-
fs.mkdirSync(path.join(cwd, 'workspaces'), { recursive: true })
|
|
94
|
-
const giPath = path.join(cwd, '.gitignore')
|
|
95
|
-
const gi = fs.existsSync(giPath) ? fs.readFileSync(giPath, 'utf8') : ''
|
|
96
|
-
if (!gi.split('\n').some((l) => l.trim().replace(/\/$/, '') === 'workspaces')) {
|
|
97
|
-
fs.writeFileSync(giPath, (gi ? gi.trimEnd() + '\n' : '') + 'workspaces/\n')
|
|
98
|
-
}
|
|
99
|
-
|
|
100
95
|
const prevPath = path.join(cwd, '.ade.json')
|
|
101
96
|
const prev = fs.existsSync(prevPath) ? JSON.parse(fs.readFileSync(prevPath, 'utf8')) : {}
|
|
97
|
+
|
|
98
|
+
// 作業區可指向既有的 repo 存放資料夾(--workspaces 或 .ade.json 的 workspaces),避免重複 clone
|
|
99
|
+
const ws = wsOverride || prev.workspaces || 'workspaces'
|
|
100
|
+
fs.mkdirSync(path.resolve(cwd, ws), { recursive: true })
|
|
101
|
+
const rel = path.relative(cwd, path.resolve(cwd, ws)).split(path.sep).join('/')
|
|
102
|
+
if (rel && !rel.startsWith('..') && !path.isAbsolute(rel)) {
|
|
103
|
+
const giPath = path.join(cwd, '.gitignore')
|
|
104
|
+
const gi = fs.existsSync(giPath) ? fs.readFileSync(giPath, 'utf8') : ''
|
|
105
|
+
if (!gi.split('\n').some((l) => l.trim().replace(/\/$/, '') === rel)) {
|
|
106
|
+
fs.writeFileSync(giPath, (gi ? gi.trimEnd() + '\n' : '') + rel + '/\n')
|
|
107
|
+
}
|
|
108
|
+
}
|
|
102
109
|
let source = null
|
|
103
110
|
try {
|
|
104
111
|
const pkg = JSON.parse(fs.readFileSync(path.join(srcDir, 'package.json'), 'utf8'))
|
|
@@ -114,7 +121,7 @@ function install(cwd, srcDir) {
|
|
|
114
121
|
} catch {}
|
|
115
122
|
fs.writeFileSync(
|
|
116
123
|
prevPath,
|
|
117
|
-
JSON.stringify({ source: source || prev.source || null, commit }, null, 2) + '\n'
|
|
124
|
+
JSON.stringify({ source: source || prev.source || null, commit, workspaces: ws }, null, 2) + '\n'
|
|
118
125
|
)
|
|
119
126
|
if (!source && !prev.source) {
|
|
120
127
|
console.warn('Warning: repository.url is not set in the ADE repo package.json; update will not work — set source in .ade.json manually')
|
package/package.json
CHANGED
package/template/README.md
CHANGED
|
@@ -40,8 +40,8 @@ init 會在當前目錄建立:
|
|
|
40
40
|
|
|
41
41
|
- `CLAUDE.md` 的 `<!-- ADE:BEGIN/END -->` managed 區段(原有內容不動)
|
|
42
42
|
- `.claude/ade/knowledge/` 知識庫副本、`.claude/skills/ade-*/` skills
|
|
43
|
-
-
|
|
44
|
-
- `.ade.json
|
|
43
|
+
- 作業區(agent clone 服務 repo 的位置;預設 `workspaces/` 並自動加入 .gitignore。已有固定放 repo 的資料夾時用 `init --workspaces <path>` 指向它,可為相對或絕對路徑,已下載的 repo 直接沿用不重 clone;路徑在本目錄外就不動 .gitignore)
|
|
44
|
+
- `.ade.json`(設定檔:`source` 來源、`commit` 版本、`workspaces` 作業區路徑。直接編輯即可改設定,改 `workspaces` 後不需重跑任何指令)
|
|
45
45
|
|
|
46
46
|
之後同指令改跑 `update` 拉取最新知識(update 會直接 clone 最新版,不受 dlx 快取影響)。
|
|
47
47
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
### Session 開始時
|
|
7
7
|
|
|
8
8
|
- **檢查知識新鮮度**:讀 `.ade.json`,執行 `git ls-remote <source> HEAD`,若 hash 與 `commit` 不符,提醒使用者執行 update 後再繼續(勿自行修改 managed 內容)
|
|
9
|
-
- Session 一律從本目錄(hub
|
|
9
|
+
- Session 一律從本目錄(hub 根)開啟;在作業區的服務 repo 內開啟會失去 ade skills
|
|
10
10
|
|
|
11
11
|
### 知識分層
|
|
12
12
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
1. 讀 `.claude/ade/knowledge/services/index.md`(全服務總覽)定位目標服務
|
|
18
18
|
2. 讀 `.claude/ade/knowledge/services/<service>.yaml` 取得定位、repo、技術棧、依賴關係
|
|
19
|
-
3.
|
|
19
|
+
3. 服務 repo 放在作業區(路徑見 `.ade.json` 的 `workspaces`,預設 `workspaces/`);`<作業區>/<service>/` 已存在就直接用,不存在才依 `repo.url` / `repo.branch` clone 進去
|
|
20
20
|
4. 讀服務 repo 自身的 README/CLAUDE.md/AGENTS.md 完成安裝、啟動、測試;跨服務流程慣例見 `knowledge/process/`,功能規格見 `knowledge/specs/`
|
|
21
21
|
|
|
22
22
|
### 知識維護
|
|
@@ -12,7 +12,7 @@ description: 功能開發完成後,核對 spec 與實作是否一致,移除
|
|
|
12
12
|
1. 確認這次開發對應的 PRD 與受影響 spec(從使用者、branch 或 PR 上下文取得;不確定就問)
|
|
13
13
|
2. 依 `ade-contribute` skill 的流程 clone ADE repo——**核對與修改都以這份 fresh clone 為唯一基準**。工作目錄的 `.claude/ade/` 副本可能過期(例如 PO merge 了 prd-to-spec 之後沒人跑過 update,本地根本沒有那些標記),只能當導航用
|
|
14
14
|
3. 找出本次 PRD 的標記:在 clone 的 spec 上先用 `grep -n "🚧" <spec>` 列出**全部**標記行(寬鬆匹配,連格式變體一起抓),再逐行看 PRD 檔名判斷歸屬——只處理含本次 PRD 檔名的行,其他 PRD 的標記與其描述的內容一律不碰
|
|
15
|
-
4.
|
|
15
|
+
4. 逐項核對:對照作業區(`.ade.json` 的 `workspaces` 路徑)下的實際實作,檢查每個屬於本次 PRD 的 `🚧` 區塊
|
|
16
16
|
- 已實作且行為一致 → 移除該標記行(整行刪除,內容保留)
|
|
17
17
|
- 實作與 spec 不符 → 以**實作為準**修改 spec 內容,並記下差異
|
|
18
18
|
- 沒做的項目 → 保留標記,記下
|
|
@@ -11,7 +11,7 @@ spec 平時只靠 PRD 流程更新;hotfix 與計畫外變更會讓 spec 悄悄
|
|
|
11
11
|
|
|
12
12
|
1. **先確保副本最新**:執行 update(或確認 `.ade.json` 的 commit 與遠端 HEAD 一致)——拿過期的 spec 副本去比對會誤報漂移
|
|
13
13
|
2. 列出 `.claude/ade/knowledge/specs/` 下的 spec;範圍大時請使用者指定優先巡檢的部分(建議:最近有 release 的服務相關)
|
|
14
|
-
3. 對每份 spec 找出涉及的服務(文內連結與 `services/index.md`),缺的 repo 依服務檔 clone
|
|
14
|
+
3. 對每份 spec 找出涉及的服務(文內連結與 `services/index.md`),缺的 repo 依服務檔 clone 進作業區(`.ade.json` 的 `workspaces` 路徑)
|
|
15
15
|
4. 逐項對照實作與 spec 敘述,記錄不一致:行為已變、功能已移除、實作有但 spec 未記載
|
|
16
16
|
- `🚧 尚未實作` 區塊屬「已定案未開發」,不算漂移,跳過
|
|
17
17
|
5. 向使用者報告漂移清單,確認哪些該修 spec(也可能是實作錯了該修 code)
|