@ibotor/smart-trellis 0.5.21 → 0.5.22

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/README.md CHANGED
@@ -223,6 +223,49 @@ smart-trellis init --tools codex,cursor --no-monorepo
223
223
 
224
224
  所以,`smart-trellis init` 的目标不是只生成一个轻量配置,而是用更少确认步骤生成原 Trellis 初始化应有的完整结果。
225
225
 
226
+ ## Apifox 前后端联调入口
227
+
228
+ 初始化 Cursor / Codex 等平台后,会生成 `trellis-joint-debugger` 入口,用于根据 Apifox 接口链接自动解析接口详情并辅助前后端联调。
229
+
230
+ 常见触发方式:
231
+
232
+ - Cursor:`/trellis-joint-debugger`
233
+ - Codex / `.agents/skills`:`$trellis-joint-debugger`
234
+
235
+ 当用户提供以下 Apifox 链接,并提到“联调”“接口”“参数”“详情”“完成它”等开发意图时,入口会优先走 Apifox Web API,而不是默认打开浏览器页面:
236
+
237
+ ```text
238
+ app.apifox.com/link/project/{projectId}/apis/api-{apiId}
239
+ app.apifox.com/project/{projectId}/apis/api-{apiId}
240
+ ```
241
+
242
+ 第一次使用前,需要配置 Apifox access token:
243
+
244
+ ```bash
245
+ python3 ./.trellis/scripts/apifox_token.py check
246
+ python3 ./.trellis/scripts/apifox_token.py save
247
+ ```
248
+
249
+ `save` 会使用隐藏输入,并把 token 保存到用户级配置:
250
+
251
+ ```text
252
+ ~/.trellis/apifox.env
253
+ ```
254
+
255
+ 因此同一台机器上只需要配置一次,后续所有 Trellis 项目都可以复用。运行时读取优先级为:
256
+
257
+ 1. `APIFOX_ACCESS_TOKEN` 环境变量
258
+ 2. `~/.trellis/apifox.env`
259
+ 3. 旧项目内 `.trellis/.runtime/apifox.env`(仅兼容读取)
260
+
261
+ token 只用于请求 header,不会被命令打印。接口详情会通过:
262
+
263
+ ```text
264
+ GET https://api.apifox.com/api/v1/projects/{projectId}/http-apis/{apiId}
265
+ ```
266
+
267
+ 如请求体或响应中出现 `$ref: #/definitions/{schemaId}`,会继续根据接口详情里的 `moduleId` 请求 data-schemas 并解析入参/出参字段。随后 Trellis 会将 method、path、入参、出参与当前项目中的 API 封装核对;如果要联调真实后端,再根据项目代理和环境配置请求业务后端。若缺少业务登录态,应明确报告 `401` / 未登录,不猜测数据。
268
+
226
269
  ## 本地开发验证
227
270
 
228
271
  在本仓库开发时,可以先构建 CLI:
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.5.22",
3
+ "description": "Patch: expand the Apifox joint debugger workflow and add user-level Apifox token storage.",
4
+ "breaking": false,
5
+ "recommendMigrate": false,
6
+ "changelog": "**Enhancements:**\n- feat(joint-debugger): expand `trellis-joint-debugger` into an Apifox-backed frontend-backend joint debugging workflow. It parses Apifox API links, fetches API details through the Apifox Web API, resolves referenced schemas, and compares method/path/fields with local API wrappers.\n- feat(scripts): add `.trellis/scripts/apifox_token.py` so users can configure `APIFOX_ACCESS_TOKEN` once per machine at `~/.trellis/apifox.env`. Environment variables still take precedence, and legacy project-local `.trellis/.runtime/apifox.env` files remain readable as a fallback.",
7
+ "migrations": [],
8
+ "notes": "No migration required. Run `trellis update` to receive the expanded joint debugger command/skill and the Apifox token helper script. Run `python3 ./.trellis/scripts/apifox_token.py save` once to store the Apifox token for all Trellis projects on this machine."
9
+ }
@@ -1,5 +1,97 @@
1
1
  # Joint Debugger
2
2
 
3
- Frontend-backend joint debugging entry point.
3
+ Frontend-backend joint debugging entry point for Apifox-backed API work.
4
4
 
5
- TODO: Fill in this workflow later.
5
+ Use this command when the user provides an Apifox API link and asks about
6
+ joint debugging, interface details, parameters, implementation, or completion.
7
+
8
+ ## Step 0: Load Trellis Context
9
+
10
+ Run the same startup context that `/trellis start` would load, but do not create
11
+ a task unless the user explicitly asks for Trellis task management.
12
+
13
+ ```bash
14
+ {{PYTHON_CMD}} ./.trellis/scripts/get_context.py
15
+ {{PYTHON_CMD}} ./.trellis/scripts/get_context.py --mode phase
16
+ {{PYTHON_CMD}} ./.trellis/scripts/get_context.py --mode packages
17
+ ```
18
+
19
+ ## Step 1: Ensure Apifox Token
20
+
21
+ Before calling Apifox APIs, check whether `APIFOX_ACCESS_TOKEN` is already
22
+ configured. The token must only be used in request headers and must never be
23
+ printed.
24
+
25
+ ```bash
26
+ {{PYTHON_CMD}} ./.trellis/scripts/apifox_token.py check
27
+ ```
28
+
29
+ If the check fails, ask the user to get an Apifox access token and run:
30
+
31
+ ```bash
32
+ {{PYTHON_CMD}} ./.trellis/scripts/apifox_token.py save
33
+ ```
34
+
35
+ The save prompt hides input and stores the token in the user-level config
36
+ `~/.trellis/apifox.env`, so it works across projects. After the user saves it,
37
+ rerun the check before continuing. Do not ask the user to paste the token into
38
+ chat. Legacy project-local `.trellis/.runtime/apifox.env` files are still read
39
+ as a fallback, but new saves are global.
40
+
41
+ ## Step 2: Parse Apifox Link
42
+
43
+ Recognize these link forms:
44
+
45
+ - `app.apifox.com/link/project/{projectId}/apis/api-{apiId}`
46
+ - `app.apifox.com/project/{projectId}/apis/api-{apiId}`
47
+
48
+ Extract `projectId` and `apiId`. Do not open the Apifox page in a browser by
49
+ default.
50
+
51
+ ## Step 3: Fetch API Detail
52
+
53
+ Load the token without printing it, then request the Apifox Web API:
54
+
55
+ ```bash
56
+ set -a
57
+ if [ -z "${APIFOX_ACCESS_TOKEN:-}" ]; then
58
+ APIFOX_TOKEN_FILE="$({{PYTHON_CMD}} ./.trellis/scripts/apifox_token.py path)"
59
+ [ -f "$APIFOX_TOKEN_FILE" ] && . "$APIFOX_TOKEN_FILE"
60
+ fi
61
+ set +a
62
+ curl -sS \
63
+ -H "Authorization: Bearer ${APIFOX_ACCESS_TOKEN}" \
64
+ -H "X-Branch-Id: 0" \
65
+ -H "X-Client-Version: 100.100.100" \
66
+ "https://api.apifox.com/api/v1/projects/{projectId}/http-apis/{apiId}"
67
+ ```
68
+
69
+ Capture `method`, `path`, `moduleId`, request parameters, `requestBody`, and
70
+ `responses`.
71
+
72
+ ## Step 4: Resolve Schema References
73
+
74
+ If `requestBody` or `responses` contains `$ref: #/definitions/{schemaId}`, use
75
+ the API detail's `moduleId` to fetch schemas:
76
+
77
+ ```bash
78
+ curl -sS \
79
+ -H "Authorization: Bearer ${APIFOX_ACCESS_TOKEN}" \
80
+ -H "X-Branch-Id: 0" \
81
+ -H "X-Client-Version: 100.100.100" \
82
+ "https://api.apifox.com/api/v1/projects/{projectId}/data-schemas?moduleId={moduleId}"
83
+ ```
84
+
85
+ Match definitions by schema id and expand request/response fields before
86
+ summarizing the interface.
87
+
88
+ ## Step 5: Compare With Code
89
+
90
+ Search the current codebase for existing API wrappers, request clients,
91
+ environment proxy settings, and matching paths. Compare the parsed
92
+ `method/path` and request/response fields with the local API encapsulation.
93
+
94
+ If the user wants real backend joint debugging, use the project's proxy and
95
+ environment configuration to call the business backend. If the backend returns
96
+ `401` or requires a login session, report that clearly as unauthenticated
97
+ instead of inventing data.
@@ -42,6 +42,7 @@ export declare const initDeveloperScript: string;
42
42
  export declare const taskScript: string;
43
43
  export declare const getContextScript: string;
44
44
  export declare const addSessionScript: string;
45
+ export declare const apifoxTokenScript: string;
45
46
  export declare const workflowMdTemplate: string;
46
47
  export declare const configYamlTemplate: string;
47
48
  export declare const gitignoreTemplate: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AAGvE,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAE/D;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAqCnD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,iBAAiB,QAA0C,CAAC;AAGzE,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAE/D;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAsCnD"}
@@ -53,6 +53,7 @@ export const initDeveloperScript = readTemplate("scripts/init_developer.py");
53
53
  export const taskScript = readTemplate("scripts/task.py");
54
54
  export const getContextScript = readTemplate("scripts/get_context.py");
55
55
  export const addSessionScript = readTemplate("scripts/add_session.py");
56
+ export const apifoxTokenScript = readTemplate("scripts/apifox_token.py");
56
57
  // Configuration files
57
58
  export const workflowMdTemplate = readTemplate("workflow.md");
58
59
  export const configYamlTemplate = readTemplate("config.yaml");
@@ -92,6 +93,7 @@ export function getAllScripts() {
92
93
  scripts.set("task.py", taskScript);
93
94
  scripts.set("get_context.py", getContextScript);
94
95
  scripts.set("add_session.py", addSessionScript);
96
+ scripts.set("apifox_token.py", apifoxTokenScript);
95
97
  return scripts;
96
98
  }
