pikiloom 0.4.26 → 0.4.27
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/dashboard/dist/assets/{AgentTab-BNJ73P0m.js → AgentTab-DIP-y4dl.js} +1 -1
- package/dashboard/dist/assets/ConnectionModal-BCfvhkiI.js +1 -0
- package/dashboard/dist/assets/{DirBrowser-D-GT-G-w.js → DirBrowser-Dot7ua9-.js} +1 -1
- package/dashboard/dist/assets/{ExtensionsTab-BrJMulJR.js → ExtensionsTab-GioMx4S6.js} +1 -1
- package/dashboard/dist/assets/{IMAccessTab-auPnx468.js → IMAccessTab-C9_r8jJP.js} +1 -1
- package/dashboard/dist/assets/{Modal-lYfO9m-I.js → Modal-M1AP1sgR.js} +1 -1
- package/dashboard/dist/assets/{Modals-PRdWOIY9.js → Modals-CCm3UUfJ.js} +1 -1
- package/dashboard/dist/assets/{Select-BhbU-rll.js → Select-YubDM16P.js} +1 -1
- package/dashboard/dist/assets/{SessionPanel-_0dLWvEb.js → SessionPanel-Cnv9o96n.js} +1 -1
- package/dashboard/dist/assets/SystemTab-VgNivIe3.js +1 -0
- package/dashboard/dist/assets/index-BY7l20bi.js +23 -0
- package/dashboard/dist/assets/index-BlqvzDUL.js +3 -0
- package/dashboard/dist/assets/index-CXIN3nTr.css +1 -0
- package/dashboard/dist/assets/{shared-C5uXvhZJ.js → shared-C0SAInnT.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dist/agent/acp-client.js +0 -59
- package/dist/agent/artifacts.js +1 -38
- package/dist/agent/auto-update.js +2 -78
- package/dist/agent/await-resume.js +0 -20
- package/dist/agent/cli/auth.js +3 -51
- package/dist/agent/cli/catalog.js +0 -3
- package/dist/agent/cli/detector.js +1 -19
- package/dist/agent/cli/index.js +0 -3
- package/dist/agent/cli/registry.js +0 -25
- package/dist/agent/driver.js +0 -14
- package/dist/agent/drivers/claude-tui.js +2 -769
- package/dist/agent/drivers/claude.js +12 -631
- package/dist/agent/drivers/codex.js +11 -162
- package/dist/agent/drivers/gemini.js +6 -114
- package/dist/agent/drivers/hermes.js +0 -128
- package/dist/agent/goal.js +0 -45
- package/dist/agent/handover.js +1 -46
- package/dist/agent/images.js +7 -133
- package/dist/agent/index.js +1 -29
- package/dist/agent/mcp/bridge.js +1 -197
- package/dist/agent/mcp/extensions.js +5 -84
- package/dist/agent/mcp/oauth.js +2 -69
- package/dist/agent/mcp/registry.js +2 -33
- package/dist/agent/mcp/session-server.js +2 -45
- package/dist/agent/mcp/tools/ask-user.js +0 -6
- package/dist/agent/mcp/tools/await-resume.js +0 -15
- package/dist/agent/mcp/tools/goal.js +0 -25
- package/dist/agent/mcp/tools/types.js +0 -5
- package/dist/agent/mcp/tools/workspace.js +0 -23
- package/dist/agent/npm.js +0 -14
- package/dist/agent/session.js +86 -196
- package/dist/agent/skill-installer.js +3 -70
- package/dist/agent/skills.js +0 -43
- package/dist/agent/stream.js +5 -148
- package/dist/agent/types.js +0 -12
- package/dist/agent/utils.js +2 -120
- package/dist/bot/bot.js +3 -468
- package/dist/bot/command-ui.js +0 -45
- package/dist/bot/commands.js +0 -51
- package/dist/bot/headless-bot.js +0 -21
- package/dist/bot/host.js +1 -5
- package/dist/bot/human-loop.js +0 -8
- package/dist/bot/menu.js +0 -3
- package/dist/bot/orchestration.js +0 -3
- package/dist/bot/render-shared.js +0 -63
- package/dist/bot/session-hub.js +14 -92
- package/dist/bot/session-status.js +1 -5
- package/dist/bot/streaming.js +0 -53
- package/dist/browser-profile.js +0 -51
- package/dist/browser-supervisor.js +0 -75
- package/dist/catalog/cli-tools.js +0 -53
- package/dist/catalog/index.js +0 -18
- package/dist/catalog/local-models.js +0 -18
- package/dist/catalog/mcp-servers.js +0 -35
- package/dist/catalog/skill-repos.js +0 -32
- package/dist/channels/base.js +0 -19
- package/dist/channels/dingtalk/bot.js +0 -3
- package/dist/channels/dingtalk/channel.js +0 -33
- package/dist/channels/discord/bot.js +0 -7
- package/dist/channels/discord/channel.js +0 -22
- package/dist/channels/feishu/bot.js +0 -71
- package/dist/channels/feishu/channel.js +0 -78
- package/dist/channels/feishu/markdown.js +0 -5
- package/dist/channels/feishu/render.js +0 -45
- package/dist/channels/health.js +0 -46
- package/dist/channels/slack/bot.js +0 -7
- package/dist/channels/slack/channel.js +1 -27
- package/dist/channels/states.js +0 -3
- package/dist/channels/telegram/bot.js +0 -60
- package/dist/channels/telegram/channel.js +2 -99
- package/dist/channels/telegram/directory.js +0 -3
- package/dist/channels/telegram/live-preview.js +0 -8
- package/dist/channels/telegram/render.js +0 -30
- package/dist/channels/wecom/bot.js +0 -3
- package/dist/channels/wecom/channel.js +0 -58
- package/dist/channels/weixin/api.js +0 -9
- package/dist/channels/weixin/bot.js +0 -88
- package/dist/channels/weixin/channel.js +0 -6
- package/dist/cli/autostart.js +1 -44
- package/dist/cli/channel-supervisor.js +1 -59
- package/dist/cli/channels.js +0 -6
- package/dist/cli/main.js +1 -145
- package/dist/cli/onboarding.js +0 -6
- package/dist/cli/run.js +0 -11
- package/dist/cli/setup-wizard.js +0 -3
- package/dist/core/config/runtime-config.js +0 -38
- package/dist/core/config/user-config.js +0 -63
- package/dist/core/config/validation.js +0 -9
- package/dist/core/constants.js +0 -268
- package/dist/core/git.js +0 -31
- package/dist/core/legacy-compat.js +1 -28
- package/dist/core/logging.js +0 -3
- package/dist/core/platform.js +0 -28
- package/dist/core/process-control.js +0 -8
- package/dist/core/secrets/index.js +0 -17
- package/dist/core/secrets/inline-seal.js +0 -7
- package/dist/core/secrets/ref.js +0 -19
- package/dist/core/secrets/resolver.js +0 -8
- package/dist/core/secrets/store.js +1 -12
- package/dist/core/utils.js +1 -37
- package/dist/core/version.js +0 -3
- package/dist/dashboard/platform.js +1 -35
- package/dist/dashboard/routes/agents.js +2 -71
- package/dist/dashboard/routes/cli.js +0 -27
- package/dist/dashboard/routes/config.js +0 -54
- package/dist/dashboard/routes/extensions.js +0 -132
- package/dist/dashboard/routes/local-models.js +0 -68
- package/dist/dashboard/routes/models.js +0 -46
- package/dist/dashboard/routes/sessions.js +0 -100
- package/dist/dashboard/runtime.js +1 -58
- package/dist/dashboard/server.js +0 -49
- package/dist/dashboard/session-control.js +2 -69
- package/dist/model/catalog.js +1 -17
- package/dist/model/index.js +0 -15
- package/dist/model/injector.js +1 -181
- package/dist/model/provider-models.js +1 -48
- package/dist/model/responses-bridge.js +3 -45
- package/dist/model/store.js +0 -17
- package/dist/model/types.js +0 -12
- package/dist/model/validation.js +1 -18
- package/dist/pikichannel/adapter-pikiloom.js +0 -31
- package/dist/pikichannel/code.js +0 -12
- package/dist/pikichannel/codec.js +0 -14
- package/dist/pikichannel/host.js +4 -33
- package/dist/pikichannel/protocol.js +0 -52
- package/dist/pikichannel/rendezvous-broker.js +5 -26
- package/dist/pikichannel/rendezvous-host.js +3 -16
- package/dist/pikichannel/server.js +6 -55
- package/dist/pikichannel/transport.js +0 -25
- package/dist/pikichannel/transports/webrtc-host.js +0 -18
- package/dist/pikichannel/transports/webrtc-shared.js +4 -34
- package/dist/pikichannel/transports/websocket-host.js +1 -14
- package/dist/pikichannel/turn.js +2 -69
- package/dist/pikichannel/web/sdk.js +14 -71
- package/package.json +1 -1
- package/dashboard/dist/assets/ConnectionModal-Dt05H2f9.js +0 -1
- package/dashboard/dist/assets/SystemTab-CN_QrRKt.js +0 -1
- package/dashboard/dist/assets/index-CP3LYJR2.js +0 -23
- package/dashboard/dist/assets/index-C_neLnaO.js +0 -3
- package/dashboard/dist/assets/index-CyCspgtc.css +0 -1
package/dist/bot/command-ui.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared selection UI models and action executor for interactive commands.
|
|
3
|
-
*/
|
|
4
1
|
import { normalizeAgent } from './bot.js';
|
|
5
2
|
import { getDriverCapabilities } from '../agent/driver.js';
|
|
6
3
|
import { getSessionStatusForChat } from './session-status.js';
|
|
@@ -36,8 +33,6 @@ export function encodeCommandAction(action) {
|
|
|
36
33
|
case 'effort.set':
|
|
37
34
|
return `eff:${action.effort}`;
|
|
38
35
|
case 'models.select.model':
|
|
39
|
-
// Encode native vs profile selection on the wire so decode is unambiguous.
|
|
40
|
-
// `md:n:<modelId>` = native; `md:p:<profileId>:<modelId>` = BYOK profile.
|
|
41
36
|
return action.profileId
|
|
42
37
|
? `md:p:${action.profileId}:${action.modelId}`
|
|
43
38
|
: `md:n:${action.modelId}`;
|
|
@@ -97,8 +92,6 @@ export function decodeCommandAction(data) {
|
|
|
97
92
|
return { kind: 'models.select.model', modelId, profileId: null };
|
|
98
93
|
}
|
|
99
94
|
if (rest.startsWith('p:')) {
|
|
100
|
-
// p:<profileId>:<modelId> — profileId is a uuid (no colons), so split on
|
|
101
|
-
// the first remaining colon yields a clean (profileId, modelId) pair.
|
|
102
95
|
const sep = rest.indexOf(':', 2);
|
|
103
96
|
if (sep < 0)
|
|
104
97
|
return null;
|
|
@@ -108,8 +101,6 @@ export function decodeCommandAction(data) {
|
|
|
108
101
|
return null;
|
|
109
102
|
return { kind: 'models.select.model', modelId, profileId };
|
|
110
103
|
}
|
|
111
|
-
// Legacy callback payloads (pre-union) carried `md:<modelId>` directly.
|
|
112
|
-
// Treat them as native selections so old buttons in the wild still work.
|
|
113
104
|
if (!rest)
|
|
114
105
|
return null;
|
|
115
106
|
return { kind: 'models.select.model', modelId: rest, profileId: null };
|
|
@@ -144,9 +135,6 @@ export function decodeCommandAction(data) {
|
|
|
144
135
|
}
|
|
145
136
|
export async function buildSessionsCommandView(bot, chatId, page, pageSize = 5) {
|
|
146
137
|
const data = await getSessionsPageData(bot, chatId, page, pageSize);
|
|
147
|
-
// Multi-row: one button per session on its own line, prefixed with the
|
|
148
|
-
// agent badge so a mixed workspace list reads cleanly. Avoid cramming
|
|
149
|
-
// multiple buttons onto one row (some IM clients truncate).
|
|
150
138
|
const sessionButtons = data.sessions.map(session => [{
|
|
151
139
|
label: `[${session.agent}] ${session.title} · ${session.time}`,
|
|
152
140
|
action: { kind: 'session.switch', sessionId: session.key },
|
|
@@ -186,16 +174,12 @@ export async function buildSessionsCommandView(bot, chatId, page, pageSize = 5)
|
|
|
186
174
|
export function buildAgentsCommandView(bot, chatId) {
|
|
187
175
|
const data = getAgentsListData(bot, chatId);
|
|
188
176
|
const installed = data.agents.filter(a => a.installed);
|
|
189
|
-
// Buttons stay short — friendly label + optional ✓ marker — so they don't
|
|
190
|
-
// truncate on narrow IM clients.
|
|
191
177
|
const actions = installed.map(agent => ({
|
|
192
178
|
label: agent.label,
|
|
193
179
|
action: { kind: 'agent.switch', agent: agent.agent },
|
|
194
180
|
state: buttonStateFromFlags({ isCurrent: agent.isCurrent }),
|
|
195
181
|
primary: agent.isCurrent,
|
|
196
182
|
}));
|
|
197
|
-
// Details (version + bound provider) live in the items list above the
|
|
198
|
-
// buttons, where the renderer can show them in full without truncation.
|
|
199
183
|
const items = installed.map(agent => {
|
|
200
184
|
const main = agent.versionShort
|
|
201
185
|
? `${agent.label} · v${agent.versionShort}`
|
|
@@ -234,17 +218,11 @@ async function initModelsDraft(bot, chatId) {
|
|
|
234
218
|
modelsDrafts.set(String(chatId), draft);
|
|
235
219
|
return draft;
|
|
236
220
|
}
|
|
237
|
-
/**
|
|
238
|
-
* Section headings for the unified picker. The trailing em-dash padding gives
|
|
239
|
-
* the row a "label" look in Telegram/Feishu — clicking it falls through to a
|
|
240
|
-
* harmless confirm which is a no-op when nothing has changed.
|
|
241
|
-
*/
|
|
242
221
|
const MODEL_GROUP_LABELS = {
|
|
243
222
|
native: '— Native —',
|
|
244
223
|
cloud: '— Cloud Profiles —',
|
|
245
224
|
local: '— Local Profiles —',
|
|
246
225
|
};
|
|
247
|
-
/** Match a picker row against the live draft so the "current" pip is unambiguous. */
|
|
248
226
|
function modelRowMatchesDraft(agent, row, draft) {
|
|
249
227
|
if (draft.profileId)
|
|
250
228
|
return !!row.profileId && row.profileId === draft.profileId;
|
|
@@ -259,8 +237,6 @@ export async function buildModelsCommandView(bot, chatId, draft) {
|
|
|
259
237
|
effort: data.effort?.current ?? null,
|
|
260
238
|
};
|
|
261
239
|
modelsDrafts.set(String(chatId), d);
|
|
262
|
-
// Bucket rows by group while preserving the order resolveAgentModels gave us
|
|
263
|
-
// (native → cloud → local). We render each non-empty group with a header.
|
|
264
240
|
const groups = {
|
|
265
241
|
native: [],
|
|
266
242
|
cloud: [],
|
|
@@ -275,9 +251,6 @@ export async function buildModelsCommandView(bot, chatId, draft) {
|
|
|
275
251
|
const rawItems = groups[group];
|
|
276
252
|
if (!rawItems.length)
|
|
277
253
|
continue;
|
|
278
|
-
// Promote the currently-selected row to the top of its group so the user
|
|
279
|
-
// sees their active pick first without having to scroll. This matches the
|
|
280
|
-
// pre-union picker's behaviour, just scoped per-group instead of globally.
|
|
281
254
|
const items = [...rawItems].sort((a, b) => Number(modelRowMatchesDraft(data.agent, b, d)) - Number(modelRowMatchesDraft(data.agent, a, d)));
|
|
282
255
|
rows.push([{
|
|
283
256
|
label: MODEL_GROUP_LABELS[group],
|
|
@@ -288,9 +261,6 @@ export async function buildModelsCommandView(bot, chatId, draft) {
|
|
|
288
261
|
for (const model of items) {
|
|
289
262
|
const selected = modelRowMatchesDraft(data.agent, model, d);
|
|
290
263
|
const labelBase = model.alias || model.id;
|
|
291
|
-
// For BYOK rows the alias is the Profile name — include provider tag so
|
|
292
|
-
// two Profiles sharing a model id (e.g. "Sonnet 4.6 · OpenRouter" vs
|
|
293
|
-
// "Sonnet 4.6 · Anthropic Direct") stay distinguishable in 1-column mode.
|
|
294
264
|
const label = group === 'native' || !model.providerName
|
|
295
265
|
? labelBase
|
|
296
266
|
: `${labelBase} · ${model.providerName}`;
|
|
@@ -389,10 +359,6 @@ export function buildModeCommandView(bot, chatId) {
|
|
|
389
359
|
const metaLines = [];
|
|
390
360
|
if (!isClaude)
|
|
391
361
|
metaLines.push('Permission mode is only available for Claude.');
|
|
392
|
-
// Workflow orchestration is no longer a standalone toggle here — it folded
|
|
393
|
-
// into the effort picker as the top "Ultra" rung (max depth + multi-agent
|
|
394
|
-
// fan-out). Surface its state and point users to /models so the capability
|
|
395
|
-
// stays discoverable.
|
|
396
362
|
if (supportsWorkflow) {
|
|
397
363
|
metaLines.push(`Workflow orchestration: ${workflowOn ? 'On (Ultra effort)' : 'Off'} — pick the Ultra rung in /models to toggle.`);
|
|
398
364
|
}
|
|
@@ -425,8 +391,6 @@ export async function executeCommandAction(bot, chatId, action, opts = {}) {
|
|
|
425
391
|
}
|
|
426
392
|
case 'session.switch': {
|
|
427
393
|
const chat = bot.chat(chatId);
|
|
428
|
-
// Workspace-wide lookup (no agent filter) so a row from any agent can be
|
|
429
|
-
// resumed directly from a single mixed list.
|
|
430
394
|
const result = await bot.fetchSessions(undefined, bot.chatWorkdir(chatId));
|
|
431
395
|
if (!result.ok)
|
|
432
396
|
return { kind: 'noop', message: 'Failed to load sessions' };
|
|
@@ -435,14 +399,10 @@ export async function executeCommandAction(bot, chatId, action, opts = {}) {
|
|
|
435
399
|
return { kind: 'noop', message: 'Session not found' };
|
|
436
400
|
const prevAgent = chat.agent;
|
|
437
401
|
const runtime = bot.adoptExistingSessionForChat(chatId, session);
|
|
438
|
-
// Restore the agent's persistent model / effort / Profile binding so the
|
|
439
|
-
// next stream — and the IM picker chips — match the resumed session.
|
|
440
402
|
if (session.model) {
|
|
441
403
|
bot.switchModelForChat(chatId, session.model, session.profileId ?? null);
|
|
442
404
|
}
|
|
443
405
|
else if (session.profileId !== undefined) {
|
|
444
|
-
// Session was native (profileId === null) — explicitly clear any
|
|
445
|
-
// active Profile so we don't run with a stale BYOK binding.
|
|
446
406
|
bot.switchModelForChat(chatId, bot.modelForAgent(session.agent), null);
|
|
447
407
|
}
|
|
448
408
|
if (session.thinkingEffort) {
|
|
@@ -532,8 +492,6 @@ export async function executeCommandAction(bot, chatId, action, opts = {}) {
|
|
|
532
492
|
case 'models.select.model': {
|
|
533
493
|
const draft = modelsDrafts.get(String(chatId)) ?? await initModelsDraft(bot, chatId);
|
|
534
494
|
draft.modelId = action.modelId;
|
|
535
|
-
// profileId can be null (native pick) or a uuid (BYOK pick). Treating
|
|
536
|
-
// `undefined` as "leave alone" preserves the action shape's old contract.
|
|
537
495
|
if (action.profileId !== undefined)
|
|
538
496
|
draft.profileId = action.profileId;
|
|
539
497
|
return { kind: 'view', view: await buildModelsCommandView(bot, chatId, draft), callbackText: '' };
|
|
@@ -561,9 +519,6 @@ export async function executeCommandAction(bot, chatId, action, opts = {}) {
|
|
|
561
519
|
}
|
|
562
520
|
const parts = [];
|
|
563
521
|
if (modelChanged) {
|
|
564
|
-
// Pass profileId explicitly: a null clears any active Profile binding,
|
|
565
|
-
// a uuid binds the picked Profile. switchModelForChat handles both
|
|
566
|
-
// sides of the dual path so call sites stay agnostic.
|
|
567
522
|
bot.switchModelForChat(chatId, draft.modelId, draft.profileId ?? null);
|
|
568
523
|
parts.push(draft.profileId ? `Profile: ${draft.modelId}` : `Model: ${draft.modelId}`);
|
|
569
524
|
}
|
package/dist/bot/commands.js
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* bot-commands.ts — channel-agnostic command data layer.
|
|
3
|
-
*
|
|
4
|
-
* Each function returns structured data objects that any IM renderer can consume.
|
|
5
|
-
* No rendering, no HTML, no platform-specific formatting.
|
|
6
|
-
*
|
|
7
|
-
* Usage from a channel-specific bot (e.g. bot-telegram.ts, bot-feishu.ts):
|
|
8
|
-
* const data = await getSessionsPageData(bot, chatId, 0);
|
|
9
|
-
* const rendered = renderSessionsPage(data); // channel-specific renderer
|
|
10
|
-
*/
|
|
11
1
|
import path from 'node:path';
|
|
12
2
|
import fs from 'node:fs';
|
|
13
3
|
import { fmtTokens, fmtUptime, fmtBytes } from './bot.js';
|
|
@@ -65,20 +55,6 @@ export function getWorkspacesData(bot, chatId) {
|
|
|
65
55
|
});
|
|
66
56
|
return { currentWorkdir, workspaces };
|
|
67
57
|
}
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
|
-
// Goal — channel-agnostic /goal command dispatch
|
|
70
|
-
// ---------------------------------------------------------------------------
|
|
71
|
-
/**
|
|
72
|
-
* Handle /goal <args> for a chat. Returns a human-readable status line for
|
|
73
|
-
* the IM renderer to send back. Returns null when there is no active session
|
|
74
|
-
* for the chat (caller renders its own "pick a session first" message).
|
|
75
|
-
*
|
|
76
|
-
* Per-agent routing:
|
|
77
|
-
* - codex → native `thread/goal/*` RPC (state machine + budget + pause/resume)
|
|
78
|
-
* - claude → native `/goal <condition>` slash command (Stop hook continuation,
|
|
79
|
-
* auto-clear on completion, no budget / no pause/resume)
|
|
80
|
-
* - others → pikiloom's portable goal.json with continuation injection
|
|
81
|
-
*/
|
|
82
58
|
export async function handleGoalCommand(bot, chatId, rawArgs) {
|
|
83
59
|
const session = bot.selectedSession(chatId);
|
|
84
60
|
if (!session || !session.sessionId)
|
|
@@ -199,9 +175,6 @@ export function summarizeSessionRun(session) {
|
|
|
199
175
|
}
|
|
200
176
|
export async function getSessionsPageData(bot, chatId, page, pageSize = 5) {
|
|
201
177
|
const cs = bot.chat(chatId);
|
|
202
|
-
// Workspace-wide: drop the cs.agent filter so the list matches what the
|
|
203
|
-
// dashboard shows for this workspace (all installed agents, sorted by
|
|
204
|
-
// most-recent activity).
|
|
205
178
|
const res = await bot.fetchSessions(undefined, bot.chatWorkdir(chatId));
|
|
206
179
|
const sessions = res.ok ? res.sessions : [];
|
|
207
180
|
const total = sessions.length;
|
|
@@ -332,14 +305,6 @@ function agentDisplayLabel(agentId) {
|
|
|
332
305
|
return AGENT_LABEL_OVERRIDES[agentId]
|
|
333
306
|
|| agentId.charAt(0).toUpperCase() + agentId.slice(1);
|
|
334
307
|
}
|
|
335
|
-
/**
|
|
336
|
-
* Pull the first semver-ish token out of a CLI `--version` string. Falls back
|
|
337
|
-
* to the original string when no semver is present.
|
|
338
|
-
*
|
|
339
|
-
* "2.1.132 (Claude Code v2.1.132)" → "2.1.132"
|
|
340
|
-
* "Hermes Agent v0.12.0 (2026.4.30)" → "0.12.0"
|
|
341
|
-
* "codex-cli 0.128.0" → "0.128.0"
|
|
342
|
-
*/
|
|
343
308
|
function shortVersion(raw) {
|
|
344
309
|
if (!raw)
|
|
345
310
|
return null;
|
|
@@ -422,9 +387,6 @@ const EFFORT_LEVELS = {
|
|
|
422
387
|
{ id: 'high', label: 'High' },
|
|
423
388
|
{ id: 'xhigh', label: 'Very High' },
|
|
424
389
|
{ id: 'max', label: 'Max' },
|
|
425
|
-
// Synthetic top rung: "max depth + multi-agent Workflow orchestration", the
|
|
426
|
-
// same bundle as Claude's `ultracode` mode. Not a real --effort value — the
|
|
427
|
-
// bot decomposes it into (effort=max, workflow=on) at apply time.
|
|
428
390
|
{ id: 'ultra', label: 'Ultra' },
|
|
429
391
|
],
|
|
430
392
|
codex: [
|
|
@@ -442,8 +404,6 @@ const EFFORT_LEVELS = {
|
|
|
442
404
|
],
|
|
443
405
|
};
|
|
444
406
|
function buildEffortData(bot, agent) {
|
|
445
|
-
// Display value folds workflow into the synthetic `ultra` rung — see
|
|
446
|
-
// Bot.effortSelectionForAgent.
|
|
447
407
|
const currentEffort = bot.effortSelectionForAgent(agent);
|
|
448
408
|
if (!currentEffort)
|
|
449
409
|
return null;
|
|
@@ -460,11 +420,6 @@ export async function getModelsListData(bot, chatId) {
|
|
|
460
420
|
const currentModel = bot.modelForAgent(cs.agent);
|
|
461
421
|
const activeProfileId = bot.activeProfileIdForAgent(cs.agent);
|
|
462
422
|
const res = await bot.fetchModels(cs.agent, bot.chatWorkdir(chatId));
|
|
463
|
-
// Match priority:
|
|
464
|
-
// - if a Profile is bound, only the row carrying that profileId is current
|
|
465
|
-
// (two Profiles can share a modelId, so id-equality alone is ambiguous);
|
|
466
|
-
// - otherwise only `'native'` rows are eligible to match against the
|
|
467
|
-
// user-config model id.
|
|
468
423
|
return {
|
|
469
424
|
agent: cs.agent,
|
|
470
425
|
currentModel,
|
|
@@ -504,9 +459,6 @@ export async function getStatusDataAsync(bot, chatId) {
|
|
|
504
459
|
export function getHostDataSync(bot) {
|
|
505
460
|
return bot.getHostData();
|
|
506
461
|
}
|
|
507
|
-
// ---------------------------------------------------------------------------
|
|
508
|
-
// Skill routing
|
|
509
|
-
// ---------------------------------------------------------------------------
|
|
510
462
|
export { SKILL_CMD_PREFIX, indexSkillsByCommand };
|
|
511
463
|
function relSkillPath(workdir, filePath) {
|
|
512
464
|
const relative = path.relative(workdir, filePath).replace(/\\/g, '/');
|
|
@@ -553,7 +505,4 @@ export function getExtensionSummaryData(bot, chatId) {
|
|
|
553
505
|
})),
|
|
554
506
|
};
|
|
555
507
|
}
|
|
556
|
-
// ---------------------------------------------------------------------------
|
|
557
|
-
// Re-export commonly used helpers for convenience
|
|
558
|
-
// ---------------------------------------------------------------------------
|
|
559
508
|
export { summarizePromptForStatus, fmtTokens, fmtUptime, fmtBytes, VERSION };
|
package/dist/bot/headless-bot.js
CHANGED
|
@@ -1,27 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HeadlessBot — the Web Dashboard acting as a first-class terminal.
|
|
3
|
-
*
|
|
4
|
-
* pikiloom's terminals (IM channels and the Dashboard) are equal, pluggable
|
|
5
|
-
* entry points. The IM channels each have a Bot subclass that connects a chat
|
|
6
|
-
* transport; the Dashboard needs no transport — it drives the bot directly via
|
|
7
|
-
* `runtime.getBotRef()`. HeadlessBot fills that gap: it satisfies the Bot
|
|
8
|
-
* contract (`run()` / `requestStop()`) so `ChannelSupervisor` can manage its
|
|
9
|
-
* lifecycle exactly like a channel bot and the dashboard can attach to it for
|
|
10
|
-
* live stream snapshots — but it connects to nothing.
|
|
11
|
-
*
|
|
12
|
-
* It exists so the bot is usable with zero IM channels configured: install an
|
|
13
|
-
* agent, open the dashboard, and you have a working terminal. When an IM
|
|
14
|
-
* channel is later added, the supervisor tears this down and the channel's bot
|
|
15
|
-
* takes over the dashboard attachment.
|
|
16
|
-
*/
|
|
17
1
|
import { Bot } from './bot.js';
|
|
18
2
|
export class HeadlessBot extends Bot {
|
|
19
3
|
resolveRun = null;
|
|
20
|
-
/**
|
|
21
|
-
* No transport to connect — just mark the terminal live and block until
|
|
22
|
-
* `requestStop()` so the supervisor's lifecycle (await runPromise on stop)
|
|
23
|
-
* matches the channel bots'.
|
|
24
|
-
*/
|
|
25
4
|
run() {
|
|
26
5
|
this.connected = true;
|
|
27
6
|
this.log('dashboard terminal ready (no IM channel configured)');
|
package/dist/bot/host.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Host system data collection: battery, CPU, memory, display name.
|
|
3
|
-
* Platform-adaptive with macOS, Linux, and Windows support.
|
|
4
|
-
*/
|
|
5
1
|
import os from 'node:os';
|
|
6
2
|
import fs from 'node:fs';
|
|
7
3
|
import path from 'node:path';
|
|
@@ -175,7 +171,7 @@ export function getHostDisplayName() {
|
|
|
175
171
|
if (name)
|
|
176
172
|
return name;
|
|
177
173
|
}
|
|
178
|
-
catch {
|
|
174
|
+
catch { }
|
|
179
175
|
}
|
|
180
176
|
return os.hostname();
|
|
181
177
|
}
|
package/dist/bot/human-loop.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Human-in-the-loop prompt state machine and answer helpers.
|
|
3
|
-
*/
|
|
4
1
|
export function createEmptyHumanLoopAnswer() {
|
|
5
2
|
return {
|
|
6
3
|
selectedValue: null,
|
|
@@ -125,11 +122,6 @@ function displayValueForOption(question, value) {
|
|
|
125
122
|
const match = question.options?.find(opt => opt.value === value);
|
|
126
123
|
return match?.label || value;
|
|
127
124
|
}
|
|
128
|
-
/**
|
|
129
|
-
* Build a channel-agnostic summary of a prompt's resolved answers. Used by the
|
|
130
|
-
* base bot's `onInteractionAnswered` hook so each channel renders the same
|
|
131
|
-
* closed-state view + echo message without diverging.
|
|
132
|
-
*/
|
|
133
125
|
export function summarizeResolvedHumanLoopAnswers(prompt, status = 'answered') {
|
|
134
126
|
const rows = [];
|
|
135
127
|
const compactParts = [];
|
package/dist/bot/menu.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session and message orchestration helpers shared across channels.
|
|
3
|
-
*/
|
|
4
1
|
import { buildDefaultMenuCommands } from './menu.js';
|
|
5
2
|
import { BOT_SHUTDOWN_FORCE_EXIT_MS as _BOT_SHUTDOWN_FORCE_EXIT_MS } from '../core/constants.js';
|
|
6
3
|
export const BOT_SHUTDOWN_FORCE_EXIT_MS = _BOT_SHUTDOWN_FORCE_EXIT_MS;
|
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared rendering utilities used by channel-specific renderers.
|
|
3
|
-
*
|
|
4
|
-
* Contains types, pure-data helpers, and functions that are identical across platforms.
|
|
5
|
-
* Platform-specific formatting (HTML vs Markdown) stays in the respective render files.
|
|
6
|
-
*/
|
|
7
1
|
import { materializeImage } from '../agent/index.js';
|
|
8
2
|
import { fmtUptime, formatThinkingForDisplay, thinkLabel } from './bot.js';
|
|
9
3
|
import { formatActivityCommandSummary, parseActivitySummary, renderPlanForPreview, summarizeActivityForPreview } from './streaming.js';
|
|
10
4
|
import { supportsChannelCapability } from '../channels/base.js';
|
|
11
5
|
import { agentLog, agentWarn } from '../agent/index.js';
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
|
-
// GFM table parsing
|
|
14
|
-
// ---------------------------------------------------------------------------
|
|
15
|
-
/** Parse GFM table lines into structured headers + rows. */
|
|
16
6
|
export function parseGfmTable(tableLines) {
|
|
17
7
|
if (tableLines.length < 3)
|
|
18
8
|
return null;
|
|
@@ -39,9 +29,6 @@ export function parseGfmTable(tableLines) {
|
|
|
39
29
|
}
|
|
40
30
|
return rows.length ? { headers, rows } : null;
|
|
41
31
|
}
|
|
42
|
-
// ---------------------------------------------------------------------------
|
|
43
|
-
// Footer helpers
|
|
44
|
-
// ---------------------------------------------------------------------------
|
|
45
32
|
export function fmtCompactUptime(ms) {
|
|
46
33
|
return fmtUptime(ms).replace(/\s+/g, '');
|
|
47
34
|
}
|
|
@@ -52,12 +39,6 @@ export function footerStatusSymbol(status) {
|
|
|
52
39
|
case 'failed': return '✗';
|
|
53
40
|
}
|
|
54
41
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Drop a leading `provider/` segment from long model ids so the footer stays
|
|
57
|
-
* readable on narrow IM clients. `anthropic/claude-sonnet-4` → `claude-sonnet-4`,
|
|
58
|
-
* `deepseek/deepseek-v4-flash` → `deepseek-v4-flash`. Already-short ids are
|
|
59
|
-
* returned unchanged.
|
|
60
|
-
*/
|
|
61
42
|
function compactModelLabel(model) {
|
|
62
43
|
const trimmed = model.trim();
|
|
63
44
|
if (trimmed.length <= 24)
|
|
@@ -65,12 +46,6 @@ function compactModelLabel(model) {
|
|
|
65
46
|
const slashIdx = trimmed.indexOf('/');
|
|
66
47
|
return slashIdx > 0 ? trimmed.slice(slashIdx + 1) : trimmed;
|
|
67
48
|
}
|
|
68
|
-
/**
|
|
69
|
-
* Split footer fields into a primary identity line (agent + model) and a
|
|
70
|
-
* secondary runtime line (effort, context%, elapsed). Channel renderers
|
|
71
|
-
* compose the two lines with their own visual styling so narrow IM clients
|
|
72
|
-
* never have to soft-wrap a single dense line.
|
|
73
|
-
*/
|
|
74
49
|
export function formatFooterParts(agent, elapsedMs, meta, contextPercent, decorations) {
|
|
75
50
|
const identityParts = [agent];
|
|
76
51
|
if (decorations?.model)
|
|
@@ -82,10 +57,6 @@ export function formatFooterParts(agent, elapsedMs, meta, contextPercent, decora
|
|
|
82
57
|
if (ctx != null)
|
|
83
58
|
runtimeParts.push(`${ctx}%`);
|
|
84
59
|
runtimeParts.push(fmtCompactUptime(Math.max(0, Math.round(elapsedMs))));
|
|
85
|
-
// BYOK attribution — tells the user the turn is being routed through a
|
|
86
|
-
// third-party provider rather than the agent CLI's native auth path.
|
|
87
|
-
// Tucked at the end of the runtime line so it doesn't crowd the (often
|
|
88
|
-
// long) identity line on narrow IM clients.
|
|
89
60
|
const providerName = meta?.providerName ?? decorations?.provider ?? null;
|
|
90
61
|
if (providerName)
|
|
91
62
|
runtimeParts.push(`via ${providerName}`);
|
|
@@ -94,23 +65,11 @@ export function formatFooterParts(agent, elapsedMs, meta, contextPercent, decora
|
|
|
94
65
|
runtime: runtimeParts.join(' · '),
|
|
95
66
|
};
|
|
96
67
|
}
|
|
97
|
-
// ---------------------------------------------------------------------------
|
|
98
|
-
// Activity trimming
|
|
99
|
-
// ---------------------------------------------------------------------------
|
|
100
|
-
/**
|
|
101
|
-
* Trim the activity narrative for a streaming preview. Keeps the **most
|
|
102
|
-
* recent** lines that fit the budget — the user is watching the turn live,
|
|
103
|
-
* what just happened matters far more than what happened 30 tool-calls ago.
|
|
104
|
-
* A leading `...` marker signals "earlier activity dropped" when truncation
|
|
105
|
-
* happens; the tail order is preserved.
|
|
106
|
-
*/
|
|
107
68
|
export function trimActivityForPreview(text, maxChars = 900) {
|
|
108
69
|
if (text.length <= maxChars)
|
|
109
70
|
return text;
|
|
110
71
|
const lines = text.split('\n').filter(line => line.trim());
|
|
111
72
|
if (lines.length <= 1) {
|
|
112
|
-
// Single very-long line — keep the trailing characters with a leading
|
|
113
|
-
// ellipsis so the freshest content is visible.
|
|
114
73
|
return '...' + text.slice(text.length - Math.max(0, maxChars - 3));
|
|
115
74
|
}
|
|
116
75
|
const ellipsis = '...';
|
|
@@ -132,9 +91,6 @@ export function trimActivityForPreview(text, maxChars = 900) {
|
|
|
132
91
|
return tail.join('\n');
|
|
133
92
|
return [ellipsis, ...tail].join('\n');
|
|
134
93
|
}
|
|
135
|
-
// ---------------------------------------------------------------------------
|
|
136
|
-
// Provider usage (plain-text builder — caller wraps as needed)
|
|
137
|
-
// ---------------------------------------------------------------------------
|
|
138
94
|
function rawUsageLine(parts) {
|
|
139
95
|
return parts.filter(part => !!part && String(part).trim()).join(' ');
|
|
140
96
|
}
|
|
@@ -167,15 +123,6 @@ export function buildProviderUsageLines(usage) {
|
|
|
167
123
|
}
|
|
168
124
|
return lines;
|
|
169
125
|
}
|
|
170
|
-
/**
|
|
171
|
-
* Iterate an assistant turn's image MessageBlocks and dispatch each through
|
|
172
|
-
* the channel's `sendImage` capability. No-op when the channel doesn't claim
|
|
173
|
-
* `sendImage`. Errors per image are logged but don't block the rest of the
|
|
174
|
-
* dispatch — the text reply path is responsible for the user-visible summary.
|
|
175
|
-
*
|
|
176
|
-
* Returns the list of `{messageId, caption}` entries so the caller can register
|
|
177
|
-
* them with the session for "reply to continue" linkage.
|
|
178
|
-
*/
|
|
179
126
|
export async function dispatchImageBlocks(channel, blocks, opts) {
|
|
180
127
|
if (!blocks?.length)
|
|
181
128
|
return [];
|
|
@@ -253,13 +200,6 @@ export function extractFinalReplyData(agent, result) {
|
|
|
253
200
|
elapsedMs,
|
|
254
201
|
};
|
|
255
202
|
}
|
|
256
|
-
/**
|
|
257
|
-
* Build the sub-agent block for the streaming preview. Sub-agents are
|
|
258
|
-
* deliberately isolated from parent activity (their tool list lives on each
|
|
259
|
-
* StreamSubAgent record), so we render a separate compact section showing each
|
|
260
|
-
* sub-agent's purpose + latest tool. Completed sub-agents are hidden — the
|
|
261
|
-
* parent's activity already reflects the Task `done` line.
|
|
262
|
-
*/
|
|
263
203
|
function renderSubAgentsForPreview(meta) {
|
|
264
204
|
const subs = meta?.subAgents;
|
|
265
205
|
if (!subs?.length)
|
|
@@ -288,9 +228,6 @@ export function extractStreamPreviewData(input) {
|
|
|
288
228
|
const label = thinkLabel(input.agent);
|
|
289
229
|
const thinkSnippet = rawThinking ? formatThinkingForDisplay(input.thinking, 600) : '';
|
|
290
230
|
const preview = display.length > maxBody ? '(...truncated)\n' + display.slice(-maxBody) : display;
|
|
291
|
-
// Elapsed time is the only monotonic progress signal available during the
|
|
292
|
-
// thinking phase (see thinkingProgressText). Hidden in the first second so a
|
|
293
|
-
// freshly-opened card doesn't flash "0s".
|
|
294
231
|
const elapsedMs = Math.max(0, input.elapsedMs);
|
|
295
232
|
const thinkingProgressText = elapsedMs >= 1000 ? fmtCompactUptime(elapsedMs) : null;
|
|
296
233
|
return {
|