@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.
@@ -0,0 +1,218 @@
1
+ {
2
+ "id": "diffs",
3
+ "activation": {
4
+ "onStartup": true
5
+ },
6
+ "name": "Diffs",
7
+ "description": "Read-only diff viewer and file renderer for agents.",
8
+ "contracts": {
9
+ "tools": ["diffs"]
10
+ },
11
+ "toolMetadata": {
12
+ "diffs": {
13
+ "optional": true
14
+ }
15
+ },
16
+ "skills": ["./skills"],
17
+ "uiHints": {
18
+ "viewerBaseUrl": {
19
+ "label": "Viewer Base URL",
20
+ "help": "Persistent gateway base URL used for returned viewer links when a tool call does not pass baseUrl."
21
+ },
22
+ "defaults.fontFamily": {
23
+ "label": "Default Font",
24
+ "help": "Preferred font family name for diff content and headers."
25
+ },
26
+ "defaults.fontSize": {
27
+ "label": "Default Font Size",
28
+ "help": "Base diff font size in pixels."
29
+ },
30
+ "defaults.lineSpacing": {
31
+ "label": "Default Line Spacing",
32
+ "help": "Line-height multiplier applied to diff rows."
33
+ },
34
+ "defaults.layout": {
35
+ "label": "Default Layout",
36
+ "help": "Initial diff layout shown in the viewer."
37
+ },
38
+ "defaults.showLineNumbers": {
39
+ "label": "Show Line Numbers",
40
+ "help": "Show line numbers by default."
41
+ },
42
+ "defaults.diffIndicators": {
43
+ "label": "Diff Indicator Style",
44
+ "help": "Choose added/removed indicators style."
45
+ },
46
+ "defaults.wordWrap": {
47
+ "label": "Default Word Wrap",
48
+ "help": "Wrap long lines by default."
49
+ },
50
+ "defaults.background": {
51
+ "label": "Default Background Highlights",
52
+ "help": "Show added/removed background highlights by default."
53
+ },
54
+ "defaults.theme": {
55
+ "label": "Default Theme",
56
+ "help": "Initial viewer theme."
57
+ },
58
+ "defaults.fileFormat": {
59
+ "label": "Default File Format",
60
+ "help": "Rendered file format for file mode (PNG or PDF)."
61
+ },
62
+ "defaults.fileQuality": {
63
+ "label": "Default File Quality",
64
+ "help": "Quality preset for PNG/PDF rendering."
65
+ },
66
+ "defaults.fileScale": {
67
+ "label": "Default File Scale",
68
+ "help": "Device scale factor used while rendering file artifacts."
69
+ },
70
+ "defaults.fileMaxWidth": {
71
+ "label": "Default File Max Width",
72
+ "help": "Maximum file render width in CSS pixels."
73
+ },
74
+ "defaults.mode": {
75
+ "label": "Default Output Mode",
76
+ "help": "Tool default when mode is omitted. Use view for canvas/gateway viewer, file for PNG/PDF, or both."
77
+ },
78
+ "defaults.ttlSeconds": {
79
+ "label": "Default Artifact TTL",
80
+ "help": "Default lifetime in seconds for diff viewer and file artifacts. Maximum: 21600."
81
+ },
82
+ "security.allowRemoteViewer": {
83
+ "label": "Allow Remote Viewer",
84
+ "help": "Allow non-loopback access to diff viewer URLs when the token path is known."
85
+ }
86
+ },
87
+ "configSchema": {
88
+ "type": "object",
89
+ "additionalProperties": false,
90
+ "properties": {
91
+ "viewerBaseUrl": {
92
+ "type": "string",
93
+ "format": "uri",
94
+ "pattern": "^[Hh][Tt][Tt][Pp][Ss]?://",
95
+ "not": {
96
+ "pattern": "[?#]"
97
+ }
98
+ },
99
+ "defaults": {
100
+ "type": "object",
101
+ "additionalProperties": false,
102
+ "properties": {
103
+ "fontFamily": {
104
+ "type": "string",
105
+ "default": "Fira Code"
106
+ },
107
+ "fontSize": {
108
+ "type": "number",
109
+ "minimum": 10,
110
+ "maximum": 24,
111
+ "default": 15
112
+ },
113
+ "lineSpacing": {
114
+ "type": "number",
115
+ "minimum": 1,
116
+ "maximum": 3,
117
+ "default": 1.6
118
+ },
119
+ "layout": {
120
+ "type": "string",
121
+ "enum": ["unified", "split"],
122
+ "default": "unified"
123
+ },
124
+ "showLineNumbers": {
125
+ "type": "boolean",
126
+ "default": true
127
+ },
128
+ "diffIndicators": {
129
+ "type": "string",
130
+ "enum": ["bars", "classic", "none"],
131
+ "default": "bars"
132
+ },
133
+ "wordWrap": {
134
+ "type": "boolean",
135
+ "default": true
136
+ },
137
+ "background": {
138
+ "type": "boolean",
139
+ "default": true
140
+ },
141
+ "theme": {
142
+ "type": "string",
143
+ "enum": ["light", "dark"],
144
+ "default": "dark"
145
+ },
146
+ "fileFormat": {
147
+ "type": "string",
148
+ "enum": ["png", "pdf"],
149
+ "default": "png"
150
+ },
151
+ "format": {
152
+ "type": "string",
153
+ "description": "Deprecated alias for fileFormat.",
154
+ "enum": ["png", "pdf"]
155
+ },
156
+ "fileQuality": {
157
+ "type": "string",
158
+ "enum": ["standard", "hq", "print"],
159
+ "default": "standard"
160
+ },
161
+ "fileScale": {
162
+ "type": "number",
163
+ "minimum": 1,
164
+ "maximum": 4
165
+ },
166
+ "fileMaxWidth": {
167
+ "type": "number",
168
+ "minimum": 640,
169
+ "maximum": 2400
170
+ },
171
+ "imageFormat": {
172
+ "type": "string",
173
+ "description": "Deprecated alias for fileFormat.",
174
+ "enum": ["png", "pdf"]
175
+ },
176
+ "imageQuality": {
177
+ "type": "string",
178
+ "description": "Deprecated alias for fileQuality.",
179
+ "enum": ["standard", "hq", "print"]
180
+ },
181
+ "imageScale": {
182
+ "type": "number",
183
+ "description": "Deprecated alias for fileScale.",
184
+ "minimum": 1,
185
+ "maximum": 4
186
+ },
187
+ "imageMaxWidth": {
188
+ "type": "number",
189
+ "description": "Deprecated alias for fileMaxWidth.",
190
+ "minimum": 640,
191
+ "maximum": 2400
192
+ },
193
+ "mode": {
194
+ "type": "string",
195
+ "enum": ["view", "image", "file", "both"],
196
+ "default": "both"
197
+ },
198
+ "ttlSeconds": {
199
+ "type": "number",
200
+ "minimum": 1,
201
+ "maximum": 21600,
202
+ "default": 1800
203
+ }
204
+ }
205
+ },
206
+ "security": {
207
+ "type": "object",
208
+ "additionalProperties": false,
209
+ "properties": {
210
+ "allowRemoteViewer": {
211
+ "type": "boolean",
212
+ "default": false
213
+ }
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
package/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { definePluginEntry } from "./api.js";
2
+ import { diffsPluginConfigSchema } from "./src/config.js";
3
+ import { registerDiffsPlugin } from "./src/plugin.js";
4
+
5
+ export default definePluginEntry({
6
+ id: "diffs",
7
+ name: "Diffs",
8
+ description: "Read-only diff viewer and PNG/PDF renderer for agents.",
9
+ configSchema: diffsPluginConfigSchema,
10
+ register: registerDiffsPlugin,
11
+ });
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@gakr-gakr/diffs",
3
+ "version": "0.1.0",
4
+ "description": "AutoBot diff viewer plugin",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/autobot/autobot"
8
+ },
9
+ "type": "module",
10
+ "scripts": {
11
+ "build:viewer": "bun build src/viewer-client.ts --target browser --format esm --minify --outfile assets/viewer-runtime.js"
12
+ },
13
+ "dependencies": {
14
+ "@pierre/diffs": "1.1.22",
15
+ "@pierre/theme": "0.0.29",
16
+ "playwright-core": "1.60.0",
17
+ "typebox": "1.1.38",
18
+ "zod": "4.4.3"
19
+ },
20
+ "devDependencies": {
21
+ "@gakr-gakr/plugin-sdk": "workspace:*"
22
+ },
23
+ "autobot": {
24
+ "extensions": [
25
+ "./index.ts"
26
+ ],
27
+ "install": {
28
+ "npmSpec": "@gakr-gakr/diffs",
29
+ "localPath": "extensions/diffs",
30
+ "defaultChoice": "npm",
31
+ "minHostVersion": ">=2026.4.30"
32
+ },
33
+ "compat": {
34
+ "pluginApi": ">=2026.5.19"
35
+ },
36
+ "build": {
37
+ "autobotVersion": "2026.5.19",
38
+ "staticAssets": [
39
+ {
40
+ "source": "./assets/viewer-runtime.js",
41
+ "output": "assets/viewer-runtime.js"
42
+ }
43
+ ]
44
+ },
45
+ "release": {
46
+ "publishToClawHub": true,
47
+ "publishToNpm": true
48
+ }
49
+ }
50
+ }
package/runtime-api.ts ADDED
@@ -0,0 +1 @@
1
+ export { resolveRequestClientIp } from "autobot/plugin-sdk/webhook-ingress";
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: diffs
3
+ description: Use the diffs tool to produce real, shareable diffs (viewer URL, file artifact, or both) instead of manual edit summaries.
4
+ ---
5
+
6
+ When you need to show edits as a real diff, prefer the `diffs` tool instead of writing a manual summary.
7
+
8
+ The `diffs` tool accepts either `before` + `after` text, or a unified `patch` string.
9
+
10
+ Use `mode=view` when you want an interactive gateway-hosted viewer. After the tool returns, use `details.viewerUrl` with the canvas tool via `canvas present` or `canvas navigate`.
11
+ If the deployment uses a loopback trusted proxy (for example Tailscale Serve with `gateway.trustedProxies` including `127.0.0.1`), raw loopback viewer requests can fail closed without forwarded client-IP headers. In that topology, prefer `mode=file` / `mode=both`, or use a configured `viewerBaseUrl` / explicit proxy/public `baseUrl` when you need a shareable viewer URL.
12
+
13
+ Use `mode=file` when you need a rendered file artifact. Set `fileFormat=png` (default) or `fileFormat=pdf`. The tool result includes `details.filePath`.
14
+
15
+ For large or high-fidelity files, use `fileQuality` (`standard`|`hq`|`print`) and optionally override `fileScale`/`fileMaxWidth`.
16
+
17
+ When you need to deliver the rendered file to a user or channel, do not rely on the raw tool-result renderer. Instead, call the `message` tool and pass `details.filePath` through `path` or `filePath`.
18
+
19
+ Use `mode=both` when you want both the gateway viewer URL and the rendered artifact.
20
+
21
+ If the user has configured diffs plugin defaults, prefer omitting `mode`, `theme`, `layout`, and related presentation options unless you need to override them for this specific diff.
22
+
23
+ Include `path` for before/after text when you know the file name.