gsd-pi 2.75.0-dev.2203010a0 → 2.75.0-dev.96d4bb599

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.
Files changed (109) hide show
  1. package/dist/onboarding.d.ts +5 -1
  2. package/dist/onboarding.js +5 -3
  3. package/dist/resources/extensions/gsd/auto-model-selection.js +1 -1
  4. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +23 -19
  5. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +128 -0
  6. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  7. package/dist/resources/extensions/gsd/bootstrap/system-context.js +17 -4
  8. package/dist/resources/extensions/gsd/commands/handlers/onboarding.js +52 -68
  9. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  10. package/dist/resources/extensions/gsd/commands-memory.js +462 -0
  11. package/dist/resources/extensions/gsd/gsd-db.js +237 -4
  12. package/dist/resources/extensions/gsd/memory-embeddings.js +219 -0
  13. package/dist/resources/extensions/gsd/memory-extractor.js +78 -27
  14. package/dist/resources/extensions/gsd/memory-ingest.js +218 -0
  15. package/dist/resources/extensions/gsd/memory-relations.js +189 -0
  16. package/dist/resources/extensions/gsd/memory-source-store.js +113 -0
  17. package/dist/resources/extensions/gsd/memory-store.js +299 -6
  18. package/dist/resources/extensions/gsd/model-router.js +9 -5
  19. package/dist/resources/extensions/gsd/notification-overlay.js +7 -22
  20. package/dist/resources/extensions/gsd/tools/memory-tools.js +306 -0
  21. package/dist/resources/extensions/gsd/tools/skip-slice.js +78 -0
  22. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  23. package/dist/web/standalone/.next/BUILD_ID +1 -1
  24. package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
  25. package/dist/web/standalone/.next/build-manifest.json +2 -2
  26. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  27. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  28. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  33. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  34. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  35. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  36. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  37. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  39. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/index.html +1 -1
  44. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  46. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
  51. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  52. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  53. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  54. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  55. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  56. package/package.json +1 -1
  57. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  58. package/packages/mcp-server/dist/server.js +12 -10
  59. package/packages/mcp-server/dist/server.js.map +1 -1
  60. package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
  61. package/packages/mcp-server/dist/session-manager.js +8 -1
  62. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  63. package/packages/mcp-server/dist/workflow-tools.d.ts +1 -0
  64. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  65. package/packages/mcp-server/dist/workflow-tools.js +113 -14
  66. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  67. package/packages/mcp-server/src/mcp-server.test.ts +40 -4
  68. package/packages/mcp-server/src/server.ts +12 -10
  69. package/packages/mcp-server/src/session-manager.ts +10 -3
  70. package/packages/mcp-server/src/workflow-tools.test.ts +91 -1
  71. package/packages/mcp-server/src/workflow-tools.ts +128 -18
  72. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  73. package/src/resources/extensions/gsd/auto-model-selection.ts +1 -1
  74. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +24 -20
  75. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +158 -0
  76. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  77. package/src/resources/extensions/gsd/bootstrap/system-context.ts +20 -4
  78. package/src/resources/extensions/gsd/commands/handlers/onboarding.ts +65 -98
  79. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  80. package/src/resources/extensions/gsd/commands-memory.ts +551 -0
  81. package/src/resources/extensions/gsd/gsd-db.ts +273 -4
  82. package/src/resources/extensions/gsd/memory-embeddings.ts +235 -0
  83. package/src/resources/extensions/gsd/memory-extractor.ts +100 -34
  84. package/src/resources/extensions/gsd/memory-ingest.ts +286 -0
  85. package/src/resources/extensions/gsd/memory-relations.ts +240 -0
  86. package/src/resources/extensions/gsd/memory-source-store.ts +138 -0
  87. package/src/resources/extensions/gsd/memory-store.ts +351 -7
  88. package/src/resources/extensions/gsd/model-router.ts +10 -5
  89. package/src/resources/extensions/gsd/notification-overlay.ts +9 -19
  90. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +12 -0
  91. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  92. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  93. package/src/resources/extensions/gsd/tests/escalation.test.ts +2 -2
  94. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  95. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  96. package/src/resources/extensions/gsd/tests/memory-embeddings.test.ts +213 -0
  97. package/src/resources/extensions/gsd/tests/memory-ingest.test.ts +153 -0
  98. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +107 -0
  99. package/src/resources/extensions/gsd/tests/memory-relations.test.ts +175 -0
  100. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  101. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +295 -0
  102. package/src/resources/extensions/gsd/tests/model-router.test.ts +50 -0
  103. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +56 -37
  104. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +125 -0
  105. package/src/resources/extensions/gsd/tools/memory-tools.ts +380 -0
  106. package/src/resources/extensions/gsd/tools/skip-slice.ts +133 -0
  107. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  108. /package/dist/web/standalone/.next/static/{8FZqxNe9FxQDmsbRzR8tA → o61X3klsB6C0UE0X1x3PA}/_buildManifest.js +0 -0
  109. /package/dist/web/standalone/.next/static/{8FZqxNe9FxQDmsbRzR8tA → o61X3klsB6C0UE0X1x3PA}/_ssgManifest.js +0 -0
