Invoke another app via a task contract and await its typed result (Recipe B).
Rejects with a machine .code on refusal: cancelled (user dismissed the
overlay), timeout (§5.7.1 liveness), forbidden (missing task:invoke, or a
file delegation you don't hold), not-declared (the task is missing from your
immediately.run.invokes), no-such-task (no app is bound to that contract),
task-cycle/task-depth-exceeded/task-version-mismatch, or invalid-params
(result failed the contract schema). Read err.message — since R3-418 the host
says which capability, which declaration or which param was at fault; the code alone
does not distinguish them.
Two things must BOTH be true before any invoke is admitted, and they are separate:
your package.jsonimmediately.run.invokes lists the task (else not-declared);
your app holds the task:invoke capability — declare it in
immediately.run.capabilities so the user can grant it (else forbidden).
Declaring the invoke does not imply the capability.
── pick-file: roots is required (SPACES_UI_SPEC §4.1) ───────────────────
constmount = awaitrequestMount(); // the user picks a space // `invokeTask` returns `unknown` — name the result type, or the destructuring // below does not compile. const { root, path } = awaitinvokeTask<{ root: number; path: string }>('pick-file', { // `SandboxMount.id` is optional (absent on the primary repo mount) — fall back to // `path`, which is always present and is what the host resolves against. roots: [capDir({ mountId:mount.id ?? mount.path, relPath:'boards' }, { mode:'ro' })], });
roots is a NON-EMPTY DirCap[] of directories you already hold. The result
names its target as { root, path } where root INDEXES params.roots, so
invokeTask('pick-file', {}) can never produce a valid result and is rejected.
There is no rootless "pick from any of my spaces" mode by design: enumerating the
user's spaces is the host's powerbox (requestMount()), and composing the two —
as above — is that flow. See SPACES_UI_SPEC R-SPACES-5/R-SPACES-12.
Each capDir is attenuated against your own grant. { mode: 'rw' } over a space
the user granted ro is refused forbidden — the commonest failure, because the
mount was granted and the path is inside it. Pass the mode you actually hold;
ro is right for a plain pick.
The requestMount() grant is DURABLE and survives a cancelled pick: the user
consented to the mount in host chrome, separately from the pick (SPACES_UI_SPEC §4.1).
Reuse it for later picks rather than re-requesting.
Off-host (plain vite dev — no host transport) it rejects with a plain
"no host transport" error: there is no host to resolve the task binding.
Invoke another app via a task contract and await its typed result (Recipe B). Rejects with a machine
.codeon refusal:cancelled(user dismissed the overlay),timeout(§5.7.1 liveness),forbidden(missingtask:invoke, or a file delegation you don't hold),not-declared(the task is missing from yourimmediately.run.invokes),no-such-task(no app is bound to that contract),task-cycle/task-depth-exceeded/task-version-mismatch, orinvalid-params(result failed the contract schema). Readerr.message— since R3-418 the host says which capability, which declaration or which param was at fault; the code alone does not distinguish them.Two things must BOTH be true before any invoke is admitted, and they are separate:
package.jsonimmediately.run.invokeslists the task (elsenot-declared);task:invokecapability — declare it inimmediately.run.capabilitiesso the user can grant it (elseforbidden). Declaring the invoke does not imply the capability.──
pick-file:rootsis required (SPACES_UI_SPEC §4.1) ───────────────────rootsis a NON-EMPTYDirCap[]of directories you already hold. The result names its target as{ root, path }whererootINDEXESparams.roots, soinvokeTask('pick-file', {})can never produce a valid result and is rejected. There is no rootless "pick from any of my spaces" mode by design: enumerating the user's spaces is the host's powerbox (requestMount()), and composing the two — as above — is that flow. See SPACES_UI_SPEC R-SPACES-5/R-SPACES-12.capDiris attenuated against your own grant.{ mode: 'rw' }over a space the user grantedrois refusedforbidden— the commonest failure, because the mount was granted and the path is inside it. Pass the mode you actually hold;rois right for a plain pick.requestMount()grant is DURABLE and survives a cancelled pick: the user consented to the mount in host chrome, separately from the pick (SPACES_UI_SPEC §4.1). Reuse it for later picks rather than re-requesting.Off-host (plain
vite dev— no host transport) it rejects with a plain "no host transport" error: there is no host to resolve the task binding.