Skip to content

Release: cross-app OS lane (shell_open, idle_keepawake, file_assoc)#430

Merged
JE-Chen merged 10 commits into
mainfrom
dev
Jun 25, 2026
Merged

Release: cross-app OS lane (shell_open, idle_keepawake, file_assoc)#430
JE-Chen merged 10 commits into
mainfrom
dev

Conversation

@JE-Chen

@JE-Chen JE-Chen commented Jun 25, 2026

Copy link
Copy Markdown
Member

Release the first three features of the ROUND-15 cross-app OS-integration lane, plus a changelog cleanup.

Features

  • shell_open (v203) — open_path / plan_open: open a file with its OS-registered default app (or a verb like print), or a URL in the default browser, routed per-OS to os.startfile / open / xdg-open / webbrowser. Pure planner + injectable opener.
  • idle_keepawake (v204) — idle_seconds / is_idle (time since last input via GetLastInputInfo) and keep_awake / keep_awake_on / allow_sleep (stop the system/display sleeping via SetThreadExecutionState / caffeinate / systemd-inhibit). Injectable probe + driver.
  • file_assoc (v205) — normalize_ext / file_association: which app is registered to open a file type (AssocQueryStringW), the inverse of shell_open. Pure normalizer + injectable resolver.

Each ships the full five layers (headless core, facade, AC_* executor, ac_* MCP tool, Script Builder under Shell), EN/Zh docs, WHATS_NEW, and headless tests. No PySide6 in the package import path.

Docs

  • WHATS_NEW.md consolidated: 204 repeated ## What's new (DATE) — TITLE headers grouped into 11 dated sections with ### TITLE sub-sections; body text unchanged.

All CI green on each feature PR (#426#429); Codacy 0 new issues; SonarCloud clean.

JE-Chen added 10 commits June 25, 2026 07:11
The framework could launch a literal .exe but not the most common hand-
off step: open report.pdf with its registered app, print a document, or
open a URL in the default browser. Route per-OS to os.startfile/open/
xdg-open/webbrowser. plan_open is a pure planner (classify URL vs file,
scheme allow-list, realpath; Windows drive is a path not a scheme);
open_path runs it through an injectable opener so the logic is testable
without launching anything.
Codacy's Semgrep dangerous-spawn/subprocess rules flag os.startfile and
subprocess.Popen on dynamic content; add line-level # nosemgrep with
justification (file path from the allow-listed plan; argv list, no
shell - injection-safe), matching the shell_command handler's pattern.
The Windows-drive test literal C:\tmp\a.txt tripped Sonar's
publicly-writable-directory rule on the 'tmp' substring (a false
positive - a test string, no runtime temp dir). Use C:\Users\me\... ,
testing the same drive-is-not-a-scheme behaviour.
…atch

Add shell_open: open files with default app / URLs in browser
Long unattended runs derail two ways: the screensaver/power policy sleeps
the box mid-run, or the run should hold while a human is using the machine.
The framework had neither signal. idle_seconds/is_idle read time since the
last input (GetLastInputInfo on Windows) through an injectable probe;
keep_awake (scoped CM) and keep_awake_on/allow_sleep (process-global on/off
for JSON flows) stop the system and display sleeping through an injectable
driver (SetThreadExecutionState/caffeinate/systemd-inhibit by default),
restored on release. plan_keep_awake is the pure planner. All logic is
unit-testable without touching the OS via the injected probe/driver.
…ke-batch

Add idle_keepawake: idle detection + keep machine awake
shell_open opens a file with whatever app is registered for it; file_assoc
answers the inverse, read-only question - which app is that? Given a path,
.ext or bare ext it returns the registered executable, friendly app name,
open command line and MIME content type via the Windows AssocQueryStringW
shell API. normalize_ext is the pure path/.ext/bare-ext to .ext helper.
The assembly logic is unit-testable without Windows through an injectable
resolver seam. The natural companion to open_path: one tells you what would
open a file, the other opens it.
…atch

Add file_assoc: resolve the app registered for a file type
The changelog had grown to 204 repeated `## What's new (DATE) — TITLE`
H2 headings, many sharing the same date. Collapse each date into a single
`## What's new (DATE)` section with every feature demoted to a `### TITLE`
sub-section, so a day's releases read as one dated group instead of a wall
of identical date headers. Body text is unchanged; older untitled summary
blocks stay intact (the one that shares a consolidated date becomes an
"Additional updates" sub-section).
…whatsnew

Group WHATS_NEW entries by date into one section per day
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 123 complexity · 0 duplication

Metric Results
Complexity 123
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@JE-Chen JE-Chen merged commit b322ae5 into main Jun 25, 2026
29 checks passed
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant