@pellux/goodvibes-agent 0.1.3 → 0.1.5

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 CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  All notable changes to GoodVibes Agent will be recorded here.
4
4
 
5
+ ## 0.1.5 - 2026-05-31
6
+
7
+ - Hardened package-facing release checks so shipped docs and Agent guidance cannot reintroduce default Knowledge/Wiki, HomeGraph, Home Assistant, copied TUI daemon, or copied WRFC-first policy text.
8
+ - Removed the generic default `knowledgeApi` client from the active Agent command context so slash commands must use the isolated Agent Knowledge API.
9
+ - Changed CLI `knowledge ingest-url` to post directly to `/api/goodvibes-agent/knowledge/ingest/url` instead of invoking the generic knowledge operator method.
10
+ - Rejected `--space`, `--knowledge-space`, `--knowledgeSpaceId`, `--includeAllSpaces`, and HomeGraph-style flags in CLI and slash Agent Knowledge commands before any daemon call.
11
+
12
+ ## 0.1.4 - 2026-05-31
13
+
14
+ - Hardened Agent Knowledge route isolation for CLI JSON output and diagnostics: Agent status, ask, search, and ingest-url now report explicit `agentKnowledge.*` identities and `/api/goodvibes-agent/knowledge/*` routes.
15
+ - Pointed runtime orchestrator and multimodal writeback dependencies at Agent Knowledge so assistant-authored knowledge cannot land in default Knowledge/Wiki.
16
+ - Moved project planning and work-plan artifacts onto the Agent Knowledge store so Agent task state does not use the regular wiki segment.
17
+
5
18
  ## 0.1.3 - 2026-05-31
6
19
 
7
20
  - Added local Agent personas with `/personas`: create/list/search/show/use/review/stale/delete, secret-looking value rejection, active persona prompt injection, and operator workspace status.
@@ -1,6 +1,6 @@
1
1
  # Getting Started
2
2
 
3
- GoodVibes Agent `0.1.3` is the current installable public alpha of the personal operator assistant built on the GoodVibes TUI foundation.
3
+ GoodVibes Agent `0.1.5` is the current installable public alpha of the personal operator assistant built on the GoodVibes TUI foundation.
4
4
 
5
5
  ## Requirements
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Release And Publishing
2
2
 
3
- GoodVibes Agent `0.1.3` is the current installable public alpha release.
3
+ GoodVibes Agent `0.1.5` is the current installable public alpha release.
4
4
 
5
5
  ## Package Identity
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "private": false,
5
5
  "description": "Near-fork GoodVibes operator assistant with the GoodVibes TUI shell, renderer, input, fullscreen workspace, and daemon-connected Agent product brain.",
6
6
  "type": "module",
@@ -32,6 +32,42 @@ interface AgentKnowledgeSuccess<TData> {
32
32
 
33
33
  type AgentKnowledgeResult<TData> = AgentKnowledgeSuccess<TData> | AgentKnowledgeFailure;
34
34
 
35
+ interface DaemonCallMethod {
36
+ readonly kind: string;
37
+ readonly route: string;
38
+ }
39
+
40
+ const AGENT_KNOWLEDGE_METHODS = {
41
+ status: {
42
+ kind: 'agentKnowledge.status',
43
+ route: '/api/goodvibes-agent/knowledge/status',
44
+ },
45
+ ask: {
46
+ kind: 'agentKnowledge.ask',
47
+ route: '/api/goodvibes-agent/knowledge/ask',
48
+ },
49
+ search: {
50
+ kind: 'agentKnowledge.search',
51
+ route: '/api/goodvibes-agent/knowledge/search',
52
+ },
53
+ ingestUrl: {
54
+ kind: 'agentKnowledge.ingest.url',
55
+ route: '/api/goodvibes-agent/knowledge/ingest/url',
56
+ },
57
+ } as const;
58
+
59
+ const DELEGATION_METHOD = {
60
+ kind: 'sessions.messages.create',
61
+ route: 'sessions.messages.create',
62
+ } as const;
63
+
64
+ interface DelegationResult {
65
+ readonly sessionId: string;
66
+ readonly message: unknown;
67
+ readonly task: string;
68
+ readonly wrfcRequested: boolean;
69
+ }
70
+
35
71
  function isRecord(value: unknown): value is JsonRecord {
36
72
  return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
37
73
  }
@@ -186,6 +222,62 @@ function createAgentSdk(connection: AgentDaemonConnection) {
186
222
  });
