Skip to content

dor open: dispatch local files through user Tool associations - #669

Merged
nedtwigg merged 23 commits into
dor-tool-inputsfrom
dor-open-dispatch
Sep 17, 2026
Merged

nedtwigg merged 23 commits into
dor-tool-inputsfrom
dor-open-dispatch

Conversation

@nedtwigg

@nedtwigg nedtwigg commented Sep 15, 2026

Copy link
Copy Markdown
Member

dor open <file> resolves one existing local file, selects the first matching user-configured association, and launches or reveals its Tool. --tool chooses a user handler explicitly. URLs, directories, and Surface handles fail; project configuration never participates in file dispatch.

The selected Tool receives the canonical filename as one argument. Opening preserves the caller's plain terminal and uses existing Workspace routing, placement, JSON output, and keyed reuse. An idle matching caller Tool can rerun through the prompt handshake.

Bundled picomatch keeps matching compatible with the supported VS Code runtime. Filename patterns match canonical basenames; path patterns match canonical absolute and paths relative to the canonical CWD, while preserving the invocation CWD for the command. Malformed association errors name unknown fields and reject null Tool mappings. Associations must reference an argument-list Tool in the same user configuration.

Validation coverage: ordered associations, canonical targets, handler validation, command routing, takeover exclusion, CLI output, and dependency disclosure. No dogfooding or installation.

Local validation: 61 host/registry/open tests, library TypeScript, and spec checks pass. The symlink-CWD regression failed before the fix and passes afterward. CI and Chromatic run on the pushed head.

Tool stack 4/7, based on #668. Next: #670. Merge bottom-up after its predecessors.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 15, 2026

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 185c108
Status: ✅  Deploy successful!
Preview URL: https://20c8eabc.mouseterm.pages.dev
Branch Preview URL: https://dor-open-dispatch.mouseterm.pages.dev

View logs

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feedback on work in progress — not a merge verdict. The stack framing and the
promotion of scope C out of ## Future both read correctly; the notes below
are on the dispatch path itself. Mark ready when you want the full review.

The first two are about resolveOpenTool's matcher: it is unavailable on the
extension-host floor this repo declares, and it cannot see a file above the
invocation directory. The third is a config shape that parses but can never run.

Comment thread lib/src/host/tool-open.ts Outdated
Comment thread lib/src/host/tool-open.ts Outdated
Comment thread lib/src/host/tool-registry.ts Outdated
Comment thread lib/src/host/tool-registry.ts Outdated
# Conflicts:
#	lib/src/components/Wall.test.tsx
#	scripts/spec-word-budgets.json
@nedtwigg
nedtwigg added this pull request to stack #578 September 15, 2026 23:51

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feedback on work in progress — not a merge verdict. The picomatch substitution
lands the matcher on the declared VS Code floor, and matching the canonical
absolute path as well as the relative one reaches the files the old rule could
not. One note below, on where the reason for the swap lives.

Comment thread docs/specs/dor-tool.md Outdated
nedtwigg and others added 7 commits September 15, 2026 18:01
# Conflicts:
#	docs/specs/dor-tool.md
#	lib/src/components/Wall.test.tsx
#	lib/src/components/wall/tool-takeover.ts
#	lib/src/components/wall/use-dor-control.ts
#	lib/src/host/tool-host.ts
#	scripts/spec-word-budgets.json
Put the `dor` verb on the take-over gate so `toolTakesOverCaller` states
"open never transforms a plain terminal" itself, instead of a defaulted
parameter threaded through three predicates plus a guard at the call site.
Build the user-Tool `ok` result in one helper shared by the lookup
fallback and `resolveOpenTool`. Share the CLI launch round trip between
`dor tool` and `dor open`, and hoist the open-rule parser out of
`parseToolFile`. Cut the spec paraphrases of rules other sections own and
add the verb row to the take-over table.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
# Conflicts:
#	docs/specs/dor-tool.md
#	lib/src/host/tool-input.ts
#	scripts/spec-word-budgets.json
# Conflicts:
#	scripts/spec-word-budgets.json

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feedback on work in progress — not a merge verdict. Both notes are on
Simplify dor open dispatch; the rationale entry for Opening local files
closes the note from the last pass.

The first one matters: parseOpenRules' broadest throw is now unexercised.
The commit deleted the {match: "*", tool: undeclared} case from
tool-open.test.ts, and defined in this user file appears nowhere else in
the tree. That throw is the only thing rejecting a rule naming an undeclared
Tool or carrying a misspelled key, and the new tool-registry.test.ts case
covers the other two throws but not this one.

Comment thread lib/src/host/tool-registry.test.ts
Comment thread lib/src/host/tool-host.ts Outdated
@nedtwigg
nedtwigg marked this pull request as ready for review September 16, 2026 23:24

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dor open resolves its target with realpath, but matches slash-bearing
patterns against a path computed from the caller's logical cwd. Those two
disagree whenever the caller reached its directory through a symlink, and a
relative rule like docs/** then silently matches nothing. Detail inline.

Two smaller notes, both spanning code outside the diff — say the word and I'll
push them as one commit:

  • resolveUserTool in lib/src/host/tool-user-config.ts now assembles the
    status: 'ok' payload itself, while okResult in
    lib/src/host/tool-host.ts — whose comment still reads "The one wire shape
    for a resolved Tool, whichever file declared it" — builds the same object for
    the project branch. With the user branch gone from it, okResult's
    scope?: 'user' option is no longer passed by any caller, so its
    ...(source.scope ? { scope: source.scope } : {}) spread is dead. Either
    have resolveUserTool call a shared okResult, or drop the scope option
    and the comment's "whichever file declared it" claim; as it stands a new
    field on the ok result needs both sites edited and only one of them says so.
  • The doc comment above isNakedToolInvocation in
    lib/src/components/wall/tool-takeover.ts still says the reported command
    "is dor tool". It is now whichever verb the gate carries, and the trailing
    "not on the verb, which stricli parses case-sensitively" describes a value
    the caller supplies rather than a literal.

Comment thread lib/src/host/tool-open.ts Outdated
Comment thread lib/src/host/tool-open.ts
# Conflicts:
#	lib/src/host/tool-host.ts

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No correctness problem in the dispatch path itself. The three notes below are on
the new declaration-time validation and one stray blank line.

Worth knowing before you chase the red: Build & Test fails at this head on
spec-lint, for docs/specs/security-local.md at 2925 words against a
2900-word budget — a file this PR does not touch. It arrives from the base. The
merge ref this run was built from used dor-tool-inputs at 8560939b; that
branch's current tip cd5162d5 already has the file at 2899 words. Since
pnpm test is &&-chained behind spec-lint, nothing after it ran, so no unit
test has executed against 6c9b4624 on CI. I ran the affected suites and tsc
locally against the merged tree and they pass, so a re-run once this branch sees
the new base should go green on its own.

Comment thread lib/src/host/tool-registry.ts Outdated
Comment thread lib/src/host/tool-registry.test.ts Outdated
Comment thread lib/src/host/tool-registry.ts Outdated
Comment thread docs/specs/dor-tool.md
@nedtwigg
nedtwigg merged commit 4955b4a into main Sep 17, 2026
11 of 17 checks passed
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.

2 participants