@colin4k1024/tsp 2.4.9 → 2.5.1

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.
Files changed (37) hide show
  1. package/README.md +71 -1
  2. package/hooks/README.md +1 -1
  3. package/hooks/hooks.json +5 -4
  4. package/hooks/strategic-compact/README.md +7 -5
  5. package/hooks/strategic-compact/suggest-compact.js +9 -174
  6. package/package.json +1 -1
  7. package/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  8. package/scripts/__pycache__/build_platform_artifacts.cpython-311.pyc +0 -0
  9. package/scripts/__pycache__/install_platform.cpython-311.pyc +0 -0
  10. package/scripts/__pycache__/langfuse_trace.cpython-311.pyc +0 -0
  11. package/scripts/__pycache__/query_audit_logs.cpython-311.pyc +0 -0
  12. package/scripts/__pycache__/scan_leaked_keys.cpython-311.pyc +0 -0
  13. package/scripts/__pycache__/team_skills_platform.cpython-311.pyc +0 -0
  14. package/scripts/__pycache__/team_skills_platform.cpython-313.pyc +0 -0
  15. package/scripts/__pycache__/validate_library.cpython-311.pyc +0 -0
  16. package/scripts/__pycache__/validate_workflow_state.cpython-311.pyc +0 -0
  17. package/scripts/evolution/__pycache__/__init__.cpython-311.pyc +0 -0
  18. package/scripts/evolution/__pycache__/store.cpython-311.pyc +0 -0
  19. package/scripts/harness-audit.js +7 -4
  20. package/scripts/hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  21. package/scripts/hooks/__pycache__/mcp_health_check.cpython-311.pyc +0 -0
  22. package/scripts/hooks/__pycache__/observe.cpython-311.pyc +0 -0
  23. package/scripts/hooks/__pycache__/session_end.cpython-311.pyc +0 -0
  24. package/scripts/hooks/__pycache__/session_start.cpython-311.pyc +0 -0
  25. package/scripts/hooks/suggest-compact.js +331 -63
  26. package/scripts/install-platform.js +68 -85
  27. package/scripts/lib/__pycache__/audit_logger.cpython-311.pyc +0 -0
  28. package/scripts/lib/__pycache__/audit_query.cpython-311.pyc +0 -0
  29. package/scripts/lib/__pycache__/hook_contract.cpython-311.pyc +0 -0
  30. package/scripts/lib/__pycache__/memory_store.cpython-311.pyc +0 -0
  31. package/scripts/lib/__pycache__/utils.cpython-311.pyc +0 -0
  32. package/scripts/lib/opencode/convert-agents.js +273 -0
  33. package/scripts/lib/opencode/convert-hooks.js +286 -0
  34. package/scripts/lib/opencode/generate-agents-md.js +361 -0
  35. package/scripts/test-opencode-install.js +151 -0
  36. package/skills/goframe-v2/examples/practices/quick-demo/manifest/config/config.yaml +14 -14
  37. package/skills/repo-scan/SKILL.md +63 -63
package/README.md CHANGED
@@ -1,4 +1,7 @@
1
- # Team Skills Platform
1
+ <div align="center">
2
+ <img src="./assets/icon.png" alt="Team Skills Platform" width="128" height="128"/>
3
+ <h1>Team Skills Platform</h1>
4
+ </div>
2
5
 
3
6
  面向团队协作与平台治理的开源 Team Skills Platform,用于把单代理执行模式升级成“`Tech Lead` 编排 + 专业角色协作”的虚拟研发团队工作模型,并叠加 ECC 风格的 harness layer、specialist 命令与运行时增强能力。当前平台同时支持 `team mode` 与 `solo mode`,前者强调多人交接,后者强调单人闭环但保留同样的关键门禁。
4
7
 
@@ -12,6 +15,7 @@
12
15
  node scripts/build-platform-artifacts.js
13
16
  node scripts/install-apply.js --profile team --target claude
14
17
  node scripts/install-apply.js --profile full --target codex
