Commit Graph
179 Commits
Author SHA1 Message Date
Chinesezjc 18e3f39ff6 fix(subprocess): cover the bundled console host in the packaged smoke
Review follow-ups: the Electron payload smoke allocates the way the product
does on Windows, so the packaged tree resolves the console host assets it now
depends on; the README states that dependency and its loud failure as a known
limitation; the terminal handle takes the platform this method already
resolved; and the note links the earlier tail-grace note, records why that
grace cannot cover a malformed tail, and drops the claim that the smoke
exercises the operating system host.
2026-09-28 16:34:06 +08:00
Chinesezjc 707b0d98cc fix(subprocess): name the bundled console host in the docs and comments
The README, the Ctrl-C comment, and the bare-kill comment still described
Windows' own console host as the one backing the PTY. Name the host the code
now selects, record the exit-event behaviour of both teardown paths measured on
the pool machine, state that a missing conpty asset fails loud, and move the
note to the bug-fix class next to the other Windows console fix. The terminal
case now asserts the option key is absent on POSIX rather than not true.
2026-09-28 16:19:38 +08:00
Chinesezjc 59ba1321eb fix(subprocess): back Windows terminals with node-pty's bundled console host
The console host Windows provides, on the images the master standby pool runs
(Server 2022, Windows 10 22H2), replays a prompt line that scrolled out of the
viewport as `\ndsh>\x1b[1C`: the trailing space becomes a cursor move, so the
persistent-pwsh readiness path never sees its `dsh> ` tail and every send waits
out the silence tier. The same case passes on the Blacksmith Windows image,
whose console host emits the tail verbatim.

Allocate Windows PTYs with `useConptyDll: true`, so the PTY is backed by the
OpenConsole the node-pty package ships. The option is set only for `win32`;
the terminal spec pins it per platform.

Probing the pool machine with the bundled console host rendered the `dsh> `
tail for all seven prompts of the failing case's command sequence, and
`pty.pid` still resolves to `pwsh.exe` and equals the shell's own `$PID`.
2026-09-28 16:07:57 +08:00
winewill c22b226b18 fix: address review threads on the fatal-diagnostics PR
- Agent Notes: cross-link the new decision with the native fatal recovery
  and fail-loud release notes both ways, rewrite the older note's
  console-retention and dialog-detail facts in place, and state the report's
  actual bounds.
- crash-report: cut the rendered error section at 256 KiB and prune only
  files matching the generated crash-<time>-<source>.log syntax.
- main: backendReady follows the backend state except during shutdown, so a
  failure while tearing down a ready backend still reads as running.
- subprocess-local: the temporary-file-cleaner hint is appended only for
  ENOENT; other codes rely on the appended error.
- client-modules: describeError is module-private; BootModuleRow.url's
  JSDoc names its fallback role.
2026-09-22 18:20:12 +08:00
winewill cafb9b93b4 fix: address adversarial review of the fatal-diagnostics branch
client-modules: a batch that already executed is never requested again,
even when its first importer was a row it did register — every executed
batch URL is remembered and a still-missing row goes straight to its
one-resource URL. The in-process module system test in test-support is
updated to the aggregated arrival message. describeError replaces three
inline non-Error ternaries and is covered.

subprocess-local: the spill path is published only after the exclusive
open succeeds, so a failed open (EEXIST on a planted entry included) can no
longer unlink a path this process did not create; a reporter that throws is
contained and written to stderr; logSpillFailure builds the owner reporter
for both the runtime and the SSH helper so the logging path is exercised
once instead of duplicated. Tests cover the runtime logger, the bare-caller
stderr default, EEXIST, and a throwing reporter.

desktop: a fatal failure during shutdown still writes its report; the
report phase follows the backend state so a failure during a restart is
'startup' again; writeReport is a required recovery operation and the
dialog tests await the write; the shell pid is labelled; the withheld
response-header list states why set-cookie is dropped.

app-boot, READMEs, Agent Note: "never resumes" is restated as control never
returning to the failed operation while the loop runs until release
settles; inspect output is bounded; incident inferences (who removed the
spill directory, which batch failure occurred) are written as inferences.
2026-09-22 14:41:10 +08:00
winewill cfa84ed4e3 fix(subprocess-local): contain spill file failures instead of killing the host
OutputCollector.spillAll ran openSync/writeSync inside the stream 'data'
listener with no containment. When the private per-process spill directory
had been removed by a temporary-file cleaner, the first overflowing chunk
threw ENOENT from Pipe.onStreamRead, became an uncaught exception in the
Desktop Host, and the Electron shell reported it as a fatal failure.

