关于 edit-offline-profile
面向 Microsoft Dataverse 离线配置维护者的技能,可对现有配置进行单项编辑,而无需重走完整设置流程。它支持调整表范围、列、同步频率及配置名称或说明,并在应用更改前展示差异。
主要功能
- 01编辑表的数据范围
- 02添加或移除所选列
- 03调整同步频率
- 04重命名配置或修改说明
- 05应用前展示变更差异
适用场景
- 01修改表的离线数据范围
- 02更新配置中的列清单
- 03调整表的同步间隔
- 04更改配置名称或说明
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ power-platform-skills --skill edit-offline-profile安装后在 Claude Code 中输入/edit-offline-profile确认已加载。
详细介绍
共享指令:shared-instructions.md — 请先阅读。
参考资料:
- dataverse-offline-api.md §4 / §7 — POST 项目 + PATCH selectedcolumns
- offline-profile-reconciliation.md — 列编辑后刷新
schemaColumns基线
编辑离线配置文件
重新执行现有配置文件中的单项操作——更改某个表的行范围、更新列列表、调整同步频率或重命名配置文件。无需为了只改一行而完整走一遍 /setup-offline-profile 向导,从而避免认知负担。
范围:现有配置文件(从 <working_dir>/offline-profile.json 或
--profile-id 读取);编辑粒度为表项。若要添加新表,请返回所有者并使用
/add-table-to-offline-profile;删除整个配置文件不属于此辅助工具的范围,也不会自动执行恢复。
调用上下文与根目录绑定
此内部辅助工具始终作为子调用执行。在读取任何项目内容或运行任何命令之前,
执行 app-working-directory.md。
必须提供所有者的绝对 working_dir;若提供了 --working-dir,则必须指向同一个本机规范根目录。缺少根目录上下文、路径为相对路径或根目录上下文冲突时,须在访问项目之前返回 NEEDS_CONTEXT;无法访问目录时返回 BLOCKED。不得使用启动时的工作目录,也不得引入其他根目录解析器。
接收来自所有者的 MOBILE_APP_ORCHESTRATING=1、orchestrator、working_dir、phase、approved_scope 和已提供的答案。保留选定的环境 ID/URL/租户、配置文件 ID、表允许列表、项目 ID,以及确切的范围/列/同步/名称/描述更改。范围缺失或冲突时返回 NEEDS_CONTEXT,不得另行选择环境/配置文件/表。此标记不代表已获批准:仅批准架构并不授权编辑配置文件、发布、删除或编辑成员关系。除非已提供的答案已批准同一项当前离线更改,否则保留步骤 3 的单次确认。
对于 --plan-only 或规划阶段移交,在只读发现后返回当前与提议之间的差异,并在 Apply、PATCH、发布或写入工件之前停止。门控响应不能解除仅提议模式。
将规范合约应用于每一次 Shell 调用和文件工具调用,包括版本/身份验证检查、清单/屏幕读取、从参考资料复制的命令、验证、恢复和重试。每次调用都重新提供绝对路径 PLUGIN_ROOT 和必需的上下文;之前的 cd、导出或 Shell 变量不会保留。使用下方规范 Bash 防护,或其 PowerShell 等效项。将占位符替换为经过验证且经过 Shell 转义的调用值;缺少值时返回 NEEDS_CONTEXT,绝不得执行未解析的占位符。
文件工具使用绝对 <working_dir>/... 路径;插件读取/脚本使用 ${PLUGIN_ROOT}/...。文件缺失时,绝不得搜索其他应用。
工作流
- 验证项目 + 定位配置文件 → 2. 确定目标(要更改哪个表 / 更改什么)→ 3. 显示当前值与提议值 → 单次确认 → 4. PATCH → 5. 发布 → 6. 更新工件 → 7. 总结
步骤 1 — 验证项目并定位配置文件
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
if [ ! -f power.config.json ] || [ ! -f app.config.js ]; then
echo "BLOCKED: working_dir is not an initialized app" >&2
exit 1
fi
读取 <working_dir>/power.config.json,并要求其中的 environmentId 非空且与所有者选定的环境匹配。重用匹配的完整环境上下文,或从绑定的根目录执行以下非持久化查询:
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
environment_id=$(node -p "require('./power.config.json').environmentId || ''") || {
echo "BLOCKED: unreadable power.config.json" >&2; exit 1;
}
if [ -z "$environment_id" ] || [ "$environment_id" != "<selected-environment-id>" ]; then
echo "NEEDS_CONTEXT: selected environment does not match working_dir" >&2
exit 1
fi
node "${PLUGIN_ROOT}/scripts/resolve-environment.js" "$environment_id" --no-cache --require-tenant
要求返回的环境 ID、HTTPS URL 和租户与所有者的信息匹配;上下文不完整或冲突时,返回 NEEDS_CONTEXT。绝不能删除 --no-cache --require-tenant、更改配置,或切换身份验证方式/环境来恢复失败。所有请求都使用确切的 <envUrl> 和 <tenantId>。
配置文件 ID 的解析方式(与 /assign-offline-profile 步骤 1 的优先级相同):
| 来源 | 使用条件 |
|---|---|
$ARGUMENTS --profile-id <guid> | 显式选择,且与所有者的配置文件上下文匹配 |
<working_dir>/offline-profile.json 顶层的 profileId | /setup-offline-profile 创建的项目的默认值,且与所有者的配置文件上下文匹配 |
| 否则 | 返回 NEEDS_CONTEXT,请所有者选择预期配置文件;绝不能悄悄选择其他配置文件 |
如果未找到配置文件,立即停止:"请先运行 /setup-offline-profile。"
验证所选的实时配置文件属于所选环境。快照/参数冲突时返回 NEEDS_CONTEXT;404 或权限失败属于 BLOCKED,不能因此改为查找其他配置文件。仅在此配置文件中解析每个 <itemId>,并验证其表与请求的确切逻辑名称相符。
故意不读取
<working_dir>/power.config.json中的配置文件 ID。 该文件由pa app init管理。本地配置文件 ID 仅位于<working_dir>/offline-profile.json中。
步骤 2 — 解析目标(要编辑的内容)
解析 $ARGUMENTS:
| 标志模式 | 效果 |
|---|---|
--rename <new-name> | 更新配置文件 name |
--describe <text> | 更新配置文件 description |
--table <logical-name> --scope <0|1|2> | 更改一个表的 recorddistributioncriteria。当 scope=2 时,结合 --me、--team、--bu 设置子标志。 |
--table <logical-name> --sync <minutes> | 更改一个表的 syncintervalinminutes(范围 5–1440) |
--table <logical-name> --columns add:col1,col2 remove:col3 | 在 selectedcolumns 中添加或移除逻辑名称。以逗号分隔,add/remove 均可选。 |
--table <logical-name> --columns reset | 将 selectedcolumns 替换为始终包含的列、清单查找列和从屏幕内容中 grep 出的列的并集(对该表重新运行架构师步骤 6 中的并集计算) |
如果没有标志 → 显示交互式选择器。使用 AskUserQuestion,列出最多 4 个最可能的编辑项:
- “重命名配置文件”
- “更改表的范围” → 下一条消息询问要更改哪个表
- “更改表的同步频率” → 下一条消息询问表名和值
- “编辑表的列列表” → 下一条消息询问表名以及要添加/移除的列
将选择器和显式标志限制在所有者当前的确切范围内。
--columns reset 从
<working_dir>/.datamodel-manifest.json 或
<working_dir>/docs/plan-artifacts/.datamodel-manifest.json 读取所选表,并且只对绝对路径 <working_dir>/app/ 和 <working_dir>/src/ 执行 grep。整个调用期间保留选定的绝对清单路径;不得回退到其他应用。更改表、配置文件或操作时,应向所有者返回 NEEDS_CONTEXT,而不是扩大现有审批范围。
步骤 3 — 显示当前值与拟议值(单一审批关卡)
对于要编辑的任何表,从 Dataverse 获取当前项目状态:
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "<envUrl>" GET \
"mobileofflineprofileitems(<itemId>)?\$select=name,recorddistributioncriteria,recordsownedbyme,recordsownedbymyteam,recordsownedbymybusinessunit,syncintervalinminutes,selectedcolumns" \
--tenant-id "<tenantId>"
呈现当前值/拟议值差异:
Profile : <name> (<id>)
Editing : <table-logical-name> item
Current → Proposed
Scope : Org+me → All records
Sync (min) : 10 → 30
Columns : 14 → 16 (add: chnl_notes, chnl_actual_visit_date)
AskUserQuestion:“应用此更改?[Apply / Cancel]”
如果选择 Apply → 继续。如果选择 Cancel → 停止。
步骤 4 — PATCH
构建 PATCH 请求正文,只包含发生变化的字段:
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "<envUrl>" PATCH \
"mobileofflineprofileitems(<itemId>)" --tenant-id "<tenantId>" \
--body '{
"recorddistributioncriteria": <new>,
"recordsownedbyme": <new-bool>,
"syncintervalinminutes": <new>,
"selectedcolumns": "{\"Columns\":[...]}"
}'
对于配置文件级别的编辑(name / description):
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "<envUrl>" PATCH \
"mobileofflineprofiles(<profileId>)" --tenant-id "<tenantId>" \
--body '{"name": "...", "description": "..."}'
除检查进程退出状态外,还要检查返回的 HTTP 状态码。403/PrivilegeCheckFailed 属于 BLOCKED;不得更改身份或配置文件以绕过权限。保留已批准变更范围之外的所有字段和表。
步骤 5 — 发布
使用 shared/references/dataverse-offline-api.md §9 中的**定向 PublishXml**方案:
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "<envUrl>" POST \
"PublishXml" --tenant-id "<tenantId>" --body '{
"ParameterXml": "<publish><mobileofflineprofiles><mobileofflineprofile><profileId></mobileofflineprofile></mobileofflineprofiles></publish>"
}'
仅发布此配置文件,而不发布整个组织的自定义项。可避免旧版 PublishAllXml 在共享环境中引发的 429 速率限制风暴。
遇到 400 / 0x80071141“循环关系”错误时,按 /setup-offline-profile 步骤 8 的方式处理(解析循环路径,提示用户移除一个关联,然后重试)。仅当 PublishXml 返回循环错误之外的意外错误,且所有者/用户批准扩大发布范围时,才回退到 PublishAllXml;针对配置文件的批准不包括此操作。
所有关联的恢复命令、重新 GET 验证和重试都必须绑定到同一根目录,并传入相同的环境/租户/配置文件/表/项上下文。绝不能在不同的配置文件上重试,也不能绕过权限错误。在步骤 6 之前确认发布已完成。
如果关联方案需要另一个离线助手,先将拟议更改交由所有者批准,然后再读取其绝对路径 ${PLUGIN_ROOT}/skills/<helper>/SKILL.md。转发:
Arguments: --working-dir '<working_dir>' --profile-id "<profileId>" --table "<table>" <exact-approved-change-flags>
Context: MOBILE_APP_ORCHESTRATING=1, orchestrator, working_dir, phase, approved_scope,
selected environment ID/URL/tenant, profile ID, table allowlist, item ID,
supplied answers, --plan-only (if present)
接收方必须遵循相同的规范根目录约定。缺少上下文时返回 NEEDS_CONTEXT;不要回退到直接调用或重新发现。
步骤 6 — 更新产物
在同一配置文件/环境中重新读取已更改的项,并重写 <working_dir>/offline-profile.json 中对应的条目。如果编辑更改了表的列(--columns add:/remove:/reset),还要根据绑定的绝对清单,将该条目的 schemaColumns 更新为表当前的完整列集。这会为下一次运行 ${PLUGIN_ROOT}/scripts/offline-profile-delta.js 重新设定架构协调标记;仅更改范围/同步/重命名时,不要改动 schemaColumns。任何差异检查都必须在单独的受保护调用中使用 --project-root '<working_dir>'。请参阅 offline-profile-reconciliation.md。
在 <working_dir>/memory-bank.md 的 ## Offline profile 区块中追加一行记录:
edits:
- { at: 2026-05-19T..., field: 'chnl_storevisit.syncintervalinminutes', from: 5, to: 10 }
步骤 7 — 总结
✓ Edited profile.
Field : chnl_storevisit.syncintervalinminutes
From : 5 min
To : 10 min
Published: 2026-05-19T...
offline-profile.json + memory-bank.md updated.
状态代码(最后一行)
DONE— 已应用并发布更改DONE_WITH_CONCERNS: <list>— 已应用更改,但存在注意事项(例如发布超时后最终成功)NEEDS_CONTEXT: <missing>— 无法确定目标表或配置文件BLOCKED: <reason>— 身份验证或 PATCH 失败
此技能不会执行的操作
- 向配置文件添加新表 → 使用
/add-table-to-offline-profile - 添加新关联(关系包含项)→ v0.2 的
selectedrelationshipsschema工作尚未完成,因此受阻;暂时使用 maker portal - 删除整个配置文件 → 手动执行
DELETE /mobileofflineprofiles(<id>)(级联删除项和关联);请参阅 dataverse-offline-api.md §11 - 在环境之间迁移配置文件 → 使用
CloneMobileOfflineProfile操作(v0.5 工作)