SLOPSHOPPER

pv2-sonde

Prototype de pipeline-v2 : sonde ce que chaque surface de Claude Code affiche (panneau, bande, ligne d'état, toast, notification).

newpanebandcommandtoaststatus
v0.1.0no licenseupdated 2026-10-13NeOzay/.claude/pipeline-v2/proto-sonde
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · pv2-sonde
│ ┃ Sonde pipeline-v2 ✕ › fix the failing auth test and add an audit lo╭───────────────────╮ │ ┃ Panneau de la sonde, surface terminal, │ pv2-sonde │ │ ┃ placement dock. ⏺ Read(src/auth.ts) │ pv2-sonde : toast │ │ ┃ ⎿ Read 6 lines ╰───────────────────╯ │ ┃ • un lien https https://code.claude.com/docs ⏺ Update(src/auth.ts) │ ┃ • un lien file ⎿ Added 2 lines, removed 1 line │ ┃ file:///plugins/pv2-sonde/../README.md ⏺ Bash(bun test) │ ┃ [ Appuyer ] ⎿ 3 pass, 1 fail │ │ ● Done. refresh now rejects expired claims and logs an audit event. │ │ ✻ Worked for 42s · done 4:20 PM │ │ › /sonde │ │ pv2-sonde : bande au-dessus de l’invite (terminal) [ Appuyer ] ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts ⚠ pv2-sonde: pv2-sonde : ligne d’état

Draws

Band
pv2-sonde : bande au-dessus de l’invite (terminal) [ Appuyer ]
Pane · Sonde pipeline-v2
Panneau de la sonde, surface terminal, placement dock. • un lien https https://code.claude.com/docs • un lien file file:///plugins/pv2-sonde/../README.md [ Appuyer ]
Source 1 files
hooks/register.tsx 122 lines
1// Sonde de pipeline-v2 : montre chaque surface de Claude Code et note ce que le moteur en fait.
2//
3// Prototype jetable, sans gestion d'erreurs (Signal de dérive S3) : il sert à répondre à la
4// question qui décide du Chantier, ce que Claude Code suivi au navigateur affiche d'un mod.
5// La commande `/sonde` ouvre un panneau, pose une ligne d'état, un toast et une notification ;
6// une bande au-dessus de l'invite est dessinée dès le démarrage.
7//
8// Le journal, `journal.log` à la racine du mod, dit ce que le moteur a fait : chaque client qui
9// s'attache, chaque demande de dessin par surface, le placement du panneau, le sort de la
10// notification. L'utilisateur dit ce qui s'est vu ; les deux font le constat.
11
12import type { EngineInterface, Register } from 'claude-code'
13
14const PANNEAU = 'sonde'
15
16// `$.fs.write` réécrit le fichier entier : le journal se tient ici et se réécrit à chaque ligne.
17const lignes: string[] = []
18
19// Une demande de dessin revient à chaque rafraîchissement : seule une combinaison nouvelle
20// de composant, surface et taille mérite une ligne.
21const dessins = new Set<string>()
22
23const noter = async ($: EngineInterface, texte: string) => {
24  lignes.push(`${new Date(await $.clock.now()).toISOString()} ${texte}`)
25  await $.fs.write(`${$.plugin.root}/journal.log`, `${lignes.join('\n')}\n`)
26}
27
28const noterDessin = async (
29  $: EngineInterface,
30  composant: string,
31  surface: string,
32  viewport: unknown,
33) => {
34  const cle = `${composant} ${surface} ${JSON.stringify(viewport ?? null)}`
35  if (dessins.has(cle)) {
36    return
37  }
38  dessins.add(cle)
39  await noter($, `ui.render ${cle}`)
40}
41
42export const register: Register = on => {
43  on('session.start', async ($, e, next) => {
44    await $.command.register({
45      name: 'sonde',
46      description: 'pipeline-v2 : ouvre un panneau, pose ligne d’état, toast et notification',
47    })
48    await noter($, `session.start surfaces=${JSON.stringify(await $.session.surfaces())}`)
49
50    return next(e)
51  })
52
53  on('session.attach', async ($, e, next) => {
54    await noter(
55      $,
56      `session.attach surface=${e.surface} clientId=${e.clientId} viewport=${JSON.stringify(e.viewport ?? null)}`,
57    )
58
59    return next(e)
60  })
61
62  on('command.run', { command: 'sonde' }, async $ => {
63    await noter($, `/sonde surfaces=${JSON.stringify(await $.session.surfaces())}`)
64    const ouvert = await $.ui.open({ id: PANNEAU, title: 'Sonde pipeline-v2' })
65    await noter($, `ui.open ${JSON.stringify(ouvert)}`)
66    $.ui.status('pv2-sonde : ligne d’état')
67    $.ui.toast('pv2-sonde : toast', { timeoutMs: 15000 })
68    const notifie = await $.ui.notify('pv2-sonde : notification', { title: 'pipeline-v2' })
69    await noter($, `ui.notify ${JSON.stringify(notifie)}`)
70
71    return { text: 'Sonde lancée : panneau, ligne d’état, toast, notification.' }
72  })
73
74  on('ui.render', { component: 'Pane', requestId: PANNEAU }, async ($, e) => {
75    await noterDessin($, 'Pane', e.surface, e.viewport)
76    const { Box, Button, Markdown } = $.ui.resolve(e)
77
78    return (
79      <Box flexDirection="column">
80        <Markdown
81          text={[
82            `**Panneau de la sonde**, surface \`${e.surface}\`, placement \`${e.props.placement}\`.`,
83            '',
84            '- un lien [https](https://code.claude.com/docs)',
85            `- un lien [file](file://${$.plugin.root}/../README.md)`,
86          ].join('\n')}
87        />
88        <Button
89          key="appui"
90          label="Appuyer"
91          onPress={async () => {
92            await noter($, `ui.press panneau surface=${e.surface}`)
93            $.ui.toast(`pv2-sonde : bouton du panneau pressé (${e.surface})`)
94          }}
95        />
96      </Box>
97    )
98  })
99
100  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
101    await noterDessin($, 'AbovePrompt', e.surface, e.viewport)
102    if (e.props.hasSurvey) {
103      return next(e)
104    }
105    const { Box, Button, Text } = $.ui.resolve(e)
106
107    return (
108      <Box>
109        <Text>pv2-sonde : bande au-dessus de l’invite ({e.surface}) </Text>
110        <Button
111          key="bande"
112          label="Appuyer"
113          onPress={async () => {
114            await noter($, `ui.press bande surface=${e.surface}`)
115            $.ui.toast(`pv2-sonde : bouton de la bande pressé (${e.surface})`)
116          }}
117        />
118      </Box>
119    )
120  })
121}
122