@pellux/goodvibes-tui 0.26.0 → 0.27.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.
- package/CHANGELOG.md +17 -0
- package/README.md +12 -7
- package/docs/foundation-artifacts/operator-contract.json +4 -1
- package/package.json +2 -2
- package/src/cli/bundle-command.ts +2 -1
- package/src/cli/service-posture.ts +2 -1
- package/src/core/conversation-rendering.ts +2 -2
- package/src/core/conversation.ts +49 -2
- package/src/core/session-recovery.ts +24 -18
- package/src/core/system-message-router.ts +42 -26
- package/src/core/turn-event-wiring.ts +12 -16
- package/src/daemon/handlers/calendar/caldav-client.ts +2 -1
- package/src/daemon/handlers/inbox/index.ts +2 -1
- package/src/daemon/handlers/inbox/poller.ts +2 -1
- package/src/daemon/handlers/inbox/providers/discord.ts +2 -1
- package/src/daemon/handlers/inbox/providers/email.ts +2 -1
- package/src/daemon/handlers/inbox/providers/route-util.ts +2 -1
- package/src/daemon/handlers/inbox/providers/slack.ts +2 -1
- package/src/daemon/handlers/triage/integration.ts +2 -1
- package/src/daemon/handlers/triage/pipeline.ts +2 -1
- package/src/daemon/handlers/triage/tagger/discord.ts +2 -1
- package/src/daemon/handlers/triage/tagger/imap.ts +4 -3
- package/src/export/gist-uploader.ts +3 -1
- package/src/input/command-registry.ts +1 -0
- package/src/input/commands/cloudflare-runtime.ts +2 -1
- package/src/input/commands/guidance-runtime.ts +2 -4
- package/src/input/commands/health-runtime.ts +13 -7
- package/src/input/commands/knowledge.ts +2 -1
- package/src/input/commands/runtime-services.ts +40 -10
- package/src/input/handler-command-route.ts +1 -1
- package/src/input/handler-interactions.ts +2 -1
- package/src/input/handler-modal-routes.ts +2 -1
- package/src/input/handler-onboarding-cloudflare.ts +2 -1
- package/src/input/handler-onboarding.ts +8 -8
- package/src/input/handler-ui-state.ts +1 -1
- package/src/input/tts-settings-actions.ts +2 -1
- package/src/main.ts +52 -59
- package/src/panels/agent-inspector-panel.ts +72 -2
- package/src/panels/agent-logs-panel.ts +127 -19
- package/src/panels/base-panel.ts +2 -1
- package/src/panels/builtin/agent.ts +3 -1
- package/src/panels/builtin/development.ts +1 -0
- package/src/panels/builtin/session.ts +1 -1
- package/src/panels/context-visualizer-panel.ts +24 -14
- package/src/panels/cost-tracker-panel.ts +7 -13
- package/src/panels/debug-panel.ts +11 -22
- package/src/panels/docs-panel.ts +14 -24
- package/src/panels/file-explorer-panel.ts +2 -1
- package/src/panels/file-preview-panel.ts +2 -1
- package/src/panels/git-panel.ts +10 -17
- package/src/panels/marketplace-panel.ts +2 -1
- package/src/panels/memory-panel.ts +2 -1
- package/src/panels/project-planning-panel.ts +5 -4
- package/src/panels/provider-health-panel.ts +56 -67
- package/src/panels/schedule-panel.ts +4 -7
- package/src/panels/session-browser-panel.ts +13 -21
- package/src/panels/skills-panel.ts +2 -1
- package/src/panels/tasks-panel.ts +2 -7
- package/src/panels/thinking-panel.ts +6 -11
- package/src/panels/token-budget-panel.ts +31 -15
- package/src/panels/tool-inspector-panel.ts +10 -18
- package/src/panels/work-plan-panel.ts +2 -1
- package/src/panels/wrfc-panel.ts +37 -35
- package/src/renderer/agent-detail-modal.ts +2 -2
- package/src/renderer/modal-utils.ts +0 -10
- package/src/renderer/process-modal.ts +2 -2
- package/src/runtime/bootstrap-command-context.ts +3 -0
- package/src/runtime/bootstrap-command-parts.ts +3 -1
- package/src/runtime/bootstrap-core.ts +31 -31
- package/src/runtime/bootstrap-shell.ts +1 -0
- package/src/runtime/onboarding/apply.ts +4 -3
- package/src/runtime/onboarding/snapshot.ts +4 -3
- package/src/runtime/process-lifecycle.ts +195 -0
- package/src/runtime/services.ts +4 -1
- package/src/runtime/wrfc-persistence.ts +20 -5
- package/src/shell/ui-openers.ts +3 -2
- package/src/verification/live-verifier.ts +4 -3
- package/src/version.ts +1 -1
- package/src/core/context-auto-compact.ts +0 -110
|
@@ -25,6 +25,7 @@ import { digestSender, toBodyPreview, toSubjectPreview } from '../mapping.ts';
|
|
|
25
25
|
import { resolveRouteId } from './route-util.ts';
|
|
26
26
|
import { ImapClient } from './imap-client.ts';
|
|
27
27
|
import type { ImapConfig, ImapEnvelope } from './imap-client.ts';
|
|
28
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
28
29
|
|
|
29
30
|
export const EMAIL_PROVIDER_ID = 'email';
|
|
30
31
|
export const EMAIL_HOST_KEY = 'surfaces.email.imapHost';
|
|
@@ -147,5 +148,5 @@ function unavailable(error: string): ProviderPollResult {
|
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
function errMsg(error: unknown): string {
|
|
150
|
-
return
|
|
151
|
+
return summarizeError(error);
|
|
151
152
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// surface) so a route lookup can never crash a provider poll.
|
|
4
4
|
|
|
5
5
|
import type { AdapterContext, InboundChannelItem } from '../provider-adapter.ts';
|
|
6
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
6
7
|
|
|
7
8
|
export async function resolveRouteId(
|
|
8
9
|
ctx: AdapterContext,
|
|
@@ -16,7 +17,7 @@ export async function resolveRouteId(
|
|
|
16
17
|
} catch (error) {
|
|
17
18
|
ctx.logger.warn('route resolution failed', {
|
|
18
19
|
provider,
|
|
19
|
-
error:
|
|
20
|
+
error: summarizeError(error),
|
|
20
21
|
});
|
|
21
22
|
return undefined;
|
|
22
23
|
}
|
|
@@ -30,6 +30,7 @@ import type {
|
|
|
30
30
|
import { POLL_CADENCE_MS } from '../provider-adapter.ts';
|
|
31
31
|
import { digestSender, toBodyPreview, toSubjectPreview } from '../mapping.ts';
|
|
32
32
|
import { resolveRouteId } from './route-util.ts';
|
|
33
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
33
34
|
|
|
34
35
|
const SLACK_API = 'https://slack.com/api';
|
|
35
36
|
export const SLACK_PROVIDER_ID = 'slack';
|
|
@@ -258,5 +259,5 @@ function unavailable(error: string): ProviderPollResult {
|
|
|
258
259
|
}
|
|
259
260
|
|
|
260
261
|
function errMsg(error: unknown): string {
|
|
261
|
-
return
|
|
262
|
+
return summarizeError(error);
|
|
262
263
|
}
|
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
type TriageTagger,
|
|
48
48
|
type TriageTaggerOptions,
|
|
49
49
|
} from './tagger/index.ts';
|
|
50
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
50
51
|
|
|
51
52
|
/**
|
|
52
53
|
* Canonical id of the inbox list method whose handler we decorate. This is the
|
|
@@ -151,7 +152,7 @@ function withInboxEnrichment(ctx: HandlerContext): EnrichmentProxy {
|
|
|
151
152
|
// Triage is best-effort: a missing/locked store must never break the
|
|
152
153
|
// read-only inbox feed. Log and return the un-enriched result.
|
|
153
154
|
ctx.logger.warn('triage: inbox enrichment skipped', {
|
|
154
|
-
message:
|
|
155
|
+
message: summarizeError(error),
|
|
155
156
|
});
|
|
156
157
|
return result;
|
|
157
158
|
}
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
type TriageScore,
|
|
24
24
|
type TriageScorerOptions,
|
|
25
25
|
} from './scorer.ts';
|
|
26
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
26
27
|
|
|
27
28
|
export const TRIAGE_STORE_FILE = 'inbox-triage.sqlite';
|
|
28
29
|
|
|
@@ -158,7 +159,7 @@ export async function runInboxTriage(
|
|
|
158
159
|
if (ownsStore) await store.save();
|
|
159
160
|
} catch (error) {
|
|
160
161
|
ctx.logger.error('triage: failed to persist scores', {
|
|
161
|
-
message:
|
|
162
|
+
message: summarizeError(error),
|
|
162
163
|
});
|
|
163
164
|
throw error;
|
|
164
165
|
} finally {
|
|
@@ -19,6 +19,7 @@ import { HandlerError } from '../../errors.ts';
|
|
|
19
19
|
import type { InboundChannelItem } from '../types.ts';
|
|
20
20
|
import type { ApplyTagsResult, TaggerProviderConfig } from './shared.ts';
|
|
21
21
|
import { discordEmojiForTag, stringMeta } from './shared.ts';
|
|
22
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
22
23
|
|
|
23
24
|
export async function applyDiscord(
|
|
24
25
|
item: InboundChannelItem,
|
|
@@ -179,7 +180,7 @@ async function fetchDiscordAppliedTags(
|
|
|
179
180
|
return current.filter((t): t is string => typeof t === 'string');
|
|
180
181
|
} catch (error) {
|
|
181
182
|
ctx.logger.warn('triage: discord thread tag read errored', {
|
|
182
|
-
message:
|
|
183
|
+
message: summarizeError(error),
|
|
183
184
|
});
|
|
184
185
|
return null;
|
|
185
186
|
}
|
|
@@ -14,6 +14,7 @@ import type { DaemonCredentialStore } from '../../credentials.ts';
|
|
|
14
14
|
import type { InboundChannelItem } from '../types.ts';
|
|
15
15
|
import type { ApplyTagsResult, TaggerProviderConfig } from './shared.ts';
|
|
16
16
|
import { imapKeywordForTag } from './shared.ts';
|
|
17
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
17
18
|
|
|
18
19
|
export interface ImapStoreArgs {
|
|
19
20
|
host: string;
|
|
@@ -227,7 +228,7 @@ export function imapStoreFlagOverTls(
|
|
|
227
228
|
reject(
|
|
228
229
|
err instanceof ImapStoreError
|
|
229
230
|
? err
|
|
230
|
-
: new ImapStoreError(
|
|
231
|
+
: new ImapStoreError(summarizeError(err), false),
|
|
231
232
|
);
|
|
232
233
|
return;
|
|
233
234
|
}
|
|
@@ -288,7 +289,7 @@ export function imapStoreFlagOverTls(
|
|
|
288
289
|
finish(
|
|
289
290
|
err instanceof ImapStoreError
|
|
290
291
|
? err
|
|
291
|
-
: new ImapStoreError(
|
|
292
|
+
: new ImapStoreError(summarizeError(err), false),
|
|
292
293
|
),
|
|
293
294
|
);
|
|
294
295
|
return;
|
|
@@ -318,7 +319,7 @@ export function imapStoreFlagOverTls(
|
|
|
318
319
|
};
|
|
319
320
|
|
|
320
321
|
socket.on('error', (err) =>
|
|
321
|
-
finish(new ImapStoreError(
|
|
322
|
+
finish(new ImapStoreError(summarizeError(err), true)),
|
|
322
323
|
);
|
|
323
324
|
socket.on('close', () => {
|
|
324
325
|
if (completed) finish();
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
// the URL can view it).
|
|
17
17
|
// ---------------------------------------------------------------------------
|
|
18
18
|
|
|
19
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
20
|
+
|
|
19
21
|
export type UploadResult =
|
|
20
22
|
| { ok: true; url: string }
|
|
21
23
|
| { ok: false; error: string };
|
|
@@ -96,7 +98,7 @@ export class GistUploadTarget implements UploadTarget {
|
|
|
96
98
|
body,
|
|
97
99
|
});
|
|
98
100
|
} catch (fetchErr: unknown) {
|
|
99
|
-
const msg =
|
|
101
|
+
const msg = summarizeError(fetchErr);
|
|
100
102
|
return { ok: false, error: `Network error: ${msg}` };
|
|
101
103
|
}
|
|
102
104
|
|
|
@@ -139,6 +139,7 @@ export interface CommandSessionServices {
|
|
|
139
139
|
readonly sessionManager?: import('@pellux/goodvibes-sdk/platform/sessions').SessionManager;
|
|
140
140
|
readonly sessionMemoryStore?: import('@pellux/goodvibes-sdk/platform/core').SessionMemoryStore;
|
|
141
141
|
readonly sessionLineageTracker?: import('@pellux/goodvibes-sdk/platform/core').SessionLineageTracker;
|
|
142
|
+
readonly wrfcController?: import('@pellux/goodvibes-sdk/platform/agents').WrfcController;
|
|
142
143
|
readonly changeTracker?: import('@pellux/goodvibes-sdk/platform/sessions').SessionChangeTracker;
|
|
143
144
|
}
|
|
144
145
|
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from '../../runtime/cloudflare-control-plane.ts';
|
|
12
12
|
import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
13
13
|
import { requireShellPaths } from './runtime-services.ts';
|
|
14
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
14
15
|
|
|
15
16
|
interface ParsedCloudflareArgs {
|
|
16
17
|
readonly positional: readonly string[];
|
|
@@ -366,5 +367,5 @@ function formatCloudflareError(error: unknown): string {
|
|
|
366
367
|
if (error instanceof CloudflareDaemonRouteError) {
|
|
367
368
|
return `${error.message} (HTTP ${error.status}, ${error.code})`;
|
|
368
369
|
}
|
|
369
|
-
return
|
|
370
|
+
return summarizeError(error);
|
|
370
371
|
}
|
|
@@ -2,7 +2,7 @@ import { estimateConversationTokens } from '@pellux/goodvibes-sdk/platform/core'
|
|
|
2
2
|
import { evaluateSessionMaintenance, formatSessionMaintenanceLines, getGuidanceMode } from '@/runtime/index.ts';
|
|
3
3
|
import { dismissGuidance, evaluateContextualGuidance, formatGuidanceItems, resetGuidance } from '@/runtime/index.ts';
|
|
4
4
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
5
|
-
import {
|
|
5
|
+
import { requireReadModels, requireSessionMemoryStore, requireShellPaths } from './runtime-services.ts';
|
|
6
6
|
|
|
7
7
|
export function registerGuidanceRuntimeCommands(registry: CommandRegistry): void {
|
|
8
8
|
registry.register({
|
|
@@ -68,8 +68,6 @@ export function registerGuidanceRuntimeCommands(registry: CommandRegistry): void
|
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
const providerApi = requireProviderApi(ctx);
|
|
72
|
-
const currentModel = await providerApi.getCurrentModel().catch(() => null); // best-effort: null handled as unknown context window
|
|
73
71
|
const llmMessages = ctx.session.conversationManager.getMessagesForLLM();
|
|
74
72
|
const readModels = requireReadModels(ctx);
|
|
75
73
|
const session = readModels.session.getSnapshot();
|
|
@@ -80,7 +78,7 @@ export function registerGuidanceRuntimeCommands(registry: CommandRegistry): void
|
|
|
80
78
|
const maintenance = evaluateSessionMaintenance({
|
|
81
79
|
configManager: ctx.platform.configManager,
|
|
82
80
|
currentTokens: estimateConversationTokens(llmMessages),
|
|
83
|
-
contextWindow:
|
|
81
|
+
contextWindow: ctx.provider.providerRegistry.getContextWindowForModel(ctx.provider.providerRegistry.getCurrentModel()),
|
|
84
82
|
messageCount: llmMessages.length,
|
|
85
83
|
sessionMemoryCount: requireSessionMemoryStore(ctx).list().length,
|
|
86
84
|
session: session.session,
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
openCommandPanel,
|
|
14
14
|
requireLocalUserAuthManager,
|
|
15
15
|
requireOperatorClient,
|
|
16
|
-
requireProviderApi,
|
|
17
16
|
requireReadModels,
|
|
18
17
|
requireSecretsManager,
|
|
19
18
|
requireServiceRegistry,
|
|
@@ -240,15 +239,19 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
|
|
|
240
239
|
|
|
241
240
|
if (sub === 'maintenance') {
|
|
242
241
|
const session = readModels.session.getSnapshot();
|
|
243
|
-
const
|
|
244
|
-
|
|
242
|
+
const providerRegistry = ctx.provider.providerRegistry;
|
|
243
|
+
// Resolve the context window the same way the Tokens panel does so the
|
|
244
|
+
// maintenance usage %/remaining agree across every diagnostics surface.
|
|
245
|
+
const contextWindow = providerRegistry.getContextWindowForModel(
|
|
246
|
+
providerRegistry.getCurrentModel(),
|
|
247
|
+
);
|
|
245
248
|
const llmMessages = typeof ctx.session.conversationManager.getMessagesForLLM === 'function'
|
|
246
249
|
? ctx.session.conversationManager.getMessagesForLLM()
|
|
247
250
|
: [];
|
|
248
251
|
const maintenance = evaluateSessionMaintenance({
|
|
249
252
|
configManager: ctx.platform.configManager,
|
|
250
253
|
currentTokens: estimateConversationTokens(llmMessages),
|
|
251
|
-
contextWindow
|
|
254
|
+
contextWindow,
|
|
252
255
|
messageCount: llmMessages.length,
|
|
253
256
|
sessionMemoryCount: requireSessionMemoryStore(ctx).list().length,
|
|
254
257
|
session: session.session,
|
|
@@ -386,12 +389,15 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
|
|
|
386
389
|
}
|
|
387
390
|
|
|
388
391
|
const session = readModels.session.getSnapshot();
|
|
389
|
-
const
|
|
390
|
-
const currentModel = await providerApi.getCurrentModel().catch(() => null); // best-effort: null handled as unknown context window
|
|
392
|
+
const providerRegistry = ctx.provider.providerRegistry;
|
|
391
393
|
const llmMessages = typeof ctx.session.conversationManager.getMessagesForLLM === 'function'
|
|
392
394
|
? ctx.session.conversationManager.getMessagesForLLM()
|
|
393
395
|
: [];
|
|
394
|
-
|
|
396
|
+
// Resolve the context window the same way the Tokens panel does so the
|
|
397
|
+
// maintenance usage %/remaining agree across every diagnostics surface.
|
|
398
|
+
const contextWindow = providerRegistry.getContextWindowForModel(
|
|
399
|
+
providerRegistry.getCurrentModel(),
|
|
400
|
+
);
|
|
395
401
|
const maintenance = evaluateSessionMaintenance({
|
|
396
402
|
configManager: ctx.platform.configManager,
|
|
397
403
|
currentTokens: estimateConversationTokens(llmMessages),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { KnowledgeService } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
2
2
|
import type { CommandContext, SlashCommand } from '../command-registry.ts';
|
|
3
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
3
4
|
|
|
4
5
|
const KNOWLEDGE_REVIEW_ACTIONS = ['accept', 'reject', 'resolve', 'reopen', 'edit', 'forget'] as const;
|
|
5
6
|
|
|
@@ -397,7 +398,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
397
398
|
...(result.appliedFacts ? [` applied facts: ${Object.keys(result.appliedFacts).join(', ') || 'none'}`] : []),
|
|
398
399
|
].join('\n'));
|
|
399
400
|
} catch (error) {
|
|
400
|
-
context.print(`[knowledge] ${
|
|
401
|
+
context.print(`[knowledge] ${summarizeError(error)}`);
|
|
401
402
|
}
|
|
402
403
|
break;
|
|
403
404
|
}
|
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
CommandSessionServices,
|
|
8
8
|
CommandWorkspaceServices,
|
|
9
9
|
} from '../command-registry.ts';
|
|
10
|
-
import { getLastCompactionEvent } from '@pellux/goodvibes-sdk/platform/core';
|
|
10
|
+
import { compactSmallWindow, getLastCompactionEvent, SMALL_WINDOW_THRESHOLD } from '@pellux/goodvibes-sdk/platform/core';
|
|
11
11
|
import type { CompactionContext, CompactionEvent } from '@pellux/goodvibes-sdk/platform/core';
|
|
12
12
|
import type { UiReadModels } from '../../runtime/ui-read-models.ts';
|
|
13
13
|
import type { ShellPathService } from '@/runtime/index.ts';
|
|
@@ -244,23 +244,53 @@ export function requireProviderApi(context: CommandContext): ProviderApi {
|
|
|
244
244
|
* change).
|
|
245
245
|
*/
|
|
246
246
|
export async function compactConversation(context: CommandContext): Promise<CompactionEvent | null> {
|
|
247
|
+
const conversationManager = context.session.conversationManager;
|
|
248
|
+
const providerRegistry = context.provider.providerRegistry;
|
|
249
|
+
// Resolve the live context window for the current model so manual /compact
|
|
250
|
+
// matches the auto-compaction path (which scales behaviour by window size)
|
|
251
|
+
// instead of passing a meaningless 0.
|
|
252
|
+
const contextWindow = providerRegistry.getContextWindowForModel(
|
|
253
|
+
providerRegistry.getCurrentModel(),
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
// Small-window models lack room for the structured (multi-LLM) extraction
|
|
257
|
+
// pipeline, so mirror the SDK auto-compaction path and degrade to the
|
|
258
|
+
// simplified "keep the most recent messages" compaction.
|
|
259
|
+
if (contextWindow > 0 && contextWindow < SMALL_WINDOW_THRESHOLD) {
|
|
260
|
+
const compacted = compactSmallWindow(conversationManager.getMessagesForLLM(), 10);
|
|
261
|
+
conversationManager.replaceMessagesForLLM(compacted);
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
|
|
247
265
|
const eventBefore = getLastCompactionEvent();
|
|
248
266
|
const sessionMemories = context.session.sessionMemoryStore?.list() ?? [];
|
|
267
|
+
const lineageTracker = context.session.sessionLineageTracker;
|
|
268
|
+
const agentManager = context.ops.agentManager;
|
|
269
|
+
const planManager = context.ops.planManager;
|
|
249
270
|
const compactionCtx: CompactionContext = {
|
|
250
|
-
messages:
|
|
271
|
+
messages: conversationManager.getMessagesForLLM(),
|
|
251
272
|
sessionMemories,
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
273
|
+
// Mirror buildAutoCompactionContext: pass the running/pending agents, the
|
|
274
|
+
// active execution plan, and the session-lineage log so the handoff summary
|
|
275
|
+
// and lineage section are populated correctly (not "compaction #0").
|
|
276
|
+
agents:
|
|
277
|
+
agentManager
|
|
278
|
+
?.exportState()
|
|
279
|
+
.filter((agent) => agent.status === 'running' || agent.status === 'pending') ?? [],
|
|
280
|
+
// Mirror buildAutoCompactionContext: include the live WRFC chains (wired
|
|
281
|
+
// through context.session.wrfcController) so the handoff summary's
|
|
282
|
+
// orchestration section matches the SDK auto-compaction path.
|
|
283
|
+
wrfcChains: context.session.wrfcController?.listChains() ?? [],
|
|
284
|
+
activePlan: planManager?.getActive(context.session.runtime.sessionId) ?? null,
|
|
285
|
+
lineageEntries: lineageTracker?.getEntries() ?? [],
|
|
286
|
+
compactionCount: lineageTracker?.getCompactionCount() ?? 0,
|
|
287
|
+
contextWindow,
|
|
258
288
|
trigger: 'manual',
|
|
259
289
|
extractionModelId: context.session.runtime.model,
|
|
260
290
|
extractionProvider: context.session.runtime.provider,
|
|
261
291
|
};
|
|
262
|
-
await
|
|
263
|
-
|
|
292
|
+
await conversationManager.compact(
|
|
293
|
+
providerRegistry,
|
|
264
294
|
context.session.runtime.model,
|
|
265
295
|
'manual',
|
|
266
296
|
context.session.runtime.provider,
|
|
@@ -117,7 +117,7 @@ export function handleCommandModeToken(state: CommandModeRouteState, token: Inpu
|
|
|
117
117
|
return true;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
return token.logicalName !== 'left' && token.logicalName !== 'right';
|
|
120
|
+
return token.logicalName !== 'left' && token.logicalName !== 'right' && token.logicalName !== 'home' && token.logicalName !== 'end';
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
function withPanelFocusSync(context: CommandContext, state: CommandModeRouteState): CommandContext {
|
|
@@ -5,6 +5,7 @@ import { cleanupMarkerRegistry, expandPrompt, findMarkerAtPos, handleBlockCopy,
|
|
|
5
5
|
import { clearModalStack, handleEscape, modalOpened } from './handler-modal-stack.ts';
|
|
6
6
|
import { openOnboardingWizardState, type OpenOnboardingWizardOptions } from './handler-ui-state.ts';
|
|
7
7
|
import type { InputHandlerLike as InputHandler } from './handler-types.ts';
|
|
8
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
8
9
|
|
|
9
10
|
export function openOnboardingWizardForHandler(
|
|
10
11
|
handler: InputHandler,
|
|
@@ -49,7 +50,7 @@ export async function hydrateOnboardingWizardFromRuntimeForHandler(handler: Inpu
|
|
|
49
50
|
handler.requestRender();
|
|
50
51
|
} catch (error) {
|
|
51
52
|
if (!handler.onboardingWizard.active || hydrationSerial !== handler.onboardingHydrationSerial) return;
|
|
52
|
-
const message =
|
|
53
|
+
const message = summarizeError(error);
|
|
53
54
|
handler.onboardingWizard.failRuntimeHydration(message);
|
|
54
55
|
handler.commandContext?.print?.(`Onboarding runtime snapshot failed: ${message}`);
|
|
55
56
|
handler.requestRender();
|
|
@@ -3,6 +3,7 @@ import type { SelectionResult, SelectionAction } from './selection-modal.ts';
|
|
|
3
3
|
import type { CommandContext } from './command-registry.ts';
|
|
4
4
|
import { openTtsProviderPicker, openTtsVoicePicker } from './tts-settings-actions.ts';
|
|
5
5
|
import { isTextBackspace } from './delete-key-policy.ts';
|
|
6
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
6
7
|
|
|
7
8
|
type SelectionRouteState = {
|
|
8
9
|
selectionModal: {
|
|
@@ -285,7 +286,7 @@ function consumeSettingsPickerRequest(state: SettingsRouteState): void {
|
|
|
285
286
|
return;
|
|
286
287
|
}
|
|
287
288
|
void openTtsVoicePicker(state.commandContext).catch((error: unknown) => {
|
|
288
|
-
state.commandContext?.print(`Unable to list TTS voices: ${
|
|
289
|
+
state.commandContext?.print(`Unable to list TTS voices: ${summarizeError(error)}`);
|
|
289
290
|
state.requestRender();
|
|
290
291
|
});
|
|
291
292
|
return;
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
getCloudflareSetupSource,
|
|
23
23
|
shouldShowCloudflareStep,
|
|
24
24
|
} from './onboarding/onboarding-wizard-cloudflare.ts';
|
|
25
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
25
26
|
|
|
26
27
|
type CloudflareOnboardingAction = Extract<OnboardingWizardAction,
|
|
27
28
|
| 'cloudflare-token-requirements'
|
|
@@ -44,7 +45,7 @@ function normalizeCloudflareActionError(error: unknown): string {
|
|
|
44
45
|
if (error instanceof CloudflareDaemonRouteError) {
|
|
45
46
|
return `${error.message} (HTTP ${error.status}, ${error.code})`;
|
|
46
47
|
}
|
|
47
|
-
return
|
|
48
|
+
return summarizeError(error);
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
function setCloudflareWizardStatusForHandler(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createOAuthLocalListener } from '@pellux/goodvibes-sdk/platform/config';
|
|
2
2
|
import { beginOpenAICodexLogin, exchangeOpenAICodexCode } from '@pellux/goodvibes-sdk/platform/config';
|
|
3
|
-
import { openExternalUrl } from '@pellux/goodvibes-sdk/platform/utils';
|
|
3
|
+
import { summarizeError, openExternalUrl } from '@pellux/goodvibes-sdk/platform/utils';
|
|
4
4
|
import { getProviderIdFromModel } from '../config/provider-model.ts';
|
|
5
5
|
import { buildProviderAccountSnapshot } from '@/runtime/index.ts';
|
|
6
6
|
import { OnboardingWizardController, type OnboardingWizardAction, type OnboardingWizardApplyFeedback } from './onboarding/onboarding-wizard.ts';
|
|
@@ -258,7 +258,7 @@ export async function handleOnboardingActionForHandler(handler: InputHandler, ac
|
|
|
258
258
|
deleteWizardProgress(handler.uiServices.environment.shellPaths);
|
|
259
259
|
} catch (markerError) {
|
|
260
260
|
handler.commandContext?.print?.(
|
|
261
|
-
`Onboarding check marker could not be written: ${
|
|
261
|
+
`Onboarding check marker could not be written: ${summarizeError(markerError)}`,
|
|
262
262
|
);
|
|
263
263
|
}
|
|
264
264
|
const activationVerification = await handler.restartOnboardingExternalServicesIfNeeded(request);
|
|
@@ -275,7 +275,7 @@ export async function handleOnboardingActionForHandler(handler: InputHandler, ac
|
|
|
275
275
|
severity: 'error',
|
|
276
276
|
title: 'Apply failed',
|
|
277
277
|
summary: 'The wizard could not persist these settings. No service restart was attempted.',
|
|
278
|
-
messages: [
|
|
278
|
+
messages: [summarizeError(error)],
|
|
279
279
|
});
|
|
280
280
|
return;
|
|
281
281
|
} finally {
|
|
@@ -346,7 +346,7 @@ export async function refreshOnboardingHydrationForHandler(handler: InputHandler
|
|
|
346
346
|
handler.requestRender();
|
|
347
347
|
} catch (error) {
|
|
348
348
|
if (!handler.onboardingWizard.active || hydrationSerial !== handler.onboardingHydrationSerial) return;
|
|
349
|
-
const message =
|
|
349
|
+
const message = summarizeError(error);
|
|
350
350
|
handler.onboardingWizard.failRuntimeHydration(message);
|
|
351
351
|
handler.requestRender();
|
|
352
352
|
}
|
|
@@ -405,7 +405,7 @@ export async function handleOpenAiSubscriptionStartForHandler(handler: InputHand
|
|
|
405
405
|
listener?.close();
|
|
406
406
|
handler.commandContext?.print?.([
|
|
407
407
|
'OpenAI subscription sign-in could not start.',
|
|
408
|
-
` ${
|
|
408
|
+
` ${summarizeError(error)}`,
|
|
409
409
|
].join('\n'));
|
|
410
410
|
handler.requestRender();
|
|
411
411
|
} finally {
|
|
@@ -449,7 +449,7 @@ export async function completeOpenAiSubscriptionFromListenerForHandler(
|
|
|
449
449
|
} catch (error) {
|
|
450
450
|
handler.commandContext?.print?.([
|
|
451
451
|
'OpenAI subscription listener could not complete automatically.',
|
|
452
|
-
` listener: ${
|
|
452
|
+
` listener: ${summarizeError(error)}`,
|
|
453
453
|
'Paste the callback code or URL into the OpenAI callback field to finish in onboarding.',
|
|
454
454
|
].join('\n'));
|
|
455
455
|
handler.requestRender();
|
|
@@ -501,7 +501,7 @@ export async function handleOpenAiSubscriptionFinishForHandler(handler: InputHan
|
|
|
501
501
|
} catch (error) {
|
|
502
502
|
handler.commandContext?.print?.([
|
|
503
503
|
'OpenAI subscription sign-in could not finish.',
|
|
504
|
-
` ${
|
|
504
|
+
` ${summarizeError(error)}`,
|
|
505
505
|
].join('\n'));
|
|
506
506
|
handler.requestRender();
|
|
507
507
|
} finally {
|
|
@@ -663,7 +663,7 @@ export async function restartOnboardingExternalServicesIfNeededForHandler(handle
|
|
|
663
663
|
return [{
|
|
664
664
|
id: 'runtime:activation-restart',
|
|
665
665
|
status: 'fail',
|
|
666
|
-
message: `Background services could not restart: ${
|
|
666
|
+
message: `Background services could not restart: ${summarizeError(error)}`,
|
|
667
667
|
target: 'service',
|
|
668
668
|
}];
|
|
669
669
|
}
|
|
@@ -345,7 +345,7 @@ export function handleHistorySearchToken(state: HistorySearchRouteState, token:
|
|
|
345
345
|
if (token.logicalName === 'escape' || (token.ctrl && token.logicalName === 'g')) {
|
|
346
346
|
state.prompt = state.historySearch.cancel();
|
|
347
347
|
state.cursorPos = state.prompt.length;
|
|
348
|
-
} else if (token.logicalName === 'return') {
|
|
348
|
+
} else if (token.logicalName === 'enter' || token.logicalName === 'return') {
|
|
349
349
|
state.prompt = state.historySearch.accept();
|
|
350
350
|
state.cursorPos = state.prompt.length;
|
|
351
351
|
} else if (token.logicalName === 'backspace') {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ConfigKey } from '@pellux/goodvibes-sdk/platform/config';
|
|
2
2
|
import type { CommandContext } from './command-registry.ts';
|
|
3
3
|
import type { SelectionItem } from './selection-modal.ts';
|
|
4
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
4
5
|
|
|
5
6
|
function getStreamingTtsProviders(ctx: CommandContext): Array<{ id: string; label: string; capabilities: readonly string[] }> {
|
|
6
7
|
const registry = ctx.platform.voiceProviderRegistry;
|
|
@@ -94,7 +95,7 @@ export async function openTtsVoicePicker(ctx: CommandContext, providerArg?: stri
|
|
|
94
95
|
});
|
|
95
96
|
return true;
|
|
96
97
|
} catch (error) {
|
|
97
|
-
ctx.print(`Unable to list TTS voices: ${
|
|
98
|
+
ctx.print(`Unable to list TTS voices: ${summarizeError(error)}`);
|
|
98
99
|
return true;
|
|
99
100
|
}
|
|
100
101
|
}
|