agentgui 1.0.911 → 1.0.913
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/lib/plugins/stream-plugin.js +1 -1
- package/lib/tool-spawner.js +26 -8
- package/package.json +1 -1
- package/site/theme.mjs +83 -65
package/lib/tool-spawner.js
CHANGED
|
@@ -29,17 +29,24 @@ const spawnNpmInstall = (pkg, onProgress) => new Promise((resolve) => {
|
|
|
29
29
|
proc.on('error', (err) => { clearTimeout(timer); if (!completed) { completed = true; resolve({ success: false, error: err.message }); } });
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
const
|
|
33
|
-
|
|
32
|
+
const BUNX_RUNNERS = [
|
|
33
|
+
{ cmd: isWindows ? 'bun.cmd' : 'bun', args: (pkg) => ['x', pkg] },
|
|
34
|
+
{ cmd: isWindows ? 'npx.cmd' : 'npx', args: (pkg) => ['-y', pkg] },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
const isMissingCmdError = (s) => /not recognized|ENOENT|command not found|cannot find/i.test(s || '');
|
|
38
|
+
|
|
39
|
+
const spawnBunxOnce = (runner, pkg, onProgress) => new Promise((resolve) => {
|
|
40
|
+
const cmd = runner.cmd;
|
|
34
41
|
let completed = false, stderr = '', stdout = '';
|
|
35
42
|
let lastDataTime = Date.now();
|
|
36
43
|
let proc;
|
|
37
44
|
try {
|
|
38
|
-
proc = spawn(cmd,
|
|
45
|
+
proc = spawn(cmd, runner.args(pkg), { stdio: ['pipe', 'pipe', 'pipe'], timeout: 300000, shell: isWindows, windowsHide: true });
|
|
39
46
|
} catch (err) {
|
|
40
|
-
return resolve({ success: false, error: `Failed to spawn
|
|
47
|
+
return resolve({ success: false, error: `Failed to spawn ${cmd}: ${err.message}`, missing: isMissingCmdError(err.message) });
|
|
41
48
|
}
|
|
42
|
-
if (!proc) return resolve({ success: false, error:
|
|
49
|
+
if (!proc) return resolve({ success: false, error: `Failed to spawn ${cmd} process`, missing: true });
|
|
43
50
|
|
|
44
51
|
const timer = setTimeout(() => {
|
|
45
52
|
if (!completed) { completed = true; try { proc.kill('SIGKILL'); } catch (_) {} resolve({ success: false, error: 'Timeout (5min)' }); }
|
|
@@ -48,7 +55,7 @@ const spawnBunxProc = (pkg, onProgress) => new Promise((resolve) => {
|
|
|
48
55
|
const heartbeatTimer = setInterval(() => {
|
|
49
56
|
if (completed) { clearInterval(heartbeatTimer); return; }
|
|
50
57
|
const elapsed = Date.now() - lastDataTime;
|
|
51
|
-
if (elapsed > 30000) console.warn(`[tool-manager] No output from
|
|
58
|
+
if (elapsed > 30000) console.warn(`[tool-manager] No output from ${cmd} ${pkg} for ${elapsed}ms - process may be hung`);
|
|
52
59
|
}, 30000);
|
|
53
60
|
|
|
54
61
|
const onData = (d) => { lastDataTime = Date.now(); if (onProgress) onProgress({ type: 'progress', data: d.toString() }); };
|
|
@@ -64,16 +71,27 @@ const spawnBunxProc = (pkg, onProgress) => new Promise((resolve) => {
|
|
|
64
71
|
const ok = [code === 0, output.includes('upgraded'), output.includes('registered'),
|
|
65
72
|
output.includes('Hooks registered'), output.includes('successfully'),
|
|
66
73
|
output.includes('Done'), code === 0 && !output.includes('error')].some(Boolean);
|
|
67
|
-
resolve(ok ? { success: true, error: null, pkg } : { success: false, error: output.substring(0, 1000) || 'Failed' });
|
|
74
|
+
resolve(ok ? { success: true, error: null, pkg } : { success: false, error: output.substring(0, 1000) || 'Failed', missing: isMissingCmdError(output) });
|
|
68
75
|
});
|
|
69
76
|
|
|
70
77
|
proc.on('error', (err) => {
|
|
71
78
|
clearTimeout(timer);
|
|
72
79
|
clearInterval(heartbeatTimer);
|
|
73
|
-
if (!completed) { completed = true; resolve({ success: false, error: `Process error: ${err.message}
|
|
80
|
+
if (!completed) { completed = true; resolve({ success: false, error: `Process error: ${err.message}`, missing: isMissingCmdError(err.message) }); }
|
|
74
81
|
});
|
|
75
82
|
});
|
|
76
83
|
|
|
84
|
+
const spawnBunxProc = async (pkg, onProgress) => {
|
|
85
|
+
let lastResult = null;
|
|
86
|
+
for (const runner of BUNX_RUNNERS) {
|
|
87
|
+
const result = await spawnBunxOnce(runner, pkg, onProgress);
|
|
88
|
+
if (result.success) return result;
|
|
89
|
+
lastResult = result;
|
|
90
|
+
if (!result.missing) return result;
|
|
91
|
+
}
|
|
92
|
+
return lastResult || { success: false, error: 'No runner available' };
|
|
93
|
+
};
|
|
94
|
+
|
|
77
95
|
function spawnForTool(tool, onProgress) {
|
|
78
96
|
const pkg = tool.installPkg || tool.pkg;
|
|
79
97
|
return tool.category === 'cli' ? spawnNpmInstall(pkg, onProgress) : spawnBunxProc(pkg, onProgress);
|
package/package.json
CHANGED
package/site/theme.mjs
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// AnEntrypoint design-system theme for flatspace.
|
|
2
|
-
// Renders
|
|
3
|
-
//
|
|
4
|
-
|
|
2
|
+
// Renders SDK chrome around home (landing) AND legacy docs/* pages
|
|
3
|
+
// (each rendered as an iframe of the original, preserving scripts/styles).
|
|
4
|
+
|
|
5
|
+
import { readFileSync, existsSync } from 'fs';
|
|
6
|
+
import { resolve, dirname } from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
5
8
|
|
|
6
9
|
const escapeHtml = (s) => String(s ?? '')
|
|
7
10
|
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
|
@@ -12,36 +15,36 @@ const escapeJson = (obj) => JSON.stringify(obj)
|
|
|
12
15
|
.replace(new RegExp('\\u2028', 'g'), '\\u2028').replace(new RegExp('\\u2029', 'g'), '\\u2029');
|
|
13
16
|
|
|
14
17
|
const SDK_URL = 'https://unpkg.com/anentrypoint-design@latest/dist/247420.js';
|
|
18
|
+
const THIS_DIR = dirname(fileURLToPath(import.meta.url));
|
|
15
19
|
|
|
16
|
-
const
|
|
20
|
+
const landingClient = `
|
|
17
21
|
import { h, applyDiff, installStyles, components as C } from 'anentrypoint-design';
|
|
18
22
|
installStyles();
|
|
19
23
|
document.documentElement.classList.add('ds-247420');
|
|
20
|
-
|
|
21
24
|
const data = JSON.parse(document.getElementById('__site__').textContent);
|
|
22
|
-
const { site, nav,
|
|
25
|
+
const { site, nav, page } = data;
|
|
23
26
|
|
|
24
27
|
function Hero() {
|
|
25
|
-
if (!
|
|
28
|
+
if (!page || !page.hero) return null;
|
|
26
29
|
return C.Panel({
|
|
27
30
|
style: 'margin:8px',
|
|
28
31
|
children: h('div', { style: 'padding:24px 22px' },
|
|
29
|
-
C.Heading({ level: 1, style: 'margin:0 0 8px 0', children:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
(
|
|
33
|
-
...
|
|
32
|
+
C.Heading({ level: 1, style: 'margin:0 0 8px 0', children: page.hero.heading || site.title }),
|
|
33
|
+
page.hero.subheading ? C.Lede({ children: page.hero.subheading }) : null,
|
|
34
|
+
page.hero.body ? h('p', { style: 'margin:8px 0 16px 0;color:var(--panel-text-2);max-width:64ch' }, page.hero.body) : null,
|
|
35
|
+
(page.hero.badges && page.hero.badges.length) ? h('div', { style: 'display:flex;gap:6px;flex-wrap:wrap;margin:0 0 12px 0' },
|
|
36
|
+
...page.hero.badges.map((b, i) => C.Chip({ key: 'b' + i, children: b.label }))
|
|
34
37
|
) : null,
|
|
35
|
-
(
|
|
36
|
-
...
|
|
38
|
+
(page.hero.ctas && page.hero.ctas.length) ? h('div', { style: 'display:flex;gap:8px;flex-wrap:wrap' },
|
|
39
|
+
...page.hero.ctas.map((c, i) => C.Btn({ key: 'c' + i, href: c.href, primary: c.primary, children: c.label }))
|
|
37
40
|
) : null
|
|
38
41
|
)
|
|
39
42
|
});
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
function Features() {
|
|
43
|
-
if (!
|
|
44
|
-
const rows =
|
|
46
|
+
if (!page || !page.features || !page.features.items || !page.features.items.length) return null;
|
|
47
|
+
const rows = page.features.items.map((it, i) => C.RowLink({
|
|
45
48
|
key: 'f' + i,
|
|
46
49
|
code: String(i + 1).padStart(2, '0'),
|
|
47
50
|
title: it.name,
|
|
@@ -50,15 +53,15 @@ function Features() {
|
|
|
50
53
|
href: it.href || '#'
|
|
51
54
|
}));
|
|
52
55
|
return C.Panel({
|
|
53
|
-
title:
|
|
56
|
+
title: page.features.heading || 'features',
|
|
54
57
|
style: 'margin:8px',
|
|
55
58
|
children: rows
|
|
56
59
|
});
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
function Quickstart() {
|
|
60
|
-
if (!
|
|
61
|
-
const lineNodes =
|
|
63
|
+
if (!page || !page.quickstart || !page.quickstart.lines || !page.quickstart.lines.length) return null;
|
|
64
|
+
const lineNodes = page.quickstart.lines.map((l, i) => {
|
|
62
65
|
const isComment = l.kind === 'cmt';
|
|
63
66
|
return h('div', { key: 'q' + i, class: 'cli' },
|
|
64
67
|
h('span', { class: 'prompt' }, isComment ? '#' : '$'),
|
|
@@ -66,28 +69,12 @@ function Quickstart() {
|
|
|
66
69
|
);
|
|
67
70
|
});
|
|
68
71
|
return C.Panel({
|
|
69
|
-
title:
|
|
72
|
+
title: page.quickstart.heading || 'quick start',
|
|
70
73
|
style: 'margin:8px',
|
|
71
74
|
children: h('div', { style: 'padding:16px 22px' }, ...lineNodes)
|
|
72
75
|
});
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
function Examples() {
|
|
76
|
-
if (!home || !home.examples || !home.examples.items || !home.examples.items.length) return null;
|
|
77
|
-
const rows = home.examples.items.map((it, i) => C.RowLink({
|
|
78
|
-
key: 'e' + i,
|
|
79
|
-
title: it.name,
|
|
80
|
-
sub: it.desc || '',
|
|
81
|
-
meta: it.cta || 'open',
|
|
82
|
-
href: it.href || '#'
|
|
83
|
-
}));
|
|
84
|
-
return C.Panel({
|
|
85
|
-
title: home.examples.heading || 'examples',
|
|
86
|
-
style: 'margin:8px',
|
|
87
|
-
children: rows
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
78
|
function Footer() {
|
|
92
79
|
return h('footer', { class: 'app-status' },
|
|
93
80
|
h('span', { class: 'item' }, 'styled with '),
|
|
@@ -102,64 +89,95 @@ function Footer() {
|
|
|
102
89
|
const navItems = (nav && nav.links ? nav.links : []).map(l => [String(l.label || ''), l.href]);
|
|
103
90
|
|
|
104
91
|
const App = C.AppShell({
|
|
105
|
-
topbar: C.Topbar({
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
items: navItems
|
|
109
|
-
}),
|
|
110
|
-
crumb: C.Crumb({
|
|
111
|
-
trail: ['247420'],
|
|
112
|
-
leaf: site.title || ''
|
|
113
|
-
}),
|
|
114
|
-
main: h('div', {},
|
|
115
|
-
Hero(),
|
|
116
|
-
Features(),
|
|
117
|
-
Quickstart(),
|
|
118
|
-
Examples()
|
|
119
|
-
),
|
|
92
|
+
topbar: C.Topbar({ brand: '247420', leaf: site.title || '', items: navItems }),
|
|
93
|
+
crumb: C.Crumb({ trail: ['247420'], leaf: site.title || '' }),
|
|
94
|
+
main: h('div', {}, Hero(), Features(), Quickstart()),
|
|
120
95
|
status: Footer()
|
|
121
96
|
});
|
|
97
|
+
applyDiff(document.getElementById('app'), [App]);
|
|
98
|
+
`;
|
|
122
99
|
|
|
100
|
+
const embedClient = `
|
|
101
|
+
import { h, applyDiff, installStyles, components as C } from 'anentrypoint-design';
|
|
102
|
+
installStyles();
|
|
103
|
+
document.documentElement.classList.add('ds-247420');
|
|
104
|
+
const data = JSON.parse(document.getElementById('__site__').textContent);
|
|
105
|
+
const { site, nav, page } = data;
|
|
106
|
+
const navItems = (nav && nav.links ? nav.links : []).map(l => [String(l.label || ''), l.href]);
|
|
107
|
+
|
|
108
|
+
function Footer() {
|
|
109
|
+
return h('footer', { class: 'app-status' },
|
|
110
|
+
h('span', { class: 'item' }, 'styled with '),
|
|
111
|
+
h('a', { class: 'item', href: 'https://anentrypoint.github.io/design/' }, 'anentrypoint-design'),
|
|
112
|
+
h('span', { class: 'item' }, '·'),
|
|
113
|
+
h('a', { class: 'item', href: 'https://247420.xyz' }, '247420.xyz'),
|
|
114
|
+
h('span', { class: 'spread' }),
|
|
115
|
+
site.repo ? h('a', { class: 'item', href: site.repo }, 'source ↗') : null
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const App = C.AppShell({
|
|
120
|
+
topbar: C.Topbar({ brand: '247420', leaf: site.title || '', items: navItems }),
|
|
121
|
+
crumb: C.Crumb({ trail: ['247420', site.title || ''], leaf: page.title || '' }),
|
|
122
|
+
main: C.Panel({
|
|
123
|
+
style: 'margin:8px',
|
|
124
|
+
children: h('iframe', {
|
|
125
|
+
src: page.embedSrc,
|
|
126
|
+
style: 'width:100%;height:calc(100vh - 180px);min-height:520px;border:0;border-radius:6px;background:var(--panel-1);display:block',
|
|
127
|
+
title: page.title || ''
|
|
128
|
+
})
|
|
129
|
+
}),
|
|
130
|
+
status: Footer()
|
|
131
|
+
});
|
|
123
132
|
applyDiff(document.getElementById('app'), [App]);
|
|
124
133
|
`;
|
|
125
134
|
|
|
126
|
-
const
|
|
135
|
+
const renderHtml = ({ site, nav, page, clientScript }) => `<!DOCTYPE html>
|
|
127
136
|
<html lang="en" class="ds-247420">
|
|
128
137
|
<head>
|
|
129
138
|
<meta charset="UTF-8" />
|
|
130
139
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
131
|
-
<title>${escapeHtml(site.title)}${site.tagline ? ' — ' + escapeHtml(site.tagline) : ''}</title>
|
|
132
|
-
<meta name="description" content="${escapeHtml(site.description || site.tagline || site.title)}" />
|
|
133
|
-
<meta property="og:title" content="${escapeHtml(site.title)}" />
|
|
134
|
-
<meta property="og:description" content="${escapeHtml(site.description || site.tagline || '')}" />
|
|
135
|
-
<meta property="og:url" content="${escapeHtml(site.url || '')}" />
|
|
136
|
-
<link rel="canonical" href="${escapeHtml(site.url || '')}" />
|
|
137
|
-
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Ctext y='26' font-size='26'%3E${encodeURIComponent(site.glyph || '◆')}%3C/text%3E%3C/svg%3E" />
|
|
140
|
+
<title>${escapeHtml(page.title || site.title)}${site.tagline ? ' — ' + escapeHtml(site.tagline) : ''}</title>
|
|
141
|
+
<meta name="description" content="${escapeHtml(page.description || site.description || site.tagline || site.title)}" />
|
|
138
142
|
<script type="importmap">{"imports":{"anentrypoint-design":"${SDK_URL}"}}</script>
|
|
139
143
|
<style>html,body{margin:0;padding:0}body{background:var(--app-bg,#FBF6EB);color:var(--ink,#1F1B16);font-family:var(--ff-ui,'Nunito',system-ui,sans-serif)}</style>
|
|
140
144
|
</head>
|
|
141
145
|
<body>
|
|
142
146
|
<div id="app"></div>
|
|
143
|
-
<script type="application/json" id="__site__">${escapeJson({ site, nav,
|
|
147
|
+
<script type="application/json" id="__site__">${escapeJson({ site, nav, page })}</script>
|
|
144
148
|
<script type="module">${clientScript}</script>
|
|
145
149
|
</body>
|
|
146
150
|
</html>
|
|
147
151
|
`;
|
|
148
152
|
|
|
149
153
|
export default {
|
|
154
|
+
// Copy original docs/* into dist/_legacy/* so iframes can load them.
|
|
150
155
|
assets: {
|
|
151
|
-
'../docs/demo.html': 'demo.html',
|
|
156
|
+
'../docs/demo.html': '_legacy/demo.html',
|
|
152
157
|
'../docs/screenshots': 'screenshots',
|
|
153
158
|
},
|
|
154
159
|
render: async (ctx) => {
|
|
155
160
|
const site = ctx.readGlobal('site') || {};
|
|
156
161
|
const nav = ctx.readGlobal('navigation') || { links: [] };
|
|
157
|
-
const
|
|
158
|
-
|
|
162
|
+
const docs = ctx.read('pages').docs;
|
|
163
|
+
const homeDoc = docs.find(p => p.id === 'home');
|
|
164
|
+
if (!homeDoc) throw new Error('site/content/pages/home.yaml missing or has no id: home');
|
|
159
165
|
|
|
160
|
-
|
|
166
|
+
const outputs = [{
|
|
161
167
|
path: 'index.html',
|
|
162
|
-
html:
|
|
168
|
+
html: renderHtml({ site, nav, page: homeDoc, clientScript: landingClient })
|
|
163
169
|
}];
|
|
170
|
+
|
|
171
|
+
// Wrapped legacy pages: SDK chrome + iframe of original.
|
|
172
|
+
const embeds = [
|
|
173
|
+
{ path: 'demo.html', title: 'demo', embedSrc: './_legacy/demo.html' },
|
|
174
|
+
];
|
|
175
|
+
for (const e of embeds) {
|
|
176
|
+
outputs.push({
|
|
177
|
+
path: e.path,
|
|
178
|
+
html: renderHtml({ site, nav, page: e, clientScript: embedClient })
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return outputs;
|
|
164
182
|
}
|
|
165
183
|
};
|