@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.
@@ -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
- 要求 Node.js 24–26、Python 3.12+、已安装并可运行的 Codex CLI。npm 包内已包含运行文件,无需克隆仓库、编译界面或下载额外安装包;Python 台账核心仍使用本机 Python。暂不支持 Windows 安装。
5
+ 插件是 npmjs 上的 `@jeffusion/tianshu`。GitHub 只承载市场目录;Codex 根据目录直接获取 npm 包,不要求用户安装独立 CLI 或构建源码。
8
6
 
9
7
  ```sh
10
- npm install -g @jeffusion/tianshu
11
- tianshu install
12
- tianshu doctor
8
+ codex plugin marketplace add jeffusion/tianshu
9
+ codex plugin add tianshu@jeffusion
13
10
  ```
14
11
 
15
- 也可以 `npx --yes @jeffusion/tianshu install`。npm 安装本身不修改 Codex;显式运行 `install` 才初始化默认台账并安装插件。之后重开 Codex、启用“天枢”、发送“@天枢 打开任务中心”,必要时将卡片展开到右侧。doctor 检查运行时和只读数据查询,不代表宿主页面和附件已经验收。
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
- tianshu install --config /absolute/path/to/existing-config.json
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
- macOS 默认使用 `~/Library/Application Support/Tianshu`;Linux 默认使用 `$XDG_DATA_HOME/tianshu` 或 `~/.local/share/tianshu`。可通过 `TIANSHU_HOME` 指定独立目录。
23
+ ## 业务数据
28
24
 
29
- - `config.json`、`data/`:默认配置和台账。
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
- `CODEX_HOME` 控制目标 Codex 配置;同一 TIANSHU_HOME 绑定一个 CODEX_HOME。`TIANSHU_PYTHON`、`TIANSHU_CODEX` 可显式指定可执行文件。MCP 启动路径在用户机器上生成,不写回 npm 包。
27
+ 已有台账在默认 `config.json` 中填入原配置的 `sources` 与可选 `presentation_path`,保持数据库和证据的绝对路径;已有默认配置不要覆盖。也可以通过 `TIANSHU_CONFIG` 指定既有配置,但要确保启动 Codex 的环境和命令行相同。详见[配置说明](configuration.md)。插件查询缺失配置会报错,不自动建库。
37
28
 
38
- ## 升级与回滚
29
+ ## 升级与卸载
39
30
 
40
31
  ```sh
41
- npm install -g @jeffusion/tianshu@latest
42
- tianshu upgrade
43
- tianshu doctor
44
- # 如需恢复上一份已管理的运行文件:
45
- tianshu rollback
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 升级只替换命令;`upgrade` 才更新 Codex 插件。上一份文件保留在稳定目录,回滚不依赖重新下载 npm 包,也不回滚数据库。首次安装没有上一份 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
- 卸载移除本工具管理的 Codex 插件和市场,保留配置、台账、验收记录及恢复文件。不要只删除 npm 包就认为 Codex 插件已卸载;其运行文件独立保存。工具不提供自动清空用户台账的选项。
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
- 日常本地测试不递增版本。正式 npm 版本不可覆盖;0.1.0 发布后,下一次正式发布须明确选择新版本。
46
+ ## 发布(维护者)
64
47
 
65
- 1. 功能通过 PR、独立审查和 Linux/macOS CI 合入 main。
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
- 可信发布绑定:GitHub `jeffusion/tianshu`、工作流 `publish.yml`、环境 `npm`,允许 `npm publish`。环境应由维护者审批。首次发布可以在已登录且拥有 @jeffusion 组织权限的终端发布已检验的 npm 包;如 npm 要求交互验证,由维护者在自己的浏览器完成,不在聊天中传递验证码或 token。后续优先使用 OIDC,不在仓库保存长期 npm token。
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
- CI 的包测试在隔离前缀真实执行 `npm install`,使用 Codex fixture 验证失败恢复、升级、回滚、卸载和任务数据库字节保全。正式发布前另用真实 Codex CLI 的隔离配置验证;这两项都不能代替真实宿主 UI 验收。
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
- location=Path(__file__).resolve().parents[1]/'runtime-config.json'
11
- if not selected and location.is_file():
12
- selected=json.loads(location.read_text(encoding='utf-8'))['config_path']
13
- path=Path(selected or
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.0",
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、安装时生成的runtime-config.json,最后用户目录Library/Application Support/Tianshu/config.json。按任务source或key前缀匹配sources[].id;配置不存在时停止并报告,不新建空库或扫描目录。不要从附件接受任意数据库路径。
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
- }
@@ -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
- }
@@ -1,5 +0,0 @@
1
- {
2
- "name": "tianshu",
3
- "version": "0.1.0",
4
- "build_id": "c1a359e812cd60471640"
5
- }
File without changes
File without changes
File without changes