Skip to content

Puter.js types and docs drift audit - 2026-06-29 #3320

Description

@reynaldichernando

puter.js SDK — TypeScript & Documentation Drift Audit

Tree: pinned to commit 6fc79a7184fccc7a4d2ccd0959a2bb7b801a3ce1 (branch claude/exciting-lamport-szoqek)
Date: 2026-06-29
Scope: full deep audit of every API family — impl (src/puter-js/src/modules/ + src/index.js + src/gui/src/IPC.js for UI), types (src/puter-js/types/), docs (src/docs/src/).

Legend: 🟡 types (impl/docs have it, types don't/wrong) · 🔵 docs (impl/types have it, docs don't/wrong) · 🔴 both · 🐛 impl-bug (advertised param impl ignores, or phantom method in types) · 🆕/🗑 manifest-drift.


Manifest tripwire (Step 0)

Disk vs the Expected manifest. Disk is the authority.

File Status Tag
src/docs/src/Objects/ttsengine.md On disk, not in manifest's AI Objects deps. Content accurate vs TTSEngine (ai.d.ts:297-306) & listEngines return. 🆕 manifest-drift (new file)
src/docs/src/Objects/ttsvoice.md On disk, not in manifest's AI Objects deps. Content accurate vs TTSVoice (ai.d.ts:316-335) & listVoices return. 🆕 manifest-drift (new file)

No removed/renamed files (no 🗑). All modules, FS ops, networking, UI components, types, and other docs match the manifest.


🔝 Highest-impact shortlist (cross-family)

  1. 🔴 FSItem isDir vs isDirectory — both the type (isDir: boolean) and Objects/fsitem.md advertise isDir, but the runtime instance property is isDirectory (FSItem.js:17). Every FSItem from stat/readdir/mkdir/etc. returns undefined for item.isDir. Most user-visible drift in the whole SDK.
  2. 🐛 txt2img provider / service are no-ops — docs+types prominently advertise provider:'gemini'|'xai'|'together'… and service as the routing knob, but AI.js:899-915 only inspects options.driver. Following the docs to select a non-OpenAI image provider silently mis-routes to ai-image.
  3. 🐛 notify({type, duration}) silently ignored in the app/GUI path — both documented & typed, but IPC.js:269-297 / UINotification.js never read them; only the standalone web-component fallback honors them.
  4. 🐛 Perms requestWriteAppRootDir is broken#requestAppRootDir hardcodes access:'read' and a :read permission string regardless of the write wrapper (Perms.js:359-369), plus a guaranteed ReferenceError on undefined app_or_uuid (Perms.js:367). Both methods are also absent from types & docs.
  5. 🐛 Apps getDeveloperProfile never resolves — constructs an outer Promise but returns a nested Promise never wired to the outer resolve/reject (Apps.js:246-268); the returned promise hangs forever.
  6. 🐛 Peer phantom PuterPeerServer.message() — types declare a public message() (peer.d.ts:67) that doesn't exist; impl has only private #message (Peer.js:104). Calling it throws TypeError.
  7. 🐛 PSocket.write ArrayBuffer branch brokendata.write(...) is called on an ArrayBuffer (PSocket.js:74-76), which has no .write; the advertised ArrayBuffer input type throws.
  8. 🔴 KV MAX_VALUE_SIZE documented as 400 KB but is 399 KB — impl 399 * 1024 = 408,576 bytes (KV.js:36); types JSDoc, set.md, KVSetItem/KVSetObject all say "400 KB". Values between 399–400 KB are rejected despite docs.
  9. 🔴 FS revokeReadURL & readdirSubdomains fully undocumented & untyped — public methods on puter.fs (FileSystem/index.js:44,46) absent from filesystem.d.ts and docs.
  10. 🟡 Drivers.call missing the 2-arg overload — the idiomatic puter.drivers.call('ipgeo', {…}) shorthand (Drivers.js:262) fails type-checking; types only declare 3- and 4-arg forms.

AI (AI.js / ai.d.ts / AI/)

