@bastani/atomic 0.9.40-alpha.1 → 0.9.40
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/CHANGELOG.md +37 -0
- package/dist/builtin/intercom/CHANGELOG.md +14 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +31 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/CHANGELOG.md +12 -0
- package/dist/builtin/web-access/README.md +1 -1
- package/dist/builtin/web-access/index.bundle.mjs +2 -5
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +25 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +11 -2
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +3 -2
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.html +1 -0
- package/dist/core/export-html/template.js +37 -20
- package/dist/core/export-html/vendor/marked-cjk-friendly.min.js +6 -0
- package/dist/core/export-html/vendor/marked.min.js +76 -3
- package/docs/providers.md +1 -1
- package/docs/settings.md +1 -1
- package/npm-shrinkwrap.json +35 -35
- package/package.json +5 -5
- package/dist/core/export-html/template-js/data-tree.js +0 -287
- package/dist/core/export-html/template-js/entries-navigation.js +0 -434
- package/dist/core/export-html/template-js/initialization.js +0 -335
- package/dist/core/export-html/template-js/message-tools.js +0 -428
- package/dist/core/export-html/template-js/tree-filter-render.js +0 -419
- package/dist/core/export-html/template-script.d.ts +0 -3
- package/dist/core/export-html/template-script.d.ts.map +0 -1
- package/dist/core/export-html/template-script.js +0 -13
- package/dist/core/export-html/template-script.js.map +0 -1
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// INITIALIZATION
|
|
3
|
-
// ============================================================
|
|
4
|
-
|
|
5
|
-
// Configure marked with syntax highlighting and TUI-compatible HTML handling
|
|
6
|
-
const strictStrikethroughRegex = /^(~~)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/;
|
|
7
|
-
|
|
8
|
-
marked.use({
|
|
9
|
-
breaks: true,
|
|
10
|
-
gfm: true,
|
|
11
|
-
tokenizer: {
|
|
12
|
-
// Treat HTML-like input as plain text so tags are shown verbatim,
|
|
13
|
-
// matching the TUI markdown renderer.
|
|
14
|
-
html() {
|
|
15
|
-
return undefined;
|
|
16
|
-
},
|
|
17
|
-
tag() {
|
|
18
|
-
return undefined;
|
|
19
|
-
},
|
|
20
|
-
del(src) {
|
|
21
|
-
const match = strictStrikethroughRegex.exec(src);
|
|
22
|
-
if (!match) return undefined;
|
|
23
|
-
return {
|
|
24
|
-
type: 'del',
|
|
25
|
-
raw: match[0],
|
|
26
|
-
text: match[2],
|
|
27
|
-
tokens: this.lexer.inlineTokens(match[2])
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
renderer: {
|
|
32
|
-
// Sanitize link URLs with a scheme allow-list. Browsers strip C0
|
|
33
|
-
// controls from schemes, so strip them before checking and emitting.
|
|
34
|
-
link(token) {
|
|
35
|
-
const href = sanitizeMarkdownUrl(token.href);
|
|
36
|
-
if (href === null) {
|
|
37
|
-
return this.parser.parseInline(token.tokens);
|
|
38
|
-
}
|
|
39
|
-
let out = '<a href="' + escapeHtml(href) + '"';
|
|
40
|
-
if (token.title) {
|
|
41
|
-
out += ' title="' + escapeHtml(token.title) + '"';
|
|
42
|
-
}
|
|
43
|
-
out += '>' + this.parser.parseInline(token.tokens) + '</a>';
|
|
44
|
-
return out;
|
|
45
|
-
},
|
|
46
|
-
// Sanitize image src URLs with the same scheme allow-list.
|
|
47
|
-
image(token) {
|
|
48
|
-
const href = sanitizeMarkdownUrl(token.href);
|
|
49
|
-
if (href === null) {
|
|
50
|
-
return escapeHtml(token.text || '');
|
|
51
|
-
}
|
|
52
|
-
let out = '<img src="' + escapeHtml(href) + '" alt="' + escapeHtml(token.text || '') + '"';
|
|
53
|
-
if (token.title) {
|
|
54
|
-
out += ' title="' + escapeHtml(token.title) + '"';
|
|
55
|
-
}
|
|
56
|
-
out += '>';
|
|
57
|
-
return out;
|
|
58
|
-
},
|
|
59
|
-
// Code blocks: syntax highlight, no HTML escaping
|
|
60
|
-
code(token) {
|
|
61
|
-
const code = token.text;
|
|
62
|
-
const lang = token.lang;
|
|
63
|
-
let highlighted;
|
|
64
|
-
if (lang && hljs.getLanguage(lang)) {
|
|
65
|
-
try {
|
|
66
|
-
highlighted = hljs.highlight(code, { language: lang }).value;
|
|
67
|
-
} catch {
|
|
68
|
-
highlighted = escapeHtml(code);
|
|
69
|
-
}
|
|
70
|
-
} else {
|
|
71
|
-
// Auto-detect language if not specified
|
|
72
|
-
try {
|
|
73
|
-
highlighted = hljs.highlightAuto(code).value;
|
|
74
|
-
} catch {
|
|
75
|
-
highlighted = escapeHtml(code);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return `<pre><code class="hljs">${highlighted}</code></pre>`;
|
|
79
|
-
},
|
|
80
|
-
// Inline code: escape HTML
|
|
81
|
-
codespan(token) {
|
|
82
|
-
return `<code>${escapeHtml(token.text)}</code>`;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
// Simple marked parse (escaping handled in renderers)
|
|
88
|
-
function safeMarkedParse(text) {
|
|
89
|
-
return marked.parse(text);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Search input
|
|
93
|
-
const searchInput = document.getElementById('tree-search');
|
|
94
|
-
searchInput.addEventListener('input', (e) => {
|
|
95
|
-
searchQuery = e.target.value;
|
|
96
|
-
forceTreeRerender();
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
// Filter buttons
|
|
100
|
-
document.querySelectorAll('.filter-btn').forEach(btn => {
|
|
101
|
-
btn.addEventListener('click', () => {
|
|
102
|
-
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
|
|
103
|
-
btn.classList.add('active');
|
|
104
|
-
filterMode = btn.dataset.filter;
|
|
105
|
-
forceTreeRerender();
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Sidebar toggle
|
|
110
|
-
const sidebar = document.getElementById('sidebar');
|
|
111
|
-
const overlay = document.getElementById('sidebar-overlay');
|
|
112
|
-
const hamburger = document.getElementById('hamburger');
|
|
113
|
-
const sidebarResizer = document.getElementById('sidebar-resizer');
|
|
114
|
-
const SIDEBAR_WIDTH_STORAGE_KEY = 'pi-share:v1:sidebar-width';
|
|
115
|
-
const MIN_CONTENT_WIDTH = 320;
|
|
116
|
-
|
|
117
|
-
function isMobileLayout() {
|
|
118
|
-
return window.matchMedia('(max-width: 900px)').matches;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function getSidebarBounds() {
|
|
122
|
-
const rootStyles = getComputedStyle(document.documentElement);
|
|
123
|
-
const minWidth = parseFloat(rootStyles.getPropertyValue('--sidebar-min-width')) || 240;
|
|
124
|
-
const maxWidth = parseFloat(rootStyles.getPropertyValue('--sidebar-max-width')) || 720;
|
|
125
|
-
const viewportMaxWidth = window.innerWidth - MIN_CONTENT_WIDTH;
|
|
126
|
-
return {
|
|
127
|
-
minWidth,
|
|
128
|
-
maxWidth: Math.max(minWidth, Math.min(maxWidth, viewportMaxWidth))
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function clampSidebarWidth(width) {
|
|
133
|
-
const { minWidth, maxWidth } = getSidebarBounds();
|
|
134
|
-
return Math.max(minWidth, Math.min(maxWidth, width));
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function applySidebarWidth(width) {
|
|
138
|
-
document.documentElement.style.setProperty('--sidebar-width', `${Math.round(clampSidebarWidth(width))}px`);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function loadSidebarWidth() {
|
|
142
|
-
try {
|
|
143
|
-
const raw = localStorage.getItem(SIDEBAR_WIDTH_STORAGE_KEY);
|
|
144
|
-
if (raw === null) return null;
|
|
145
|
-
const width = Number(raw);
|
|
146
|
-
return Number.isFinite(width) ? width : null;
|
|
147
|
-
} catch {
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function saveSidebarWidth(width) {
|
|
153
|
-
try {
|
|
154
|
-
localStorage.setItem(SIDEBAR_WIDTH_STORAGE_KEY, String(Math.round(clampSidebarWidth(width))));
|
|
155
|
-
} catch {
|
|
156
|
-
// Ignore storage failures (e.g. private browsing restrictions)
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function setupSidebarResize() {
|
|
161
|
-
const savedWidth = loadSidebarWidth();
|
|
162
|
-
if (savedWidth !== null) {
|
|
163
|
-
applySidebarWidth(savedWidth);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (!sidebarResizer) return;
|
|
167
|
-
|
|
168
|
-
let cleanupDrag = null;
|
|
169
|
-
|
|
170
|
-
const stopDrag = (pointerId) => {
|
|
171
|
-
if (cleanupDrag) {
|
|
172
|
-
cleanupDrag(pointerId);
|
|
173
|
-
cleanupDrag = null;
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
sidebarResizer.addEventListener('pointerdown', (e) => {
|
|
178
|
-
if (isMobileLayout()) return;
|
|
179
|
-
|
|
180
|
-
e.preventDefault();
|
|
181
|
-
const startX = e.clientX;
|
|
182
|
-
const startWidth = sidebar.getBoundingClientRect().width;
|
|
183
|
-
document.body.classList.add('sidebar-resizing');
|
|
184
|
-
sidebarResizer.setPointerCapture?.(e.pointerId);
|
|
185
|
-
|
|
186
|
-
const onPointerMove = (event) => {
|
|
187
|
-
applySidebarWidth(startWidth + (event.clientX - startX));
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
cleanupDrag = (pointerIdToRelease) => {
|
|
191
|
-
document.body.classList.remove('sidebar-resizing');
|
|
192
|
-
sidebarResizer.releasePointerCapture?.(pointerIdToRelease);
|
|
193
|
-
window.removeEventListener('pointermove', onPointerMove);
|
|
194
|
-
window.removeEventListener('pointerup', onPointerUp);
|
|
195
|
-
window.removeEventListener('pointercancel', onPointerCancel);
|
|
196
|
-
saveSidebarWidth(sidebar.getBoundingClientRect().width);
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
const onPointerUp = (event) => stopDrag(event.pointerId);
|
|
200
|
-
const onPointerCancel = (event) => stopDrag(event.pointerId);
|
|
201
|
-
|
|
202
|
-
window.addEventListener('pointermove', onPointerMove);
|
|
203
|
-
window.addEventListener('pointerup', onPointerUp);
|
|
204
|
-
window.addEventListener('pointercancel', onPointerCancel);
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
sidebarResizer.addEventListener('dblclick', () => {
|
|
208
|
-
if (isMobileLayout()) return;
|
|
209
|
-
applySidebarWidth(400);
|
|
210
|
-
saveSidebarWidth(400);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
window.addEventListener('resize', () => {
|
|
214
|
-
if (isMobileLayout()) return;
|
|
215
|
-
applySidebarWidth(sidebar.getBoundingClientRect().width);
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
setupSidebarResize();
|
|
220
|
-
|
|
221
|
-
hamburger.addEventListener('click', () => {
|
|
222
|
-
sidebar.classList.add('open');
|
|
223
|
-
overlay.classList.add('open');
|
|
224
|
-
hamburger.style.display = 'none';
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
const closeSidebar = () => {
|
|
228
|
-
sidebar.classList.remove('open');
|
|
229
|
-
overlay.classList.remove('open');
|
|
230
|
-
hamburger.style.display = '';
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
overlay.addEventListener('click', closeSidebar);
|
|
234
|
-
document.getElementById('sidebar-close').addEventListener('click', closeSidebar);
|
|
235
|
-
|
|
236
|
-
// Toggle states
|
|
237
|
-
let thinkingExpanded = true;
|
|
238
|
-
let toolOutputsExpanded = false;
|
|
239
|
-
let showHiddenMessages = false;
|
|
240
|
-
|
|
241
|
-
function setHiddenMessagesVisible(visible) {
|
|
242
|
-
showHiddenMessages = visible;
|
|
243
|
-
document.body.classList.toggle('show-hidden-messages', visible);
|
|
244
|
-
const button = document.querySelector('[data-action="toggle-hidden-messages"]');
|
|
245
|
-
if (button) {
|
|
246
|
-
button.setAttribute('aria-pressed', String(visible));
|
|
247
|
-
button.textContent = visible ? 'Hide hidden messages' : 'Show hidden messages';
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
function setThinkingExpanded(expanded) {
|
|
252
|
-
thinkingExpanded = expanded;
|
|
253
|
-
document.querySelector('[data-action="toggle-thinking"]')?.setAttribute('aria-pressed', String(expanded));
|
|
254
|
-
document.querySelectorAll('.thinking-text').forEach(el => {
|
|
255
|
-
el.style.display = thinkingExpanded ? '' : 'none';
|
|
256
|
-
});
|
|
257
|
-
document.querySelectorAll('.thinking-collapsed').forEach(el => {
|
|
258
|
-
el.style.display = thinkingExpanded ? 'none' : 'block';
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
function setToolOutputsExpanded(expanded) {
|
|
263
|
-
toolOutputsExpanded = expanded;
|
|
264
|
-
document.querySelector('[data-action="toggle-tools"]')?.setAttribute('aria-pressed', String(expanded));
|
|
265
|
-
document.querySelectorAll('.tool-output.expandable').forEach(el => {
|
|
266
|
-
el.classList.toggle('expanded', toolOutputsExpanded);
|
|
267
|
-
});
|
|
268
|
-
document.querySelectorAll('.compaction').forEach(el => {
|
|
269
|
-
el.classList.toggle('expanded', toolOutputsExpanded);
|
|
270
|
-
});
|
|
271
|
-
document.querySelectorAll('.skill-invocation').forEach(el => {
|
|
272
|
-
el.classList.toggle('expanded', toolOutputsExpanded);
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const attachHeaderHandlers = () => {
|
|
277
|
-
document.querySelector('[data-action="toggle-thinking"]')?.addEventListener('click', () => {
|
|
278
|
-
setThinkingExpanded(!thinkingExpanded);
|
|
279
|
-
});
|
|
280
|
-
document.querySelector('[data-action="toggle-tools"]')?.addEventListener('click', () => {
|
|
281
|
-
setToolOutputsExpanded(!toolOutputsExpanded);
|
|
282
|
-
});
|
|
283
|
-
document.querySelector('[data-action="toggle-hidden-messages"]')?.addEventListener('click', () => {
|
|
284
|
-
setHiddenMessagesVisible(!showHiddenMessages);
|
|
285
|
-
});
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const isEditableTarget = (element) => {
|
|
289
|
-
if (!element) return false;
|
|
290
|
-
const tagName = element.tagName;
|
|
291
|
-
if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT' || tagName === 'BUTTON') {
|
|
292
|
-
return true;
|
|
293
|
-
}
|
|
294
|
-
return element.isContentEditable || Boolean(element.closest?.('[contenteditable="true"]'));
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
// Keyboard shortcuts
|
|
298
|
-
document.addEventListener('keydown', (e) => {
|
|
299
|
-
if (e.key === 'Escape') {
|
|
300
|
-
searchInput.value = '';
|
|
301
|
-
searchQuery = '';
|
|
302
|
-
navigateTo(leafId, 'bottom');
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
if (e.ctrlKey || e.metaKey || e.altKey || isEditableTarget(document.activeElement)) {
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const key = e.key.toLowerCase();
|
|
310
|
-
if (key === 't') {
|
|
311
|
-
e.preventDefault();
|
|
312
|
-
setThinkingExpanded(!thinkingExpanded);
|
|
313
|
-
} else if (key === 'o') {
|
|
314
|
-
e.preventDefault();
|
|
315
|
-
setToolOutputsExpanded(!toolOutputsExpanded);
|
|
316
|
-
} else if (key === 'h') {
|
|
317
|
-
e.preventDefault();
|
|
318
|
-
setHiddenMessagesVisible(!showHiddenMessages);
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
// Initial render
|
|
323
|
-
// If URL has targetId, scroll to that specific message; otherwise stay at top
|
|
324
|
-
if (leafId) {
|
|
325
|
-
if (urlTargetId && byId.has(urlTargetId)) {
|
|
326
|
-
// Deep link: navigate to leaf and scroll to target message
|
|
327
|
-
navigateTo(leafId, 'target', urlTargetId);
|
|
328
|
-
} else {
|
|
329
|
-
navigateTo(leafId, 'none');
|
|
330
|
-
}
|
|
331
|
-
} else if (entries.length > 0) {
|
|
332
|
-
// Fallback: use last entry if no leafId
|
|
333
|
-
navigateTo(entries[entries.length - 1].id, 'none');
|
|
334
|
-
}
|
|
335
|
-
})();
|