Spilling is best-effort by contract (spillPath is optional; a failed final
close already withholds it). Every filesystem failure while opening or
appending the spill file now discards the spill, reports once through the
owner's logger, and leaves in-memory collection untouched. Spill inputs move
into one SpillOptions object with the reporter, so tail-only collectors no
longer pass an empty directory; prepareManagedProcessBinding is the explicit
resolve step for the directory and reporter defaults, and the runtime and
SSH helper supply their plugin loggers.

Tests cover ENOENT on open (removed directory), ENOTDIR on open, and ENOSPC
on append after the file exists, asserting the tail stays byte-exact, the
spill file is withdrawn, and the reporter fires once.
2026-09-22 12:40:07 +08:00
Tianyi Cui 580bdc7258 refactor: remove redundant unknown casts 2026-09-19 20:13:58 +08:00
07akioni f8b1309fe5 fix(subprocess): hide Windows shell console windows at creation 2026-09-16 18:56:39 +08:00
Yichen Jiang ad8a00c291 Merge remote-tracking branch 'origin/master' into worktree/sidebar-session-recovery
# Conflicts:
#	packages/subprocess/subprocess-local/src/index.ts
2026-09-15 12:15:20 +08:00
Yichen Jiang 281723bed8 fix(web): isolate terminal bindings and validate saved layouts 2026-09-15 12:07:01 +08:00
imccyu 232ab768a9 perf(runtime): defer optional native dependencies 2026-09-15 11:06:43 +08:00
Yichen Jiang b25c5ad82e feat(web): restore sidebar layouts and reclaim unattended terminals 2026-09-15 10:27:44 +08:00
Yichen Jiang 1b7b50bbe1 Merge remote-tracking branch 'origin/master' into worktree/web-sidebar-terminal
# Conflicts:
#	apps/web/package.json
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	packages/api/remotes/src/client/index.ts
#	packages/e2b/subprocess-e2b/README.md
#	packages/e2b/subprocess-e2b/README.zh.md
#	packages/e2b/subprocess-e2b/src/index.ts
#	packages/e2b/subprocess-e2b/src/terminal.ts
#	packages/e2b/subprocess-e2b/tests/subprocess.spec.ts
#	packages/e2b/subprocess-e2b/tests/terminal.spec.ts
#	packages/mcp/mcp-resources/README.i18n.yaml
#	pnpm-lock.yaml
#	scripts/verify-package-readme-model-experience.ts
#	snapshots/session/cordis-inspect-jsdoc/session.v3.jsonl
#	tsconfig.base.json
#	tsconfig.client.json
#	tsconfig.host.json
2026-09-14 10:36:31 +08:00
Tianyi Cui dd55f38614 docs(subprocess): record signal error isolation and fixture safety 2026-09-12 19:44:51 +08:00
Tianyi Cui 71334b9c78 fix(subprocess): preserve direct outcomes on signal failure 2026-09-12 19:14:34 +08:00
Tianyi Cui c07df5aa65 fix(subprocess): confirm direct SIGKILL after group delivery 2026-09-12 18:49:15 +08:00
Tianyi Cui 4b99ace8fb fix(subprocess): await direct fallback settlement before scope failure 2026-09-12 17:55:53 +08:00
Tianyi Cui abb7c6a49d fix(ssh): join transport cleanup and preserve collected output 2026-09-12 15:03:03 +08:00
Tianyi Cui 4fb0fdac68 feat(ssh): checkpoint POSIX helper and remote providers 2026-09-12 15:03:03 +08:00
Tianyi Cui 562e7f364e fix(subprocess): await control endpoint closure during disposal 2026-09-12 15:03:01 +08:00
Tianyi Cui 838da1d07e fix(subprocess): separate process quiescence from caller control streams 2026-09-12 15:03:01 +08:00
Tianyi Cui 83a45679df fix(subprocess): create control carriers for overlapped Windows I/O 2026-09-12 15:03:00 +08:00
Tianyi Cui d8efd4f8cd feat(subprocess): carry a duplex control pipe through managed launches 2026-09-12 15:03:00 +08:00
Dudu-0223 dafff8e51c fix(subprocess): settle consumed empty scopes before exit notification 2026-09-11 17:05:15 +08:00
turtle1999 18a1955b7e fix(ci): handle scope termination races and cyclic process snapshots 2026-09-11 14:50:46 +08:00
turtle1999 aaa02a3970 fix(subprocess): settle a Linux scope left active with no processes
Range observation waited for an active transient scope to leave `active`
before it would prove the managed range empty. systemd ends a scope only when
it observes the populated-to-empty transition, so a payload killed before the
manager placed it in the scope's cgroup leaves the unit active with an empty
cgroup forever. `waitForExit()` then polled a unit that could not change, and
`LocalSubprocessRuntime.disposeManagedProcesses()` awaited it without bound —
teardown hung for any command cancelled immediately after spawn.

