sync SVN r18174

This commit is contained in:
2026-09-17 22:36:46 +03:00
parent 04a78f99db
commit ca2056d06a
13 changed files with 2159 additions and 0 deletions

View File

@@ -0,0 +1,173 @@
# Hooks ca functii + acces la context consumat — verificare documentatie oficiala
Data verificare: 2026-09-17. Metoda: WebFetch pe paginile oficiale (rezumate de un model
intermediar, nu HTML brut — unde continutul a fost trunchiat, marcat explicit mai jos) +
verificare empirica directa pe un `.jsonl` de pe disc.
## 1. Exista hook-uri definite ca FUNCTII (nu shell command)?
### In Claude Code (`settings.json` / plugin `hooks/hooks.json`) — NU
Pagina `https://code.claude.com/docs/en/hooks` defineste explicit tipurile de handler pentru
hook-uri:
> "Hooks are user-defined shell commands, HTTP endpoints, MCP tool calls, LLM prompts, or
> subagents that execute automatically at specific points in Claude Code's lifecycle."
Cinci tipuri de `type`, toate procese externe sau apeluri la distanta, niciunul „functie in-proces":
1. `"command"` — shell command (Bash/PowerShell)
2. `"http"` — POST catre un endpoint HTTP
3. `"mcp_tool"` — apel catre un tool MCP
4. `"prompt"` — evaluare printr-un prompt LLM single-turn
5. `"agent"` — subagent (experimental)
Confirmat separat pe `https://code.claude.com/docs/en/plugins-reference`, care listeaza acelasi
set de cinci tipuri pentru schema hook-urilor din plugin-uri si spune explicit:
> "There is no `function` type mentioned anywhere in the documentation."
Exemplu de schema (din `plugins-reference`):
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/scripts/format-code.sh" }
]
}
]
}
}
```
**Concluzie punct 1a**: in Claude Code (inclusiv plugin-uri), hook-urile NU pot fi functii
JS/TS/Python in-proces — doar comenzi shell, HTTP, MCP tool, prompt LLM sau subagent.
### In Claude Agent SDK (TypeScript) — DA, dar cu rezerva NEDOCUMENTAT pe detalii
Pagina `https://code.claude.com/docs/en/agent-sdk/typescript` (redirect de la
`docs.claude.com/.../agent-sdk/typescript`) arata ca optiunea `hooks` a SDK-ului accepta
callback-uri, nu comenzi shell:
> `hooks` | `Partial<Record<`HookEvent`, `HookCallbackMatcher`[]>>` | `{}` | Hook callbacks for events
Asta e un mecanism DIFERIT de `settings.json` al Claude Code: aici hook-ul e literal o functie
TypeScript data la `query({ ..., hooks: {...} })`, ruland in acelasi proces Node ca aplicatia SDK.
**NEDOCUMENTAT - nu am putut extrage**: definitiile exacte de tip pentru `HookEvent`,
`HookCallback`, `HookCallbackMatcher`, `HookJSONOutput`, sau tipurile de input per eveniment
(`PreToolUseHookInput` etc.) — pagina e mare si WebFetch a trunchiat/rezumat continutul de doua
ori la rand, fara sa gaseasca sectiunea cu type body-urile (doar link-uri ancora `#hookevent`,
`#hookcallbackmatcher`, nerezolvate de rezumator). Nu pot afirma nici ca schema de input e identica
cu a hook-urilor `command`, nici ca difera — necesita citire directa a paginii (curl/browser),
nu WebFetch.
## 2. Primesc function hooks (SDK) un input mai bogat decat hook-urile `command`?
**NEDOCUMENTAT - nu am putut extrage.** Pagina SDK TS nu a livrat campurile exacte ale obiectului
de input trimis catre `HookCallback` (vezi punctul 1). Singurul camp relevant gasit pe acea pagina
a fost `maxThinkingTokens` (o optiune de configurare a sesiunii, nu un camp de input al hook-ului).
Nu exista nicio mentiune gasita de `usage`, `context_window` sau echivalent in continutul extras.
## 3. Ce primeste `statusLine` ca input, si acelasi obiect e disponibil vreunui hook?
Pagina `https://code.claude.com/docs/en/statusline` confirma ca `statusLine` e un mecanism separat
de hook-uri: un script shell propriu, care primeste JSON pe stdin cu date de sesiune, explicit
descris ca fiind pentru monitorizarea folosirii contextului:
> "The status line is a customizable bar at the bottom of Claude Code that runs any shell script
> you configure. It receives JSON session data on stdin and displays whatever your script prints,
> giving you a persistent, at-a-glance view of context usage, costs, git status..."
**NEDOCUMENTAT - nu am putut extrage** schema JSON exacta trimisa pe stdin (campurile
`context_window.used_percentage` etc.) — fetch-ul a livrat doar introducerea paginii, nu tabelul
de schema (posibil mai jos in pagina, trunchiat de rezumator).
Nu am gasit, in niciuna din paginile de hook-uri (`hooks`, `hooks-guide`, `plugins-reference`),
vreo mentiune ca acelasi obiect JSON dat lui `statusLine` ar fi disponibil si unui hook obisnuit.
Structural, `statusLine` e configurat separat de `hooks` in `settings.json` si documentat ca
mecanism de sine statator, nu ca un tip de hook din lista de 5 (`command`/`http`/`mcp_tool`/
`prompt`/`agent`).
## 4. Exista un eveniment de hook dedicat contextului (prag, PreCompact cu date de ocupare)?
Pagina `hooks` listeaza evenimentul `PreCompact` ("Before context compaction") si `PostCompact`,
dar continutul extras nu contine schema de input pentru `PreCompact`:
> `PreCompact` are matcher pe ce a declansat compactarea (`"manual"` sau `"auto"`), dar campurile
> JSON de input nu sunt specificate in continutul extras.
Nu exista, in continutul extras din niciuna dintre pagini, un eveniment de tip "context threshold"
separat de `PreCompact`/`PostCompact`. **NEDOCUMENTAT - nu am putut extrage** schema completa a
`PreCompact` (posibil contine deja procente de ocupare — nu s-a putut confirma nici infirma).
Campurile COMUNE confirmate pentru toate evenimentele de hook (din tabelul extras pe pagina
`hooks`):
```
session_id, prompt_id, transcript_path, cwd, scratchpad_dir, permission_mode,
effort.level, hook_event_name, agent_id (doar subagenti), agent_type (doar subagenti)
```
Niciun camp de tokeni/usage/context in aceasta lista. Coincide cu dovada empirica deja detinuta
(inputul real al `SubagentStop` capturat anterior nu are camp de tokeni).
## 5. Schema unei linii `assistant` din transcriptul `.jsonl` — are `usage`?
**Verificat direct pe disc, DA** — nu doar documentatie, dovada empirica reala:
```
grep -o '"usage":{[^}]*}' bdb0bf8c-a086-4d46-b08d-545a92e5c32c.jsonl | head -3
```
rezultat (identic pe primele linii verificate):
```json
"usage":{"input_tokens":2,"cache_creation_input_tokens":34191,"cache_read_input_tokens":31003,"output_tokens":1710,"output_tokens_details":{"thinking_tokens":198}
```
Deci fiecare linie `assistant` din `.jsonl` are un obiect `message.usage` cu:
`input_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens`, `output_tokens`,
`output_tokens_details.thinking_tokens`.
Asta e citibil de orice proces cu acces la fisier (inclusiv un hook `command`, daca i s-ar da
calea) — dar hook-ul primeste doar `transcript_path` ca referinta, nu campul de usage direct in
inputul lui JSON. Un hook `command` ar putea *citi singur* fisierul si insuma `usage` peste toate
liniile `assistant` ca sa aproximeze contextul consumat — asta nu necesita „function hooks",
functioneaza si cu un hook shell obisnuit care are `jq`/`python` la indemana si stie
`transcript_path`.
## Verdict
**Poate un hook sa afle contextul consumat, si pe ce cale — da, dar nu prin niciun camp direct din
inputul JSON al hook-ului**, indiferent daca hook-ul e `command` sau (in SDK, nu in Claude Code)
o functie in-proces:
- **Calea documentata si confirmata empiric**: orice hook `command` (sau function-hook din SDK,
daca primeste `transcript_path` in input — nedocumentat exact, dar plauzibil, campul e comun
tuturor evenimentelor conform tabelului din `hooks`) poate **citi singur** `transcript_path` de
pe disc si insuma `message.usage` din liniile `assistant` ca sa aproximeze tokenii consumati.
Asta confirma ce a spus deja Marius implicit: se poate afla, dar prin citire activa a
transcriptului, nu pentru ca hook-ul primeste un camp gata calculat.
- **Nu exista, in ce am putut extrage din documentatie, niciun camp `usage`/`context_window`/
`tokens` in inputul JSON dat direct hook-ului** (nici la `command`, nici — din cate am putut
verifica — mentionat pentru function hooks din SDK).
- **`statusLine` e mecanismul care primeste `context_window.used_percentage` gata calculat**, dar
e un canal separat de `hooks` in `settings.json`, nu un tip de hook; nu am gasit dovada ca acel
obiect ar fi expus si catre hook-uri.
- Afirmatia initiala („niciun hook Claude Code nu poate afla cat context s-a consumat") e
**partial gresita**: un hook nu primeste tokenii de-a gata, dar poate sa-i afle citind singur
`transcript_path` — cale disponibila oricarui hook `command`, nu doar unor ipotetice „function
hooks".
## Goluri ramase (NEDOCUMENTAT, de reverificat cu citire directa a paginii, nu WebFetch)
- Schema completa de tip TypeScript pentru `HookCallback`/`HookCallbackMatcher`/`HookEvent` din
SDK (`code.claude.com/docs/en/agent-sdk/typescript`) — pagina prea mare, WebFetch a trunchiat de
doua ori la rand.
- Schema JSON completa trimisa pe stdin catre `statusLine` (`code.claude.com/docs/en/statusline`).
- Schema completa de input pentru `PreCompact` (`code.claude.com/docs/en/hooks`).