anentrypoint-design 0.0.75 → 0.0.77

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anentrypoint-design",
3
- "version": "0.0.75",
3
+ "version": "0.0.77",
4
4
  "description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
5
5
  "type": "module",
6
6
  "main": "./dist/247420.js",
@@ -139,7 +139,7 @@ export function Table({ headers = [], rows = [], onRowClick, emptyText = 'no row
139
139
  h('tbody', {}, ...rows.map((row, i) => h('tr', {
140
140
  class: onRowClick ? 'clickable' : '',
141
141
  onclick: onRowClick ? () => onRowClick(i) : null
142
- }, ...row.map(c => h('td', {}, c == null ? '' : String(c)))))));
142
+ }, ...row.map(c => h('td', {}, c == null ? '' : (typeof c === 'object' ? c : String(c))))))));
143
143
  }
144
144
 
145
145
  export function Section({ title, children }) {
@@ -15,7 +15,7 @@ export function flattenKv(obj, prefix='') {
15
15
  const key = prefix ? prefix+'.'+k : k;
16
16
  if (v === null || v === undefined) rows.push([key, '—']);
17
17
  else if (typeof v === 'object' && !Array.isArray(v)) rows.push(...flattenKv(v, key));
18
- else if (Array.isArray(v)) rows.push([key, v.length === 0 ? '[]' : v.map(x => typeof x === 'object' ? '{…}' : String(x)).join(', ')]);
18
+ else if (Array.isArray(v)) rows.push([key, v.length === 0 ? '' : v.map(x => typeof x === 'object' ? '{…}' : String(x)).join(', ')]);
19
19
  else rows.push([key, String(v)]);
20
20
  }
21
21
  return rows;
@@ -1,5 +1,5 @@
1
1
  import * as webjsx from '../../../vendor/webjsx/index.js';
2
- import { Panel, Receipt } from '../content.js';
2
+ import { Panel, Hero, Receipt } from '../content.js';
3
3
  import { Chip } from '../shell.js';
4
4
  import { skillLabel, getRecentPaths, saveRecentPath, renderChatMessages } from './helpers.js';
5
5
  const h = webjsx.createElement;
@@ -71,6 +71,7 @@ export async function chat(h0) {
71
71
  const byCat = skills.reduce((a, s) => { const c = s.category || 'other'; (a[c] = a[c] || []).push(s); return a; }, {});
72
72
  setTimeout(() => renderChatMessages(getMsgs(), cs.messages), 50);
73
73
  return [
74
+ Hero({ title: 'chat', body: 'talk to the agent. pick a working dir, optional skill, optional provider.', accent: cs.sessionId ? 'session '+cs.sessionId.slice(0,8) : 'new session' }),
74
75
  Panel({ title: 'chat', right: h('button', { class: 'btn-primary', onclick: ev => { ev.preventDefault(); newSession(); } }, '+ new'), children: [
75
76
  h('form', { class: 'fd-chat-form', onsubmit: sendChat },
76
77
  h('label', { class: 'fd-label' }, 'WORKING DIRECTORY'),
@@ -1,5 +1,5 @@
1
1
  import * as webjsx from '../../../vendor/webjsx/index.js';
2
- import { Panel, Row, Receipt, Kpi, Table, Form } from '../content.js';
2
+ import { Panel, Row, Hero, Receipt, Kpi, Table, Form } from '../content.js';
3
3
  import { Chip } from '../shell.js';
4
4
  import { EmptyState } from '../files.js';
5
5
  import { skillLabel, renderConfigSections } from './helpers.js';
@@ -18,15 +18,21 @@ export async function models(h0) {
18
18
  }));
19
19
  if (typeof window.__fd_nav === 'function') window.__fd_nav('models');
20
20
  }
21
- const modelPanels = configured.map(p => {
22
- const models = Array.isArray(probeState[p.name]) ? probeState[p.name] : p.models;
21
+ const probedPanels = [];
22
+ const unprobedRows = [];
23
+ for (const p of configured) {
24
+ const ms = Array.isArray(probeState[p.name]) ? probeState[p.name] : p.models;
23
25
  const loading = probeState[p.name] === 'loading';
24
- const children = loading ? h('span', {}, 'probing…')
25
- : models && models.length > 0 ? Table({ headers: ['model id'], rows: models.map(m => [m]) })
26
- : h('span', { class: 'fd-muted' }, p.modelsError ? 'error: '+p.modelsError : 'not probed — click "probe all"');
27
- return Panel({ title: p.name + (p.available ? ' ●' : ' ○'), children });
28
- });
26
+ if (loading) probedPanels.push(Panel({ title: p.name + ' ⏳', children: h('span', { class: 'fd-muted' }, 'probing…') }));
27
+ else if (ms && ms.length > 0) probedPanels.push(Panel({ title: p.name + (p.available ? ' ●' : ' ○'), count: ms.length, children: Table({ headers: ['model id'], rows: ms.map(m => [m]) }) }));
28
+ else unprobedRows.push([p.name, p.available ? 'available' : 'unavailable', p.modelsError ? 'error: '+p.modelsError : 'click "probe all"']);
29
+ }
30
+ const modelPanels = [
31
+ ...probedPanels,
32
+ unprobedRows.length ? Panel({ title: 'unprobed providers', count: unprobedRows.length, children: Table({ headers: ['provider','status','note'], rows: unprobedRows }) }) : null
33
+ ].filter(Boolean);
29
34
  return [
35
+ Hero({ title: 'models', body: 'pick a provider, pick a model. probe to list available models.', accent: configured.length+' configured' }),
30
36
  Kpi({ items: [[configured.length,'configured'],[providers.filter(p => p.available).length,'available']] }),
31
37
  Panel({ title: 'change active model', children: Form({ fields: [
32
38
  { name: 'provider', placeholder: 'provider', value: cfg.agent?.provider || '' },
@@ -45,6 +51,7 @@ export async function models(h0) {
45
51
  export async function cron(h0) {
46
52
  const list = await h0.pi.cron.list();
47
53
  return [
54
+ Hero({ title: 'cron', body: 'scheduled prompts. cron syntax, fired by freddie.', accent: list.length+' jobs' }),
48
55
  Kpi({ items: [[list.length,'jobs']] }),
49
56
  Panel({ title: 'add job', children: Form({ fields: [
50
57
  { name: 'cron', placeholder: '* * * * *', required: true },
@@ -58,6 +65,7 @@ export async function skills(h0) {
58
65
  const list = [...h0.pi.skills.values()];
59
66
  const byCat = list.reduce((a, s) => { (a[s.category||'other'] = a[s.category||'other'] || []).push(s); return a; }, {});
60
67
  return [
68
+ Hero({ title: 'skills', body: 'SKILL.md bundles loaded from ~/.freddie/skills + plugins.', accent: list.length+' loaded' }),
61
69
  Kpi({ items: [[list.length,'skills'],[Object.keys(byCat).length,'categories']] }),
62
70
  list.length === 0 ? EmptyState({ text: 'no skills — add SKILL.md files to ~/.freddie/skills/', glyph: '◈' }) : null,
63
71
  ...Object.entries(byCat).map(([cat, ss]) => Panel({ title: cat, count: ss.length, children: Table({ headers: ['name','description'], rows: ss.map(s => [skillLabel(s), (s.description||'').slice(0,120)]) }) }))
@@ -68,6 +76,7 @@ export async function config(h0) {
68
76
  const cfg = typeof h0.pi.config?.load === 'function' ? await h0.pi.config.load() : {};
69
77
  const commands = typeof h0.pi.cli?.values === 'function' ? [...h0.pi.cli.values()] : [];
70
78
  return [
79
+ Hero({ title: 'config', body: 'live ~/.freddie/config.yaml. dotted keys, json or string values.', accent: 'v'+(cfg._config_version||0) }),
71
80
  Kpi({ items: [[commands.length,'commands'],[cfg._config_version||0,'config version']] }),
72
81
  Panel({ title: 'set config value', children: Form({ fields: [
73
82
  { name: 'key', placeholder: 'dotted.key', required: true },
@@ -93,6 +102,7 @@ export async function env(h0) {
93
102
  }
94
103
  const sortedGroups = Object.entries(groups).sort((a,b) => b[1].length - a[1].length);
95
104
  return [
105
+ Hero({ title: 'keys', body: 'env vars freddie reads. grouped by service prefix. click a chip to set.', accent: setCount+' / '+list.length+' set' }),
96
106
  Kpi({ items: [[setCount,'set'],[list.length-setCount,'missing'],[list.length,'total'],[sortedGroups.length,'groups']] }),
97
107
  list.length === 0 ? EmptyState({ text: 'no env keys registered', glyph: '⚿' }) : null,
98
108
  ...sortedGroups.map(([g, keys]) => {
@@ -109,6 +119,7 @@ export async function tools(h0) {
109
119
  const envIsSet = k => typeof h0.pi.env?.isSet === 'function' ? h0.pi.env.isSet(k) : false;
110
120
  const bySet = list.reduce((a, t) => { (a[t.toolset||'core'] = a[t.toolset||'core'] || []).push(t); return a; }, {});
111
121
  return [
122
+ Hero({ title: 'tools', body: 'every tool the agent can call. param count + required env per row.', accent: list.length+' tools' }),
112
123
  Kpi({ items: [[list.length,'tools'],[Object.keys(bySet).length,'toolsets']] }),
113
124
  ...Object.entries(bySet).map(([ts, items]) => Panel({ title: 'toolset · '+ts, count: items.length, children: items.map(t => {
114
125
  const params = t.schema?.parameters?.properties ? Object.keys(t.schema.parameters.properties).length : 0;
@@ -143,6 +154,7 @@ export async function batch(h0) {
143
154
  : results.length === 0 ? Panel({ title: 'results', children: EmptyState({ text: 'no results yet', glyph: '⊞' }) })
144
155
  : Panel({ title: 'results', count: results.length, children: Table({ headers: ['#','prompt','result','status'], rows: results.map((it, i) => [String(i+1), (it.prompt||'').slice(0,60), (it.result||it.error||'').slice(0,120), it.error ? 'error' : 'ok']) }) });
145
156
  return [
157
+ Hero({ title: 'batch', body: 'run many prompts in parallel. one per line.', accent: results.length ? results.length+' results' : 'idle' }),
146
158
  Panel({ title: 'run batch', children: Form({ fields: [
147
159
  { name: 'prompts', kind: 'textarea', placeholder: 'one prompt per line', rows: 6 },
148
160
  { name: 'concurrency', type: 'number', value: '4' }
@@ -156,6 +168,7 @@ export async function gateway(h0) {
156
168
  const active = platforms.filter(p => p.enabled);
157
169
  const envIsSet = k => typeof h0.pi.env?.isSet === 'function' ? h0.pi.env.isSet(k) : false;
158
170
  return [
171
+ Hero({ title: 'gateway', body: 'webhook + bot platforms. each adapter declares required env keys.', accent: active.length+' / '+platforms.length+' active' }),
159
172
  Kpi({ items: [[platforms.length,'platforms'],[active.length,'active']] }),
160
173
  Panel({ title: 'platforms', count: platforms.length, right: active.length > 0 ? Chip({ tone: 'ok', children: active.length+' active' }) : Chip({ tone: 'miss', children: 'none active' }),
161
174
  children: platforms.length === 0 ? EmptyState({ text: 'no platforms registered', glyph: '⇌' }) : platforms.map(p => {
@@ -35,6 +35,7 @@ export async function sessions(h0) {
35
35
  return [(s.id||'').slice(0,8), s.title||'—', s.platform||'—', s.model||'—', s.cwd?s.cwd.slice(-30):'—', s.skill?skillLabel({name:s.skill}):'—', cont];
36
36
  });
37
37
  return [
38
+ Hero({ title: 'sessions', body: 'every chat turn lives here.', accent: list.length+' total' }),
38
39
  Kpi({ items: [[list.length,'sessions']] }),
39
40
  Panel({ title: 'sessions', count: list.length, children: list.length === 0 ? EmptyState({ text: 'no sessions yet', glyph: '✉' }) : Table({ headers: ['id','title','platform','model','cwd','skill',''], rows }) })
40
41
  ];
@@ -67,6 +68,7 @@ export async function agents(h0) {
67
68
  const sList = await h0.pi.sessions.list();
68
69
  const recent = sList.slice(0, 10);
69
70
  return [
71
+ Hero({ title: 'agents', body: 'agent state machine snapshot. one xstate per turn.', accent: (a.count||0)+' active' }),
70
72
  Kpi({ items: [[a.count||0,'active'],[a.turns||0,'turns'],[sList.length,'total sessions']] }),
71
73
  Panel({ title: 'current agent', children: Receipt({ rows: [
72
74
  ['active session', a.active || '(none)'],
@@ -94,6 +96,7 @@ export async function analytics(h0) {
94
96
  : Table({ headers: ['name','count'], rows: sortDesc(obj) })
95
97
  });
96
98
  return [
99
+ Hero({ title: 'analytics', body: 'shape of work — what platforms, what models, what tools.' }),
97
100
  Kpi({ items: [[list.length,'sessions'],[tools.length,'tools'],[skills.length,'skills']] }),
98
101
  mkPanel('by platform', byPlat, '◉'),
99
102
  mkPanel('by model', byModel, '◎'),