@jjlabsio/claude-crew 0.1.46 → 0.1.47

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.
@@ -11,7 +11,7 @@
11
11
  "name": "claude-crew",
12
12
  "source": "./",
13
13
  "description": "오케스트레이터 + PM, 플래너, 개발, QA, 마케팅 에이전트 팀으로 단일 제품의 개발과 마케팅을 통합 관리",
14
- "version": "0.1.46",
14
+ "version": "0.1.47",
15
15
  "author": {
16
16
  "name": "Jaejin Song",
17
17
  "email": "wowlxx28@gmail.com"
@@ -28,5 +28,5 @@
28
28
  "category": "workflow"
29
29
  }
30
30
  ],
31
- "version": "0.1.46"
31
+ "version": "0.1.47"
32
32
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-crew",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "description": "1인 SaaS 개발자를 위한 멀티 에이전트 오케스트레이션 — 개발, 마케팅, 일정을 한 대화에서 통합 관리",
5
5
  "author": {
6
6
  "name": "Jaejin Song",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlabsio/claude-crew",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "description": "1인 SaaS 개발자를 위한 멀티 에이전트 오케스트레이션 — 개발, 마케팅, 일정을 한 대화에서 통합 관리",
5
5
  "author": "Jaejin Song <wowlxx28@gmail.com>",
6
6
  "license": "MIT",
@@ -11,6 +11,7 @@ import { execSync } from 'node:child_process';
11
11
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
12
12
  import { join, dirname } from 'node:path';
13
13
  import { homedir } from 'node:os';
14
+ import { PLUGIN_ROOT } from './lib/pluginRoot.mjs';
14
15
 
15
16
  // ---------------------------------------------------------------------------
16
17
  // Read stdin (with timeout)
@@ -33,6 +34,39 @@ function gitExec(cmd, cwd) {
33
34
  } catch { return null; }
34
35
  }
35
36
 
37
+ function readPluginVersion() {
38
+ const packageJson = JSON.parse(readFileSync(join(PLUGIN_ROOT, 'package.json'), 'utf-8'));
39
+ return packageJson.version;
40
+ }
41
+
42
+ function updatePluginRootCache(pluginRoot) {
43
+ try {
44
+ const crewDir = join(homedir(), '.claude', 'crew');
45
+ const cachePath = join(crewDir, 'plugin-root.json');
46
+
47
+ let shouldWrite = !existsSync(cachePath);
48
+ if (!shouldWrite) {
49
+ try {
50
+ const current = JSON.parse(readFileSync(cachePath, 'utf-8'));
51
+ shouldWrite = current.pluginRoot !== pluginRoot;
52
+ } catch {
53
+ shouldWrite = true;
54
+ }
55
+ }
56
+
57
+ if (!shouldWrite) return;
58
+
59
+ mkdirSync(crewDir, { recursive: true });
60
+ writeFileSync(cachePath, JSON.stringify({
61
+ pluginRoot,
62
+ version: readPluginVersion(),
63
+ updatedAt: new Date().toISOString(),
64
+ }, null, 2));
65
+ } catch {
66
+ // Best-effort cache for runner fallback. HUD setup must continue on failure.
67
+ }
68
+ }
69
+
36
70
  // ---------------------------------------------------------------------------
37
71
  // Main
38
72
  // ---------------------------------------------------------------------------
@@ -74,6 +108,8 @@ async function main() {
74
108
  writeFileSync(localSettingsPath, JSON.stringify(localSettings, null, 2));
75
109
  }
76
110
 
111
+ updatePluginRootCache(pluginRoot);
112
+
77
113
  console.log(JSON.stringify({ continue: true }));