Each state query now also reads the unit's process count. Once termination was
requested and the launcher has exited, a still-active unit reporting no
processes is the empty range: the launcher forked every process it will ever
fork, so nothing later joins that cgroup. The owner stops the leftover unit so
transient units cannot accumulate, and an unreported or `[not set]` count
stays unknown and keeps waiting.

The race needs a live user-systemd manager, so it stayed dormant wherever the
native scope path was unavailable and surfaced once CI routed lanes onto the
Blacksmith hosted image, whose runners accept that path. Ten repetitions of
`local.spec.ts > disposal kills still-running processes and awaits their exit`
in a Linux container with a user manager failed seven times before the change
and passed ten times after it.
2026-09-10 17:27:52 +08:00
Yichen Jiang b79a227cec fix(subprocess): preserve Linux cancellation before bootstrap consumption 2026-09-10 14:45:45 +08:00
Yichen Jiang 0a525601a7 fix(web): harden sidebar terminal lifecycle and recovery 2026-09-09 18:17:47 +08:00
Yichen Jiang e15a9b1bec feat(web): add interactive sidebar terminals 2026-09-09 16:40:58 +08:00
pku-xht e9f1b6c53e Merge remote-tracking branch 'origin/master' into codex/subprocess-native-containment
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.md
#	.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.zh.md
#	.agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.i18n.yaml
#	.agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.i18n.yaml
#	.agents/notes/implemented/architecture/2026-09-06-embedded-stream-record-readers.i18n.yaml
#	.agents/notes/implemented/bug-fix/2026-09-03-normalized-unread-fs-tool-diagnostic.i18n.yaml
#	.agents/notes/implemented/bug-fix/2026-09-06-windows-python-console-spawn-wait.i18n.yaml
#	.agents/notes/implemented/feature/2026-08-26-generic-file-upload.i18n.yaml
#	.agents/notes/implemented/feature/2026-09-07-model-switch-notice.i18n.yaml
#	.agents/notes/implemented/process/2026-09-03-semantic-issue-templates-and-policy.i18n.yaml
#	packages/shell/bash-local/tests/executor.spec.ts
#	packages/subprocess/subprocess-local/README.i18n.yaml
#	packages/subprocess/subprocess-local/README.md
#	packages/subprocess/subprocess-local/README.zh.md
#	packages/subprocess/subprocess-local/src/spawn.ts
#	packages/subprocess/subprocess-local/tests/spawn.spec.ts
#	packages/subprocess/win32-process/package.json
2026-09-07 17:43:45 +08:00
Chinesezjc 1f0a87eb06 Merge remote-tracking branch 'origin/master' into fix/test-tmp-teardown-self-clean
# Conflicts:
#	packages/subprocess/subprocess-local/tests/spawn.spec.ts
2026-09-04 11:58:16 +08:00
pku-xht e82e5ffd7a fix(subprocess): normalize PTY scope launcher environment 2026-09-04 02:58:09 +08:00
pku-xht d82fd86c5c fix(subprocess): isolate native runner bootstrap 2026-09-04 00:24:52 +08:00
pku-xht 423412b7bf fix(runtime): simplify executable entry dispatch 2026-09-03 21:18:27 +08:00
Turtle a05b5fbe79 fix(subprocess): hide Windows cleanup helpers 2026-09-03 19:01:30 +08:00
Chinesezjc c8fc38541f test: own the default spill dir in subprocess specs; correct retention wording
Second review round (ds-review-bot v4p/v5/v6): the exit cleanup claim that
collectors unlink their spill files on dispose was wrong — completed spill
files are retained (seal() only closes, discardSpill() is the only unlink),
so the exit removal only ever applies to directories that never spilled.
Reword the JSDoc, README, and Agent Note accordingly, drop the redundant
readdirSync precheck (rmdirSync ENOTEMPTY is caught anyway), and recount the
v8-ignore window. The spawn.spec default-spill test now records the default
per-process directory it created and removes it in afterAll, so a completed
spill file is never left behind by the unit suite.
2026-09-03 17:29:21 +08:00
Chinesezjc 1bc330ce01 docs: cross-link the spill retention decision from the teardown note
The Agent Note now links the 2026-07-17 local-spill-startup-cleanup note it
builds on, and the privateSpillDir JSDoc documents the empty-dir exit
removal alongside the directory's creation contract.
2026-09-03 17:07:43 +08:00
Chinesezjc 29e6669e3c test: narrow process-exit spill cleanup to empty dirs; drop spill-store deletion
Review (ds-review-bot) found the exit-time deletion of per-process spill
roots conflicts with the documented retention decision: spill artifacts are
model-visible locators that resumed or forked sessions may still reference
(2026-07-17-local-spill-startup-cleanup), and an exception thrown from an
'exit' listener can change the process exit code.

