feat(compute): watch paths — which pushes redeploy a service
Companion docs PR: InsForge/insta-skills#83 (insta-cli AGENTS.md #4 — flag changes are mirrored in skills/insta/cli-reference.md).
Platform side is shipped and live: insta-platform#399.
What this adds
insta compute watch-paths [service] # print them
insta compute watch-paths --set 'apps/web/**,packages/ui/**'
insta compute watch-paths --clear
insta compute connect-repo <owner/repo> --watch-paths 'apps/web/**'
--set PATCHes; it does not reconnect. Watch paths do not change what a build produces, so changing them must not rebuild the service — and connect-repo would. This is also why the CLI had no way to express the change before: there was no PATCH-shaped command on the source at all (which is why --repo-branch, --root-dir and --no-auto-deploy still cost a rebuild today; not this PR's job).
insta compute repo names the patterns, because they change what "every push to main redeploys it" means. The line distinguishes the three cases: they narrow a push that would deploy, they are stored but inert where nothing deploys on a push at all (public repo, auto-deploy off), or there are none.
The two shapes that would lie, and don't
- The printed line carries
root_dirand the patterns, which are anchored to different roots. It now says so —(apps/api/) — … only when a push changes these repo-root paths: src/**— because a service withroot_dir: apps/apiwhose owner readssrc/**asapps/api/src/**would silently stop deploying. Both the help strings and this line say REPOSITORY ROOT for the same reason. --clearused to be documented as "back on every push" and the appended clause read "…deploys are manual (pushes do not redeploy), but only when it changes X" on a public repo. Both are false where a push cannot redeploy at all. The help says "every push that deploys this service", and the line says the patterns are stored but cannot apply.
Encoding
--set takes one comma-separated argument, because a shell expands an unquoted apps/web/** into filenames. The price is that a pattern containing a comma is unexpressible; the comment says so. An empty list is refused locally rather than sent: [] means no patterns to the server, which is the opposite of what --set was asked for — and --watch-paths '' from an unset shell variable would otherwise have connected the repo with no filter at all (that one was a truthiness test, now !== undefined, and it is pinned).
Validation stays server-side — the platform already strips a leading ./, refuses {} braces and an all-exclusions list, and caps 50 patterns / 200 characters — so the CLI does not duplicate any of it. One gap I am not closing here and have filed no workaround for: a non-empty input that normalizes to nothing server-side (--set './') is coerced to null, i.e. read as a clear. That is the platform's to refuse, and I am fixing it there rather than reimplementing the normalizer in the CLI.
Tests
Pure helpers, as this file already does: parseWatchPaths (splitting, trimming, the empty refusal), sourceBody (rides along only when given, and the empty-string case), and repoLine across the reachable public × auto_deploy × watch_paths grid — including the root_dir combination above. computeWatchPaths' --set-with---clear and empty---set guards throw before any network or config access, following test/volume.test.ts's precedent for exactly that.
Four mutation checks, each reddening: allowing --set with --clear, letting an empty --watch-paths vanish, restoring the root ambiguity, and never mutating at all. npm run typecheck, npm run build and 858 tests clean.
Summary by cubic
Adds insta compute watch-paths to show, set, or clear which repo paths trigger a redeploy, and --watch-paths on connect-repo to set them at connect time. compute repo now prints the active patterns, since they change what "every push redeploys it" means.
New Features
--setPATCHes the source instead of reconnecting, so changing watch paths never rebuilds the service.- Patterns are anchored to the repo root, not the service's
root_dir; the output line says so to avoid silently narrowing deploys. --settakes one comma-separated argument because an unquotedapps/web/**would be expanded by the shell; empty lists are refused locally.- When a push can't redeploy at all (public repo, auto-deploy off), the output says the patterns are stored but cannot apply rather than implying they'd trigger a deploy.