toolnet-memory 0.2.21 → 0.3.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.
@@ -0,0 +1,185 @@
1
+ export class ToolNetApiClient {
2
+ baseUrl;
3
+ token;
4
+ principal;
5
+ timeoutMs;
6
+ constructor(options) {
7
+ this.baseUrl = options.baseUrl.replace(/\/+$/u, '');
8
+ this.token = options.token;
9
+ this.principal = options.principal;
10
+ this.timeoutMs = options.timeoutMs ?? 10_000;
11
+ }
12
+ health() {
13
+ return this.request('/v1/health');
14
+ }
15
+ project() {
16
+ return this.request('/v1/project');
17
+ }
18
+ memoryAsk(input) {
19
+ return this.request('/v1/memory/ask', {
20
+ method: 'POST',
21
+ body: JSON.stringify(input),
22
+ });
23
+ }
24
+ memorySearch(input) {
25
+ return this.request('/v1/memory/search', {
26
+ method: 'POST',
27
+ body: JSON.stringify(input),
28
+ });
29
+ }
30
+ skillSearch(input) {
31
+ return this.request('/v1/skills/search', {
32
+ method: 'POST',
33
+ body: JSON.stringify(input),
34
+ });
35
+ }
36
+ offloadRead(input) {
37
+ return this.request('/v1/offload/read', {
38
+ method: 'POST',
39
+ body: JSON.stringify(input),
40
+ });
41
+ }
42
+ hub() {
43
+ return this.request('/v1/hub');
44
+ }
45
+ hubTeams() {
46
+ return this.request('/v1/hub/teams');
47
+ }
48
+ createHubTeam(input) {
49
+ return this.request('/v1/hub/teams', {
50
+ method: 'POST',
51
+ body: JSON.stringify(input),
52
+ });
53
+ }
54
+ hubAgents() {
55
+ return this.request('/v1/hub/agents');
56
+ }
57
+ createHubAgent(input) {
58
+ return this.request('/v1/hub/agents', {
59
+ method: 'POST',
60
+ body: JSON.stringify(input),
61
+ });
62
+ }
63
+ hubAcl() {
64
+ return this.request('/v1/hub/acl');
65
+ }
66
+ grantHubAcl(input) {
67
+ return this.request('/v1/hub/acl/grant', {
68
+ method: 'POST',
69
+ body: JSON.stringify(input),
70
+ });
71
+ }
72
+ revokeHubAcl(principal) {
73
+ return this.request('/v1/hub/acl/revoke', {
74
+ method: 'POST',
75
+ body: JSON.stringify({ principal }),
76
+ });
77
+ }
78
+ hubLoadouts() {
79
+ return this.request('/v1/hub/loadouts');
80
+ }
81
+ setHubLoadout(input) {
82
+ return this.request('/v1/hub/loadouts', {
83
+ method: 'POST',
84
+ body: JSON.stringify(input),
85
+ });
86
+ }
87
+ hubObservability() {
88
+ return this.request('/v1/hub/observability');
89
+ }
90
+ wiki() {
91
+ return this.request('/v1/wiki');
92
+ }
93
+ wikiPages() {
94
+ return this.request('/v1/wiki/pages');
95
+ }
96
+ createWikiPage(input) {
97
+ return this.request('/v1/wiki/pages', {
98
+ method: 'POST',
99
+ body: JSON.stringify(input),
100
+ });
101
+ }
102
+ wikiPage(slug) {
103
+ return this.request(`/v1/wiki/pages/${encodeURIComponent(slug)}`);
104
+ }
105
+ updateWikiPage(slug, input) {
106
+ return this.request(`/v1/wiki/pages/${encodeURIComponent(slug)}`, {
107
+ method: 'PUT',
108
+ body: JSON.stringify(input),
109
+ });
110
+ }
111
+ wikiSearch(query, limit = 10) {
112
+ const params = new URLSearchParams({
113
+ q: query,
114
+ limit: String(limit),
115
+ });
116
+ return this.request(`/v1/wiki/search?${params.toString()}`);
117
+ }
118
+ wikiHistory(slug) {
119
+ return this.request(`/v1/wiki/pages/${encodeURIComponent(slug)}/history`);
120
+ }
121
+ wikiBacklinks(slug) {
122
+ return this.request(`/v1/wiki/pages/${encodeURIComponent(slug)}/backlinks`);
123
+ }
124
+ governance() {
125
+ return this.request('/v1/governance');
126
+ }
127
+ governanceReviews(status) {
128
+ const suffix = status ? `?status=${encodeURIComponent(status)}` : '';
129
+ return this.request(`/v1/governance/reviews${suffix}`);
130
+ }
131
+ reviewKnowledge(reviewId, input) {
132
+ return this.request(`/v1/governance/reviews/${encodeURIComponent(reviewId)}`, {
133
+ method: 'POST',
134
+ body: JSON.stringify(input),
135
+ });
136
+ }
137
+ knowledgeQuality() {
138
+ return this.request('/v1/governance/quality');
139
+ }
140
+ governancePolicy() {
141
+ return this.request('/v1/governance/policy');
142
+ }
143
+ setGovernancePolicy(input) {
144
+ return this.request('/v1/governance/policy', {
145
+ method: 'PUT',
146
+ body: JSON.stringify(input),
147
+ });
148
+ }
149
+ async request(path, init = {}) {
150
+ const controller = new AbortController();
151
+ const timeout = setTimeout(() => {
152
+ controller.abort();
153
+ }, this.timeoutMs);
154
+ try {
155
+ const headers = new Headers(init.headers);
156
+ headers.set('accept', 'application/json');
157
+ if (init.body !== undefined) {
158
+ headers.set('content-type', 'application/json');
159
+ }
160
+ if (this.token) {
161
+ headers.set('authorization', `Bearer ${this.token}`);
162
+ }
163
+ if (this.principal) {
164
+ headers.set('x-toolnet-principal', this.principal);
165
+ }
166
+ const response = await fetch(`${this.baseUrl}${path}`, {
167
+ ...init,
168
+ headers,
169
+ signal: controller.signal,
170
+ });
171
+ const text = await response.text();
172
+ const body = text ? JSON.parse(text) : null;
173
+ if (!response.ok) {
174
+ const message = body && typeof body === 'object' && 'error' in body && typeof body.error === 'string'
175
+ ? body.error
176
+ : `ToolNet API request failed: HTTP ${response.status}`;
177
+ throw new Error(message);
178
+ }
179
+ return body;
180
+ }
181
+ finally {
182
+ clearTimeout(timeout);
183
+ }
184
+ }
185
+ }
@@ -0,0 +1,402 @@
1
+ export interface ToolNetApiClientOptions {
2
+ baseUrl: string;
3
+ token?: string;
4
+ principal?: string;
5
+ timeoutMs?: number;
6
+ }
7
+ export interface ToolNetApiHealth {
8
+ ok: true;
9
+ service: 'toolnet-memory';
10
+ schema: 'toolnet.api-health.v1';
11
+ project: {
12
+ id: string;
13
+ name: string;
14
+ remote: string;
15
+ };
16
+ }
17
+ export interface ToolNetApiProject {
18
+ schema: 'toolnet.api-project.v1';
19
+ project: {
20
+ id: string;
21
+ name: string;
22
+ remote: string;
23
+ graphVersion: number;
24
+ memoryVersion: number;
25
+ createdAt: string;
26
+ updatedAt: string;
27
+ };
28
+ }
29
+ export interface ToolNetApiMemoryAskInput {
30
+ question: string;
31
+ mode?: 'ai' | 'local';
32
+ }
33
+ export interface ToolNetApiMemoryAsk {
34
+ schema: 'toolnet.api-memory-ask.v1';
35
+ result: {
36
+ answer: string;
37
+ mode: 'ai' | 'local';
38
+ usedAi: boolean;
39
+ source?: string;
40
+ intent?: string;
41
+ provider?: string;
42
+ model?: string;
43
+ };
44
+ }
45
+ export interface ToolNetApiMemorySearchInput {
46
+ query: string;
47
+ limit?: number;
48
+ }
49
+ export interface ToolNetApiMemorySearchResult {
50
+ id: string;
51
+ type: 'code' | 'activity' | 'decision' | 'rule' | 'todo' | 'summary';
52
+ content: string;
53
+ importance: 'critical' | 'high' | 'normal' | 'temporary';
54
+ score: number;
55
+ tags: string[];
56
+ }
57
+ export interface ToolNetApiMemorySearch {
58
+ schema: 'toolnet.api-memory-search.v1';
59
+ results: ToolNetApiMemorySearchResult[];
60
+ }
61
+ export interface ToolNetApiSkillSearchInput {
62
+ query: string;
63
+ limit?: number;
64
+ }
65
+ export interface ToolNetApiSkillSource {
66
+ agent: string;
67
+ nativeSessionId: string;
68
+ sessionKey: string;
69
+ firstSequence: number;
70
+ lastSequence: number;
71
+ eventIds: string[];
72
+ }
73
+ export interface ToolNetApiSkillSearchMatch {
74
+ id: string;
75
+ title: string;
76
+ task: string;
77
+ summary: string;
78
+ steps: string[];
79
+ verification: string[];
80
+ files: string[];
81
+ source: ToolNetApiSkillSource;
82
+ createdAt: string;
83
+ score: number;
84
+ }
85
+ export interface ToolNetApiSkillSearch {
86
+ schema: 'toolnet.api-skill-search.v1';
87
+ result: {
88
+ schema: 'toolnet.skill-memory-search.v1';
89
+ query: string;
90
+ count: number;
91
+ matches: ToolNetApiSkillSearchMatch[];
92
+ };
93
+ }
94
+ export interface ToolNetApiContextOffloadReadInput {
95
+ assetId: string;
96
+ maxChars?: number;
97
+ }
98
+ export interface ToolNetApiContextOffloadRead {
99
+ schema: 'toolnet.api-context-offload.v1';
100
+ result: {
101
+ assetId: string;
102
+ kind: string;
103
+ bytes: number;
104
+ truncated: boolean;
105
+ content: string;
106
+ };
107
+ }
108
+ export type ToolNetHubRole = 'owner' | 'admin' | 'member' | 'viewer';
109
+ export type ToolNetHubScope = 'hub:read' | 'teams:write' | 'agents:write' | 'acl:manage' | 'loadouts:write' | 'observability:read' | 'wiki:read' | 'wiki:write' | 'governance:read' | 'governance:write';
110
+ export interface ToolNetHubTeam {
111
+ id: string;
112
+ name: string;
113
+ description?: string;
114
+ createdAt: string;
115
+ updatedAt: string;
116
+ }
117
+ export interface ToolNetHubAgent {
118
+ id: string;
119
+ name: string;
120
+ kind?: string;
121
+ teamIds: string[];
122
+ metadata?: Record<string, unknown>;
123
+ createdAt: string;
124
+ updatedAt: string;
125
+ }
126
+ export interface ToolNetHubAclGrant {
127
+ principal: string;
128
+ role: ToolNetHubRole;
129
+ scopes: ToolNetHubScope[];
130
+ createdAt: string;
131
+ updatedAt: string;
132
+ }
133
+ export interface ToolNetHubLoadout {
134
+ agentId: string;
135
+ tools: string[];
136
+ memoryMode: 'local' | 'ai';
137
+ skillMemory: boolean;
138
+ contextOffload: boolean;
139
+ maxContextChars: number;
140
+ updatedAt: string;
141
+ }
142
+ export interface ToolNetHubEvent {
143
+ id: string;
144
+ kind: 'request' | 'mutation';
145
+ action: string;
146
+ principal: string;
147
+ ok: boolean;
148
+ statusCode?: number;
149
+ durationMs?: number;
150
+ timestamp: string;
151
+ }
152
+ export interface ToolNetApiHubSummary {
153
+ schema: 'toolnet.api-hub-summary.v1';
154
+ hub: {
155
+ schema: 'toolnet.memory-hub.v1';
156
+ project: {
157
+ id: string;
158
+ name: string;
159
+ remote: string;
160
+ };
161
+ teams: number;
162
+ agents: number;
163
+ aclGrants: number;
164
+ loadouts: number;
165
+ updatedAt: string;
166
+ };
167
+ }
168
+ export interface ToolNetApiHubTeams {
169
+ schema: 'toolnet.api-hub-teams.v1';
170
+ teams: ToolNetHubTeam[];
171
+ }
172
+ export interface ToolNetApiCreateHubTeamInput {
173
+ id?: string;
174
+ name: string;
175
+ description?: string;
176
+ }
177
+ export interface ToolNetApiHubTeam {
178
+ schema: 'toolnet.api-hub-team.v1';
179
+ team: ToolNetHubTeam;
180
+ }
181
+ export interface ToolNetApiHubAgents {
182
+ schema: 'toolnet.api-hub-agents.v1';
183
+ agents: ToolNetHubAgent[];
184
+ }
185
+ export interface ToolNetApiCreateHubAgentInput {
186
+ id?: string;
187
+ name: string;
188
+ kind?: string;
189
+ teamIds?: string[];
190
+ metadata?: Record<string, unknown>;
191
+ }
192
+ export interface ToolNetApiHubAgent {
193
+ schema: 'toolnet.api-hub-agent.v1';
194
+ agent: ToolNetHubAgent;
195
+ }
196
+ export interface ToolNetApiHubAcl {
197
+ schema: 'toolnet.api-hub-acl.v1';
198
+ grants: ToolNetHubAclGrant[];
199
+ }
200
+ export interface ToolNetApiGrantHubAclInput {
201
+ principal: string;
202
+ role: ToolNetHubRole;
203
+ scopes?: ToolNetHubScope[];
204
+ }
205
+ export interface ToolNetApiHubAclGrant {
206
+ schema: 'toolnet.api-hub-acl-grant.v1';
207
+ grant: ToolNetHubAclGrant;
208
+ }
209
+ export interface ToolNetApiHubAclRevoke {
210
+ schema: 'toolnet.api-hub-acl-revoke.v1';
211
+ principal: string;
212
+ revoked: true;
213
+ }
214
+ export interface ToolNetApiHubLoadouts {
215
+ schema: 'toolnet.api-hub-loadouts.v1';
216
+ loadouts: ToolNetHubLoadout[];
217
+ }
218
+ export interface ToolNetApiSetHubLoadoutInput {
219
+ agentId: string;
220
+ tools?: string[];
221
+ memoryMode?: 'local' | 'ai';
222
+ skillMemory?: boolean;
223
+ contextOffload?: boolean;
224
+ maxContextChars?: number;
225
+ }
226
+ export interface ToolNetApiHubLoadout {
227
+ schema: 'toolnet.api-hub-loadout.v1';
228
+ loadout: ToolNetHubLoadout;
229
+ }
230
+ export interface ToolNetApiHubObservability {
231
+ schema: 'toolnet.api-hub-observability.v1';
232
+ observability: {
233
+ requests: number;
234
+ mutations: number;
235
+ errors: number;
236
+ lastActivityAt?: string;
237
+ events: ToolNetHubEvent[];
238
+ };
239
+ }
240
+ export interface ToolNetWikiPage {
241
+ id: string;
242
+ slug: string;
243
+ title: string;
244
+ summary?: string;
245
+ content: string;
246
+ tags: string[];
247
+ links: string[];
248
+ revision: number;
249
+ createdAt: string;
250
+ updatedAt: string;
251
+ }
252
+ export interface ToolNetWikiRevision {
253
+ id: string;
254
+ pageId: string;
255
+ slug: string;
256
+ revision: number;
257
+ title: string;
258
+ summary?: string;
259
+ content: string;
260
+ tags: string[];
261
+ links: string[];
262
+ createdAt: string;
263
+ }
264
+ export interface ToolNetWikiSearchResult {
265
+ page: ToolNetWikiPage;
266
+ score: number;
267
+ }
268
+ export interface ToolNetApiWikiSummary {
269
+ schema: 'toolnet.api-wiki-summary.v1';
270
+ wiki: {
271
+ schema: 'toolnet.wiki-summary.v1';
272
+ projectId: string;
273
+ pages: number;
274
+ revisions: number;
275
+ tags: string[];
276
+ links: number;
277
+ orphanPages: number;
278
+ automatedPages: number;
279
+ updatedAt: string;
280
+ };
281
+ }
282
+ export interface ToolNetApiWikiPages {
283
+ schema: 'toolnet.api-wiki-pages.v1';
284
+ pages: ToolNetWikiPage[];
285
+ }
286
+ export interface ToolNetApiWikiPage {
287
+ schema: 'toolnet.api-wiki-page.v1';
288
+ page: ToolNetWikiPage;
289
+ }
290
+ export interface ToolNetApiCreateWikiPageInput {
291
+ slug?: string;
292
+ title: string;
293
+ summary?: string;
294
+ content: string;
295
+ tags?: string[];
296
+ }
297
+ export interface ToolNetApiUpdateWikiPageInput {
298
+ title?: string;
299
+ summary?: string;
300
+ content?: string;
301
+ tags?: string[];
302
+ }
303
+ export interface ToolNetApiWikiSearch {
304
+ schema: 'toolnet.api-wiki-search.v1';
305
+ query: string;
306
+ results: ToolNetWikiSearchResult[];
307
+ }
308
+ export interface ToolNetApiWikiHistory {
309
+ schema: 'toolnet.api-wiki-history.v1';
310
+ revisions: ToolNetWikiRevision[];
311
+ }
312
+ export interface ToolNetApiWikiBacklinks {
313
+ schema: 'toolnet.api-wiki-backlinks.v1';
314
+ pages: ToolNetWikiPage[];
315
+ }
316
+ export type ToolNetKnowledgeGovernanceReviewStatus = 'pending' | 'approved' | 'rejected' | 'superseded';
317
+ export type ToolNetKnowledgeGovernanceRisk = 'normal' | 'critical' | 'conflict';
318
+ export interface ToolNetKnowledgeGovernancePolicy {
319
+ autoApproveThreshold: number;
320
+ criticalApproveThreshold: number;
321
+ staleAfterDays: number;
322
+ }
323
+ export interface ToolNetKnowledgeGovernanceReview {
324
+ id: string;
325
+ sourceKey: string;
326
+ sourceType: 'memory' | 'scene' | 'skill';
327
+ slug: string;
328
+ digest: string;
329
+ title: string;
330
+ summary?: string;
331
+ content: string;
332
+ tags: string[];
333
+ confidence: number;
334
+ risk: ToolNetKnowledgeGovernanceRisk;
335
+ reasons: string[];
336
+ conflicts: string[];
337
+ status: ToolNetKnowledgeGovernanceReviewStatus;
338
+ createdAt: string;
339
+ updatedAt: string;
340
+ reviewedAt?: string;
341
+ reviewedBy?: string;
342
+ reviewNote?: string;
343
+ appliedAt?: string;
344
+ supersededBy?: string;
345
+ mergedInto?: string;
346
+ }
347
+ export interface ToolNetApiGovernanceSummary {
348
+ schema: 'toolnet.api-governance-summary.v1';
349
+ governance: {
350
+ schema: 'toolnet.knowledge-governance-summary.v1';
351
+ projectId: string;
352
+ pending: number;
353
+ approved: number;
354
+ rejected: number;
355
+ superseded: number;
356
+ criticalPending: number;
357
+ conflictPending: number;
358
+ auditEvents: number;
359
+ policy: ToolNetKnowledgeGovernancePolicy;
360
+ updatedAt: string;
361
+ };
362
+ }
363
+ export interface ToolNetApiGovernanceReviews {
364
+ schema: 'toolnet.api-governance-reviews.v1';
365
+ reviews: ToolNetKnowledgeGovernanceReview[];
366
+ }
367
+ export interface ToolNetApiGovernanceReview {
368
+ schema: 'toolnet.api-governance-review.v1';
369
+ review: ToolNetKnowledgeGovernanceReview;
370
+ }
371
+ export interface ToolNetGovernanceDecisionInput {
372
+ action: 'approve' | 'reject' | 'supersede' | 'merge';
373
+ note?: string;
374
+ targetReviewId?: string;
375
+ }
376
+ export interface ToolNetApiKnowledgeQuality {
377
+ schema: 'toolnet.api-knowledge-quality.v1';
378
+ quality: {
379
+ schema: 'toolnet.knowledge-quality.v1';
380
+ totalPages: number;
381
+ automatedPages: number;
382
+ manualPages: number;
383
+ stalePages: Array<{
384
+ slug: string;
385
+ title: string;
386
+ updatedAt: string;
387
+ ageDays: number;
388
+ }>;
389
+ duplicateTitles: Array<{
390
+ title: string;
391
+ pages: string[];
392
+ }>;
393
+ pendingReviews: number;
394
+ lowConfidenceReviews: number;
395
+ conflicts: number;
396
+ generatedAt: string;
397
+ };
398
+ }
399
+ export interface ToolNetApiGovernancePolicy {
400
+ schema: 'toolnet.api-governance-policy.v1';
401
+ policy: ToolNetKnowledgeGovernancePolicy;
402
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolnet-memory",
3
- "version": "0.2.21",
3
+ "version": "0.3.0",
4
4
  "description": "Persistent project memory, work continuity, and code intelligence for AI coding agents.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,7 +28,7 @@
28
28
  "scripts": {
29
29
  "dev": "tsx src/index.ts",
30
30
  "build": "tsc -p tsconfig.json",
31
- "lint": "eslint src tests --ext .ts",
31
+ "lint": "eslint src tests packages --ext .ts",
32
32
  "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"*.md\" \"*.json\"",
33
33
  "format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"*.md\" \"*.json\"",
34
34
  "typecheck": "tsc --noEmit",
@@ -57,7 +57,7 @@
57
57
  "code:visualization:test": "tsx src/code-intelligence/test-visualization.ts",
58
58
  "graph:ui": "tsx src/visualization/server.ts",
59
59
  "project:status": "tsx src/production/project-status.ts",
60
- "build:prod": "npm run build && rm -rf dist/tests dist/visualization/public && mkdir -p dist/visualization/public/vendor && cp src/visualization/public/index.html dist/visualization/public/index.html && cp node_modules/3d-force-graph/dist/3d-force-graph.min.js dist/visualization/public/vendor/3d-force-graph.min.js && find dist -type f \\( -name \"*.bak-*\" -o -name \"*.map\" \\) -delete",
60
+ "build:prod": "npm run build && npm run build:sdk && rm -rf dist/tests dist/visualization/public && mkdir -p dist/visualization/public/vendor && cp src/visualization/public/index.html dist/visualization/public/index.html && cp node_modules/3d-force-graph/dist/3d-force-graph.min.js dist/visualization/public/vendor/3d-force-graph.min.js && find dist -type f \\( -name \"*.bak-*\" -o -name \"*.map\" \\) -delete",
61
61
  "prepack": "npm run build:prod",
62
62
  "session:test": "vitest run tests/session/session-core.test.ts",
63
63
  "session:opencode:test": "vitest run tests/session/opencode-adapter.test.ts",
@@ -70,7 +70,9 @@
70
70
  "semantic-work:test": "vitest run tests/work-continuity/semantic-context.test.ts",
71
71
  "context-injection:test": "vitest run tests/work-continuity/context-injection.test.ts",
72
72
  "build:bundle": "npm run build && node scripts/build-bundle.mjs",
73
- "build:release": "npm run build:prod && node scripts/build-bundle.mjs"
73
+ "build:release": "npm run build:prod && node scripts/build-bundle.mjs",
74
+ "api": "tsx src/api/bootstrap.ts",
75
+ "build:sdk": "tsc -p tsconfig.sdk.json"
74
76
  },
75
77
  "dependencies": {
76
78
  "@aws-sdk/client-s3": "^3.1102.0",
@@ -99,9 +101,16 @@
99
101
  "bundle",
100
102
  "bin/toolnet-memory",
101
103
  "README.md",
102
- ".env.example"
104
+ ".env.example",
105
+ "dist/sdk"
103
106
  ],
104
107
  "publishConfig": {
105
108
  "access": "public"
109
+ },
110
+ "exports": {
111
+ "./sdk": {
112
+ "types": "./dist/sdk/public.d.ts",
113
+ "import": "./dist/sdk/public.js"
114
+ }
106
115
  }
107
116
  }