@gakr-gakr/diffs 0.1.0

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.
package/README.md ADDED
@@ -0,0 +1,217 @@
1
+ # @gakr-gakr/diffs
2
+
3
+ Read-only diff viewer plugin for **AutoBot** agents.
4
+
5
+ It gives agents one tool, `diffs`, that can:
6
+
7
+ - render a gateway-hosted diff viewer for canvas use
8
+ - render the same diff to a file (PNG or PDF)
9
+ - accept either arbitrary `before` and `after` text or a unified patch
10
+
11
+ ## What Agents Get
12
+
13
+ The tool can return:
14
+
15
+ - `details.viewerUrl`: a gateway URL that can be opened in the canvas
16
+ - `details.filePath`: a local rendered artifact path when file rendering is requested
17
+ - `details.fileFormat`: the rendered file format (`png` or `pdf`)
18
+ - `details.artifactId` and `details.expiresAt`: artifact identity and TTL metadata
19
+ - `details.context`: available routing metadata such as `agentId`, `sessionId`, `messageChannel`, and `agentAccountId`
20
+
21
+ When the plugin is enabled, it also ships a companion skill from `skills/` and prepends stable tool-usage guidance into system-prompt space via `before_prompt_build`. The hook uses `prependSystemContext`, so the guidance stays out of user-prompt space while still being available every turn.
22
+
23
+ This means an agent can:
24
+
25
+ - call `diffs` with `mode=view`, then pass `details.viewerUrl` to `canvas present`
26
+ - call `diffs` with `mode=file`, then send the file through the normal `message` tool using `path` or `filePath`
27
+ - call `diffs` with `mode=both` when it wants both outputs
28
+
29
+ ## Tool Inputs
30
+
31
+ Before and after:
32
+
33
+ ```json
34
+ {
35
+ "before": "# Hello\n\nOne",
36
+ "after": "# Hello\n\nTwo",
37
+ "path": "docs/example.md",
38
+ "mode": "view"
39
+ }
40
+ ```
41
+
42
+ Patch:
43
+
44
+ ```json
45
+ {
46
+ "patch": "diff --git a/src/example.ts b/src/example.ts\n--- a/src/example.ts\n+++ b/src/example.ts\n@@ -1 +1 @@\n-const x = 1;\n+const x = 2;\n",
47
+ "mode": "both"
48
+ }
49
+ ```
50
+
51
+ Useful options:
52
+
53
+ - `mode`: `view`, `file`, or `both`
54
+ Deprecated alias: `image` behaves like `file` and is still accepted for backward compatibility.
55
+ - `layout`: `unified` or `split`
56
+ - `theme`: `light` or `dark` (default: `dark`)
57
+ - `fileFormat`: `png` or `pdf` (default: `png`)
58
+ - `fileQuality`: `standard`, `hq`, or `print`
59
+ - `fileScale`: device scale override (`1`-`4`)
60
+ - `fileMaxWidth`: max width override in CSS pixels (`640`-`2400`)
61
+ - `expandUnchanged`: expand unchanged sections (per-call option only, not a plugin default key)
62
+ - `path`: display name for before and after input
63
+ - `lang`: language hint for before/after input; unknown values fall back to plain text
64
+ - `title`: explicit viewer title
65
+ - `ttlSeconds`: artifact lifetime for viewer and standalone file outputs
66
+ - `baseUrl`: override the gateway base URL used in the returned viewer link (origin or origin+base path only; no query/hash)
67
+ - `viewerBaseUrl` plugin config: persistent fallback used when a tool call omits `baseUrl`
68
+
69
+ Legacy input aliases still accepted for backward compatibility:
70
+
71
+ - `format` -> `fileFormat`
72
+ - `imageFormat` -> `fileFormat`
73
+ - `imageQuality` -> `fileQuality`
74
+ - `imageScale` -> `fileScale`
75
+ - `imageMaxWidth` -> `fileMaxWidth`
76
+
77
+ Input safety limits:
78
+
79
+ - `before` and `after`: max 512 KiB each
80
+ - `patch`: max 2 MiB
81
+ - patch rendering cap: max 128 files / 120,000 lines
82
+
83
+ ## Plugin Defaults
84
+
85
+ Set plugin-wide defaults in `~/.autobot/autobot.json`:
86
+
87
+ ```json5
88
+ {
89
+ plugins: {
90
+ entries: {
91
+ diffs: {
92
+ enabled: true,
93
+ config: {
94
+ defaults: {
95
+ fontFamily: "Fira Code",
96
+ fontSize: 15,
97
+ lineSpacing: 1.6,
98
+ layout: "unified",
99
+ showLineNumbers: true,
100
+ diffIndicators: "bars",
101
+ wordWrap: true,
102
+ background: true,
103
+ theme: "dark",
104
+ fileFormat: "png",
105
+ fileQuality: "standard",
106
+ fileScale: 2,
107
+ fileMaxWidth: 960,
108
+ mode: "both",
109
+ ttlSeconds: 21600,
110
+ },
111
+ },
112
+ },
113
+ },
114
+ },
115
+ }
116
+ ```
117
+
118
+ Explicit tool parameters still win over these defaults.
119
+
120
+ Security options:
121
+
122
+ - `security.allowRemoteViewer` (default `false`): allows non-loopback access to `/plugins/diffs/view/...` token URLs
123
+ - `viewerBaseUrl` (optional): persistent viewer-link origin/path fallback for shareable URLs
124
+ - `defaults.ttlSeconds` (default `1800`, max `21600`): default artifact lifetime for viewer and standalone file outputs
125
+
126
+ Example:
127
+
128
+ ```json5
129
+ {
130
+ plugins: {
131
+ entries: {
132
+ diffs: {
133
+ enabled: true,
134
+ config: {
135
+ viewerBaseUrl: "https://gateway.example.com/autobot",
136
+ },
137
+ },
138
+ },
139
+ },
140
+ }
141
+ ```
142
+
143
+ ## Example Agent Prompts
144
+
145
+ Open in canvas:
146
+
147
+ ```text
148
+ Use the `diffs` tool in `view` mode for this before and after content, then open the returned viewer URL in the canvas.
149
+
150
+ Path: docs/example.md
151
+
152
+ Before:
153
+ # Hello
154
+
155
+ This is version one.
156
+
157
+ After:
158
+ # Hello
159
+
160
+ This is version two.
161
+ ```
162
+
163
+ Render a file (PNG or PDF):
164
+
165
+ ```text
166
+ Use the `diffs` tool in `file` mode for this before and after input. After it returns `details.filePath`, use the `message` tool with `path` or `filePath` to send me the rendered diff file.
167
+
168
+ Path: README.md
169
+
170
+ Before:
171
+ AutoBot supports plugins.
172
+
173
+ After:
174
+ AutoBot supports plugins and hosted diff views.
175
+ ```
176
+
177
+ Do both:
178
+
179
+ ```text
180
+ Use the `diffs` tool in `both` mode for this diff. Open the viewer in the canvas and then send the rendered file by passing `details.filePath` to the `message` tool.
181
+
182
+ Path: src/demo.ts
183
+
184
+ Before:
185
+ const status = "old";
186
+
187
+ After:
188
+ const status = "new";
189
+ ```
190
+
191
+ Patch input:
192
+
193
+ ```text
194
+ Use the `diffs` tool with this unified patch in `view` mode. After it returns the viewer URL, present it in the canvas.
195
+
196
+ diff --git a/src/example.ts b/src/example.ts
197
+ --- a/src/example.ts
198
+ +++ b/src/example.ts
199
+ @@ -1,3 +1,3 @@
200
+ export function add(a: number, b: number) {
201
+ - return a + b;
202
+ + return a + b + 1;
203
+ }
204
+ ```
205
+
206
+ ## Notes
207
+
208
+ - The viewer is hosted locally through the gateway under `/plugins/diffs/...`.
209
+ - Artifacts are ephemeral and stored in the plugin temp subfolder (`$TMPDIR/autobot-diffs`).
210
+ - Default viewer URLs use loopback (`127.0.0.1`) unless you set plugin `viewerBaseUrl`, pass `baseUrl`, or use `gateway.bind=custom` + `gateway.customBindHost`.
211
+ - If `gateway.trustedProxies` includes loopback for a same-host proxy (for example Tailscale Serve), raw `127.0.0.1` viewer requests without forwarded client-IP headers fail closed by design.
212
+ - In that topology, prefer `mode=file` / `mode=both` for attachments, or intentionally enable remote viewers and set plugin `viewerBaseUrl` (or pass a proxy/public `baseUrl`) when you need a shareable viewer URL.
213
+ - Remote viewer misses are throttled to reduce token-guess abuse.
214
+ - PNG or PDF rendering requires a Chromium-compatible browser. Set `browser.executablePath` if auto-detection is not enough.
215
+ - If your delivery channel compresses images heavily (for example Telegram or WhatsApp), prefer `fileFormat: "pdf"` to preserve readability.
216
+ - `N unmodified lines` rows may not always include expand controls for patch input, because many patch hunks do not carry full expandable context data.
217
+ - Diff rendering is powered by [Diffs](https://diffs.com).
package/api.ts ADDED
@@ -0,0 +1,10 @@
1
+ export type { AutoBotConfig } from "autobot/plugin-sdk/config-contracts";
2
+ export {
3
+ definePluginEntry,
4
+ type AnyAgentTool,
5
+ type AutoBotPluginApi,
6
+ type AutoBotPluginConfigSchema,
7
+ type AutoBotPluginToolContext,
8
+ type PluginLogger,
9
+ } from "autobot/plugin-sdk/plugin-entry";
10
+ export { resolvePreferredAutoBotTmpDir } from "autobot/plugin-sdk/temp-path";