@tealbrick/kit 0.2.7 → 0.3.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/BOOTSTRAP.md +17 -18
  2. package/BUZZ.md +146 -0
  3. package/NATIVE.md +83 -0
  4. package/README.md +265 -4
  5. package/RUNTIME.md +1 -1
  6. package/assets/buzz/buzz-backend-provider.py +99 -0
  7. package/assets/buzz/buzz-plist.py +22 -0
  8. package/assets/buzz/buzz-run.sh +39 -0
  9. package/assets/buzz/tb-provider-apply.py +97 -0
  10. package/dist/buzz.d.ts +63 -0
  11. package/dist/buzz.js +262 -0
  12. package/dist/cli.js +22 -4
  13. package/dist/index.d.ts +23 -14
  14. package/dist/index.js +4 -2
  15. package/dist/native-acp.d.ts +40 -0
  16. package/dist/native-acp.js +224 -0
  17. package/dist/native-app-capabilities.d.ts +33 -0
  18. package/dist/native-app-capabilities.js +37 -0
  19. package/dist/native-buzz.d.ts +161 -0
  20. package/dist/native-buzz.js +649 -0
  21. package/dist/native-child-guard.d.ts +1 -0
  22. package/dist/native-child-guard.js +22 -0
  23. package/dist/native-claude.d.ts +99 -0
  24. package/dist/native-claude.js +584 -0
  25. package/dist/native-enroll.d.ts +22 -0
  26. package/dist/native-enroll.js +85 -0
  27. package/dist/native-runtime-sync.d.ts +49 -0
  28. package/dist/native-runtime-sync.js +101 -0
  29. package/dist/native-selection.d.ts +27 -0
  30. package/dist/native-selection.js +87 -0
  31. package/dist/native-serve-config.d.ts +286 -0
  32. package/dist/native-serve-config.js +296 -0
  33. package/dist/native-serve.d.ts +76 -0
  34. package/dist/native-serve.js +145 -0
  35. package/dist/native-setup.d.ts +63 -0
  36. package/dist/native-setup.js +122 -0
  37. package/dist/native-standing-grants.d.ts +105 -0
  38. package/dist/native-standing-grants.js +226 -0
  39. package/dist/native.d.ts +42 -0
  40. package/dist/native.js +193 -0
  41. package/dist/onboarding.d.ts +9 -0
  42. package/dist/onboarding.js +9 -2
  43. package/dist/runtime-onboarding.js +3 -3
  44. package/dist/secrets.d.ts +2 -1
  45. package/dist/secrets.js +4 -2
  46. package/package.json +19 -10
