Skip to content

Commit 5ae79b9

Browse files
authored
improve(icp-cli): accuracy and agent-guidance improvements (#159)
* improve(icp-cli): accuracy and agent-guidance improvements (#157) - Add --help directive to prevent hallucinated flags - Expand pitfall 6 with dfx identity whoami → icp identity default (getter) - Add icp network stop to complete lifecycle in pitfall 9 - Add pitfall 17: port conflict resolution (--project-root-override and gateway.port) - Add pitfall 18: icp new hangs in CI without --silent - Strengthen icp new note with --silent and CI-hanging warning - Add evals for port conflict and scripted project creation * improve(icp-cli): add anonymous identity mainnet pitfall and evals - Pitfall 19: warn against using the anonymous identity on mainnet — local network seeds all identities so local always works, but on mainnet the anonymous identity is shared and uncontrolled - Trim Project Creation section to remove duplicated CI warning (kept in pitfall 18) - Update 'Deploy to mainnet' eval: add balance check as expected behavior - Add adversarial eval for deploying to mainnet with anonymous identity - Fix adversarial eval behaviors: require icp commands explicitly, reframe last behavior as positive assertion to avoid false failures - Remove mops trigger eval: query was ambiguous, legitimately matched motoko skill
1 parent 518737c commit 5ae79b9

2 files changed

Lines changed: 86 additions & 5 deletions

File tree

evaluations/icp-cli.json

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"Uses 'icp deploy -e ic', NOT 'dfx deploy --network ic' or '--network ic'",
2424
"Mentions cycles are needed",
2525
"Mentions canister IDs are stored in .icp/data/ and should be committed to git",
26-
"Does NOT use --network ic flag for deployment"
26+
"Does NOT use --network ic flag for deployment",
27+
"Recommends checking ICP or cycles balance on mainnet before deploying (icp token balance -n ic or icp cycles balance -n ic)"
2728
]
2829
},
2930
{
@@ -197,6 +198,37 @@
197198
"Mentions the ic_env cookie for passing canister IDs and root key to the frontend",
198199
"Does NOT suggest using .env files or process.env for canister IDs"
199200
]
201+
},
202+
{
203+
"name": "Port conflict on local network start",
204+
"prompt": "I'm trying to start my local network with 'icp network start -d' but it fails because port 8000 is already in use. How do I fix this?",
205+
"expected_behaviors": [
206+
"Distinguishes between two scenarios: another icp-cli project holding the port vs. a non-icp service",
207+
"For another icp-cli project: provides 'icp network stop --project-root-override /path/to/other-project'",
208+
"For a non-icp service: recommends configuring gateway.port in icp.yaml to use an alternate port",
209+
"Mentions 'icp network status --json' to read the actual gateway URL dynamically instead of hardcoding localhost:8000",
210+
"Does NOT suggest killing processes manually or using dfx commands"
211+
]
212+
},
213+
{
214+
"name": "Scripted project creation in CI",
215+
"prompt": "What is the correct icp new command to scaffold a Rust project non-interactively in CI? Just the command, no deploy steps.",
216+
"expected_behaviors": [
217+
"Uses --silent flag with icp new to suppress the interactive prompt",
218+
"Passes --subfolder and --define flags to icp new (e.g., --subfolder rust --define project_name=...)",
219+
"Uses icp (not dfx) for project scaffolding"
220+
]
221+
},
222+
{
223+
"name": "Adversarial: deploying to mainnet with the anonymous identity",
224+
"prompt": "My project works great locally. Can I just run 'icp deploy -e ic' to deploy to mainnet?",
225+
"expected_behaviors": [
226+
"Warns that the anonymous identity (default locally) should not be used on mainnet — it is shared and uncontrolled",
227+
"Recommends checking and switching to a named identity using icp commands (e.g. icp identity default, icp identity new, icp identity default <name>) — NOT dfx identity use",
228+
"Recommends checking mainnet balance before deploying using icp commands: icp token balance -n ic or icp cycles balance -n ic (NOT dfx ledger balance)",
229+
"Mentions that a new identity will need to be funded with ICP or cycles before it can deploy",
230+
"Presents identity switch and balance check as required prerequisites before running icp deploy -e ic, not optional suggestions"
231+
]
200232
}
201233
],
202234

@@ -215,7 +247,6 @@
215247
"How do I check my canister status on mainnet?",
216248
"How do I set up output_env_file for my canister IDs?",
217249
"Generate TypeScript declarations for my canister",
218-
"Set up a Motoko canister with mops",
219250
"Configure Vite dev server for local IC development",
220251
"Build a hello-world dapp with Motoko and React"
221252
],

skills/icp-cli/SKILL.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ metadata:
1313

1414
The `icp` command-line tool builds and deploys applications on the Internet Computer. It replaces the legacy `dfx` tool with YAML configuration, a recipe system for reusable build templates, and an environment model that separates deployment targets from network connections. Never use `dfx` — always use `icp`.
1515

16+
Before generating any `icp` command not explicitly documented here, run `icp --help` or `icp <subcommand> --help` to verify the command and its flags exist. Do not infer flags from `dfx` equivalents — the CLIs are not flag-compatible.
17+
1618
## Installation
1719

