claude-nexus 0.21.0 → 0.23.0

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.
@@ -7,7 +7,7 @@
7
7
  {
8
8
  "name": "claude-nexus",
9
9
  "description": "Agent orchestration plugin for Claude Code. Injects optimized context per agent role with minimal overhead.",
10
- "version": "0.21.0",
10
+ "version": "0.23.0",
11
11
  "author": {
12
12
  "name": "kih"
13
13
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-nexus",
3
- "version": "0.21.0",
3
+ "version": "0.23.0",
4
4
  "description": "Agent orchestration plugin for Claude Code — optimized context injection per role",
5
5
  "author": {
6
6
  "name": "kih"
package/README.en.md CHANGED
@@ -9,7 +9,7 @@ Agent orchestration plugin for Claude Code.
9
9
 
10
10
  ## Why
11
11
 
12
- Specialized agent teams handle development and research systematically — architect, engineer, tester, researcher, and more. One tag triggers automatic orchestration of complex tasks across the right agents without manual coordination.
12
+ Specialized subagents handle development and research systematically — architect, engineer, tester, researcher, and more. One tag triggers automatic orchestration of complex tasks across the right agents without manual coordination.
13
13
 
14
14
  ## Quick Start
15
15
 
@@ -27,7 +27,7 @@ Run `/claude-nexus:nx-init` — scans your project and auto-generates structured
27
27
  **3. Start using**
28
28
 
29
29
  - **Plan**: `[plan] How should we design the auth system?` — clarify intent and align before executing
30
- - **Run**: `[run] Implement login API` — agent team handles analysis through implementation
30
+ - **Run**: `[run] Implement login API` — subagents handle analysis through implementation
31
31
 
32
32
  ## Usage
33
33
 
@@ -36,15 +36,15 @@ Tag your message to route it to the right workflow:
36
36
  | Tag | Action | Example |
37
37
  |-----|--------|---------|
38
38
  | `[plan]` | Pre-execution planning | `[plan] Discuss DB migration strategy` |
39
- | `[run]` | Execution (agent team) | `[run] Refactor payment module` |
40
- | `[d]` | Record a decision | `[d] Use PostgreSQL for primary storage` |
39
+ | `[run]` | Execution (subagent composition) | `[run] Refactor payment module` |
40
+ | `[d]` | Record a decision (within plan session) | `[d] Use PostgreSQL for primary storage` |
41
41
  | `[rule]` | Save a rule | `[rule] Always use bun instead of npm` |
42
42
 
43
- Typical flow: use `[plan]` to discuss and align → decide → use `[run]` to execute.
43
+ Typical flow: `[plan]` to discuss and align → `[d]` to decide (within plan) → `[run]` to execute.
44
44
 
45
45
  ## Agents
46
46
 
47
- ### How Team (4 agents)
47
+ ### How (4 agents)
48
48
 
49
49
  | Agent | Invocation | Role | Model |
50
50
  |-------|-----------|------|-------|
@@ -53,7 +53,7 @@ Typical flow: use `[plan]` to discuss and align → decide → use `[run]` to ex
53
53
  | **Postdoc** | `claude-nexus:postdoc` | Research methodology and evidence synthesis | opus |
54
54
  | **Strategist** | `claude-nexus:strategist` | Business strategy and competitive positioning | opus |
55
55
 
56
- ### Do Team (3 agents)
56
+ ### Do (3 agents)
57
57
 
58
58
  | Agent | Invocation | Role | Model |
59
59
  |-------|-----------|------|-------|
@@ -61,7 +61,7 @@ Typical flow: use `[plan]` to discuss and align → decide → use `[run]` to ex
61
61
  | **Researcher** | `claude-nexus:researcher` | Web search, independent investigation | sonnet |
62
62
  | **Writer** | `claude-nexus:writer` | Technical writing and documentation | sonnet |
63
63
 
64
- ### Check Team (2 agents)
64
+ ### Check (2 agents)
65
65
 
66
66
  | Agent | Invocation | Role | Model |
67
67
  |-------|-----------|------|-------|
@@ -85,17 +85,16 @@ Typical flow: use `[plan]` to discuss and align → decide → use `[run]` to ex
85
85
 
86
86
  Claude-callable tools exposed by the Nexus MCP server.
87
87
 
88
- ### Core (15 tools)
88
+ ### Core (14 tools)
89
89
 
90
90
  | Tool | Purpose |
91
91
  |------|---------|
92
- | `nx_briefing` | Assemble role-specific briefing (core knowledge + rules) |
93
92
  | `nx_core_read/write` | Project knowledge management (git-tracked) |
94
93
  | `nx_rules_read/write` | Team custom rules management (git-tracked) |
95
94
  | `nx_context` | Current session state lookup (branch, tasks, plan) |
96
95
  | `nx_task_list/add/update/close` | Task management + history.json archiving |
97
- | `nx_artifact_write` | Save team artifacts (branch-isolated) |
98
- | `nx_plan_start` | Start plan session (topic + issues, team verification) |
96
+ | `nx_artifact_write` | Save artifacts (branch-isolated) |
97
+ | `nx_plan_start` | Start plan session (topic + issues + research summary) |
99
98
  | `nx_plan_status` | Query plan state |
100
99
  | `nx_plan_update` | Modify plan issues (add/remove/edit/reopen) |
101
100
  | `nx_plan_decide` | Record issue decision (plan.json) |
@@ -127,9 +126,13 @@ Nexus registers a single Gate module as a Claude Code hook.
127
126
 
128
127
  | Event | Role |
129
128
  |-------|------|
129
+ | `SessionStart` | Initialize `.nexus/` structure, reset agent-tracker |
130
130
  | `UserPromptSubmit` | Tag detection → mode activation + TASK_PIPELINE injection + additionalContext guidance |
131
- | `PreToolUse` | Edit/Write: blocks when tasks.json missing. nx_plan_start: attendee team verification. Agent: team_name tracking |
131
+ | `PreToolUse` | Edit/Write: blocks when incomplete tasks exist |
132
+ | `SubagentStart` | Auto-inject role-filtered core knowledge index (lazy-read) |
133
+ | `SubagentStop` | Record agent completion. Warn if owned tasks remain incomplete |
132
134
  | `Stop` | Blocks exit with pending tasks. Forces nx_task_close when all completed |
135
+ | `PostCompact` | Snapshot session state (mode, plan, agent status) |
133
136
 
134
137
  </details>
135
138
 
@@ -154,17 +157,16 @@ Project knowledge and rules are stored under `.nexus/` and tracked by git.
154
157
  <details>
155
158
  <summary>Runtime State</summary>
156
159
 
157
- Runtime state is stored under `.nexus/` and is excluded from git.
160
+ Runtime state is stored under `.nexus/state/` and is excluded from git. `history.json` is at `.nexus/` root and git-tracked.
158
161
 
159
162
  ```
160
163
  .nexus/
161
- ├── branches/ Per-branch isolation
162
- └── {branch}/
163
- ├── tasks.json ← Task list
164
- ├── meet.json Meeting issue tracker
165
- ├── history.json Cycle archive (created by nx_task_close)
166
- └── artifacts/ Team artifacts
167
- └── sync-state.json ← Last sync commit
164
+ ├── history.json Cycle archive (git-tracked, created by nx_task_close)
165
+ └── state/ ← Runtime state (git-ignored)
166
+ ├── tasks.json ← Task list ([run] cycle)
167
+ ├── plan.json Planning session ([plan] cycle)
168
+ ├── agent-tracker.json Subagent lifecycle tracking
169
+ └── artifacts/ Artifacts
168
170
  ```
169
171
 
170
172
  </details>
package/README.md CHANGED
@@ -29,15 +29,16 @@ claude plugin install claude-nexus@nexus
29
29
  **첫 사용**
30
30
 
31
31
  - **플랜**: `[plan] 인증 시스템 어떻게 설계하면 좋을까?`
32
- - **결정 기록**: `응 그 방향으로 [d]`
32
+ - **결정 기록**: (plan 중) `응 그 방향으로 [d]`
33
+ - **실행**: `[run] 로그인 API 구현`
33
34
 
34
35
  ## 사용법
35
36
 
36
37
  | 태그 | 동작 | 예시 |
37
38
  |------|------|------|
38
39
  | `[plan]` | 플랜 모드 활성화 | `[plan] DB 마이그레이션 전략 논의` |
39
- | `[d]` | 결정 기록 | `응 그 방향으로 [d]` |
40
- | `[run]` | 실행 (에이전트 ) | `[run] 결제 모듈 리팩토링` |
40
+ | `[d]` | 결정 기록 (plan 세션 내) | `응 그 방향으로 [d]` |
41
+ | `[run]` | 실행 (서브에이전트 구성) | `[run] 결제 모듈 리팩토링` |
41
42
  | `[rule]` | 규칙 저장 | `[rule] npm 대신 bun 사용` |
42
43
 
43
44
  ## 에이전트
@@ -59,7 +60,7 @@ claude plugin install claude-nexus@nexus
59
60
  | 스킬 | 트리거 | 설명 |
60
61
  |------|--------|------|
61
62
  | **nx-plan** | `[plan]` | 구조화된 플랜. 요구사항 정리 → 결정 기록 |
62
- | **nx-run** | (기본 동작) | 동적 에이전트 구성 실행 |
63
+ | **nx-run** | `[run]` | 동적 에이전트 구성 실행 |
63
64
  | **nx-init** | `/claude-nexus:nx-init` | 프로젝트 온보딩. 코드 스캔 → 지식 생성 |
64
65
  | **nx-setup** | `/claude-nexus:nx-setup` | 대화형 설정 |
65
66
  | **nx-sync** | `/claude-nexus:nx-sync` | 코어 지식 동기화. 소스 변경사항을 .nexus/core/ 문서에 반영 |
@@ -71,17 +72,16 @@ claude plugin install claude-nexus@nexus
71
72
 
72
73
  Claude가 직접 호출하는 도구입니다.
73
74
 
74
- ### Core (15개)
75
+ ### Core (14개)
75
76
 
76
77
  | 도구 | 용도 |
77
78
  |------|------|
78
- | `nx_briefing` | 에이전트 역할별 브리핑 조립 (core knowledge + rules 기반) |
79
79
  | `nx_core_read/write` | 프로젝트 지식 관리 (`.nexus/core/`, git 추적) |
80
80
  | `nx_rules_read/write` | 팀 커스텀 규칙 관리 (`.nexus/rules/`, git 추적) |
81
81
  | `nx_context` | 현재 세션 상태 조회 (브랜치, 태스크, 플랜) |
82
82
  | `nx_task_list/add/update/close` | `.nexus/state/tasks.json` 기반 태스크 관리 + `.nexus/history.json` 아카이브 |
83
83
  | `nx_artifact_write` | 팀 산출물 저장 (`.nexus/state/artifacts/`) |
84
- | `nx_plan_start` | 플랜 세션 시작 (토픽 + 논점 등록, 참석자 검증) |
84
+ | `nx_plan_start` | 플랜 세션 시작 (토픽 + 논점 + 리서치 요약 등록) |
85
85
  | `nx_plan_status` | 플랜 상태 조회 |
86
86
  | `nx_plan_update` | 플랜 논점 수정 (add/remove/edit/reopen) |
87
87
  | `nx_plan_decide` | 논점 결정 처리 (plan.json) |
@@ -113,9 +113,13 @@ Gate 단일 모듈로 동작합니다.
113
113
 
114
114
  | 이벤트 | 역할 |
115
115
  |--------|------|
116
+ | `SessionStart` | `.nexus/` 구조 초기화, agent-tracker 리셋 |
116
117
  | `UserPromptSubmit` | 태그 감지 → 모드 활성화 + TASK_PIPELINE 주입 + additionalContext 안내 |
117
- | `PreToolUse` | Edit/Write: tasks.json 없으면 차단. nx_plan_start: 참석자 팀 검증. Agent: team_name 트래킹 |
118
+ | `PreToolUse` | Edit/Write: tasks.json 미완료 차단 |
119
+ | `SubagentStart` | 에이전트 역할별 코어 지식 인덱스 자동 주입 (lazy-read) |
120
+ | `SubagentStop` | 에이전트 완료 기록. 미완료 태스크 경고 |
118
121
  | `Stop` | pending 태스크 있으면 종료 차단. all completed면 nx_task_close 강제 |
122
+ | `PostCompact` | 세션 상태 스냅샷 (모드, 플랜, 에이전트 현황) |
119
123
 
120
124
  </details>
121
125
 
@@ -128,7 +132,7 @@ Gate 단일 모듈로 동작합니다.
128
132
  - `rules/` — 팀 커스텀 규칙. git 추적.
129
133
  - `config.json` — Nexus 설정. git 추적.
130
134
  - `history.json` — 사이클 아카이브. git 추적.
131
- - `state/` — 런타임 상태 (tasks, meet 등). git 무시.
135
+ - `state/` — 런타임 상태 (tasks, plan 등). git 무시.
132
136
 
133
137
  </details>
134
138
 
@@ -139,12 +143,10 @@ Gate 단일 모듈로 동작합니다.
139
143
 
140
144
  ```
141
145
  .nexus/state/
142
- ├── tasks.json
143
- ├── meet.json
144
- ├── edit-tracker.json
145
- ├── reopen-tracker.json
146
- ├── agent-tracker.json
147
- └── artifacts/
146
+ ├── tasks.json ← 태스크 목록 ([run] 사이클)
147
+ ├── plan.json ← 플랜 세션 ([plan] 사이클)
148
+ ├── agent-tracker.json ← 서브에이전트 라이프사이클
149
+ └── artifacts/ ← 산출물
148
150
  ```
149
151
 
150
152
  </details>
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.21.0
1
+ 0.23.0
@@ -22255,9 +22255,11 @@ function registerPlanTools(server2) {
22255
22255
  "\uC548\uAC74 \uACB0\uC815 \uAE30\uB85D \u2014 [d] \uD0DC\uADF8\uB85C \uD2B8\uB9AC\uAC70",
22256
22256
  {
22257
22257
  issue_id: external_exports.number().describe("\uACB0\uC815\uD560 \uC548\uAC74 ID"),
22258
- summary: external_exports.string().describe("\uACB0\uC815 \uC694\uC57D")
22258
+ summary: external_exports.string().describe("\uACB0\uC815 \uC694\uC57D"),
22259
+ how_agents: external_exports.array(external_exports.string()).optional().describe('\uC774\uC288 \uBD84\uC11D\uC5D0 \uCC38\uC5EC\uD55C HOW \uC5D0\uC774\uC804\uD2B8 \uC774\uB984 \uBAA9\uB85D (\uC608: ["architect", "designer"])'),
22260
+ how_summary: external_exports.record(external_exports.string(), external_exports.string()).optional().describe('\uC5D0\uC774\uC804\uD2B8\uBCC4 \uD575\uC2EC \uC758\uACAC \uC694\uC57D (\uC608: { "architect": "...", "designer": "..." })')
22259
22261
  },
22260
- async ({ issue_id, summary }) => {
22262
+ async ({ issue_id, summary, how_agents, how_summary }) => {
22261
22263
  const data = await readPlan();
22262
22264
  if (!data) {
22263
22265
  return textResult({ error: "No active plan session" });
@@ -22268,6 +22270,8 @@ function registerPlanTools(server2) {
22268
22270
  }
22269
22271
  issue2.status = "decided";
22270
22272
  issue2.decision = summary;
22273
+ if (how_agents !== void 0) issue2.how_agents = how_agents;
22274
+ if (how_summary !== void 0) issue2.how_summary = how_summary;
22271
22275
  await writePlan(data);
22272
22276
  const allComplete = data.issues.every((i) => i.status === "decided");
22273
22277
  if (allComplete) {
@@ -22478,135 +22482,8 @@ function registerArtifactTools(server2) {
22478
22482
  );
22479
22483
  }
22480
22484
 
22481
- // src/mcp/tools/briefing.ts
22482
- var import_fs11 = require("fs");
22483
- var import_promises7 = require("fs/promises");
22484
- var import_path12 = require("path");
22485
- var MATRIX = {
22486
- architect: { identity: "all", codebase: "all", reference: "all", memory: "all" },
22487
- postdoc: { identity: "all", codebase: "all", reference: "all", memory: "all" },
22488
- engineer: { identity: null, codebase: "all", reference: null, memory: "all" },
22489
- researcher: { identity: "all", codebase: null, reference: "all", memory: "all" },
22490
- tester: { identity: "all", codebase: "all", reference: null, memory: "all" },
22491
- designer: { identity: "all", codebase: "all", reference: "all", memory: "all" },
22492
- strategist: { identity: "all", codebase: "all", reference: "all", memory: "all" },
22493
- writer: { identity: null, codebase: "all", reference: null, memory: "all" },
22494
- reviewer: { identity: "all", codebase: "all", reference: null, memory: "all" }
22495
- };
22496
- function parseTags2(content) {
22497
- const match = content.match(/^<!--\s*tags:\s*(.+?)\s*-->/);
22498
- if (!match) return [];
22499
- return match[1].split(",").map((t) => t.trim()).filter(Boolean);
22500
- }
22501
- async function readLayerFiles(layer, hint) {
22502
- const layerDir = coreLayerDir(layer);
22503
- if (!(0, import_fs11.existsSync)(layerDir)) return [];
22504
- const files = (await (0, import_promises7.readdir)(layerDir)).filter((f) => f.endsWith(".md"));
22505
- const results = [];
22506
- for (const file of files) {
22507
- const filePath = (0, import_path12.join)(layerDir, file);
22508
- const content = await (0, import_promises7.readFile)(filePath, "utf-8");
22509
- results.push({ filename: file, content });
22510
- }
22511
- if (hint && results.length > 0) {
22512
- const hintLower = hint.toLowerCase();
22513
- const matched = results.filter(({ filename, content }) => {
22514
- const tags = parseTags2(content);
22515
- return tags.some((t) => t.toLowerCase().includes(hintLower)) || filename.toLowerCase().includes(hintLower);
22516
- });
22517
- if (matched.length > 0) return matched;
22518
- }
22519
- return results;
22520
- }
22521
- function registerBriefingTool(server2) {
22522
- server2.tool(
22523
- "nx_briefing",
22524
- "Assemble a role-specific briefing from the core knowledge store (identity, codebase, reference, memory layers) plus decisions and rules.",
22525
- {
22526
- role: external_exports.enum(["architect", "postdoc", "engineer", "researcher", "tester", "designer", "strategist", "writer", "reviewer"]).describe("Agent role"),
22527
- hint: external_exports.string().optional().describe("Relevant module/area hint for tag filtering")
22528
- },
22529
- async (params) => {
22530
- const role = params.role;
22531
- const hint = params.hint;
22532
- const matrix = MATRIX[role];
22533
- if (!matrix) {
22534
- return textResult({ error: `Unknown role: ${role}` });
22535
- }
22536
- const collectedFiles = [];
22537
- const sections = {};
22538
- for (const layer of LAYERS) {
22539
- const policy = matrix[layer];
22540
- if (policy === null) continue;
22541
- const files = await readLayerFiles(layer, hint);
22542
- sections[layer] = files;
22543
- for (const f of files) {
22544
- collectedFiles.push(`${layer}/${f.filename}`);
22545
- }
22546
- }
22547
- let decisionsSection = "";
22548
- const decisionsPath = (0, import_path12.join)(STATE_ROOT, "decisions.json");
22549
- if ((0, import_fs11.existsSync)(decisionsPath)) {
22550
- const raw = await (0, import_promises7.readFile)(decisionsPath, "utf-8");
22551
- decisionsSection = raw.trim();
22552
- }
22553
- let rulesSection = "";
22554
- const rulesDir = (0, import_path12.join)(NEXUS_ROOT, "rules");
22555
- if ((0, import_fs11.existsSync)(rulesDir)) {
22556
- const ruleFiles = (await (0, import_promises7.readdir)(rulesDir)).filter((f) => f.endsWith(".md"));
22557
- let parts = [];
22558
- for (const ruleFile of ruleFiles) {
22559
- const content = await (0, import_promises7.readFile)((0, import_path12.join)(rulesDir, ruleFile), "utf-8");
22560
- parts.push({ filename: ruleFile, content });
22561
- }
22562
- if (hint && parts.length > 0) {
22563
- const hintLower = hint.toLowerCase();
22564
- const matched = parts.filter(({ filename, content }) => {
22565
- const tags = parseTags2(content);
22566
- return tags.some((t) => t.toLowerCase().includes(hintLower)) || filename.toLowerCase().includes(hintLower);
22567
- });
22568
- if (matched.length > 0) parts = matched;
22569
- }
22570
- rulesSection = parts.map(({ filename, content }) => `### ${filename}
22571
- ${content.trim()}`).join("\n\n");
22572
- }
22573
- const lines = [];
22574
- lines.push(`<!-- briefing: role=${role}, hint=${hint ?? "null"}, files=[${collectedFiles.join(", ")}] -->`);
22575
- lines.push("");
22576
- if (decisionsSection) {
22577
- lines.push("## Decisions");
22578
- lines.push(decisionsSection);
22579
- lines.push("");
22580
- }
22581
- if (rulesSection) {
22582
- lines.push("## Rules");
22583
- lines.push(rulesSection);
22584
- lines.push("");
22585
- }
22586
- for (const layer of LAYERS) {
22587
- const policy = matrix[layer];
22588
- if (policy === null) continue;
22589
- const layerName = layer.charAt(0).toUpperCase() + layer.slice(1);
22590
- lines.push(`## ${layerName}`);
22591
- const files = sections[layer] ?? [];
22592
- if (files.length === 0) {
22593
- lines.push(`No ${layer} files.`);
22594
- } else {
22595
- for (const { filename, content } of files) {
22596
- lines.push(`### ${filename}`);
22597
- lines.push(content.trim());
22598
- }
22599
- }
22600
- lines.push("");
22601
- }
22602
- const markdown = lines.join("\n");
22603
- return { content: [{ type: "text", text: markdown }] };
22604
- }
22605
- );
22606
- }
22607
-
22608
22485
  // src/mcp/server.ts
22609
- var import_path13 = require("path");
22486
+ var import_path12 = require("path");
22610
22487
  var server = new McpServer({
22611
22488
  name: "nx",
22612
22489
  version: getCurrentVersion() || "0.0.0"
@@ -22615,7 +22492,7 @@ registerCoreStore(server);
22615
22492
  registerMarkdownStore(server, {
22616
22493
  toolPrefix: "nx_rules",
22617
22494
  entityName: "name",
22618
- dirPath: (0, import_path13.join)(NEXUS_ROOT, "rules"),
22495
+ dirPath: (0, import_path12.join)(NEXUS_ROOT, "rules"),
22619
22496
  pathFn: rulesPath,
22620
22497
  listKey: "rules",
22621
22498
  cache: false
@@ -22626,7 +22503,6 @@ registerAstTools(server);
22626
22503
  registerTaskTools(server);
22627
22504
  registerArtifactTools(server);
22628
22505
  registerPlanTools(server);
22629
- registerBriefingTool(server);
22630
22506
  async function main() {
22631
22507
  const transport = new StdioServerTransport();
22632
22508
  await server.connect(transport);