@josephyan/qingflow-app-builder-mcp 0.2.0-beta.7 → 0.2.0-beta.71

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 (70) hide show
  1. package/README.md +5 -3
  2. package/docs/local-agent-install.md +21 -5
  3. package/npm/bin/qingflow-app-builder-mcp.mjs +1 -1
  4. package/npm/lib/runtime.mjs +168 -12
  5. package/package.json +1 -1
  6. package/pyproject.toml +4 -1
  7. package/skills/qingflow-app-builder/SKILL.md +155 -22
  8. package/skills/qingflow-app-builder/references/create-app.md +51 -21
  9. package/skills/qingflow-app-builder/references/environments.md +1 -1
  10. package/skills/qingflow-app-builder/references/flow-actors-and-permissions.md +123 -0
  11. package/skills/qingflow-app-builder/references/gotchas.md +28 -1
  12. package/skills/qingflow-app-builder/references/solution-playbooks.md +14 -12
  13. package/skills/qingflow-app-builder/references/tool-selection.md +47 -19
  14. package/skills/qingflow-app-builder/references/update-flow.md +112 -25
  15. package/skills/qingflow-app-builder/references/update-layout.md +11 -24
  16. package/skills/qingflow-app-builder/references/update-schema.md +1 -23
  17. package/skills/qingflow-app-builder/references/update-views.md +87 -21
  18. package/skills/qingflow-app-builder-code-integrations/SKILL.md +137 -0
  19. package/skills/qingflow-app-builder-code-integrations/agents/openai.yaml +4 -0
  20. package/skills/qingflow-app-builder-code-integrations/references/code-block.md +66 -0
  21. package/skills/qingflow-app-builder-code-integrations/references/q-linker.md +77 -0
  22. package/src/qingflow_mcp/__init__.py +1 -1
  23. package/src/qingflow_mcp/backend_client.py +210 -0
  24. package/src/qingflow_mcp/builder_facade/models.py +1252 -3
  25. package/src/qingflow_mcp/builder_facade/service.py +11367 -2389
  26. package/src/qingflow_mcp/cli/__init__.py +1 -0
  27. package/src/qingflow_mcp/cli/commands/__init__.py +15 -0
  28. package/src/qingflow_mcp/cli/commands/app.py +40 -0
  29. package/src/qingflow_mcp/cli/commands/auth.py +78 -0
  30. package/src/qingflow_mcp/cli/commands/builder.py +515 -0
  31. package/src/qingflow_mcp/cli/commands/common.py +62 -0
  32. package/src/qingflow_mcp/cli/commands/imports.py +96 -0
  33. package/src/qingflow_mcp/cli/commands/record.py +304 -0
  34. package/src/qingflow_mcp/cli/commands/task.py +89 -0
  35. package/src/qingflow_mcp/cli/commands/workspace.py +33 -0
  36. package/src/qingflow_mcp/cli/context.py +48 -0
  37. package/src/qingflow_mcp/cli/formatters.py +355 -0
  38. package/src/qingflow_mcp/cli/json_io.py +50 -0
  39. package/src/qingflow_mcp/cli/main.py +149 -0
  40. package/src/qingflow_mcp/config.py +39 -0
  41. package/src/qingflow_mcp/import_store.py +121 -0
  42. package/src/qingflow_mcp/list_type_labels.py +24 -0
  43. package/src/qingflow_mcp/response_trim.py +668 -0
  44. package/src/qingflow_mcp/server.py +160 -18
  45. package/src/qingflow_mcp/server_app_builder.py +275 -68
  46. package/src/qingflow_mcp/server_app_user.py +219 -191
  47. package/src/qingflow_mcp/session_store.py +41 -1
  48. package/src/qingflow_mcp/solution/compiler/form_compiler.py +43 -4
  49. package/src/qingflow_mcp/solution/compiler/icon_utils.py +119 -45
  50. package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +41 -2
  51. package/src/qingflow_mcp/solution/executor.py +107 -11
  52. package/src/qingflow_mcp/solution/spec_models.py +2 -0
  53. package/src/qingflow_mcp/tools/ai_builder_tools.py +2032 -127
  54. package/src/qingflow_mcp/tools/app_tools.py +419 -12
  55. package/src/qingflow_mcp/tools/approval_tools.py +571 -72
  56. package/src/qingflow_mcp/tools/auth_tools.py +398 -2
  57. package/src/qingflow_mcp/tools/code_block_tools.py +756 -0
  58. package/src/qingflow_mcp/tools/custom_button_tools.py +179 -0
  59. package/src/qingflow_mcp/tools/directory_tools.py +203 -31
  60. package/src/qingflow_mcp/tools/feedback_tools.py +230 -0
  61. package/src/qingflow_mcp/tools/file_tools.py +1 -0
  62. package/src/qingflow_mcp/tools/import_tools.py +2150 -0
  63. package/src/qingflow_mcp/tools/package_tools.py +18 -4
  64. package/src/qingflow_mcp/tools/portal_tools.py +31 -0
  65. package/src/qingflow_mcp/tools/qingbi_report_tools.py +109 -7
  66. package/src/qingflow_mcp/tools/record_tools.py +9894 -1104
  67. package/src/qingflow_mcp/tools/solution_tools.py +115 -3
  68. package/src/qingflow_mcp/tools/task_context_tools.py +2040 -0
  69. package/src/qingflow_mcp/tools/task_tools.py +376 -225
  70. package/src/qingflow_mcp/tools/workspace_tools.py +163 -19
