Please give us `icp init` for existing folders

Because, @marc0olo, like DFINITY, they had no rationale against the idea. They realized at some point they were just being stubborn not implementing it, stuck in their technical point of view, not admitting the user/product perspective will always win.

I’ve discussed this with 3 of you at the sdk team, and nobody gave me an explanation of why not, being subconsciously (?) embarrassed.

If you want ICP to succeed (that should be the real final filter), then you know what to do.

Hi @geitzeist99, thanks for the feedback.

Some of the stuff you mention already exists, I’m not sure if it’s not obvious from the help or if you feel like some of the fields might be missing from the response.
In general, most of the commands will take a --json but they don’t output json to stdout if the command fails (maybe that’s what you’re asking for?)

In any case, here are some examples - if you think the output should be different, or fields are missing etc - please give us some sample output and you reasoning. Your feedback is much appreciated.

  1. Add stable --json receipts for mutating operations, especially
    snapshots.

You can already pass --json to the snapshot commands, eg

❯ icp canister snapshot create frontend --json | jq
{
  "snapshot_id": "0000000000000000ffffffffffc000020101",
  "taken_at_timestamp": 1778709681897818005,
  "total_size_bytes": 272586987
}

Is the problem that fields are missing, like canister_id or that there is no success/failure in the json output?

  1. Make canister calls return structured JSON with transport metadata separate from decoded reply data.

That also has a --json that will output the metadata with the reply in a separate field that you would have to decode yourself depending on the --output that you pass

❯ icp canister call motoko-ex greet '("raymond")' --query --json | jq
{
  "response_bytes": "4449444c0001710f48656c6c6f2c207261796d6f6e6421",
  "response_text": null,
  "response_candid": "(\"Hello, raymond!\")"
}

❯ icp canister call motoko-ex greet '("raymond")' --query --json -o text | jq
{
  "response_bytes": "4449444c0001710f48656c6c6f2c207261796d6f6e6421",
  "response_text": "DIDL\u0000\u0001q\u000fHello, raymond!",
  "response_candid": null
}

Is there something else you would like to see in the payload?

  1. Add stable JSON for project/environment/status inspection.

icp project show outputs yaml - the intent was that you could see what the “exploded” file was after recipes were rendered including assuming default values and that you could copy/paste stuff back into your icp.yaml if you want to customize some of it.

So you could use yq instead, for eg:

# See the project directory
❯ icp project show | yq -r ".dir"
/Users/raymond/tmp/motoko-ex

# Show the list of environments
❯ icp project show  | yq -r ".environments[].name"
ic
local

# Show the name of canisters in the "ic" environment
❯ icp project show  | yq -r '.environments[] | select(.name == "ic") | .canisters | keys'
[
  "motoko-ex"
]

You can also check a network (but it must be running):

{
  "managed": true,
  "api_url": "http://127.0.0.1:8000/",
  "gateway_url": "http://127.0.0.1:8000/",
  "candid_ui_principal": "tqzl2-p7777-77776-aaaaa-cai",
  "proxy_canister_principal": "txyno-ch777-77776-aaaaq-cai",
  "root_key": "308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008b52b4994f94c7ce4be1c1542d7c81dc79fea17d49efe8fa42e8566373581d4b969c4a59e96a0ef51b711fe5027ec01601182519d0a788f4bfe388e593b97cd1d7e44904de79422430bca686ac8c21305b3397b5ba4d7037d17877312fb7ee34"
}

If you are looking for canister ids and stuff, you should use
icp canister status -e <environment> --json

{
  "id": "t63gs-up777-77776-aaaba-cai",
  "name": "motoko-ex",
  "status": "Running",
  "settings": {
    "controllers": [
      "zbf4m-zw3nk-6owqc-qmluz-xhwxt-2pkky-xhjy2-kqxor-qzxsn-6d2bz-nae"
    ],
    "compute_allocation": "0",
    "memory_allocation": "0",
    "freezing_threshold": "2_592_000",
    "reserved_cycles_limit": "5_000_000_000_000",
    "wasm_memory_limit": "3_221_225_472",
    "wasm_memory_threshold": "0",
    "log_memory_limit": "0",
    "log_visibility": {
      "type": "Controllers"
    },
    "environment_variables": [
      {
        "name": "PUBLIC_CANISTER_ID:motoko-ex",
        "value": "t63gs-up777-77776-aaaba-cai"
      }
    ]
  },
  "module_hash": "0x66ce5ddcd06f1135c1a04792a2f1b7c3d9e229b977a8fc9762c71ecc5314c9eb",
  "memory_size": "5_539_921",
  "cycles": "1_497_896_187_059",
  "reserved_cycles": "0",
  "idle_cycles_burned_per_day": "141_534_128",
  "query_stats": {
    "num_calls_total": "0",
    "num_instructions_total": "0",
    "request_payload_bytes_total": "0",
    "response_payload_bytes_total": "0"
  }
}

Hey @jdelforge

You can initialize in place with:
icp new --init

This will use your current directory as the project name (the project name is required for rendering the templates)

The reason why I didn’t want to add an init is that I didn’t want to have both icp new and icp init as top level commands doing almost similar things. The “new” is inherited from dfx which was icp-cli’s predecessor.

I tend to think “new” is more appropriate than “init” in our case because the operation is not just adding metadata that is relevant to the tool - the template it can render could be as complicated as the author wants to make it and in many cases it’s a dangerous operation to run it after you’ve started writing some code because it might overwrite it. In contrast a git init is confined to touching the .git directory which tends to be reserved for it.

Of course, I realize in the end this is a matter of taste and I hope the success of ICP doesn’t hinge only on that decision.

Fantastic, not sure how me and Codex missed that. Will make all the necessary changes now, thanks!

Ahhh…lovely…a couple days of retooling on a dead body coming up…yeah.

Fair enough, I understand better.

From my builder perspective: I would never think of using icp init if I already had a code structure in place. icp init could simply warn about this edge case.

100% of the time, as my initial post explains, i just store “Documents, specs, notes, screenshots, quotes, designs, images, prompts, …” before chosing my stack.

I never chose my stack then think about the project’s idea.

If, for example, I already had a code structure in place, I would intuitively create a new clean folder and import the stuff I need.

But we have a complete different perspective I guess. 11+ years shipping. 0 year building sdk environments.

I love simplicity, beauty. I believe the very first command has a psychological importance, and should have zero friction. Nobody would guess intuitively that icp new --init is the very first command if they’re new to the ecosystem. Nobody.

And I guess there will be more devs onboarding than devs used to icp new --init

Starting a project, choosing a stack, are always a devotion, and to start with a friction is always frustrating.

Best of luck, love the IC.

__
By the way, icp deploy --mode reinstall also badly needs a confirmation step.

If you’d like to provide feedback to canic then would be appreciated. It wraps icp-cli (mostly) so we have carte blanche to make it how we like it.

The aim of my project is to fill in all the tools that the foundation should have made in the past 5 years but haven’t. It’s mostly around fleets of canisters (millions of canisters, thousands of subnets etc.) but even on a single canister you’ll get a lot of extra tooling.