Repository navigation
Releases: ddtcorex/dsh-maestro-core
Releases · ddtcorex/dsh-maestro-core
Release list
v0.14.0
Changed
- BREAKING: the systemd templates run the packaged dsh runtime.
scripts/install-systemd.shnow installs adsh-web.servicethat runsnode "$DSH_BIN" web --no-openwithDSH_BIN=~/.local/share/dsh/current/bin/dshandWorkingDirectory=~/.local/share/dsh, instead of booting adeepseek-harnesscheckout through tsx. Install@deepseek-ai/dshunder~/.local/share/dsh/<version>and linkcurrentbefore running the installer. The supervisor unit passes the sameDSH_BIN. The working directory holds no.env, which dsh would otherwise load as a project env layer. restart-dsh-web.shno longer requires--repo: a systemd-managed unit needs no checkout, and without systemd the helper launchesDSH_BIN.--repo/DSH_REPOremain as the source-launch fallback.
Fixed
- Every path that boots
dsh webfollowsDSH_BINwhen it is set (resolveDshLaunch): thedsh_web_restart/dsh_web_drybootgate, thedsh_web_gcorphan fingerprint, the daemon nohup fallback and the debug-agent dry-boot. They previously always booted the source checkout, so on a packaged host the gate verified code the host does not run. WithoutDSH_BINthe source launch is unchanged.
What's Changed
- fix(supervisor): run and restart dsh from the packaged runtime by @ddtcorex in #131
- chore(release): 0.14.0 by @ddtcorex in #132
Full Changelog: v0.13.0...v0.14.0
v0.13.0
Removed
- Last-known-good snapshots and crash rollback are gone. The supervisor daemon no longer writes
~/.dsh/.supervisor/lkg/snapshots and no longer restores files on crash — a broken boot surfaces through the crash report (reports/report-<ts>.md) instead of an automatic restore. Health polling, restart on crash, Telegram notify, session auto-resume and the debug-agent still run as before. Thedsh_web_restartgate now always dry-boots since there is no snapshot baseline to compare against.
What's Changed
- feat(supervisor): remove LKG snapshots and crash rollback by @ddtcorex in #129
- chore(release): 0.13.0 by @ddtcorex in #130
Full Changelog: v0.12.1...v0.13.0
v0.12.1
Removed
- The guard no longer lists
maestro_read_fileandmaestro_write_fileas file tools. No plugin has registered them since the monolith was retired; the genericread_file,write_file,fs_readandfs_writenames stay covered.
What's Changed
- docs(core): fix rules-audit findings by @ddtcorex in #123
- chore: follow the maestro-reviewer rename by @ddtcorex in #124
- test(config): read maestro-reviewer from the meta root by @ddtcorex in #125
- test(core): read the review client from dsh-maestro-review by @ddtcorex in #126
- refactor(guard): drop the retired maestro file tool names by @ddtcorex in #127
- chore(release): 0.12.1 by @ddtcorex in #128
Full Changelog: v0.12.0...v0.12.1
v0.12.0
Removed
- BREAKING: schema v1 guard config is no longer translated.
mapLegacyConfig,loadGuardConfigWithMigration,journalConfigMigrationand theconfig-legacyjournal note are gone. A persisteddomains.guardthat still carriesgitProtection,publishBlocked,cwdContainmentorcredentialPathsnow has those keys ignored, so protection falls back to the built-in defaults until the schema v2 keys (rules,protectedBranches,protectedPaths) are set. The Settings tab no longer renders a "legacy" tier source. - BREAKING: the retired ticket store is no longer moved aside.
retireLegacyStoreandguard/migrate.tsare removed;pending.jsonis left where it is. The guard still treatslegacy-pending.jsonas a protected path. - BREAKING:
<dsh home>/maestro/settings.jsonis no longer read. The supervisor consults only<dsh home>/dsh-maestro-config/settings.json. - BREAKING: the mtime-only
~/.dsh/.supervisor/planned-restartfile is no longer honoured. Only the JSONplanned-restart.jsonmarker counts.restart-dsh-web.shnow writes that JSON marker (default pathplanned-restart.json, 180s ttl); a customDSH_SUPERVISOR_MARKERmust point at a JSON marker too. - BREAKING:
SyncService.pull()andSyncService.push()and thePullResultandPushResulttypes. Usepreview({ direction })thenapply({ previewId, direction, confirm: true }). - BREAKING: the
maestro_sync_pullandmaestro_sync_pushtools and thepullandpushsync RPC methods. They were preview-only aliases that never wrote. Agents callmaestro_sync_previewthenmaestro_sync_apply; the Sync tab already usespreviewStartandapply. - The duplicate
MaestroMarkin the sync UI kit; the sync surface imports the one inconfig/components/BrandMark.tsx.
Fixed
- Connection row injects webStartup. DSH 0.2.1-alpha.x removed the webRuntime service; a connection entry still injecting it waits for a service that never mounts and dsh web never boots.
- Journal stays silent on the rotation chmod race. Boot-time rotation can rename the live file away between appendFile and the hardening chmod; the entry is already preserved, so only ENOENT is tolerated and any other chmod failure still reports.
What's Changed
- docs(core): document requirements, pinning and the shipped connection patch by @ddtcorex in #117
- chore(core): remove dead code and legacy shims by @ddtcorex in #118
- fix(supervisor): defer RPC registration until connection is active by @ddtcorex in #119
- chore(core): drop unused markerPath parameter by @ddtcorex in #120
- DSH 0.2.1 compat: webStartup inject + journal chmod race tolerance by @ddtcorex in #121
- chore(release): 0.12.0 by @ddtcorex in #122
Full Changelog: v0.11.2...v0.12.0
v0.11.2
Fixed
- RPC rows activate on DSH 0.2.x. The bundle patch declares
webServeron theconnectionentry, so rows that callrpc.handleno longer fail withcannot get property "webServer" without injectand their channels no longer answer 405.
What's Changed
- fix(core): declare webServer on the connection entry by @ddtcorex in #115
- chore(release): 0.11.2 by @ddtcorex in #116
Full Changelog: v0.11.1...v0.11.2
v0.11.1
Fixed
- Settings fields share one box. Fields adopt the host's own
ConfigFielddeclaration plus a 44px touch floor, so the dialog no longer shows several geometries. The SSH target buttons stay on a row of their own below the field, the Maestro tab dropdowns keep 13px text, and the SSH label states a whole-pixel line-height so the hairline border cannot land on a half pixel.
What's Changed
- docs(snapshot): say "harness home" instead of the private tunnel prefix by @ddtcorex in #111
- fix(supervisor): register tools and skills in a child fiber by @ddtcorex in #112
- fix(core): adopt the shared settings field box by @ddtcorex in #113
- chore(release): 0.11.1 by @ddtcorex in #114
Full Changelog: v0.11.0...v0.11.1
v0.11.0
Security
- The
/dsh-maestro-configchannel no longer serves other plugins' secrets.
list/get/set/unsetread and wrote every domain of the shared
settings store, so any logged-in browser session — including one arriving
through the PIN-gated public tunnel — could read the GitLab token, the
webhook secret, the Telegram bot token and the tunnel credentials path in
clear text, and could write or unset another plugin's keys without that
plugin's validator. All four endpoints now accept onlyguard,
guardBlacklistandsupervisor, the domains this package's Settings card
uses;listno longer reveals foreign domain names. In-process consumers of
ctx.maestroConfigkeep the full service.
Fixed
- The boot resume scan fires at boot, not minutes later (0.10.0 and earlier).
The window was anchored onDate.now() - withinMs, which drifts minutes into
the session, so a session interrupted right before a restart was excluded from
its own recovery scan. The anchor is now the process start time, and
runAutoResumetakes the boundary as an injectable option so the behaviour is
testable rather than clock-dependent. - The Maestro Settings card renders again (0.10.0 and earlier). A refactor
trimmed the tab set and removed theerrorstate its surviving handlers still
called, so the whole section threw at render time and came up empty.
Changed
- The store cache validates mtime, inode and size. Two copies writing inside
one filesystem timestamp tick, or an out-of-band edit that restored the mtime,
served a stale document. - Lock stealing is safe. A lock carries an owner token and is released only
by its owner; a stale lock must be older than 30s (longer than the 5s acquire
timeout) and is stolen with an atomic rename that is rolled back if the moved
file turns out to be a different inode. The settings directory is created 0700
and the lock 0600. - A throwing
onChangecallback can no longer fail a write that already
landed, or drop a sibling listener. fs.watchhas anerrorlistener, so a watcher failure is logged instead
of crashing the process.- A failed store write removes its temp file instead of leaving it behind.
Added
systemd/andscripts/ship in the npm tarball. The manifest'sfiles
list excluded them, so a freshnpm install @ddtcorex/dsh-maestro-corecould
not install the supervisor daemon it publishes —scripts/install-systemd.sh
was reachable only from a git checkout.
What's Changed
- fix(client): derive the browser loader id from the manifest by @ddtcorex in #103
- fix(config): render the Maestro settings tab again by @ddtcorex in #104
- fix(supervisor): make the boot resume scan fire at boot, not minutes later by @ddtcorex in #106
- docs: record what the absorption actually preserved by @ddtcorex in #105
- docs(core): align README, AGENTS and skill with the code by @ddtcorex in #107
- fix(core): restrict the config RPC to owned domains and harden the store by @ddtcorex in #108
- fix: ship systemd/ and scripts/ in the npm tarball by @ddtcorex in #109
- chore(release): 0.11.0 by @ddtcorex in #110
Full Changelog: v0.10.0...v0.11.0
v0.10.0
Changed
- One package, four host rows. The settings store, the Maestro settings
card service, the guard and the sync engine now live in this repository as
src/host/{store,config,guard,sync}, loaded by four rows in
cordis.patch.ymlinstead of four separately installed packages. Each
repository's history is preserved and its changelog is kept under
docs/history/. - The store registers no domain validator.
store/index.tsis the file
and the atomic write; the legacy flat-key adapter moved tostore/legacy.ts
and each domain owner registers its own validator throughdefineDomain.
The guard validators ship with the guard module; the review and notifier
validators are declared by those plugins. onChangefires for writes made by another copy. An embedded store copy
watches the settings file while it has listeners, so a module that embeds the
store keeps hearing Settings writes. The watcher starts with the first
listener and stops with the last.- One client bundle.
src/client/index.tsxcomposes the auto-reload, the
settings card and the Sync card, each guarded so one failure cannot cost the
others their registration.
Added
scripts/vendor-store.mjsgenerates a consumer's embedded store copy with a
body hash, andverifyVendoredrejects a hand-edited or stale copy.exports["./store"]publishes the store as a subpath.
Removed
- The
@ddtcorex/dsh-maestro-config-libdependency, the sibling checkout in
pnpm-workspace.yamland thesibling-reposentry in CI.
Changed
- The package is published as
@ddtcorex/dsh-maestro-core— renamed from
@ddtcorex/dsh-maestro-supervisorin one sweep, because a profile carrying
half the rename resolves nothing. The repository and the workspace directory
were renamed with it. The three subpath rownamevalues in
cordis.patch.yml, the client loaderid, the source-kind label the
supervisor persists into session logs, and every runnable path inREADME.md
andAGENTS.mdmoved in the same commit. The RPC channel names
(/dsh-maestro-supervisor-resume,-session-health,-reload) and the
dsh-web-supervisorbinary name are wire protocol and did not change, so
the earlier sections of this file keep the old spelling on purpose.
What's Changed
- fix(supervisor): catch the fire-and-forget start by @ddtcorex in #93
- fix(supervisor): drop the ignored authority argument from rpc.handle by @ddtcorex in #94
- fix(supervisor): discover the session log generation instead of listing it by @ddtcorex in #95
- docs(supervisor): point skill references at dsh-safe-restart by @ddtcorex in #96
- fix(supervisor): parse CRLF skill frontmatter and attribute injected messages by @ddtcorex in #97
- chore: drop the dead dsh-client-runtime client inject edge by @ddtcorex in #98
- docs(skill): add a bundle-resolution arm to the restart preflight by @ddtcorex in #99
- fix(supervisor): report the real restart budget and daemon staleness by @ddtcorex in #100
- feat(core): absorb config-lib, config, guard and sync into one package by @ddtcorex in #101
- build(core): publish under @ddtcorex/dsh-maestro-core by @ddtcorex in #102
Full Changelog: v0.9.0...v0.10.0
v0.9.0
Fixed
- Supervisor fallback reads the shared settings store — the four
domains.supervisor.*reads pointed at~/.dsh/maestro/settings.json,
which never exists on a real install where the config lib writes
~/.dsh/dsh-maestro-config/settings.json; they now resolve the shared
path honouringDSH_HOME(#91). - A fresh install defers to the store — the hardcoded
autoResumeEnabled: trueleftcordis.patch.yml, so the UI toggle is no
longer silently overridden (#91).
Added
isAutoResumePinned()and a status RPC endpoint, so a settings UI can
render an honest locked/disabled toggle when an install-supplied Cordis
config pins the value (#91).
Changed
- Follow
@ddtcorex/dsh-maestro-config-libto^0.3.0.
What's Changed
- docs: declare package license, repository and node engine by @ddtcorex in #90
- fix(supervisor): correct settings path, remove pinned autoResume default, expose pin status by @ddtcorex in #91
- chore: release v0.9.0 by @ddtcorex in #92
Full Changelog: v0.8.4...v0.9.0
v0.8.4
Fixed
- A resumed session keeps its agent preset —
agents.resume()composes an
agent's scoped world only throughResumeAgentOptions.setup, and the resume
path passed none, so every auto-resumed session was published joined to no
preset: its tool view collapsed to the deployment-global layer and every
preset tool (bash,read,write,edit,glob,grep,subagent,
skill,todo_write,workflow,cordis_*, goal/plan/jobs) answered
Error: unknown tool "bash"for the rest of that agent's life. Measured on
the live incident: the resume header carried 76 tools instead of 110, and
agentPresets.composedPreset(agent.ctx)wasundefinedwhere a healthy
session answerscordis. Activation now delegates to
sessionController.resolveAgent— the entry point the Web API itself uses,
which composes the preset, de-duplicates concurrent resumes and returns the
live agent when the browser already re-opened the session — and falls back to
agents.resumewithsetup: agentPresets.mount(agentCtx, presetId), reading
the preset the session records (projection, then persisted header, then raw
log header). A session that records no preset still resumes bare, which is
correct for agents created outside the Web app. - A preset that cannot be composed no longer degrades into a preset-less
resume — thesetupfailure is wrapped inPresetComposeError, that one
session is skipped with aresume-failedjournal entry and an operator
notification, and the remaining sessions still resume. - An unreadable tool registry is no longer reported as healthy — the probe
returned{missing: [], visible: 0}both when nothing was missing and when it
could not read the registry at all, which is how the loss above stayed
invisible (maestro_resume_tool_healthprintedmissing=none visible=0).
Probes now carryregistry: reachable | unreachable, and the health output
rendersregistry=… composed=… repaired=…beside the tool view. - Removed the pre-delivery
bashreadiness wait — it polled the global
registry forbash, which never holds a preset tool (measured), so it could
only exhaust its budget and continue anyway; composition is now verified
against the preset roster instead.
Added
maestro_repair_session_preset— re-links one live session's agent to the
preset that session records (agentPresets.recompose, which for an agent with
no binding is its first bind). It repairs an agent that lost its preset before
this release without waiting for a restart, and reportsrepaired,
already-composed,no-preset-recorded,no-live-agentor
recompose-failed.- Automatic repair on resume (
resumeAutoRepair, defaulttrue) — after a
resumed agent is activated the roster is asked
(composedPreset(agent.ctx)) and a preset-less agent is re-linked before the
recovery prompt is delivered, so the turn the prompt starts already carries
the preset's tools. The check is skipped when it cannot be made (no roster
service, or an agent without its own context), and the config key is the kill
switch for this live re-link (setup/tools/change); with it off the loss is
still notified and parked.
What's Changed
- docs: correct the lib/ build-output claim by @ddtcorex in #80
- docs: drop hard-coded test counts by @ddtcorex in #81
- fix(supervisor): let the resume-tool-health tool report a null probe by @ddtcorex in #82
- fix(supervisor): detect an interrupted long turn by the log mtime by @ddtcorex in #83
- fix(supervisor): retry a resume blocked by another owner's write handle by @ddtcorex in #84
- fix(supervisor): continue a session the restarted host already owns by @ddtcorex in #85
- fix(supervisor): gate both resume paths on bash being registered by @ddtcorex in #86
- chore: release v0.8.3 by @ddtcorex in #87
- fix(supervisor): resume a session under its agent preset by @ddtcorex in #88
- chore: release v0.8.4 by @ddtcorex in #89
Full Changelog: v0.8.2...v0.8.4