@@ -0,0 +1,161 @@
1
+ import type { ClaudeSdk } from './native-claude.js';
2
+ /**
3
+ * Buzz (block/buzz) helpers for `kit native acp`: harness-authored prompt parsing, the `buzz` CLI
4
+ * runner, the owner-only in-process `buzz` MCP server, and the per-thread agent↔agent loop breaker.
5
+ * Message content is never parsed for identity or routing; only buzz-acp's structural blocks are.
6
+ */
7
+ export declare const HEX64: RegExp;
8
+ export type BuzzRouteInfo = {
9
+ channel: string;
10
+ replyTo?: string;
11
+ };
12
+ /** Routing extracted from buzz-acp's authoritative <context> block (channel UUID, reply anchor). */
13
+ export declare function buzzRoute(prompt: string): BuzzRouteInfo | undefined;
14
+ export interface BuzzTrigger {
15
+ route?: BuzzRouteInfo;
16
+ /** `Thread root:` from the <context> block. */
17
+ threadRoot?: string;
18
+ /** Triggering (last) event id and author, only when the event block parses unambiguously. */
19
+ eventId?: string;
20
+ author?: string;
21
+ /** Why author/event (or the route) could not be established (logged; never echoed to the model). */
22
+ unknown?: 'no_context' | 'route_rejected' | 'no_event_block' | 'ambiguous_event_block' | 'channel_mismatch';
23
+ }
24
+ /**
25
+ * Parse the trigger from buzz-acp's per-section prompt blocks (crates/buzz-acp/src/queue.rs
26
+ * format_prompt / format_context_hints / format_event_block; pool.rs sends one ACP text block per
27
+ * section). Event content is verbatim (unescaped) inside its block, so identity is read only from
28
+ * header lines at positions the harness controls, and a batch whose header count does not match
29
+ * its `count` attribute is treated as ambiguous rather than guessed.
30
+ */
31
+ export declare function buzzTrigger(blocks: string[]): BuzzTrigger;
32
+ /** Owner pubkey from a NIP-OA auth tag `["auth", ownerHex, conditions, sig]` (structure only). */
33
+ export declare function ownerFromAuthTag(tag: string | undefined): string | undefined;
34
+ /** x-only (BIP-340 / Nostr) public key for a hex or nsec secret key; undefined when unusable. */
35
+ export declare function pubkeyFromSecret(secret: string | undefined): string | undefined;
36
+ export type BuzzResult = {
37
+ ok: boolean;
38
+ stdout: string;
39
+ error?: string;
40
+ };
41
+ /** Runs `buzz` with an argv array (never a shell); stdin carries message content. */
42
+ export type BuzzRun = (args: string[], stdin?: string) => Promise<BuzzResult>;
43
+ /** Redact nsec keys and 64-hex values from error text (hex the caller passed in argv is kept). */
44
+ export declare function redactSecrets(text: string, keep?: string[]): string;
45
+ export declare function buzzRunner(cli: string, { timeoutMs, env, maxOutput }?: {
46
+ timeoutMs?: number;
47
+ env?: NodeJS.ProcessEnv;
48
+ maxOutput?: number;
49
+ }): BuzzRun;
50
+ /** Binary download through the CLI (`buzz media get <input> -o -`), capped at maxBytes. */
51
+ export type BuzzDownload = (args: string[], maxBytes: number) => Promise<{
52
+ ok: boolean;
53
+ data?: Buffer;
54
+ error?: string;
55
+ }>;
56
+ export declare function buzzDownloader(cli: string, { timeoutMs, env }?: {
57
+ timeoutMs?: number;
58
+ env?: NodeJS.ProcessEnv;
59
+ }): BuzzDownload;
60
+ export declare const MAX_ATTACHMENT_BYTES: number;
61
+ /** Content-type allowlist by magic bytes (images, pdf, audio, video, text, office); returns the file extension. */
62
+ export declare function attachmentKind(data: Buffer, claimed?: string): string | undefined;
63
+ export interface BuzzAttachments {
64
+ /**
65
+ * Kit-owned inbox `<root>/inbox` (realpath'd root). It lies outside the workspace: the sandboxed session
66
+ * may read it but never write it, so it cannot swap the directory or plant links while a download runs.
67
+ */
68
+ inbox: string;
69
+ /** Relay base URL (BUZZ_RELAY_URL); media URLs must be on this origin. */
70
+ relayUrl?: string;
71
+ download: BuzzDownload;
72
+ maxBytes?: number;
73
+ }
74
+ /** Validate a relay media reference: `sha256[.ext]`, or an URL on the relay origin under /media/. */
75
+ export declare function mediaInput(input: string, relayUrl?: string): {
76
+ input: string;
77
+ sha: string;
78
+ ext?: string;
79
+ } | undefined;
80
+ /** Download into the kit-owned inbox as `<sha256>.<ext>` (temp file opened `wx` in the inbox, then renamed). */
81
+ export declare function fetchAttachment(a: BuzzAttachments, raw: string): Promise<{
82
+ path: string;
83
+ bytes: number;
84
+ }>;
85
+ export declare const MAX_OUTGOING_FILES = 10, MAX_OUTGOING_BYTES: number, MAX_OUTGOING_TOTAL: number;
86
+ export interface BuzzOutbox {
87
+ /** Realpath of the sandboxed workspace: only regular files inside it may be sent. */
88
+ workspace: string;
89
+ /** Kit-private staging root under `<root>/.tealbrick`, which the sandbox cannot write. */
90
+ dir: string;
91
+ maxBytes?: number;
92
+ maxTotal?: number;
93
+ /** Test hook: runs after a file is validated and before its bytes are copied. */
94
+ beforeCopy?: (path: string) => Promise<void>;
95
+ }
96
+ export type StagedFile = {
97
+ path: string;
98
+ name: string;
99
+ bytes: number;
100
+ };
101
+ /** Basename safe for the relay and logs: letters, digits, `._-`; no leading dot; at most 120 chars. */
102
+ export declare function safeFileName(name: string): string;
103
+ /** Absolute path for a file to send: inside the workspace, no dot segments (dotfiles, .tealbrick) and no `inbox`. */
104
+ export declare function outgoingPath(workspace: string, p: string): string | undefined;
105
+ /**
106
+ * Copy files the model names into a fresh kit-private staging dir, for the unsandboxed buzz CLI to upload.
107
+ * Each file is opened O_NOFOLLOW|O_NONBLOCK (no final symlink, no blocking FIFO), must be a regular file with
108
+ * one link (no hard link to a host file), and the opened inode must be the one at its realpath inside the
109
+ * workspace (so a symlinked or swapped directory cannot redirect the open). Bytes are then copied from that
110
+ * descriptor, never re-read by path, so a swap after validation cannot change what is uploaded.
111
+ */
112
+ export declare function stageOutgoing(o: BuzzOutbox, paths: string[]): Promise<{
113
+ dir: string;
114
+ files: StagedFile[];
115
+ }>;
116
+ export declare const buzzToolNames: string[];
117
+ /** Present only in the sandboxed workspace mode. */
118
+ export declare const buzzAttachmentTool = "mcp__buzz__buzz_fetch_attachment";
119
+ export type BuzzSent = {
120
+ channel: string;
121
+ replyTo?: string;
122
+ mentions: string[];
123
+ content: string;
124
+ eventId?: string;
125
+ files?: string[];
126
+ };
127
+ export declare const MAX_TOOL_OUTPUT = 12000;
128
+ /** Compact, size-bounded view of `buzz messages get|thread` JSON output. */
129
+ export declare function compactEvents(stdout: string, max?: number): string;
130
+ export interface BuzzToolContext {
131
+ run: BuzzRun;
132
+ self?: string;
133
+ onSent?: (sent: BuzzSent) => void;
134
+ log?: (event: Record<string, unknown>) => void;
135
+ attachments?: BuzzAttachments;
136
+ outbox?: BuzzOutbox;
137
+ }
138
+ /** In-process `buzz` MCP server (owner session only; never handed to expert subagents). */
139
+ export declare function buzzMcpServer(sdk: ClaudeSdk, ctx: BuzzToolContext): unknown;
140
+ /** Neutralize `@Name` text so the CLI's content mention resolution cannot add p-tags we did not intend. */
141
+ export declare function neutralizeMentions(content: string): string;
142
+ export declare const LOOP_WINDOW_MS: number, LOOP_MAX_AGENT_TURNS = 4, REQUEST_TTL_MS: number, MAX_THREADS = 500;
143
+ /** Agent-triggered turns one peer may cause across ALL threads per LOOP_WINDOW_MS (fan-out across new threads). */
144
+ export declare const LOOP_MAX_PEER_TURNS = 8;
145
+ /** Per-thread and per-peer agent↔agent bookkeeping: in memory, process lifetime, LRU-bounded. */
146
+ export declare class BuzzThreads {
147
+ private now;
148
+ private max;
149
+ private peerMax;
150
+ private threads;
151
+ private peers;
152
+ constructor(now?: () => number, max?: number, peerMax?: number);
153
+ private get;
154
+ get size(): number;
155
+ /** Classify a turn triggered by another agent: capped (thread cap) or peer_capped (per-peer cap across threads): do not run; else an answer to our request, or a request to us. */
156
+ admit(key: string, author: string): 'capped' | 'peer_capped' | 'answer' | 'request';
157
+ /** Record that we asked these agents something in this thread. */
158
+ recordRequest(key: string, pubkeys: string[]): void;
159
+ /** At most one auto-post mention back per agent per thread per window. */
160
+ mayMentionBack(key: string, pubkey: string): boolean;
161
+ }