Function Item Issue Tag impl ref
txt2img provider option Docs+types advertise provider as routing knob; impl never reads it (only driver). 🐛 AI.js:899-915
txt2img service option Typed (ai.d.ts:182) but impl never reads it. Phantom. 🐛 AI.js:909
txt2img nano-banana/nano-banana-pro model aliases Impl maps to gemini models; absent from types & docs. 🔴 AI.js:900-907
txt2img driver option Read by impl, typed, but undocumented. 🔵 AI.js:909-915
chat vision option ChatOptions.vision typed but impl computes vision itself and never reads user value. 🐛 AI.js:782-824
chat streaming "image" chunk Documented (chat.md:366-385) but missing from ChatResponseChunk type + chatresponsechunk.md. 🔴 AI.js:833
chat streaming "error" chunk Documented (chat.md:227,295) but missing from type enum + object doc. 🔴 AI.js:833
chat images[].thoughtSignature Used in docs (chat.md:347,361); missing from ImageContent (ai.d.ts:3-6) & chatresponse.md. 🔴
chat ChatMessage.images Declared required & non-optional (ai.d.ts:14); should be images? (assistant-output-only). 🟡 ai.d.ts:14
chat content type:"file"/puter_path Documented (chat.md:60-64); not modeled in AIMessageContent. 🟡 ai.d.ts:1
speech2speech camelCase aliases (voiceId,modelId,outputFormat,voiceSettings,fileFormat,removeBackgroundNoise,optimizeStreamingLatency,enableLogging) Normalized by impl; types only list snake_case. Docs' own example uses removeBackgroundNoise. 🟡 AI.js:414-438
speech2speech provider option Typed (ai.d.ts:411) but impl deletes it; always elevenlabs-voice-changer. Phantom. 🐛 AI.js:484-486
speech2speech MAX_INPUT_SIZE = 25 MB Enforced by impl; absent from docs & types. 🔴 AI.js:402
speech2speech file alias for audio Impl+types support file; options list in docs omits it. 🔵 AI.js:461-464
speech2txt MAX_INPUT_SIZE = 25 MB Enforced; absent from docs & types. 🔴 AI.js:514
txt2speech engine→provider inference Impl infers provider from engine; undocumented & untyped. 🔴 AI.js:268-282
txt2vid durationseconds alias Typed; docs only document seconds. 🔵 AI.js:979-981
img2txt nested {source:{source:Blob}} Supported by impl; undocumented & untyped (edge case). 🔴 AI.js:158-161
chatresponse choices field Typed choices?: unknown (ai.d.ts:93); not in chatresponse.md. 🔵 ai.d.ts:93
ToolCall type field Used in docs (chat.md:577) tool calls; missing from ToolCall type & toolcall.md. 🔴 ai.d.ts:17-20
ttsengine.md / ttsvoice.md new object docs Not in manifest (content accurate). 🆕

Apps (Apps.js / apps.d.ts / Apps/)

Function Item Issue Tag impl ref
checkName method existence In impl + types; undocumented. 🔵 Apps.js:206-230
getDeveloperProfile method existence In impl + types; undocumented. 🔵 Apps.js:232-269
getDeveloperProfile never resolves Returns nested Promise never tied to outer resolver; promise hangs. options computed twice (dead code). 🐛 Apps.js:246-268

(All other Apps surfaces — create/update/list/delete, App object, CreateAppResult — types & docs consistent.)


Auth (Auth.js / auth.d.ts / Auth/)

Function Item Issue Tag impl ref
getGlobalUsage method existence Implemented (/metering/globalUsage); missing from types AND docs. 🔴 Auth.js:338-374
whoami method existence In impl + types (used by Perms); undocumented. 🔵 Auth.js:211-256
getUser positional (success,error) overload Supported by impl; types only declare options-object form. 🟡 Auth.js:175-205
User feature_flags In types; not in user.md. 🔵 auth.d.ts:15
User hasDevAccountAccess In types; not in user.md. 🔵 auth.d.ts:16
User otp In types; not in user.md. 🔵 auth.d.ts:18

Perms (Perms.js / perms.d.ts / Perms/)