187
223
  }
188
224
 
225
+ async function postAgentKnowledgeJson<TData>(
226
+ connection: AgentDaemonConnection,
227
+ route: string,
228
+ body: JsonRecord,
229
+ ): Promise<TData> {
230
+ const response = await fetch(`${connection.baseUrl}${route}`, {
231
+ method: 'POST',
232
+ headers: {
233
+ authorization: `Bearer ${connection.token ?? ''}`,
234
+ 'content-type': 'application/json',
235
+ },
236
+ body: JSON.stringify(body),
237
+ });
238
+ const text = await response.text();
239
+ let parsed: unknown = text;
240
+ if (text.trim()) {
241
+ try {
242
+ parsed = JSON.parse(text) as unknown;
243
+ } catch {
244
+ parsed = text;
245
+ }
246
+ }
247
+ if (!response.ok) {
248
+ const detail = isRecord(parsed) && typeof parsed.error === 'string' ? parsed.error : text;
249
+ throw new Error(`HTTP ${response.status} ${response.statusText}${detail ? `: ${detail}` : ''}`);
250
+ }
251
+ return parsed as TData;
252
+ }
253
+
254
+ function findDisallowedKnowledgeScopeFlag(args: readonly string[]): string | null {
255
+ const disallowed = [
256
+ '--space',
257
+ '--knowledge-space',
258
+ '--knowledge-space-id',
259
+ '--knowledgeSpaceId',
260
+ '--include-all-spaces',
261
+ '--includeAllSpaces',
262
+ '--homegraph',
263
+ '--home-graph',
264
+ ];
265
+ for (const token of args) {
266
+ for (const flag of disallowed) {
267
+ if (token === flag || token.startsWith(`${flag}=`)) return flag;
268
+ }
269
+ }
270
+ return null;
271
+ }
272
+
273
+ function formatScopeFlagRejection(flag: string): string {
274
+ return [
275
+ `Agent Knowledge is isolated; ${flag} is not accepted.`,
276
+ 'GoodVibes Agent must not use default Knowledge/Wiki, HomeGraph, or Home Assistant spaces.',
277
+ 'Use only /api/goodvibes-agent/knowledge/* Agent-owned routes.',
278
+ ].join('\n');
279
+ }
280
+
189
281
  function sourceLine(value: unknown): string {
190
282
  const record = isRecord(value) ? value : {};
191
283
  const title = cleanInline(record.title)
@@ -323,7 +415,7 @@ function formatFailure(failure: AgentKnowledgeFailure, json: boolean): string {
323
415
 
324
416
  async function runKnowledgeCall<TData>(
325
417
  runtime: CliCommandRuntime,
326
- route: string,
418
+ method: DaemonCallMethod,
327
419
  call: (connection: AgentDaemonConnection) => Promise<TData>,
328
420
  ): Promise<AgentKnowledgeResult<TData>> {
329
421
  const connection = resolveDaemonConnection(runtime);
@@ -333,14 +425,14 @@ async function runKnowledgeCall<TData>(
333
425
  kind: 'auth_required',
334
426
  error: `No daemon operator token found at ${connection.tokenPath}`,
335
427
  baseUrl: connection.baseUrl,
336
- route,
428
+ route: method.route,
337
429
  };
338
430
  }
339
431
  try {
340
432
  const data = await call(connection);
341
- return { ok: true, kind: route, route, data };
433
+ return { ok: true, kind: method.kind, route: method.route, data };
342
434
  } catch (error) {
343
- return classifyKnowledgeError(error, connection, route);
435
+ return classifyKnowledgeError(error, connection, method.route);
344
436
  }
345
437
  }
346
438
 
@@ -348,9 +440,22 @@ export async function handleAgentKnowledgeCommand(runtime: CliCommandRuntime): P
348
440
  const [sub = 'status', ...rest] = runtime.cli.commandArgs;
349
441
  const normalized = sub.toLowerCase();
350
442
  const json = runtime.cli.flags.outputFormat === 'json';
443
+ const disallowedScopeFlag = findDisallowedKnowledgeScopeFlag(rest);
444
+ if (disallowedScopeFlag) {
445
+ const failure = {
446
+ ok: false,
447
+ kind: 'agent_knowledge_scope_rejected',
448
+ error: formatScopeFlagRejection(disallowedScopeFlag),
449
+ route: '/api/goodvibes-agent/knowledge/*',
450
+ };
451
+ return {
452
+ output: json ? JSON.stringify(failure, null, 2) : failure.error,
453
+ exitCode: 2,
454
+ };
455
+ }
351
456
 
352
457
  if (normalized === 'status') {
353
- const result = await runKnowledgeCall(runtime, 'knowledge.status', async (connection) => (
458
+ const result = await runKnowledgeCall(runtime, AGENT_KNOWLEDGE_METHODS.status, async (connection) => (
354
459
  await createAgentSdk(connection).knowledge.status()
355
460
  ));
356
461
  if (!result.ok) return { output: formatFailure(result, json), exitCode: 1 };
@@ -366,7 +471,7 @@ export async function handleAgentKnowledgeCommand(runtime: CliCommandRuntime): P
366
471
  const mode = readOptionValue(rest, '--mode');
367
472
  const selectedMode = mode === 'concise' || mode === 'standard' || mode === 'detailed' ? mode : 'standard';
368
473
  const limit = readPositiveInt(rest, '--limit', 8);
369
- const result = await runKnowledgeCall(runtime, 'knowledge.ask', async (connection) => (
474
+ const result = await runKnowledgeCall(runtime, AGENT_KNOWLEDGE_METHODS.ask, async (connection) => (
370
475
  await createAgentSdk(connection).knowledge.ask({
371
476
  query,
372
477
  limit,
@@ -387,7 +492,7 @@ export async function handleAgentKnowledgeCommand(runtime: CliCommandRuntime): P
387
492
  const query = commandValues(rest).join(' ').trim();
388
493
  if (!query) return { output: 'Usage: goodvibes-agent knowledge search <query> [--limit <n>]', exitCode: 2 };
389
494
  const limit = readPositiveInt(rest, '--limit', 10);
390
- const result = await runKnowledgeCall(runtime, 'knowledge.search', async (connection) => (
495
+ const result = await runKnowledgeCall(runtime, AGENT_KNOWLEDGE_METHODS.search, async (connection) => (
391
496
  await createAgentSdk(connection).knowledge.search({ query, limit })
392
497
  ));
393
498
  if (!result.ok) return { output: formatFailure(result, json), exitCode: 1 };
@@ -403,8 +508,8 @@ export async function handleAgentKnowledgeCommand(runtime: CliCommandRuntime): P
403
508
  if (!url) return { output: 'Usage: goodvibes-agent knowledge ingest-url <url> [--title <title>] [--tags a,b]', exitCode: 2 };
404
509
  const title = readOptionValue(rest, '--title');
405
510
  const tags = readStringList(rest, '--tags');
406
- const result = await runKnowledgeCall(runtime, 'knowledge.ingest.url', async (connection) => (
407
- await createAgentSdk(connection).operator.invoke('knowledge.ingest.url', {
511
+ const result = await runKnowledgeCall(runtime, AGENT_KNOWLEDGE_METHODS.ingestUrl, async (connection) => (
512
+ await postAgentKnowledgeJson(connection, AGENT_KNOWLEDGE_METHODS.ingestUrl.route, {
408
513
  url,
409
514
  title,
410
515
  tags,
@@ -432,7 +537,7 @@ export async function handleCompatCommand(runtime: CliCommandRuntime): Promise<C
432
537
  const daemonRecord = isRecord(daemon.body) ? daemon.body : {};
433
538
  const daemonVersion = readString(daemonRecord, 'version') ?? 'unknown';
434
539
  const versionCompatible = daemon.ok && daemonVersion === metadata.sdkVersion;
435
- const knowledgeRoute = await runKnowledgeCall(runtime, 'knowledge.status', async (routeConnection) => (
540
+ const knowledgeRoute = await runKnowledgeCall(runtime, AGENT_KNOWLEDGE_METHODS.status, async (routeConnection) => (
436
541
  await createAgentSdk(routeConnection).knowledge.status()
437
542
  ));
438
543
  const knowledgeRouteReady = knowledgeRoute.ok;
@@ -482,7 +587,7 @@ export async function handleDelegateCommand(runtime: CliCommandRuntime): Promise
482
587
  exitCode: 2,
483
588
  };
484
589
  }
485
- const result = await runKnowledgeCall(runtime, 'sessions.messages.create', async (connection) => {
590
+ const result = await runKnowledgeCall<DelegationResult>(runtime, DELEGATION_METHOD, async (connection) => {
486
591
  const sdk = createAgentSdk(connection);
487
592
  const created = await sdk.operator.invoke('sessions.create', {
488
593
  title: `Agent delegation: ${task.slice(0, 72)}`,
@@ -21,6 +21,10 @@ export interface PackageCliVerificationReport {
21
21
  readonly requiredPathsPresent: readonly string[];
22
22
  readonly forbiddenPaths: readonly string[];
23
23
  };
24
+ readonly packageFacingText: {
25
+ readonly checkedPaths: readonly string[];
26
+ readonly failures: readonly string[];
27
+ };
24
28
  readonly issues: readonly string[];
25
29
  }
26
30
 
@@ -46,6 +50,43 @@ const FORBIDDEN_TARBALL_DOCS = [
46
50
  'docs/homeassistant-surface.md',
47
51
  'docs/wrfc/',
48
52
  ] as const;
53
+ const PACKAGE_FACING_TEXT_PATHS = [
54
+ 'README.md',
55
+ 'docs/README.md',
56
+ 'docs/getting-started.md',
57
+ 'docs/deployment-and-services.md',
58
+ 'docs/release-and-publishing.md',
59
+ '.goodvibes/GOODVIBES.md',
60
+ '.goodvibes/agents/reviewer.md',
61
+ '.goodvibes/skills/add-provider/SKILL.md',
62
+ ] as const;
63
+ const PACKAGE_FACING_FORBIDDEN_TEXT = [
64
+ '/api/knowledge',
65
+ '/api/homeassistant',
66
+ 'homeassistant.homeGraph',
67
+ 'includeAllSpaces',
68
+ 'knowledgeSpaceId',
69
+ '@pellux/goodvibes-tui',
70
+ '@pellux/goodvibes-daemon',
71
+ 'goodvibes-daemon',
72
+ '~/.goodvibes/tui',
73
+ 'Every plan must have a multi-agent execution strategy',
74
+ 'NEVER skip WRFC',
75
+ 'ALWAYS work in parallel when implementing a plan',
76
+ 'PRIMARY GOAL: Fully complete and functional code',
77
+ 'You are a code reviewer for the WRFC',
78
+ 'ReviewerReport',
79
+ '"wrfcId"',
80
+ ] as const;
81
+ const PACKAGE_FACING_REQUIRED_TEXT: readonly {
82
+ readonly path: typeof PACKAGE_FACING_TEXT_PATHS[number];
83
+ readonly required: readonly string[];
84
+ }[] = [
85
+ { path: 'README.md', required: ['/api/goodvibes-agent/knowledge'] },
86
+ { path: 'docs/README.md', required: ['/api/goodvibes-agent/knowledge'] },
87
+ { path: 'docs/getting-started.md', required: ['/api/goodvibes-agent/knowledge'] },
88
+ { path: 'docs/release-and-publishing.md', required: ['/api/goodvibes-agent/knowledge'] },
89
+ ];
49
90
 
50
91
  function readPackageJson(root: string): Record<string, unknown> {
51
92
  return JSON.parse(readFileSync(join(root, 'package.json'), 'utf-8')) as Record<string, unknown>;
@@ -82,6 +123,35 @@ function npmPackDryRun(root: string): { readonly files: readonly string[]; reado
82
123
  };
83
124
  }
84
125
 
126
+ export function verifyPackageFacingText(root: string): { readonly checkedPaths: readonly string[]; readonly failures: readonly string[] } {
127
+ const failures: string[] = [];
128
+ for (const path of PACKAGE_FACING_TEXT_PATHS) {
129
+ const absolutePath = join(root, path);
130
+ if (!existsSync(absolutePath)) {
131
+ failures.push(`package-facing text is missing: ${path}`);
132
+ continue;
133
+ }
134
+ const content = readFileSync(absolutePath, 'utf-8');
135
+ for (const forbidden of PACKAGE_FACING_FORBIDDEN_TEXT) {
136
+ if (content.includes(forbidden)) {
137
+ failures.push(`package-facing text ${path} contains forbidden default/TUI route or policy: ${forbidden}`);
138
+ }
139
+ }
140
+ const requirement = PACKAGE_FACING_REQUIRED_TEXT.find((entry) => entry.path === path);
141
+ if (requirement) {
142
+ for (const required of requirement.required) {
143
+ if (!content.includes(required)) {
144
+ failures.push(`package-facing text ${path} is missing required Agent route/policy text: ${required}`);
145
+ }
146
+ }
147
+ }
148
+ }
149
+ return {
150
+ checkedPaths: PACKAGE_FACING_TEXT_PATHS,
151
+ failures,
152
+ };
153
+ }
154
+
85
155
  export function verifyPackageCliInstall(root: string): PackageCliVerificationReport {
86
156
  const pkg = readPackageJson(root);
87
157
  const bin = pkg.bin && typeof pkg.bin === 'object' ? pkg.bin as Record<string, string | undefined> : {};
@@ -93,6 +163,7 @@ export function verifyPackageCliInstall(root: string): PackageCliVerificationRep
93
163
  return FORBIDDEN_TARBALL_DOCS.some((docPath) => path === docPath || path.startsWith(docPath));
94
164
  });
95
165
  const issues: string[] = [];
166
+ const packageFacingText = verifyPackageFacingText(root);
96
167
 
97
168
  for (const item of bins) {
98
169
  if (!item.target) issues.push(`package.json bin is missing ${item.command}.`);
@@ -107,6 +178,9 @@ export function verifyPackageCliInstall(root: string): PackageCliVerificationRep
107
178
  for (const path of forbiddenPaths) {
108
179
  issues.push(`npm tarball includes forbidden path: ${path}`);
109
180
  }
181
+ for (const failure of packageFacingText.failures) {
182
+ issues.push(failure);
183
+ }
110
184
 
111
185
  return {
112
186
  packageName: String(pkg.name ?? ''),
@@ -118,6 +192,7 @@ export function verifyPackageCliInstall(root: string): PackageCliVerificationRep
118
192
  requiredPathsPresent,
119
193
  forbiddenPaths,
120
194
  },
195
+ packageFacingText,
121
196
  issues,
122
197
  };
123
198
  }
@@ -203,7 +203,6 @@ export interface CommandContext
203
203
  readonly peer?: PeerClient;
204
204
  readonly providerApi?: ProviderApi;
205
205
  readonly agentKnowledgeApi?: KnowledgeApi;
206
- readonly knowledgeApi?: KnowledgeApi;
207
206
  readonly hookApi?: HookApi;
208
207
  readonly mcpApi?: McpApi;
209
208
  readonly opsApi?: OpsApi;
@@ -22,6 +22,33 @@ function readFlag(args: string[], name: string): string | undefined {
22
22
  return index >= 0 ? args[index + 1] : undefined;
23
23
  }
24
24
 
25
+ function findDisallowedKnowledgeScopeFlag(args: readonly string[]): string | null {
26
+ const disallowed = [
27
+ '--space',
28
+ '--knowledge-space',
29
+ '--knowledge-space-id',
30
+ '--knowledgeSpaceId',
31
+ '--include-all-spaces',
32
+ '--includeAllSpaces',
33
+ '--homegraph',
34
+ '--home-graph',
35
+ ];
36
+ for (const token of args) {
37
+ for (const flag of disallowed) {
38
+ if (token === flag || token.startsWith(`${flag}=`)) return flag;
39
+ }
40
+ }
41
+ return null;
42
+ }
43
+
44
+ function printScopeFlagRejection(context: CommandContext, flag: string): void {
45
+ context.print([
46
+ `[knowledge] Agent Knowledge is isolated; ${flag} is not accepted.`,
47
+ '[knowledge] GoodVibes Agent must not use default Knowledge/Wiki, HomeGraph, or Home Assistant spaces.',
48
+ '[knowledge] Use only /api/goodvibes-agent/knowledge/* Agent-owned routes.',
49
+ ].join('\n'));
50
+ }
51
+
25
52
  function readStringListFlag(args: string[], name: string): string[] {
26
53
  const value = readFlag(args, name);
27
54
  if (!value) return [];
@@ -143,6 +170,11 @@ export const knowledgeCommand: SlashCommand = {
143
170
  }
144
171
  const sub = (args[0] ?? 'status').toLowerCase();
145
172
  const rest = args.slice(1);
173
+ const disallowedScopeFlag = findDisallowedKnowledgeScopeFlag(rest);
174
+ if (disallowedScopeFlag) {
175
+ printScopeFlagRejection(context, disallowedScopeFlag);
176
+ return;
177
+ }
146
178
 
147
179
  switch (sub) {
148
180
  case 'ask': {
@@ -154,10 +186,6 @@ export const knowledgeCommand: SlashCommand = {
154
186
  context.print('[knowledge] Usage: /knowledge ask <query> [--limit <n>] [--mode <concise|standard|detailed>]');
155
187
  return;
156
188
  }
157
- if (readFlag(rest, '--space') || readFlag(rest, '--knowledge-space')) {
158
- context.print('[knowledge] Agent Knowledge is isolated. --space/--knowledge-space is not accepted because Agent must not fall back to default Knowledge/Wiki or HomeGraph.');
159
- return;
160
- }
161
189
  const requestedMode = readFlag(rest, '--mode') as KnowledgeAskMode | undefined;
162
190
  const mode: KnowledgeAskMode = requestedMode && ['concise', 'standard', 'detailed'].includes(requestedMode)
163
191
  ? requestedMode
@@ -4,9 +4,10 @@ import type { MemorySearchFilter } from '@pellux/goodvibes-sdk/platform/state';
4
4
  import { VALID_CLASSES, VALID_SCOPES, isValidClass, isValidScope } from './recall-shared.ts';
5
5
 
6
6
  export function getMemoryApi(context: CommandContext): MemoryApi | null {
7
- const memoryApi = context.clients?.knowledgeApi?.memory;
7
+ const memoryApi = context.clients?.agentKnowledgeApi?.memory;
8
8
  if (!memoryApi) {
9
- context.print('[recall] Memory API is not available in this runtime.');
9
+ context.print('[recall] Agent Memory API is not available in this runtime.');
10
+ context.print('[recall] Refusing to use default Knowledge/Wiki or HomeGraph fallback.');
10
11
  return null;
11
12
  }
12
13
  return memoryApi;
@@ -246,8 +246,12 @@ export async function compactConversation(context: CommandContext): Promise<void
246
246
  );
247
247
  }
248
248
 
249
+ export function requireAgentKnowledgeApi(context: CommandContext): KnowledgeApi {
250
+ return requireContextValue(context.clients?.agentKnowledgeApi, 'clients.agentKnowledgeApi');
251
+ }
252
+
249
253
  export function requireKnowledgeApi(context: CommandContext): KnowledgeApi {
250
- return requireContextValue(context.clients?.knowledgeApi, 'clients.knowledgeApi');
254
+ return requireAgentKnowledgeApi(context);
251
255
  }
252
256
 
253
257
  export function requireHookApi(context: CommandContext): HookApi {
@@ -101,7 +101,6 @@ export type CreateBootstrapCommandContextOptions = {
101
101
  operatorClient?: OperatorClient;
102
102
  peerClient?: PeerClient;
103
103
  agentKnowledgeApi?: KnowledgeApi;
104
- knowledgeApi?: KnowledgeApi;
105
104
  hookApi?: HookApi;
106
105
  mcpApi?: McpApi;
107
106
  opsApi?: OpsApi;
@@ -172,7 +171,6 @@ export function createBootstrapCommandContext(
172
171
  operatorClient,
173
172
  peerClient,
174
173
  agentKnowledgeApi,
175
- knowledgeApi,
176
174
  hookApi,
177
175
  mcpApi,
178
176
  opsApi,
@@ -249,7 +247,6 @@ export function createBootstrapCommandContext(
249
247
  peerClient,
250
248
  agentKnowledgeApi,
251
249
  providerApi,
252
- knowledgeApi,
253
250
  hookApi,
254
251
  mcpApi,
255
252
  opsApi,
@@ -118,7 +118,6 @@ export interface BootstrapCommandSectionOptions {
118
118
  readonly peerClient?: PeerClient;
119
119
  readonly providerApi?: ProviderApi;
120
120
  readonly agentKnowledgeApi?: KnowledgeApi;
121
- readonly knowledgeApi?: KnowledgeApi;
122
121
  readonly hookApi?: HookApi;
123
122
  readonly mcpApi?: McpApi;
124
123
  readonly opsApi?: OpsApi;
@@ -373,7 +372,7 @@ export function createBootstrapCommandExtensionsSection(
373
372
  export function createBootstrapCommandClientsSection(
374
373
  options: Pick<
375
374
  BootstrapCommandSectionOptions,
376
- 'operatorClient' | 'peerClient' | 'providerApi' | 'agentKnowledgeApi' | 'knowledgeApi' | 'hookApi' | 'mcpApi' | 'opsApi' | 'directTransport'
375
+ 'operatorClient' | 'peerClient' | 'providerApi' | 'agentKnowledgeApi' | 'hookApi' | 'mcpApi' | 'opsApi' | 'directTransport'
377
376
  >,
378
377
  ): BootstrapCommandClientSection {
379
378
  return {
@@ -381,7 +380,6 @@ export function createBootstrapCommandClientsSection(
381
380
  peer: options.peerClient,
382
381
  providerApi: options.providerApi,
383
382
  agentKnowledgeApi: options.agentKnowledgeApi,
384
- knowledgeApi: options.knowledgeApi,
385
383
  hookApi: options.hookApi,
386
384
  mcpApi: options.mcpApi,
387
385
  opsApi: options.opsApi,
@@ -242,7 +242,7 @@ export async function initializeBootstrapCore(
242
242
  webSearchService: services.webSearchService,
243
243
  channelRegistry: services.channelPlugins,
244
244
  remoteRunnerRegistry: services.remoteRunnerRegistry,
245
- knowledgeService: services.knowledgeService,
245
+ knowledgeService: services.agentKnowledgeService,
246
246
  archetypeLoader: services.archetypeLoader,
247
247
  configManager,
248
248
  providerRegistry: services.providerRegistry,
@@ -172,7 +172,6 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
172
172
  const {
173
173
  directTransport,
174
174
  hookApi,
175
- knowledgeApi,
176
175
  mcpApi,
177
176
  opsApi,
178
177
  providerApi,
@@ -241,7 +240,6 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
241
240
  operatorClient: directTransport.operator,
242
241
  peerClient: directTransport.peer,
243
242
  agentKnowledgeApi,
244
- knowledgeApi: agentKnowledgeApi,
245
243
  hookApi,
246
244
  mcpApi,
247
245
  opsApi,
@@ -440,7 +440,7 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
440
440
  semanticService: homeGraphSemanticService,
441
441
  });
442
442
  const projectPlanningProjectId = projectPlanningProjectIdFromPath(workingDirectory);
443
- const projectPlanningService = new ProjectPlanningService(knowledgeStore, {
443
+ const projectPlanningService = new ProjectPlanningService(agentKnowledgeStore, {
444
444
  defaultProjectId: projectPlanningProjectId,
445
445
  });
446
446
  const workPlanStore = new WorkPlanStore({
@@ -473,7 +473,7 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
473
473
  }));
474
474
  const mediaProviders = new MediaProviderRegistry();
475
475
  ensureBuiltinMediaProviders(mediaProviders, artifactStore, providerRegistry);
476
- const multimodalService = new MultimodalService(artifactStore, mediaProviders, voiceService, knowledgeService);
476
+ const multimodalService = new MultimodalService(artifactStore, mediaProviders, voiceService, agentKnowledgeService);
477
477
  const pluginManager = new PluginManager({
478
478
  pathOptions: {
479
479
  cwd: shellPaths.workingDirectory,
@@ -560,7 +560,7 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
560
560
  webSearchService,
561
561
  channelRegistry: channelPlugins,
562
562
  remoteRunnerRegistry,
563
- knowledgeService,
563
+ knowledgeService: agentKnowledgeService,
564
564
  memoryRegistry,
565
565
  archetypeLoader,
566
566
  configManager,
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.3';
9
+ let _version = '0.1.5';
10
10
  try {
11
11
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8'));
12
12
  _version = pkg.version ?? _version;
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Michael Davis and GoodVibes contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.