@@ -6,34 +6,12 @@ Use this when fields already exist and the task is only about form grouping or o
6
6
 
7
7
  1. `app_read_fields`
8
8
  2. `app_read_layout_summary`
9
- 3. `app_layout_plan`
9
+ 3. `builder_tool_contract` when the section shape is not already obvious
10
10
  4. `app_layout_apply`
11
11
 
12
12
  ## Example
13
13
 
14
- Plan a balanced merge layout:
15
-
16
- ```json
17
- {
18
- "tool_name": "app_layout_plan",
19
- "arguments": {
20
- "profile": "default",
21
- "app_key": "APP_123",
22
- "mode": "merge",
23
- "sections": [
24
- {
25
- "title": "基础信息",
26
- "rows": [
27
- ["客户名称", "订单金额"],
28
- ["状态", "跟进日期"]
29
- ]
30
- }
31
- ]
32
- }
33
- }
34
- ```
35
-
36
- Apply the layout. This publishes by default:
14
+ Apply a custom layout with the canonical public section shape:
37
15
 
38
16
  ```json
39
17
  {
@@ -74,8 +52,17 @@ Only happens in `mode=replace`. Switch to `mode=merge` unless you intend to plac
74
52
 
75
53
  Re-read with `app_read_layout_summary`. Check `current_field_names`, `request_id`, and `suggested_next_call`.
76
54
 
55
+ ### `VALIDATION_ERROR`
56
+
57
+ Do not keep guessing section keys. Reuse `suggested_next_call`, `canonical_arguments`, `section_allowed_keys`, and `minimal_section_example`.
58
+
59
+ If the same shape error repeats twice, stop free-form retries and re-read `builder_tool_contract(app_layout_apply)`.
60
+
77
61
  ## Notes
78
62
 
79
63
  - `section_id` is optional; it is generated from the section title
80
64
  - `merge` is safer than `replace`
81
65
  - Unmentioned fields stay in place or get auto-added to `未分组字段`
66
+ - Public builder layout sections use `title + rows`
67
+ - Do not treat “一行四个字段 / 四列布局 / 每行放四个” as a top-level `columns` parameter; translate it into a `rows` matrix
68
+ - Do not prefer `fields` or `field_ids` once `rows` is known, even though MCP may normalize those shorthands for recovery
@@ -6,8 +6,7 @@ Use this when the app already exists and the task is only about fields.
6
6
 
7
7
  1. `app_resolve`
8
8
  2. `app_read_fields`
9
- 3. `app_schema_plan`
10
- 4. `app_schema_apply`
9
+ 3. `app_schema_apply`
11
10
 
12
11
  ## Example
13
12
 
@@ -23,27 +22,6 @@ Read current fields first:
23
22
  }
24
23
  ```
25
24
 