78
114
  } catch (e) {
79
115
  console.log(JSON.stringify({
@@ -7,20 +7,33 @@ description: 모든 crew 에이전트 dispatch의 중앙 규약 — provider별
7
7
 
8
8
  crew 업무 스킬은 에이전트 provider별 호출 세부사항을 직접 구현하지 않고 이 중앙 규약을 따른다. 본 스킬은 prepare, resolve, dispatch, resume, followup 주입, retry/fallback/escalate 판단의 공통 표면을 정의한다.
9
9
 
10
- 설치 후 drift 차단용 pre-commit hook은 `node scripts/crew-agent-runner.mjs install-hooks`로 설치한다.
10
+ 설치 후 drift 차단용 pre-commit hook은 `node "$CREW_ROOT/scripts/crew-agent-runner.mjs" install-hooks`로 설치한다.
11
11
  (plugin 개발자 전용 — 사용자는 호출하지 않습니다. build/validate는 plugin source repo의 drift 차단 도구입니다.)
12
12
 
13
13
  ## Dispatch 절차
14
14
 
15
15
  업무 스킬(crew-plan/crew-interview/crew-dev)이 role을 실행해야 할 때 본 절차를 따른다.
16
16
 
17
+ ### Step 0. Runner 경로 결정
18
+
19
+ 오케스트레이터는 runner 호출 전에 plugin root를 결정하고, 결정된 경로를 `CREW_ROOT`로 사용한다.
20
+
21
+ Fallback 체인 (순서 중요):
22
+
23
+ 1. `$CLAUDE_PLUGIN_ROOT`가 있으면 사용한다. 정상 Claude Code plugin 환경이므로 추가 검증하지 않는다.
24
+ 2. `~/.claude/crew/plugin-root.json`의 `pluginRoot`를 읽는다. 해당 경로에 `scripts/crew-agent-runner.mjs`가 존재하면 사용하고, 없으면 다음 fallback으로 진행한다.
25
+ 3. `git rev-parse --show-toplevel` 결과를 dev 환경 전용 후보로 사용한다. 해당 경로의 `package.json`에서 `name`이 `@jjlabsio/claude-crew`인지 검증하고, 맞으면 사용한다. 아니면 다음 fallback으로 진행한다.
26
+ 4. 모든 fallback이 실패하면 `'/crew-setup을 먼저 실행하세요'` 에러 메시지로 중단한다.
27
+
28
+ 이후 모든 runner 호출은 `node "$CREW_ROOT/scripts/crew-agent-runner.mjs"` 형식을 사용한다.
29
+
17
30
  ### 1. request 객체 작성
18
31
 
19
32
  `{ role, inputs (path+content), instruction, successGate, failureHandling, taskId }` 형태의 임시 JSON 파일을 작성한다.
20
33
 
21
34
  ### 2. prepare
22
35
 
23
- 오케스트레이터는 `node "$CLAUDE_PLUGIN_ROOT/scripts/crew-agent-runner.mjs" prepare --role <role> --request-file <request-file> --json`을 실행한다.
36
+ 오케스트레이터는 `node "$CREW_ROOT/scripts/crew-agent-runner.mjs" prepare --role <role> --request-file <request-file> --json`을 실행한다.
24
37
  prepare는 provider/model/contract를 해석하고 다음 action 중 하나를 반환한다.
25
38
 
26
39
  ### 3a. dispatch action
@@ -67,8 +80,8 @@ capability를 넘어선 도구 요청이다. 오케스트레이터가 `contract.
67
80
 
68
81
  ### Codex 경로
69
82
 
70
- 1. `node scripts/crew-agent-runner.mjs render-followup --previous-result <file> --new-input <file>` 실행 → followup prompt 문자열 → 임시 파일에 저장.
71
- 2. `node scripts/crew-agent-runner.mjs dispatch --role <role> --request-file <new-request-with-followup-prompt> --resume-handle <agent_handle> --json` 실행.
83
+ 1. `node "$CREW_ROOT/scripts/crew-agent-runner.mjs" render-followup --previous-result <file> --new-input <file>` 실행 → followup prompt 문자열 → 임시 파일에 저장.
84
+ 2. `node "$CREW_ROOT/scripts/crew-agent-runner.mjs" dispatch --role <role> --request-file <new-request-with-followup-prompt> --resume-handle <agent_handle> --json` 실행.
72
85
  - 내부적으로 runner가 `crew-codex-companion.mjs task-resume-candidate`로 thread 일치 검증 후 `task --resume-last`를 호출하고 AgentResult를 정규화한다.
73
86
  3. AgentResult JSON을 받아 다음 상태 처리.
74
87
 
@@ -102,6 +102,27 @@ push는 하지 않는다.
102
102
 
103
103
  ---
104
104
 
105
+ ## Step 2b — Plugin Root 영속화
106
+
107
+ `$CLAUDE_PLUGIN_ROOT`가 살아있는 setup 시점에 runner fallback용 plugin root를 사용자 데이터 영역에 저장한다.
108
+
109
+ 1. `~/.claude/crew/` 디렉토리가 없으면 생성한다.
110
+ 2. `~/.claude/crew/plugin-root.json`을 다음 형식으로 쓴다. 기존 파일이 있으면 덮어쓴다.
111
+ ```json
112
+ {
113
+ "pluginRoot": "<$CLAUDE_PLUGIN_ROOT 값>",
114
+ "version": "<현재 플러그인 버전>",
115
+ "updatedAt": "<ISO timestamp>"
116
+ }
117
+ ```
118
+ 3. plugin 자체 데이터인 version은 plugin root 기준 `package.json`에서 읽는다.
119
+
120
+ **주의**:
121
+ - plugin root는 `$CLAUDE_PLUGIN_ROOT` 값을 사용한다.
122
+ - `~/.claude/crew/plugin-root.json`은 사용자 데이터이므로 home 기준 경로에 저장한다.
123
+
124
+ ---
125
+
105
126
  ## Step 3 — Provider 설정
106
127
 
107
128
  에이전트별로 어떤 provider(claude/codex)와 model을 사용할지 설정한다.