@@ -0,0 +1,240 @@
1
+ // GSD Memory Relations — knowledge-graph edges between memories
2
+ //
3
+ // Phase 4 companion to memory-store.ts. Edges live in the `memory_relations`
4
+ // table and are created by (a) explicit LINK actions emitted by the memory
5
+ // extractor, or (b) future `/gsd memory link` CLI commands. All writes go
6
+ // through the single-writer gate in `gsd-db.ts`.
7
+
8
+ import {
9
+ _getAdapter,
10
+ deleteMemoryRelationsFor,
11
+ insertMemoryRelationRow,
12
+ isDbAvailable,
13
+ } from "./gsd-db.js";
14
+
15
+ // ─── Types ──────────────────────────────────────────────────────────────────
16
+
17
+ export type RelationType =
18
+ | "related_to"
19
+ | "depends_on"
20
+ | "contradicts"
21
+ | "elaborates"
22
+ | "supersedes";
23
+
24
+ export const VALID_RELATIONS: readonly RelationType[] = [
25
+ "related_to",
26
+ "depends_on",
27
+ "contradicts",
28
+ "elaborates",
29
+ "supersedes",
30
+ ];
31
+
32
+ export interface MemoryRelation {
33
+ from: string;
34
+ to: string;
35
+ rel: RelationType;
36
+ confidence: number;
37
+ createdAt: string;
38
+ }
39
+
40
+ export interface MemoryGraphNode {
41
+ id: string;
42
+ category: string;
43
+ content: string;
44
+ confidence: number;
45
+ }
46
+
47
+ export interface MemoryGraph {
48
+ nodes: MemoryGraphNode[];
49
+ edges: MemoryRelation[];
50
+ }
51
+
52
+ // ─── Helpers ────────────────────────────────────────────────────────────────
53
+
54
+ export function isValidRelation(value: unknown): value is RelationType {
55
+ return typeof value === "string" && (VALID_RELATIONS as readonly string[]).includes(value);
56
+ }
57
+
58
+ function clampConfidence(value: unknown): number {
59
+ if (typeof value !== "number" || !Number.isFinite(value)) return 0.8;
60
+ if (value < 0.1) return 0.1;
61
+ if (value > 0.99) return 0.99;
62
+ return value;
63
+ }
64
+
65
+ // ─── Mutations ──────────────────────────────────────────────────────────────
66
+
67
+ export function createMemoryRelation(
68
+ from: string,
69
+ to: string,
70
+ rel: RelationType,
71
+ confidence?: number,
72
+ ): boolean {
73
+ if (!isDbAvailable()) return false;
74
+ if (!from || !to || from === to || !isValidRelation(rel)) return false;
75
+
76
+ const adapter = _getAdapter();
77
+ if (!adapter) return false;
78
+
79
+ try {
80
+ // Verify both memories exist — relation rows without endpoints are useless.
81
+ const fromRow = adapter.prepare("SELECT 1 FROM memories WHERE id = :id").get({ ":id": from });
82
+ const toRow = adapter.prepare("SELECT 1 FROM memories WHERE id = :id").get({ ":id": to });
83
+ if (!fromRow || !toRow) return false;
84
+
85
+ insertMemoryRelationRow({
86
+ fromId: from,
87
+ toId: to,
88
+ rel,
89
+ confidence: clampConfidence(confidence),
90
+ createdAt: new Date().toISOString(),
91
+ });
92
+ return true;
93
+ } catch {
94
+ return false;
95
+ }
96
+ }
97
+
98
+ export function removeMemoryRelationsFor(memoryId: string): void {
99
+ if (!isDbAvailable() || !memoryId) return;
100
+ try {
101
+ deleteMemoryRelationsFor(memoryId);
102
+ } catch {
103
+ // non-fatal
104
+ }
105
+ }
106
+
107
+ // ─── Queries ────────────────────────────────────────────────────────────────
108
+
109
+ export function listRelationsFor(memoryId: string): MemoryRelation[] {
110
+ if (!isDbAvailable()) return [];
111
+ const adapter = _getAdapter();
112
+ if (!adapter) return [];
113
+ try {
114
+ const rows = adapter
115
+ .prepare(
116
+ "SELECT from_id, to_id, rel, confidence, created_at FROM memory_relations WHERE from_id = :id OR to_id = :id",
117
+ )
118
+ .all({ ":id": memoryId });
119
+ return rows.map(rowToRelation);
120
+ } catch {
121
+ return [];
122
+ }
123
+ }
124
+
125
+ export function traverseGraph(startId: string, depth: number): MemoryGraph {
126
+ const emptyResult: MemoryGraph = { nodes: [], edges: [] };
127
+ if (!isDbAvailable() || !startId) return emptyResult;
128
+ const adapter = _getAdapter();
129
+ if (!adapter) return emptyResult;
130
+
131
+ const hop = Math.max(0, Math.min(5, Math.floor(depth || 0)));
132
+
133
+ try {
134
+ const visited = new Set<string>();
135
+ const queue: Array<{ id: string; hop: number }> = [{ id: startId, hop: 0 }];
136
+ const nodes = new Map<string, MemoryGraphNode>();
137
+ const edges: MemoryRelation[] = [];
138
+
139
+ while (queue.length > 0) {
140
+ const { id, hop: level } = queue.shift()!;
141
+ if (visited.has(id)) continue;
142
+ visited.add(id);
143
+
144
+ const nodeRow = adapter
145
+ .prepare(
146
+ "SELECT id, category, content, confidence, superseded_by FROM memories WHERE id = :id",
147
+ )
148
+ .get({ ":id": id });
149
+ if (!nodeRow) continue;
150
+
151
+ nodes.set(id, {
152
+ id: nodeRow["id"] as string,
153
+ category: nodeRow["category"] as string,
154
+ content: nodeRow["content"] as string,
155
+ confidence: nodeRow["confidence"] as number,
156
+ });
157
+
158
+ // Include supersedes edges from the base table so old graphs remain
159
+ // connected even before the extractor starts emitting LINK actions.
160
+ const successor = nodeRow["superseded_by"] as string | null;
161
+ if (successor && successor !== "CAP_EXCEEDED") {
162
+ edges.push({
163
+ from: id,
164
+ to: successor,
165
+ rel: "supersedes",
166
+ confidence: 1,
167
+ createdAt: "",
168
+ });
169
+ if (!visited.has(successor) && level < hop) {
170
+ queue.push({ id: successor, hop: level + 1 });
171
+ }
172
+ }
173
+ const predecessors = adapter
174
+ .prepare("SELECT id FROM memories WHERE superseded_by = :id")
175
+ .all({ ":id": id });
176
+ for (const pred of predecessors) {
177
+ const predId = pred["id"] as string;
178
+ edges.push({ from: predId, to: id, rel: "supersedes", confidence: 1, createdAt: "" });
179
+ if (!visited.has(predId) && level < hop) {
180
+ queue.push({ id: predId, hop: level + 1 });
181
+ }
182
+ }
183
+
184
+ if (level >= hop) continue;
185
+
186
+ const outgoing = adapter
187
+ .prepare(
188
+ "SELECT from_id, to_id, rel, confidence, created_at FROM memory_relations WHERE from_id = :id",
189
+ )
190
+ .all({ ":id": id });
191
+ for (const row of outgoing) {
192
+ const edge = rowToRelation(row);
193
+ edges.push(edge);
194
+ if (!visited.has(edge.to)) queue.push({ id: edge.to, hop: level + 1 });
195
+ }
196
+
197
+ const incoming = adapter
198
+ .prepare(
199
+ "SELECT from_id, to_id, rel, confidence, created_at FROM memory_relations WHERE to_id = :id",
200
+ )
201
+ .all({ ":id": id });
202
+ for (const row of incoming) {
203
+ const edge = rowToRelation(row);
204
+ edges.push(edge);
205
+ if (!visited.has(edge.from)) queue.push({ id: edge.from, hop: level + 1 });
206
+ }
207
+ }
208
+
209
+ return {
210
+ nodes: [...nodes.values()],
211
+ edges: dedupeEdges(edges),
212
+ };
213
+ } catch {
214
+ return emptyResult;
215
+ }
216
+ }
217
+
218
+ function rowToRelation(row: Record<string, unknown>): MemoryRelation {
219
+ const relRaw = row["rel"] as string;
220
+ const rel = isValidRelation(relRaw) ? relRaw : ("related_to" as RelationType);
221
+ return {
222
+ from: row["from_id"] as string,
223
+ to: row["to_id"] as string,
224
+ rel,
225
+ confidence: (row["confidence"] as number) ?? 0.8,
226
+ createdAt: (row["created_at"] as string) ?? "",
227
+ };
228
+ }
229
+
230
+ function dedupeEdges(edges: MemoryRelation[]): MemoryRelation[] {
231
+ const seen = new Set<string>();
232
+ const out: MemoryRelation[] = [];
233
+ for (const e of edges) {
234
+ const key = `${e.from}|${e.to}|${e.rel}`;
235
+ if (seen.has(key)) continue;
236
+ seen.add(key);
237
+ out.push(e);
238
+ }
239
+ return out;
240
+ }
@@ -0,0 +1,138 @@
1
+ // GSD Memory Sources — CRUD for raw ingested content (notes, files, URLs, artifacts)
2
+ //
3
+ // Distinct from `memories`: a `memory_source` row is the preserved raw input
4
+ // that an extractor may (or may not) distill into one or more memories.
5
+ // Storing the source makes ingestion idempotent (content_hash) and gives the
6
+ // user a way to trace a memory back to its origin.
7
+
8
+ import { createHash, randomUUID } from "node:crypto";
9
+ import { _getAdapter, isDbAvailable, insertMemorySourceRow, deleteMemorySourceRow } from "./gsd-db.js";
10
+
11
+ export type MemorySourceKind = "note" | "url" | "file" | "artifact" | "capture" | "learning";
12
+
13
+ export interface MemorySource {
14
+ id: string;
15
+ kind: MemorySourceKind;
16
+ uri: string | null;
17
+ title: string | null;
18
+ content: string;
19
+ content_hash: string;
20
+ imported_at: string;
21
+ scope: string;
22
+ tags: string[];
23
+ }
24
+
25
+ function rowToSource(row: Record<string, unknown>): MemorySource {
26
+ const tagsRaw = typeof row["tags"] === "string" ? (row["tags"] as string) : "[]";
27
+ let tags: string[] = [];
28
+ try {
29
+ const parsed = JSON.parse(tagsRaw);
30
+ if (Array.isArray(parsed)) tags = parsed.filter((t): t is string => typeof t === "string");
31
+ } catch {
32
+ // leave tags empty
33
+ }
34
+ return {
35
+ id: row["id"] as string,
36
+ kind: row["kind"] as MemorySourceKind,
37
+ uri: (row["uri"] as string) ?? null,
38
+ title: (row["title"] as string) ?? null,
39
+ content: row["content"] as string,
40
+ content_hash: row["content_hash"] as string,
41
+ imported_at: row["imported_at"] as string,
42
+ scope: (row["scope"] as string) ?? "project",
43
+ tags,
44
+ };
45
+ }
46
+
47
+ export function hashContent(content: string): string {
48
+ return createHash("sha256").update(content).digest("hex");
49
+ }
50
+
51
+ export function newSourceId(): string {
52
+ return `SRC-${randomUUID().slice(0, 8)}`;
53
+ }
54
+
55
+ export interface CreateSourceOptions {
56
+ kind: MemorySourceKind;
57
+ uri?: string | null;
58
+ title?: string | null;
59
+ content: string;
60
+ scope?: string;
61
+ tags?: string[];
62
+ }
63
+
64
+ export interface CreateSourceResult {
65
+ id: string;
66
+ duplicate: boolean;
67
+ }
68
+
69
+ /**
70
+ * Insert a memory_source. Idempotent — if the content_hash already exists,
71
+ * returns the existing source's id and duplicate=true instead of inserting.
72
+ */
73
+ export function createMemorySource(opts: CreateSourceOptions): CreateSourceResult | null {
74
+ if (!isDbAvailable()) return null;
75
+ const adapter = _getAdapter();
76
+ if (!adapter) return null;
77
+
78
+ try {
79
+ const contentHash = hashContent(opts.content);
80
+ const existing = adapter
81
+ .prepare("SELECT id FROM memory_sources WHERE content_hash = :h")
82
+ .get({ ":h": contentHash });
83
+ if (existing && typeof existing["id"] === "string") {
84
+ return { id: existing["id"] as string, duplicate: true };
85
+ }
86
+
87
+ const id = newSourceId();
88
+ insertMemorySourceRow({
89
+ id,
90
+ kind: opts.kind,
91
+ uri: opts.uri ?? null,
92
+ title: opts.title ?? null,
93
+ content: opts.content,
94
+ contentHash,
95
+ importedAt: new Date().toISOString(),
96
+ scope: opts.scope ?? "project",
97
+ tags: opts.tags ?? [],
98
+ });
99
+ return { id, duplicate: false };
100
+ } catch {
101
+ return null;
102
+ }
103
+ }
104
+
105
+ export function listMemorySources(limit = 50): MemorySource[] {
106
+ if (!isDbAvailable()) return [];
107
+ const adapter = _getAdapter();
108
+ if (!adapter) return [];
109
+ try {
110
+ const rows = adapter
111
+ .prepare("SELECT * FROM memory_sources ORDER BY imported_at DESC LIMIT :limit")
112
+ .all({ ":limit": limit });
113
+ return rows.map(rowToSource);
114
+ } catch {
115
+ return [];
116
+ }
117
+ }
118
+
119
+ export function getMemorySource(id: string): MemorySource | null {
120
+ if (!isDbAvailable()) return null;
121
+ const adapter = _getAdapter();
122
+ if (!adapter) return null;
123
+ try {
124
+ const row = adapter.prepare("SELECT * FROM memory_sources WHERE id = :id").get({ ":id": id });
125
+ return row ? rowToSource(row) : null;
126
+ } catch {
127
+ return null;
128
+ }
129
+ }
130
+
131
+ export function deleteMemorySource(id: string): boolean {
132
+ if (!isDbAvailable()) return false;
133
+ try {
134
+ return deleteMemorySourceRow(id);
135
+ } catch {
136
+ return false;
137
+ }
138
+ }