dfa4d384e940ee9f7e2eec4af8a0059acac28a06
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ac8db54ecb |
Add svc.sh update command: auto-detect repo advances and refresh services
Why: After the repository moves forward, updating a running service meant manually figuring out the new commit, rebuilding and redeploying by hand; the user asked for the tool to detect and update automatically. Evidence: - "update [name...] [--check] [--all] [--no-fetch]": fetches origin, compares each service's registered source against the latest (Dev repo origin/main for local@/dev@ sources, newest Releases version for release@), prints a per-service table (current / latest / state), and without --check refreshes outdated running services by reusing the full deploy pipeline (stop → build/verify → start → health check; persisted exec= config and tags survive; update events appended to history). - local@ services: auto git pull --ff-only origin main + make sync before rebuilding, guarded three ways (current branch == main, clean worktree, ff-only) — dirty trees or non-main branches are skipped with a warning, never touching uncommitted work. - dev@ sources go straight to the remote main commit via an isolated worktree; release@ sources deploy the newest Releases version with sha256 verification; postgres and static --dir services are reported as not applicable; sources that diverged from or lead the remote are never force-updated. - Verified end to end with five test services: dev@73b2802 → dev@ffda6d3 (real isolated build, HTTP 200, tag/port preserved, worktree recycled), non-main-branch skip, stopped-service warning vs --all, release sha256-verified update, --check read-only (svc.env checksums unchanged), unregistered name exits 2. - Fixed en route: a latent bug from the v2 refactor — materialize_dev_commit leaked submodule/make stdout into the captured worktree path, breaking every real dev@sha deploy since (cp: File name too long); build output now goes to stderr. Also fixed an unbound-variable crash in the update loop (local statement self-reference under set -u). Impact: New read-mostly operational command; no behavior change to existing commands except dev@sha deploys now actually working end to end. Makefile gains svc-update; --help and docs/svc.md document the command. Refs: .task/feature-svc-auto-update.md(任务卡=PR 描述) |
||
|
|
2c7f55bfe8 |
Document svc.sh comprehensively and layer its help system
Why: svc.sh grew into a three-kind service manager with database operations, but its only documentation was a flat --help wall of text; the user asked for a complete usage document and a better help experience. Evidence: - docs/svc.md: 14-section manual (prerequisites, quick start, concepts and directory layout, per-command reference for service/global/db commands, deploy sources, database operations handbook, configuration layering, registry fields and event types, safety boundaries, exit codes, troubleshooting table, recipe index) — every claim cross-checked against the implementation from the previous two rounds. - Help layering: no-args and -h print a one-screen overview; --help renders the header comment reorganized into 7 labeled sections; the new "help [topic]" command deep-dives eight topics (model, deploy, lifecycle, db, dbops, config, examples, safety); usage errors now show the short overview plus a pointer to --help / help / docs/svc.md. All topics verified to render; unknown topic exits 2. - No runtime behavior changed: end-to-end db lifecycle regression (create → start → backup → status → stop → rm --purge) passes after the refactor. - Makefile help and README's documentation section point to docs/svc.md. Impact: Documentation-only plus display-layer changes; command semantics, exit codes and file formats are untouched. Maintenance note: behavior changes must now update both --help and docs/svc.md. Refs: .task/feature-svc-docs-help.md(任务卡=PR 描述) |
||
|
|
69871136e5 |
Add db ops to svc.sh: port change, backup, restore, clone, cross-instance copy
Why: The service manager could create and run postgres instances but had no way to retarget a port explicitly, back data up, clone an instance to another port, or move a database between instances — the user asked for exactly these operations. Evidence: - "set <name> [--port N] [--host H] [--apply] [--tag T...]": explicit registration change; running postgres requires --apply (stop → rewrite registration → start); port availability checked against both registrations and live listeners. Verified: 8890→8895 with data intact and DSN updated, old port freed; refusal without --apply. - "db backup <name> [--db X] [--out F]": pg_dump -Fc into runtime/<name>/backups/ (0600) with pg_restore --list self-check; "db backups" lists them. - "db restore <name> --file F [--db X] [--force]": restores into a new db or refuses on a non-empty target unless --force (drop with FORCE + recreate + restore), reporting table counts afterwards. Verified all three paths. - "db clone <src> <dst> [--port P] [--password PW] [--tag] [--online]": default physical clone (brief source stop, cp -a of pgdata minus postmaster files, new registration, source restarted on its own port); --online copies via dump/restore without stopping the source (verified source pid unchanged). Clone lands on the requested or derived port. - "db copy <src> <dst> [--db X] [--force]": single-database logical move between two running instances with the same non-empty-target guard. "db ls <name>" lists databases. - Fixed during verification: clone/copy leaked the CLI --port into the source restart path (source briefly came up on the clone's port); the address overrides are now cleared inside those commands. Impact: All operations stay inside runtime/<name>/, append to history.jsonl, and reuse the existing safety constraints (own-process stop, port conflicts reported not seized, secrets in 0600 files). Overwriting a non-empty database requires an explicit --force everywhere. Makefile help line mentions the new db subcommands. Refs: .task/feature-svc-db-ops.md(任务卡=PR 描述) |
||
|
|
60261a835a |
Generalize svc.sh into a multi-kind service manager with tags and persistence
Why: svc.sh only managed agent-system environments; databases, standalone frontend serving, per-service tags and reusable start configs were out of scope, and the user asked for a unified service lifecycle on this host. Evidence: - Service model v2: kind=agent|static|postgres registered in runtime/<name>/svc.env (dotenv, mode 600); legacy entries without kind= are adopted as agent. - postgres: "db create <name> --port/--user/--password/--db/--auth-mode/ --tag" runs initdb (scram-sha-256, pwfile 0600), start/stop/restart use pg_ctl (-m fast, never SIGKILL on postmaster) with pg_isready checks and first-start database creation; "db dsn <name> [--reveal]" prints a composable DSN (password masked by default). Verified end to end against a real postgresql@18 instance: data survives restart, wrong passwords rejected, stop/restart clean. - static: "deploy --kind static --from dev[@sha]|local" builds frontend dist into htdocs/ in an isolated worktree, or "--dir PATH" serves an existing directory; verified serving HTTP 200, restart, stop, dry-run plan, and explicit rejection of release sources. - agent: unchanged three deploy sources plus --tag; bare start/restart now reuses the persisted exec= from svc.env (verified: same custom port and args across restart); old binaries lacking --dsn/--auth get those flags auto-omitted with a warning. - "list|status [--tag]" shows NAME/KIND/STATE/PID/ADDR/SOURCE/TAGS for all registered services; "<name> status" gives per-kind detail; "rm <name> [--purge]" unregisters (and optionally deletes) only runtime/<name>/. - Fixed during verification: psql arg mangling (-c -c), tags lost because record_state read svc.env inside its own redirect block, postgres --version field parsing, unbound vars for unregistered names. Impact: Same invariants as before: writes stay under runtime/<name>/ and runtime/.worktrees/ (only --from local also writes main-checkout build outputs, all gitignored), stops only own pidfile+cmdline-verified processes, port conflicts reported not seized. Prompt output moved to stderr so stdout (tables, DSNs) stays pipeable. Makefile gains svc-list. Refs: .task/feature-svc-services-registry.md(任务卡=PR 描述) |
||
|
|
8ba1b0e715 |
Add commit-picked deploys and a service registry to svc.sh
Why:
svc.sh only knew two hardcoded environments (dev/prod) and always built
the current workspace, so there was no way to deploy a specific Dev- repo
commit or a Releases artifact, and no record of what was actually started.
Evidence:
- scripts/svc.sh commits dev|release lists deployable commits (release
entries annotated with version + devCommit; both mark HEAD and the
environments already running them).
- deploy --from local|dev@<sha>|release@<version|sha> materializes the
chosen source: dev commits build in an isolated worktree
(runtime/.worktrees/<sha>, submodule pins verified to land exactly),
release artifacts are sha256-verified against versions/<v>/manifest.json
(a forged manifest is refused); --pick offers an interactive numbered
choice and --dry-run prints the plan.
- Environment names are generalized (^[a-z][a-z0-9-]{0,15}$, derived port
8800-9099 on collision-free scan); each env is self-contained under
runtime/<env>/{bin,plugins,data} with svc.env (current state) and
history.jsonl (append-only deploy/start/stop events). status scans all
registered envs and history [env] [N] merges the event stream.
- Old artifacts that predate --dsn/--auth have those flags auto-omitted
(probed via serve usage); legacy svc.env files still render in status.
- Verified end to end in the task worktree: stub-binary lifecycle, a real
release@0.1.0 deploy (HTTP 200, source shown in status, commits marked),
failure paths (sha mismatch, immediate exit, non-TTY --pick).
Impact:
scripts/svc.sh users gain multi-version side-by-side environments and
rollback by redeploying an older source; existing dev/prod defaults and
safety constraints (own-pidfile-only stop, port-occupancy check) are
unchanged. Environments deployed by the previous script need one fresh
deploy before start/restart works again. Makefile gains svc-commits and
svc-history targets.
Refs: .task/feature-svc-deploy-source-registry.md(任务卡=PR 描述)
|
||
|
|
2460e49157 |
Support --env config files with CLI override
Why: per-environment bring-up needs a persistent file for the SVC_* knobs (model keys, addresses, tavily pool) instead of relying on shell history or the single global .svc.env; CLI flags must still win for one-off overrides like a different port. Evidence: live matrix - .env.dev parsed (comments, paired quotes, export prefix) with its address and model values applied and seeded; --port 8831 overrode the file's port while keeping its 0.0.0.0 host; missing file fails fast; .svc.env and --env layer correctly (overlap keys resolve to --env, disjoint keys merge). Impact: --env FILE / --env=FILE anywhere on the command line; dotenv parsed safely line-by-line (valid identifiers only, never sourced); precedence CLI > --env file > .svc.env > OS env > defaults; help and make svc ARGS examples updated. Refs: feature/svc-envfile task card. |
||
|
|
81ac0ca5c2 |
Seed model and search settings on service start
Why: a freshly deployed environment boots with an empty settings store, so the first run dies with "main model unconfigured" and the user has to open the settings UI before anything works - the opposite of one-command bring-up. Evidence: live matrix - full seed (chat+lightweight+tavily) lands in the settings store (API view shows baseUrl/model with the key masked), restart without flags does not re-seed and the settings persist, .svc.env sourcing seeds a fresh environment from the one-time config file, and a no-flag start stays silent. Also wrapped a /proc read race in pid_alive that printed tr noise during stop. Impact: --model-base/--model-key/--model-name, --light-base/-key/ -name, --tavily-keys on start/deploy (idempotent, only provided fields); SVC_MODEL_*/SVC_LIGHT_*/SVC_TAVILY_KEYS env vars; <repo>/ .svc.env one-time config file (gitignored) makes every future deploy self-configuring; auth-protected instances fall back to a clear hint. Refs: feature/svc-auto-seed task card. |
||
|
|
8a494e87c7 |
Add CLI flags to svc.sh (addr/host/port/data/dsn/auth/mock/passthrough)
Why: the manager only took configuration from SVC_* environment variables; binding a public interface or pointing at a database meant exporting vars first, which is awkward for one-off deploys and invisible in shell history review. Evidence: live matrix on the worktree - --port (8801), --host 0.0.0.0 (bind verified via ss, health probe auto-maps to 127.0.0.1), --addr whole-form, CLI-over-env precedence (--port beats SVC_DEV_ADDR), --mock reaching the server cmdline, --dsn passthrough proven by the postgres connect attempt in the log, -- passthrough (--artifacts), and make svc ARGS passthrough. A set -e silent-exit trap in env_config was caught by the first run and fixed (condition-as-last-statement). Impact: scripts/svc.sh <env> [action] [--addr|--host|--port|--data| --dsn|--auth|--mock|--plugins| -- <extra>]; precedence CLI > env vars > defaults; help rewritten with examples; make svc gains ARGS; logs keeps the positional line-count form. The real-world port guard held: a dev instance started from the main checkout was refused with owner info, untouched. Refs: feature/svc-cli-args task card. |
||
|
|
35d114307d |
Add the svc.sh environment service manager
Why: deploying a new build meant manually finding and killing the old
process, rebuilding and re-launching with the right flags; dev and prod
instances could collide on ports, data dirs or kill each other.
Evidence: live matrix on the worktree - dev deploy (stop -> make build
-> start with health check), redeploy swaps the pid and keeps seeded
data, prod deploys alongside dev on separate port/data with fully
isolated /api/projects, port takeover is refused with the owning
process named while the running env stays up, stop clears pidfile and
frees the port. A pid-capture bug (compound-background subshell wrote
the wrapper pid instead of the server) was caught and fixed during the
first live run.
Impact: scripts/svc.sh <dev|prod> [deploy|stop|start|restart|status|
logs]; runtime/<env>/{data,svc.pid,svc.log,svc.env} isolation; defaults
dev 127.0.0.1:8788 / prod 127.0.0.1:8787 overridable via SVC_* env
vars (incl. SVC_PROD_DSN for the PG tier); make svc ENV=... shortcut;
runtime/ gitignored. Safety: only processes started by the script are
stopped (pidfile + /proc cmdline double check).
Refs: feature/svc-env-script task card.
|