@unson/brainbase-mcp 0.2.4 → 0.3.1
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/README.md +17 -12
- package/dist/canonical-edge-builder.d.ts +11 -0
- package/dist/canonical-edge-builder.js +35 -0
- package/dist/canonical-graph.d.ts +9 -0
- package/dist/canonical-graph.js +174 -0
- package/dist/cli.js +134 -32
- package/dist/connected-onboarding.js +45 -11
- package/dist/entity-resolution.d.ts +111 -0
- package/dist/entity-resolution.js +381 -0
- package/dist/graph-diagnosis.d.ts +24 -0
- package/dist/graph-diagnosis.js +129 -0
- package/dist/guided-onboarding.js +4 -4
- package/dist/import-extract.d.ts +8 -3
- package/dist/import-extract.js +142 -17
- package/dist/onboarding.js +7 -5
- package/dist/ontology-migration.d.ts +30 -0
- package/dist/ontology-migration.js +339 -0
- package/dist/ontology-ssot.js +2 -2
- package/dist/ontology.d.ts +101 -3
- package/dist/ontology.js +64 -8
- package/dist/operationalization.js +6 -6
- package/dist/projects.d.ts +3 -1
- package/dist/projects.js +40 -0
- package/dist/relation-registry.d.ts +11 -0
- package/dist/relation-registry.js +66 -0
- package/dist/server.d.ts +86 -2
- package/dist/server.js +158 -9
- package/dist/skills.js +9 -6
- package/dist/ssot.d.ts +16 -0
- package/dist/ssot.js +68 -18
- package/dist/templates.d.ts +110 -2
- package/dist/templates.js +74 -5
- package/dist/tools.d.ts +6 -2
- package/dist/tools.js +184 -147
- package/dist/types.d.ts +52 -1
- package/package.json +4 -3
package/dist/projects.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { buildCanonicalEdge } from './canonical-edge-builder.js';
|
|
1
2
|
export function parseProjectSource(value) {
|
|
2
3
|
const [areaRaw, labelRaw, refRaw] = value.split('|').map((part) => part.trim());
|
|
3
4
|
const area = parseProjectSourceArea(areaRaw);
|
|
@@ -74,6 +75,43 @@ export function buildProjectRegistrationPlan(input) {
|
|
|
74
75
|
tags: ['project', 'principle'],
|
|
75
76
|
updatedAt: now
|
|
76
77
|
}));
|
|
78
|
+
const decisionEntities = decisions.map((decision) => ({
|
|
79
|
+
id: decision.id,
|
|
80
|
+
type: 'decision',
|
|
81
|
+
name: decision.title,
|
|
82
|
+
summary: decision.decision,
|
|
83
|
+
tags: decision.tags,
|
|
84
|
+
metadata: {
|
|
85
|
+
rationale: decision.rationale,
|
|
86
|
+
projectId
|
|
87
|
+
}
|
|
88
|
+
}));
|
|
89
|
+
const canonicalEntities = [
|
|
90
|
+
{ ...projectEntity, type: 'project' },
|
|
91
|
+
...stakeholderEntities.map((entity) => ({ ...entity, type: 'person' })),
|
|
92
|
+
...decisionEntities
|
|
93
|
+
];
|
|
94
|
+
const participationEdges = stakeholders.map((stakeholder) => {
|
|
95
|
+
const personId = `person-${stableHash(stakeholder.person)}`;
|
|
96
|
+
return buildCanonicalEdge({
|
|
97
|
+
fromId: personId,
|
|
98
|
+
relation: 'participates_in',
|
|
99
|
+
toId: projectId,
|
|
100
|
+
role: stakeholder.role,
|
|
101
|
+
context: stakeholder.context,
|
|
102
|
+
provenance: {
|
|
103
|
+
sourceKind: 'onboarding',
|
|
104
|
+
sourceId: `relationship-${stableHash(`${name}|${stakeholder.person}|${stakeholder.context}`)}`
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
const governanceEdges = decisions.map((decision) => buildCanonicalEdge({
|
|
109
|
+
fromId: decision.id,
|
|
110
|
+
relation: 'governs',
|
|
111
|
+
toId: projectId,
|
|
112
|
+
context: decision.decision,
|
|
113
|
+
provenance: { sourceKind: 'onboarding', sourceId: decision.id }
|
|
114
|
+
}));
|
|
77
115
|
return {
|
|
78
116
|
goal: 'Review project registration before promoting it into canonical Brainbase SSOT.',
|
|
79
117
|
canonicalWrites: false,
|
|
@@ -91,6 +129,8 @@ export function buildProjectRegistrationPlan(input) {
|
|
|
91
129
|
stakeholders,
|
|
92
130
|
writes: {
|
|
93
131
|
graphEntities: [projectEntity, ...stakeholderEntities],
|
|
132
|
+
canonicalEntities,
|
|
133
|
+
canonicalEdges: [...participationEdges, ...governanceEdges],
|
|
94
134
|
relationships,
|
|
95
135
|
personalKg,
|
|
96
136
|
decisions
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CanonicalEntityKind, CoreRelation } from './types.js';
|
|
2
|
+
export interface CanonicalRelationDefinition {
|
|
3
|
+
id: CoreRelation;
|
|
4
|
+
from: CanonicalEntityKind;
|
|
5
|
+
to: CanonicalEntityKind;
|
|
6
|
+
meaning: string;
|
|
7
|
+
scopeTraversal: 'none' | 'project_direct' | 'project_transitive';
|
|
8
|
+
traversalDirection: 'none' | 'forward' | 'reverse';
|
|
9
|
+
}
|
|
10
|
+
export declare const canonicalRelationRegistry: Readonly<Record<CoreRelation, Readonly<CanonicalRelationDefinition>>>;
|
|
11
|
+
export declare function getCanonicalRelation(relation: string): Readonly<CanonicalRelationDefinition>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const definitions = {
|
|
2
|
+
member_of: {
|
|
3
|
+
id: 'member_of',
|
|
4
|
+
from: 'person',
|
|
5
|
+
to: 'org',
|
|
6
|
+
meaning: 'A person is a member of an organization.',
|
|
7
|
+
scopeTraversal: 'none',
|
|
8
|
+
traversalDirection: 'none'
|
|
9
|
+
},
|
|
10
|
+
participates_in: {
|
|
11
|
+
id: 'participates_in',
|
|
12
|
+
from: 'person',
|
|
13
|
+
to: 'project',
|
|
14
|
+
meaning: 'A person participates in a project.',
|
|
15
|
+
scopeTraversal: 'project_direct',
|
|
16
|
+
traversalDirection: 'forward'
|
|
17
|
+
},
|
|
18
|
+
accountable_for: {
|
|
19
|
+
id: 'accountable_for',
|
|
20
|
+
from: 'person',
|
|
21
|
+
to: 'project',
|
|
22
|
+
meaning: 'A person is accountable for a project outcome or decision.',
|
|
23
|
+
scopeTraversal: 'project_direct',
|
|
24
|
+
traversalDirection: 'forward'
|
|
25
|
+
},
|
|
26
|
+
owned_by: {
|
|
27
|
+
id: 'owned_by',
|
|
28
|
+
from: 'project',
|
|
29
|
+
to: 'org',
|
|
30
|
+
meaning: 'A project is owned by an organization.',
|
|
31
|
+
scopeTraversal: 'project_direct',
|
|
32
|
+
traversalDirection: 'reverse'
|
|
33
|
+
},
|
|
34
|
+
governs: {
|
|
35
|
+
id: 'governs',
|
|
36
|
+
from: 'decision',
|
|
37
|
+
to: 'project',
|
|
38
|
+
meaning: 'A durable decision or principle governs a project.',
|
|
39
|
+
scopeTraversal: 'project_direct',
|
|
40
|
+
traversalDirection: 'forward'
|
|
41
|
+
},
|
|
42
|
+
supersedes: {
|
|
43
|
+
id: 'supersedes',
|
|
44
|
+
from: 'decision',
|
|
45
|
+
to: 'decision',
|
|
46
|
+
meaning: 'A durable decision explicitly supersedes another decision.',
|
|
47
|
+
scopeTraversal: 'project_transitive',
|
|
48
|
+
traversalDirection: 'forward'
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
export const canonicalRelationRegistry = deepFreeze(definitions);
|
|
52
|
+
export function getCanonicalRelation(relation) {
|
|
53
|
+
const definition = canonicalRelationRegistry[relation];
|
|
54
|
+
if (!definition) {
|
|
55
|
+
throw new Error(`ONTOLOGY-RELATION-UNKNOWN: unsupported canonical relation ${JSON.stringify(relation)}`);
|
|
56
|
+
}
|
|
57
|
+
return definition;
|
|
58
|
+
}
|
|
59
|
+
function deepFreeze(value) {
|
|
60
|
+
if (value && typeof value === 'object' && !Object.isFrozen(value)) {
|
|
61
|
+
Object.freeze(value);
|
|
62
|
+
for (const nested of Object.values(value))
|
|
63
|
+
deepFreeze(nested);
|
|
64
|
+
}
|
|
65
|
+
return value;
|
|
66
|
+
}
|
package/dist/server.d.ts
CHANGED
|
@@ -8,6 +8,15 @@ export declare const toolDefinitions: readonly [{
|
|
|
8
8
|
readonly dataDir: {
|
|
9
9
|
readonly type: "string";
|
|
10
10
|
};
|
|
11
|
+
readonly project: {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
readonly description: "Optional canonical project ID, name, or alias.";
|
|
14
|
+
};
|
|
15
|
+
readonly as_of: {
|
|
16
|
+
readonly type: "string";
|
|
17
|
+
readonly format: "date-time";
|
|
18
|
+
readonly description: "RFC 3339 validity instant. Defaults to now.";
|
|
19
|
+
};
|
|
11
20
|
};
|
|
12
21
|
};
|
|
13
22
|
}, {
|
|
@@ -40,6 +49,15 @@ export declare const toolDefinitions: readonly [{
|
|
|
40
49
|
readonly limit: {
|
|
41
50
|
readonly type: "number";
|
|
42
51
|
};
|
|
52
|
+
readonly project: {
|
|
53
|
+
readonly type: "string";
|
|
54
|
+
readonly description: "Optional canonical project ID, name, or alias.";
|
|
55
|
+
};
|
|
56
|
+
readonly as_of: {
|
|
57
|
+
readonly type: "string";
|
|
58
|
+
readonly format: "date-time";
|
|
59
|
+
readonly description: "RFC 3339 validity instant. Defaults to now.";
|
|
60
|
+
};
|
|
43
61
|
};
|
|
44
62
|
};
|
|
45
63
|
}, {
|
|
@@ -380,7 +398,7 @@ export declare const toolDefinitions: readonly [{
|
|
|
380
398
|
readonly type: "string";
|
|
381
399
|
};
|
|
382
400
|
readonly ontologyVersion: {
|
|
383
|
-
readonly enum: readonly ["0.0.0", "1.0.0"];
|
|
401
|
+
readonly enum: readonly ["0.0.0", "1.0.0", "2.0.0"];
|
|
384
402
|
};
|
|
385
403
|
};
|
|
386
404
|
};
|
|
@@ -398,7 +416,7 @@ export declare const toolDefinitions: readonly [{
|
|
|
398
416
|
readonly format: "date-time";
|
|
399
417
|
};
|
|
400
418
|
readonly ontologyVersion: {
|
|
401
|
-
readonly enum: readonly ["0.0.0", "1.0.0"];
|
|
419
|
+
readonly enum: readonly ["0.0.0", "1.0.0", "2.0.0"];
|
|
402
420
|
};
|
|
403
421
|
};
|
|
404
422
|
};
|
|
@@ -413,6 +431,72 @@ export declare const toolDefinitions: readonly [{
|
|
|
413
431
|
};
|
|
414
432
|
};
|
|
415
433
|
};
|
|
434
|
+
}, {
|
|
435
|
+
readonly name: "resolve_entity";
|
|
436
|
+
readonly description: "Resolve mentions in text to canonical Graph v2 entity IDs and return a privacy-safe evidence receipt.";
|
|
437
|
+
readonly inputSchema: {
|
|
438
|
+
readonly type: "object";
|
|
439
|
+
readonly required: readonly ["text", "asOf"];
|
|
440
|
+
readonly additionalProperties: false;
|
|
441
|
+
readonly properties: {
|
|
442
|
+
readonly dataDir: {
|
|
443
|
+
readonly type: "string";
|
|
444
|
+
readonly description: "Optional Personal OS directory.";
|
|
445
|
+
};
|
|
446
|
+
readonly text: {
|
|
447
|
+
readonly type: "string";
|
|
448
|
+
readonly description: "Text whose entity mentions should be resolved. The text is hashed, not stored in the receipt.";
|
|
449
|
+
};
|
|
450
|
+
readonly asOf: {
|
|
451
|
+
readonly type: "string";
|
|
452
|
+
readonly format: "date-time";
|
|
453
|
+
readonly description: "RFC 3339 instant used for temporal entity and edge validity.";
|
|
454
|
+
};
|
|
455
|
+
readonly mentionSpans: {
|
|
456
|
+
readonly type: "array";
|
|
457
|
+
readonly items: {
|
|
458
|
+
readonly type: "object";
|
|
459
|
+
readonly required: readonly ["start", "end"];
|
|
460
|
+
readonly additionalProperties: false;
|
|
461
|
+
readonly properties: {
|
|
462
|
+
readonly start: {
|
|
463
|
+
readonly type: "integer";
|
|
464
|
+
readonly minimum: 0;
|
|
465
|
+
};
|
|
466
|
+
readonly end: {
|
|
467
|
+
readonly type: "integer";
|
|
468
|
+
readonly minimum: 1;
|
|
469
|
+
};
|
|
470
|
+
};
|
|
471
|
+
};
|
|
472
|
+
};
|
|
473
|
+
readonly projectScope: {
|
|
474
|
+
readonly type: "object";
|
|
475
|
+
readonly required: readonly ["projectIds"];
|
|
476
|
+
readonly additionalProperties: false;
|
|
477
|
+
readonly properties: {
|
|
478
|
+
readonly projectIds: {
|
|
479
|
+
readonly type: "array";
|
|
480
|
+
readonly minItems: 1;
|
|
481
|
+
readonly items: {
|
|
482
|
+
readonly type: "string";
|
|
483
|
+
readonly minLength: 1;
|
|
484
|
+
};
|
|
485
|
+
};
|
|
486
|
+
readonly policy: {
|
|
487
|
+
readonly enum: readonly ["strict", "prefer_project", "allow_global_fallback"];
|
|
488
|
+
};
|
|
489
|
+
};
|
|
490
|
+
};
|
|
491
|
+
readonly entityTypes: {
|
|
492
|
+
readonly type: "array";
|
|
493
|
+
readonly minItems: 1;
|
|
494
|
+
readonly items: {
|
|
495
|
+
readonly enum: readonly ["person", "org", "project", "decision"];
|
|
496
|
+
};
|
|
497
|
+
};
|
|
498
|
+
};
|
|
499
|
+
};
|
|
416
500
|
}];
|
|
417
501
|
export declare function callBrainbaseTool(name: string, rawArgs?: unknown): Promise<unknown>;
|
|
418
502
|
export declare function createServer(): Server;
|
package/dist/server.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
1
4
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
5
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
6
|
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
4
7
|
import { z } from 'zod';
|
|
5
8
|
import { ConnectedOnboardingRuntime } from './connected-onboarding.js';
|
|
9
|
+
import { validateCanonicalGraph } from './canonical-graph.js';
|
|
10
|
+
import { resolveText } from './entity-resolution.js';
|
|
6
11
|
import { resolveDataDir } from './paths.js';
|
|
7
12
|
import { auditPersonalOsDirectory } from './ontology-ssot.js';
|
|
8
13
|
import { getOntologyImpact, inferPersonalOs, portableOntology, resolveOntologyVersion } from './ontology.js';
|
|
@@ -15,7 +20,34 @@ const argsSchema = z.object({
|
|
|
15
20
|
type: z.enum(['person', 'org', 'project', 'relationship', 'decision']).optional(),
|
|
16
21
|
fromVersion: z.string().optional(),
|
|
17
22
|
ontologyVersion: z.string().optional(),
|
|
18
|
-
asOf: z.string().datetime({ offset: true }).optional()
|
|
23
|
+
asOf: z.string().datetime({ offset: true }).optional(),
|
|
24
|
+
project: z.string().min(1).optional(),
|
|
25
|
+
as_of: z.string().datetime({ offset: true }).optional()
|
|
26
|
+
});
|
|
27
|
+
const mentionSpanSchema = z.object({
|
|
28
|
+
start: z.number().int().nonnegative(),
|
|
29
|
+
end: z.number().int().positive()
|
|
30
|
+
}).strict().refine((span) => span.end > span.start, { message: 'mention span end must be after start' });
|
|
31
|
+
const resolveEntitySchema = z.object({
|
|
32
|
+
dataDir: z.string().optional(),
|
|
33
|
+
text: z.string(),
|
|
34
|
+
asOf: z.string().datetime({ offset: true }),
|
|
35
|
+
mentionSpans: z.array(mentionSpanSchema).optional(),
|
|
36
|
+
projectScope: z.object({
|
|
37
|
+
projectIds: z.array(z.string().min(1)).min(1),
|
|
38
|
+
policy: z.enum(['strict', 'prefer_project', 'allow_global_fallback']).optional()
|
|
39
|
+
}).strict().optional(),
|
|
40
|
+
entityTypes: z.array(z.enum(['person', 'org', 'project', 'decision'])).min(1).optional()
|
|
41
|
+
}).strict().superRefine((value, context) => {
|
|
42
|
+
for (const [index, span] of (value.mentionSpans ?? []).entries()) {
|
|
43
|
+
if (span.end > value.text.length) {
|
|
44
|
+
context.addIssue({
|
|
45
|
+
code: z.ZodIssueCode.custom,
|
|
46
|
+
path: ['mentionSpans', index, 'end'],
|
|
47
|
+
message: 'mention span must be within text'
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
19
51
|
});
|
|
20
52
|
const sourceInventorySchema = z.object({
|
|
21
53
|
id: z.string(),
|
|
@@ -89,7 +121,9 @@ export const toolDefinitions = [
|
|
|
89
121
|
inputSchema: {
|
|
90
122
|
type: 'object',
|
|
91
123
|
properties: {
|
|
92
|
-
dataDir: { type: 'string' }
|
|
124
|
+
dataDir: { type: 'string' },
|
|
125
|
+
project: { type: 'string', description: 'Optional canonical project ID, name, or alias.' },
|
|
126
|
+
as_of: { type: 'string', format: 'date-time', description: 'RFC 3339 validity instant. Defaults to now.' }
|
|
93
127
|
}
|
|
94
128
|
}
|
|
95
129
|
},
|
|
@@ -113,7 +147,9 @@ export const toolDefinitions = [
|
|
|
113
147
|
properties: {
|
|
114
148
|
dataDir: { type: 'string' },
|
|
115
149
|
query: { type: 'string' },
|
|
116
|
-
limit: { type: 'number' }
|
|
150
|
+
limit: { type: 'number' },
|
|
151
|
+
project: { type: 'string', description: 'Optional canonical project ID, name, or alias.' },
|
|
152
|
+
as_of: { type: 'string', format: 'date-time', description: 'RFC 3339 validity instant. Defaults to now.' }
|
|
117
153
|
}
|
|
118
154
|
}
|
|
119
155
|
},
|
|
@@ -230,7 +266,7 @@ export const toolDefinitions = [
|
|
|
230
266
|
type: 'object',
|
|
231
267
|
properties: {
|
|
232
268
|
dataDir: { type: 'string' },
|
|
233
|
-
ontologyVersion: { enum: ['0.0.0', '1.0.0'] }
|
|
269
|
+
ontologyVersion: { enum: ['0.0.0', '1.0.0', '2.0.0'] }
|
|
234
270
|
}
|
|
235
271
|
}
|
|
236
272
|
},
|
|
@@ -242,7 +278,7 @@ export const toolDefinitions = [
|
|
|
242
278
|
properties: {
|
|
243
279
|
dataDir: { type: 'string' },
|
|
244
280
|
asOf: { type: 'string', format: 'date-time' },
|
|
245
|
-
ontologyVersion: { enum: ['0.0.0', '1.0.0'] }
|
|
281
|
+
ontologyVersion: { enum: ['0.0.0', '1.0.0', '2.0.0'] }
|
|
246
282
|
}
|
|
247
283
|
}
|
|
248
284
|
},
|
|
@@ -255,12 +291,52 @@ export const toolDefinitions = [
|
|
|
255
291
|
fromVersion: { type: 'string' }
|
|
256
292
|
}
|
|
257
293
|
}
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
name: 'resolve_entity',
|
|
297
|
+
description: 'Resolve mentions in text to canonical Graph v2 entity IDs and return a privacy-safe evidence receipt.',
|
|
298
|
+
inputSchema: {
|
|
299
|
+
type: 'object',
|
|
300
|
+
required: ['text', 'asOf'],
|
|
301
|
+
additionalProperties: false,
|
|
302
|
+
properties: {
|
|
303
|
+
dataDir: { type: 'string', description: 'Optional Personal OS directory.' },
|
|
304
|
+
text: { type: 'string', description: 'Text whose entity mentions should be resolved. The text is hashed, not stored in the receipt.' },
|
|
305
|
+
asOf: { type: 'string', format: 'date-time', description: 'RFC 3339 instant used for temporal entity and edge validity.' },
|
|
306
|
+
mentionSpans: {
|
|
307
|
+
type: 'array',
|
|
308
|
+
items: {
|
|
309
|
+
type: 'object',
|
|
310
|
+
required: ['start', 'end'],
|
|
311
|
+
additionalProperties: false,
|
|
312
|
+
properties: { start: { type: 'integer', minimum: 0 }, end: { type: 'integer', minimum: 1 } }
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
projectScope: {
|
|
316
|
+
type: 'object',
|
|
317
|
+
required: ['projectIds'],
|
|
318
|
+
additionalProperties: false,
|
|
319
|
+
properties: {
|
|
320
|
+
projectIds: { type: 'array', minItems: 1, items: { type: 'string', minLength: 1 } },
|
|
321
|
+
policy: { enum: ['strict', 'prefer_project', 'allow_global_fallback'] }
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
entityTypes: {
|
|
325
|
+
type: 'array',
|
|
326
|
+
minItems: 1,
|
|
327
|
+
items: { enum: ['person', 'org', 'project', 'decision'] }
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
258
331
|
}
|
|
259
332
|
];
|
|
260
333
|
export async function callBrainbaseTool(name, rawArgs = {}) {
|
|
261
334
|
if (name in connectedSchemas) {
|
|
262
335
|
return callConnectedOnboardingTool(name, rawArgs);
|
|
263
336
|
}
|
|
337
|
+
if (name === 'resolve_entity') {
|
|
338
|
+
return callResolveEntityTool(rawArgs);
|
|
339
|
+
}
|
|
264
340
|
const args = argsSchema.parse(rawArgs ?? {});
|
|
265
341
|
const dataDir = resolveDataDir(args.dataDir);
|
|
266
342
|
switch (name) {
|
|
@@ -316,21 +392,25 @@ export async function callBrainbaseTool(name, rawArgs = {}) {
|
|
|
316
392
|
...portableOntology
|
|
317
393
|
};
|
|
318
394
|
case 'audit_ontology':
|
|
319
|
-
return auditPersonalOsDirectory(dataDir, {
|
|
395
|
+
return auditPersonalOsDirectory(dataDir, {
|
|
396
|
+
ontologyVersion: args.ontologyVersion === undefined
|
|
397
|
+
? undefined
|
|
398
|
+
: resolveOntologyVersion(args.ontologyVersion)
|
|
399
|
+
});
|
|
320
400
|
case 'ontology_impact':
|
|
321
401
|
return getOntologyImpact(args.fromVersion);
|
|
322
402
|
}
|
|
323
403
|
const os = await loadPersonalOs(dataDir);
|
|
324
404
|
switch (name) {
|
|
325
405
|
case 'get_context':
|
|
326
|
-
return getContext(os);
|
|
406
|
+
return getContext(os, { project: args.project, asOf: args.as_of ?? args.asOf });
|
|
327
407
|
case 'list_entities':
|
|
328
408
|
return listEntities(os, args.type);
|
|
329
409
|
case 'search':
|
|
330
410
|
if (!args.query) {
|
|
331
411
|
throw new Error('search requires query');
|
|
332
412
|
}
|
|
333
|
-
return { results: searchAll(os, args.query, args.limit) };
|
|
413
|
+
return { results: searchAll(os, args.query, args.limit, { project: args.project, asOf: args.as_of ?? args.asOf }) };
|
|
334
414
|
case 'search_personal_kg':
|
|
335
415
|
if (!args.query) {
|
|
336
416
|
throw new Error('search_personal_kg requires query');
|
|
@@ -341,12 +421,81 @@ export async function callBrainbaseTool(name, rawArgs = {}) {
|
|
|
341
421
|
case 'infer_decisions':
|
|
342
422
|
return inferPersonalOs(os, {
|
|
343
423
|
asOf: args.asOf,
|
|
344
|
-
ontologyVersion:
|
|
424
|
+
ontologyVersion: args.ontologyVersion === undefined
|
|
425
|
+
? undefined
|
|
426
|
+
: resolveOntologyVersion(args.ontologyVersion)
|
|
345
427
|
});
|
|
346
428
|
default:
|
|
347
429
|
throw new Error(`Unknown tool: ${name}`);
|
|
348
430
|
}
|
|
349
431
|
}
|
|
432
|
+
async function callResolveEntityTool(rawArgs) {
|
|
433
|
+
const args = resolveEntitySchema.parse(rawArgs ?? {});
|
|
434
|
+
const dataDir = resolveDataDir(args.dataDir);
|
|
435
|
+
const graphPath = join(dataDir, 'graph.json');
|
|
436
|
+
let serialized;
|
|
437
|
+
try {
|
|
438
|
+
serialized = await readFile(graphPath, 'utf8');
|
|
439
|
+
}
|
|
440
|
+
catch {
|
|
441
|
+
return blockedResolution(args, 'unavailable', 'graph_unavailable');
|
|
442
|
+
}
|
|
443
|
+
let graph;
|
|
444
|
+
try {
|
|
445
|
+
graph = JSON.parse(serialized);
|
|
446
|
+
}
|
|
447
|
+
catch {
|
|
448
|
+
return blockedResolution(args, 'invalid', 'graph_invalid');
|
|
449
|
+
}
|
|
450
|
+
try {
|
|
451
|
+
validateCanonicalGraph(graph);
|
|
452
|
+
}
|
|
453
|
+
catch {
|
|
454
|
+
return blockedResolution(args, 'invalid', 'graph_invalid');
|
|
455
|
+
}
|
|
456
|
+
if (isGraphVersion(graph, 1)) {
|
|
457
|
+
return {
|
|
458
|
+
status: 'migration_required',
|
|
459
|
+
graphSchemaVersion: 1,
|
|
460
|
+
requiredAction: 'migrate_graph_v2'
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
if (!isGraphVersion(graph, 2)) {
|
|
464
|
+
return blockedResolution(args, 'invalid', 'graph_invalid');
|
|
465
|
+
}
|
|
466
|
+
const receipt = resolveText({
|
|
467
|
+
text: args.text,
|
|
468
|
+
...(args.mentionSpans ? { mentionSpans: args.mentionSpans } : {}),
|
|
469
|
+
...(args.projectScope ? { projectScope: args.projectScope } : {}),
|
|
470
|
+
asOf: args.asOf,
|
|
471
|
+
...(args.entityTypes ? { entityTypes: args.entityTypes } : {}),
|
|
472
|
+
source: {
|
|
473
|
+
authority: 'local_graph',
|
|
474
|
+
status: 'complete',
|
|
475
|
+
revision: createHash('sha256').update(serialized).digest('hex'),
|
|
476
|
+
graph: graph
|
|
477
|
+
}
|
|
478
|
+
}).receipt;
|
|
479
|
+
return { status: 'verified', receipt };
|
|
480
|
+
}
|
|
481
|
+
function blockedResolution(args, sourceStatus, issueCode) {
|
|
482
|
+
const receipt = resolveText({
|
|
483
|
+
text: args.text,
|
|
484
|
+
...(args.mentionSpans ? { mentionSpans: args.mentionSpans } : {}),
|
|
485
|
+
...(args.projectScope ? { projectScope: args.projectScope } : {}),
|
|
486
|
+
asOf: args.asOf,
|
|
487
|
+
...(args.entityTypes ? { entityTypes: args.entityTypes } : {}),
|
|
488
|
+
source: {
|
|
489
|
+
authority: 'local_graph',
|
|
490
|
+
status: sourceStatus,
|
|
491
|
+
issues: [{ code: issueCode, message: issueCode }]
|
|
492
|
+
}
|
|
493
|
+
}).receipt;
|
|
494
|
+
return { status: 'unverified', receipt };
|
|
495
|
+
}
|
|
496
|
+
function isGraphVersion(graph, version) {
|
|
497
|
+
return Boolean(graph && typeof graph === 'object' && 'version' in graph && graph.version === version);
|
|
498
|
+
}
|
|
350
499
|
async function callConnectedOnboardingTool(name, rawArgs) {
|
|
351
500
|
const schema = connectedSchemas[name];
|
|
352
501
|
const args = schema.parse(rawArgs ?? {});
|
package/dist/skills.js
CHANGED
|
@@ -27,11 +27,14 @@ const SKILL_DEFINITIONS = {
|
|
|
27
27
|
'2. `brainbase onboard:start --target codex|claude|codecode` を実行し、本人、プロジェクト、関係者、判断基準の最小候補を確認する。',
|
|
28
28
|
'3. ユーザーが明示的に承認した事実だけを `brainbase onboard:seed` で保存する。',
|
|
29
29
|
'4. `brainbase onboard:install --target codex|claude|codecode --dry-run` でMCP設定を確認し、承認後に実設定へ反映して対象エージェントを再起動する。',
|
|
30
|
-
'5. 新しい実際のエージェントで、Brainbaseの `get_context
|
|
31
|
-
'6.
|
|
32
|
-
'7.
|
|
33
|
-
'8.
|
|
34
|
-
'9.
|
|
30
|
+
'5. 新しい実際のエージェントで、Brainbaseの `resolve_entity`、`get_context`、`search` を使うよう明示して最初の現実の依頼を実行する。',
|
|
31
|
+
'6. 内部準備の宣言を挟まず、利用者向け回答の先頭を「覚えていたこと」にする。続けて「つながったこと」「次にできること」の3節を短い箇条書きで示す。確認済みの事実と未確認事項は混ぜず、初回表示に表は使わない。',
|
|
32
|
+
'7. 正規ID、関係経路、Receipt digest、生のtool trace、source file名は「詳細」に分け、ホストが対応する場合は折りたたむ。利用者が求めない限り初回の本文へ並べない。',
|
|
33
|
+
'8. 内部Skillの読み込み、検索の再試行、tool orchestrationは説明しない。失敗によって結果や次の行動が変わる場合だけ示す。',
|
|
34
|
+
'9. その実回答について本人に役立ったかを確認する。取得開始からここまでを10分以内の初回価値候補ジャーニーとして測る。',
|
|
35
|
+
'10. CLIの `onboard:demo` は必要なら接続前のプレビューに使えるが、CLIサンプルは初回価値の達成証拠にしない。',
|
|
36
|
+
'11. 本人が役立つと確認した後だけ、必要に応じてsource診断、追加候補、Skills、ルーティンへ進む。',
|
|
37
|
+
'12. 継続利用するプロジェクトの詳細が必要なら、本人確認後に `brainbase onboard:projects --write` で登録する。',
|
|
35
38
|
'',
|
|
36
39
|
'## 安全ルール',
|
|
37
40
|
'',
|
|
@@ -113,7 +116,7 @@ const SKILL_DEFINITIONS = {
|
|
|
113
116
|
'3. どの候補idを承認、却下、修正するかをユーザーに確認する。',
|
|
114
117
|
'4. まず `brainbase onboard:apply --from <candidate-file> --select <id>` でdry-runする。手入力の事実には `brainbase onboard:seed` を使う。',
|
|
115
118
|
'5. `--write` は明示的な承認後にだけ使い、canonical filesへ書き込む。',
|
|
116
|
-
'6. `brainbase doctor`
|
|
119
|
+
'6. `brainbase doctor` を実行し、Brainbase MCPの `resolve_entity`、`get_context`、`search` で承認済み事実と正規ID接続が見えることを確認する。',
|
|
117
120
|
'',
|
|
118
121
|
'## 安全ルール',
|
|
119
122
|
'',
|
package/dist/ssot.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CanonicalGraphMigrationPlan } from './ontology-migration.js';
|
|
1
2
|
import type { PersonalOs } from './types.js';
|
|
2
3
|
export declare function initializePersonalOs(dataDir: string): Promise<void>;
|
|
3
4
|
export declare function loadPersonalOs(dataDir: string): Promise<PersonalOs>;
|
|
@@ -11,3 +12,18 @@ export declare function mutatePersonalOsWithSidecar<T>(dataDir: string, sidecarP
|
|
|
11
12
|
sidecarContent: string;
|
|
12
13
|
result: T;
|
|
13
14
|
}>): Promise<T>;
|
|
15
|
+
export type CanonicalGraphMigrationExecution = CanonicalGraphMigrationPlan & {
|
|
16
|
+
expectedInputDigest: string;
|
|
17
|
+
written: boolean;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Plans or atomically applies the canonical Graph migration.
|
|
21
|
+
*
|
|
22
|
+
* The input is always recovered, read, and planned while holding the same
|
|
23
|
+
* lock used by every canonical SSOT writer. Omitting `write` is a byte-safe
|
|
24
|
+
* preview; a blocked or already-current plan is never committed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function migrateCanonicalGraph(dataDir: string, options?: {
|
|
27
|
+
write?: boolean;
|
|
28
|
+
expectedInputDigest?: string;
|
|
29
|
+
}): Promise<CanonicalGraphMigrationExecution>;
|