create-agentic-dev-env 0.2.5 → 0.2.7

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
- if (cmd === 'init') init(process.cwd(), pkgDir)
12
- else if (cmd === 'update') update(process.cwd())
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,29 @@ function install(cwd, srcDir) {
90
92
  }
91
93
  fs.writeFileSync(claudePath, md)
92
94
 
93
- fs.mkdirSync(path.join(cwd, 'workspaces'), { recursive: true })
95
+ const prevPath = path.join(cwd, '.ade.json')
96
+ const prev = fs.existsSync(prevPath) ? JSON.parse(fs.readFileSync(prevPath, 'utf8')) : {}
97
+
98
+ // 作業區固定叫 workspaces/;指定既有 repo 存放資料夾時(--workspaces 或 .ade.json 的
99
+ // workspaces),workspaces 建成指向它的 symlink,cd workspaces 即達、已下載的 repo 直接沿用
100
+ const ws = wsOverride || prev.workspaces || null
101
+ const wsDir = path.join(cwd, 'workspaces')
102
+ if (ws && path.resolve(cwd, ws) !== wsDir) {
103
+ fs.mkdirSync(path.resolve(cwd, ws), { recursive: true })
104
+ let st = null
105
+ try { st = fs.lstatSync(wsDir) } catch {}
106
+ if (st && st.isSymbolicLink()) fs.unlinkSync(wsDir)
107
+ else if (st) throw new Error('workspaces already exists and is not a symlink; move its contents into the target folder and remove it, then retry')
108
+ fs.symlinkSync(ws, wsDir, 'dir')
109
+ } else {
110
+ fs.mkdirSync(wsDir, { recursive: true })
111
+ }
94
112
  const giPath = path.join(cwd, '.gitignore')
95
113
  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')
114
+ // 不帶斜線才涵蓋 symlink 形態(gitignore `dir/` 不匹配 symlink)
115
+ if (!gi.split('\n').some((l) => l.trim() === 'workspaces')) {
116
+ fs.writeFileSync(giPath, (gi ? gi.trimEnd() + '\n' : '') + 'workspaces\n')
98
117
  }
99
-
100
- const prevPath = path.join(cwd, '.ade.json')
101
- const prev = fs.existsSync(prevPath) ? JSON.parse(fs.readFileSync(prevPath, 'utf8')) : {}
102
118
  let source = null
103
119
  try {
104
120
  const pkg = JSON.parse(fs.readFileSync(path.join(srcDir, 'package.json'), 'utf8'))
@@ -114,7 +130,7 @@ function install(cwd, srcDir) {
114
130
  } catch {}
115
131
  fs.writeFileSync(
116
132
  prevPath,
117
- JSON.stringify({ source: source || prev.source || null, commit }, null, 2) + '\n'
133
+ JSON.stringify({ source: source || prev.source || null, commit, workspaces: ws }, null, 2) + '\n'
118
134
  )
119
135
  if (!source && !prev.source) {
120
136
  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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-agentic-dev-env",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Scaffold and manage team Agentic Dev Environment (ADE) knowledge repos",
5
5
  "repository": {
6
6
  "type": "git",
@@ -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
- - `workspaces/`(agent clone 服務 repo 的作業區,自動加入 .gitignore)
44
- - `.ade.json`(記錄來源與版本)
43
+ - `workspaces/`(agent clone 服務 repo 的作業區,自動加入 .gitignore。已有固定放 repo 的資料夾時用 `init --workspaces <path>` 指向它——`workspaces` 會建成該資料夾的 symlink,`cd workspaces` 即達、已下載的 repo 直接沿用不重 clone
44
+ - `.ade.json`(設定檔:`source` 來源、`commit` 版本、`workspaces` 作業區實際位置(symlink 目標,預設 null)。改 `workspaces` 後跑一次 update 重建 symlink)
45
45
 
46
46
  之後同指令改跑 `update` 拉取最新知識(update 會直接 clone 最新版,不受 dlx 快取影響)。
47
47
 
@@ -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. `workspaces/<service>/` 不存在,依 `repo.url` / `repo.branch` clone 到 `workspaces/<service>/`
19
+ 3. `workspaces/<service>/` 已存在就直接用,不存在才依 `repo.url` / `repo.branch` clone 到 `workspaces/<service>/`
20
20
  4. 讀服務 repo 自身的 README/CLAUDE.md/AGENTS.md 完成安裝、啟動、測試;跨服務流程慣例見 `knowledge/process/`,功能規格見 `knowledge/specs/`
21
21
 
22
22
  ### 知識維護