/plugin-types omits the op events session.authorize and flag.value that the hooks load line lists (2.1.263)

Status Open
Reported on v2.1.263
Maintainer reply None cached
Activity 0 comments · opened Sep 6, 2026

Summary

claude --version prints 2.1.263 (Claude Code). The hooks module load line of a function-hooks plugin lists two op events that the claude-code.d.ts written by /plugin-types in the same build omits from OpEventOf and OpValueOf: session.authorize and flag.value. The runtime carries both: $.session.authorize() exists on the session noun and dispatches the op, and a flag noun with $.flag.value(name, fallback) exists in the noun table behind a build gate.

Load line (verbatim, from ~/.claude/debug/<session>.txt under claude --debug)

hooks module function-hooks loaded (worker, environment 1); events: tool.call,ui.render,ui.resolve,ui.press,ui.input,ui.select,agent.offer,agent.spawn,prompt.submit,prompt.section,prompt.context,tool.describe,skill.prompt,attribution.text,session.start,turn.start,turn.step,turn.complete,engine.create,model.complete,model.classify,model.fork,audio.play,audio.speak,mcp.call,session.cwd,session.model,session.turnCount,session.id,session.messages,session.repo,session.surface,session.authorize,turn.abort,flag.value,tool.list,tool.register,agent.list,ui.toast,ui.status,ui.log,ui.notice,ui.invalidate,fs.readFile,fs.writeFile,fs.listDir,fs.exists,fs.stat,fs.ancestors,store.get,store.set,store.delete,store.keys,http.fetch,process.run

What the declarations hold

OpEventOf in the generated claude-code.d.ts (2.1.263) declares these keys: model.complete, model.classify, model.fork, audio.play, audio.speak, mcp.call, session.cwd, session.model, session.turnCount, session.id, session.messages, session.repo, session.surface, turn.abort, tool.list, tool.register, agent.list, ui.toast, ui.status, ui.log, ui.notice, ui.invalidate, fs.readFile, fs.writeFile, fs.listDir, fs.exists, fs.stat, fs.ancestors, store.get, store.set, store.delete, store.keys, http.fetch, process.run.

Missing: session.authorize and flag.value. The $.session noun type declares no authorize member, no flag noun is declared on EngineInterface, and HttpInit declares no auth field even though the $.http.fetch doc comment says "an auth credential rides https only". OpEventOf is a type alias, so a plugin cannot augment it with declare module 'claude-code' { interface OpEventOf { ... } }; a * hook that meets either event has next.event typed as EventName, which lacks both names.

Probed shapes (scratch plugins under claude --plugin-dir, debug files read)

session.authorize

  • Trigger: $.session.authorize() from a hook (the member exists at runtime though the declarations omit it). No other route raised it: a plain reply, a Bash call, a permission-gated call, --permission-mode plan, --permission-mode acceptEdits, a two-message --input-format stream-json session, and an interactive session all show only the load line.
  • Origin: the calling plugin (hooks module function-hooks: session.authorize nested in probe-ops).
  • Input e as a second plugin's * hook logged it: {} (no arguments).
  • Result as the * hook logged it: {"value":null}; the caller receives null.
  • The binary shows the implementation returns null while a build constant is false, and otherwise { handle, kind } with kind "bearer" or "api-key" from the first-party credential headers, for an auth field of $.http.fetch(url, init) ("unknown auth handle; $.session.authorize() mints one").

flag.value

  • Not dispatchable from a plugin in this build: $.flag is undefined (TypeError: undefined is not an object (evaluating '$.flag.value')), because the noun table withholds flag under the same build constant, and the op's own check answers "reads a feature flag, which this build has no table of".
  • Input per the runtime table: { name: string, fallback: unknown } ($.flag.value(name, fallback), the check requires a non-empty name and a fallback).
  • Result: the flag's value or the fallback.

Expected

Either the load line lists only the ops the build serves, or /plugin-types declares both (OpEventOf, OpValueOf, $.session.authorize, the flag noun, and HttpInit.auth), so that a * hook can narrow next.event and the declarations match the events the hooks module is told it wraps.

Repro

claude --version
claude --plugin-dir <any function-hooks plugin> --debug -p 'reply ready' --output-format stream-json --verbose
grep 'hooks module .* loaded' ~/.claude/debug/<session id>.txt
# then in a hook: await $.session.authorize()  -> null, the op settles through other plugins' * hooks
#                 $.flag.value('x', 'y')        -> TypeError, $.flag is undefined

/plugin-types regenerated on 2.1.263 writes the same file (byte-identical), so the gap is the declaration writer rather than a stale file.

View original on GitHub ↗