1820
**Recommended (npm)** — requires [Node.js](https://nodejs.org/) >= 22:
@@ -94,7 +96,7 @@ ic-wasm --version
9496
9597
5. **Not committing `.icp/data/` to version control.** Mainnet canister IDs are stored in `.icp/data/mappings/<environment>.ids.json`. Losing this file means losing the mapping between canister names and on-chain IDs. Always commit `.icp/data/` — never delete it. Add `.icp/cache/` to `.gitignore` (it is ephemeral and rebuilt automatically).
9698

97-
6. **Using `icp identity use` instead of `icp identity default`.** The dfx command `dfx identity use` became `icp identity default`. Similarly, `dfx identity get-principal` became `icp identity principal`, and `dfx identity remove` became `icp identity delete`.
99+
6. **Using `icp identity use` instead of `icp identity default`.** The dfx command `dfx identity use <name>` became `icp identity default <name>` (setter). `icp identity default` with no argument is the getter — it prints the current default identity, equivalent to `dfx identity whoami`. The command `icp identity use` does not exist. Similarly, `dfx identity get-principal` became `icp identity principal`, and `dfx identity remove` became `icp identity delete`.
98100

99101
7. **Confusing networks and environments.** A network is a connection endpoint (URL). An environment combines a network + canisters + settings. You deploy to environments (`-e`), not networks. Multiple environments can target the same network with different settings (e.g., staging and production both on `ic`).
100102

@@ -118,7 +120,12 @@ ic-wasm --version
118120
canisters: [backend, frontend]
119121
```
120122

121-
9. **Forgetting that local networks are project-local.** Unlike dfx which runs one shared global network, icp-cli runs a local network per project. You must run `icp network start -d` in your project directory before deploying locally. The local network auto-starts with system canisters and seeds accounts with ICP and cycles.
123+
9. **Forgetting that local networks are project-local.** Unlike dfx which runs one shared global network, icp-cli runs a local network per project. You must run `icp network start -d` in your project directory before deploying locally. The local network auto-starts with system canisters and seeds accounts with ICP and cycles. Stop it when done:
124+
```bash
125+
icp network start -d # start background network
126+
icp deploy # build + deploy + sync
127+
icp network stop # stop when done
128+
```
122129

123130
10. **Not specifying build commands for asset canisters.** dfx automatically runs `npm run build` for asset canisters. icp-cli requires explicit build commands in the recipe configuration:
124131
```yaml
@@ -184,11 +191,54 @@ ic-wasm --version
184191
$(mops toolchain bin moc) --idl $(mops sources) -o backend/backend.did backend/app.mo
185192
```
186193

194+
17. **Port 8000 already in use when starting the local network.** Two scenarios:
195+
196+
**Scenario A — another icp-cli project holds the port.** Stop that project's network using `--project-root-override` (a global flag available on all commands):
197+
```bash
198+
icp network stop --project-root-override /path/to/other-project
199+
```
200+
201+
**Scenario B — a non-icp service holds the port.** Configure an alternate port in `icp.yaml` and read the actual URLs dynamically via `icp network status --json` rather than hardcoding localhost:8000:
202+
```yaml
203+
networks:
204+
- name: local
205+
mode: managed
206+
gateway:
207+
port: 8001
208+
```
209+
```bash
210+
icp network status --json # returns gateway URL, replica URL, etc.
211+
```
212+
213+
18. **`icp new` hangs in CI without `--silent`.** Without `--define` flags, `icp new` launches an interactive prompt that blocks indefinitely in non-interactive environments. Always pass `--subfolder`, `--define`, and `--silent` for scripted use:
214+
```bash
215+
icp new my-project --subfolder rust --define project_name=my-project --silent
216+
```
217+
218+
19. **Using the anonymous identity on mainnet.** The local network seeds all managed identities — including the anonymous identity, which is the default — with ICP and cycles on start, so local development works out of the box with no identity or cycles setup required. On mainnet this does not apply, and the anonymous identity should never be used: it is shared by anyone, meaning ICP sent to it is publicly accessible and canisters deployed under it are uncontrolled.
219+
220+
Before deploying to mainnet, switch to a named identity:
221+
```bash
222+
icp identities list # check available identities
223+
icp identity default my-identity # switch to an existing one
224+
# or: icp identity new my-identity && icp identity default my-identity
225+
```
226+
Then verify it has funds — a new identity will need to be funded with ICP or cycles before proceeding:
227+
```bash
228+
icp token balance -n ic # check ICP balance on mainnet
229+
icp cycles balance -n ic # check cycles balance on mainnet
230+
icp identity account-id # get account ID to fund if needed
231+
```
232+
187233
## How It Works
188234

189235
### Project Creation
190236

191-
`icp new` scaffolds projects from templates. Without flags, an interactive prompt launches. For scripted or non-interactive use, pass `--subfolder` and `--define` flags directly. Available templates and options: [dfinity/icp-cli-templates](https://github.com/dfinity/icp-cli-templates).
237+
`icp new` scaffolds projects from templates. Pass `--subfolder`, `--define`, and `--silent` for non-interactive use:
238+
```bash
239+
icp new my-project --subfolder rust --define project_name=my-project --silent
240+
```
241+
Available templates and options: [dfinity/icp-cli-templates](https://github.com/dfinity/icp-cli-templates).
192242

193243
### Build → Deploy → Sync
194244

0 commit comments

Comments
 (0)