- dsh-spill-local: revert the exit handler entirely; its default root is
  already owned by the package's 30-day startup sweep.
- dsh-subprocess-local/spawn: remove the per-process spill dir at a
  JavaScript-observable exit only while it is EMPTY (collectors unlink
  their spill files on dispose), best-effort with a named swallow so a
  Windows-held handle never changes the exit code; dirs holding spill
  files keep them for external cleanup.
- Document the empty-dir exit removal in the package README and the Agent
  Note, and re-record both bilingual pairs.
2026-09-03 17:06:48 +08:00
Turtle cc8099dc5f fix(subprocess): hide Windows child windows 2026-09-03 17:05:18 +08:00
Chinesezjc 6d9776a3b0 test: exempt process-exit spill cleanup from the per-file coverage gate
The exit listener runs after the coverage dump, so its body can never be
measured by the unit coverage lane; mark it v8-ignore with the reason, as
with other process-exit-only code paths.
2026-09-03 16:35:45 +08:00
Chinesezjc 0364343a7e test: remove dsh-* temp dirs created by unit tests at teardown
Spec files that create /tmp/dsh-* directories via mkdtemp now track and
delete them in afterEach/afterAll; module-scope fixture dirs (executor
spill dirs) are removed in afterAll. The file list came from the
observed-residue inventory on the self-hosted CI host: only specs whose
dirs actually accumulated were leak sources (issue #3134), superseding
the kept-but-unmerged CI sweep branch per the #3233 review decision.

Product per-process spill roots (dsh-subprocess-local spawn,
dsh-spill-local store) register a process-exit handler that removes the
memoized dir, so processes that used the spawn/spill path clean up on
normal exit. A SIGKILLed process cannot run in-process teardown; the
machine-side timer remains the backstop for that path.

Agent Note: .agents/notes/implemented/process/2026-08-28-test-temp-dir-self-cleanup.md
2026-09-03 16:19:18 +08:00
pku-xht 0652b7b4d7 fix(subprocess): close containment review gaps 2026-09-03 06:18:21 +08:00
pku-xht 14c16012fb fix(subprocess): preserve post-commit runner errors 2026-09-03 04:07:57 +08:00
pku-xht ff6a49660f fix(subprocess): tighten native containment settlement 2026-09-03 03:26:42 +08:00
pku-xht bc681d7a54 fix(subprocess): harden cancellation settlement 2026-09-03 01:18:40 +08:00
pku-xht 05b6789425 fix(subprocess): preserve clean range after start errors 2026-09-03 00:59:07 +08:00
pku-xht fe873955b4 Merge master@313ac567 into subprocess native containment 2026-09-02 23:00:02 +08:00
pku-xht ac1a5891c2 fix(subprocess): close remaining native containment findings 2026-09-02 22:49:46 +08:00
pku-xht fc19a0a3fa fix(subprocess): clarify provider failures and scope polling 2026-08-31 19:26:08 +08:00
pku-xht 6d49ac2ef6 fix(subprocess): align runner bindings with current types 2026-08-31 15:37:14 +08:00