26
- Plan the patch:
27
-
28
- ```json
29
- {
30
- "tool_name": "app_schema_plan",
31
- "arguments": {
32
- "profile": "default",
33
- "app_key": "APP_123",
34
- "add_fields": [
35
- {"name": "跟进日期", "type": "date"}
36
- ],
37
- "update_fields": [
38
- {"selector": {"name": "金额"}, "set": {"name": "订单金额", "required": true}}
39
- ],
40
- "remove_fields": [
41
- {"name": "旧字段"}
42
- ]
43
- }
44
- }
45
- ```
46
-
47
25
  Apply the patch:
48
26
 
49
27
  ```json
@@ -1,27 +1,47 @@
1
1
  # Update Views
2
2
 
3
- Use this when the task is only about list, card, or board views.
3
+ Use this when the task is only about table, card, board, or gantt views.
4
4
 
5
5
  ## Minimal sequence
6
6
 
7
- 1. `app_read_fields`
8
- 2. `app_read_views_summary`
9
- 3. `app_views_plan`
7
+ 1. `builder_tool_contract(tool_name="app_views_apply")`
8
+ 2. `app_read_fields`
9
+ 3. `app_read_views_summary`
10
10
  4. `app_views_apply`
11
+ 5. `app_read_views_summary` again whenever apply returns `failed` or `partial_success`
12
+
13
+ If you are unsure about keys or view types, call `builder_tool_contract(tool_name="app_views_apply")` before guessing.
14
+
15
+ Important verification rule:
16
+
17
+ - `app_views_apply` can create a view object before every filter is fully verified in readback
18
+ - Do not report “筛选已成功应用” unless the apply result also shows `verification.views_verified=true`
19
+ - If apply returns `partial_success`, inspect `verification.by_view` and `details.filter_mismatches` before claiming the filters are active
11
20
 
12
21
  ## Example
13
22
 
14
- Plan a default table view:
23
+ Canonical rules before any example:
24
+
25
+ - Always use `columns`
26
+ - Do not emit `column_names`
27
+ - Treat `fields` only as a legacy alias the MCP may normalize, not as the preferred shape
28
+ - Use `filters` with canonical keys `field_name`, `operator`, `value`/`values`
29
+ - For gantt, use `start_field`, `end_field`, and optionally `title_field`
30
+ - If `app_read_views_summary` shows duplicate view names, include `view_key` in `upsert_views[]` and update that exact target
31
+
32
+ Apply a default table view:
15
33
 
16
34
  ```json
17
35
  {
18
- "tool_name": "app_views_plan",
36
+ "tool_name": "app_views_apply",
19
37
  "arguments": {
20
38
  "profile": "default",
21
39
  "app_key": "APP_123",
40
+ "publish": true,
22
41
  "upsert_views": [
23
42
  {
24
43
  "name": "全部订单",
44
+ "view_key": "VIEW_KEY_IF_DUPLICATE_NAMES_EXIST",
25
45
  "type": "table",
26
46
  "columns": ["订单编号", "客户名称", "订单金额", "状态"]
27
47
  }
@@ -30,8 +50,9 @@ Plan a default table view:
30
50
  }
31
51
  }
32
52
  ```
53
+ After `app_views_apply` returns canonical arguments or blocking issues, prefer reusing its `suggested_next_call.arguments` directly. Do not rewrite aliases back into non-canonical keys such as `column_names`.
33
54
 
34
- Apply it:
55
+ Board example:
35
56
 
36
57
  ```json
37
58
  {
@@ -39,12 +60,12 @@ Apply it:
39
60
  "arguments": {
40
61
  "profile": "default",
41
62
  "app_key": "APP_123",
42
- "publish": true,
43
63
  "upsert_views": [
44
64
  {
45
- "name": "全部订单",
46
- "type": "table",
47
- "columns": ["订单编号", "客户名称", "订单金额", "状态"]
65
+ "name": "按状态看板",
66
+ "type": "board",
67
+ "group_by": "状态",
68
+ "columns": ["订单编号", "客户名称", "订单金额"]
48
69
  }
49
70
  ],
50
71
  "remove_views": []
@@ -52,7 +73,7 @@ Apply it:
52
73
  }
53
74
  ```
54
75
 
55
- Board example:
76
+ Gantt example with filters:
56
77
 
57
78
  ```json
58
79
  {
@@ -62,10 +83,19 @@ Board example:
62
83
  "app_key": "APP_123",
63
84
  "upsert_views": [
64
85
  {
65
- "name": "按状态看板",
66
- "type": "board",
67
- "group_by": "状态",
68
- "columns": ["订单编号", "客户名称", "订单金额"]
86
+ "name": "项目甘特图",
87
+ "type": "gantt",
88
+ "columns": ["项目名称", "开始日期", "结束日期", "状态"],
89
+ "start_field": "开始日期",
90
+ "end_field": "结束日期",
91
+ "title_field": "项目名称",
92
+ "filters": [
93
+ {
94
+ "field_name": "状态",
95
+ "operator": "eq",
96
+ "value": "进行中"
97
+ }
98
+ ]
69
99
  }
70
100
  ],
71
101
  "remove_views": []
@@ -81,16 +111,52 @@ At least one `columns` or `group_by` field name does not exist.
81
111
 
82
112
  ### `INVALID_VIEW_TYPE`
83
113
 
84
- Public view types are only `table`, `card`, `board`.
114
+ Public view types are only `table`, `card`, `board`, `gantt`.
115
+
116
+ Map old or intuitive labels before calling the tool:
117
+
118
+ - `tableView` -> `table`
119
+ - `cardView` -> `card`
120
+ - `kanban` -> `board`
121
+
122
+ ### `INVALID_GANTT_CONFIG`
123
+
124
+ Gantt views require at least:
125
+
126
+ - `start_field`
127
+ - `end_field`
128
+
129
+ Also make sure these field names already exist on the app.
85
130
 
86
131
  ### `VIEW_APPLY_FAILED`
87
132
 
88
133
  The backend rejected the normalized view payload. Re-read fields and inspect `request_id` before retrying.
89
134
 
135
+ Do not repeat `app_views_apply` with guessed keys. First:
136
+
137
+ 1. check `suggested_next_call`
138
+ 2. reuse `canonical_arguments` if present
139
+ 3. call `app_read_views_summary` to see whether any requested views landed anyway
140
+ 4. if needed, call `builder_tool_contract`
141
+ 5. retry only the minimal failed view patch
142
+
143
+ ### `VIEW_FILTER_READBACK_MISMATCH`
144
+
145
+ The view object was created or updated, but the readback config did not keep the intended filter values.
146
+
147
+ Treat this as:
148
+
149
+ - the view exists
150
+ - the filter is **not yet verified**
151
+
152
+ Do not tell the user the filter is active until the readback verification matches the intended filter.
153
+
90
154
  ## Notes
91
155
 
92
- - `fields` is accepted as an alias for `columns`
93
- - `tableView -> table`
94
- - `cardView -> card`
95
- - `kanban -> board`
156
+ - `fields` is accepted as an alias for `columns`, but skill examples should still use `columns`
157
+ - `column_names` should not appear in skill examples
158
+ - `app_read_views_summary` should be treated as canonical readback and now returns `columns`
159
+ - If `app_views_apply` returns `AMBIGUOUS_VIEW`, stop and re-run `app_read_views_summary`; then retry with the exact `view_key`
160
+ - `filters` are ANDed together as one flat condition group
96
161
  - `app_views_apply` publishes by default
162
+ - For select-style filters, success means the backend preserved the option value in readback, not just that the view name now exists
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: qingflow-app-builder-code-integrations
3
+ description: Configure Qingflow code block and Q-Linker fields through the builder surface when the task involves input field insertion, alias parsing, target field binding, or troubleshooting broken code/q-linker form configurations. Use after MCP is connected and authenticated, especially for CRM-style scoring, lookup, and enrichment forms.
4
+ metadata:
5
+ short-description: Configure Qingflow code blocks and Q-Linkers safely
6
+ ---
7
+
8
+ # Qingflow App Builder Code Integrations
9
+
10
+ Use this skill when the user wants to build or repair:
11
+ - `code_block` fields
12
+ - `q_linker` fields
13
+ - output alias parsing
14
+ - target field binding
15
+ - form configurations that depend on code block or Q-Linker relations
16
+
17
+ Do not use this skill for MCP setup, generic field CRUD, or runtime execution debugging unless those are strictly supporting code block or Q-Linker configuration work.
18
+
19
+ ## Core Rule
20
+
21
+ Treat code blocks and Q-Linkers as **integration fields**, not ordinary fields.
22
+
23
+ For both of them, the public builder request may look like one step, but the real backend form structure has multiple layers. Never invent a new backend meaning. Only compile into the backend structures that already exist.
24
+
25
+ ## Mental Model
26
+
27
+ ### Code block
28
+
29
+ There are three conceptual layers:
30
+
31
+ 1. Code block field itself
32
+ 2. Parsed output aliases
33
+ 3. Target field bindings
34
+
35
+ Current builder support:
36
+ - configure the code block field itself
37
+ - configure input insertion into code content
38
+ - configure alias parsing
39
+
40
+ Important:
41
+ - keep `qf_output = {...}` as a plain assignment
42
+ - do not emit `const qf_output =` or `let qf_output =`
43
+
44
+ ### Q-Linker
45
+
46
+ There are two conceptual layers:
47
+
48
+ 1. Q-Linker field itself via `remoteLookupConfig`
49
+ 2. Target field bindings via relation-default + `questionRelations(relationType=Q_LINKER)`
50
+
51
+ Current builder support:
52
+ - one-step high-level config through `q_linker_binding`
53
+ - internal compilation into existing backend payloads
54
+
55
+ ## Operating Order
56
+
57
+ For code block or Q-Linker work, use this order:
58
+
59
+ 1. Resolve the app and read fields:
60
+ - `app_resolve`
61
+ - `app_read_fields`
62
+ 2. Confirm the target field set already exists.
63
+ 3. Apply schema updates with `app_schema_apply`.
64
+ 4. Read fields again and verify:
65
+ - field type
66
+ - alias config
67
+ - target field binding shape
68
+ 5. For page-safety checks, use user-side schema or insert checks:
69
+ - `record_insert_schema_get`
70
+ - optional safe `record_insert`
71
+
72
+ Do not treat raw apply success as enough. Always re-read the field config.
73
+
74
+ ## Code Block Rules
75
+
76
+ Read [references/code-block.md](references/code-block.md) before changing a code block field.
77
+
78
+ Use builder high-level config only for:
79
+ - input field insertion
80
+ - code content
81
+ - alias parsing
82
+ - auto trigger
83
+ - custom button text
84
+
85
+ When binding outputs to target fields, do not guess payload shape from memory. Follow the current builder implementation and the readback shape.
86
+
87
+ Hard rules:
88
+ - target fields must already exist
89
+ - keep target field types business-compatible
90
+ - if a page starts hanging on “关联中”, inspect whether the target field default type or relation config was written incorrectly
91
+
92
+ ## Q-Linker Rules
93
+
94
+ Read [references/q-linker.md](references/q-linker.md) before changing a Q-Linker field.
95
+
96
+ First-stage stable support is only:
97
+ - custom mode
98
+ - request config
99
+ - alias parsing
100
+ - target field binding
101
+ - auto trigger / button text
102
+
103
+ Do not generate:
104
+ - template mode
105
+ - openApp/light-wing branches
106
+ - subtable table-match bindings
107
+
108
+ Hard rules:
109
+ - `outputs[*].target_field` is required
110
+ - use only supported target field types
111
+ - on rebinding, old target fields must be restored from relation-default to safe default type
112
+ - `resultFormatPath` must preserve backend-required alias metadata
113
+
114
+ ## Verification Checklist
115
+
116
+ After each code block or Q-Linker change, verify all of these:
117
+
118
+ - `app_read_fields` shows the intended field type
119
+ - the high-level config is readable and stable
120
+ - target fields still have valid types
121
+ - insert schema can be opened
122
+ - record insert does not get blocked by malformed integration config
123
+
124
+ If the task explicitly includes runtime verification, keep it separate from configuration verification.
125
+
126
+ ## Common Pitfalls
127
+
128
+ - Writing code block code with `const qf_output =`
129
+ - Treating a Q-Linker or code block binding as a plain field default
130
+ - Forgetting to restore old target fields after unbinding
131
+ - Using unsupported target field types
132
+ - Assuming apply success means the form page can open
133
+
134
+ ## References
135
+
136
+ - Code block details: [references/code-block.md](references/code-block.md)
137
+ - Q-Linker details: [references/q-linker.md](references/q-linker.md)
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Qingflow Code Integrations"
3
+ short_description: "Configure Qingflow code block and Q-Linker fields safely"
4
+ default_prompt: "Use $qingflow-app-builder-code-integrations when configuring Qingflow code block or Q-Linker fields, especially when input insertion, alias parsing, target field binding, or page-safety verification matter."
@@ -0,0 +1,66 @@
1
+ # Code Block Builder Notes
2
+
3
+ ## What Builder Should Configure
4
+
5
+ - code block field type
6
+ - code content
7
+ - inserted input fields inside code content
8
+ - alias parsing
9
+ - auto trigger
10
+ - custom button text
11
+
12
+ ## Stable Writing Rules
13
+
14
+ - Always emit `qf_output = {...}`
15
+ - Never emit `const qf_output = {...}`
16
+ - Never emit `let qf_output = {...}`
17
+
18
+ ## Useful CRM Pattern
19
+
20
+ Inputs:
21
+ - customer name
22
+ - source
23
+ - budget
24
+ - timing
25
+ - decision-maker flag
26
+
27
+ Outputs:
28
+ - score
29
+ - level
30
+ - priority
31
+ - summary
32
+ - next follow date
33
+
34
+ ## Target Field Rules
35
+
36
+ Required:
37
+ - every `outputs[*].target_field` must point to an existing field
38
+
39
+ Allowed target field types:
40
+ - text
41
+ - long text
42
+ - number
43
+ - amount
44
+ - date
45
+ - datetime
46
+ - single select
47
+ - multi select
48
+ - boolean
49
+
50
+ Do not bind code block outputs to:
51
+ - q_linker
52
+ - code_block
53
+ - relation
54
+ - subtable
55
+ - attachment
56
+ - member
57
+ - department
58
+ - address
59
+
60
+ ## Safe Verification
61
+
62
+ - `app_read_fields`
63
+ - `record_insert_schema_get`
64
+ - optional `record_code_block_run`
65
+
66
+ Treat configuration verification and runtime verification as separate checks.
@@ -0,0 +1,77 @@
1
+ # Q-Linker Builder Notes
2
+
3
+ ## What Builder Should Configure
4
+
5
+ - `remoteLookupConfig`
6
+ - alias parsing
7
+ - target field binding
8
+ - auto trigger
9
+ - custom button text
10
+
11
+ ## Current Supported Scope
12
+
13
+ - custom mode only
14
+ - standard request fields
15
+ - alias path parsing
16
+ - target field binding to existing ordinary fields
17
+
18
+ ## Recommended Public APIs For Samples
19
+
20
+ ### Httpbin
21
+
22
+ - URL: `https://httpbin.org/get`
23
+ - Good for:
24
+ - query echo
25
+ - request URL echo
26
+
27
+ Useful paths:
28
+ - `$.args.keyword`
29
+ - `$.url`
30
+
31
+ ### Open-Meteo Geocoding
32
+
33
+ - URL: `https://geocoding-api.open-meteo.com/v1/search`
34
+ - Good for:
35
+ - place normalization
36
+ - country
37
+ - lat/lng summary
38
+
39
+ Useful paths:
40
+ - `$.results[0].name`
41
+ - `$.results[0].country`
42
+ - `$.results[0].latitude`
43
+ - `$.results[0].longitude`
44
+
45
+ ## Target Field Rules
46
+
47
+ Required:
48
+ - every `outputs[*].target_field` must point to an existing field
49
+
50
+ Prefer:
51
+ - text
52
+ - long text
53
+ - number
54
+ - amount
55
+ - date
56
+ - datetime
57
+ - single select
58
+ - multi select
59
+ - boolean
60
+
61
+ Avoid:
62
+ - q_linker
63
+ - code_block
64
+ - relation
65
+ - subtable
66
+ - attachment
67
+ - member
68
+ - department
69
+ - address
70
+
71
+ ## Safe Verification
72
+
73
+ - `app_read_fields`
74
+ - `record_insert_schema_get`
75
+ - `record_insert`
76
+
77
+ This verifies that the configuration does not break the form page, even before runtime execution is tested.
@@ -2,4 +2,4 @@ from __future__ import annotations
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.2.0b7"
5
+ __version__ = "0.2.0b48"