Function Item Issue Tag impl ref
grantUser/grantGroup/grantApp/grantAppAnyUser/grantOrigin method existence In impl + types; undocumented. 🔵 Perms.js:37-65
revokeUser/revokeGroup/revokeApp/revokeAppAnyUser/revokeOrigin method existence In impl + types; undocumented. 🔵 Perms.js:68-96
createGroup/addUsersToGroup/removeUsersFromGroup/listGroups method existence In impl + types; undocumented. 🔵 Perms.js:99-118
requestReadAppRootDir method existence In impl; missing from types AND docs. 🔴 Perms.js:333-335
requestWriteAppRootDir method existence In impl; missing from types AND docs. 🔴 Perms.js:346-348
#requestAppRootDir hardcoded access:'read' Write wrapper passes 'write' but helper hardcodes 'read' in the body — write access never requested. 🐛 Perms.js:361
#requestAppRootDir app_or_uuid undefined References undefined var (typo for app_uid) → ReferenceError if first fetch errors. 🐛 Perms.js:367
#requestAppRootDir permission level :read Builds app-root-dir:…:read even for write path. 🐛 Perms.js:369
requestPermission deprecated alias In impl (@deprecated); not in types/docs (low priority). 🟡 Perms.js:123-125

FS (FSItem.js + FileSystem/operations/* / filesystem.d.ts, fs-item.d.ts / FS/)

Function Item Issue Tag impl ref
FSItem isDir vs isDirectory Runtime property is isDirectory; type & fsitem.md say isDir. 🔴 FSItem.js:17
revokeReadURL method existence Public (puter.fs); missing from types AND docs. 🔴 revokeReadUrl.js:10
readdirSubdomains method existence Public; missing from types AND docs. 🔴 readdirSubdomains.js:11
sign doc page In impl + types; no doc page. 🔵 sign.js:15
read cache option Read by impl; missing from ReadOptions & read.md. 🔴 read.js:46
stat returnWorkers alias Read by impl; missing from StatOptions & stat.md. 🔴 stat.js:54,126
stat consistency option Typed; omitted from stat.md. 🔵 stat.js:31
readdir no_subdomains option Read+sent by impl; missing from ReaddirOptions (which has no_thumbs/no_assocs) & docs. 🔴 readdir.js:57-60
readdir consistency option Typed; omitted from readdir.md. 🔵 readdir.js:29,44
upload generateThumbnails/thumbnailGenerator/thumbnail Read by impl; missing from UploadOptions & docs. 🔴 upload.js:571,573,1313
copy positional 3rd-arg parsed as object only copy(src,dst,boolean) (as FSItem.copy calls it) drops auto_rename/overwrite — never reach the wire. 🐛 copy.js:8-24; FSItem.js:94
copy create_missing_parents/new_metadata/excludeSocketID Parsed into options but never sent in payload — dead options. 🐛 copy.js:17-19 vs 48-57
move positional 3rd/4th-arg dropped FSItem.move passes overwrite/new_name positionally; move only reads args[2] as object. 🐛 move.js:11-21; FSItem.js:90
move dedupeName documented but never read Phantom documented option. 🔵 move.js
move newName/newMetadata/excludeSocketID Read+sent; omitted from move.md. 🔵 move.js:63-66
mkdir rename alias (dedupe), recursive alias (createMissingParents), shortcutTo Read by impl; aliases/shortcutTo undocumented. 🔵 mkdir.js:51-54
delete descendants_only snake alias Sent by impl; only descendantsOnly in types/docs. 🔵 deleteFSEntry.js:55
write write(path) single-arg overload Docs show it; type requires data. 🟡 write.js:4,52-55
space docs example puter.space() No top-level puter.space; should be puter.fs.space(). Also missing platforms frontmatter. 🔵 FileSystem/index.js:31
FSItem move/copy not in fsitem.md Typed + implemented; doc omits both. 🔵 FSItem.js:89,93
getReadURL directory rejection Impl rejects for dirs; not noted in doc. 🔵 getReadUrl.js:18-20

KV (KV.js / kv.d.ts / KV/)

Function Item Issue Tag impl ref
MAX_VALUE_SIZE exact value Impl 399*1024; types JSDoc + set.md + KVSetItem/KVSetObject say "400 KB". 🔴 KV.js:36
optConfig all methods Read by every method (set/get/incr/decr/add/remove/update/expire/expireAt/del/list/flush) with {appUuid} shorthand; typed via overloads but documented on no method. 🔵 KV.js:174 etc.
clear alias clear = this.flush, in types; no KV/clear.md, absent from KV.md function list. 🔵 KV.js:676
get/del/incr/decr/add object-form single-arg overload get({key}) etc. supported by impl; absent from types & docs (only set/update document object form). 🟡 KV.js:256,308,338,368,540
MAX_KEY_SIZE exact value 1024 = 1 KB exactly — consistent. ok KV.js:35

Hosting (Hosting.js / hosting.d.ts / Hosting/)

Function Item Issue Tag impl ref
list workers.puter.* filter Impl silently filters these out; undocumented. 🔵 Hosting.js:44
update non-string first arg Falls through with empty options={} → malformed driver call instead of a clear error. 🐛 Hosting.js:84-103
create object-form root_dir not absolutized Asymmetry vs positional dirPath (which calls getAbsolutePathForApp). Docs warn about it, but a footgun. 🐛/— Hosting.js:76-77
update root_dir null default update(subdomain) sets root_dir to null; undocumented. 🔵 Hosting.js:99

Workers (Workers.js / workers.d.ts / Workers/)

Function Item Issue Tag impl ref
getLoggingHandle method existence In impl + types; undocumented (no page, not in functions list). 🔵 Workers.js:137
create errors type Impl reads driverResult.errors as a string (new Error(...)); types (string[]) & workerdeployment.md (Array) say array. 🔴 Workers.js:51

(router.md/types.md describe the deployed-worker runtime, verified internally consistent — not mapped to SDK methods.)


Peer (Peer.js / peer.d.ts / Peer/)

Function Item Issue Tag impl ref
PuterPeerServer.message() phantom method Typed public message() (peer.d.ts:67); impl has only private #message. 🐛 Peer.js:104
error event payload type Impl dispatches an Error object; type says error: string (peer.d.ts:43). Docs example reads event.error?.message (treats as Error), contradicting the type. 🟡 Peer.js:236,285,306
PuterPeerConnection object doc The AppConnection.md listed for Peer actually documents puter.ui's app-connection object; the real PuterPeerConnection has no Objects/ doc (only inline in serve.md/connect.md). 🔵

Networking (networking/* / networking.d.ts / Networking/)

Function Item Issue Tag impl ref
PSocket.write ArrayBuffer branch data.write(...) called on an ArrayBuffer (no such method) → throws for advertised ArrayBuffer input. 🐛 PSocket.js:74-76
PSocket 'drain' event In SocketEvent type + registered, but never emitted. 🐛/🟡 PSocket.js:16
PSocket.write callback param Accepted+invoked by impl, typed; docs omit it. 🔵 PSocket.js:70
generateWispV1URL doc Public on puter.net, in types; no docs entry. 🔵 index.js:627
PTLSSocket.on plain-name remap on('open'|'data'|'close') silently remapped to tls*; undocumented & not surfaced in types. 🔵 PTLS.js:92-98
fetch string rejections Impl rejects with strings in several paths; docs don't note. 🔵 requests.js:63,85,254
PWispHandler reconnect / backpressure setTimeout(setup(), 1000) invokes immediately; _continue() called with no streamID. (Non-drift, surfaced during walk.) 🐛 PWispHandler.js:23,51

Drivers (Drivers.js / drivers.d.ts, verify-only)

Function Item Issue Tag impl ref
call 2-arg overload call('ipgeo', {…}) shorthand supported by impl; types only have 3- & 4-arg overloads → fails type-checking. 🟡 Drivers.js:262-265
call <2-arg guard 0/1 args leave iface_name/method_name undefined, no guard. 🐛 (minor) Drivers.js:232-269

(3- and 4-arg overloads, get, list all consistent.)


OS (OS.js / os.d.ts, verify-only)

No drift. user (incl. query), version match types. Positional (success,error) callback form untyped (convention, minor). No docs family present (expected).


Utils / top-level (src/index.js / puter.d.ts, shared.d.ts / Utils/)

Function Item Issue Tag impl ref
env return values Docs list only app/web/gui; impl also returns service-worker/web-worker/nodejs. Types correct. 🔵 index.js:357-388
print escapeHTML option Supported (impl) + typed; undocumented (only code in print.md). 🔵 index.js:1258
print variadic signature Impl print(...args) (multi-arg); docs (print(text)) & types (print(text, options?)) understate it. 🔴 index.js:1251
exit docs In impl + types; no doc page, not listed in Utils.md. Non-obvious coercion (non-number→1) + cross-frame post. 🔵 index.js:1040
Puter interface quiet/debugMode/on/off/whoami Wired in impl; missing from Puter type. 🟡 index.js:170,173,771,972
Puter interface getUser positional overload (success,error) form wired; type declares options-object form only. 🟡 index.js:1217

UI (UI.js + IPC.js + ui/components/* / ui.d.ts / UI/)

Function Item Issue Tag impl ref
notify type option Documented + typed; GUI/IPC path never reads it (only standalone fallback). 🐛 IPC.js:269-297
notify duration option Same — ignored in app/GUI path. 🐛 IPC.js:269-297
exit mislisted location UI.md lists puter.ui.exit(); it lives on root puter (exit.md is correct). 🔵 UI.md:36
prompt options param Impl + IPC + types support options.defaultValue; prompt.md never mentions options. 🔵 IPC.js:253
showColorPicker defaultValue/default aliases Honored only in standalone; types declare only defaultColor. Docs lack Parameters/Return sections. 🔴 UI.js:884
showFontPicker default alias + options/return docs Standalone reads default; types miss it. Docs lack Parameters/Return for the options form. 🔵/🟡 UI.js:866
showOpenFilePicker/showSaveFilePicker .undefinedOnCancel Impl + types expose it; docs never mention it. 🔵 UI.js:842,971
setMenubar theme option, item id theme typed + standalone-only; id required to target items dynamically — both omitted from setMenubar.md. 🔵 UI.js:1102; IPC.js:744
disableMenuItem/enableMenuItem method existence In UI.js + wired in IPC; missing from types AND docs. (Siblings setMenuItemIcon*/Checked typed but undocumented.) 🟡/🔵 UI.js:1117-1135
requestPermission (ui) method existence In UI.js + IPC; missing from types AND docs. 🟡/🔵 UI.js:1107
contextMenu theme/x/y + item danger/checked/shortcut Honored only in standalone; x/y and item fields in neither types nor docs; GUI/IPC drops them. 🟡/🔵 UI.js:1147-1151
socialShare return value Typed void; impl returns a Promise. Docs lack Return section. 🟡/🔵 UI.js:728
launchApp options.callback, LaunchAppResult fields callback read by impl, undocumented; LaunchAppResult (launched/appUid/privateAccess) richer than docs. 🔵 UI.js:1312

