@shwfed/config 3.0.7 → 3.0.9
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/module.json +1 -1
- package/dist/runtime/components/actions/ai-l1.md +24 -0
- package/dist/runtime/components/actions/buttons/2026-04-18/com.shwfed.actions.button.prototype/schema.d.ts +1 -0
- package/dist/runtime/components/actions/buttons/2026-04-18/com.shwfed.actions.button.prototype/schema.js +2 -1
- package/dist/runtime/components/actions/buttons/2026-05-11/com.shwfed.actions.button.modal.layout/prompt.md +8 -0
- package/dist/runtime/components/actions/buttons/2026-05-11/com.shwfed.actions.button.modal.layout/schema.d.ts +6 -0
- package/dist/runtime/components/actions/buttons/2026-05-11/com.shwfed.actions.button.modal.layout/schema.js +4 -0
- package/dist/runtime/components/actions/buttons/2026-05-15/com.shwfed.actions.button.event.dispatch/prompt.md +8 -0
- package/dist/runtime/components/actions/buttons/2026-05-15/com.shwfed.actions.button.event.dispatch/schema.d.ts +1 -0
- package/dist/runtime/components/actions/buttons/2026-05-15/com.shwfed.actions.button.event.dispatch/schema.js +2 -1
- package/dist/runtime/components/actions/buttons/2026-06-08/com.shwfed.actions.button.http.request.json.batch/prompt.md +9 -0
- package/dist/runtime/components/actions/buttons/2026-06-08/com.shwfed.actions.button.http.request.json.batch/schema.d.ts +1 -0
- package/dist/runtime/components/actions/buttons/2026-06-08/com.shwfed.actions.button.http.request.json.batch/schema.js +2 -1
- package/dist/runtime/components/actions/buttons/2026-07-13/com.shwfed.actions.button.state.write/prompt.md +8 -0
- package/dist/runtime/components/actions/buttons/2026-07-13/com.shwfed.actions.button.state.write/schema.d.ts +1 -0
- package/dist/runtime/components/actions/buttons/2026-07-13/com.shwfed.actions.button.state.write/schema.js +2 -1
- package/dist/runtime/components/actions/items/2026-05-21/com.shwfed.actions.item.markdown/schema.d.ts +1 -0
- package/dist/runtime/components/actions/items/2026-05-21/com.shwfed.actions.item.markdown/schema.js +2 -1
- package/dist/runtime/components/actions/utils/ai-button-tools.d.ts +29 -0
- package/dist/runtime/components/actions/utils/ai-button-tools.js +664 -0
- package/dist/runtime/components/actions/utils/resolve.d.ts +22 -0
- package/dist/runtime/components/actions/utils/resolve.js +23 -1
- package/dist/runtime/components/config/ai-generate.d.vue.ts +7 -0
- package/dist/runtime/components/config/ai-generate.system.md +40 -0
- package/dist/runtime/components/{table → config}/ai-generate.vue +55 -32
- package/dist/runtime/components/config/ai-generate.vue.d.ts +7 -0
- package/dist/runtime/components/config/ai-page-slot.l1.md +25 -0
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.actions/schema.d.ts +6 -0
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.actions/schema.js +4 -0
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/schema.d.ts +6 -0
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/schema.js +4 -0
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.markdown/schema.d.ts +1 -0
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.markdown/schema.js +1 -0
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.d.vue.ts +58 -58
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.vue.d.ts +58 -58
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.d.vue.ts +58 -58
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.vue.d.ts +58 -58
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +35 -29
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.js +4 -0
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.tabs/schema.d.ts +7 -0
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.tabs/schema.js +4 -0
- package/dist/runtime/components/config/blocks/2026-05-17/com.shwfed.block.chart.xy/schema.d.ts +1 -0
- package/dist/runtime/components/config/blocks/2026-05-17/com.shwfed.block.chart.xy/schema.js +1 -0
- package/dist/runtime/components/config/blocks/2026-06-01/com.shwfed.block.animated.number/schema.d.ts +1 -0
- package/dist/runtime/components/config/blocks/2026-06-01/com.shwfed.block.animated.number/schema.js +1 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/schema.d.ts +6 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/schema.js +4 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.icon/schema.d.ts +1 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.icon/schema.js +1 -0
- package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/config.d.vue.ts +18 -18
- package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/config.vue.d.ts +18 -18
- package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/runtime.d.vue.ts +18 -18
- package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/runtime.vue.d.ts +18 -18
- package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/schema.d.ts +6 -0
- package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/schema.js +4 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/schema.d.ts +7 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/schema.js +4 -0
- package/dist/runtime/components/config/config.vue +24 -3
- package/dist/runtime/components/config/use-editor.d.ts +1 -0
- package/dist/runtime/components/config/use-editor.js +18 -0
- package/dist/runtime/components/config/utils/ai-cursor.d.ts +21 -0
- package/dist/runtime/components/config/utils/ai-cursor.js +833 -0
- package/dist/runtime/components/config/utils/ai-host-manuals.d.ts +2 -0
- package/dist/runtime/components/config/utils/ai-host-manuals.js +19 -0
- package/dist/runtime/components/config/utils/linkage.d.ts +15 -6
- package/dist/runtime/components/config/utils/linkage.js +23 -7
- package/dist/runtime/components/config/utils/resolve.d.ts +19 -0
- package/dist/runtime/components/config/utils/resolve.js +25 -2
- package/dist/runtime/components/form/ai-l1.md +22 -0
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.markdown/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.markdown/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.actions/schema.d.ts +7 -0
- package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.actions/schema.js +4 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.date/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.date/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.d.vue.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.vue.d.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetime/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetime/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.time/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.time/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.numberrange/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.numberrange/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.switch/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.switch/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/prompt.md +8 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.d.ts +7 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.js +4 -0
- package/dist/runtime/components/form/fields/2026-05-17/com.shwfed.form.field.checkbox.group/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-17/com.shwfed.form.field.checkbox.group/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-05-17/com.shwfed.form.field.radio.group/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-17/com.shwfed.form.field.radio.group/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/prompt.md +12 -0
- package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/schema.d.ts +6 -0
- package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/schema.js +4 -0
- package/dist/runtime/components/form/fields/2026-05-20/com.shwfed.form.field.collapsible/schema.d.ts +6 -0
- package/dist/runtime/components/form/fields/2026-05-20/com.shwfed.form.field.collapsible/schema.js +4 -0
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.month/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.month/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.d.vue.ts +6 -6
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.vue.d.ts +6 -6
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/prompt.md +7 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/prompt.md +7 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/prompt.md +9 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/prompt.md +11 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-06-09/com.shwfed.form.field.upload/prompt.md +12 -0
- package/dist/runtime/components/form/fields/2026-06-09/com.shwfed.form.field.upload/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-06-09/com.shwfed.form.field.upload/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/prompt.md +14 -0
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/prompt.md +19 -0
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/schema.js +1 -0
- package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/schema.d.ts +7 -0
- package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/schema.js +4 -0
- package/dist/runtime/components/form/fields/2026-07-13/com.shwfed.form.field.dynamic/prompt.md +14 -0
- package/dist/runtime/components/form/fields/2026-07-13/com.shwfed.form.field.dynamic/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-07-13/com.shwfed.form.field.dynamic/schema.js +1 -0
- package/dist/runtime/components/form/utils/ai-field-tools.d.ts +2 -2
- package/dist/runtime/components/form/utils/ai-field-tools.js +47 -30
- package/dist/runtime/components/form/utils/resolve.d.ts +11 -0
- package/dist/runtime/components/form/utils/resolve.js +13 -1
- package/dist/runtime/components/operations/2026-06-09/com.shwfed.operation.alert/schema.d.ts +1 -0
- package/dist/runtime/components/operations/2026-06-09/com.shwfed.operation.alert/schema.js +2 -1
- package/dist/runtime/components/operations/2026-06-11/com.shwfed.operation.http.request.json/schema.d.ts +1 -0
- package/dist/runtime/components/operations/2026-06-11/com.shwfed.operation.http.request.json/schema.js +1 -0
- package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/schema.d.ts +1 -0
- package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/schema.js +2 -1
- package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.navigation/schema.d.ts +1 -0
- package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.navigation/schema.js +2 -1
- package/dist/runtime/components/operations/2026-07-06/com.shwfed.operation.table.add-row/schema.d.ts +1 -0
- package/dist/runtime/components/operations/2026-07-06/com.shwfed.operation.table.add-row/schema.js +2 -1
- package/dist/runtime/components/operations/utils/resolve.d.ts +17 -0
- package/dist/runtime/components/operations/utils/resolve.js +18 -1
- package/dist/runtime/components/table/ai-l1.md +38 -0
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.actions/schema.d.ts +7 -0
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.actions/schema.js +5 -1
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.date/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.date/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.icon/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.icon/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.markdown/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.markdown/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.number/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.number/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.select/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.select/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.text/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.text/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-05-21/com.shwfed.table.column.drag-handle/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-05-21/com.shwfed.table.column.drag-handle/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +8 -8
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +8 -8
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +8 -8
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +8 -8
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/prompt.md +12 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/schema.js +1 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/prompt.md +16 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/schema.js +1 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.js +1 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +8 -8
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +8 -8
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.js +1 -0
- package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/schema.js +2 -1
- package/dist/runtime/components/table/columns/2026-07-12/com.shwfed.table.column.dynamic/prompt.md +15 -0
- package/dist/runtime/components/table/config.d.vue.ts +3 -3
- package/dist/runtime/components/table/config.vue +1 -33
- package/dist/runtime/components/table/config.vue.d.ts +3 -3
- package/dist/runtime/components/table/row-provider.vue +7 -1
- package/dist/runtime/components/table/schema.d.ts +58 -58
- package/dist/runtime/components/table/utils/ai-tools.js +16 -7
- package/dist/runtime/components/table/utils/resolve.d.ts +5 -0
- package/dist/runtime/components/table/utils/resolve.js +12 -1
- package/dist/runtime/components/tabs/index.vue +10 -2
- package/dist/runtime/components/ui/chat/ChatMessages.vue +30 -6
- package/dist/runtime/components/ui/date-picker/DatePickerInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-picker/DatePickerInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-picker/DatePickerTimeInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-picker/DatePickerTimeInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerTimeInput.d.vue.ts +2 -2
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerTimeInput.vue.d.ts +2 -2
- package/dist/runtime/share/define-registry.d.ts +66 -0
- package/dist/runtime/share/define-registry.js +37 -1
- package/dist/runtime/share/use-persisted-chat.d.ts +11 -9
- package/dist/runtime/share/use-persisted-chat.js +3 -3
- package/dist/runtime/utils/ai/index.d.ts +1 -1
- package/dist/runtime/utils/ai/index.js +18 -11
- package/dist/runtime/utils/cel-catalog.d.ts +1 -0
- package/dist/runtime/utils/cel-catalog.js +10 -0
- package/dist/runtime/utils/cel-catalog.md +42 -0
- package/dist/runtime/utils/cel-context.d.ts +15 -0
- package/dist/runtime/utils/cel-context.js +8 -0
- package/dist/runtime/utils/disabled-date.d.ts +8 -2
- package/dist/runtime/utils/disabled-date.js +2 -1
- package/package.json +1 -1
- package/dist/runtime/components/table/ai-generate.d.vue.ts +0 -16
- package/dist/runtime/components/table/ai-generate.system.md +0 -101
- package/dist/runtime/components/table/ai-generate.vue.d.ts +0 -16
- /package/dist/runtime/components/{table → config}/ai-generate.system.d.ts +0 -0
- /package/dist/runtime/components/{table → config}/ai-generate.system.js +0 -0
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
import { JSONSchema, ParseResult, Schema } from "effect";
|
|
2
|
+
import { coerceFromString } from "../../../share/coerce-from-string.js";
|
|
3
|
+
import { Area, findFreePlacement, normalizeLayoutSet } from "../../../share/layout.js";
|
|
4
|
+
import { activeBlocks, blockRef, findBlock } from "./resolve.js";
|
|
5
|
+
import { createTableAiTools } from "../../table/utils/ai-tools.js";
|
|
6
|
+
import { createFormFieldTools } from "../../form/utils/ai-field-tools.js";
|
|
7
|
+
import { createActionsAiTools } from "../../actions/utils/ai-button-tools.js";
|
|
8
|
+
import { findColumn } from "../../table/utils/resolve.js";
|
|
9
|
+
import { findField } from "../../form/utils/resolve.js";
|
|
10
|
+
import { findButton } from "../../actions/utils/resolve.js";
|
|
11
|
+
import { configureTableActionsScope, metadata as tableMetadata } from "../../table/schema.js";
|
|
12
|
+
import { registerRowVariablesIfAbsent } from "../../table/utils/shared.js";
|
|
13
|
+
import { metadata as formMetadata } from "../../form/schema.js";
|
|
14
|
+
import { registerFormVariablesIfAbsent } from "../../form/utils/form-vars.js";
|
|
15
|
+
import { registerLoopVariablesIfAbsent } from "../../../share/loop-item-var.js";
|
|
16
|
+
import { registerNodeVariableIfAbsent } from "../../../share/tree-node-var.js";
|
|
17
|
+
import { PAGE_TARGET_ID } from "../../../share/page-target.js";
|
|
18
|
+
import * as alertOp from "../../operations/2026-06-09/com.shwfed.operation.alert/schema.js";
|
|
19
|
+
import * as httpRequestOp from "../../operations/2026-06-11/com.shwfed.operation.http.request.json/schema.js";
|
|
20
|
+
import * as navigationOp from "../../operations/2026-06-15/com.shwfed.operation.navigation/schema.js";
|
|
21
|
+
import * as httpDownloadOp from "../../operations/2026-06-15/com.shwfed.operation.http.download/schema.js";
|
|
22
|
+
import { getHostManual } from "./ai-host-manuals.js";
|
|
23
|
+
const ENTERABLE_HOSTS = /* @__PURE__ */ new Set(["table", "form", "slot", "actions"]);
|
|
24
|
+
function enterableEdge(entry) {
|
|
25
|
+
const edge = entry?.edges?.[0];
|
|
26
|
+
if (!edge) return void 0;
|
|
27
|
+
if (!ENTERABLE_HOSTS.has(edge.host)) return void 0;
|
|
28
|
+
return edge;
|
|
29
|
+
}
|
|
30
|
+
function isBlockDrillable(block) {
|
|
31
|
+
return enterableEdge(findBlock(block.type, block.compatibilityDate)) !== void 0;
|
|
32
|
+
}
|
|
33
|
+
function blockLabel(block) {
|
|
34
|
+
const entry = findBlock(block.type, block.compatibilityDate);
|
|
35
|
+
const instance = entry?.metadata.instanceName?.(block);
|
|
36
|
+
if (instance && instance.length > 0) return instance;
|
|
37
|
+
return entry?.metadata.name ?? block.type;
|
|
38
|
+
}
|
|
39
|
+
function recomputeTracks(placements) {
|
|
40
|
+
let cols = 0;
|
|
41
|
+
let rows = 0;
|
|
42
|
+
for (const p of Object.values(placements)) {
|
|
43
|
+
const [, [x2, y2]] = p.area;
|
|
44
|
+
if (x2 - 1 > cols) cols = x2 - 1;
|
|
45
|
+
if (y2 - 1 > rows) rows = y2 - 1;
|
|
46
|
+
}
|
|
47
|
+
return { columns: Math.max(1, cols), rows: Math.max(1, rows) };
|
|
48
|
+
}
|
|
49
|
+
function overlaps(a, b) {
|
|
50
|
+
return a[0][0] < b[1][0] && a[1][0] > b[0][0] && a[0][1] < b[1][1] && a[1][1] > b[0][1];
|
|
51
|
+
}
|
|
52
|
+
const BLOCK_HARNESS_KEYS = ["id", "type", "compatibilityDate"];
|
|
53
|
+
const PlaceBlockInput = Schema.Struct({
|
|
54
|
+
id: Schema.String.pipe(Schema.minLength(1)),
|
|
55
|
+
area: Area
|
|
56
|
+
});
|
|
57
|
+
function decodePlace(input) {
|
|
58
|
+
const result = Schema.decodeUnknownEither(PlaceBlockInput)(coerceFromString(input, PlaceBlockInput));
|
|
59
|
+
if (result._tag === "Right") {
|
|
60
|
+
return { ok: true, value: result.right };
|
|
61
|
+
}
|
|
62
|
+
const issues = ParseResult.ArrayFormatter.formatErrorSync(result.left);
|
|
63
|
+
const report = issues.map((i) => `- ${i.path.map(String).join(".") || "(root)"}: ${i.message}`).join("\n");
|
|
64
|
+
return { ok: false, report };
|
|
65
|
+
}
|
|
66
|
+
function emptyLayoutSet() {
|
|
67
|
+
return { name: "\u9ED8\u8BA4", layout: { columns: 1, placements: {} } };
|
|
68
|
+
}
|
|
69
|
+
export function createPageSlotTools(deps) {
|
|
70
|
+
function readSlot() {
|
|
71
|
+
const page = deps.read();
|
|
72
|
+
const slot = page.slot && typeof page.slot === "object" ? page.slot : { blocks: [], layouts: [] };
|
|
73
|
+
return { page, slot };
|
|
74
|
+
}
|
|
75
|
+
return [
|
|
76
|
+
// ---- 信息获取 ----
|
|
77
|
+
{
|
|
78
|
+
name: "list_available_block_types",
|
|
79
|
+
description: "List the page block types you can insert (table, form, chart, card, tabs, \u2026). Returns each type, its name, and \u2014 when set \u2014 a one-line description of when to use it. Use this first to discover what blocks exist; for a block's field contract call describe_specific_block_type, and for its deep configuration (a table's columns, a form's fields, a container's inner blocks) insert it then enter_node into it.",
|
|
80
|
+
inputJsonSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
81
|
+
execute: () => activeBlocks().map((b) => {
|
|
82
|
+
const entry = { type: b.type, name: b.metadata.name };
|
|
83
|
+
if (b.metadata.description !== void 0) entry.description = b.metadata.description;
|
|
84
|
+
return entry;
|
|
85
|
+
})
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "describe_specific_block_type",
|
|
89
|
+
description: "Return the JSON Schema (without id/type/compatibilityDate \u2014 managed by the harness), the default body, and \u2014 when the type has one \u2014 a prose `guide` (when to use it, config recipe, gotchas) for one page block type. Most blocks wrap a deeper config (a table, a form, a nested slot): insert the block, then enter_node into it to configure the details discovery-first. Deprecated/unknown types are not accepted.",
|
|
90
|
+
inputJsonSchema: {
|
|
91
|
+
type: "object",
|
|
92
|
+
properties: {
|
|
93
|
+
type: { type: "string", description: "A `type` value from list_available_block_types." }
|
|
94
|
+
},
|
|
95
|
+
required: ["type"],
|
|
96
|
+
additionalProperties: false
|
|
97
|
+
},
|
|
98
|
+
execute: (input) => {
|
|
99
|
+
const { type } = input ?? {};
|
|
100
|
+
if (typeof type !== "string" || type.length === 0) {
|
|
101
|
+
return "describe failed: `type` must be a non-empty string.";
|
|
102
|
+
}
|
|
103
|
+
const entry = activeBlocks().find((b) => b.type === type);
|
|
104
|
+
if (!entry) {
|
|
105
|
+
return `describe failed: block type "${type}" is not available. Call list_available_block_types to see what is.`;
|
|
106
|
+
}
|
|
107
|
+
let jsonSchema;
|
|
108
|
+
try {
|
|
109
|
+
const publicSchema = entry.schema(deps.configure, blockRef(deps.configure)).pipe(Schema.omit(...BLOCK_HARNESS_KEYS));
|
|
110
|
+
jsonSchema = JSONSchema.make(publicSchema);
|
|
111
|
+
} catch {
|
|
112
|
+
jsonSchema = "(schema unavailable)";
|
|
113
|
+
}
|
|
114
|
+
const result = { schema: jsonSchema, defaults: entry.defaultBody() };
|
|
115
|
+
if (entry.prompt !== void 0) result.guide = entry.prompt;
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: "list_blocks",
|
|
121
|
+
description: "Return the current slot's blocks \u2014 each with `id`, `type`, a friendly `name`, whether it is `drillable` (can be entered to configure details), and its `placement` (grid area in the slot's first layout, or null when unplaced). Use this to discover ids before enter_node / place_block / delete_blocks.",
|
|
122
|
+
inputJsonSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
123
|
+
execute: () => {
|
|
124
|
+
const { slot } = readSlot();
|
|
125
|
+
const blocks = Array.isArray(slot.blocks) ? slot.blocks : [];
|
|
126
|
+
const layout0 = Array.isArray(slot.layouts) ? slot.layouts[0]?.layout : void 0;
|
|
127
|
+
const placements = layout0?.placements ?? {};
|
|
128
|
+
return {
|
|
129
|
+
blocks: blocks.map((b) => ({
|
|
130
|
+
id: b.id,
|
|
131
|
+
type: b.type,
|
|
132
|
+
name: blockLabel(b),
|
|
133
|
+
drillable: isBlockDrillable(b),
|
|
134
|
+
placement: placements[b.id]?.area ?? null
|
|
135
|
+
})),
|
|
136
|
+
grid: layout0 ? { columns: layout0.columns ?? null } : null
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
// ---- 配置 ----
|
|
141
|
+
{
|
|
142
|
+
name: "insert_block",
|
|
143
|
+
description: "Insert one new block of the given `type` into the current slot. The harness mints the id, seeds sensible defaults, and auto-places it in the slot's first layout at a free spot sized by the block's default footprint. Do NOT pass id / compatibilityDate. Configure the block's details afterwards by enter_node-ing into it. Returns the new block id and its placement; adjust the position with place_block if needed.",
|
|
144
|
+
inputJsonSchema: {
|
|
145
|
+
type: "object",
|
|
146
|
+
properties: {
|
|
147
|
+
type: { type: "string", description: "A block type from list_available_block_types." }
|
|
148
|
+
},
|
|
149
|
+
required: ["type"],
|
|
150
|
+
additionalProperties: false
|
|
151
|
+
},
|
|
152
|
+
execute: (input) => {
|
|
153
|
+
const { type } = input ?? {};
|
|
154
|
+
if (typeof type !== "string" || type.length === 0) {
|
|
155
|
+
return "insert failed: `type` must be a non-empty string.";
|
|
156
|
+
}
|
|
157
|
+
const entry = activeBlocks().find((b) => b.type === type);
|
|
158
|
+
if (!entry) {
|
|
159
|
+
return `insert failed: block type "${type}" is not available. Call list_available_block_types to see what is.`;
|
|
160
|
+
}
|
|
161
|
+
const { page, slot } = readSlot();
|
|
162
|
+
const blocks = Array.isArray(slot.blocks) ? slot.blocks : [];
|
|
163
|
+
const id = deps.genUuid();
|
|
164
|
+
const block = { ...entry.defaultBody(), id, type: entry.type, compatibilityDate: entry.compatibilityDate };
|
|
165
|
+
const layouts = Array.isArray(slot.layouts) && slot.layouts.length > 0 ? slot.layouts : [emptyLayoutSet()];
|
|
166
|
+
const ls0 = layouts[0];
|
|
167
|
+
const w = entry.metadata.w.initial ?? 1;
|
|
168
|
+
const h = entry.metadata.h.initial ?? 1;
|
|
169
|
+
const existing = ls0.layout?.placements ?? {};
|
|
170
|
+
const placement = findFreePlacement(existing, w, h);
|
|
171
|
+
const placements = { ...existing, [id]: placement };
|
|
172
|
+
const tracks = recomputeTracks(placements);
|
|
173
|
+
const nextLayouts = [
|
|
174
|
+
{ ...ls0, layout: { ...ls0.layout, placements, columns: tracks.columns, rows: tracks.rows } },
|
|
175
|
+
...layouts.slice(1)
|
|
176
|
+
];
|
|
177
|
+
deps.write({ ...page, slot: { ...slot, blocks: [...blocks, block], layouts: nextLayouts } });
|
|
178
|
+
return { id, type: entry.type, placement: placement.area };
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: "delete_blocks",
|
|
183
|
+
description: "Delete one or more blocks by id from the current slot. Get ids from list_blocks. Blocks are matched by id only; on any unknown id the whole call is rejected without writing. Deleting a block also removes it from every layout (its placement is stripped).",
|
|
184
|
+
inputJsonSchema: {
|
|
185
|
+
type: "object",
|
|
186
|
+
properties: {
|
|
187
|
+
ids: {
|
|
188
|
+
type: "array",
|
|
189
|
+
items: { type: "string", minLength: 1 },
|
|
190
|
+
minItems: 1,
|
|
191
|
+
description: "Block ids to delete. Get them from list_blocks first."
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
required: ["ids"],
|
|
195
|
+
additionalProperties: false
|
|
196
|
+
},
|
|
197
|
+
execute: (input) => {
|
|
198
|
+
const raw = input ?? {};
|
|
199
|
+
const ids = raw.ids;
|
|
200
|
+
if (!Array.isArray(ids) || ids.length === 0) {
|
|
201
|
+
return "delete failed: `ids` must be a non-empty array of block ids.";
|
|
202
|
+
}
|
|
203
|
+
for (const id of ids) {
|
|
204
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
205
|
+
return "delete failed: every `ids` entry must be a non-empty string.";
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const seen = /* @__PURE__ */ new Set();
|
|
209
|
+
for (const id of ids) {
|
|
210
|
+
if (seen.has(id)) return `delete failed: duplicate id "${id}" in input \u2014 dedupe and call again.`;
|
|
211
|
+
seen.add(id);
|
|
212
|
+
}
|
|
213
|
+
const { page, slot } = readSlot();
|
|
214
|
+
const blocks = Array.isArray(slot.blocks) ? slot.blocks : [];
|
|
215
|
+
const existing = new Set(blocks.map((b) => b.id));
|
|
216
|
+
for (const id of ids) {
|
|
217
|
+
if (!existing.has(id)) {
|
|
218
|
+
return `delete failed: block id "${id}" is not present. Call list_blocks to see current ids.`;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const drop = new Set(ids);
|
|
222
|
+
const nextBlocks = blocks.filter((b) => !drop.has(b.id));
|
|
223
|
+
const layouts = Array.isArray(slot.layouts) ? slot.layouts : [];
|
|
224
|
+
const nextLayouts = layouts.map((ls) => {
|
|
225
|
+
const placements = ls.layout?.placements ?? {};
|
|
226
|
+
const entries = Object.entries(placements).filter(([pid]) => !drop.has(pid));
|
|
227
|
+
if (entries.length === Object.keys(placements).length) return ls;
|
|
228
|
+
const nextLs = { ...ls, layout: { ...ls.layout, placements: Object.fromEntries(entries) } };
|
|
229
|
+
return normalizeLayoutSet(nextLs);
|
|
230
|
+
});
|
|
231
|
+
deps.write({ ...page, slot: { ...slot, blocks: nextBlocks, layouts: nextLayouts } });
|
|
232
|
+
return { deleted: ids, count: ids.length };
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: "place_block",
|
|
237
|
+
description: "Place a block into the current slot's first layout at grid coordinates you choose. `area` is [[x1,y1],[x2,y2]] on 1-based grid lines (top-left inclusive, bottom-right exclusive); e.g. a block spanning columns 1\u201332 on rows 1\u20138 is [[1,1],[33,9]]. The block must already exist (insert it first). The harness rejects an area overlapping another block \u2014 pick a free spot (see list_blocks) and call again. Placing an already-placed block MOVES it. The grid grows to fit your placement.",
|
|
238
|
+
inputJsonSchema: {
|
|
239
|
+
type: "object",
|
|
240
|
+
properties: {
|
|
241
|
+
id: { type: "string", description: "The block id to place (from list_blocks)." },
|
|
242
|
+
area: {
|
|
243
|
+
type: "array",
|
|
244
|
+
description: "Grid area [[x1,y1],[x2,y2]], 1-based grid lines, bottom-right exclusive.",
|
|
245
|
+
items: { type: "array", items: { type: "integer", minimum: 1 }, minItems: 2, maxItems: 2 },
|
|
246
|
+
minItems: 2,
|
|
247
|
+
maxItems: 2
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
required: ["id", "area"],
|
|
251
|
+
additionalProperties: false
|
|
252
|
+
},
|
|
253
|
+
execute: (input) => {
|
|
254
|
+
const verdict = decodePlace(input ?? {});
|
|
255
|
+
if (!verdict.ok) {
|
|
256
|
+
return `place failed. Fix these and call place_block again:
|
|
257
|
+
${verdict.report}`;
|
|
258
|
+
}
|
|
259
|
+
const { id, area } = verdict.value;
|
|
260
|
+
const { page, slot } = readSlot();
|
|
261
|
+
const blocks = Array.isArray(slot.blocks) ? slot.blocks : [];
|
|
262
|
+
if (!blocks.some((b) => b.id === id)) {
|
|
263
|
+
return `place failed: block id "${id}" is not present. Call list_blocks to see ids.`;
|
|
264
|
+
}
|
|
265
|
+
const layouts = Array.isArray(slot.layouts) ? slot.layouts : [];
|
|
266
|
+
const ls0 = layouts[0];
|
|
267
|
+
if (!ls0 || !ls0.layout) {
|
|
268
|
+
return "place failed: the slot has no layout to place into.";
|
|
269
|
+
}
|
|
270
|
+
const placements = { ...ls0.layout.placements ?? {} };
|
|
271
|
+
for (const [pid, p] of Object.entries(placements)) {
|
|
272
|
+
if (pid === id) continue;
|
|
273
|
+
if (overlaps(area, p.area)) {
|
|
274
|
+
return `place failed: area overlaps block "${pid}" at ${JSON.stringify(p.area)}. Pick a free area (see list_blocks) and call again.`;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
placements[id] = { area };
|
|
278
|
+
const tracks = recomputeTracks(placements);
|
|
279
|
+
const nextLayout = { ...ls0.layout, placements, columns: tracks.columns, rows: tracks.rows };
|
|
280
|
+
deps.write({ ...page, slot: { ...slot, layouts: [{ ...ls0, layout: nextLayout }, ...layouts.slice(1)] } });
|
|
281
|
+
return { id, area, columns: tracks.columns, rows: tracks.rows };
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
];
|
|
285
|
+
}
|
|
286
|
+
function structKeyBridge(parent, key) {
|
|
287
|
+
return {
|
|
288
|
+
read: () => parent.read()?.[key],
|
|
289
|
+
write: (next) => {
|
|
290
|
+
const rec = parent.read() ?? {};
|
|
291
|
+
parent.write({ ...rec, [key]: next });
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function arrayItemBridge(parent, arrayKey, id, subKey) {
|
|
296
|
+
return {
|
|
297
|
+
read: () => {
|
|
298
|
+
const arr = parent.read()?.[arrayKey] ?? [];
|
|
299
|
+
const item = arr.find((x) => x.id === id);
|
|
300
|
+
if (!item) return void 0;
|
|
301
|
+
return subKey ? item[subKey] : item;
|
|
302
|
+
},
|
|
303
|
+
write: (next) => {
|
|
304
|
+
const rec = parent.read() ?? {};
|
|
305
|
+
const arr = rec[arrayKey] ?? [];
|
|
306
|
+
const nextArr = arr.map((x) => x.id === id ? subKey ? { ...x, [subKey]: next } : next : x);
|
|
307
|
+
parent.write({ ...rec, [arrayKey]: nextArr });
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
function withLoopVars(base) {
|
|
312
|
+
return (env) => {
|
|
313
|
+
base(env);
|
|
314
|
+
registerLoopVariablesIfAbsent(env);
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function withRowVars(base) {
|
|
318
|
+
return (env) => {
|
|
319
|
+
base(env);
|
|
320
|
+
registerRowVariablesIfAbsent(env);
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function withFormVars(base) {
|
|
324
|
+
return (env) => {
|
|
325
|
+
base(env);
|
|
326
|
+
registerFormVariablesIfAbsent(env);
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function withNodeVar(base) {
|
|
330
|
+
return (env) => {
|
|
331
|
+
base(env);
|
|
332
|
+
registerNodeVariableIfAbsent(env);
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
function withToolbarVars(base) {
|
|
336
|
+
return (env) => configureTableActionsScope(env, base);
|
|
337
|
+
}
|
|
338
|
+
function applyEdgeScope(edge, base) {
|
|
339
|
+
return edge.celScope === "loop-item" ? withLoopVars(base) : base;
|
|
340
|
+
}
|
|
341
|
+
function opDescriptor(o) {
|
|
342
|
+
return { id: o.type, name: o.metadata.name, compatibilityDate: o.compatibilityDate };
|
|
343
|
+
}
|
|
344
|
+
function pageEventTarget() {
|
|
345
|
+
return {
|
|
346
|
+
id: PAGE_TARGET_ID,
|
|
347
|
+
kind: "page",
|
|
348
|
+
name: "\u9875\u9762",
|
|
349
|
+
operations: [
|
|
350
|
+
opDescriptor(alertOp),
|
|
351
|
+
opDescriptor(httpRequestOp),
|
|
352
|
+
opDescriptor(navigationOp),
|
|
353
|
+
opDescriptor(httpDownloadOp),
|
|
354
|
+
{ id: "close", name: "\u5173\u95ED\u6807\u7B7E\u9875" }
|
|
355
|
+
]
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function tableEventTargets(table) {
|
|
359
|
+
const tableId = typeof table.id === "string" ? table.id : null;
|
|
360
|
+
const tableOps = tableMetadata.operations;
|
|
361
|
+
return [{
|
|
362
|
+
id: tableId,
|
|
363
|
+
kind: "table",
|
|
364
|
+
name: typeof table.displayName === "string" && table.displayName.length > 0 ? table.displayName : tableMetadata.name,
|
|
365
|
+
operations: tableOps.map((o) => ({ id: o.id, name: o.name, ...o.compatibilityDate ? { compatibilityDate: o.compatibilityDate } : {} })),
|
|
366
|
+
...tableId === null ? { note: "\u8BE5\u8868\u683C\u5C1A\u65E0 id\uFF0C\u6309\u94AE\u65E0\u6CD5\u53EF\u9760\u5730\u4EE5\u5B83\u4E3A\u76EE\u6807\u3002" } : {}
|
|
367
|
+
}];
|
|
368
|
+
}
|
|
369
|
+
export function createConfigAiCursor(deps) {
|
|
370
|
+
const pageSlotBridge = {
|
|
371
|
+
read: () => {
|
|
372
|
+
const page = deps.read();
|
|
373
|
+
return page?.slot && typeof page.slot === "object" ? page.slot : { blocks: [], layouts: [] };
|
|
374
|
+
},
|
|
375
|
+
write: (nextSlot) => {
|
|
376
|
+
const page = deps.read();
|
|
377
|
+
deps.write({ ...page, slot: nextSlot });
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
function slotFamily(bridge, configure) {
|
|
381
|
+
return createPageSlotTools({
|
|
382
|
+
read: () => ({ slot: bridge.read() ?? { blocks: [], layouts: [] } }),
|
|
383
|
+
write: (next) => bridge.write(next.slot),
|
|
384
|
+
configure,
|
|
385
|
+
genUuid: deps.genUuid
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
const pageFrame = {
|
|
389
|
+
kind: "page",
|
|
390
|
+
label: "\u9875\u9762",
|
|
391
|
+
family: slotFamily(pageSlotBridge, deps.configure),
|
|
392
|
+
slotBridge: pageSlotBridge,
|
|
393
|
+
configure: deps.configure,
|
|
394
|
+
eventTargets: () => [pageEventTarget()]
|
|
395
|
+
};
|
|
396
|
+
let frames = [pageFrame];
|
|
397
|
+
const fallbackManuals = /* @__PURE__ */ new Set();
|
|
398
|
+
const deliveredManuals = deps.manualsDelivered ?? {
|
|
399
|
+
has: (kind) => fallbackManuals.has(kind),
|
|
400
|
+
add: (kind) => {
|
|
401
|
+
fallbackManuals.add(kind);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
const scope = () => frames.map((f) => f.label).join(" > ");
|
|
405
|
+
const current = () => frames[frames.length - 1];
|
|
406
|
+
function attachManual(result, kind) {
|
|
407
|
+
if (!deliveredManuals.has(kind)) {
|
|
408
|
+
deliveredManuals.add(kind);
|
|
409
|
+
const manual = getHostManual(kind);
|
|
410
|
+
if (manual !== void 0) result.manual = manual;
|
|
411
|
+
}
|
|
412
|
+
return result;
|
|
413
|
+
}
|
|
414
|
+
function aggregateEventTargets(ownerTargets) {
|
|
415
|
+
const out = [];
|
|
416
|
+
const seen = /* @__PURE__ */ new Set();
|
|
417
|
+
const push = (t) => {
|
|
418
|
+
const key = t.id ?? `${t.kind}:${t.name}`;
|
|
419
|
+
if (seen.has(key)) return;
|
|
420
|
+
seen.add(key);
|
|
421
|
+
out.push(t);
|
|
422
|
+
};
|
|
423
|
+
for (const t of ownerTargets) push(t);
|
|
424
|
+
for (let i = frames.length - 1; i >= 0; i--) {
|
|
425
|
+
for (const t of frames[i].eventTargets?.() ?? []) push(t);
|
|
426
|
+
}
|
|
427
|
+
return out;
|
|
428
|
+
}
|
|
429
|
+
function enterTable(bridge, block, configure) {
|
|
430
|
+
const family = createTableAiTools({
|
|
431
|
+
read: () => bridge.read() ?? {},
|
|
432
|
+
write: (next) => bridge.write(next),
|
|
433
|
+
configure,
|
|
434
|
+
genUuid: deps.genUuid
|
|
435
|
+
});
|
|
436
|
+
const label = blockLabel(block);
|
|
437
|
+
frames.push({
|
|
438
|
+
kind: "table",
|
|
439
|
+
label,
|
|
440
|
+
node: { id: block.id, type: block.type, compatibilityDate: block.compatibilityDate },
|
|
441
|
+
family,
|
|
442
|
+
configure,
|
|
443
|
+
eventTargets: () => tableEventTargets(bridge.read() ?? {}),
|
|
444
|
+
recap: () => {
|
|
445
|
+
const t = bridge.read() ?? {};
|
|
446
|
+
return { columns: (Array.isArray(t.columns) ? t.columns : []).map((c) => ({ id: c.id, type: c.type })) };
|
|
447
|
+
},
|
|
448
|
+
// A table's row-action columns and its toolbar/bottom action bars are the
|
|
449
|
+
// enterable children (design §1.3: table → actions/bottomActions,
|
|
450
|
+
// column.actions → actions).
|
|
451
|
+
enter: (id) => {
|
|
452
|
+
const t = bridge.read() ?? {};
|
|
453
|
+
if (id === "actions" || id === "bottomActions") {
|
|
454
|
+
return enterActions(
|
|
455
|
+
structKeyBridge(bridge, id),
|
|
456
|
+
{ id, type: `table.${id}`, compatibilityDate: block.compatibilityDate },
|
|
457
|
+
id === "actions" ? "\u4E0A\u65B9\u64CD\u4F5C" : "\u4E0B\u65B9\u64CD\u4F5C",
|
|
458
|
+
withToolbarVars(configure),
|
|
459
|
+
[]
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
const columns2 = Array.isArray(t.columns) ? t.columns : [];
|
|
463
|
+
const col = columns2.find((c) => c.id === id);
|
|
464
|
+
if (!col) {
|
|
465
|
+
return `enter_node failed: no column or action bar with id "${id}". A table's enterable children are its row-action columns (see list_columns) plus "actions" / "bottomActions" (its toolbar / bottom action bars).`;
|
|
466
|
+
}
|
|
467
|
+
const entry = findColumn(col.type, col.compatibilityDate);
|
|
468
|
+
const edge = entry?.edges?.[0];
|
|
469
|
+
if (!edge || edge.host !== "actions") {
|
|
470
|
+
return `enter_node: column "${id}" (${col.type}) has no embedded host to drill into. Configure it with the table's column tools instead.`;
|
|
471
|
+
}
|
|
472
|
+
return enterActions(
|
|
473
|
+
arrayItemBridge(bridge, "columns", id),
|
|
474
|
+
{ id, type: col.type, compatibilityDate: col.compatibilityDate },
|
|
475
|
+
"\u64CD\u4F5C\u5217",
|
|
476
|
+
withRowVars(configure),
|
|
477
|
+
[]
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
const table = bridge.read() ?? {};
|
|
482
|
+
const columns = Array.isArray(table.columns) ? table.columns : [];
|
|
483
|
+
const result = {
|
|
484
|
+
scope: scope(),
|
|
485
|
+
entered: { id: block.id, node: `${block.type}@${block.compatibilityDate}`, name: label },
|
|
486
|
+
toolFamily: "table",
|
|
487
|
+
summary: {
|
|
488
|
+
columnIds: columns.map((c) => c.id),
|
|
489
|
+
dataSourceConfigured: table.dataSource !== void 0,
|
|
490
|
+
queryConfigured: table.query !== void 0
|
|
491
|
+
},
|
|
492
|
+
drillable: [],
|
|
493
|
+
hint: '\u7528 describe_general_settings / list_available_column_types / list_columns \u7B49\u6309\u9700\u4E86\u89E3\u4E0E\u914D\u7F6E\uFF1B\u641C\u7D22\u6761\u4EF6\u7528 *_field* \u5DE5\u5177\u3002\u64CD\u4F5C\u6309\u94AE\uFF1Aenter_node "actions" / "bottomActions" \u8FDB\u5165\u5DE5\u5177\u680F / \u5E95\u90E8\u64CD\u4F5C\u680F\uFF0C\u6216 enter_node \u4E00\u4E2A\u64CD\u4F5C\u5217\u8FDB\u5165\u5176\u6309\u94AE\u3002\u914D\u7F6E\u5B8C\u6210\u540E\u8C03\u7528 leave_node \u8FD4\u56DE\u3002'
|
|
494
|
+
};
|
|
495
|
+
return attachManual(result, "table");
|
|
496
|
+
}
|
|
497
|
+
function enterForm(bridge, block, configure) {
|
|
498
|
+
const family = createFormFieldTools({
|
|
499
|
+
read: () => bridge.read(),
|
|
500
|
+
write: (next) => bridge.write(next),
|
|
501
|
+
configure,
|
|
502
|
+
genUuid: deps.genUuid
|
|
503
|
+
});
|
|
504
|
+
const label = blockLabel(block);
|
|
505
|
+
frames.push({
|
|
506
|
+
kind: "form",
|
|
507
|
+
label,
|
|
508
|
+
node: { id: block.id, type: block.type, compatibilityDate: block.compatibilityDate },
|
|
509
|
+
family,
|
|
510
|
+
configure,
|
|
511
|
+
eventTargets: () => {
|
|
512
|
+
const form2 = bridge.read() ?? {};
|
|
513
|
+
if (typeof form2.id !== "string") return [];
|
|
514
|
+
const ops = formMetadata.operations;
|
|
515
|
+
return [{ id: form2.id, kind: "form", name: "\u8868\u5355", operations: ops.map((o) => ({ id: o.id, name: o.name })) }];
|
|
516
|
+
},
|
|
517
|
+
recap: () => {
|
|
518
|
+
const f = bridge.read() ?? {};
|
|
519
|
+
return { fields: (Array.isArray(f.fields) ? f.fields : []).map((x) => ({ id: x.id, type: x.type })) };
|
|
520
|
+
},
|
|
521
|
+
// A form's fields are its enterable children: a field.table (table
|
|
522
|
+
// family), a field.list/.collapsible/.tabs sub-form (form family), a
|
|
523
|
+
// field.actions (actions family). Data-driven off the field's edge.
|
|
524
|
+
enter: (id) => {
|
|
525
|
+
const f = bridge.read() ?? {};
|
|
526
|
+
const fields2 = Array.isArray(f.fields) ? f.fields : [];
|
|
527
|
+
const field = fields2.find((x) => x.id === id);
|
|
528
|
+
if (!field) {
|
|
529
|
+
return `enter_node failed: no field with id "${id}". Call list_fields to see current fields.`;
|
|
530
|
+
}
|
|
531
|
+
const entry = findField(field.type, field.compatibilityDate);
|
|
532
|
+
const edge = entry?.edges?.[0];
|
|
533
|
+
if (!edge) {
|
|
534
|
+
return `enter_node: field "${id}" (${field.type}) has no embedded host to drill into. Configure it with the form field tools instead.`;
|
|
535
|
+
}
|
|
536
|
+
const fieldConfigure = applyEdgeScope(edge, configure);
|
|
537
|
+
switch (edge.host) {
|
|
538
|
+
case "table":
|
|
539
|
+
return enterTable(arrayItemBridge(bridge, "fields", id, edge.key), { id, type: field.type, compatibilityDate: field.compatibilityDate }, fieldConfigure);
|
|
540
|
+
case "form":
|
|
541
|
+
if (edge.itemSlot) {
|
|
542
|
+
return enterTabs(bridge, "fields", id, edge, { id, type: field.type, compatibilityDate: field.compatibilityDate }, fieldConfigure);
|
|
543
|
+
}
|
|
544
|
+
return enterForm(arrayItemBridge(bridge, "fields", id, edge.key), { id, type: field.type, compatibilityDate: field.compatibilityDate }, fieldConfigure);
|
|
545
|
+
case "actions":
|
|
546
|
+
return enterActions(
|
|
547
|
+
arrayItemBridge(bridge, "fields", id),
|
|
548
|
+
{ id, type: field.type, compatibilityDate: field.compatibilityDate },
|
|
549
|
+
typeof field.displayName === "string" && field.displayName || "\u64CD\u4F5C\u5B57\u6BB5",
|
|
550
|
+
withFormVars(fieldConfigure),
|
|
551
|
+
[]
|
|
552
|
+
);
|
|
553
|
+
default:
|
|
554
|
+
return `enter_node: field "${id}" embeds ${edge.host}, which the cursor can't enter yet.`;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
const form = bridge.read() ?? {};
|
|
559
|
+
const fields = Array.isArray(form.fields) ? form.fields : [];
|
|
560
|
+
const result = {
|
|
561
|
+
scope: scope(),
|
|
562
|
+
entered: { id: block.id, node: `${block.type}@${block.compatibilityDate}`, name: label },
|
|
563
|
+
toolFamily: "form",
|
|
564
|
+
summary: { fieldIds: fields.map((f) => f.id) },
|
|
565
|
+
drillable: [],
|
|
566
|
+
hint: "\u7528 list_available_field_types / describe_specific_field_type / list_fields \u7B49\u6309\u9700\u4E86\u89E3\u4E0E\u914D\u7F6E\uFF1Binsert_field \u65B0\u589E\u5B57\u6BB5\u540E\u7528 place_field \u653E\u7F6E\uFF1BCEL \u7528 describe_form_settings \u67E5\u770B\u4F5C\u7528\u57DF\u3002\u5D4C\u5957\u5B57\u6BB5\uFF08\u8868\u683C / \u5217\u8868 / \u6298\u53E0 / \u6807\u7B7E\u9875 / \u64CD\u4F5C\uFF09\u7528 enter_node \u94BB\u5165\u3002\u914D\u7F6E\u5B8C\u6210\u540E\u8C03\u7528 leave_node \u8FD4\u56DE\u3002"
|
|
567
|
+
};
|
|
568
|
+
return attachManual(result, "form");
|
|
569
|
+
}
|
|
570
|
+
function enterSlot(bridge, node, label, configure, ownerTargets = []) {
|
|
571
|
+
frames.push({
|
|
572
|
+
kind: "slot",
|
|
573
|
+
label,
|
|
574
|
+
node,
|
|
575
|
+
family: slotFamily(bridge, configure),
|
|
576
|
+
slotBridge: bridge,
|
|
577
|
+
configure,
|
|
578
|
+
...ownerTargets.length > 0 ? { eventTargets: () => ownerTargets } : {}
|
|
579
|
+
});
|
|
580
|
+
const slot = bridge.read() ?? { blocks: [], layouts: [] };
|
|
581
|
+
const blocks = Array.isArray(slot.blocks) ? slot.blocks : [];
|
|
582
|
+
return {
|
|
583
|
+
scope: scope(),
|
|
584
|
+
entered: { id: node.id, node: `${node.type}@${node.compatibilityDate}`, name: label },
|
|
585
|
+
toolFamily: "page-slot",
|
|
586
|
+
summary: { blockIds: blocks.map((b) => b.id) },
|
|
587
|
+
drillable: [],
|
|
588
|
+
hint: "\u8FD9\u662F\u4E00\u4E2A\u9875\u9762\u69FD\uFF08page-slot\uFF09\u3002\u7528 list_available_block_types / list_blocks / insert_block / place_block \u5728\u5176\u5185\u90E8\u642D\u5757\uFF0C\u53EF\u7EE7\u7EED enter_node \u94BB\u5165\u66F4\u6DF1\u7684\u5BB9\u5668\u3002\u914D\u7F6E\u5B8C\u6210\u540E\u8C03\u7528 leave_node \u8FD4\u56DE\u3002"
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
function enterTabs(parent, arrayKey, containerId, edge, node, configure) {
|
|
592
|
+
const containerBridge = arrayKey === "__self__" ? parent : arrayItemBridge(parent, arrayKey, containerId);
|
|
593
|
+
const label = "\u6807\u7B7E\u9875";
|
|
594
|
+
const listPanes = {
|
|
595
|
+
name: "list_panes",
|
|
596
|
+
description: "Return the tabs container's panes \u2014 each with its `id` and label. Use enter_node with a pane id to drill into that pane's content.",
|
|
597
|
+
inputJsonSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
598
|
+
execute: () => {
|
|
599
|
+
const c2 = containerBridge.read() ?? {};
|
|
600
|
+
const panes2 = Array.isArray(c2[edge.key]) ? c2[edge.key] : [];
|
|
601
|
+
return panes2.map((p, i) => ({ id: p.id, index: i, label: p.label ?? null }));
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
frames.push({
|
|
605
|
+
kind: "tabs",
|
|
606
|
+
label,
|
|
607
|
+
node,
|
|
608
|
+
family: [listPanes],
|
|
609
|
+
configure,
|
|
610
|
+
recap: () => {
|
|
611
|
+
const c2 = containerBridge.read() ?? {};
|
|
612
|
+
const panes2 = Array.isArray(c2[edge.key]) ? c2[edge.key] : [];
|
|
613
|
+
return { panes: panes2.map((p) => ({ id: p.id })) };
|
|
614
|
+
},
|
|
615
|
+
enter: (paneId) => {
|
|
616
|
+
const c2 = containerBridge.read() ?? {};
|
|
617
|
+
const panes2 = Array.isArray(c2[edge.key]) ? c2[edge.key] : [];
|
|
618
|
+
const idx = panes2.findIndex((p) => p.id === paneId);
|
|
619
|
+
if (idx < 0) {
|
|
620
|
+
return `enter_node failed: no pane with id "${paneId}". Call list_panes to see pane ids.`;
|
|
621
|
+
}
|
|
622
|
+
const paneBridge = {
|
|
623
|
+
read: () => {
|
|
624
|
+
const cc = containerBridge.read() ?? {};
|
|
625
|
+
const ps = cc[edge.key] ?? [];
|
|
626
|
+
return ps[idx]?.[edge.itemSlot];
|
|
627
|
+
},
|
|
628
|
+
write: (next) => {
|
|
629
|
+
const cc = containerBridge.read() ?? {};
|
|
630
|
+
const ps = (cc[edge.key] ?? []).map((p, i) => i === idx ? { ...p, [edge.itemSlot]: next } : p);
|
|
631
|
+
containerBridge.write({ ...cc, [edge.key]: ps });
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
const paneNode = { id: paneId, type: `${node.type}#pane`, compatibilityDate: node.compatibilityDate };
|
|
635
|
+
if (edge.host === "form") {
|
|
636
|
+
return enterForm(paneBridge, paneNode, configure);
|
|
637
|
+
}
|
|
638
|
+
return enterSlot(paneBridge, paneNode, "\u6807\u7B7E\u9875", configure);
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
const c = containerBridge.read() ?? {};
|
|
642
|
+
const panes = Array.isArray(c[edge.key]) ? c[edge.key] : [];
|
|
643
|
+
return {
|
|
644
|
+
scope: scope(),
|
|
645
|
+
entered: { id: node.id, node: `${node.type}@${node.compatibilityDate}`, name: label },
|
|
646
|
+
toolFamily: "tabs",
|
|
647
|
+
summary: { paneIds: panes.map((p) => p.id) },
|
|
648
|
+
drillable: [],
|
|
649
|
+
hint: "\u8FD9\u662F\u4E00\u4E2A\u591A\u6807\u7B7E\u5BB9\u5668\u3002\u7528 list_panes \u67E5\u770B\u5404\u6807\u7B7E\u9875\uFF0C\u518D enter_node \u4E00\u4E2A\u6807\u7B7E\u9875 id \u94BB\u5165\u5176\u5185\u5BB9\u914D\u7F6E\u3002\u914D\u7F6E\u5B8C\u6210\u540E\u8C03\u7528 leave_node \u8FD4\u56DE\u3002"
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
function enterActions(bridge, node, label, configure, ownerTargets) {
|
|
653
|
+
const family = createActionsAiTools({
|
|
654
|
+
read: () => bridge.read(),
|
|
655
|
+
write: (next) => bridge.write(next),
|
|
656
|
+
configure,
|
|
657
|
+
genUuid: deps.genUuid,
|
|
658
|
+
eventTargets: () => aggregateEventTargets(ownerTargets)
|
|
659
|
+
});
|
|
660
|
+
frames.push({
|
|
661
|
+
kind: "actions",
|
|
662
|
+
label,
|
|
663
|
+
node,
|
|
664
|
+
family,
|
|
665
|
+
configure,
|
|
666
|
+
...ownerTargets.length > 0 ? { eventTargets: () => ownerTargets } : {},
|
|
667
|
+
recap: () => {
|
|
668
|
+
const c2 = bridge.read() ?? {};
|
|
669
|
+
return { items: (Array.isArray(c2.items) ? c2.items : []).map((it) => ({ id: it.id })) };
|
|
670
|
+
},
|
|
671
|
+
// A modal.layout button's inner slot is the one enterable child of an
|
|
672
|
+
// actions bar — the modal-recursion win (design §1.3).
|
|
673
|
+
enter: (id) => {
|
|
674
|
+
const c2 = bridge.read() ?? {};
|
|
675
|
+
const items2 = Array.isArray(c2.items) ? c2.items : [];
|
|
676
|
+
let found;
|
|
677
|
+
for (let i = 0; i < items2.length; i++) {
|
|
678
|
+
if (items2[i].id === id) {
|
|
679
|
+
found = { path: "top", topIdx: i, item: items2[i] };
|
|
680
|
+
break;
|
|
681
|
+
}
|
|
682
|
+
const subs = items2[i].items;
|
|
683
|
+
if (Array.isArray(subs)) {
|
|
684
|
+
const si = subs.findIndex((s) => s.id === id);
|
|
685
|
+
if (si >= 0) {
|
|
686
|
+
found = { path: "sub", topIdx: i, subIdx: si, item: subs[si] };
|
|
687
|
+
break;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
if (!found) {
|
|
692
|
+
return `enter_node failed: no button with id "${id}". Call list_action_items to see ids.`;
|
|
693
|
+
}
|
|
694
|
+
const action = found.item.action;
|
|
695
|
+
if (!action) {
|
|
696
|
+
return `enter_node: item "${id}" has no button action to drill into.`;
|
|
697
|
+
}
|
|
698
|
+
const bEdge = findButton(action.type, action.compatibilityDate)?.edges?.[0];
|
|
699
|
+
if (!bEdge || bEdge.host !== "slot") {
|
|
700
|
+
return `enter_node: button "${id}" (${action.type}) has no inner slot to drill into. Configure it with configure_button / set_action_item.`;
|
|
701
|
+
}
|
|
702
|
+
const slotKey = bEdge.key;
|
|
703
|
+
const slotBridge = {
|
|
704
|
+
read: () => {
|
|
705
|
+
const cc = bridge.read() ?? {};
|
|
706
|
+
const its = cc.items ?? [];
|
|
707
|
+
const it = found.path === "top" ? its[found.topIdx] : its[found.topIdx]?.items?.[found.subIdx];
|
|
708
|
+
return it?.action?.[slotKey];
|
|
709
|
+
},
|
|
710
|
+
write: (next) => {
|
|
711
|
+
const cc = bridge.read() ?? {};
|
|
712
|
+
const its = (cc.items ?? []).map((it, i) => {
|
|
713
|
+
if (found.path === "top") {
|
|
714
|
+
if (i !== found.topIdx) return it;
|
|
715
|
+
return { ...it, action: { ...it.action, [slotKey]: next } };
|
|
716
|
+
}
|
|
717
|
+
if (i !== found.topIdx) return it;
|
|
718
|
+
const subs = (it.items ?? []).map((s, si) => si === found.subIdx ? { ...s, action: { ...s.action, [slotKey]: next } } : s);
|
|
719
|
+
return { ...it, items: subs };
|
|
720
|
+
});
|
|
721
|
+
bridge.write({ ...cc, items: its });
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
return enterSlot(
|
|
725
|
+
slotBridge,
|
|
726
|
+
{ id, type: action.type, compatibilityDate: action.compatibilityDate ?? "" },
|
|
727
|
+
bEdge.label,
|
|
728
|
+
configure,
|
|
729
|
+
[{ id, kind: "modal", name: "\u5F39\u7A97\u6309\u94AE", operations: [{ id: "close", name: "\u5173\u95ED\u5F39\u7A97" }] }]
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
});
|
|
733
|
+
const c = bridge.read() ?? {};
|
|
734
|
+
const items = Array.isArray(c.items) ? c.items : [];
|
|
735
|
+
return attachManual({
|
|
736
|
+
scope: scope(),
|
|
737
|
+
entered: { id: node.id, node: `${node.type}@${node.compatibilityDate}`, name: label },
|
|
738
|
+
toolFamily: "actions",
|
|
739
|
+
summary: { itemIds: items.map((it) => it.id) },
|
|
740
|
+
drillable: [],
|
|
741
|
+
hint: "\u8FD9\u662F\u4E00\u7EC4\u64CD\u4F5C\u6309\u94AE\u3002\u7528 list_available_button_types / describe_specific_button_type \u9009\u578B\uFF0Cinsert_action_group / insert_button \u65B0\u589E\uFF0Cconfigure_button \u914D\u7F6E\u52A8\u4F5C\u4E0E\u89E6\u53D1\uFF08\u5148 describe_event_targets / list_operations \u67E5\u76EE\u6807\u4E0E\u64CD\u4F5C\uFF09\uFF0Cset_action_item \u914D\u6309\u94AE\u5916\u89C2\u3002\u6A21\u6001\u7A97\u53E3\u6309\u94AE\u53EF enter_node \u94BB\u5165\u5176\u5F39\u7A97\u5185\u5BB9\u3002\u914D\u7F6E\u5B8C\u6210\u540E\u8C03\u7528 leave_node \u8FD4\u56DE\u3002"
|
|
742
|
+
}, "actions");
|
|
743
|
+
}
|
|
744
|
+
const enterNode = {
|
|
745
|
+
name: "enter_node",
|
|
746
|
+
description: 'Descend the scope cursor one level into a DIRECT child so its own tool family activates. From a page/slot: a block (table / form / card / loop / tabs / actions). From a table: a row-action column, or "actions" / "bottomActions" (its action bars). From a form: a nested field (table / list / collapsible / tabs / actions). From an actions bar: a modal.layout button (its inner slot). From a tabs container: one pane (see list_panes). Pass the target\'s `id`. Reach deep targets by repeated enter_node, one level at a time. Returns a light orientation (breadcrumb, node identity, value summary, activated tool family, and \u2014 the first time you enter a host kind \u2014 its operating manual). Use leave_node to come back up.',
|
|
747
|
+
inputJsonSchema: {
|
|
748
|
+
type: "object",
|
|
749
|
+
properties: {
|
|
750
|
+
id: { type: "string", description: "The child id to enter (from list_blocks / list_columns / list_fields / list_action_items / list_panes)." }
|
|
751
|
+
},
|
|
752
|
+
required: ["id"],
|
|
753
|
+
additionalProperties: false
|
|
754
|
+
},
|
|
755
|
+
execute: (input) => {
|
|
756
|
+
const cur = current();
|
|
757
|
+
const { id } = input ?? {};
|
|
758
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
759
|
+
return "enter_node failed: `id` must be a non-empty string.";
|
|
760
|
+
}
|
|
761
|
+
if (cur.slotBridge) {
|
|
762
|
+
const slot = cur.slotBridge.read();
|
|
763
|
+
const block = slot?.blocks?.find((b) => b.id === id);
|
|
764
|
+
if (!block) {
|
|
765
|
+
return `enter_node failed: no block with id "${id}". Call list_blocks to see current blocks.`;
|
|
766
|
+
}
|
|
767
|
+
const entry = findBlock(block.type, block.compatibilityDate);
|
|
768
|
+
const edge = entry?.edges?.[0];
|
|
769
|
+
if (!edge) {
|
|
770
|
+
return `enter_node: block "${id}" is a ${block.type} \u2014 a leaf block with nothing to configure by drilling in. Use describe_specific_block_type / place_block / delete_blocks from the current slot instead.`;
|
|
771
|
+
}
|
|
772
|
+
const childBase = cur.configure;
|
|
773
|
+
switch (edge.host) {
|
|
774
|
+
case "table":
|
|
775
|
+
return enterTable(arrayItemBridge(cur.slotBridge, "blocks", id, edge.key), block, childBase);
|
|
776
|
+
case "form":
|
|
777
|
+
return enterForm(arrayItemBridge(cur.slotBridge, "blocks", id, edge.key), block, childBase);
|
|
778
|
+
case "slot": {
|
|
779
|
+
const childConfigure = applyEdgeScope(edge, childBase);
|
|
780
|
+
if (edge.itemSlot) {
|
|
781
|
+
return enterTabs(cur.slotBridge, "blocks", id, edge, { id: block.id, type: block.type, compatibilityDate: block.compatibilityDate }, childConfigure);
|
|
782
|
+
}
|
|
783
|
+
return enterSlot(arrayItemBridge(cur.slotBridge, "blocks", id, edge.key), { id: block.id, type: block.type, compatibilityDate: block.compatibilityDate }, blockLabel(block), childConfigure);
|
|
784
|
+
}
|
|
785
|
+
case "actions": {
|
|
786
|
+
const ops = (entry?.metadata).operations;
|
|
787
|
+
const ownerTargets = ops && ops.length > 0 ? [{ id: block.id, kind: "host", name: blockLabel(block), operations: ops.map((o) => ({ id: o.id, name: o.name, ...o.compatibilityDate ? { compatibilityDate: o.compatibilityDate } : {} })) }] : [];
|
|
788
|
+
const childConfigure = ops && ops.length > 0 ? withNodeVar(childBase) : childBase;
|
|
789
|
+
return enterActions(arrayItemBridge(cur.slotBridge, "blocks", id, edge.key), { id: block.id, type: block.type, compatibilityDate: block.compatibilityDate }, blockLabel(block), childConfigure, ownerTargets);
|
|
790
|
+
}
|
|
791
|
+
default:
|
|
792
|
+
return `enter_node: block "${id}" embeds ${edge.host}, which the cursor can't enter yet.`;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
if (cur.enter) return cur.enter(id);
|
|
796
|
+
return `enter_node failed: the current scope (${scope()}) has no further enterable children. Configure it with the listed tools, or call leave_node to go up.`;
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
const leaveNode = {
|
|
800
|
+
name: "leave_node",
|
|
801
|
+
description: "Ascend the scope cursor one level back to the parent scope, re-activating its tool family. Returns the parent breadcrumb and a light recap of its children.",
|
|
802
|
+
inputJsonSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
803
|
+
execute: () => {
|
|
804
|
+
if (frames.length <= 1) {
|
|
805
|
+
return `leave_node: already at the top scope (${scope()}); nothing to leave.`;
|
|
806
|
+
}
|
|
807
|
+
const left = frames.pop();
|
|
808
|
+
const parent = current();
|
|
809
|
+
const recap = { scope: scope(), left: left.label, backTo: parent.label };
|
|
810
|
+
if (parent.slotBridge) {
|
|
811
|
+
const slot = parent.slotBridge.read();
|
|
812
|
+
const blocks = slot?.blocks ?? [];
|
|
813
|
+
recap.blocks = blocks.map((b) => ({ id: b.id, type: b.type, name: blockLabel(b) }));
|
|
814
|
+
} else if (parent.recap) {
|
|
815
|
+
Object.assign(recap, parent.recap());
|
|
816
|
+
}
|
|
817
|
+
return recap;
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
const genUuidTool = {
|
|
821
|
+
name: "gen_uuid",
|
|
822
|
+
description: 'Mint a fresh UUID from the harness. You almost never need this: the harness assigns every id itself (insert_block / insert_field / insert_button / \u2026 return the id, and configure_button backfills a trigger row that omits one). Call it ONLY when you must author an id you then reference in the same write \u2014 chiefly a trigger row `id` whose step output a LATER row reads via `steps["<id>"]`. Never invent an id yourself (e.g. all-zeros) \u2014 collisions there break the steps address. Returns `{ uuid }`.',
|
|
823
|
+
inputJsonSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
824
|
+
execute: () => ({ uuid: deps.genUuid() })
|
|
825
|
+
};
|
|
826
|
+
function tools() {
|
|
827
|
+
return [...current().family, enterNode, leaveNode, genUuidTool];
|
|
828
|
+
}
|
|
829
|
+
function reset() {
|
|
830
|
+
frames = [pageFrame];
|
|
831
|
+
}
|
|
832
|
+
return { tools, reset, scope };
|
|
833
|
+
}
|