issue-257: Implement extensions/vision/src/client.ts (request build, fetch, parse, error mapping) #271
No reviewers
Labels
No labels
bug
chore
documentation
enhancement
feature
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
david/pi-extensions-and-skills!271
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/issue-257/implement-extensions-vision-src-client-ts-request"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
257: Implement extensions/vision/src/client.ts (request build, fetch, parse, error mapping)
Closes #257 — 257.
Generated in 42m 29s.
Review findings
I'll start by exploring the relevant files to understand the context, then apply fixes for the review findings.
Let me look at the sibling extension precedent and the project structure.
Let me check the test infrastructure and available type packages.
Now I understand the situation. Let me analyze the four findings:
package.json, no node_modules, no@types/node, and no roottypescript. Thecheckscript would fail (notscavailable) — adding it without installable deps creates a broken gate. The reviewer themselves framed this as "expected until M8 wiring." I'll carry this forward as unresolved.Let me apply the code fixes first.
Now let me add the two new tests. First, the network-error test with a live signal (Low #3), inserted after the existing network test:
Now the timeout-via-
AbortSignal.anytest (Medium #2), inserted after the existing timeout test:Now let me run the vision client tests to verify the new tests pass.
All 21 client tests pass (was 19, now +2). Let me run the full suite to confirm no regressions.
Full suite is green: 957 tests, 956 pass, 1 skipped (penpot gate), 0 fail (was 955, now +2 new tests). Let me verify the edited regions of
client.tsare clean.Let me do a final sanity typecheck of the edited
client.tsusing a throwaway tsconfig, to confirm the inline change is still type-clean.That's just the
.ts-extension import flag (a runtime-stripping detail, not a type error). Let me add that flag to confirm no real type errors.All fixes are verified.
client.tsis type-clean, and the full suite is green (957 tests, 956 pass, 1 skipped, 0 fail). Here is my final report.Review Findings — issue-257: Implement extensions/vision/src/client.ts (request build, fetch, parse, error mapping)
Summary
Applied fixes for 3 of 4 findings in a single pass. Gates run:
npm test(full suite) → 957 tests, 956 pass, 1 skipped (unrelated penpot gate requiringPENPOT_SOURCE_DIR), 0 fail (up from 955: +2 new tests); the 21 visionclient.test.tscases all pass. A throwawaytsc --noEmitonclient.tsconfirms it is type-clean after the edit.Resolved:
client.ts:216— Added a test that passes a liveAbortControllersignal with a tinytimeoutMs(20) against a never-resolving fetch, soAbortSignal.anyfires the deadline (winning over pi's never-aborting signal) andclassifyFetchErrorreads theTimeoutErroroff the combined signal's reason, yielding categorytimeoutthrough the previously-untestedAbortSignal.any+ deadline path.client.test.ts:367— Added a network-error test that passes a live controller signal with a generous deadline, covering theAbortSignal.any+ network branch (combined not aborted →network).client.ts:229— Inlined" — DeepSeek server error; retry the call"directly intotoHttpErrorand removed the forward-referenced single-memberHINTSobject.Carried forward (unresolved):
extensions/vision/(+package.json) — Could not add atsconfig.json+check(tsc --noEmit) script without creating a broken gate: vision has nopackage.json, nonode_modules, no@types/node, and there is no roottypescriptbinary. Thecheckcommand would fail (notsc), violating the keep-the-suite-green rule. This is a final-wiring (M8) concern, so it is left for that milestone.Critical
(none)
High
(none)
Medium
extensions/vision/(+package.json) — The vision extension has notsconfig.jsonand nocheck(tsc --noEmit) script, while all four sibling extensions that carry one —mongodb,pr-comments,forgejo,victorialogs— ship a tsconfig plus a"check": "tsc --noEmit"script.npm testruns the.tsthrough Node's native type-stripping, which only strips types, so a type error inclient.tswould not be caught by any gate. Suggested fix: add atsconfig.json+ acheckscript for the vision extension (mirroringextensions/mongodb/tsconfig.json/extensions/mongodb/package.json) as part of final wiring, and wire it intonpm testor CI.extensions/vision/src/client.ts:216— TheAbortSignal.anydeadline branch is never exercised by a passing test. The timeout test (client.test.ts:387) passessignal: undefined, which takes thecombineSignalsdirect-return path (AbortSignal.timeout(timeoutMs), line 215); the abort test (client.test.ts:405) exercisesAbortSignal.anybut with pi's abort winning (60 s deadline never fires). The branch whereAbortSignal.anyis used and the deadline wins — i.e. timeout classified via the combined signal'sreasoninclassifyFetchError(line 298) — is untested, and it is the core timeout-vs-abort classification logic. Suggested fix: add a test that passes a liveAbortControllersignal with a tinytimeoutMsand a never-resolving fetch, asserting the deadline wins and yields categorytimeoutthrough theAbortSignal.anypath.Medium
extensions/vision/src/client.test.ts:367— The network-error test passessignal: undefined, so it does not cover theAbortSignal.anywrapper thatcombineSignalsadds when a real signal is present. A network error with a live signal still classifies asnetwork(combined.abortedis false inclassifyFetchError, line 298), but that path is untested. Suggested fix: add a network-error test that passes a live controller signal to cover theAbortSignal.any+ network branch.Low
extensions/vision/src/client.ts:229—HINTS(line 325) is a single-member object referenced before its declaration site (intoHttpError, line 229). It works becausetoHttpErroris only called at runtime, well after module init (no temporal-dead-zone issue), but the indirection adds noise for one string. Suggested fix: inline" — DeepSeek server error; retry the call"directly, or move theHINTSdeclaration abovetoHttpErrorfor readability.