SQLite needs write access to the repo directory to create journal files
alongside pipekit.db. Fixed by setting group pipekit + g+w on the
directory itself only (not recursive).
Driver registration now matches existing rows by kind before falling
back to name, so re-deploys update the correct row regardless of what
name was used at initial registration.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
deploy.sh now prints each step with what it's doing, adds the invoking
user to the pipekit group automatically, uses --home-dir /nonexistent
for the system user, and passes --no-cache-dir to pip to suppress the
home directory warning.
cli.py: removed the kind-based early-exit in drivers register that was
short-circuiting before the upsert logic, so re-running deploy now
correctly updates existing driver rows rather than printing "already
registered". Also removed the now-unused --force flag.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Scheduling: cron-based group runs via a daemon thread (scheduler.py)
started at API startup. Schedules managed inline on the group edit form.
last_fired_at persisted before run to prevent double-fire on restart.
Requires croniter (added to requirements.txt); DB migration adds
last_fired_at column to schedule table.
Deploy: deploy.sh now creates the pipekit system user, chowns the repo,
builds the venv as pipekit, and installs/enables the systemd unit.
systemd/pipekit.service is now a production-ready unit (User=pipekit
uncommented). pipekit secrets set preserves existing file permissions
instead of resetting to 0600. Driver registration is now idempotent
(upsert via get_driver_by_name + update_driver).
Docs: CLAUDE.md and SPEC.md updated to reflect groups, scheduling,
scheduler-in-API-process architecture, TUI deferred (not dropped),
stop-on-failure tradeoff, jrunner as prerequisite, and deploy flow.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
cmd_serve now reads api_host from Config with a 127.0.0.1 safe default,
matching the existing api_port pattern. --host/--port CLI flags still
override. Local config is bumped to bind 0.0.0.0:8200.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
deploy.sh is the idempotent rollout path: venv + deps, launcher,
/etc/pipekit/secrets.env skeleton (mode 0600), schema init, and
auto-register of every JDBC driver shipped with jrunner. systemd
unit is a template, not auto-installed — user copies it when ready
to cut over.
`pipekit secrets {list,set,unset}` manages /etc/pipekit/secrets.env
with atomic 0600 writes so passwords don't need sudoedit. Prompted
input by default; positional value allowed for scripting.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Registers a driver-table row from the CLI. Kind is validated against
the code-level driver registry; JDBC class names default from a
built-in table (db2, pg, mssql). Refuses to double-register a kind
unless --force is passed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Orchestration layer around the jrunner Java JDBC CLI, replacing the
previous shell-based sync system in .archive/pre-rewrite. Includes
the FastAPI + Jinja web frontend, per-driver adapters (DB2, MSSQL,
PG), wizard-driven module creation with editable dest types and
source-sourced table/column descriptions, watermark/hook CRUD,
and the engine that runs modules end-to-end.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>