@pellux/goodvibes-agent 0.1.110 → 0.1.112
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 +20 -0
- package/README.md +3 -3
- package/dist/package/main.js +3075 -2713
- package/docs/getting-started.md +3 -3
- package/package.json +1 -1
- package/src/cli/help.ts +0 -1
- package/src/cli/parser.ts +0 -8
- package/src/cli/types.ts +0 -1
- package/src/input/agent-workspace-categories.ts +5 -7
- package/src/input/agent-workspace-snapshot.ts +2 -10
- package/src/input/agent-workspace-types.ts +2 -3
- package/src/input/commands/brief-runtime.ts +1 -1
- package/src/input/commands/channels-runtime.ts +397 -35
- package/src/input/commands/experience-runtime.ts +4 -9
- package/src/input/commands/health-runtime.ts +26 -6
- package/src/input/commands/mcp-runtime.ts +51 -26
- package/src/input/commands/memory.ts +10 -10
- package/src/input/commands/planning-runtime.ts +4 -9
- package/src/input/commands/provider-accounts-runtime.ts +2 -3
- package/src/input/commands/qrcode-runtime.ts +48 -9
- package/src/input/commands/recall-bundle.ts +16 -16
- package/src/input/commands/recall-capture.ts +18 -18
- package/src/input/commands/recall-query.ts +22 -22
- package/src/input/commands/recall-review.ts +12 -12
- package/src/input/commands/tasks-runtime.ts +9 -15
- package/src/input/commands/work-plan-runtime.ts +5 -19
- package/src/input/commands.ts +2 -7
- package/src/renderer/agent-workspace.ts +1 -2
- package/src/runtime/onboarding/derivation.ts +6 -67
- package/src/version.ts +1 -1
|
@@ -7,8 +7,8 @@ import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
|
7
7
|
export function getMemoryApi(context: CommandContext): MemoryApi | null {
|
|
8
8
|
const memoryApi = context.clients?.agentKnowledgeApi?.memory;
|
|
9
9
|
if (!memoryApi) {
|
|
10
|
-
context.print('[
|
|
11
|
-
context.print('[
|
|
10
|
+
context.print('[memory] Agent Memory API is not available in this runtime.');
|
|
11
|
+
context.print('[memory] Refusing to use default Knowledge/Wiki or non-Agent knowledge fallback.');
|
|
12
12
|
return null;
|
|
13
13
|
}
|
|
14
14
|
return memoryApi;
|
|
@@ -29,7 +29,7 @@ export function handleRecallSearch(args: string[], context: CommandContext): voi
|
|
|
29
29
|
const cls = args[clsIdx + 1];
|
|
30
30
|
if (isValidClass(cls)) filter.cls = cls;
|
|
31
31
|
else {
|
|
32
|
-
context.print(`[
|
|
32
|
+
context.print(`[memory] Unknown class "${cls}". Valid: ${VALID_CLASSES.join(', ')}`);
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -39,7 +39,7 @@ export function handleRecallSearch(args: string[], context: CommandContext): voi
|
|
|
39
39
|
const scope = args[scopeIdx + 1];
|
|
40
40
|
if (isValidScope(scope)) filter.scope = scope;
|
|
41
41
|
else {
|
|
42
|
-
context.print(`[
|
|
42
|
+
context.print(`[memory] Unknown scope "${scope}". Valid: ${VALID_SCOPES.join(', ')}`);
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -59,11 +59,11 @@ export function handleRecallSearch(args: string[], context: CommandContext): voi
|
|
|
59
59
|
const semanticResults = semantic ? memory.searchSemantic(filter) : [];
|
|
60
60
|
const results = semantic ? semanticResults.map((entry) => entry.record) : memory.search(filter);
|
|
61
61
|
if (!results.length) {
|
|
62
|
-
context.print('[
|
|
62
|
+
context.print('[memory] No records found.');
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
context.print(`[
|
|
66
|
+
context.print(`[memory] ${results.length} ${semantic ? 'semantic ' : ''}record(s):`);
|
|
67
67
|
for (const record of results) {
|
|
68
68
|
const semanticEntry = semanticResults.find((entry) => entry.record.id === record.id);
|
|
69
69
|
const ts = new Date(record.createdAt).toISOString().slice(0, 16).replace('T', ' ');
|
|
@@ -93,7 +93,7 @@ export function handleRecallVector(args: string[], context: CommandContext): voi
|
|
|
93
93
|
context.print(formatVectorStats(memory.vectorStats(), sub));
|
|
94
94
|
return;
|
|
95
95
|
}
|
|
96
|
-
context.print('[
|
|
96
|
+
context.print('[memory] Usage: /memory vector [status|doctor|rebuild]');
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
function formatVectorStats(
|
|
@@ -101,7 +101,7 @@ function formatVectorStats(
|
|
|
101
101
|
label: string,
|
|
102
102
|
): string {
|
|
103
103
|
return [
|
|
104
|
-
`[
|
|
104
|
+
`[memory] Vector index ${label}`,
|
|
105
105
|
` backend: ${stats.backend}`,
|
|
106
106
|
` enabled: ${stats.enabled ? 'yes' : 'no'}`,
|
|
107
107
|
` available: ${stats.available ? 'yes' : 'no'}`,
|
|
@@ -119,16 +119,16 @@ export function handleRecallGet(args: string[], context: CommandContext): void {
|
|
|
119
119
|
}
|
|
120
120
|
const id = args[0];
|
|
121
121
|
if (!id) {
|
|
122
|
-
context.print('[
|
|
122
|
+
context.print('[memory] Usage: /memory get <id>');
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
125
|
const record = memory.get(id);
|
|
126
126
|
if (!record) {
|
|
127
|
-
context.print(`[
|
|
127
|
+
context.print(`[memory] Record not found: ${id}`);
|
|
128
128
|
return;
|
|
129
129
|
}
|
|
130
130
|
const ts = new Date(record.createdAt).toISOString().slice(0, 19).replace('T', ' ');
|
|
131
|
-
context.print(`[
|
|
131
|
+
context.print(`[memory] ${record.id}`);
|
|
132
132
|
context.print(` Scope: ${record.scope}`);
|
|
133
133
|
context.print(` Class: ${record.cls}`);
|
|
134
134
|
context.print(` Summary: ${record.summary}`);
|
|
@@ -163,19 +163,19 @@ export async function handleRecallLink(args: string[], context: CommandContext):
|
|
|
163
163
|
const parsed = stripYesFlag(args);
|
|
164
164
|
const [fromId, toId, relation] = parsed.rest;
|
|
165
165
|
if (!fromId || !toId || !relation) {
|
|
166
|
-
context.print('[
|
|
166
|
+
context.print('[memory] Usage: /memory link <fromId> <toId> <relation> --yes');
|
|
167
167
|
return;
|
|
168
168
|
}
|
|
169
169
|
if (!parsed.yes) {
|
|
170
|
-
requireYesFlag(context, `link memory records ${fromId} and ${toId}`, '/
|
|
170
|
+
requireYesFlag(context, `link memory records ${fromId} and ${toId}`, '/memory link <fromId> <toId> <relation> --yes');
|
|
171
171
|
return;
|
|
172
172
|
}
|
|
173
173
|
const link = await memory.link(fromId, toId, relation);
|
|
174
174
|
if (!link) {
|
|
175
|
-
context.print('[
|
|
175
|
+
context.print('[memory] Link failed — check that both IDs exist.');
|
|
176
176
|
return;
|
|
177
177
|
}
|
|
178
|
-
context.print(`[
|
|
178
|
+
context.print(`[memory] Linked: ${fromId} -> ${toId} [${relation}]`);
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
export function handleRecallRemove(args: string[], context: CommandContext): void {
|
|
@@ -186,19 +186,19 @@ export function handleRecallRemove(args: string[], context: CommandContext): voi
|
|
|
186
186
|
const parsed = stripYesFlag(args);
|
|
187
187
|
const id = parsed.rest[0];
|
|
188
188
|
if (!id) {
|
|
189
|
-
context.print('[
|
|
189
|
+
context.print('[memory] Usage: /memory remove <id> --yes');
|
|
190
190
|
return;
|
|
191
191
|
}
|
|
192
192
|
if (!parsed.yes) {
|
|
193
|
-
requireYesFlag(context, `delete durable memory record ${id}`, '/
|
|
193
|
+
requireYesFlag(context, `delete durable memory record ${id}`, '/memory remove <id> --yes');
|
|
194
194
|
return;
|
|
195
195
|
}
|
|
196
196
|
const removed = memory.delete(id);
|
|
197
197
|
if (!removed) {
|
|
198
|
-
context.print(`[
|
|
198
|
+
context.print(`[memory] Record not found: ${id}`);
|
|
199
199
|
return;
|
|
200
200
|
}
|
|
201
|
-
context.print(`[
|
|
201
|
+
context.print(`[memory] Deleted: ${id}`);
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
export function handleRecallList(args: string[], context: CommandContext): void {
|
|
@@ -213,7 +213,7 @@ export function handleRecallList(args: string[], context: CommandContext): void
|
|
|
213
213
|
if (scopeIdx !== -1 && args[scopeIdx + 1]) {
|
|
214
214
|
const scope = args[scopeIdx + 1];
|
|
215
215
|
if (!isValidScope(scope)) {
|
|
216
|
-
context.print(`[
|
|
216
|
+
context.print(`[memory] Unknown scope "${scope}". Valid: ${VALID_SCOPES.join(', ')}`);
|
|
217
217
|
return;
|
|
218
218
|
}
|
|
219
219
|
filter.scope = scope;
|
|
@@ -221,7 +221,7 @@ export function handleRecallList(args: string[], context: CommandContext): void
|
|
|
221
221
|
|
|
222
222
|
const records = memory.search(filter);
|
|
223
223
|
if (!records.length) {
|
|
224
|
-
context.print('[
|
|
224
|
+
context.print('[memory] No records.');
|
|
225
225
|
return;
|
|
226
226
|
}
|
|
227
227
|
|
|
@@ -232,7 +232,7 @@ export function handleRecallList(args: string[], context: CommandContext): void
|
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
for (const [clsName, group] of Object.entries(grouped)) {
|
|
235
|
-
context.print(`\n[
|
|
235
|
+
context.print(`\n[memory] ${clsName.toUpperCase()} (${group.length}):`);
|
|
236
236
|
for (const record of group) {
|
|
237
237
|
const tagStr = record.tags.length ? ` [${record.tags.join(', ')}]` : '';
|
|
238
238
|
context.print(` ${record.id} [${record.scope}]${tagStr} ${record.summary}`);
|
|
@@ -11,10 +11,10 @@ export function handleRecallQueue(args: string[], context: CommandContext): void
|
|
|
11
11
|
const limit = Math.max(1, parseInt(args[0] ?? '10', 10) || 10);
|
|
12
12
|
const queue = memory.reviewQueue(limit);
|
|
13
13
|
if (!queue.length) {
|
|
14
|
-
context.print('[
|
|
14
|
+
context.print('[memory] Review queue is empty.');
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
context.print(`[
|
|
17
|
+
context.print(`[memory] Review queue (${queue.length}):`);
|
|
18
18
|
for (const record of queue) {
|
|
19
19
|
const reason = record.staleReason ? ` — ${record.staleReason}` : '';
|
|
20
20
|
context.print(` ${record.id} [${record.scope}/${record.cls}] ${record.reviewState} ${record.confidence}% ${record.summary}${reason}`);
|
|
@@ -29,7 +29,7 @@ export function handleRecallReview(args: string[], context: CommandContext): voi
|
|
|
29
29
|
|
|
30
30
|
const [id, stateRaw, ...rest] = args;
|
|
31
31
|
if (!id || !stateRaw || !isValidReviewState(stateRaw)) {
|
|
32
|
-
context.print(`[
|
|
32
|
+
context.print(`[memory] Usage: /memory review <id> <${VALID_REVIEW_STATES.join('|')}> [--confidence <0-100>] [--by <name>] [--reason <text>]`);
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -48,10 +48,10 @@ export function handleRecallReview(args: string[], context: CommandContext): voi
|
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
if (!record) {
|
|
51
|
-
context.print(`[
|
|
51
|
+
context.print(`[memory] Record not found: ${id}`);
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
context.print(`[
|
|
54
|
+
context.print(`[memory] Reviewed ${record.id}: ${record.reviewState} ${record.confidence}%`);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export function handleRecallExplain(args: string[], context: CommandContext): void {
|
|
@@ -68,15 +68,15 @@ export function handleRecallExplain(args: string[], context: CommandContext): vo
|
|
|
68
68
|
});
|
|
69
69
|
const task = taskTokens.join(' ').trim();
|
|
70
70
|
if (!task) {
|
|
71
|
-
context.print('[
|
|
71
|
+
context.print('[memory] Usage: /memory explain <task description...> [--scope <write-scope> ...]');
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
74
|
const explanation = memory.explain(task, scopeValues);
|
|
75
75
|
if (explanation.injections.length === 0) {
|
|
76
|
-
context.print('[
|
|
76
|
+
context.print('[memory] No reviewed project knowledge was selected for that task.');
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
|
-
context.print(explanation.prompt ?? '[
|
|
79
|
+
context.print(explanation.prompt ?? '[memory] No explainable project knowledge was selected.');
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
export function handleRecallPromote(args: string[], context: CommandContext): void {
|
|
@@ -88,17 +88,17 @@ export function handleRecallPromote(args: string[], context: CommandContext): vo
|
|
|
88
88
|
const id = parsed.rest[0];
|
|
89
89
|
const scope = parsed.rest[1];
|
|
90
90
|
if (!id || !scope || !isValidScope(scope)) {
|
|
91
|
-
context.print(`[
|
|
91
|
+
context.print(`[memory] Usage: /memory promote <id> <${VALID_SCOPES.join('|')}> --yes`);
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
94
|
if (!parsed.yes) {
|
|
95
|
-
requireYesFlag(context, `promote durable memory record ${id} to ${scope} scope`, '/
|
|
95
|
+
requireYesFlag(context, `promote durable memory record ${id} to ${scope} scope`, '/memory promote <id> <scope> --yes');
|
|
96
96
|
return;
|
|
97
97
|
}
|
|
98
98
|
const record = memory.update(id, { scope });
|
|
99
99
|
if (!record) {
|
|
100
|
-
context.print(`[
|
|
100
|
+
context.print(`[memory] Record not found: ${id}`);
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
|
-
context.print(`[
|
|
103
|
+
context.print(`[memory] Promoted ${record.id} to ${record.scope} scope.`);
|
|
104
104
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
2
|
import type { RuntimeTask, TaskLifecycleState } from '@/runtime/index.ts';
|
|
3
|
-
import { requireOperatorClient
|
|
3
|
+
import { requireOperatorClient } from './runtime-services.ts';
|
|
4
4
|
|
|
5
5
|
const BLOCKED_TASK_MUTATIONS: ReadonlySet<string> = new Set([
|
|
6
6
|
'create',
|
|
@@ -54,20 +54,19 @@ export function registerTasksRuntimeCommands(registry: CommandRegistry): void {
|
|
|
54
54
|
description: 'Inspect connected-service tasks without starting or mutating local background work',
|
|
55
55
|
usage: '[list [status|kind] | show <taskId> | output <taskId>]',
|
|
56
56
|
handler(args, ctx) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
const subcommand = args[0]?.toLowerCase() ?? 'list';
|
|
58
|
+
if (subcommand === 'open' || subcommand === 'panel') {
|
|
59
|
+
ctx.print('Task panels are not part of the Agent workspace. Use /tasks list.');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (BLOCKED_TASK_MUTATIONS.has(subcommand)) {
|
|
64
|
+
printTaskMutationBlocked(ctx.print, subcommand);
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
const operatorClient = requireOperatorClient(ctx);
|
|
69
69
|
const tasks = sortRuntimeTasks([...operatorClient.tasks.list(500)]);
|
|
70
|
-
const subcommand = args[0]?.toLowerCase() ?? 'list';
|
|
71
70
|
|
|
72
71
|
if (subcommand === 'list') {
|
|
73
72
|
const filter = args[1]?.toLowerCase();
|
|
@@ -132,11 +131,6 @@ export function registerTasksRuntimeCommands(registry: CommandRegistry): void {
|
|
|
132
131
|
return;
|
|
133
132
|
}
|
|
134
133
|
|
|
135
|
-
if (BLOCKED_TASK_MUTATIONS.has(subcommand)) {
|
|
136
|
-
printTaskMutationBlocked(ctx.print, subcommand);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
134
|
ctx.print(`Unknown tasks subcommand: ${subcommand}`);
|
|
141
135
|
},
|
|
142
136
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
2
|
import type { WorkPlanItemStatus, WorkPlanStore } from '../../work-plans/work-plan-store.ts';
|
|
3
3
|
import { WORK_PLAN_STATUSES } from '../../work-plans/work-plan-store.ts';
|
|
4
|
-
import { requirePanelManager } from './runtime-services.ts';
|
|
5
4
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
6
5
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
7
6
|
|
|
@@ -25,17 +24,6 @@ function getStore(ctx: import('../command-registry.ts').CommandContext): WorkPla
|
|
|
25
24
|
return ctx.workspace.workPlanStore ?? null;
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
function openPanel(ctx: import('../command-registry.ts').CommandContext): void {
|
|
29
|
-
if (ctx.showPanel) {
|
|
30
|
-
ctx.showPanel('work-plan');
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
const panelManager = requirePanelManager(ctx);
|
|
34
|
-
panelManager.open('work-plan');
|
|
35
|
-
panelManager.show();
|
|
36
|
-
ctx.renderRequest();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
27
|
function formatList(store: WorkPlanStore): string {
|
|
40
28
|
const items = store.listItems();
|
|
41
29
|
if (items.length === 0) return 'Work plan is empty. Add one with /workplan add <title>.';
|
|
@@ -82,8 +70,8 @@ export function registerWorkPlanRuntimeCommands(registry: CommandRegistry): void
|
|
|
82
70
|
name: 'workplan',
|
|
83
71
|
aliases: ['wp', 'todo'],
|
|
84
72
|
description: 'Track a persistent workspace-scoped work plan',
|
|
85
|
-
usage: '[
|
|
86
|
-
argsHint: '[
|
|
73
|
+
usage: '[list|show|add <title> [--owner name] [--source label] [--notes text]|done <id>|start <id>|block <id>|fail <id>|cancel <id>|pending <id>|remove <id> --yes|clear-done --yes]',
|
|
74
|
+
argsHint: '[list|add|show|done]',
|
|
87
75
|
handler(args, ctx) {
|
|
88
76
|
const parsed = stripYesFlag(args);
|
|
89
77
|
const commandArgs = [...parsed.rest];
|
|
@@ -92,11 +80,10 @@ export function registerWorkPlanRuntimeCommands(registry: CommandRegistry): void
|
|
|
92
80
|
ctx.print('Work plan store is not available in this runtime.');
|
|
93
81
|
return;
|
|
94
82
|
}
|
|
95
|
-
const subcommand = (commandArgs[0] ?? '
|
|
83
|
+
const subcommand = (commandArgs[0] ?? 'list').toLowerCase();
|
|
96
84
|
try {
|
|
97
85
|
if (subcommand === 'panel' || subcommand === 'open') {
|
|
98
|
-
|
|
99
|
-
ctx.print('Opened work plan panel.');
|
|
86
|
+
ctx.print('Work plan panels are not part of the Agent workspace. Use /workplan list.');
|
|
100
87
|
return;
|
|
101
88
|
}
|
|
102
89
|
if (subcommand === 'list') {
|
|
@@ -119,8 +106,7 @@ export function registerWorkPlanRuntimeCommands(registry: CommandRegistry): void
|
|
|
119
106
|
...(addArgs.notes ? { notes: addArgs.notes } : {}),
|
|
120
107
|
};
|
|
121
108
|
const item = store.addItem(addArgs.title, addOptions);
|
|
122
|
-
|
|
123
|
-
ctx.print(`Added work plan item ${item.id}.`);
|
|
109
|
+
ctx.print(`Added work plan item ${item.id}. Use /workplan list to review.`);
|
|
124
110
|
return;
|
|
125
111
|
}
|
|
126
112
|
if (subcommand === 'remove' || subcommand === 'delete' || subcommand === 'rm') {
|
package/src/input/commands.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { CommandRegistry } from './command-registry.ts';
|
|
2
2
|
import type { CommandContext } from './command-registry.ts';
|
|
3
|
-
import { policyCommand } from './commands/policy.ts';
|
|
4
3
|
import { sessionCommand } from './commands/session.ts';
|
|
5
4
|
import { recallCommand } from './commands/memory.ts';
|
|
6
5
|
import { knowledgeCommand } from './commands/knowledge.ts';
|
|
@@ -67,6 +66,7 @@ export function registerBuiltinCommands(registry: CommandRegistry): void {
|
|
|
67
66
|
registerDelegationRuntimeCommands(registry);
|
|
68
67
|
registerConfigCommand(registry);
|
|
69
68
|
registerOperatorRuntimeCommands(registry);
|
|
69
|
+
registry.unregister('profiles');
|
|
70
70
|
registerNotifyRuntimeCommands(registry);
|
|
71
71
|
registerProductRuntimeCommands(registry);
|
|
72
72
|
registerPlatformAccessRuntimeCommands(registry);
|
|
@@ -89,17 +89,12 @@ export function registerBuiltinCommands(registry: CommandRegistry): void {
|
|
|
89
89
|
registerPlanningRuntimeCommands(registry);
|
|
90
90
|
registerScheduleRuntimeCommands(registry);
|
|
91
91
|
registerSessionContentCommands(registry);
|
|
92
|
+
registry.unregister('session-memory');
|
|
92
93
|
registerAgentMemoryCommand(registry);
|
|
93
94
|
|
|
94
|
-
// ── /policy ───────────────────────────────────────────────────────────────
|
|
95
|
-
registry.register(policyCommand);
|
|
96
|
-
|
|
97
95
|
// ── /session ─────────────────────────────────────────────────────────────
|
|
98
96
|
registry.register(sessionCommand);
|
|
99
97
|
|
|
100
|
-
// ── /recall ──────────────────────────────────────────────────────────────
|
|
101
|
-
registry.register(recallCommand);
|
|
102
|
-
|
|
103
98
|
// ── /knowledge ───────────────────────────────────────────────────────────
|
|
104
99
|
registry.register(knowledgeCommand);
|
|
105
100
|
}
|
|
@@ -263,7 +263,7 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
|
|
|
263
263
|
{ text: `Selected TTS readiness: ${readiness.selectedTtsProviderLabel} -> ${readiness.selectedTtsProviderStatus}; voice ${readiness.ttsVoiceConfigured ? 'configured' : 'default'}; response route ${readiness.ttsResponseRouteConfigured ? 'configured' : 'chat route'}.`, fg: readiness.selectedTtsProviderStatus === 'ready' ? PALETTE.good : PALETTE.warn },
|
|
264
264
|
{ text: `Media providers: ${snapshot.mediaProviderCount}; understanding: ${snapshot.mediaUnderstandingProviderCount}; generation: ${snapshot.mediaGenerationProviderCount}.`, fg: PALETTE.info },
|
|
265
265
|
{ text: `Ready media providers: ${readiness.readyMediaProviderCount}/${snapshot.mediaProviderCount}.`, fg: readiness.readyMediaProviderCount > 0 ? PALETTE.good : PALETTE.warn },
|
|
266
|
-
{ text: `Browser
|
|
266
|
+
{ text: `Browser tools: ${readiness.browserToolState}; public base URL ${snapshot.browserToolPublicBaseUrl}.`, fg: snapshot.browserToolExposureEnabled ? PALETTE.warn : PALETTE.muted },
|
|
267
267
|
{ text: readiness.browserToolNextStep, fg: PALETTE.muted },
|
|
268
268
|
{ text: 'Voice provider readiness', fg: PALETTE.title, bold: true },
|
|
269
269
|
);
|
|
@@ -295,7 +295,6 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
|
|
|
295
295
|
{ text: `Active Agent profile: ${snapshot.activeRuntimeProfile}`, fg: PALETTE.info },
|
|
296
296
|
{ text: `Agent profiles under this home: ${snapshot.runtimeProfileCount}`, fg: PALETTE.info },
|
|
297
297
|
{ text: `Starter templates: ${snapshot.runtimeStarterTemplateCount}; local custom: ${snapshot.localStarterTemplateCount}`, fg: PALETTE.info },
|
|
298
|
-
{ text: `Config profiles: ${snapshot.configProfileCount}`, fg: PALETTE.info },
|
|
299
298
|
{ text: `Starter ids: ${snapshot.runtimeStarterTemplates.map((template) => template.id).join(', ') || 'none'}`, fg: PALETTE.info },
|
|
300
299
|
{ text: 'Starter Templates', fg: PALETTE.title, bold: true },
|
|
301
300
|
{ text: `Agent profile root: ${snapshot.runtimeProfileRoot}`, fg: PALETTE.muted },
|
|
@@ -179,48 +179,8 @@ function hasCustomizedWorkspaceDefaults(snapshot: OnboardingSnapshotState): bool
|
|
|
179
179
|
|| !isDeepEqual(snapshot.config.display, DEFAULT_CONFIG.display);
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
function hasAnyServerEnabled(snapshot: OnboardingSnapshotState): boolean {
|
|
183
|
-
return snapshot.bindSettings.daemonEnabled
|
|
184
|
-
|| snapshot.bindSettings.controlPlane.enabled
|
|
185
|
-
|| snapshot.bindSettings.httpListenerEnabled
|
|
186
|
-
|| snapshot.bindSettings.web.enabled;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function isLoopbackHost(host: string | null | undefined): boolean {
|
|
190
|
-
const normalized = (host ?? '').trim().toLowerCase();
|
|
191
|
-
if (normalized.length === 0) return false;
|
|
192
|
-
return normalized === 'localhost'
|
|
193
|
-
|| normalized === '::1'
|
|
194
|
-
|| normalized === '[::1]'
|
|
195
|
-
|| normalized === '0:0:0:0:0:0:0:1'
|
|
196
|
-
|| /^127(?:\.\d{1,3}){3}$/.test(normalized);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function isRemoteBind(hostMode: string, host: string | null | undefined, allowRemote = false): boolean {
|
|
200
|
-
if (hostMode === 'network') return true;
|
|
201
|
-
if (hostMode === 'local') return allowRemote;
|
|
202
|
-
if (hostMode === 'custom') return !isLoopbackHost(host);
|
|
203
|
-
return false;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function hasRemoteDeviceAccess(snapshot: OnboardingSnapshotState): boolean {
|
|
207
|
-
return (
|
|
208
|
-
((snapshot.bindSettings.daemonEnabled || snapshot.bindSettings.controlPlane.enabled)
|
|
209
|
-
&& isRemoteBind(
|
|
210
|
-
snapshot.bindSettings.controlPlane.hostMode,
|
|
211
|
-
snapshot.bindSettings.controlPlane.host,
|
|
212
|
-
snapshot.bindSettings.controlPlane.allowRemote,
|
|
213
|
-
))
|
|
214
|
-
|| (snapshot.bindSettings.web.enabled && isRemoteBind(
|
|
215
|
-
snapshot.bindSettings.web.hostMode,
|
|
216
|
-
snapshot.bindSettings.web.host,
|
|
217
|
-
))
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
182
|
function hasWebhookOrEventIngress(snapshot: OnboardingSnapshotState): boolean {
|
|
222
|
-
return snapshot
|
|
223
|
-
|| hasInboundEventSurface(snapshot)
|
|
183
|
+
return hasInboundEventSurface(snapshot)
|
|
224
184
|
|| snapshot.services.services.some((service) => service.hasWebhookUrl || service.hasSigningSecret || service.hasPublicKey || service.hasAppToken);
|
|
225
185
|
}
|
|
226
186
|
|
|
@@ -262,12 +222,8 @@ function hasAutomationReviewSignals(snapshot: OnboardingSnapshotState): boolean
|
|
|
262
222
|
return hasWebhookOrEventIngress(snapshot);
|
|
263
223
|
}
|
|
264
224
|
|
|
265
|
-
function describeOperatorTerminal(
|
|
266
|
-
|
|
267
|
-
return 'Use GoodVibes Agent as the terminal operator while connecting to existing GoodVibes services. Agent setup does not create new entrypoints.';
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return 'Use GoodVibes Agent as the terminal operator; connection settings are shown only so setup is understandable.';
|
|
225
|
+
function describeOperatorTerminal(): string {
|
|
226
|
+
return 'Use GoodVibes Agent as the terminal operator while connecting to existing GoodVibes services. Agent setup does not create new entrypoints.';
|
|
271
227
|
}
|
|
272
228
|
|
|
273
229
|
function describeProviderAccess(snapshot: OnboardingSnapshotState): string {
|
|
@@ -358,7 +314,7 @@ export function deriveStep1Capabilities(
|
|
|
358
314
|
id: 'operator-terminal',
|
|
359
315
|
label: 'Agent Operator TUI',
|
|
360
316
|
selected: true,
|
|
361
|
-
detail: describeOperatorTerminal(
|
|
317
|
+
detail: describeOperatorTerminal(),
|
|
362
318
|
},
|
|
363
319
|
{
|
|
364
320
|
id: 'provider-access',
|
|
@@ -419,25 +375,8 @@ export function deriveStep1CapabilityFlags(
|
|
|
419
375
|
export function deriveStep1_5NetworkMode(
|
|
420
376
|
bindSettings: Pick<OnboardingSnapshotState, 'bindSettings'>['bindSettings'],
|
|
421
377
|
): OnboardingNetworkMode {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
if (
|
|
426
|
-
(bindSettings.daemonEnabled || bindSettings.controlPlane.enabled)
|
|
427
|
-
&& (!hasNetworkFacingSurface || bindSettings.controlPlane.hostMode !== 'local')
|
|
428
|
-
) {
|
|
429
|
-
activeModes.push(bindSettings.controlPlane.hostMode);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
if (bindSettings.httpListenerEnabled) {
|
|
433
|
-
activeModes.push(bindSettings.httpListener.hostMode);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
if (bindSettings.web.enabled) {
|
|
437
|
-
activeModes.push(bindSettings.web.hostMode);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
return activeModes.some((mode) => mode !== 'network') ? 'custom' : 'local-network-default';
|
|
378
|
+
void bindSettings;
|
|
379
|
+
return 'local-network-default';
|
|
441
380
|
}
|
|
442
381
|
|
|
443
382
|
export function deriveReopenEditAcknowledgementState(
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '0.1.
|
|
9
|
+
let _version = '0.1.112';
|
|
10
10
|
let _sdkVersion = '0.33.35';
|
|
11
11
|
try {
|
|
12
12
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|