dsh-d365-kit 0.34.1 → 0.34.4

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 (75) hide show
  1. package/CHANGELOG.md +319 -308
  2. package/CHANGELOG.zh-CN.md +318 -307
  3. package/INSTALL.md +94 -94
  4. package/INSTALL.zh-CN.md +93 -93
  5. package/LICENSE +21 -21
  6. package/README.md +336 -327
  7. package/README.zh-CN.md +336 -327
  8. package/client.js +1818 -1818
  9. package/cordis.patch.yml +44 -44
  10. package/docs/en/architecture.md +172 -172
  11. package/docs/en/checks.md +184 -184
  12. package/docs/en/installation.md +151 -151
  13. package/docs/en/permissions.md +161 -161
  14. package/docs/en/scenarios.md +202 -202
  15. package/docs/en/tools.md +665 -665
  16. package/docs/en/troubleshooting.md +131 -131
  17. package/docs/zh/architecture.md +172 -172
  18. package/docs/zh/checks.md +184 -184
  19. package/docs/zh/installation.md +151 -151
  20. package/docs/zh/permissions.md +161 -161
  21. package/docs/zh/scenarios.md +202 -202
  22. package/docs/zh/tools.md +665 -665
  23. package/docs/zh/troubleshooting.md +131 -131
  24. package/examples/prompts.en.md +206 -206
  25. package/examples/prompts.zh-CN.md +206 -206
  26. package/examples/waivers.example.json +20 -20
  27. package/icon.svg +6 -6
  28. package/index.js +139 -139
  29. package/lib/auth.js +181 -181
  30. package/lib/client.js +496 -496
  31. package/lib/code-check.js +549 -549
  32. package/lib/config.js +323 -323
  33. package/lib/contract-history.js +49 -49
  34. package/lib/contract.js +583 -583
  35. package/lib/csharp-check.js +493 -493
  36. package/lib/data-migrate.js +1318 -1318
  37. package/lib/data-policy.js +78 -78
  38. package/lib/error-codes.js +80 -80
  39. package/lib/gitlab.js +161 -161
  40. package/lib/health.js +205 -205
  41. package/lib/migrate.js +732 -732
  42. package/lib/preflight.js +116 -116
  43. package/lib/refs.js +191 -191
  44. package/lib/resources.js +320 -320
  45. package/lib/retention-defaults.js +17 -17
  46. package/lib/retention.js +384 -384
  47. package/lib/runtime.js +232 -232
  48. package/lib/settings-http.js +512 -512
  49. package/lib/settings-store.js +371 -371
  50. package/lib/snapshot.js +149 -149
  51. package/lib/tool-code-check.js +133 -133
  52. package/lib/tool-configure.js +169 -169
  53. package/lib/tool-contract.js +376 -376
  54. package/lib/tool-data-sync.js +559 -559
  55. package/lib/tool-data-write.js +203 -203
  56. package/lib/tool-data.js +282 -282
  57. package/lib/tool-diff.js +484 -484
  58. package/lib/tool-environments.js +106 -106
  59. package/lib/tool-flows.js +540 -540
  60. package/lib/tool-health.js +127 -127
  61. package/lib/tool-layers.js +497 -497
  62. package/lib/tool-metadata.js +417 -417
  63. package/lib/tool-migrate.js +102 -102
  64. package/lib/tool-refs.js +206 -206
  65. package/lib/tool-reports.js +299 -299
  66. package/lib/tool-sync.js +430 -430
  67. package/lib/tool-write.js +563 -563
  68. package/lib/waivers.js +83 -83
  69. package/lib/write-actions.js +1374 -1374
  70. package/lib/write-policy.js +199 -199
  71. package/lib/write-store.js +167 -167
  72. package/locale/en.json +68 -68
  73. package/locale/zh.json +68 -68
  74. package/package.json +2 -2
  75. package/skills/d365-troubleshooting/SKILL.md +115 -115
@@ -1,202 +1,202 @@
1
- # Usage Scenarios
2
-
3
- **English** | [简体中文](../zh/scenarios.md)
4
-
5
- Everything below can be said to the agent as-is. Tool arguments are in brackets; the agent fills them in itself.
6
-
7
- ---
8
-
9
- ## 1. Taking over an environment: get the lay of the land
10
-
11
- ```
12
- Connect to all four environments and see what each one is doing.
13
- ```
14
-
15
- ```
16
- d365_envs check=true
17
- d365_health allEnvironments=true hours=24
18
- d365_metadata resource=organization
19
- d365_metadata resource=solutions top=10 orderby="installedon desc"
20
- ```
21
-
22
- What you get: whether each environment is reachable, its org version, hung/failed jobs, imports and publishes in progress, and what was installed recently.
23
-
24
- This is the first step before answering any "does the environment have X" — it keeps you from mistaking "not configured" for "not present in the environment".
25
-
26
- ---
27
-
28
- ## 2. Can this field be deleted?
29
-
30
- ```
31
- Which forms, views, and workflows still use contoso_customertier on account? Also check how many records still carry a value.
32
- ```
33
-
34
- ```
35
- d365_refs kind=field entity=account attribute=contoso_customertier allEnvironments=true
36
- d365_data action=group entity=account field=contoso_customertier top=10
37
- d365_layers component=contoso_customertier componentType=Attribute entity=account
38
- ```
39
-
40
- Three pieces of evidence together:
41
-
42
- - **References**: 17 forms, 64 views (62 columns / 50 filters), 0 workflows/business rules;
43
- - **Data**: the distribution of records that have a value for the field (empty is its own bucket);
44
- - **Layers**: who added the field and which solution owns the active layer — if it comes from a managed solution you cannot delete it locally, only the publisher can change it.
45
-
46
- The delete itself is `d365_write action=plan-delete-attribute ... acknowledge=true`, but you usually use these three pieces of evidence to convince people first.
47
-
48
- ---
49
-
50
- ## 3. Why two environments differ
51
-
52
- ```
53
- Sync forms, views, and fields from DEV and SIT, tell me the differences, then explain why the Account form differs.
54
- ```
55
-
56
- ```
57
- d365_sync environments=["dev","sit"] resources=["forms","views","solutions"] includeAttributes=true entities=["account"]
58
- d365_diff base=dev head=sit resources=["forms","views","attributes"]
59
- d365_layers component=Account componentType=SystemForm allEnvironments=true
60
- ```
61
-
62
- `d365_diff` gives the mechanical difference (which rows were added/removed, which fields changed); `d365_layers` gives the reason (who overrode it, who sits on top).
63
-
64
- Noise is already handled: timestamps and `*id` columns are not compared, and `organization` is skipped by default. When form content differs a lot, the field-level diff in the report reads far better than a wall of XML.
65
-
66
- ---
67
-
68
- ## 4. Assessing a solution before release
69
-
70
- ```
71
- What are the risks of shipping ContosoBase from DEV to SIT and UAT?
72
- ```
73
-
74
- ```
75
- d365_migrate action=assess source=dev solution=ContosoBase targets=["sit","uat"]
76
- ```
77
-
78
- The report answers:
79
-
80
- - whether the targets have this solution, and whether the source version is newer;
81
- - who owns the top layer of each component in the target, and which solutions' definitions get shadowed after import (shadowed solutions are listed, sorted by component count);
82
- - whether option set values will be lost (a value the source has and the target lacks = critical; mismatched labels = warning);
83
- - which components the target is missing;
84
- - when the source is unmanaged, the layer the import creates cannot be cleared by uninstalling a solution.
85
-
86
- A real case: for a solution holding just 1 global option set, the assessment can come back as "0 critical, 2 warnings, but it will invalidate the definitions of 7 solutions" — the decision that actually matters is not about losing data, it is that **the next time anyone imports a Contoso patch, that layer gets covered again**.
87
-
88
- ---
89
-
90
- ## 5. Checking whether an MR can ship to UAT
91
-
92
- ```
93
- https://gitlab.example.com/contoso/powerapps/-/merge_requests/7759/diffs will this MR cause problems if it goes to UAT?
94
- ```
95
-
96
- ```
97
- d365_code_check mergeRequest="https://gitlab.example.com/contoso/powerapps/-/merge_requests/7759/diffs" targets=["uat"]
98
- ```
99
-
100
- Three sections come out:
101
-
102
- - **Blockers**: a field is on none of the forms that load the library, an entity does not exist, a deleted function is still referenced by a handler, a C# type/step/image is missing;
103
- - **Warnings**: a field is only on some forms, the assembly version was not bumped, a hard-coded GUID;
104
- - **Manual confirmation**: configuration data, secure configuration, privileges, ambiguity between a column name and a plain key.
105
-
106
- The report is at `.d365/reports/code-check-<MR>-<timestamp>.md`.
107
-
108
- C#-only MRs work too: infer the assembly from the project directory → exact match → look up types/steps/images/filtering attributes. Assembly names are matched exactly only; guessing wrong is worse than not checking.
109
-
110
- ---
111
-
112
- ## 6. Filling in a batch of option values
113
-
114
- ```
115
- contoso_taxcategoryos is still missing 36 tax registration number types; add them to DEV from the list in .d365/reports.
116
- ```
117
-
118
- ```
119
- d365_write action=plan-add-options environment=dev optionSet=contoso_taxcategoryos \
120
- labels=["AD3|Andorra: Tax Register Number (NRT)", "..."]
121
- ```
122
-
123
- The plan returns the list of operations (values continue from the current maximum +1; codes that already exist go into skipped). Once checked:
124
-
125
- ```
126
- Run mw04aul6-1ci6aa
127
- ```
128
-
129
- A card pops up in the conversation → approve → write → publish only this option set. The audit trail is in `.d365/changes/`, the publish result in `.d365/changes/publish-<planId>.json`.
130
-
131
- **Do not append them by hand in the remaining environments**: let them ride along with the solution import, otherwise the next time someone imports a managed patch your hand-added layer gets covered.
132
-
133
- ---
134
-
135
- ## 7. Upstream changed a plugin — what is downstream missing
136
-
137
- ```
138
- Has SIT and UAT caught up with DEV's plugin registrations? Also check whether any scripts referenced by forms are missing.
139
- ```
140
-
141
- ```
142
- d365_contract action=drift source=dev targets=["sit","uat"] forms=true
143
- ```
144
-
145
- Typical result (real data): 86 findings = 4 missing assemblies, 72 missing plugin steps, 8 missing types, 2 missing form libraries.
146
- `forms=false` skips reading formxml; `handlers=true` downloads scripts to check that the functions exist (slow, up to 400 scripts per environment).
147
-
148
- Register a waiver for differences that are genuinely allowed:
149
-
150
- ```
151
- d365_contract action=waive rule=form-library-missing env=sit \
152
- object="/_static/_common/scripts/CommandbarActions.js" reason="this environment does not use SLA dialogs" days=30
153
- ```
154
-
155
- The next run over the same `source → targets` reports a trend of "N new / M gone".
156
-
157
- ---
158
-
159
- ## 8. Publish is stuck / can I write now
160
-
161
- ```
162
- Is any import or publish running in the four environments right now? I want to change some metadata.
163
- ```
164
-
165
- ```
166
- d365_health allEnvironments=true
167
- ```
168
-
169
- If an environment has a `Publish` or an import in progress, any write gets `0x80071151` or waits until the lock times out. Wait for it to finish; `d365_write execute` checks this step itself and refuses outright when the environment is busy instead of throwing a raw 429.
170
-
171
- Only use `force: true` once you have confirmed that record is a leftover (for example, an import that was interrupted days ago).
172
-
173
- ---
174
-
175
- ## 9. Disk is bloated by artifacts
176
-
177
- ```
178
- How big is .d365 now? What can be cleaned up?
179
- ```
180
-
181
- ```
182
- d365_reports action=list
183
- d365_reports action=cleanup target=query # dry run only by default
184
- d365_reports action=cleanup target=query dryRun=false
185
- d365_reports action=compact # compact snapshot JSON to one line
186
- ```
187
-
188
- Real data: four full snapshots take about 540 MB, and compacting to one line saves 68 MB; within a single snapshot, `plugin_steps.json` is about 55 MB, `solution_components.json` about 39 MB, and `web_resources.json` about 20 MB.
189
-
190
- For the retention policy and automatic cleanup, see [tools.md](tools.md#d365_reports) and the [root README](../../README.md).
191
-
192
- ---
193
-
194
- ## Combined usage
195
-
196
- | Question | Combination |
197
- | --- | --- |
198
- | Is it safe to change this field | `d365_refs` + `d365_data` + `d365_layers` |
199
- | Can this version ship | `d365_health` + `d365_migrate` + `d365_contract` |
200
- | Can this MR merge | `d365_code_check` + `d365_refs` |
201
- | Where do the environments differ | `d365_sync` + `d365_diff` + `d365_layers` |
202
- | Why does it fail at runtime | `d365_refs` (field/script references) + `d365_layers` (who overrides) + `d365_health` (jobs) |
1
+ # Usage Scenarios
2
+
3
+ **English** | [简体中文](../zh/scenarios.md)
4
+
5
+ Everything below can be said to the agent as-is. Tool arguments are in brackets; the agent fills them in itself.
6
+
7
+ ---
8
+
9
+ ## 1. Taking over an environment: get the lay of the land
10
+
11
+ ```
12
+ Connect to all four environments and see what each one is doing.
13
+ ```
14
+
15
+ ```
16
+ d365_envs check=true
17
+ d365_health allEnvironments=true hours=24
18
+ d365_metadata resource=organization
19
+ d365_metadata resource=solutions top=10 orderby="installedon desc"
20
+ ```
21
+
22
+ What you get: whether each environment is reachable, its org version, hung/failed jobs, imports and publishes in progress, and what was installed recently.
23
+
24
+ This is the first step before answering any "does the environment have X" — it keeps you from mistaking "not configured" for "not present in the environment".
25
+
26
+ ---
27
+
28
+ ## 2. Can this field be deleted?
29
+
30
+ ```
31
+ Which forms, views, and workflows still use contoso_customertier on account? Also check how many records still carry a value.
32
+ ```
33
+
34
+ ```
35
+ d365_refs kind=field entity=account attribute=contoso_customertier allEnvironments=true
36
+ d365_data action=group entity=account field=contoso_customertier top=10
37
+ d365_layers component=contoso_customertier componentType=Attribute entity=account
38
+ ```
39
+
40
+ Three pieces of evidence together:
41
+
42
+ - **References**: 17 forms, 64 views (62 columns / 50 filters), 0 workflows/business rules;
43
+ - **Data**: the distribution of records that have a value for the field (empty is its own bucket);
44
+ - **Layers**: who added the field and which solution owns the active layer — if it comes from a managed solution you cannot delete it locally, only the publisher can change it.
45
+
46
+ The delete itself is `d365_write action=plan-delete-attribute ... acknowledge=true`, but you usually use these three pieces of evidence to convince people first.
47
+
48
+ ---
49
+
50
+ ## 3. Why two environments differ
51
+
52
+ ```
53
+ Sync forms, views, and fields from DEV and SIT, tell me the differences, then explain why the Account form differs.
54
+ ```
55
+
56
+ ```
57
+ d365_sync environments=["dev","sit"] resources=["forms","views","solutions"] includeAttributes=true entities=["account"]
58
+ d365_diff base=dev head=sit resources=["forms","views","attributes"]
59
+ d365_layers component=Account componentType=SystemForm allEnvironments=true
60
+ ```
61
+
62
+ `d365_diff` gives the mechanical difference (which rows were added/removed, which fields changed); `d365_layers` gives the reason (who overrode it, who sits on top).
63
+
64
+ Noise is already handled: timestamps and `*id` columns are not compared, and `organization` is skipped by default. When form content differs a lot, the field-level diff in the report reads far better than a wall of XML.
65
+
66
+ ---
67
+
68
+ ## 4. Assessing a solution before release
69
+
70
+ ```
71
+ What are the risks of shipping ContosoBase from DEV to SIT and UAT?
72
+ ```
73
+
74
+ ```
75
+ d365_migrate action=assess source=dev solution=ContosoBase targets=["sit","uat"]
76
+ ```
77
+
78
+ The report answers:
79
+
80
+ - whether the targets have this solution, and whether the source version is newer;
81
+ - who owns the top layer of each component in the target, and which solutions' definitions get shadowed after import (shadowed solutions are listed, sorted by component count);
82
+ - whether option set values will be lost (a value the source has and the target lacks = critical; mismatched labels = warning);
83
+ - which components the target is missing;
84
+ - when the source is unmanaged, the layer the import creates cannot be cleared by uninstalling a solution.
85
+
86
+ A real case: for a solution holding just 1 global option set, the assessment can come back as "0 critical, 2 warnings, but it will invalidate the definitions of 7 solutions" — the decision that actually matters is not about losing data, it is that **the next time anyone imports a Contoso patch, that layer gets covered again**.
87
+
88
+ ---
89
+
90
+ ## 5. Checking whether an MR can ship to UAT
91
+
92
+ ```
93
+ https://gitlab.example.com/contoso/powerapps/-/merge_requests/7759/diffs will this MR cause problems if it goes to UAT?
94
+ ```
95
+
96
+ ```
97
+ d365_code_check mergeRequest="https://gitlab.example.com/contoso/powerapps/-/merge_requests/7759/diffs" targets=["uat"]
98
+ ```
99
+
100
+ Three sections come out:
101
+
102
+ - **Blockers**: a field is on none of the forms that load the library, an entity does not exist, a deleted function is still referenced by a handler, a C# type/step/image is missing;
103
+ - **Warnings**: a field is only on some forms, the assembly version was not bumped, a hard-coded GUID;
104
+ - **Manual confirmation**: configuration data, secure configuration, privileges, ambiguity between a column name and a plain key.
105
+
106
+ The report is at `.d365/reports/code-check-<MR>-<timestamp>.md`.
107
+
108
+ C#-only MRs work too: infer the assembly from the project directory → exact match → look up types/steps/images/filtering attributes. Assembly names are matched exactly only; guessing wrong is worse than not checking.
109
+
110
+ ---
111
+
112
+ ## 6. Filling in a batch of option values
113
+
114
+ ```
115
+ contoso_taxcategoryos is still missing 36 tax registration number types; add them to DEV from the list in .d365/reports.
116
+ ```
117
+
118
+ ```
119
+ d365_write action=plan-add-options environment=dev optionSet=contoso_taxcategoryos \
120
+ labels=["AD3|Andorra: Tax Register Number (NRT)", "..."]
121
+ ```
122
+
123
+ The plan returns the list of operations (values continue from the current maximum +1; codes that already exist go into skipped). Once checked:
124
+
125
+ ```
126
+ Run mw04aul6-1ci6aa
127
+ ```
128
+
129
+ A card pops up in the conversation → approve → write → publish only this option set. The audit trail is in `.d365/changes/`, the publish result in `.d365/changes/publish-<planId>.json`.
130
+
131
+ **Do not append them by hand in the remaining environments**: let them ride along with the solution import, otherwise the next time someone imports a managed patch your hand-added layer gets covered.
132
+
133
+ ---
134
+
135
+ ## 7. Upstream changed a plugin — what is downstream missing
136
+
137
+ ```
138
+ Has SIT and UAT caught up with DEV's plugin registrations? Also check whether any scripts referenced by forms are missing.
139
+ ```
140
+
141
+ ```
142
+ d365_contract action=drift source=dev targets=["sit","uat"] forms=true
143
+ ```
144
+
145
+ Typical result (real data): 86 findings = 4 missing assemblies, 72 missing plugin steps, 8 missing types, 2 missing form libraries.
146
+ `forms=false` skips reading formxml; `handlers=true` downloads scripts to check that the functions exist (slow, up to 400 scripts per environment).
147
+
148
+ Register a waiver for differences that are genuinely allowed:
149
+
150
+ ```
151
+ d365_contract action=waive rule=form-library-missing env=sit \
152
+ object="/_static/_common/scripts/CommandbarActions.js" reason="this environment does not use SLA dialogs" days=30
153
+ ```
154
+
155
+ The next run over the same `source → targets` reports a trend of "N new / M gone".
156
+
157
+ ---
158
+
159
+ ## 8. Publish is stuck / can I write now
160
+
161
+ ```
162
+ Is any import or publish running in the four environments right now? I want to change some metadata.
163
+ ```
164
+
165
+ ```
166
+ d365_health allEnvironments=true
167
+ ```
168
+
169
+ If an environment has a `Publish` or an import in progress, any write gets `0x80071151` or waits until the lock times out. Wait for it to finish; `d365_write execute` checks this step itself and refuses outright when the environment is busy instead of throwing a raw 429.
170
+
171
+ Only use `force: true` once you have confirmed that record is a leftover (for example, an import that was interrupted days ago).
172
+
173
+ ---
174
+
175
+ ## 9. Disk is bloated by artifacts
176
+
177
+ ```
178
+ How big is .d365 now? What can be cleaned up?
179
+ ```
180
+
181
+ ```
182
+ d365_reports action=list
183
+ d365_reports action=cleanup target=query # dry run only by default
184
+ d365_reports action=cleanup target=query dryRun=false
185
+ d365_reports action=compact # compact snapshot JSON to one line
186
+ ```
187
+
188
+ Real data: four full snapshots take about 540 MB, and compacting to one line saves 68 MB; within a single snapshot, `plugin_steps.json` is about 55 MB, `solution_components.json` about 39 MB, and `web_resources.json` about 20 MB.
189
+
190
+ For the retention policy and automatic cleanup, see [tools.md](tools.md#d365_reports) and the [root README](../../README.md).
191
+
192
+ ---
193
+
194
+ ## Combined usage
195
+
196
+ | Question | Combination |
197
+ | --- | --- |
198
+ | Is it safe to change this field | `d365_refs` + `d365_data` + `d365_layers` |
199
+ | Can this version ship | `d365_health` + `d365_migrate` + `d365_contract` |
200
+ | Can this MR merge | `d365_code_check` + `d365_refs` |
201
+ | Where do the environments differ | `d365_sync` + `d365_diff` + `d365_layers` |
202
+ | Why does it fail at runtime | `d365_refs` (field/script references) + `d365_layers` (who overrides) + `d365_health` (jobs) |