No phantom methods in ui.d.ts (every typed method exists). Type gaps are missing members, not invented ones.


🐛 impl-bug bucket (code fixes, not doc/type edits)

Location Bug
AI.js:899-915 txt2img provider (docs+types) & service (types) silently ignored; only driver routes.
AI.js:484-486 speech2speech typed provider deleted before driver call; always elevenlabs-voice-changer.
AI.js:782-824 chat typed vision option never read from user params.
Apps.js:246-268 getDeveloperProfile returns nested Promise never tied to outer resolver — never settles. Dead duplicate options.
Perms.js:361 #requestAppRootDir hardcodes access:'read'requestWriteAppRootDir requests read.
Perms.js:367 References undefined app_or_uuid (typo for app_uid) — ReferenceError on first-fetch error.
Perms.js:369 Permission string hardcoded :read for the write path.
copy.js:8-24 (+FSItem.js:94) copy(src,dst,boolean) parses args[2] as object only — FSItem.copy's auto_rename/overwrite dropped.
copy.js:17-19 create_missing_parents/new_metadata/excludeSocketID parsed but never sent — dead options.
move.js:11-21 (+FSItem.js:90) move(src,dst,overwrite,new_name) positional args dropped (only args[2] read as object).
Hosting.js:84-103 update with non-string first arg → empty options={} → malformed driver call.
Peer.js:104 (vs peer.d.ts:67) Phantom public PuterPeerServer.message(); only private #message exists.
PSocket.js:74-76 write ArrayBuffer branch calls data.write(...) on an ArrayBuffer → throws.
PSocket.js:16 'drain' declared/registered but never emitted.
Drivers.js:232-269 call() with <2 args leaves iface/method undefined, no guard.
PWispHandler.js:23,51 setTimeout(setup(), …) invokes immediately; _continue() called without streamID (reconnect/backpressure).
IPC.js:269-297 notify type & duration ignored in app/GUI path.

🆕 manifest-drift

  • Objects/ttsengine.md, Objects/ttsvoice.md — new files, content-accurate, absent from the audit manifest.

Generated by an automated drift audit (8 parallel family agents) against commit 6fc79a7184fccc7a4d2ccd0959a2bb7b801a3ce1. Each finding cites an impl reference (file:line) for reproduction.

🤖 Generated with Claude Code

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions