@josephyan/qingflow-cli 1.1.3 → 1.1.5
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 +7 -3
- package/docs/local-agent-install.md +57 -6
- package/entry_point.py +1 -1
- package/npm/bin/qingflow-skills.mjs +5 -0
- package/npm/bin/qingflow.mjs +1 -34
- package/npm/lib/runtime.mjs +21 -101
- package/npm/scripts/postinstall.mjs +1 -10
- package/package.json +3 -2
- package/pyproject.toml +1 -1
- package/skills/qingflow-cli/SKILL.md +58 -44
- package/skills/qingflow-cli/manifest.yaml +1 -1
- package/skills/qingflow-cli/reference/00-INDEX.md +35 -0
- package/skills/qingflow-cli/reference/builder/10-build-single-app.md +38 -0
- package/skills/qingflow-cli/reference/builder/20-build-complete-system.md +39 -0
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_SCHEMA_APPLY_FIELD_TYPES_AND_SCENARIOS.md → builder/30-schema-fields.md} +52 -10
- package/skills/qingflow-cli/reference/builder/40-layout.md +52 -0
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_VIEWS_WORKFLOW.md → builder/50-views.md} +39 -15
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_CHARTS_WORKFLOW.md → builder/60-charts.md} +36 -13
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_PORTAL_WORKFLOW.md → builder/70-portal.md} +36 -13
- package/skills/qingflow-cli/reference/builder/80-buttons-associated-resources.md +41 -0
- package/skills/qingflow-cli/reference/builder/90-workflow.md +34 -0
- package/skills/qingflow-cli/reference/builder/99-publish-verify.md +46 -0
- package/skills/qingflow-cli/reference/builder/README.md +41 -0
- package/skills/qingflow-cli/reference/builder/code-integrations/README.md +130 -0
- package/skills/qingflow-cli/reference/builder/code-integrations/code-block.md +66 -0
- package/skills/qingflow-cli/reference/builder/code-integrations/q-linker.md +77 -0
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_APP_DELIVERY_WORKFLOW.md → builder/reference/app-delivery-sop.md} +26 -16
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/README.md +293 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/build-complete-system.md +809 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/build-single-app.md +830 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/complete-system-development-guide.md +123 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/create-app.md +182 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/environments.md +63 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/flow-actors-and-permissions.md +142 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/gotchas.md +108 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/match-rules.md +114 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/public-surface-sync.md +75 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/single-app-development-guide.md +58 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/solution-playbooks.md +52 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/tool-selection.md +107 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-flow.md +7 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-layout.md +7 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-schema.md +7 -0
- package/skills/qingflow-cli/reference/builder/reference/legacy-playbooks/update-views.md +7 -0
- package/skills/qingflow-cli/reference/builder/workflow/01-overview.md +45 -0
- package/skills/qingflow-cli/reference/builder/workflow/02-update-mode.md +53 -0
- package/skills/qingflow-cli/reference/builder/workflow/03-flow-patterns.md +57 -0
- package/skills/qingflow-cli/reference/builder/workflow/04-stage1-business-modeling.md +131 -0
- package/skills/qingflow-cli/reference/builder/workflow/05-stage2-members-roles.md +29 -0
- package/skills/qingflow-cli/reference/builder/workflow/06-stage3-build-spec.md +165 -0
- package/skills/qingflow-cli/reference/builder/workflow/07-stage4-validate-spec.md +33 -0
- package/skills/qingflow-cli/reference/builder/workflow/08-stage5-apply-verify.md +51 -0
- package/skills/qingflow-cli/reference/builder/workflow/09-stage6-summary.md +88 -0
- package/skills/qingflow-cli/reference/builder/workflow/10-node-config-reference.md +93 -0
- package/skills/qingflow-cli/reference/builder/workflow/11-troubleshooting.md +15 -0
- package/skills/qingflow-cli/reference/builder/workflow/README.md +88 -0
- package/skills/qingflow-cli/reference/builder/workflow/workflow-schema.json +1754 -0
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_ADMIN_CHEATSHEET.md → core/QINGFLOW_CLI_ADMIN_CHEATSHEET.md} +3 -3
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md → core/QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md} +6 -6
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_EXPLORATION_REPORT.md → core/QINGFLOW_CLI_EXPLORATION_REPORT.md} +2 -2
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_FIELD_DATA_TYPES.md → core/QINGFLOW_CLI_FIELD_DATA_TYPES.md} +11 -11
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_MEMBER_CHEATSHEET.md → core/QINGFLOW_CLI_MEMBER_CHEATSHEET.md} +4 -4
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_ONE_SHOT_CHEATSHEET.md → core/QINGFLOW_CLI_ONE_SHOT_CHEATSHEET.md} +4 -4
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_RECORD_CREATE_WORKFLOW.md → record/QINGFLOW_CLI_RECORD_CREATE_WORKFLOW.md} +3 -3
- package/skills/qingflow-cli/reference/record/QINGFLOW_CLI_RECORD_DELETE_WORKFLOW.md +31 -0
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_RECORD_IMPORT_WORKFLOW.md → record/QINGFLOW_CLI_RECORD_IMPORT_WORKFLOW.md} +4 -4
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_RECORD_UPDATE_WORKFLOW.md → record/QINGFLOW_CLI_RECORD_UPDATE_WORKFLOW.md} +7 -7
- package/skills/qingflow-cli/reference/record/analysis/README.md +130 -0
- package/skills/qingflow-cli/reference/record/analysis/analysis-gotchas.md +91 -0
- package/skills/qingflow-cli/reference/record/analysis/analysis-patterns.md +112 -0
- package/skills/qingflow-cli/reference/record/analysis/business-context.md +74 -0
- package/skills/qingflow-cli/reference/record/analysis/confidence-reporting.md +69 -0
- package/skills/qingflow-cli/reference/record/analysis/data-access-playbook.md +106 -0
- package/skills/qingflow-cli/reference/record/analysis/pandas-recipes.md +172 -0
- package/skills/qingflow-cli/reference/record/analysis/report-format.md +76 -0
- package/skills/qingflow-cli/reference/record/insert/README.md +75 -0
- package/skills/qingflow-cli/reference/{QINGFLOW_CLI_TASK_CONTEXT_WORKFLOW.md → task/QINGFLOW_CLI_TASK_CONTEXT_WORKFLOW.md} +5 -5
- package/skills/qingflow-cli/reference/task/ops/README.md +131 -0
- package/skills/qingflow-cli/reference/task/ops/environments.md +43 -0
- package/skills/qingflow-cli/reference/task/ops/workflow-usage.md +26 -0
- package/skills/qingflow-cli/scripts/validate_system_build_summary.py +124 -0
- package/skills/qingflow-cli/scripts/workflow/diff_flow_spec.py +275 -0
- package/skills/qingflow-cli/scripts/workflow/validate_flow_spec.py +605 -0
- package/skills/qingflow-mcp-setup/SKILL.md +115 -0
- package/skills/qingflow-mcp-setup/agents/openai.yaml +4 -0
- package/skills/qingflow-mcp-setup/references/claude-desktop.md +34 -0
- package/skills/qingflow-mcp-setup/references/environments.md +62 -0
- package/skills/qingflow-mcp-setup/references/generic-stdio.md +32 -0
- package/skills/qingflow-mcp-setup/scripts/check_local_server.sh +38 -0
- package/src/qingflow_mcp/__init__.py +1 -1
- package/src/qingflow_mcp/__main__.py +6 -2
- package/src/qingflow_mcp/builder_facade/models.py +287 -25
- package/src/qingflow_mcp/builder_facade/service.py +4195 -856
- package/src/qingflow_mcp/cli/commands/builder.py +316 -247
- package/src/qingflow_mcp/cli/commands/chart.py +1 -1
- package/src/qingflow_mcp/cli/commands/common.py +12 -3
- package/src/qingflow_mcp/cli/commands/exports.py +2 -2
- package/src/qingflow_mcp/cli/commands/imports.py +3 -3
- package/src/qingflow_mcp/cli/commands/portal.py +2 -2
- package/src/qingflow_mcp/cli/commands/record.py +101 -27
- package/src/qingflow_mcp/cli/commands/task.py +28 -47
- package/src/qingflow_mcp/cli/commands/view.py +1 -1
- package/src/qingflow_mcp/cli/context.py +0 -3
- package/src/qingflow_mcp/cli/formatters.py +784 -16
- package/src/qingflow_mcp/cli/main.py +117 -33
- package/src/qingflow_mcp/errors.py +43 -2
- package/src/qingflow_mcp/public_surface.py +26 -17
- package/src/qingflow_mcp/response_trim.py +81 -17
- package/src/qingflow_mcp/server.py +14 -12
- package/src/qingflow_mcp/server_app_builder.py +65 -21
- package/src/qingflow_mcp/server_app_user.py +22 -16
- package/src/qingflow_mcp/session_store.py +11 -7
- package/src/qingflow_mcp/solution/compiler/__init__.py +3 -1
- package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +173 -0
- package/src/qingflow_mcp/solution/executor.py +245 -18
- package/src/qingflow_mcp/tools/ai_builder_tools.py +1782 -399
- package/src/qingflow_mcp/tools/app_tools.py +184 -43
- package/src/qingflow_mcp/tools/approval_tools.py +197 -35
- package/src/qingflow_mcp/tools/auth_tools.py +92 -16
- package/src/qingflow_mcp/tools/code_block_tools.py +298 -40
- package/src/qingflow_mcp/tools/custom_button_tools.py +64 -10
- package/src/qingflow_mcp/tools/directory_tools.py +236 -72
- package/src/qingflow_mcp/tools/export_tools.py +244 -34
- package/src/qingflow_mcp/tools/feedback_tools.py +9 -0
- package/src/qingflow_mcp/tools/file_tools.py +9 -3
- package/src/qingflow_mcp/tools/import_tools.py +336 -49
- package/src/qingflow_mcp/tools/navigation_tools.py +91 -12
- package/src/qingflow_mcp/tools/package_tools.py +118 -6
- package/src/qingflow_mcp/tools/portal_tools.py +39 -3
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +116 -7
- package/src/qingflow_mcp/tools/record_tools.py +1141 -356
- package/src/qingflow_mcp/tools/resource_read_tools.py +188 -39
- package/src/qingflow_mcp/tools/role_tools.py +80 -9
- package/src/qingflow_mcp/tools/solution_tools.py +59 -45
- package/src/qingflow_mcp/tools/task_context_tools.py +662 -158
- package/src/qingflow_mcp/tools/task_tools.py +113 -29
- package/src/qingflow_mcp/tools/view_tools.py +106 -3
- package/src/qingflow_mcp/tools/workflow_tools.py +48 -4
- package/src/qingflow_mcp/tools/workspace_tools.py +71 -3
- /package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_MATCH_RULES.md → builder/reference/match-rules.md} +0 -0
- /package/skills/qingflow-cli/reference/{QINGFLOW_CLI_BUILDER_WORKSPACE_ICONS.md → builder/reference/workspace-icons.md} +0 -0
- /package/skills/qingflow-cli/reference/{charts_remove.example.json → examples/charts/charts_remove.example.json} +0 -0
- /package/skills/qingflow-cli/reference/{charts_reorder.example.json → examples/charts/charts_reorder.example.json} +0 -0
- /package/skills/qingflow-cli/reference/{charts_upsert_bar.example.json → examples/charts/charts_upsert_bar.example.json} +0 -0
- /package/skills/qingflow-cli/reference/{charts_upsert_dashboard_starter.example.json → examples/charts/charts_upsert_dashboard_starter.example.json} +0 -0
- /package/skills/qingflow-cli/reference/{charts_upsert_minimal.example.json → examples/charts/charts_upsert_minimal.example.json} +0 -0
- /package/skills/qingflow-cli/reference/{portal_sections_all_types.example.json → examples/portal/portal_sections_all_types.example.json} +0 -0
- /package/skills/qingflow-cli/reference/{portal_sections_five_types.example.json → examples/portal/portal_sections_five_types.example.json} +0 -0
- /package/skills/qingflow-cli/reference/{portal_sections_standard_workbench.example.json → examples/portal/portal_sections_standard_workbench.example.json} +0 -0
- /package/skills/qingflow-cli/reference/{_batch_schema_complex.json → examples/schema/_batch_schema_complex.json} +0 -0
- /package/skills/qingflow-cli/reference/{_batch_schema_scalar.json → examples/schema/_batch_schema_scalar.json} +0 -0
- /package/skills/qingflow-cli/reference/{schema_add_fields_minimal.example.json → examples/schema/schema_add_fields_minimal.example.json} +0 -0
- /package/skills/qingflow-cli/reference/{schema_apply_add_fields_all_types.json → examples/schema/schema_apply_add_fields_all_types.json} +0 -0
- /package/skills/qingflow-cli/reference/{views_upsert_table_minimal.example.json → examples/views/views_upsert_table_minimal.example.json} +0 -0
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
Install:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install @josephyan/qingflow-cli@1.1.
|
|
6
|
+
npm install @josephyan/qingflow-cli@1.1.5
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
Run:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx -y -p @josephyan/qingflow-cli@1.1.
|
|
12
|
+
npx -y -p @josephyan/qingflow-cli@1.1.5 qingflow
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Environment:
|
|
@@ -23,9 +23,13 @@ This package bootstraps a local Python runtime on first install and then starts
|
|
|
23
23
|
Bundled skills:
|
|
24
24
|
|
|
25
25
|
- `skills/qingflow-cli`
|
|
26
|
+
- `skills/qingflow-mcp-setup`
|
|
26
27
|
|
|
27
28
|
Note:
|
|
28
29
|
|
|
29
30
|
- The skill files are included in the npm package.
|
|
30
|
-
-
|
|
31
|
+
- Installing the npm package does not overwrite agent skills automatically.
|
|
32
|
+
- To mount bundled skills from an installed package, run `qingflow-skills install --agent codex --scope user`.
|
|
33
|
+
- For one-shot `npx -p` installs, prefer `--copy` because symlinks would point into the npm execution cache.
|
|
34
|
+
- Use `qingflow-skills list` to inspect bundled skills. The installer defaults to symlinks for stable package installs and refuses to overwrite existing skills unless `--force` is provided.
|
|
31
35
|
- If a stdio MCP client reports `Transport closed`, delete `.npm-python`, reinstall the package, and make sure CLI/user/builder packages are on the same version. The stdio entrypoints refuse runtime bootstrap so install logs never corrupt MCP stdout.
|
|
@@ -101,7 +101,51 @@ npm install /absolute/path/to/dist/npm/qingflow-tech-qingflow-app-builder-mcp-<v
|
|
|
101
101
|
1. 创建 `.npm-python/`
|
|
102
102
|
2. 在其中建立 Python 虚拟环境
|
|
103
103
|
3. 执行 `pip install .`
|
|
104
|
-
4.
|
|
104
|
+
4. 在安装位置暴露对应入口:CLI 包暴露 `qingflow` / `qingflow-skills`;app-user 包暴露 `qingflow-app-user-mcp` / `qingflow-app-user-mcp-skills`;app-builder 包暴露 `qingflow-app-builder-mcp` / `qingflow-app-builder-mcp-skills`
|
|
105
|
+
5. 携带 `skills/<skill-name>/SKILL.md`,但不在 `postinstall` 阶段自动覆盖本机 agent skills
|
|
106
|
+
|
|
107
|
+
## Skills 挂载
|
|
108
|
+
|
|
109
|
+
显式查看包内 skills:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
qingflow-skills list
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
独立 MCP split 包使用包专属 skills 命令,避免全局安装多个包时发生 bin 覆盖:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
qingflow-app-user-mcp-skills list
|
|
119
|
+
qingflow-app-builder-mcp-skills list
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
显式挂载到 Codex 用户目录:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
qingflow-skills install --agent codex --scope user
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
如果通过一次性 `npx -p <package>` 执行安装,请加 `--copy`,避免 symlink 指向 npm 临时执行缓存:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx -y -p @qingflow-tech/qingflow-cli qingflow-skills install --agent codex --scope user --copy
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
也可以挂载到项目级 agent 目录:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
qingflow-skills install --agent claude-code --scope project
|
|
138
|
+
qingflow-skills install --agent cursor --scope project --copy
|
|
139
|
+
qingflow-skills install --agent all --scope project
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
默认行为:
|
|
143
|
+
|
|
144
|
+
- `--mode symlink`:使用 symlink,让 npm 包版本成为单一来源
|
|
145
|
+
- `--scope user`:安装到用户级 agent skills 目录
|
|
146
|
+
- `--agent codex`:目标 agent 为 Codex
|
|
147
|
+
- 不覆盖已有同名 skill;需要替换时显式加 `--force`
|
|
148
|
+
- 每次安装会在目标 skills 目录下写入 `.qingflow-skill-sources/<skill>.json`,记录 package、version、source、destination、agent、scope、mode
|
|
105
149
|
|
|
106
150
|
## 本地验证
|
|
107
151
|
|
|
@@ -110,24 +154,31 @@ npm install /absolute/path/to/dist/npm/qingflow-tech-qingflow-app-builder-mcp-<v
|
|
|
110
154
|
```bash
|
|
111
155
|
cd qingflow-support/mcp-server
|
|
112
156
|
node ./npm/bin/qingflow.mjs --help
|
|
157
|
+
node ./npm/bin/qingflow-skills.mjs list
|
|
113
158
|
node ./npm/bin/qingflow-app-user-mcp.mjs
|
|
114
159
|
node ./npm/bin/qingflow-app-builder-mcp.mjs
|
|
115
160
|
```
|
|
116
161
|
|
|
117
|
-
|
|
162
|
+
如果你是全局安装对应包:
|
|
118
163
|
|
|
119
164
|
```bash
|
|
120
165
|
qingflow --help
|
|
166
|
+
qingflow-skills list
|
|
121
167
|
qingflow-app-user-mcp
|
|
168
|
+
qingflow-app-user-mcp-skills list
|
|
122
169
|
qingflow-app-builder-mcp
|
|
170
|
+
qingflow-app-builder-mcp-skills list
|
|
123
171
|
```
|
|
124
172
|
|
|
125
|
-
如果你是把包安装到了某个本地 agent workspace
|
|
173
|
+
如果你是把包安装到了某个本地 agent workspace,安装对应包后命令通常位于:
|
|
126
174
|
|
|
127
175
|
```bash
|
|
128
176
|
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow
|
|
177
|
+
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow-skills
|
|
129
178
|
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow-app-user-mcp
|
|
179
|
+
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow-app-user-mcp-skills
|
|
130
180
|
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow-app-builder-mcp
|
|
181
|
+
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow-app-builder-mcp-skills
|
|
131
182
|
```
|
|
132
183
|
|
|
133
184
|
如果你是从 tgz 安装到某个空目录,命令通常位于:
|
|
@@ -217,7 +268,7 @@ qingflow-app-builder-mcp
|
|
|
217
268
|
"command": "npx",
|
|
218
269
|
"args": [
|
|
219
270
|
"-y",
|
|
220
|
-
"@
|
|
271
|
+
"@qingflow-tech/qingflow-app-user-mcp"
|
|
221
272
|
],
|
|
222
273
|
"env": {
|
|
223
274
|
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
|
|
@@ -230,7 +281,7 @@ qingflow-app-builder-mcp
|
|
|
230
281
|
"command": "npx",
|
|
231
282
|
"args": [
|
|
232
283
|
"-y",
|
|
233
|
-
"@
|
|
284
|
+
"@qingflow-tech/qingflow-app-builder-mcp"
|
|
234
285
|
],
|
|
235
286
|
"env": {
|
|
236
287
|
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
|
|
@@ -272,7 +323,7 @@ npm install
|
|
|
272
323
|
|
|
273
324
|
如果 MCP 客户端一调用工具就报 `Transport closed`,优先检查这几件事:
|
|
274
325
|
|
|
275
|
-
1. 不要混用不同版本的 `@
|
|
326
|
+
1. 不要混用不同版本的 `@qingflow-tech/qingflow-cli`、`@qingflow-tech/qingflow-app-user-mcp`、`@qingflow-tech/qingflow-app-builder-mcp`
|
|
276
327
|
2. 删除安装目录下的 `.npm-python`
|
|
277
328
|
3. 重新执行 `npm install` 或重新安装对应 tgz/npm 包
|
|
278
329
|
4. 再启动 MCP 客户端
|
package/entry_point.py
CHANGED
|
@@ -7,7 +7,7 @@ src_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "src"))
|
|
|
7
7
|
if src_path not in sys.path:
|
|
8
8
|
sys.path.insert(0, src_path)
|
|
9
9
|
|
|
10
|
-
from qingflow_mcp.
|
|
10
|
+
from qingflow_mcp.server_app_user import main
|
|
11
11
|
|
|
12
12
|
if __name__ == "__main__":
|
|
13
13
|
main()
|
package/npm/bin/qingflow.mjs
CHANGED
|
@@ -1,39 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
2
|
+
import { spawnServer, getPackageRoot, runSkillsCli } from "../lib/runtime.mjs";
|
|
5
3
|
|
|
6
|
-
const PKG_BY_BIN = {
|
|
7
|
-
qingflow: "qingflow-cli",
|
|
8
|
-
"qingflow-app-user-mcp": "qingflow-app-user-mcp",
|
|
9
|
-
"qingflow-app-builder-mcp": "qingflow-app-builder-mcp",
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
function resolvePackageModule(metaUrl, ...segments) {
|
|
13
|
-
const scriptPath = fileURLToPath(metaUrl);
|
|
14
|
-
const scriptDir = path.dirname(scriptPath);
|
|
15
|
-
// bin files live in <pkg>/npm/bin/, runtime.mjs lives in the sibling <pkg>/npm/lib/,
|
|
16
|
-
// so step up one level before joining the requested segments.
|
|
17
|
-
const direct = path.join(scriptDir, "..", ...segments);
|
|
18
|
-
if (fs.existsSync(direct)) {
|
|
19
|
-
return pathToFileURL(direct).href;
|
|
20
|
-
}
|
|
21
|
-
if (path.basename(scriptDir) === ".bin") {
|
|
22
|
-
const binName = path.basename(scriptPath);
|
|
23
|
-
const pkgName = PKG_BY_BIN[binName];
|
|
24
|
-
if (!pkgName) {
|
|
25
|
-
throw new Error(`Unknown qingflow command: ${binName}`);
|
|
26
|
-
}
|
|
27
|
-
const scope = process.env.QINGFLOW_NPM_SCOPE || "@josephyan";
|
|
28
|
-
const fromBin = path.join(scriptDir, "..", scope, pkgName, "npm", ...segments);
|
|
29
|
-
if (fs.existsSync(fromBin)) {
|
|
30
|
-
return pathToFileURL(fromBin).href;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
throw new Error(`Cannot locate ${segments.join("/")} from ${scriptPath}`);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const { getPackageRoot, spawnServer, runSkillsCli } = await import(resolvePackageModule(import.meta.url, "lib", "runtime.mjs"));
|
|
37
4
|
const packageRoot = getPackageRoot(import.meta.url);
|
|
38
5
|
const args = process.argv.slice(2);
|
|
39
6
|
if (args[0] === "skills") {
|
package/npm/lib/runtime.mjs
CHANGED
|
@@ -5,12 +5,6 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
|
|
6
6
|
const WINDOWS = process.platform === "win32";
|
|
7
7
|
|
|
8
|
-
const PKG_BY_BIN = {
|
|
9
|
-
qingflow: "qingflow-cli",
|
|
10
|
-
"qingflow-app-user-mcp": "qingflow-app-user-mcp",
|
|
11
|
-
"qingflow-app-builder-mcp": "qingflow-app-builder-mcp",
|
|
12
|
-
};
|
|
13
|
-
|
|
14
8
|
function runChecked(command, args, options = {}) {
|
|
15
9
|
const result = spawnSync(command, args, {
|
|
16
10
|
encoding: "utf8",
|
|
@@ -34,18 +28,7 @@ function commandWorks(command, args) {
|
|
|
34
28
|
}
|
|
35
29
|
|
|
36
30
|
export function getPackageRoot(metaUrl) {
|
|
37
|
-
|
|
38
|
-
const scriptDir = path.dirname(scriptPath);
|
|
39
|
-
if (path.basename(scriptDir) === ".bin") {
|
|
40
|
-
const binName = path.basename(scriptPath);
|
|
41
|
-
const pkgName = PKG_BY_BIN[binName];
|
|
42
|
-
if (!pkgName) {
|
|
43
|
-
throw new Error(`Unknown qingflow command: ${binName}`);
|
|
44
|
-
}
|
|
45
|
-
const scope = process.env.QINGFLOW_NPM_SCOPE || "@josephyan";
|
|
46
|
-
return path.join(scriptDir, "..", scope, pkgName);
|
|
47
|
-
}
|
|
48
|
-
return path.resolve(scriptDir, "..", "..");
|
|
31
|
+
return path.resolve(path.dirname(fileURLToPath(metaUrl)), "..", "..");
|
|
49
32
|
}
|
|
50
33
|
|
|
51
34
|
export function getCodexHome() {
|
|
@@ -154,43 +137,6 @@ function writeSkillProvenance(skillsDestRoot, skillName, payload) {
|
|
|
154
137
|
fs.writeFileSync(path.join(provenanceRoot, `${skillName}.json`), `${JSON.stringify(payload, null, 2)}\n`);
|
|
155
138
|
}
|
|
156
139
|
|
|
157
|
-
function sleepMs(ms) {
|
|
158
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function withSkillInstallLock(skillsDestRoot, callback) {
|
|
162
|
-
const lockDir = path.join(skillsDestRoot, ".qingflow-skill-install.lock");
|
|
163
|
-
const startedAt = Date.now();
|
|
164
|
-
while (true) {
|
|
165
|
-
try {
|
|
166
|
-
fs.mkdirSync(lockDir);
|
|
167
|
-
break;
|
|
168
|
-
} catch (error) {
|
|
169
|
-
if (error.code !== "EEXIST") {
|
|
170
|
-
throw error;
|
|
171
|
-
}
|
|
172
|
-
try {
|
|
173
|
-
const stat = fs.statSync(lockDir);
|
|
174
|
-
if (Date.now() - stat.mtimeMs > 300_000) {
|
|
175
|
-
fs.rmSync(lockDir, { recursive: true, force: true });
|
|
176
|
-
continue;
|
|
177
|
-
}
|
|
178
|
-
} catch {
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
if (Date.now() - startedAt > 30_000) {
|
|
182
|
-
throw new Error(`Timed out waiting for skill install lock: ${lockDir}`);
|
|
183
|
-
}
|
|
184
|
-
sleepMs(100);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
try {
|
|
188
|
-
return callback();
|
|
189
|
-
} finally {
|
|
190
|
-
fs.rmSync(lockDir, { recursive: true, force: true });
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
140
|
export function installBundledSkills(
|
|
195
141
|
packageRoot,
|
|
196
142
|
{
|
|
@@ -234,29 +180,27 @@ export function installBundledSkills(
|
|
|
234
180
|
mode,
|
|
235
181
|
};
|
|
236
182
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
});
|
|
255
|
-
}
|
|
183
|
+
for (const skillName of wanted) {
|
|
184
|
+
const src = path.join(skillsSrc, skillName);
|
|
185
|
+
const dest = path.join(skillsDestRoot, skillName);
|
|
186
|
+
const installResult = installOneSkill(src, dest, { force, mode });
|
|
187
|
+
result[installResult.status === "conflict" ? "conflicts" : installResult.status].push(skillName);
|
|
188
|
+
if (installResult.status !== "conflict") {
|
|
189
|
+
writeSkillProvenance(skillsDestRoot, skillName, {
|
|
190
|
+
package: packageJson.name ?? null,
|
|
191
|
+
version: packageJson.version ?? null,
|
|
192
|
+
skill: skillName,
|
|
193
|
+
source: src,
|
|
194
|
+
destination: dest,
|
|
195
|
+
agent,
|
|
196
|
+
scope,
|
|
197
|
+
mode,
|
|
198
|
+
installed_at: new Date().toISOString(),
|
|
199
|
+
});
|
|
256
200
|
}
|
|
201
|
+
}
|
|
257
202
|
|
|
258
|
-
|
|
259
|
-
});
|
|
203
|
+
return result;
|
|
260
204
|
}
|
|
261
205
|
|
|
262
206
|
function parseSkillsCliArgs(args) {
|
|
@@ -536,17 +480,6 @@ function getVenvPip(packageRoot) {
|
|
|
536
480
|
: path.join(getVenvDir(packageRoot), "bin", "pip");
|
|
537
481
|
}
|
|
538
482
|
|
|
539
|
-
function findOfflineProjectWheel(findLinksDir) {
|
|
540
|
-
const wheels = fs
|
|
541
|
-
.readdirSync(findLinksDir)
|
|
542
|
-
.filter((name) => /^qingflow_mcp-.*\.whl$/i.test(name))
|
|
543
|
-
.sort();
|
|
544
|
-
if (wheels.length === 0) {
|
|
545
|
-
throw new Error(`Offline install expected a qingflow_mcp wheel in ${findLinksDir}`);
|
|
546
|
-
}
|
|
547
|
-
return path.join(findLinksDir, wheels[wheels.length - 1]);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
483
|
export function findPython() {
|
|
551
484
|
const preferred = process.env.QINGFLOW_MCP_PYTHON?.trim();
|
|
552
485
|
const candidates = preferred
|
|
@@ -595,20 +528,7 @@ export function ensurePythonEnv(packageRoot, { force = false, commandName = "qin
|
|
|
595
528
|
}
|
|
596
529
|
|
|
597
530
|
const pip = getVenvPip(packageRoot);
|
|
598
|
-
|
|
599
|
-
const offlineFindLinks = process.env.QINGFLOW_MCP_PIP_FIND_LINKS?.trim();
|
|
600
|
-
if (process.env.QINGFLOW_MCP_PIP_NO_INDEX === "1") {
|
|
601
|
-
pipArgs.push("--no-index");
|
|
602
|
-
}
|
|
603
|
-
if (offlineFindLinks) {
|
|
604
|
-
pipArgs.push("--find-links", offlineFindLinks);
|
|
605
|
-
}
|
|
606
|
-
if (process.env.QINGFLOW_MCP_PIP_NO_INDEX === "1" && offlineFindLinks) {
|
|
607
|
-
pipArgs.push(findOfflineProjectWheel(offlineFindLinks));
|
|
608
|
-
} else {
|
|
609
|
-
pipArgs.push(".");
|
|
610
|
-
}
|
|
611
|
-
runChecked(pip, pipArgs, { cwd: packageRoot });
|
|
531
|
+
runChecked(pip, ["install", "--disable-pip-version-check", "."], { cwd: packageRoot });
|
|
612
532
|
|
|
613
533
|
fs.writeFileSync(
|
|
614
534
|
stampPath,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ensurePythonEnv, getPackageRoot
|
|
1
|
+
import { ensurePythonEnv, getPackageRoot } from "../lib/runtime.mjs";
|
|
2
2
|
|
|
3
3
|
const packageRoot = getPackageRoot(import.meta.url);
|
|
4
4
|
|
|
@@ -6,15 +6,6 @@ try {
|
|
|
6
6
|
console.log("[qingflow-mcp] Bootstrapping Python runtime...");
|
|
7
7
|
ensurePythonEnv(packageRoot, { commandName: "qingflow" });
|
|
8
8
|
console.log("[qingflow-mcp] Python runtime is ready.");
|
|
9
|
-
const skills = installBundledSkills(packageRoot, { force: true });
|
|
10
|
-
if (!skills.skipped) {
|
|
11
|
-
const changed = [
|
|
12
|
-
skills.installed.length ? `installed=${skills.installed.join(",")}` : "",
|
|
13
|
-
skills.unchanged.length ? `unchanged=${skills.unchanged.join(",")}` : "",
|
|
14
|
-
skills.conflicts.length ? `conflicts=${skills.conflicts.join(",")}` : "",
|
|
15
|
-
].filter(Boolean).join(" ");
|
|
16
|
-
console.log(`[qingflow-mcp] Installed skills to ${skills.destination}: ${changed || "none"}`);
|
|
17
|
-
}
|
|
18
9
|
} catch (error) {
|
|
19
10
|
console.error(`[qingflow-mcp] postinstall failed: ${error.message}`);
|
|
20
11
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@josephyan/qingflow-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "Human-friendly Qingflow command line interface for auth, record operations, import, tasks, and stable builder flows.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"qingflow": "./npm/bin/qingflow.mjs"
|
|
8
|
+
"qingflow": "./npm/bin/qingflow.mjs",
|
|
9
|
+
"qingflow-skills": "./npm/bin/qingflow-skills.mjs"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
11
12
|
"postinstall": "node ./npm/scripts/postinstall.mjs"
|