97
99
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env python3
2
+ """Manage the user-level Apifox access token for Trellis joint debugging."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import getpass
8
+ import os
9
+ import shlex
10
+ import sys
11
+ from pathlib import Path
12
+
13
+
14
+ TOKEN_NAME = "APIFOX_ACCESS_TOKEN"
15
+ GLOBAL_CONFIG_PATH = Path(
16
+ os.environ.get("TRELLIS_APIFOX_TOKEN_FILE", "~/.trellis/apifox.env")
17
+ ).expanduser()
18
+ LEGACY_PROJECT_CONFIG_PATH = Path(".trellis/.runtime/apifox.env")
19
+
20
+
21
+ def parse_env_value(value: str) -> str:
22
+ try:
23
+ parts = shlex.split(value, comments=False, posix=True)
24
+ except ValueError:
25
+ return value.strip().strip("'\"")
26
+ if len(parts) == 1:
27
+ return parts[0]
28
+ return value.strip().strip("'\"")
29
+
30
+
31
+ def read_token_file(path: Path) -> str | None:
32
+ try:
33
+ content = path.read_text(encoding="utf-8")
34
+ except OSError:
35
+ return None
36
+
37
+ for raw_line in content.splitlines():
38
+ line = raw_line.strip()
39
+ if not line or line.startswith("#") or "=" not in line:
40
+ continue
41
+ key, value = line.split("=", 1)
42
+ if key.strip() != TOKEN_NAME:
43
+ continue
44
+ value = parse_env_value(value.strip())
45
+ return value or None
46
+ return None
47
+
48
+
49
+ def configured_source() -> str | None:
50
+ if os.environ.get(TOKEN_NAME):
51
+ return "environment"
52
+ if read_token_file(GLOBAL_CONFIG_PATH):
53
+ return "user config"
54
+ if read_token_file(LEGACY_PROJECT_CONFIG_PATH):
55
+ return "project-local config (legacy)"
56
+ return None
57
+
58
+
59
+ def cmd_check(_args: argparse.Namespace) -> int:
60
+ source = configured_source()
61
+ if source:
62
+ print(f"{TOKEN_NAME} is configured via {source}. Token value hidden.")
63
+ return 0
64
+
65
+ print(f"{TOKEN_NAME} is not configured.")
66
+ print("Run: python3 ./.trellis/scripts/apifox_token.py save")
67
+ print("Then paste the token into the hidden prompt.")
68
+ return 1
69
+
70
+
71
+ def cmd_save(_args: argparse.Namespace) -> int:
72
+ token = getpass.getpass(f"Paste {TOKEN_NAME} (input hidden): ").strip()
73
+ if not token:
74
+ print("No token provided; nothing saved.", file=sys.stderr)
75
+ return 1
76
+ if "\n" in token or "\r" in token:
77
+ print("Token must be a single line.", file=sys.stderr)
78
+ return 1
79
+
80
+ GLOBAL_CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
81
+ try:
82
+ GLOBAL_CONFIG_PATH.parent.chmod(0o700)
83
+ except OSError:
84
+ pass
85
+ GLOBAL_CONFIG_PATH.write_text(
86
+ "# User-level Trellis config. Do not commit or print this value.\n"
87
+ f"{TOKEN_NAME}={shlex.quote(token)}\n",
88
+ encoding="utf-8",
89
+ )
90
+ GLOBAL_CONFIG_PATH.chmod(0o600)
91
+ print(f"{TOKEN_NAME} saved to {GLOBAL_CONFIG_PATH}. Token value hidden.")
92
+ return 0
93
+
94
+
95
+ def cmd_path(_args: argparse.Namespace) -> int:
96
+ print(GLOBAL_CONFIG_PATH)
97
+ return 0
98
+
99
+
100
+ def build_parser() -> argparse.ArgumentParser:
101
+ parser = argparse.ArgumentParser(
102
+ description="Manage the user-level Apifox access token for Trellis.",
103
+ )
104
+ subparsers = parser.add_subparsers(dest="command", required=True)
105
+
106
+ check_parser = subparsers.add_parser("check", help="Check token presence.")
107
+ check_parser.set_defaults(func=cmd_check)
108
+
109
+ save_parser = subparsers.add_parser(
110
+ "save",
111
+ help="Save token to user-level config.",
112
+ )
113
+ save_parser.set_defaults(func=cmd_save)
114
+
115
+ path_parser = subparsers.add_parser("path", help="Print user-level config path.")
116
+ path_parser.set_defaults(func=cmd_path)
117
+
118
+ return parser
119
+
120
+
121
+ def main() -> int:
122
+ parser = build_parser()
123
+ args = parser.parse_args()
124
+ return args.func(args)
125
+
126
+
127
+ if __name__ == "__main__":
128
+ raise SystemExit(main())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibotor/smart-trellis",
3
- "version": "0.5.21",
3
+ "version": "0.5.22",
4
4
  "description": "Smart Trellis CLI with project-aware initialization defaults",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",