18
+ node scripts/install-apply.js --profile full --target opencode
15
19
  ```
16
20
 
17
21
  ## Who It's For / 适合谁
@@ -55,6 +59,72 @@ TSP 采用 **角色 + 技能 + Agent + 规则 + Hooks + Workflow 引擎** 六层
55
59
 
56
60
  安装工具链公开主线支持 **3 个 code agent**:Claude Code、Codex、OpenCode。其他历史 target 保留为隐藏兼容路径,不再作为公开 onboarding 主线。
57
61
 
62
+ ### OpenCode 集成
63
+
64
+ TSP 为 OpenCode 提供了完整的适配支持,包括:
65
+
66
+ - **AGENTS.md 自动生成**:包含完整的规则索引、角色索引、命令索引和技能索引
67
+ - **Agent 系统适配**:所有角色和 specialist agents 都添加了 YAML front matter 配置
68
+ - **Hooks 系统适配**:将 TSP hooks 转换为 OpenCode 插件格式
69
+ - **配置文件生成**:自动生成 `opencode.json` 配置文件
70
+ - **Skills 系统兼容**:所有 SKILL.md 文件都兼容 OpenCode 的 skill 工具
71
+
72
+ #### OpenCode 安装
73
+
74
+ ```bash
75
+ # 安装完整 OpenCode 配置
76
+ node scripts/install-apply.js --profile full --target opencode
77
+
78
+ # 或使用 npm 脚本
79
+ npm run install:opencode
80
+ ```
81
+
82
+ #### OpenCode 配置
83
+
84
+ 安装完成后,OpenCode 配置文件位于 `~/.config/opencode/opencode.json`,包含:
85
+
86
+ ```json
87
+ {
88
+ "$schema": "https://opencode.ai/config.json",
89
+ "instructions": ["./AGENTS.md"],
90
+ "plugin": ["team-skills-platform"],
91
+ "permission": {
92
+ "edit": "allow",
93
+ "bash": "allow"
94
+ }
95
+ }
96
+ ```
97
+
98
+ #### OpenCode 使用
99
+
100
+ 1. **启动 OpenCode**:在项目目录运行 `opencode`
101
+ 2. **查看可用角色**:AGENTS.md 中包含所有角色的索引
102
+ 3. **切换角色**:使用 `@tech-lead`、`@frontend-engineer` 等方式切换角色
103
+ 4. **执行命令**:使用 `/team-intake`、`/team-plan` 等团队命令
104
+ 5. **加载技能**:使用 `skill` 工具加载 SKILL.md 文件
105
+
106
+ #### OpenCode 目录结构
107
+
108
+ ```
109
+ ~/.config/opencode/
110
+ ├── AGENTS.md # 主配置文件(自动生成)
111
+ ├── opencode.json # OpenCode 配置文件
112
+ ├── agents/ # Agent 定义文件
113
+ │ ├── tech-lead.md
114
+ │ ├── product-manager.md
115
+ │ └── ...
116
+ ├── command/ # 命令文件
117
+ │ ├── team-intake.md
118
+ │ ├── team-plan.md
119
+ │ └── ...
120
+ └── plugins/ # 插件目录
121
+ ├── team-skills-platform/ # TSP 插件
122
+ │ ├── skills/ # 技能文件
123
+ │ ├── rules/ # 规则文件
124
+ │ └── ...
125
+ └── tsp-hooks.js # Hooks 插件
126
+ ```
127
+
58
128
  发布为 npm 包 `@colin4k1024/tsp`,内置 Rust bridge 预构建二进制,安装零依赖。
59
129
 
60
130
  ### 集成的开源框架与方法论
package/hooks/README.md CHANGED
@@ -26,7 +26,7 @@ User request → Claude picks a tool → PreToolUse hook runs → Tool executes
26
26
  | **Git push reminder** | `Bash` | Reminds to review changes before `git push` | 0 (warns) |
27
27
  | **Pre-commit quality check** | `Bash` | Runs quality checks before `git commit`: lints staged files, validates commit message format when provided via `-m/--message`, detects console.log/debugger/secrets | 2 (blocks critical) / 0 (warns) |
28
28
  | **Doc file warning** | `Write` | Warns about non-standard `.md`/`.txt` files (allows README, CLAUDE, CONTRIBUTING, CHANGELOG, LICENSE, SKILL, docs/, skills/); cross-platform path handling | 0 (warns) |
29
- | **Strategic compact** | `Edit\|Write` | Suggests manual `/compact` at logical intervals (every ~50 tool calls) | 0 (warns) |
29
+ | **Strategic compact** | `*` | Suggests `/compact` when context usage crosses 70/85/95% thresholds, using Claude context-window metrics when available | 0 (warns) |
30
30
  | **InsAIts security monitor (opt-in)** | `Bash\|Write\|Edit\|MultiEdit` | Optional security scan for high-signal tool inputs. Disabled unless `ECC_ENABLE_INSAITS=1`. Blocks on critical findings, warns on non-critical, and writes audit log to `.insaits_audit_session.jsonl`. JS wrapper is the canonical hook entry; the Python monitor is an explicit third-party SDK exception. Requires `pip install insa-its`. [Details](../scripts/hooks/insaits-security-monitor.py) | 2 (blocks critical) / 0 (warns) |
31
31
 
32
32
  ### PostToolUse Hooks
package/hooks/hooks.json CHANGED
@@ -69,15 +69,16 @@
69
69
  "id": "pre:write:doc-file-warning"
70
70
  },
71
71
  {
72
- "matcher": "Edit|Write",
72
+ "matcher": "*",
73
73
  "hooks": [
74
74
  {
75
75
  "type": "command",
76
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags.js\" \"pre:edit-write:suggest-compact\" \"scripts/hooks/suggest-compact.js\" \"standard,strict\""
76
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/run-with-flags.js\" \"pre:all:strategic-compact\" \"scripts/hooks/suggest-compact.js\" \"standard,strict\"",
77
+ "timeout": 10
77
78
  }
78
79
  ],
79
- "description": "Suggest manual compaction at logical intervals",
80
- "id": "pre:edit-write:suggest-compact"
80
+ "description": "Suggest strategic context compaction when context usage crosses 70/85/95% thresholds",
81
+ "id": "pre:all:strategic-compact"
81
82
  },
82
83
  {
83
84
  "matcher": "*",
@@ -4,11 +4,11 @@
4
4
 
5
5
  ## 当前状态
6
6
 
7
- ✅ **已实现** - 通过 `scripts/hooks/pre_compact.py` 和 `scripts/hooks/suggest_compact.py` 提供完整功能。
7
+ ✅ **已实现** - 通过 `scripts/hooks/pre-compact.js` 和 `scripts/hooks/suggest-compact.js` 提供完整功能。
8
8
 
9
9
  ## 实现细节
10
10
 
11
- ### pre_compact.py
11
+ ### pre-compact.js
12
12
 
13
13
  **触发时机**: 上下文压缩前自动调用
14
14
 
@@ -25,12 +25,14 @@
25
25
  - 总是丢弃的类型:`tool_result`, `search_result`, `exploration_trace`(超过 500 字符时)
26
26
  - 其他根据上下文大小决定
27
27
 
28
- ### suggest_compact.py
28
+ ### suggest-compact.js
29
29
 
30
- **触发时机**: 上下文使用超过 70% 时自动调用
30
+ **触发时机**: `hooks/hooks.json` 的 `pre:all:strategic-compact` 在工具调用前运行;当真实上下文使用超过 70% 时注入 `/compact` 建议。
31
31
 
32
32
  **功能**:
33
- - 计算上下文使用率
33
+ - 优先读取 Claude hook 输入里的 `context_window.used_percentage` / `context_window.remaining_percentage`
34
+ - 其次读取 `CLAUDE_CONTEXT_SIZE` / `CLAUDE_CONTEXT_LIMIT`
35
+ - 最后读取 `harness-statusline.js` 写入的 `/tmp/harness-ctx-{session_id}.json`
34
36
  - 评估紧迫度:`low` (< 70%) | `medium` (70-85%) | `high` (85-95%) | `critical` (> 95%)
35
37
  - 估算可节省的 token
36
38
  - 提供具体压缩建议:
@@ -1,100 +1,14 @@
1
1
  #!/usr/bin/env node
2
- // suggest-compact.js — SuggestCompact hook
3
- // JS equivalent of scripts/hooks/suggest_compact.py
4
- //
5
- // Called when context is getting large. Analyses usage ratio and outputs
6
- // compact suggestions + reorganisation plan.
7
- //
8
- // Reads context metrics from:
9
- // 1. stdin JSON ({ context_window: { used_percentage, remaining_percentage } })
10
- // 2. env vars (CLAUDE_CONTEXT_SIZE, CLAUDE_CONTEXT_LIMIT)
11
- // 3. bridge file /tmp/harness-ctx-{session_id}.json (written by harness-statusline.js)
12
- //
13
- // Silent-fail: any error → process.exit(0)
2
+ /**
3
+ * Compatibility entry for older strategic-compact hook paths.
4
+ *
5
+ * The canonical implementation lives in scripts/hooks/suggest-compact.js so
6
+ * hooks.json, installers, tests, and audits share one behavior.
7
+ */
14
8
 
15
9
  'use strict';
16
10
 
17
- const fs = require('fs');
18
- const path = require('path');
19
- const os = require('os');
20
-
21
- // Urgency thresholds (context usage %)
22
- const URGENCY = [
23
- [95, 'critical'],
24
- [85, 'high'],
25
- [70, 'medium'],
26
- [ 0, 'low'],
27
- ];
28
-
29
- function getUrgency(usagePct) {
30
- for (const [threshold, label] of URGENCY) {
31
- if (usagePct > threshold) return label;
32
- }
33
- return 'low';
34
- }
35
-
36
- function buildSuggestions(usagePct, contextSize) {
37
- const suggestions = [];
38
- let savings = 0;
39
-
40
- if (usagePct > 85) {
41
- const s = Math.round(contextSize * 0.15);
42
- suggestions.push({
43
- action: 'summarize',
44
- target: 'early conversation history',
45
- reason: 'Preserve decisions and conclusions, compress exploration traces',
46
- estimated_tokens_saved: s,
47
- });
48
- savings += s;
49
- }
50
-
51
- if (usagePct > 70) {
52
- const s = Math.round(contextSize * 0.10);
53
- suggestions.push({
54
- action: 'discard',
55
- target: 'tool results and search outputs',
56
- reason: 'These are reference-only, not critical for continuity',
57
- estimated_tokens_saved: s,
58
- });
59
- savings += s;
60
- }
61
-
62
- if (usagePct > 60) {
63
- const s = Math.round(contextSize * 0.08);
64
- suggestions.push({
65
- action: 'reorganize',
66
- target: 'specialist outputs',
67
- reason: 'Move key conclusions to session summary, keep full outputs in memory store',
68
- estimated_tokens_saved: s,
69
- });
70
- savings += s;
71
- }
72
-
73
- return { suggestions, savings };
74
- }
75
-
76
- function buildReorganizationPlan() {
77
- return {
78
- phase_1: {
79
- action: 'save_decisions_to_memory',
80
- description: 'Extract all decisions and save to ~/.claude/memory/error_experience/decisions/',
81
- },
82
- phase_2: {
83
- action: 'save_pending_items',
84
- description: 'Extract pending items and next hints to session summary',
85
- },
86
- phase_3: {
87
- action: 'compress_conversation',
88
- description: 'Keep system prompts and last 20 exchanges, summarize middle',
89
- },
90
- phase_4: {
91
- action: 'compact_tool_results',
92
- description: 'Replace long tool outputs with summaries: [File X read, Y lines]',
93
- },
94
- };
95
- }
96
-
97
- // ─── main ───────────────────────────────────────────────────────────────────
11
+ const { buildHookOutput } = require('../../scripts/hooks/suggest-compact');
98
12
 
99
13
  let input = '';
100
14
  const stdinTimeout = setTimeout(() => process.exit(0), 8000);
@@ -103,87 +17,8 @@ process.stdin.on('data', chunk => { input += chunk; });
103
17
  process.stdin.on('end', () => {
104
18
  clearTimeout(stdinTimeout);
105
19
  try {
106
- let data = {};
107
- try { data = JSON.parse(input || '{}'); } catch (_) { /* ignore */ }
108
-
109
- const sessionId = data.session_id || '';
110
-
111
- // ── Resolve context metrics (3 sources, first wins) ──
112
- let usagePct = null;
113
- let contextSize = 0;
114
- let contextLimit = 200000;
115
-
116
- // Source 1: stdin context_window
117
- const cw = data.context_window;
118
- if (cw && cw.used_percentage != null) {
119
- usagePct = cw.used_percentage;
120
- contextSize = Math.round((usagePct / 100) * contextLimit);
121
- }
122
-
123
- // Source 2: env vars
124
- if (usagePct == null) {
125
- const envSize = parseInt(process.env.CLAUDE_CONTEXT_SIZE || '0', 10);
126
- const envLimit = parseInt(process.env.CLAUDE_CONTEXT_LIMIT || '200000', 10);
127
- if (envSize > 0) {
128
- contextSize = envSize;
129
- contextLimit = envLimit;
130
- usagePct = Math.round((envSize / envLimit) * 100);
131
- }
132
- }
133
-
134
- // Source 3: bridge file from harness-statusline.js
135
- if (usagePct == null && sessionId) {
136
- const bridgePath = path.join(os.tmpdir(), `harness-ctx-${sessionId}.json`);
137
- if (fs.existsSync(bridgePath)) {
138
- try {
139
- const bridge = JSON.parse(fs.readFileSync(bridgePath, 'utf8'));
140
- usagePct = bridge.used_pct ?? null;
141
- contextSize = usagePct != null ? Math.round((usagePct / 100) * contextLimit) : 0;
142
- } catch (_) { /* ignore */ }
143
- }
144
- }
145
-
146
- if (usagePct == null) {
147
- process.exit(0); // No metrics available — nothing to suggest
148
- }
149
-
150
- const urgency = getUrgency(usagePct);
151
- const shouldCompact = usagePct > 70;
152
-
153
- const { suggestions, savings } = buildSuggestions(usagePct, contextSize);
154
- const reorganizationPlan = shouldCompact ? buildReorganizationPlan() : null;
155
-
156
- const payload = {
157
- should_compact: shouldCompact,
158
- urgency,
159
- context_usage_ratio: usagePct,
160
- estimated_token_savings: savings,
161
- suggestions,
162
- reorganization_plan: reorganizationPlan,
163
- };
164
-
165
- const _msg = `Compact suggestion: ${urgency} urgency, ~${savings} tokens could be saved`;
166
-
167
- // Build context advisory (only inject if compact is warranted)
168
- if (!shouldCompact) {
169
- process.exit(0);
170
- }
171
-
172
- const urgencyEmoji = { critical: '🔴', high: '🟠', medium: '🟡', low: '🟢' }[urgency] ?? '⚪';
173
- const ctx = [
174
- `## 上下文压缩建议 ${urgencyEmoji} (strategic-compact)`,
175
- `- 使用率: ${usagePct}% | 紧迫度: ${urgency} | 可节省: ~${savings} tokens`,
176
- ...suggestions.map(s => `- [${s.action}] ${s.target}: ${s.reason}`),
177
- ].join('\n');
178
-
179
- process.stdout.write(JSON.stringify({
180
- hookSpecificOutput: {
181
- hookEventName: 'SuggestCompact',
182
- additionalContext: ctx,
183
- },
184
- compactSuggestion: payload,
185
- }));
186
-
20
+ const output = buildHookOutput(input);
21
+ if (output) process.stdout.write(JSON.stringify(output));
187
22
  } catch (_) {
188
23
  process.exit(0);
189
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colin4k1024/tsp",
3
- "version": "2.4.9",
3
+ "version": "2.5.1",
4
4
  "description": "Open-source Team Skills Platform for role-based AI delivery workflows, shared skills, hooks, commands, and multi-platform installs.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -203,6 +203,9 @@ function getRepoChecks(rootDir) {
203
203
  const commandPrimary = safeRead(rootDir, 'commands/harness-audit.md').trim();
204
204
  const commandParity = safeRead(rootDir, '.opencode/commands/harness-audit.md').trim();
205
205
  const hooksJson = safeRead(rootDir, 'hooks/hooks.json');
206
+ const hasStrategicCompactHook =
207
+ hooksJson.includes('pre:all:strategic-compact') &&
208
+ hooksJson.includes('scripts/hooks/suggest-compact.js');
206
209
 
207
210
  return [
208
211
  {
@@ -270,10 +273,10 @@ function getRepoChecks(rootDir) {
270
273
  category: 'Context Efficiency',
271
274
  points: 3,
272
275
  scopes: ['repo', 'hooks'],
273
- path: 'scripts/hooks/suggest-compact.js',
274
- description: 'Suggest-compact automation hook exists',
275
- pass: fileExists(rootDir, 'scripts/hooks/suggest-compact.js'),
276
- fix: 'Implement scripts/hooks/suggest-compact.js for context pressure hints.',
276
+ path: 'hooks/hooks.json',
277
+ description: 'Suggest-compact automation is registered for strategic context pressure hints',
278
+ pass: fileExists(rootDir, 'scripts/hooks/suggest-compact.js') && hasStrategicCompactHook,
279
+ fix: 'Register pre:all:strategic-compact in hooks/hooks.json and point it at scripts/hooks/suggest-compact.js.',
277
280
  },
278
281
  {
279
282
  id: 'context-model-route',