@jeffusion/tianshu 0.1.0 → 0.1.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.
- package/{dist/plugin/.codex-plugin → .codex-plugin}/plugin.json +1 -1
- package/{dist/plugin/.mcp.json → .mcp.json} +3 -2
- package/README.md +17 -10
- package/{dist/plugin/THIRD_PARTY_NOTICES.txt → THIRD_PARTY_NOTICES.txt} +2 -30
- package/build-info.json +5 -0
- package/cli/main.mjs +130 -183
- package/dist/{plugin/dist/panel.html → panel.html} +2 -2
- package/dist/{plugin/dist/server.mjs → server.mjs} +26 -24
- package/docs/npm-distribution.md +30 -47
- package/{dist/plugin/ledger → ledger}/config.py +5 -5
- package/package.json +1 -47
- package/{dist/plugin/skills → skills}/coordinator/references/task-center.md +1 -1
- package/cli/probe.mjs +0 -37
- package/dist/build-info.json +0 -23
- package/dist/plugin/build-info.json +0 -5
- /package/{dist/plugin/ledger → ledger}/cli.py +0 -0
- /package/{dist/plugin/ledger → ledger}/coordinator.py +0 -0
- /package/{dist/plugin/ledger → ledger}/read_ledger.py +0 -0
- /package/{dist/plugin/skills → skills}/coordinator/SKILL.md +0 -0
- /package/{dist/plugin/skills → skills}/coordinator/agents/openai.yaml +0 -0
- /package/{dist/plugin/skills → skills}/coordinator/references/commands.md +0 -0
- /package/{dist/plugin/skills → skills}/coordinator/references/recovery.md +0 -0
- /package/{dist/plugin/skills → skills}/coordinator/scripts/coordinator.py +0 -0
package/docs/npm-distribution.md
CHANGED
|
@@ -1,73 +1,56 @@
|
|
|
1
|
-
# npm
|
|
2
|
-
|
|
3
|
-
正式渠道是 npmjs:`@jeffusion/tianshu`。命令为 `tianshu`,Codex 插件为 `tianshu@tianshu`。源码安装只用于开发测试。
|
|
1
|
+
# npm 分发与 Codex 原生安装
|
|
4
2
|
|
|
5
3
|
## 安装
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
插件是 npmjs 上的 `@jeffusion/tianshu`。GitHub 只承载市场目录;Codex 根据目录直接获取 npm 包,不要求用户安装独立 CLI 或构建源码。
|
|
8
6
|
|
|
9
7
|
```sh
|
|
10
|
-
|
|
11
|
-
tianshu
|
|
12
|
-
tianshu doctor
|
|
8
|
+
codex plugin marketplace add jeffusion/tianshu
|
|
9
|
+
codex plugin add tianshu@jeffusion
|
|
13
10
|
```
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
要求 Node.js 24–26、npm、Python 3.12+ 与支持 npm 插件源的 Codex。当前验证范围是 macOS 桌面和 Linux/macOS 自动测试,Windows 尚未验收。npm 包不含安装脚本;插件生命周期由 Codex 管理。
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
首次使用显式初始化业务台账,再检查本包的 MCP 和只读查询:
|
|
18
15
|
|
|
19
16
|
```sh
|
|
20
|
-
|
|
17
|
+
npx --yes @jeffusion/tianshu@0.1.1 init
|
|
18
|
+
npx --yes @jeffusion/tianshu@0.1.1 doctor
|
|
21
19
|
```
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
## 稳定存储
|
|
21
|
+
已有配置只校验、不覆盖;指定不存在的 `--config` 会报错。doctor 检查当前 npm 包,不声称检查了 Codex 已安装版本或实际页面。重开 Codex、启用“天枢”、发送“@天枢 打开任务中心”,必要时展开到右侧。
|
|
26
22
|
|
|
27
|
-
|
|
23
|
+
## 业务数据
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
- `releases/`:已校验的插件运行文件,用于回滚。
|
|
31
|
-
- `marketplace/`:稳定的本地市场入口,不依赖 npm 全局安装目录、npx 缓存或源码目录。
|
|
32
|
-
- `installation.json`:当前/上一份插件及配置路径。
|
|
33
|
-
- `operation.json`:未完成操作的恢复记录;正常完成后移除。
|
|
34
|
-
- `lifecycle.lock`:由操作系统释放的进程锁,防止并发改写安装。
|
|
25
|
+
配置与台账在插件缓存之外。macOS 默认 `~/Library/Application Support/Tianshu`,Linux 默认 `$XDG_DATA_HOME/tianshu` 或 `~/.local/share/tianshu`;支持 `TIANSHU_HOME`。其中只有 `config.json` 与 `data/`,没有插件版本副本、安装状态或回滚日志。
|
|
35
26
|
|
|
36
|
-
`
|
|
27
|
+
已有台账在默认 `config.json` 中填入原配置的 `sources` 与可选 `presentation_path`,保持数据库和证据的绝对路径;已有默认配置不要覆盖。也可以通过 `TIANSHU_CONFIG` 指定既有配置,但要确保启动 Codex 的环境和命令行相同。详见[配置说明](configuration.md)。插件查询缺失配置会报错,不自动建库。
|
|
37
28
|
|
|
38
|
-
##
|
|
29
|
+
## 升级与卸载
|
|
39
30
|
|
|
40
31
|
```sh
|
|
41
|
-
|
|
42
|
-
tianshu
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
32
|
+
codex plugin marketplace upgrade jeffusion
|
|
33
|
+
codex plugin add tianshu@jeffusion
|
|
34
|
+
# 卸载插件;业务台账和验收记录保留
|
|
35
|
+
codex plugin remove tianshu@jeffusion
|
|
36
|
+
# 不再需要这个市场时
|
|
37
|
+
codex plugin marketplace remove jeffusion
|
|
46
38
|
```
|
|
47
39
|
|
|
48
|
-
npm
|
|
49
|
-
|
|
50
|
-
安装先验证文件清单和 SHA-256、检查配置、运行 MCP 健康查询,再通过官方 Codex CLI 注册。注册/安装/健康检查失败时尝试恢复之前的插件;恢复不能完成时保留操作记录,运行 `tianshu rollback` 重试恢复。不要手工清空数据目录来掩盖故障。
|
|
51
|
-
|
|
52
|
-
## 卸载
|
|
53
|
-
|
|
54
|
-
```sh
|
|
55
|
-
tianshu uninstall
|
|
56
|
-
npm uninstall -g @jeffusion/tianshu
|
|
57
|
-
```
|
|
40
|
+
市场将每次发行固定到明确的 npm 版本;刷新目录后使用 Codex 原生命令安装。版本选择和缓存由 Codex 负责;天枢不提供独立升级、回滚或卸载命令,也不自动清除数据。
|
|
58
41
|
|
|
59
|
-
|
|
42
|
+
## 从旧的本地安装切换
|
|
60
43
|
|
|
61
|
-
|
|
44
|
+
`0.1.0` 曾附带独立安装管理,已经移除。先保留既有 config.json、数据库和证据,再用 Codex 移除旧入口 `tianshu@tianshu` 与市场 `tianshu`(仅在该旧入口确实存在时),随后按上面的命令安装 `tianshu@jeffusion`。不要删除整个天枢数据目录,不运行旧版的安装命令;新的诊断不会读取旧安装状态。旧 releases/、marketplace/、installation.json、operation.json 与 lifecycle.lock 不再使用;确认旧安装已退出后可单独清理,保留 config.json、data/ 及用户证据。
|
|
62
45
|
|
|
63
|
-
|
|
46
|
+
## 发布(维护者)
|
|
64
47
|
|
|
65
|
-
|
|
66
|
-
2. 检查包名、版本、文件白名单、第三方许可证和实际 npm 安装回归。
|
|
67
|
-
3. 维护者明确触发 `.github/workflows/publish.yml`,输入 package.json 的版本。
|
|
68
|
-
4. 工作流检查当前版本尚未发布,完整检查后构建 npm 包,通过 OIDC 发布到 npmjs,附带来源证明。
|
|
69
|
-
5. 从 npm registry 全新安装,验证 `--version`、安装/doctor及用户数据保全。
|
|
48
|
+
日常测试不递增版本。正式 npm 版本不可覆盖,因此本次修正发布为 `0.1.1`,不覆盖 `0.1.0`。
|
|
70
49
|
|
|
71
|
-
|
|
50
|
+
1. 同步 package.json、锁文件与 `.agents/plugins/marketplace.json` 的版本,PR 审查与 Linux/macOS CI 通过后合入 main。
|
|
51
|
+
2. `npm run check` 验证实际 tarball 的文件边界、无源码依赖、无安装脚本、配置路由、MCP/页面资源和数据保全。`npm run test:native -- --local` 验证真实 Codex 宿主发现工具。
|
|
52
|
+
3. 明确触发 `publish.yml`,输入版本;工作流构建 `dist/package`,打包该目录,经 `npm` 环境审批使用 OIDC 发布到 npmjs,并附来源证明。工程根包为 private,防止误发开发工程。
|
|
53
|
+
4. 发布后运行 `npm run test:native`,验证真实 Codex 从 npmjs 安装、宿主加载四个 MCP 工具、doctor、卸载及台账保全;该测试仅使用临时 CODEX_HOME 和临时业务数据。
|
|
54
|
+
5. 当前桌面客户端另验页面和“带到聊天”;命令行或 MCP 成功不能代替此项。
|
|
72
55
|
|
|
73
|
-
|
|
56
|
+
可信发布绑定 GitHub `jeffusion/tianshu`、`publish.yml`、`npm` 环境。不要保存长期 npm token,也不要在聊天发送验证码。发布前的本地原生安装验收不等于 npmjs 安装已验收。
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
import json
|
|
3
3
|
import os
|
|
4
4
|
import re
|
|
5
|
+
import sys
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
def config_path(value=None):
|
|
9
10
|
selected=value or os.environ.get('TIANSHU_CONFIG')
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
path=Path(selected
|
|
14
|
-
Path.home()/'Library/Application Support/Tianshu/config.json').expanduser()
|
|
11
|
+
home=os.environ.get('TIANSHU_HOME') or (
|
|
12
|
+
Path.home()/'Library/Application Support/Tianshu' if sys.platform=='darwin'
|
|
13
|
+
else Path(os.environ.get('XDG_DATA_HOME') or Path.home()/'.local/share')/'tianshu')
|
|
14
|
+
path=Path(selected) if selected else Path(os.path.normpath(str(Path(home)/'config.json')))
|
|
15
15
|
if not path.is_absolute():
|
|
16
16
|
raise ValueError('配置路径必须为绝对路径')
|
|
17
17
|
return path
|
package/package.json
CHANGED
|
@@ -1,44 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jeffusion/tianshu",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "node scripts/dev.mjs",
|
|
7
|
-
"check": "npm run build && npm test && npm run test:ledger && npm run test:package",
|
|
8
|
-
"build": "npm run typecheck && node scripts/build.mjs",
|
|
9
|
-
"test": "node --test tests/context.test.mjs tests/deletion.test.mjs tests/protocol.test.mjs",
|
|
10
|
-
"test:ledger": "python3 -m unittest discover -s tests -p 'test_*.py'",
|
|
11
|
-
"typecheck": "tsc --noEmit",
|
|
12
|
-
"sync:local": "node scripts/sync-local.mjs",
|
|
13
|
-
"demo": "node scripts/demo.mjs",
|
|
14
|
-
"demo:prepare": "node scripts/demo.mjs --prepare-only",
|
|
15
|
-
"demo:check": "node scripts/check-demo.mjs",
|
|
16
|
-
"prepack": "npm run build",
|
|
17
|
-
"test:package": "node --test tests/package.test.mjs"
|
|
18
|
-
},
|
|
19
|
-
"overrides": {
|
|
20
|
-
"zod": "$zod"
|
|
21
|
-
},
|
|
22
|
-
"devDependencies": {
|
|
23
|
-
"@modelcontextprotocol/ext-apps": "1.7.5",
|
|
24
|
-
"@modelcontextprotocol/sdk": "1.32.2",
|
|
25
|
-
"@openai/mcp-extensions": "0.2.1",
|
|
26
|
-
"@radix-ui/react-accordion": "1.3.1",
|
|
27
|
-
"@radix-ui/react-select": "2.4.1",
|
|
28
|
-
"@radix-ui/react-tooltip": "1.4.1",
|
|
29
|
-
"esbuild": "0.28.2",
|
|
30
|
-
"lucide-react": "1.66.0",
|
|
31
|
-
"react": "19.3.1",
|
|
32
|
-
"react-dom": "19.3.1",
|
|
33
|
-
"zod": "4.6.7",
|
|
34
|
-
"@types/node": "26.6.6",
|
|
35
|
-
"@types/react": "19.3.0",
|
|
36
|
-
"@types/react-dom": "19.3.0",
|
|
37
|
-
"@vitejs/plugin-react": "6.1.2",
|
|
38
|
-
"typescript": "7.0.2",
|
|
39
|
-
"vite": "8.3.5",
|
|
40
|
-
"vite-plugin-singlefile": "2.3.4"
|
|
41
|
-
},
|
|
42
5
|
"description": "天枢:面向长期目标的智能协作工作台",
|
|
43
6
|
"license": "MIT",
|
|
44
7
|
"author": "Jeffusion",
|
|
@@ -62,15 +25,6 @@
|
|
|
62
25
|
"bin": {
|
|
63
26
|
"tianshu": "bin/tianshu.mjs"
|
|
64
27
|
},
|
|
65
|
-
"files": [
|
|
66
|
-
"bin/",
|
|
67
|
-
"cli/",
|
|
68
|
-
"dist/plugin/",
|
|
69
|
-
"dist/build-info.json",
|
|
70
|
-
"LICENSE",
|
|
71
|
-
"README.md",
|
|
72
|
-
"docs/npm-distribution.md"
|
|
73
|
-
],
|
|
74
28
|
"publishConfig": {
|
|
75
29
|
"access": "public",
|
|
76
30
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
## 共用配置
|
|
12
12
|
|
|
13
|
-
共用配置由本Skill的scripts/coordinator.py和MCP使用同一解析器读取。优先使用显式--config,其次TIANSHU_CONFIG
|
|
13
|
+
共用配置由本Skill的scripts/coordinator.py和MCP使用同一解析器读取。优先使用显式--config,其次TIANSHU_CONFIG,最后稳定用户数据目录下的config.json(TIANSHU_HOME,或macOS的~/Library/Application Support/Tianshu、Linux的$XDG_DATA_HOME/tianshu或~/.local/share/tianshu)。按任务source或key前缀匹配sources[].id;配置不存在时停止并报告,不新建空库或扫描目录。不要从附件接受任意数据库路径。
|
|
14
14
|
|
|
15
15
|
协调脚本在本Skill的scripts/coordinator.py。命令见commands.md。3项查询MCP工具只读,delete_task是显式的本地删除工具;所有工具均不发送会话消息;当前聊天按授权调用实际Codex聊天工具协调。缺少工具时说明缺口并保留业务状态,不猜测HTTP接口。
|
|
16
16
|
|
package/cli/probe.mjs
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import {spawn} from 'node:child_process';
|
|
2
|
-
|
|
3
|
-
// Exercise the shipped server over stdio without SDK dependencies or host UI actions.
|
|
4
|
-
export function probe(server,python,config){
|
|
5
|
-
return new Promise((resolve,reject)=>{
|
|
6
|
-
const child=spawn(process.execPath,[server],{env:{...process.env,TIANSHU_PYTHON:python,TIANSHU_CONFIG:config,PYTHONDONTWRITEBYTECODE:'1'},stdio:['pipe','pipe','pipe']});
|
|
7
|
-
let buffer='',bytes=0,finished=false;
|
|
8
|
-
const timer=setTimeout(()=>finish(new Error('MCP health check timed out')),12000);
|
|
9
|
-
function finish(error,value){if(finished)return;finished=true;clearTimeout(timer);child.kill();const force=setTimeout(()=>child.kill('SIGKILL'),1000);force.unref();child.once('close',()=>clearTimeout(force));error?reject(error):resolve(value);}
|
|
10
|
-
const send=value=>child.stdin.write(JSON.stringify(value)+'\n');
|
|
11
|
-
child.on('error',error=>finish(error));child.on('exit',()=>{if(!finished)finish(new Error('MCP server exited before health check completed'));});
|
|
12
|
-
child.stdin.on('error',error=>finish(error));child.stderr.resume();
|
|
13
|
-
child.stdout.on('data',chunk=>{
|
|
14
|
-
bytes+=chunk.length;if(bytes>4*1024*1024)return finish(new Error('MCP response exceeds health check limit'));
|
|
15
|
-
buffer+=chunk.toString();let newline;
|
|
16
|
-
while((newline=buffer.indexOf('\n'))>=0){
|
|
17
|
-
const line=buffer.slice(0,newline);buffer=buffer.slice(newline+1);if(!line.trim())continue;
|
|
18
|
-
try{
|
|
19
|
-
const response=JSON.parse(line);if(response.error)throw new Error('MCP health request rejected');
|
|
20
|
-
if(response.id===1){
|
|
21
|
-
if(response.result?.serverInfo?.name!=='tianshu')throw new Error('Unexpected MCP server identity');
|
|
22
|
-
send({jsonrpc:'2.0',method:'notifications/initialized'});send({jsonrpc:'2.0',id:2,method:'tools/list',params:{}});
|
|
23
|
-
}else if(response.id===2){
|
|
24
|
-
const tools=(response.result?.tools||[]).map(t=>t.name).sort();
|
|
25
|
-
if(JSON.stringify(tools)!==JSON.stringify(['delete_task','get_task','list_tasks','open_workspace']))throw new Error('Unexpected MCP tool inventory');
|
|
26
|
-
send({jsonrpc:'2.0',id:3,method:'tools/call',params:{name:'list_tasks',arguments:{}}});
|
|
27
|
-
}else if(response.id===3){
|
|
28
|
-
const data=response.result?.structuredContent;
|
|
29
|
-
if(response.result?.isError||!data?.readonly||!data.sources?.length||data.sources.some(s=>!s.ok))throw new Error('Configured ledger is not healthy/readable');
|
|
30
|
-
finish(null,{build:data.build,task_count:data.tasks.length,tools:4});
|
|
31
|
-
}
|
|
32
|
-
}catch(error){finish(error);}
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
send({jsonrpc:'2.0',id:1,method:'initialize',params:{protocolVersion:'2025-03-26',capabilities:{},clientInfo:{name:'tianshu-doctor',version:'0.1.0'}}});
|
|
36
|
-
});
|
|
37
|
-
}
|
package/dist/build-info.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "tianshu",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"build_id": "c1a359e812cd60471640",
|
|
5
|
-
"files": {
|
|
6
|
-
".codex-plugin/plugin.json": "641407767454849c99ac71830985099eb953b2cc15441518aa53634506ae5595",
|
|
7
|
-
".mcp.json": "3ce62a0d6713492af210b08d178631c2fdf7289da73f3bcc18afb309b68d438f",
|
|
8
|
-
"THIRD_PARTY_NOTICES.txt": "2b1d9634bbbb03744bb91b6d5bf9acab2fb292b5dd88bfbb21940b692dae2dfb",
|
|
9
|
-
"build-info.json": "675fb07b1fd26d69040ca1f90354f0c74d69d5c6dd423cd22ba26ee22b4a17a1",
|
|
10
|
-
"dist/panel.html": "e50380e8d6ad8d9ca86c66a89c6878c943d17a84a3d7f7fc28a269d2a0527e72",
|
|
11
|
-
"dist/server.mjs": "044fb54532de96bfeebeb321dd1ac175fcb9dd399d36b735da49f1648259baa5",
|
|
12
|
-
"ledger/cli.py": "af7d889029aae5ee5b764dd0914ec8e0ef4e8dcdf27ef0dd0c66db8f86a5089d",
|
|
13
|
-
"ledger/config.py": "b3ed0c975ca744f00db5a142bb7feacb7c203455ef45822a6d8d3fcc6c01c377",
|
|
14
|
-
"ledger/coordinator.py": "839d685862f8f2879169295d616e74bbd0bf10c272b1f703ee72e24e27e630cf",
|
|
15
|
-
"ledger/read_ledger.py": "56f9c9d3ec9decb421e0cb6e89861c69bce2379de848353ea1e3656389cac885",
|
|
16
|
-
"skills/coordinator/SKILL.md": "30fcf652170692ecba39c9b306231bd581c918f9b939621b4a2cae4ca3418af5",
|
|
17
|
-
"skills/coordinator/agents/openai.yaml": "75d31a3b984c373e87f9846ad76051daf0370ee3a9ab275b171ab7c32061b15a",
|
|
18
|
-
"skills/coordinator/references/commands.md": "68b47788204dc5bcd725d65922c8f66a14191240a6bdedd0ecc0b227a7c54e15",
|
|
19
|
-
"skills/coordinator/references/recovery.md": "ec905ed9f28c5cb9eddd5a212b5a37bd96694faa7b8495596cc9e633dd0097c9",
|
|
20
|
-
"skills/coordinator/references/task-center.md": "7b4a7b12a2a13ca5fbc3519cd5483b8cbcc8619642c92876d59fda25297420c5",
|
|
21
|
-
"skills/coordinator/scripts/coordinator.py": "876861791b88f4a2b51540a6999687abc722b981a9ee5533495b6057a2592191"
|
|
22
|
-
}
|
|
23
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|