7 Commits
Author SHA1 Message Date
Yiğit ERDOĞANandClaude Opus 5 9769237d36 fix: Lobster cannot create its cache or state directories on Windows (#126)
* fix(state): normalize extended-length mkdir paths

On Windows fs.mkdir(recursive) reports the first created directory as an
extended-length path (\?\C:\...) while the requested directory is a plain
drive path. path.resolve keeps the prefix, so the two never compare equal
and path.relative between them yields an absolute path. The chain walk then
takes "C:" as its next segment and syncs a directory that does not exist,
so ensureDirectory throws ENOENT every time it actually creates something.

That breaks LLM cache writes, state.set, diff snapshots, and approval index
publication on the first Windows run.

Strip the prefix before resolving so both ends of the chain share one root
form. On POSIX the prefixes never occur and the walk is unchanged.

* fix(state): keep device namespaces out of the path normalization

Stripping every \?\ prefix also rewrote namespaces that have no plain
equivalent, so an explicitly configured LOBSTER_STATE_DIR such as
\?\Volume{GUID}\lobster\state became relative and resolved against the
current drive. That regressed a form main handles today.

Map only the drive-letter and UNC namespaces, which do have a plain
equivalent, and return anything else untouched. Cover the mapping directly
so the device-namespace case is pinned.

* fix(state): recognise the UNC namespace whatever its case

Windows compares path namespace components case-insensitively, so
`\?\unc\server\share` names the same share as `\?\UNC\server\share`.
Matching only the uppercase form left the lowercase spelling extended
while the directory it walks toward is plain, so the sync walk could
never reach the requested final path on such a setup.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011gD5sJTbh2jn1uvgNCmkLq

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 12:22:56 -07:00
xingzhouandPeter Steinberger c440ca57d1 fix(runtime): cancelled workflows no longer continue external commands (#119)
* fix(runtime): stop process-backed work on cancellation

* fix(runtime): invalidate cancelled resume state

* Revert "fix(runtime): invalidate cancelled resume state"

This reverts commit 0f7d291f98.

* fix(runtime): narrow cancellation to safe child processes

* fix(runtime): stop after completed search cancellation

* fix(runtime): halt direct pipelines after cancellation

Preserve completed in-flight stage results while preventing later direct pipeline stages from starting after parent cancellation.

* fix(runtime): consume aborted approval resumes

* fix(runtime): cancelled workflows no longer continue external commands

* fix(workflow): propagate custom parent cancellation

* fix(runtime): preserve pre-aborted resume state

* fix(runtime): stop lazy handoff after cancellation

* fix(workflow): close remaining cancellation boundaries

* fix(runtime): preserve workflow resumes during setup cancellation

* fix(runtime): close final cancellation persistence gaps

* fix(runtime): stop lazy handoff after cancellation

* fix(runtime): interrupt blocked lazy handoff reads

* fix(runtime): terminate cancellation process trees

* fix(runtime): await process tree termination

* fix(runtime): terminate workflow process trees

* fix(runtime): bridge CLI cancellation

* fix(cli): preserve cancellation lifecycle

* fix(cli): abort stalled signal-aware commands

* fix(cli): release aborted interactive prompts

* fix(cli): preserve sequential prompt input

* fix(cli): preserve buffered prompt input

* fix(cli): handle prompt EOF after buffered input

* fix(runtime): preserve UTF-8 subprocess output

* fix(workflow): preserve retryable resume before execution

* fix(workflow): roll back cancelled resume replacement

* fix(state): roll back cancelled monitor snapshot

* fix(resume): preserve cancelled gate capabilities

* fix(resume): close cancellation rollback windows

* fix(resume): harden cancellation state cleanup

* fix(runtime): close resumed cancellation gaps

* fix(runtime): preserve cancellation cleanup

* fix(runtime): close cancellation lifecycle gaps

* fix(runtime): harden resumed cancellation boundaries

* fix(workflow): consume timed-out resume capabilities

* fix(workflow): preserve resume policy boundaries

* fix(runtime): preserve cancellation cleanup liveness

* fix(runtime): harden cancellation cleanup

* fix(runtime): stop lazy output after cancellation

* fix(runtime): settle cancellation cleanup

* fix(runtime): preserve safe input resumes

* fix(runtime): prevent consumed resume replays

* fix(runtime): serialize approval resume consumption

* fix(runtime): prevent concurrent safe gate forks

* fix(runtime): close cancellation review gaps

* fix(llm): restore cache after cancelled refresh

* fix(runtime): close remaining cancellation windows

* fix(runtime): preserve cancellation recovery invariants

* fix(runtime): prevent stale resume recovery

* fix(runtime): preserve resume claim recovery

* fix(runtime): retry pre-dispatch claims safely

* fix(state): synchronize rollback-safe reads

* fix(resume): discard cancelled pipeline successors

* fix(runtime): harden cancellation and state locking

* fix(runtime): recover durable cancellation failures

* fix(runtime): preserve legacy workflow cancellation

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-13 10:54:20 -07:00
Vincent Koc d9a0fe7e02 style: format lobster sources 2026-06-22 14:26:35 +08:00
Andy Ye 69dcc88cad fix: harden disposable persistence writes
Harden LLM cache files, diff snapshots, and approval ID indexes against truncated or malformed JSON after process termination.

Disposable cache and snapshot corruption now recovers as a miss; authoritative resume state still surfaces malformed JSON. Approval short-ID indexes use atomic no-overwrite publication and degrade to full resume-token approval when the index cannot be published durably.

Closes #111.
Closes #112.
Closes #113.

Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
2026-06-10 00:36:09 -07:00
Krasimir KralevandKrasimir Kralev 1679bed1a4 fix(state): write state atomically
Fixes #108 and #109.

- Replace direct state writes with same-directory atomic temp-file writes.
- Preserve existing file modes and create new state files as 0600.
- Clean up temp files on failed replacement paths.
- Add state/SDK regression coverage plus changelog entry.

Proof:
- pnpm run typecheck
- node --test dist/test/state.test.js dist/test/resume.test.js dist/test/multi_approval_resume.test.js dist/test/approve_preview.test.js
- pnpm run lint
- pnpm run test
- built SDK write/read proof preserved 0600 across replacement
- autoreview clean: no accepted/actionable findings

Co-authored-by: Krasimir Kralev <krasi@idrobots.com>
2026-06-03 14:05:28 -07:00
Peter Steinberger e4514ecad5 style: format with oxfmt 2026-05-04 01:56:15 +01:00
Vignesh Natarajan 5f8a64e695 feat: migrate lobster to TypeScript and oxlint 2026-01-21 21:42:06 -08:00