copilotkit 4.26.0 → 4.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +418 -40
- package/cli-build-info.json +7 -7
- package/index.js +15343 -9085
- package/onboarding/index.json +3 -2
- package/onboarding/prompts/authenticate/start.md +48 -56
- package/onboarding/prompts/conversion/plan.md +3 -3
- package/onboarding/prompts/credentials/finalize-plan.md +42 -29
- package/onboarding/prompts/credentials/plan.md +50 -34
- package/onboarding/prompts/credentials/settle-credentials.md +38 -14
- package/onboarding/prompts/credentials/write-plan.md +122 -47
- package/onboarding/prompts/deployment/choose-local.md +17 -20
- package/onboarding/prompts/deployment/local-evaluation.md +45 -21
- package/onboarding/prompts/fallback/best-effort.md +14 -16
- package/onboarding/prompts/feature/a2ui/implement.md +4 -4
- package/onboarding/prompts/feature/a2ui/plan.md +3 -3
- package/onboarding/prompts/feature/a2ui/proof.md +5 -5
- package/onboarding/prompts/feature/a2ui/start.md +10 -8
- package/onboarding/prompts/feature/channels/implement.md +11 -8
- package/onboarding/prompts/feature/channels/plan.md +15 -7
- package/onboarding/prompts/feature/channels/proof.md +8 -7
- package/onboarding/prompts/feature/channels/start.md +11 -10
- package/onboarding/prompts/feature/chat-suggestions/implement.md +4 -4
- package/onboarding/prompts/feature/chat-suggestions/plan.md +3 -3
- package/onboarding/prompts/feature/chat-suggestions/proof.md +5 -5
- package/onboarding/prompts/feature/chat-suggestions/start.md +10 -8
- package/onboarding/prompts/feature/complete.md +2 -2
- package/onboarding/prompts/feature/learning/implement.md +14 -12
- package/onboarding/prompts/feature/learning/plan.md +4 -4
- package/onboarding/prompts/feature/learning/proof.md +24 -14
- package/onboarding/prompts/feature/learning/start.md +8 -8
- package/onboarding/prompts/feature/open-generative-ui/implement.md +4 -4
- package/onboarding/prompts/feature/open-generative-ui/plan.md +3 -3
- package/onboarding/prompts/feature/open-generative-ui/proof.md +5 -5
- package/onboarding/prompts/feature/open-generative-ui/start.md +10 -8
- package/onboarding/prompts/feature/realtime-sync/implement.md +7 -5
- package/onboarding/prompts/feature/realtime-sync/plan.md +3 -3
- package/onboarding/prompts/feature/realtime-sync/proof.md +5 -5
- package/onboarding/prompts/feature/realtime-sync/start.md +7 -7
- package/onboarding/prompts/feature/rich-threads/implement.md +8 -6
- package/onboarding/prompts/feature/rich-threads/plan.md +3 -3
- package/onboarding/prompts/feature/rich-threads/proof.md +5 -5
- package/onboarding/prompts/feature/rich-threads/start.md +7 -7
- package/onboarding/prompts/feature/stop.md +4 -4
- package/onboarding/prompts/feature/voice/implement.md +4 -4
- package/onboarding/prompts/feature/voice/plan.md +4 -4
- package/onboarding/prompts/feature/voice/proof.md +5 -5
- package/onboarding/prompts/feature/voice/start.md +10 -8
- package/onboarding/prompts/framework/ag2.md +20 -5
- package/onboarding/prompts/framework/agno.md +25 -9
- package/onboarding/prompts/framework/built-in.md +21 -6
- package/onboarding/prompts/framework/claude-sdk-python.md +11 -5
- package/onboarding/prompts/framework/claude-sdk-typescript.md +13 -6
- package/onboarding/prompts/framework/crewai-flows.md +24 -10
- package/onboarding/prompts/framework/custom-ag-ui.md +62 -28
- package/onboarding/prompts/framework/deep-agents.md +26 -9
- package/onboarding/prompts/framework/google-adk.md +18 -5
- package/onboarding/prompts/framework/langgraph-fastapi.md +20 -5
- package/onboarding/prompts/framework/langgraph-python.md +20 -5
- package/onboarding/prompts/framework/langgraph-typescript.md +27 -7
- package/onboarding/prompts/framework/llamaindex.md +24 -8
- package/onboarding/prompts/framework/mastra.md +21 -8
- package/onboarding/prompts/framework/ms-agent-dotnet.md +24 -6
- package/onboarding/prompts/framework/ms-agent-harness-dotnet.md +24 -5
- package/onboarding/prompts/framework/ms-agent-python.md +21 -5
- package/onboarding/prompts/framework/pydantic-ai.md +20 -5
- package/onboarding/prompts/framework/strands-python.md +27 -12
- package/onboarding/prompts/framework/strands-typescript.md +27 -12
- package/onboarding/prompts/frontend/angular.md +4 -4
- package/onboarding/prompts/frontend/nextjs.md +4 -4
- package/onboarding/prompts/frontend/plan.md +21 -13
- package/onboarding/prompts/frontend/react-native.md +3 -3
- package/onboarding/prompts/frontend/react-spa.md +3 -3
- package/onboarding/prompts/frontend/vue.md +3 -3
- package/onboarding/prompts/implementation/build-and-validate.md +27 -20
- package/onboarding/prompts/proof/complete.md +9 -7
- package/onboarding/prompts/proof/oss-baseline.md +9 -6
- package/onboarding/prompts/proof/round-trip.md +18 -20
- package/onboarding/prompts/research/gather.md +38 -10
- package/onboarding/prompts/research/merge.md +3 -3
- package/onboarding/prompts/research/preflight.md +2 -2
- package/onboarding/prompts/research/route.md +10 -4
- package/onboarding/prompts/setup/questions.md +54 -202
- package/onboarding/prompts/starter/clone.md +141 -57
- package/onboarding/prompts/stopped/run-failed.md +5 -3
- package/onboarding/prompts/subagent/create-plan.md +73 -22
- package/onboarding/prompts/subagent/implement-and-validate.md +27 -34
- package/onboarding/prompts/subagent/inspect-repository.md +3 -2
- package/onboarding/prompts/subagent/prove-oss-baseline.md +10 -5
- package/onboarding/prompts/subagent/prove-round-trip.md +46 -54
- package/onboarding/prompts/unsupported/no-validated-path.md +5 -4
- package/package.json +1 -1
- package/release/release-tool.js +19 -2
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Clone a starter
|
|
2
2
|
|
|
3
|
+
First run `npx --prefer-offline --yes copilotkit@4.28.0 onboard setup-answers`. It prints the answers that
|
|
4
|
+
`setup/questions` recorded, even after this conversation lost them: `framework`, `frontend`,
|
|
5
|
+
`vendor`, `project`, `key`, and on the local route `learning`. Take every "recorded" answer
|
|
6
|
+
below from the record, or this conversation when the record lacks it. Do not ask a question
|
|
7
|
+
that either one answers.
|
|
8
|
+
|
|
3
9
|
Use this shortcut only when the repository findings prove that the target project
|
|
4
10
|
directory holds no project yet: no source directory such as `src/`, `app/`, `agent/` or
|
|
5
11
|
`web/`, no dependency manifest such as `package.json` or `pyproject.toml`, and no `.env`.
|
|
@@ -16,7 +22,7 @@ project to use, or to open the coding agent in a new empty folder.
|
|
|
16
22
|
Before you end your turn to wait for the developer, report the pause:
|
|
17
23
|
|
|
18
24
|
```text
|
|
19
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
25
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard checkpoint --phase awaiting-developer
|
|
20
26
|
```
|
|
21
27
|
|
|
22
28
|
Match the selected agent framework and frontend to this table:
|
|
@@ -50,28 +56,27 @@ directory as it is, so a name such as `MyApp` is valid. Do not rename the direct
|
|
|
50
56
|
the shortcut in each of these cases:
|
|
51
57
|
|
|
52
58
|
- The selected pair is not in the table.
|
|
53
|
-
- The developer chose a model vendor whose key is not the Model key of the matched row.
|
|
54
|
-
Each starter runs on the vendor in that column only.
|
|
55
59
|
- The directory name is not valid.
|
|
56
60
|
|
|
57
61
|
Do not run `init`. No command ran, so this is not a failed shortcut. Go back to the
|
|
58
62
|
`## Documentation` section of the frontend prompt you read before this one, and build the
|
|
59
63
|
project from its pages.
|
|
60
64
|
|
|
61
|
-
Use the
|
|
62
|
-
name. A project the developer already has takes `--project` in the command below. Do not ask
|
|
65
|
+
Use the recorded `project` answer. A new project (`project.create`) takes the recorded
|
|
66
|
+
name. A project the developer already has (`project.project`) takes `--project` in the command below. Do not ask
|
|
63
67
|
again.
|
|
64
68
|
|
|
65
|
-
If
|
|
69
|
+
If neither the record nor this conversation holds a project answer, ask here. If the developer did not name a
|
|
66
70
|
project, create one for the app being cloned. This directory is new, so no existing project is already its own: take the project
|
|
67
|
-
name from the target directory name derived above, and ask the
|
|
68
|
-
|
|
71
|
+
name from the target directory name derived above, and ask as the options view of `onboard setup-message` does:
|
|
72
|
+
"Project: **new project "<name>"**", then "Other: another name · a project you already
|
|
73
|
+
have". Do not list the projects in the organization. If no developer answers, use
|
|
69
74
|
the derived name.
|
|
70
75
|
|
|
71
76
|
Only if the developer asks for an existing project, or asks to see the projects they have,
|
|
72
77
|
read the choices:
|
|
73
78
|
|
|
74
|
-
`npx --prefer-offline --yes copilotkit@4.
|
|
79
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 project list --json`
|
|
75
80
|
|
|
76
81
|
Then ask which one to use. Do not order the projects by creation time. If the developer
|
|
77
82
|
already gave this answer, do not ask again. Do not read a secret value. Do not show or
|
|
@@ -80,19 +85,26 @@ store a secret value.
|
|
|
80
85
|
Before you end your turn to wait for the developer, report the pause:
|
|
81
86
|
|
|
82
87
|
```text
|
|
83
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
88
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard checkpoint --phase awaiting-developer
|
|
84
89
|
```
|
|
85
90
|
|
|
86
91
|
## Ask where the model credential lives
|
|
87
92
|
|
|
88
93
|
The starter reads a model credential, and the `init` command below does not ask for one.
|
|
89
|
-
Use the
|
|
90
|
-
`--model-key-file`. An answer of "later" clones without one: the step after the clone pauses
|
|
94
|
+
Use the recorded `key` answer. A named file (`key.file`) goes to
|
|
95
|
+
`--model-key-file`. An answer of "later" (`key.later`) clones without one: the step after the clone pauses
|
|
91
96
|
for the key. Do not ask again.
|
|
92
97
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
When the recorded vendor is not the vendor of the Model key column, `init` copies the
|
|
99
|
+
wrong variable from a key file. An OpenAI-compatible provider counts as another vendor,
|
|
100
|
+
although its key is `OPENAI_API_KEY`. So clone without `--model-key-file` in that case, and
|
|
101
|
+
follow `## Switch the starter to the recorded vendor` after the clone.
|
|
102
|
+
|
|
103
|
+
If neither the record nor this conversation holds a key answer, ask for it now, while the developer is still
|
|
104
|
+
here, and not after the clone. The variable is the Model key column of the row you
|
|
105
|
+
matched. When the recorded vendor is another one, the variable is that vendor's:
|
|
106
|
+
`ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`, `OPENAI_API_KEY` for OpenAI, or `OPENAI_API_KEY`
|
|
107
|
+
for an OpenAI-compatible provider. Do not guess it from the framework name.
|
|
96
108
|
|
|
97
109
|
Ask the developer one question: which file holds that key, or whether they will add it
|
|
98
110
|
themselves after the clone. Asking where a credential lives is not requesting a secret
|
|
@@ -107,7 +119,7 @@ stops the clone. Pass the new file with `--model-key-file`, as for any other key
|
|
|
107
119
|
Before you end your turn to wait for the developer, report the pause:
|
|
108
120
|
|
|
109
121
|
```text
|
|
110
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
122
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard checkpoint --phase awaiting-model-credential
|
|
111
123
|
```
|
|
112
124
|
|
|
113
125
|
A path the developer names is theirs to give, including one outside the project. A path
|
|
@@ -120,7 +132,7 @@ This route skips the plan step that records the path, so record it here, once, b
|
|
|
120
132
|
the clone:
|
|
121
133
|
|
|
122
134
|
```text
|
|
123
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
135
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard classify --starting-state <starting-state> --agent-framework <agent-framework> --frontend <frontend> --model-vendor <model-vendor> --model-vendor-choice <model-vendor-choice>
|
|
124
136
|
```
|
|
125
137
|
|
|
126
138
|
- `<starting-state>`: the starting state the research recorded, usually `empty`.
|
|
@@ -128,7 +140,7 @@ npx --prefer-offline --yes copilotkit@4.26.0 onboard classify --starting-state <
|
|
|
128
140
|
`langgraph-typescript` for `framework/langgraph-typescript`. It is not the Framework ID
|
|
129
141
|
in the table.
|
|
130
142
|
- `<frontend>`: the Frontend column of the matched row, `nextjs` or `angular`.
|
|
131
|
-
- `<model-vendor>`: `openai`, `anthropic`, `google`, or `other`.
|
|
143
|
+
- `<model-vendor>`: `openai`, `anthropic`, `google`, `openai-compatible`, or `other`.
|
|
132
144
|
- `<model-vendor-choice>`: if the developer chose the provider, `developer`. Otherwise,
|
|
133
145
|
`default`.
|
|
134
146
|
|
|
@@ -143,13 +155,15 @@ Do not inspect another entry in the parent directory. Replace each placeholder w
|
|
|
143
155
|
recorded value. Do not run a placeholder as a shell argument. If the path holds a space,
|
|
144
156
|
put it in double quotes.
|
|
145
157
|
|
|
146
|
-
`npx --prefer-offline --yes copilotkit@4.
|
|
158
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 init --dir <absolute-target-directory> --framework <framework-id> --channel none --no-banner --no-key-prompt --create <name> --install`
|
|
147
159
|
|
|
148
160
|
`--dir` is always the absolute path of the target directory. `init` builds the app in that
|
|
149
161
|
directory and gives the app the directory's name. Do not add `--name`: `init` refuses
|
|
150
162
|
`--name` together with `--dir`. Pass the confirmed project name to `--create` only. If the
|
|
151
163
|
developer names an existing project, use `--project <slug-or-id>` instead of
|
|
152
|
-
`--create <name>`. If the
|
|
164
|
+
`--create <name>`. If `init` says that the account already has a project with that name,
|
|
165
|
+
ask the developer for a new name, or which of their projects to use. Do not select the
|
|
166
|
+
existing project until they name it. If the developer asked to skip the dependency install, use
|
|
153
167
|
`--no-install` instead of `--install`. Do not wait for an interactive prompt. Pass every
|
|
154
168
|
answer as a flag. `--no-key-prompt` stops `init` from asking for a model key. The `init`
|
|
155
169
|
output still names each missing key as `Set <VARIABLE> in .env`.
|
|
@@ -164,23 +178,23 @@ the developer for the right path, or run the command again without the flag.
|
|
|
164
178
|
Before you end your turn to wait for the developer, report the pause:
|
|
165
179
|
|
|
166
180
|
```text
|
|
167
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
181
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard checkpoint --phase awaiting-model-credential
|
|
168
182
|
```
|
|
169
183
|
|
|
170
184
|
If you cannot pass the key file to `init`, for example because a sandbox refuses the path,
|
|
171
185
|
clone without `--model-key-file`. Then copy the key from `<target>` with one command:
|
|
172
|
-
`cd <target> && npx --prefer-offline --yes copilotkit@4.
|
|
186
|
+
`cd <target> && npx --prefer-offline --yes copilotkit@4.28.0 onboard credentials --model-key <VARIABLE> --env-path <key-file> --copy-to <env file> --json`.
|
|
173
187
|
`<env file>` is `.env`, or `agent/.env` for the Microsoft Agent Framework Python starter.
|
|
174
188
|
The command writes the key into that file without printing it. If the
|
|
175
189
|
command is refused too, ask the developer to run it. Give them exactly this one line:
|
|
176
|
-
`! cd <target> && npx --prefer-offline --yes copilotkit@4.
|
|
190
|
+
`! cd <target> && npx --prefer-offline --yes copilotkit@4.28.0 onboard credentials --model-key <VARIABLE> --env-path <key-file> --copy-to <env file>`.
|
|
177
191
|
The command needs no input. Without `!`, they run the same command in a terminal.
|
|
178
192
|
Do not write a `sed`, `grep`, or `cat` command to copy the key.
|
|
179
193
|
|
|
180
194
|
Before you end your turn to wait for the developer, report the pause:
|
|
181
195
|
|
|
182
196
|
```text
|
|
183
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
197
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard checkpoint --phase awaiting-model-credential
|
|
184
198
|
```
|
|
185
199
|
|
|
186
200
|
### For a recorded local choice
|
|
@@ -190,22 +204,31 @@ command instead of the hosted command above. Do not ask the project questions ab
|
|
|
190
204
|
Local evaluation creates its own empty project, and `init --local` refuses `--create` and
|
|
191
205
|
`--project`.
|
|
192
206
|
|
|
193
|
-
`npx --prefer-offline --yes copilotkit@4.
|
|
194
|
-
|
|
195
|
-
Use the
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
207
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 init --dir <absolute-target-directory> --framework <framework-id> --channel none --no-banner --no-key-prompt --local --defer-model --install`
|
|
208
|
+
|
|
209
|
+
Use the `learning` answer from the record, or this conversation. Use the default only when
|
|
210
|
+
neither holds one.
|
|
211
|
+
For `learning.later`, keep `--defer-model`. For `learning.file`, replace
|
|
212
|
+
`--defer-model` with `--model-config <learning.file>`. Do not read or print that
|
|
213
|
+
file. The CLI selects the latest stable release. If the developer gave a candidate
|
|
214
|
+
manifest for release testing, add `--candidate <manifest.json>`. Otherwise, do not add it.
|
|
215
|
+
The `--dir`, `--no-install` and `--model-key-file` rules above apply here too.
|
|
216
|
+
|
|
217
|
+
Before `init`, run `npx --prefer-offline --yes copilotkit@4.28.0 onboard local-terms --json`. If `accepted`
|
|
218
|
+
is false, pause here. Give the developer this exact command to run in their own terminal:
|
|
219
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 local accept-terms`. Never accept the agreement yourself.
|
|
220
|
+
Report the pause with
|
|
221
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 onboard checkpoint --phase awaiting-developer`, end your turn,
|
|
222
|
+
and wait for "done". Then run `local-terms` again, and continue only when `accepted` is
|
|
223
|
+
true. A local command that fails with `eula_acceptance_required` comes back to this step.
|
|
224
|
+
|
|
225
|
+
For `learning.guided`, keep `--defer-model`.
|
|
203
226
|
After `init` reports the stack ready:
|
|
204
227
|
|
|
205
228
|
Ask the developer to run this command in their own terminal window, in `<target>`:
|
|
206
229
|
|
|
207
230
|
```text
|
|
208
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
231
|
+
npx --prefer-offline --yes copilotkit@4.28.0 local setup
|
|
209
232
|
```
|
|
210
233
|
|
|
211
234
|
Do not give it as a `!` line, and do not run it yourself. Its guided model prompt needs a
|
|
@@ -214,9 +237,9 @@ changes nothing. The prompt asks for the model and its key, and it saves them pr
|
|
|
214
237
|
On a running stack, it restarts only Learning. Do not ask for a model file.
|
|
215
238
|
|
|
216
239
|
Say that the run continues when they reply or resume this session. Report the pause with
|
|
217
|
-
`npx --prefer-offline --yes copilotkit@4.
|
|
240
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 onboard checkpoint --phase awaiting-model-credential`, end your
|
|
218
241
|
turn, and wait. When the developer replies, run
|
|
219
|
-
`npx --prefer-offline --yes copilotkit@4.
|
|
242
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 local status --json` from `<target>` and read `learning.configuration`.
|
|
220
243
|
|
|
221
244
|
The command installs the local stack, then connects the starter to it. It writes the
|
|
222
245
|
gitignored `.copilotkit/local.json` stack reference and `.copilotkit/project.json` with the
|
|
@@ -236,11 +259,37 @@ Do not rebuild the starter by hand. Then inspect only the generated
|
|
|
236
259
|
paths inside the target directory. Record the files, install result, project connection,
|
|
237
260
|
and validation commands.
|
|
238
261
|
|
|
262
|
+
## Switch the starter to the recorded vendor
|
|
263
|
+
|
|
264
|
+
Each starter reads its model from `COPILOTKIT_AGENT_MODEL`, and `init` sets it to the
|
|
265
|
+
starter's default in the starter's env file. When the recorded `vendor.vendor` is another
|
|
266
|
+
vendor, the clone ran without `--model-key-file`. Switch the starter before you settle its
|
|
267
|
+
key. The Claude Agent SDK starters run only Anthropic, so never switch them. Switch an ADK
|
|
268
|
+
starter only to OpenAI or an OpenAI-compatible provider, and every other starter only to an
|
|
269
|
+
OpenAI-compatible provider: this release does not run them on Anthropic or Google. If the
|
|
270
|
+
recorded vendor is Anthropic or Google on such a starter, do not switch: say that this
|
|
271
|
+
release supports the row's vendors on that framework, that Anthropic and Google come in a
|
|
272
|
+
later release, and offer the Built-in CopilotKit agent if they need them now.
|
|
273
|
+
|
|
274
|
+
1. Set `COPILOTKIT_AGENT_MODEL` in the starter's env file to the recorded vendor and a
|
|
275
|
+
model that the vendor serves to a new key today: `openai:<model>` on an ADK starter.
|
|
276
|
+
Do not change the starter's code.
|
|
277
|
+
2. For an OpenAI-compatible provider, set `COPILOTKIT_AGENT_MODEL` to
|
|
278
|
+
`openai:<vendor.modelId>`, and `OPENAI_BASE_URL` to `vendor.baseUrl`.
|
|
279
|
+
3. If the developer named a key file, copy the key with the `onboard credentials
|
|
280
|
+
--model-key <VARIABLE> --env-path <key-file> --copy-to <env file> --json` command above,
|
|
281
|
+
with the recorded vendor's variable. Otherwise the next section pauses for it.
|
|
282
|
+
|
|
283
|
+
For the Microsoft Agent Framework .NET starter, set these values with
|
|
284
|
+
`dotnet user-secrets set` from the agent directory, because .NET does not read the env
|
|
285
|
+
file. In the next section, check the recorded vendor's variable in place of the Model key
|
|
286
|
+
column's.
|
|
287
|
+
|
|
239
288
|
## Settle the model credential
|
|
240
289
|
|
|
241
290
|
The `init` output names each key it copied from a key file as
|
|
242
|
-
`Copied <VARIABLE> from the model key file into <file>`. A copied key is in place, so
|
|
243
|
-
|
|
291
|
+
`Copied <VARIABLE> from the model key file into <file>`. A copied key is in place, so it
|
|
292
|
+
needs no `grep` check. If the key file did not hold a variable, the output warns by name.
|
|
244
293
|
|
|
245
294
|
The `init` output names each missing credential as `Set <VARIABLE> in .env`. For each
|
|
246
295
|
one, check the starter's own `.env` without reading the value:
|
|
@@ -252,54 +301,88 @@ grep -c '^<VARIABLE>=.' <target>/.env
|
|
|
252
301
|
`1` means the variable holds a value. `0` means it is empty or absent. The command prints
|
|
253
302
|
a count and never the value.
|
|
254
303
|
|
|
255
|
-
If a variable is empty,
|
|
304
|
+
If a variable is empty, run
|
|
305
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 onboard credentials --model-key <VARIABLE> --json` from
|
|
306
|
+
`<target>`, and show the developer `question.ask` word for word. It names the file by its
|
|
307
|
+
full path and the line to add. If they reply with the path of a file that holds the key, run
|
|
308
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 onboard credentials --model-key <VARIABLE> --env-path <file> --copy-to <question.envFile> --json`
|
|
309
|
+
from `<target>`. Ask nothing else first. Quote a path that holds a space. The command copies
|
|
310
|
+
the key without printing it. When it reports `ready`, the key is in `question.envFile`. Run
|
|
311
|
+
the check above again, and continue. Follow this paragraph, not the packet's `next`, which is
|
|
312
|
+
written for an existing app that copies the key only after its plan.
|
|
313
|
+
|
|
314
|
+
A local server needs no key. That is a server such as Ollama or LM Studio, with
|
|
315
|
+
`OPENAI_BASE_URL` on `localhost`, `127.0.0.1` or `::1` in `<target>/.env`. A local base
|
|
316
|
+
URL that only your shell sets does not count, because it can be your own proxy. When
|
|
317
|
+
`<target>/.env` sets that base URL and the developer said it needs no key, do not ask for
|
|
318
|
+
one. Write `OPENAI_API_KEY=not-needed` to the file that the key goes in. The OpenAI SDKs
|
|
319
|
+
refuse an empty key, and a local server ignores the value. Write no other stand-in value.
|
|
256
320
|
|
|
257
321
|
The two Microsoft Agent Framework starters keep their key outside `<target>/.env`, so
|
|
258
322
|
`init` prints no `Set` line for them. Settle the key from the Model key column instead:
|
|
259
323
|
|
|
260
324
|
- For the Python starter, a key file passed to `init` fills `<target>/agent/.env`, and the
|
|
261
325
|
output says so. Otherwise, run the same check for `OPENAI_API_KEY` against
|
|
262
|
-
`<target>/agent/.env`. A missing file counts as `0`. If it is empty, ask
|
|
263
|
-
|
|
326
|
+
`<target>/agent/.env`. A missing file counts as `0`. If it is empty, ask as above, with
|
|
327
|
+
`--env-path agent/.env` added to the first command.
|
|
264
328
|
- For the .NET starter, the key lives in `dotnet user-secrets`, and no check can read it
|
|
265
329
|
without printing the value. Ask the developer to run
|
|
266
330
|
`cd <target>/agent && dotnet user-secrets set OPENAI_API_KEY "<key>"` themselves, even
|
|
267
331
|
if they named a key file.
|
|
268
332
|
|
|
269
|
-
When you ask,
|
|
270
|
-
when they reply or resume this session. Then report the pause and end your turn:
|
|
333
|
+
When you ask, say that the run continues when they reply or resume this session. Then report the pause and end your turn:
|
|
271
334
|
|
|
272
335
|
```text
|
|
273
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
336
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard checkpoint --phase awaiting-model-credential
|
|
274
337
|
```
|
|
275
338
|
|
|
276
339
|
This is a pause, not a stop. Do not send a stop report, and do not take a stop route.
|
|
277
340
|
When the developer says the credential is in place, run the check again, and continue
|
|
278
341
|
when every variable holds a value. For the .NET starter, continue on the developer's word. Do not write a placeholder or an empty value to get
|
|
279
342
|
past this step. A starter with a dummy key looks finished and fails at the first model
|
|
280
|
-
call.
|
|
343
|
+
call. The one exception is the `not-needed` value for a local server above.
|
|
281
344
|
|
|
282
345
|
If no credential is missing, report no pause and continue.
|
|
283
346
|
|
|
284
|
-
|
|
347
|
+
When every variable holds a value, ask its vendor whether the key can pay for a model call.
|
|
348
|
+
Run this from `<target>`, with one `--model-key` for each variable. For the Microsoft Agent
|
|
349
|
+
Framework Python starter, add `--env-path agent/.env`. Skip it for the .NET starter.
|
|
350
|
+
|
|
351
|
+
```text
|
|
352
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard credentials --model-key <VARIABLE> --json
|
|
353
|
+
```
|
|
285
354
|
|
|
286
|
-
|
|
287
|
-
`
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
355
|
+
The command never prints a value. If `status` is `ready`, continue. Otherwise do what
|
|
356
|
+
`next` says. When it says to ask `question.ask`, end your turn. The command already
|
|
357
|
+
reported the pause. When the developer replies, run the command again. If they choose
|
|
358
|
+
another provider that the framework can use, set `COPILOTKIT_AGENT_MODEL` to it, as the
|
|
359
|
+
previous section describes, and check that provider's variable instead. With the cause `model_unavailable`, the key
|
|
360
|
+
works and the app's model does not: the vendor does not serve the model that
|
|
361
|
+
`COPILOTKIT_AGENT_MODEL` names. When the developer agrees to the model that `question.ask`
|
|
362
|
+
names, or names another, change `COPILOTKIT_AGENT_MODEL` where `question.ask` says, and
|
|
363
|
+
run the command again.
|
|
364
|
+
|
|
365
|
+
Then run `npx --prefer-offline --yes copilotkit@4.28.0 onboard read proof/round-trip`.
|
|
366
|
+
|
|
367
|
+
If the local command fails, `init` keeps the cloned starter in `<target>`, and its error
|
|
368
|
+
says whether it installed the starter's dependencies, or names the command that does. Do
|
|
369
|
+
not run `init` again, because the target is no longer empty. Do not delete the starter or
|
|
370
|
+
the stack. Report the exact error, and do not claim that the starter is ready. A failure
|
|
371
|
+
with `eula_acceptance_required` goes back to the agreement step above, then resumes with
|
|
372
|
+
the `local setup` command below. A failure that names Docker is an environment blocker, not a broken run. For example, Docker is stopped or
|
|
373
|
+
missing, or `Docker available resources` or `Docker memory` is below 4 CPUs, 4 GiB of
|
|
291
374
|
available memory, or 40 GiB storage. Tell the developer what to change in Docker. For
|
|
292
375
|
memory, pass on the amount the message names. Then report the pause and end your turn:
|
|
293
376
|
|
|
294
377
|
```text
|
|
295
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
378
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard checkpoint --phase awaiting-developer
|
|
296
379
|
```
|
|
297
380
|
|
|
298
381
|
When the developer says that Docker is ready, resume from `<target>` with the same model
|
|
299
382
|
choice. If the run used a `--candidate`, add the same one:
|
|
300
383
|
|
|
301
384
|
```text
|
|
302
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
385
|
+
npx --prefer-offline --yes copilotkit@4.28.0 local setup --defer-model --json
|
|
303
386
|
```
|
|
304
387
|
|
|
305
388
|
If the run used model settings, replace `--defer-model` with `--model-config <private-file>`.
|
|
@@ -307,15 +390,16 @@ Read blockers and the recorded failed step. Do not delete or recreate a failed s
|
|
|
307
390
|
setup reports the stack ready, connect the starter from `<target>`:
|
|
308
391
|
|
|
309
392
|
```text
|
|
310
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
393
|
+
npx --prefer-offline --yes copilotkit@4.28.0 local connect --approve-connection --json
|
|
311
394
|
```
|
|
312
395
|
|
|
313
396
|
The connection writes `.copilotkit/local.json`, `.copilotkit/project.json`, and the local
|
|
314
397
|
keys in `<target>/.env`. Then continue with the credential check above. If the resumed
|
|
315
|
-
setup fails again with an error that
|
|
398
|
+
setup fails again with an error that names neither Docker nor `eula_acceptance_required`,
|
|
399
|
+
take the route below.
|
|
316
400
|
|
|
317
401
|
If the command fails, report its exact error and do not claim that the starter is ready.
|
|
318
402
|
Then run
|
|
319
|
-
`npx --prefer-offline --yes copilotkit@4.
|
|
403
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 onboard read stopped/run-failed`. The starter is one this
|
|
320
404
|
graph ships and the stack was chosen from its own supported list, so a command that
|
|
321
405
|
returned an error is a run that broke, not a setup this release does not support.
|
|
@@ -21,6 +21,8 @@ Say what the developer has now. Name the processes still running and the files t
|
|
|
21
21
|
changed, so they can carry on by hand or start again from a known state. A run that stops
|
|
22
22
|
without saying what it left behind leaves the developer to discover it. This step prints
|
|
23
23
|
`## The developer's files` below: relay that report as printed, with its restore command.
|
|
24
|
+
When the report says the run started in an empty folder, relay that one line alone in
|
|
25
|
+
place of the files: list no files and offer no restore.
|
|
24
26
|
|
|
25
27
|
A step can fail on a network error: `EAI_AGAIN`, `ECONNRESET`, `ETIMEDOUT`, a timeout,
|
|
26
28
|
or a message that names a proxy. The CLI has already tried that step again. Ask the
|
|
@@ -40,13 +42,13 @@ put to them, stop here and send the report below.
|
|
|
40
42
|
Before you end your turn to wait for the developer, report the pause:
|
|
41
43
|
|
|
42
44
|
```text
|
|
43
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
45
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard checkpoint --phase awaiting-developer
|
|
44
46
|
```
|
|
45
47
|
|
|
46
48
|
If they approve it, make that one fix and nothing else. Then come back into this run:
|
|
47
49
|
|
|
48
50
|
```text
|
|
49
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
51
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard resume --message "<approval>"
|
|
50
52
|
```
|
|
51
53
|
|
|
52
54
|
Put the developer's approval in `--message`, in one or two sentences: the fix they
|
|
@@ -69,7 +71,7 @@ Send one short report. The friction command follows the telemetry setting the de
|
|
|
69
71
|
already chose, so it needs no separate question.
|
|
70
72
|
|
|
71
73
|
```text
|
|
72
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
74
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard friction --phase stop --category <slug> --message "<sentences>"
|
|
73
75
|
```
|
|
74
76
|
|
|
75
77
|
`--message` takes one or two sentences: the step you stopped at and what stopped
|
|
@@ -32,8 +32,8 @@ Wiring is not behavior. The CopilotKit SDK dependency, the middleware the agent
|
|
|
32
32
|
in, the runtime mount, the AG-UI connection, and a frontend that renders what the agent
|
|
33
33
|
already returns are wiring. Plan them as ordinary steps.
|
|
34
34
|
|
|
35
|
-
Every item on the behavior list is a change the developer has to approve
|
|
36
|
-
needs one, plan it as its own item, name the file and the exact change, and state that it
|
|
35
|
+
Every item on the behavior list is a change the developer has to approve, so it goes under
|
|
36
|
+
`Changes that need your approval`. Where a step needs one, plan it as its own item, name the file and the exact change, and state that it
|
|
37
37
|
changes how the agent answers everywhere, not only in CopilotKit. A system prompt the
|
|
38
38
|
developer wrote is the agent's behavior rather than a setting this run tunes until a
|
|
39
39
|
component renders. Where the plan cannot be written without such a change and you cannot
|
|
@@ -56,7 +56,7 @@ shows a `runner` option instead, the Intelligence quickstart wins.
|
|
|
56
56
|
The main coding agent gives you a Learning Container id, or tells you the Learning step was
|
|
57
57
|
skipped for this organization.
|
|
58
58
|
|
|
59
|
-
Where it gives you an id, plan two things and name both in the plan
|
|
59
|
+
Where it gives you an id, plan two things and name both in the plan:
|
|
60
60
|
the container id itself, and a `getLearningContainerId` callback returning that id on the
|
|
61
61
|
`CopilotKitIntelligence` instance. Take the callback from the Learning page, and fetch it
|
|
62
62
|
here rather than expecting the run to have handed it over:
|
|
@@ -97,7 +97,7 @@ against a dead host, and the failure arrives as an empty-body 404 with no cause
|
|
|
97
97
|
Ask the CLI for the dependency upgrade, from the target directory:
|
|
98
98
|
|
|
99
99
|
```text
|
|
100
|
-
npx --prefer-offline --yes copilotkit@4.
|
|
100
|
+
npx --prefer-offline --yes copilotkit@4.28.0 onboard upgrade-plan --json
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
It reads the installed tree and the registry. Read `status`:
|
|
@@ -118,8 +118,8 @@ It reads the installed tree and the registry. Read `status`:
|
|
|
118
118
|
|
|
119
119
|
The floor is 1.70.0 because the runtime resolves managed Intelligence entitlement
|
|
120
120
|
authority from that version. Below it, the Intelligence features stay dark with no error.
|
|
121
|
-
An exact pin is usually deliberate, so
|
|
122
|
-
repair the run invents halfway through. Where the developer needs a pin held, return
|
|
121
|
+
An exact pin is usually deliberate, so a move of one is a change the developer
|
|
122
|
+
approves, not a repair the run invents halfway through. Where the developer needs a pin held, return
|
|
123
123
|
`Status: blocked` and name `unsupported/no-validated-path` as the outcome.
|
|
124
124
|
|
|
125
125
|
A package the plan adds that a `@copilotkit/*` or `@ag-ui/*` package also depends on, such
|
|
@@ -131,6 +131,10 @@ version the target `@copilotkit/*` release requires, and plan the latest version
|
|
|
131
131
|
Where the project already depends on that package, keep its version if that tree accepts
|
|
132
132
|
it. Otherwise name the move in the plan, with the version it moves to.
|
|
133
133
|
|
|
134
|
+
A version the documentation gives as a dist-tag, such as `ai-v6` in `@ai-sdk/openai@ai-v6`,
|
|
135
|
+
is not a version. Resolve it with `npm view <package>@<tag> version`, and plan that exact
|
|
136
|
+
version.
|
|
137
|
+
|
|
134
138
|
Where the SDK requires an application-level value that the repository cannot supply, such
|
|
135
139
|
as an end-user identity for threads, use one clearly marked local placeholder and name what
|
|
136
140
|
production requires instead. Do not stop onboarding to ask the developer for it.
|
|
@@ -145,9 +149,10 @@ If the value of the journey depends on data the project already holds, name that
|
|
|
145
149
|
name where it lives, and name how it reaches the agent. Rendering a list in the DOM does
|
|
146
150
|
not give the agent access to it. An agent wired without the page's data answers from
|
|
147
151
|
entities it invents, and the answer looks correct. Take the frontend-context step from
|
|
148
|
-
the selected documentation, and never guess
|
|
149
|
-
|
|
150
|
-
|
|
152
|
+
the selected documentation, and never guess a CopilotKit API. Where no selected page shows
|
|
153
|
+
how this framework reads that data, the agent reads it from the AG-UI run input `context`,
|
|
154
|
+
as https://docs.copilotkit.ai/agent-app-context.md shows. Name the agent code that reads
|
|
155
|
+
`context` and passes it to the model.
|
|
151
156
|
|
|
152
157
|
Where that data exists, name the entities the proof compares against: the ids, names, or
|
|
153
158
|
records the project holds and the answer has to reference. Where the outcome references
|
|
@@ -180,24 +185,21 @@ here is work the developer did not ask for.
|
|
|
180
185
|
Plan the threads drawer itself: add it from the selected drawer page, where this frontend
|
|
181
186
|
does not already render one. Where this journey's frontend framework ships no threads
|
|
182
187
|
drawer -- React Native --, plan that the thread is proved by
|
|
183
|
-
`npx --prefer-offline --yes copilotkit@4.
|
|
188
|
+
`npx --prefer-offline --yes copilotkit@4.28.0 verify --round-trip`, which needs no browser. Do not plan a
|
|
184
189
|
step that opens the managed Intelligence dashboard.
|
|
185
190
|
|
|
186
191
|
## Name the files the run writes itself
|
|
187
192
|
|
|
188
193
|
List these in the plan under `Files the run writes itself`, apart from the implementation
|
|
189
|
-
steps. They are not steps, and they need no
|
|
190
|
-
|
|
194
|
+
steps. They are not steps, and they need no approval, except a file that is also under
|
|
195
|
+
`Uncommitted files`: list that one under `Changes that need your approval` too.
|
|
191
196
|
|
|
192
197
|
- Each `planChanges` entry from `onboard credentials`: the project key in the env file
|
|
193
198
|
`environmentPath` names, the project record, and, where it lists `ignore-entries`, the
|
|
194
|
-
lines `project select` adds to `.gitignore` so that no credential env file
|
|
195
|
-
committed.
|
|
199
|
+
lines `project select` adds to `.gitignore` so that no credential env file and no
|
|
200
|
+
`.playwright-mcp/` browser snapshot can be committed.
|
|
196
201
|
- `.copilotkit/proof/`, where the proof writes its evidence. It holds no source. The
|
|
197
202
|
developer can delete it after the run.
|
|
198
|
-
- The CopilotKit Skills, as a line the developer approves or declines:
|
|
199
|
-
`npx skills add CopilotKit/CopilotKit/skills -y`. It writes `.agents/skills/` and links
|
|
200
|
-
it into `.claude/skills/`. Both sit in the working tree and show up in `git status`.
|
|
201
203
|
|
|
202
204
|
## Scaffold an empty project
|
|
203
205
|
|
|
@@ -230,7 +232,8 @@ the plan under `Uncommitted files`, one line each, with the path and one sentenc
|
|
|
230
232
|
what the step changes there and why no other file will do. Keep the step in the plan.
|
|
231
233
|
Adding a feature to an app the developer already built is the case this exists for: the
|
|
232
234
|
option lives in a file they wrote, and on an app whose work was never committed that file
|
|
233
|
-
has uncommitted changes.
|
|
235
|
+
has uncommitted changes. Each of those edits needs approval, so the developer's answer
|
|
236
|
+
to the plan is their consent. The CLI records none.
|
|
234
237
|
|
|
235
238
|
Installing or upgrading a package changes the manifest that lists it, such as `package.json`
|
|
236
239
|
or `pyproject.toml`, and its lockfile, such as `package-lock.json` or `uv.lock`. Install
|
|
@@ -241,8 +244,8 @@ Do not plan the deletion of a file that has uncommitted changes, and do not plan
|
|
|
241
244
|
moves or renames one. If a step cannot be written any other way, return `Status: blocked`
|
|
242
245
|
and name the path.
|
|
243
246
|
|
|
244
|
-
Keep final validation and proof outside the implementation steps. The developer
|
|
245
|
-
|
|
247
|
+
Keep final validation and proof outside the implementation steps. The developer sees one
|
|
248
|
+
plan.
|
|
246
249
|
|
|
247
250
|
Keep a production build out of the validation commands. A type check plus the real round
|
|
248
251
|
trip is the proof, and the round trip runs in development mode. Name the production build
|
|
@@ -256,8 +259,8 @@ directory in `nextjsWithoutCopilotKit`, plan it as its own step, before the firs
|
|
|
256
259
|
that imports a CopilotKit package in that directory. Name the migration `file` and each
|
|
257
260
|
change in `changes`, and give its `reason` in one sentence. Under `node` or `node10`
|
|
258
261
|
resolution, TypeScript ignores a package's `exports` map, so every CopilotKit subpath
|
|
259
|
-
import fails the type check while the app still runs. A plan without this step stops
|
|
260
|
-
|
|
262
|
+
import fails the type check while the app still runs. A plan without this step stops partway
|
|
263
|
+
through the build to ask for it. If the file has uncommitted changes, list it under
|
|
261
264
|
`Uncommitted files`. Where no migration is reported, do not change
|
|
262
265
|
`moduleResolution` or `module`. This change does not weaken type safety.
|
|
263
266
|
|
|
@@ -274,6 +277,54 @@ Do not add compiler strictness the project did not have. Nothing later in the ru
|
|
|
274
277
|
allowed to weaken type safety, so a stricter gate named here is one the run cannot get
|
|
275
278
|
back out of.
|
|
276
279
|
|
|
280
|
+
## Name the changes that need approval
|
|
281
|
+
|
|
282
|
+
The run shows the plan to the developer and goes on to build it without waiting. It stops
|
|
283
|
+
for an answer only when the plan makes a change that needs approval. `onboard start` took a
|
|
284
|
+
backup, so `onboard restore` undoes any other change the backup holds.
|
|
285
|
+
|
|
286
|
+
List each change that needs approval under `Changes that need your approval`, one line each: the path
|
|
287
|
+
or package, what the step does to it, and why the plan needs it. Write `none` when there is
|
|
288
|
+
none. List every other change under `What I will change`. A step makes a change that needs
|
|
289
|
+
approval when it:
|
|
290
|
+
|
|
291
|
+
- upgrades a dependency by a major version: a move whose `to` has a different major version
|
|
292
|
+
than `from`, or a move of an exact pin
|
|
293
|
+
- removes a dependency the app already uses, or moves one outside the range the app
|
|
294
|
+
declares
|
|
295
|
+
- deletes, moves, or renames a file the developer wrote
|
|
296
|
+
- changes a file that has uncommitted changes, from `Uncommitted files`
|
|
297
|
+
- untracks a file or changes `.gitignore`, other than the lines under
|
|
298
|
+
`Files the run writes itself`
|
|
299
|
+
- writes to an env file the app already uses, other than the key line for the key file
|
|
300
|
+
the setup answers recorded
|
|
301
|
+
- changes the existing agent's behavior, as `What the existing agent's behavior is`
|
|
302
|
+
defines it
|
|
303
|
+
- changes more than 10 files in all. Count only the files the plan's own steps change. Do
|
|
304
|
+
not count a file the framework's own tooling writes by itself, such as the `AGENTS.md`
|
|
305
|
+
and `CLAUDE.md` that `next dev` writes, or a file under `Files the run writes itself`.
|
|
306
|
+
The limit is the same one the backup tripwire sets for deleted files
|
|
307
|
+
- writes a file outside the project directory
|
|
308
|
+
- changes the version of any CopilotKit dependency: an `@copilotkit/*` package or the
|
|
309
|
+
`copilotkit` Python package, by any amount
|
|
310
|
+
|
|
311
|
+
A change the developer approved in the setup message needs no approval in the plan. The setup
|
|
312
|
+
answers the main coding agent gives you show it: `envFile` is `approved` for the untrack or
|
|
313
|
+
the `.gitignore` line that the env-file line named, and `alternative` for the key in the other
|
|
314
|
+
env file. `uncommittedWrites: approved` allows the connection's writes to the env file and
|
|
315
|
+
`.copilotkit/project.json`. Name each one under the notes instead.
|
|
316
|
+
|
|
317
|
+
The plan also needs approval when the backup does not hold every file: `backup.status` is
|
|
318
|
+
`partial` or `failed` in the `backup` result the main coding agent gives you. Name it as a
|
|
319
|
+
line of its own. For `partial`, name each path in `backup.notHeld` with its `why`, which
|
|
320
|
+
names the limit for a size skip, and the count in `backup.moreNotHeld` if any. For
|
|
321
|
+
`failed`, name the cause in `backup.detail`, and that `onboard restore` puts nothing back.
|
|
322
|
+
A step that changes one of those paths cannot be undone. `pending` needs no approval: the CLI
|
|
323
|
+
takes the backup when the run moves to the chosen project, or at the next step, before any
|
|
324
|
+
change. Say that in the plan.
|
|
325
|
+
|
|
326
|
+
Do not leave a change that needs approval out of the list to keep the run moving.
|
|
327
|
+
|
|
277
328
|
Gather what you need in as few commands as possible. Combine independent reads into one
|
|
278
329
|
command rather than running them one at a time. Split a command only when its result decides
|
|
279
330
|
what you run next.
|