greplica 0.1.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.
- package/README.md +177 -0
- package/dist/apps/cli/main.d.ts +2 -0
- package/dist/apps/cli/main.js +404 -0
- package/dist/apps/cli/main.js.map +1 -0
- package/dist/apps/cli/repo-context.d.ts +2 -0
- package/dist/apps/cli/repo-context.js +58 -0
- package/dist/apps/cli/repo-context.js.map +1 -0
- package/dist/libs/agent-runner/codex.d.ts +2 -0
- package/dist/libs/agent-runner/codex.js +53 -0
- package/dist/libs/agent-runner/codex.js.map +1 -0
- package/dist/libs/agent-runner/metrics.d.ts +10 -0
- package/dist/libs/agent-runner/metrics.js +72 -0
- package/dist/libs/agent-runner/metrics.js.map +1 -0
- package/dist/libs/agent-runner/types.d.ts +23 -0
- package/dist/libs/agent-runner/types.js +2 -0
- package/dist/libs/agent-runner/types.js.map +1 -0
- package/dist/libs/config/greplica-config.d.ts +24 -0
- package/dist/libs/config/greplica-config.js +121 -0
- package/dist/libs/config/greplica-config.js.map +1 -0
- package/dist/libs/config/greplica-home.d.ts +1 -0
- package/dist/libs/config/greplica-home.js +6 -0
- package/dist/libs/config/greplica-home.js.map +1 -0
- package/dist/libs/env/load-local-env.d.ts +19 -0
- package/dist/libs/env/load-local-env.js +69 -0
- package/dist/libs/env/load-local-env.js.map +1 -0
- package/dist/libs/install/edit-marked-section.d.ts +1 -0
- package/dist/libs/install/edit-marked-section.js +22 -0
- package/dist/libs/install/edit-marked-section.js.map +1 -0
- package/dist/libs/install/install.d.ts +18 -0
- package/dist/libs/install/install.js +80 -0
- package/dist/libs/install/install.js.map +1 -0
- package/dist/libs/install/instruction-blocks.d.ts +1 -0
- package/dist/libs/install/instruction-blocks.js +13 -0
- package/dist/libs/install/instruction-blocks.js.map +1 -0
- package/dist/libs/install/paths.d.ts +12 -0
- package/dist/libs/install/paths.js +31 -0
- package/dist/libs/install/paths.js.map +1 -0
- package/dist/libs/knowledge-graph/claim.d.ts +11 -0
- package/dist/libs/knowledge-graph/claim.js +2 -0
- package/dist/libs/knowledge-graph/claim.js.map +1 -0
- package/dist/libs/knowledge-graph/commit.d.ts +10 -0
- package/dist/libs/knowledge-graph/commit.js +2 -0
- package/dist/libs/knowledge-graph/commit.js.map +1 -0
- package/dist/libs/knowledge-graph/edge.d.ts +13 -0
- package/dist/libs/knowledge-graph/edge.js +17 -0
- package/dist/libs/knowledge-graph/edge.js.map +1 -0
- package/dist/libs/knowledge-graph/folder-export.d.ts +6 -0
- package/dist/libs/knowledge-graph/folder-export.js +337 -0
- package/dist/libs/knowledge-graph/folder-export.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/bm25.d.ts +9 -0
- package/dist/libs/knowledge-graph/graph-context/bm25.js +62 -0
- package/dist/libs/knowledge-graph/graph-context/bm25.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/config.d.ts +39 -0
- package/dist/libs/knowledge-graph/graph-context/config.js +48 -0
- package/dist/libs/knowledge-graph/graph-context/config.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/context-builder.d.ts +18 -0
- package/dist/libs/knowledge-graph/graph-context/context-builder.js +276 -0
- package/dist/libs/knowledge-graph/graph-context/context-builder.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/documents.d.ts +20 -0
- package/dist/libs/knowledge-graph/graph-context/documents.js +81 -0
- package/dist/libs/knowledge-graph/graph-context/documents.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/embedder.d.ts +6 -0
- package/dist/libs/knowledge-graph/graph-context/embedder.js +8 -0
- package/dist/libs/knowledge-graph/graph-context/embedder.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/exact.d.ts +3 -0
- package/dist/libs/knowledge-graph/graph-context/exact.js +37 -0
- package/dist/libs/knowledge-graph/graph-context/exact.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/local-embedder.d.ts +13 -0
- package/dist/libs/knowledge-graph/graph-context/local-embedder.js +74 -0
- package/dist/libs/knowledge-graph/graph-context/local-embedder.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/openai-embedder.d.ts +14 -0
- package/dist/libs/knowledge-graph/graph-context/openai-embedder.js +59 -0
- package/dist/libs/knowledge-graph/graph-context/openai-embedder.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/rank.d.ts +16 -0
- package/dist/libs/knowledge-graph/graph-context/rank.js +52 -0
- package/dist/libs/knowledge-graph/graph-context/rank.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/render.d.ts +38 -0
- package/dist/libs/knowledge-graph/graph-context/render.js +114 -0
- package/dist/libs/knowledge-graph/graph-context/render.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/types.d.ts +58 -0
- package/dist/libs/knowledge-graph/graph-context/types.js +2 -0
- package/dist/libs/knowledge-graph/graph-context/types.js.map +1 -0
- package/dist/libs/knowledge-graph/graph-context/vector.d.ts +3 -0
- package/dist/libs/knowledge-graph/graph-context/vector.js +25 -0
- package/dist/libs/knowledge-graph/graph-context/vector.js.map +1 -0
- package/dist/libs/knowledge-graph/proposal.d.ts +65 -0
- package/dist/libs/knowledge-graph/proposal.js +135 -0
- package/dist/libs/knowledge-graph/proposal.js.map +1 -0
- package/dist/libs/knowledge-graph/schema.d.ts +32 -0
- package/dist/libs/knowledge-graph/schema.js +2 -0
- package/dist/libs/knowledge-graph/schema.js.map +1 -0
- package/dist/libs/knowledge-graph/scope.d.ts +16 -0
- package/dist/libs/knowledge-graph/scope.js +2 -0
- package/dist/libs/knowledge-graph/scope.js.map +1 -0
- package/dist/libs/knowledge-graph/service.d.ts +54 -0
- package/dist/libs/knowledge-graph/service.js +89 -0
- package/dist/libs/knowledge-graph/service.js.map +1 -0
- package/dist/libs/knowledge-graph/validate-proposal.d.ts +9 -0
- package/dist/libs/knowledge-graph/validate-proposal.js +166 -0
- package/dist/libs/knowledge-graph/validate-proposal.js.map +1 -0
- package/dist/libs/storage/sqlite/db.d.ts +3 -0
- package/dist/libs/storage/sqlite/db.js +16 -0
- package/dist/libs/storage/sqlite/db.js.map +1 -0
- package/dist/libs/storage/sqlite/migrate.d.ts +2 -0
- package/dist/libs/storage/sqlite/migrate.js +56 -0
- package/dist/libs/storage/sqlite/migrate.js.map +1 -0
- package/dist/libs/storage/sqlite/repository.d.ts +95 -0
- package/dist/libs/storage/sqlite/repository.js +310 -0
- package/dist/libs/storage/sqlite/repository.js.map +1 -0
- package/dist/libs/storage/sqlite/schema.d.ts +1 -0
- package/dist/libs/storage/sqlite/schema.js +93 -0
- package/dist/libs/storage/sqlite/schema.js.map +1 -0
- package/package.json +37 -0
- package/skills/greplica-bootstrap/SKILL.md +116 -0
- package/skills/greplica-update-working-memory/SKILL.md +183 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
export function normalizeProposal(input, lookup) {
|
|
2
|
+
if (!isRecord(input)) {
|
|
3
|
+
return input;
|
|
4
|
+
}
|
|
5
|
+
const creates = isRecord(input.creates) ? input.creates : {};
|
|
6
|
+
const components = objectArray(creates.components);
|
|
7
|
+
const flows = objectArray(creates.flows);
|
|
8
|
+
const claims = objectArray(creates.claims);
|
|
9
|
+
const sources = objectArray(creates.sources);
|
|
10
|
+
const explicitEdges = objectArray(creates.edges);
|
|
11
|
+
const subjectTypes = new Map();
|
|
12
|
+
for (const component of components)
|
|
13
|
+
subjectTypes.set(component.id, "component");
|
|
14
|
+
for (const flow of flows)
|
|
15
|
+
subjectTypes.set(flow.id, "flow");
|
|
16
|
+
for (const claim of claims)
|
|
17
|
+
subjectTypes.set(claim.id, "claim");
|
|
18
|
+
for (const source of sources)
|
|
19
|
+
subjectTypes.set(source.id, "source");
|
|
20
|
+
const normalizedComponents = components.map(({ contains: _contains, supersedes: _supersedes, ...component }) => component);
|
|
21
|
+
const normalizedFlows = flows.map(({ contains: _contains, touches: _touches, supersedes: _supersedes, ...flow }) => flow);
|
|
22
|
+
const normalizedClaims = claims.map(({ about: _about, evidenced_by: _evidencedBy, supersedes: _supersedes, ...claim }) => claim);
|
|
23
|
+
const edges = [];
|
|
24
|
+
for (const component of components) {
|
|
25
|
+
for (const target of asArray(component.contains)) {
|
|
26
|
+
edges.push(makeEdge("contains", component.id, "component", target, "component"));
|
|
27
|
+
}
|
|
28
|
+
for (const target of asArray(component.supersedes)) {
|
|
29
|
+
edges.push(makeEdge("supersedes", component.id, "component", target, "component"));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
for (const flow of flows) {
|
|
33
|
+
for (const target of asArray(flow.contains)) {
|
|
34
|
+
edges.push(makeEdge("contains", flow.id, "flow", target, "flow"));
|
|
35
|
+
}
|
|
36
|
+
for (const target of asArray(flow.touches)) {
|
|
37
|
+
edges.push(makeEdge("touches", flow.id, "flow", target, "component"));
|
|
38
|
+
}
|
|
39
|
+
for (const target of asArray(flow.supersedes)) {
|
|
40
|
+
edges.push(makeEdge("supersedes", flow.id, "flow", target, "flow"));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
for (const claim of claims) {
|
|
44
|
+
for (const target of asArray(claim.about)) {
|
|
45
|
+
const targetType = resolveSubjectType(target, subjectTypes, lookup);
|
|
46
|
+
edges.push(makeEdge("about", claim.id, "claim", target, targetType ?? "component"));
|
|
47
|
+
}
|
|
48
|
+
for (const target of asArray(claim.evidenced_by)) {
|
|
49
|
+
edges.push(makeEdge("evidenced_by", claim.id, "claim", target, "source"));
|
|
50
|
+
}
|
|
51
|
+
for (const target of asArray(claim.supersedes)) {
|
|
52
|
+
edges.push(makeEdge("supersedes", claim.id, "claim", target, "claim"));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
for (const edge of explicitEdges) {
|
|
56
|
+
if (isCanonicalEdge(edge)) {
|
|
57
|
+
edges.push(edge);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const fromType = resolveSubjectType(edge.from, subjectTypes, lookup) ?? "component";
|
|
61
|
+
const toType = resolveSubjectType(edge.to, subjectTypes, lookup) ?? defaultToType(edge.kind);
|
|
62
|
+
edges.push(makeEdge(edge.kind, edge.from, fromType, edge.to, toType, edge.metadata));
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
title: typeof input.title === "string" ? input.title : "",
|
|
66
|
+
summary: typeof input.summary === "string" ? input.summary : undefined,
|
|
67
|
+
creates: {
|
|
68
|
+
components: normalizedComponents,
|
|
69
|
+
flows: normalizedFlows,
|
|
70
|
+
claims: normalizedClaims,
|
|
71
|
+
sources,
|
|
72
|
+
edges: dedupeEdges(edges),
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function makeEdge(kind, fromId, fromType, toId, toType, metadata) {
|
|
77
|
+
return {
|
|
78
|
+
id: edgeId(kind, fromType, fromId, toType, toId),
|
|
79
|
+
from_id: fromId,
|
|
80
|
+
from_type: fromType,
|
|
81
|
+
to_id: toId,
|
|
82
|
+
to_type: toType,
|
|
83
|
+
kind,
|
|
84
|
+
metadata,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function edgeId(kind, fromType, fromId, toType, toId) {
|
|
88
|
+
return `edge_${slug(kind)}_${slug(fromType)}_${slug(fromId)}_${slug(toType)}_${slug(toId)}`;
|
|
89
|
+
}
|
|
90
|
+
function dedupeEdges(edges) {
|
|
91
|
+
const seen = new Set();
|
|
92
|
+
const deduped = [];
|
|
93
|
+
for (const edge of edges) {
|
|
94
|
+
if (seen.has(edge.id))
|
|
95
|
+
continue;
|
|
96
|
+
seen.add(edge.id);
|
|
97
|
+
deduped.push(edge);
|
|
98
|
+
}
|
|
99
|
+
return deduped;
|
|
100
|
+
}
|
|
101
|
+
function resolveSubjectType(id, createdSubjects, lookup) {
|
|
102
|
+
return createdSubjects.get(id) ?? lookup?.subjectType(id);
|
|
103
|
+
}
|
|
104
|
+
function defaultToType(kind) {
|
|
105
|
+
switch (kind) {
|
|
106
|
+
case "about":
|
|
107
|
+
return "component";
|
|
108
|
+
case "contains":
|
|
109
|
+
return "component";
|
|
110
|
+
case "touches":
|
|
111
|
+
return "component";
|
|
112
|
+
case "supersedes":
|
|
113
|
+
return "component";
|
|
114
|
+
case "evidenced_by":
|
|
115
|
+
return "source";
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function asArray(value) {
|
|
119
|
+
if (value === undefined)
|
|
120
|
+
return [];
|
|
121
|
+
return Array.isArray(value) ? value : [value];
|
|
122
|
+
}
|
|
123
|
+
function objectArray(value) {
|
|
124
|
+
return Array.isArray(value) ? value : [];
|
|
125
|
+
}
|
|
126
|
+
function isCanonicalEdge(edge) {
|
|
127
|
+
return "from_id" in edge && "from_type" in edge && "to_id" in edge && "to_type" in edge;
|
|
128
|
+
}
|
|
129
|
+
function isRecord(value) {
|
|
130
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
131
|
+
}
|
|
132
|
+
function slug(value) {
|
|
133
|
+
return value.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=proposal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposal.js","sourceRoot":"","sources":["../../../libs/knowledge-graph/proposal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type GraphScopeId = string;
|
|
2
|
+
export type MemoryCommitId = string;
|
|
3
|
+
export type ComponentId = string;
|
|
4
|
+
export type FlowId = string;
|
|
5
|
+
export type ClaimId = string;
|
|
6
|
+
export type EdgeId = string;
|
|
7
|
+
export type SourceId = string;
|
|
8
|
+
export type GraphObjectType = "component" | "flow" | "claim" | "edge" | "source";
|
|
9
|
+
export type MembershipSubjectType = "component" | "flow" | "claim" | "edge";
|
|
10
|
+
export type SubjectIdByType = {
|
|
11
|
+
component: ComponentId;
|
|
12
|
+
flow: FlowId;
|
|
13
|
+
claim: ClaimId;
|
|
14
|
+
edge: EdgeId;
|
|
15
|
+
source: SourceId;
|
|
16
|
+
};
|
|
17
|
+
export interface Component {
|
|
18
|
+
id: ComponentId;
|
|
19
|
+
name: string;
|
|
20
|
+
code_anchor?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface Flow {
|
|
23
|
+
id: FlowId;
|
|
24
|
+
name: string;
|
|
25
|
+
}
|
|
26
|
+
export type SourceKind = "session";
|
|
27
|
+
export interface Source {
|
|
28
|
+
id: SourceId;
|
|
29
|
+
kind: SourceKind;
|
|
30
|
+
ref: string;
|
|
31
|
+
title?: string;
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../libs/knowledge-graph/schema.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GraphScopeId, MembershipSubjectType, MemoryCommitId } from "./schema.js";
|
|
2
|
+
export type GraphScopeKind = "main" | "working" | "branch" | "session" | "source";
|
|
3
|
+
export interface GraphScope {
|
|
4
|
+
id: GraphScopeId;
|
|
5
|
+
kind: GraphScopeKind;
|
|
6
|
+
name: string;
|
|
7
|
+
parent_scope_id?: GraphScopeId;
|
|
8
|
+
ref?: string;
|
|
9
|
+
created_at: string;
|
|
10
|
+
}
|
|
11
|
+
export interface GraphMembership {
|
|
12
|
+
scope_id: GraphScopeId;
|
|
13
|
+
subject_type: MembershipSubjectType;
|
|
14
|
+
subject_id: string;
|
|
15
|
+
memory_commit_id: MemoryCommitId;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../../libs/knowledge-graph/scope.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type ProposalValidationResult } from "./validate-proposal.js";
|
|
2
|
+
import type { Claim } from "./claim.js";
|
|
3
|
+
import type { Edge } from "./edge.js";
|
|
4
|
+
import type { Component, Flow, Source } from "./schema.js";
|
|
5
|
+
import { GraphContextBuilder } from "./graph-context/context-builder.js";
|
|
6
|
+
import { type GraphContextConfig } from "./graph-context/config.js";
|
|
7
|
+
import type { EmbeddingStatus, GraphContextResult } from "./graph-context/types.js";
|
|
8
|
+
import type { SqliteRepository } from "../storage/sqlite/repository.js";
|
|
9
|
+
export type { GraphContextResult } from "./graph-context/types.js";
|
|
10
|
+
export interface RepoRef {
|
|
11
|
+
repo_root?: string;
|
|
12
|
+
remote_url?: string;
|
|
13
|
+
repo_name: string;
|
|
14
|
+
default_branch: string;
|
|
15
|
+
}
|
|
16
|
+
export interface InitRepoResult {
|
|
17
|
+
repo_id: string;
|
|
18
|
+
main_scope_id: string;
|
|
19
|
+
working_scope_id: string;
|
|
20
|
+
database_path: string;
|
|
21
|
+
created: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface GraphReadResult {
|
|
24
|
+
components: Component[];
|
|
25
|
+
flows: Flow[];
|
|
26
|
+
claims: Claim[];
|
|
27
|
+
sources: Source[];
|
|
28
|
+
edges: Edge[];
|
|
29
|
+
}
|
|
30
|
+
export interface ApplyProposalResult {
|
|
31
|
+
memory_commit_id: string;
|
|
32
|
+
scope_id: string;
|
|
33
|
+
embedding_status: EmbeddingStatus;
|
|
34
|
+
created: {
|
|
35
|
+
components: number;
|
|
36
|
+
flows: number;
|
|
37
|
+
claims: number;
|
|
38
|
+
sources: number;
|
|
39
|
+
edges: number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export declare class KnowledgeGraphService {
|
|
43
|
+
private readonly repository;
|
|
44
|
+
private readonly contextConfig;
|
|
45
|
+
private readonly contextBuilder;
|
|
46
|
+
constructor(repository: SqliteRepository, contextConfig?: GraphContextConfig, contextBuilder?: GraphContextBuilder);
|
|
47
|
+
initRepo(input: RepoRef): InitRepoResult;
|
|
48
|
+
readGraph(input: RepoRef): GraphReadResult;
|
|
49
|
+
contextGraph(input: RepoRef, query: string): Promise<GraphContextResult>;
|
|
50
|
+
validateProposal(input: RepoRef, proposal: unknown): ProposalValidationResult;
|
|
51
|
+
applyProposal(input: RepoRef, proposal: unknown): Promise<ApplyProposalResult>;
|
|
52
|
+
private ensureInitialized;
|
|
53
|
+
}
|
|
54
|
+
export declare function createLocalKnowledgeGraphService(config?: GraphContextConfig): KnowledgeGraphService;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { normalizeProposal } from "./proposal.js";
|
|
2
|
+
import { validateProposal } from "./validate-proposal.js";
|
|
3
|
+
import { GraphContextBuilder } from "./graph-context/context-builder.js";
|
|
4
|
+
import { graphContextConfig } from "./graph-context/config.js";
|
|
5
|
+
import { defaultDatabasePath, openDatabase } from "../storage/sqlite/db.js";
|
|
6
|
+
import { SqliteRepository as SqliteKnowledgeGraphRepository } from "../storage/sqlite/repository.js";
|
|
7
|
+
export class KnowledgeGraphService {
|
|
8
|
+
repository;
|
|
9
|
+
contextConfig;
|
|
10
|
+
contextBuilder;
|
|
11
|
+
constructor(repository, contextConfig = graphContextConfig, contextBuilder = new GraphContextBuilder(repository)) {
|
|
12
|
+
this.repository = repository;
|
|
13
|
+
this.contextConfig = contextConfig;
|
|
14
|
+
this.contextBuilder = contextBuilder;
|
|
15
|
+
}
|
|
16
|
+
initRepo(input) {
|
|
17
|
+
const { repo, created } = this.repository.upsertRepo(input);
|
|
18
|
+
const main = this.repository.ensureScope({
|
|
19
|
+
repo_id: repo.id,
|
|
20
|
+
kind: "main",
|
|
21
|
+
name: input.default_branch,
|
|
22
|
+
ref: input.default_branch,
|
|
23
|
+
});
|
|
24
|
+
const working = this.repository.ensureScope({
|
|
25
|
+
repo_id: repo.id,
|
|
26
|
+
kind: "working",
|
|
27
|
+
name: "working",
|
|
28
|
+
parent_scope_id: main.id,
|
|
29
|
+
ref: "working",
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
repo_id: repo.id,
|
|
33
|
+
main_scope_id: main.id,
|
|
34
|
+
working_scope_id: working.id,
|
|
35
|
+
database_path: defaultDatabasePath(),
|
|
36
|
+
created,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
readGraph(input) {
|
|
40
|
+
const initialized = this.ensureInitialized(input);
|
|
41
|
+
return this.repository.readGraphView(initialized.repo_id);
|
|
42
|
+
}
|
|
43
|
+
async contextGraph(input, query) {
|
|
44
|
+
const initialized = this.ensureInitialized(input);
|
|
45
|
+
return this.contextBuilder.build(initialized.repo_id, this.repository.readGraphView(initialized.repo_id), query, {
|
|
46
|
+
config: this.contextConfig,
|
|
47
|
+
warnOnCreatedEmbeddings: true,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
validateProposal(input, proposal) {
|
|
51
|
+
this.ensureInitialized(input);
|
|
52
|
+
return validateProposal(normalizeProposal(proposal, this.repository), this.repository);
|
|
53
|
+
}
|
|
54
|
+
async applyProposal(input, proposal) {
|
|
55
|
+
const normalizedProposal = normalizeProposal(proposal, this.repository);
|
|
56
|
+
const validation = this.validateProposal(input, normalizedProposal);
|
|
57
|
+
if (!validation.valid) {
|
|
58
|
+
throw new Error(`Proposal is invalid:\n${validation.errors.map((error) => `- ${error}`).join("\n")}`);
|
|
59
|
+
}
|
|
60
|
+
const initialized = this.ensureInitialized(input);
|
|
61
|
+
const working = this.repository.requireWorkingScope(initialized.repo_id);
|
|
62
|
+
const memoryCommit = this.repository.createMemoryCommit({
|
|
63
|
+
scope_id: working.id,
|
|
64
|
+
title: normalizedProposal.title,
|
|
65
|
+
summary: normalizedProposal.summary,
|
|
66
|
+
});
|
|
67
|
+
this.repository.createProposalRecords(working.id, memoryCommit.id, normalizedProposal);
|
|
68
|
+
const embeddingStatus = await this.contextBuilder.ensureForGraph(initialized.repo_id, this.repository.readGraphView(initialized.repo_id), this.contextConfig);
|
|
69
|
+
return {
|
|
70
|
+
memory_commit_id: memoryCommit.id,
|
|
71
|
+
scope_id: working.id,
|
|
72
|
+
embedding_status: embeddingStatus,
|
|
73
|
+
created: {
|
|
74
|
+
components: normalizedProposal.creates.components?.length ?? 0,
|
|
75
|
+
flows: normalizedProposal.creates.flows?.length ?? 0,
|
|
76
|
+
claims: normalizedProposal.creates.claims?.length ?? 0,
|
|
77
|
+
sources: normalizedProposal.creates.sources?.length ?? 0,
|
|
78
|
+
edges: normalizedProposal.creates.edges?.length ?? 0,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
ensureInitialized(input) {
|
|
83
|
+
return this.initRepo(input);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export function createLocalKnowledgeGraphService(config = graphContextConfig) {
|
|
87
|
+
return new KnowledgeGraphService(new SqliteKnowledgeGraphRepository(openDatabase()), config);
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../libs/knowledge-graph/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAiC,MAAM,wBAAwB,CAAC;AAIzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAA2B,MAAM,2BAA2B,CAAC;AAExF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5E,OAAO,EAAE,gBAAgB,IAAI,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AAwCrG,MAAM,OAAO,qBAAqB;IAEb;IACA;IACA;IAHnB,YACmB,UAA4B,EAC5B,gBAAoC,kBAAkB,EACtD,iBAAiB,IAAI,mBAAmB,CAAC,UAAU,CAAC;QAFpD,eAAU,GAAV,UAAU,CAAkB;QAC5B,kBAAa,GAAb,aAAa,CAAyC;QACtD,mBAAc,GAAd,cAAc,CAAsC;IACpE,CAAC;IAEJ,QAAQ,CAAC,KAAc;QACrB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;YACvC,OAAO,EAAE,IAAI,CAAC,EAAE;YAChB,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,KAAK,CAAC,cAAc;YAC1B,GAAG,EAAE,KAAK,CAAC,cAAc;SAC1B,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;YAC1C,OAAO,EAAE,IAAI,CAAC,EAAE;YAChB,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,eAAe,EAAE,IAAI,CAAC,EAAE;YACxB,GAAG,EAAE,SAAS;SACf,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,EAAE;YAChB,aAAa,EAAE,IAAI,CAAC,EAAE;YACtB,gBAAgB,EAAE,OAAO,CAAC,EAAE;YAC5B,aAAa,EAAE,mBAAmB,EAAE;YACpC,OAAO;SACR,CAAC;IACJ,CAAC;IAED,SAAS,CAAC,KAAc;QACtB,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAc,EAAE,KAAa;QAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE;YAC/G,MAAM,EAAE,IAAI,CAAC,aAAa;YAC1B,uBAAuB,EAAE,IAAI;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,KAAc,EAAE,QAAiB;QAChD,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC9B,OAAO,gBAAgB,CAAC,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACzF,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAAc,EAAE,QAAiB;QACnD,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACxE,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;QACpE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,yBAAyB,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxG,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACzE,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC;YACtD,QAAQ,EAAE,OAAO,CAAC,EAAE;YACpB,KAAK,EAAE,kBAAkB,CAAC,KAAK;YAC/B,OAAO,EAAE,kBAAkB,CAAC,OAAO;SACpC,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,EAAE,YAAY,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC;QACvF,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,cAAc,CAC9D,WAAW,CAAC,OAAO,EACnB,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,EAClD,IAAI,CAAC,aAAa,CACnB,CAAC;QAEF,OAAO;YACL,gBAAgB,EAAE,YAAY,CAAC,EAAE;YACjC,QAAQ,EAAE,OAAO,CAAC,EAAE;YACpB,gBAAgB,EAAE,eAAe;YACjC,OAAO,EAAE;gBACP,UAAU,EAAE,kBAAkB,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;gBAC9D,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;gBACpD,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC;gBACtD,OAAO,EAAE,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;gBACxD,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;aACrD;SACF,CAAC;IACJ,CAAC;IAEO,iBAAiB,CAAC,KAAc;QACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,UAAU,gCAAgC,CAAC,SAA6B,kBAAkB;IAC9F,OAAO,IAAI,qBAAqB,CAAC,IAAI,8BAA8B,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AAC/F,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GraphObjectType } from "./schema.js";
|
|
2
|
+
export interface ExistingSubjectLookup {
|
|
3
|
+
subjectExists(type: GraphObjectType, id: string): boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface ProposalValidationResult {
|
|
6
|
+
valid: boolean;
|
|
7
|
+
errors: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function validateProposal(proposal: unknown, existingSubjects?: ExistingSubjectLookup): ProposalValidationResult;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { isAllowedEdge } from "./edge.js";
|
|
2
|
+
const claimKinds = new Set(["fact", "requirement", "decision", "task", "question", "risk"]);
|
|
3
|
+
const claimTruths = new Set(["code_verified", "source_verified", "unknown"]);
|
|
4
|
+
const claimIntents = new Set(["intended", "accidental", "unknown"]);
|
|
5
|
+
const sourceKinds = new Set(["session"]);
|
|
6
|
+
const edgeKinds = new Set(["about", "contains", "touches", "supersedes", "evidenced_by"]);
|
|
7
|
+
const graphObjectTypes = new Set(["component", "flow", "claim", "edge", "source"]);
|
|
8
|
+
export function validateProposal(proposal, existingSubjects) {
|
|
9
|
+
const errors = [];
|
|
10
|
+
if (!isRecord(proposal)) {
|
|
11
|
+
return { valid: false, errors: ["Proposal must be an object."] };
|
|
12
|
+
}
|
|
13
|
+
if (!isNonEmptyString(proposal.title)) {
|
|
14
|
+
errors.push("Proposal title must be a non-empty string.");
|
|
15
|
+
}
|
|
16
|
+
if (proposal.summary !== undefined && typeof proposal.summary !== "string") {
|
|
17
|
+
errors.push("Proposal summary must be a string when present.");
|
|
18
|
+
}
|
|
19
|
+
if (!isRecord(proposal.creates)) {
|
|
20
|
+
errors.push("Proposal creates must be an object.");
|
|
21
|
+
return { valid: false, errors };
|
|
22
|
+
}
|
|
23
|
+
const typedProposal = proposal;
|
|
24
|
+
const creates = typedProposal.creates ?? {};
|
|
25
|
+
const ids = new Map();
|
|
26
|
+
const components = arrayField(creates, "components", errors);
|
|
27
|
+
const flows = arrayField(creates, "flows", errors);
|
|
28
|
+
const claims = arrayField(creates, "claims", errors);
|
|
29
|
+
const sources = arrayField(creates, "sources", errors);
|
|
30
|
+
const edges = arrayField(creates, "edges", errors);
|
|
31
|
+
for (const component of components) {
|
|
32
|
+
if (!isRecord(component)) {
|
|
33
|
+
errors.push("Every component must be an object.");
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
validateSubjectBase("component", component.id, ids, existingSubjects, errors);
|
|
37
|
+
if (!isNonEmptyString(component.name))
|
|
38
|
+
errors.push(`Component ${stringId(component.id)} needs a name.`);
|
|
39
|
+
if (component.code_anchor !== undefined && typeof component.code_anchor !== "string") {
|
|
40
|
+
errors.push(`Component ${stringId(component.id)} code_anchor must be a string when present.`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
for (const flow of flows) {
|
|
44
|
+
if (!isRecord(flow)) {
|
|
45
|
+
errors.push("Every flow must be an object.");
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
validateSubjectBase("flow", flow.id, ids, existingSubjects, errors);
|
|
49
|
+
if (!isNonEmptyString(flow.name))
|
|
50
|
+
errors.push(`Flow ${stringId(flow.id)} needs a name.`);
|
|
51
|
+
}
|
|
52
|
+
for (const claim of claims) {
|
|
53
|
+
if (!isRecord(claim)) {
|
|
54
|
+
errors.push("Every claim must be an object.");
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
validateSubjectBase("claim", claim.id, ids, existingSubjects, errors);
|
|
58
|
+
if (!claimKinds.has(String(claim.kind)))
|
|
59
|
+
errors.push(`Claim ${stringId(claim.id)} has invalid kind.`);
|
|
60
|
+
if (!isNonEmptyString(claim.text))
|
|
61
|
+
errors.push(`Claim ${stringId(claim.id)} needs text.`);
|
|
62
|
+
if (!claimTruths.has(String(claim.truth)))
|
|
63
|
+
errors.push(`Claim ${stringId(claim.id)} has invalid truth.`);
|
|
64
|
+
if (!claimIntents.has(String(claim.intent)))
|
|
65
|
+
errors.push(`Claim ${stringId(claim.id)} has invalid intent.`);
|
|
66
|
+
}
|
|
67
|
+
for (const source of sources) {
|
|
68
|
+
if (!isRecord(source)) {
|
|
69
|
+
errors.push("Every source must be an object.");
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
validateSubjectBase("source", source.id, ids, existingSubjects, errors);
|
|
73
|
+
if (!sourceKinds.has(String(source.kind)))
|
|
74
|
+
errors.push(`Source ${stringId(source.id)} has invalid kind.`);
|
|
75
|
+
if (!isNonEmptyString(source.ref))
|
|
76
|
+
errors.push(`Source ${stringId(source.id)} needs ref.`);
|
|
77
|
+
if (source.title !== undefined && typeof source.title !== "string") {
|
|
78
|
+
errors.push(`Source ${stringId(source.id)} title must be a string when present.`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
for (const edge of edges) {
|
|
82
|
+
if (!isRecord(edge)) {
|
|
83
|
+
errors.push("Every edge must be an object.");
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
validateSubjectBase("edge", edge.id, ids, existingSubjects, errors);
|
|
87
|
+
const fromType = String(edge.from_type);
|
|
88
|
+
const toType = String(edge.to_type);
|
|
89
|
+
const kind = String(edge.kind);
|
|
90
|
+
if (!graphObjectTypes.has(fromType))
|
|
91
|
+
errors.push(`Edge ${stringId(edge.id)} has invalid from_type.`);
|
|
92
|
+
if (!graphObjectTypes.has(toType))
|
|
93
|
+
errors.push(`Edge ${stringId(edge.id)} has invalid to_type.`);
|
|
94
|
+
if (!edgeKinds.has(kind))
|
|
95
|
+
errors.push(`Edge ${stringId(edge.id)} has invalid kind.`);
|
|
96
|
+
if (graphObjectTypes.has(fromType) && !subjectRefExists(fromType, String(edge.from_id), ids, existingSubjects)) {
|
|
97
|
+
errors.push(`Edge ${stringId(edge.id)} references missing from subject ${fromType}:${String(edge.from_id)}.`);
|
|
98
|
+
}
|
|
99
|
+
if (graphObjectTypes.has(toType) && !subjectRefExists(toType, String(edge.to_id), ids, existingSubjects)) {
|
|
100
|
+
errors.push(`Edge ${stringId(edge.id)} references missing to subject ${toType}:${String(edge.to_id)}.`);
|
|
101
|
+
}
|
|
102
|
+
if (graphObjectTypes.has(fromType) &&
|
|
103
|
+
graphObjectTypes.has(toType) &&
|
|
104
|
+
edgeKinds.has(kind) &&
|
|
105
|
+
!isAllowedEdge({ from_type: fromType, to_type: toType, kind })) {
|
|
106
|
+
errors.push(`Edge ${stringId(edge.id)} has invalid direction for ${kind}.`);
|
|
107
|
+
}
|
|
108
|
+
if (edge.metadata !== undefined && !isRecord(edge.metadata)) {
|
|
109
|
+
errors.push(`Edge ${stringId(edge.id)} metadata must be an object when present.`);
|
|
110
|
+
}
|
|
111
|
+
if (kind === "evidenced_by") {
|
|
112
|
+
validateEvidenceMetadata(edge, errors);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return { valid: errors.length === 0, errors };
|
|
116
|
+
}
|
|
117
|
+
function validateEvidenceMetadata(edge, errors) {
|
|
118
|
+
if (!isRecord(edge.metadata)) {
|
|
119
|
+
errors.push(`Edge ${stringId(edge.id)} evidenced_by edges require metadata.reason.`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const reason = edge.metadata.reason;
|
|
123
|
+
if (!isNonEmptyString(reason)) {
|
|
124
|
+
errors.push(`Edge ${stringId(edge.id)} evidenced_by metadata.reason must be a non-empty string.`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function validateSubjectBase(type, id, ids, existingSubjects, errors) {
|
|
128
|
+
if (!isNonEmptyString(id)) {
|
|
129
|
+
errors.push(`${type} must have a non-empty id.`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const key = subjectKey(type, id);
|
|
133
|
+
if (ids.has(key)) {
|
|
134
|
+
errors.push(`Duplicate id ${key} in proposal.`);
|
|
135
|
+
}
|
|
136
|
+
ids.set(key, { type, id });
|
|
137
|
+
if (existingSubjects?.subjectExists(type, id)) {
|
|
138
|
+
errors.push(`${key} already exists.`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function subjectRefExists(type, id, ids, existingSubjects) {
|
|
142
|
+
return ids.has(subjectKey(type, id)) || existingSubjects?.subjectExists(type, id) === true;
|
|
143
|
+
}
|
|
144
|
+
function subjectKey(type, id) {
|
|
145
|
+
return `${type}:${id}`;
|
|
146
|
+
}
|
|
147
|
+
function isRecord(value) {
|
|
148
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
149
|
+
}
|
|
150
|
+
function isNonEmptyString(value) {
|
|
151
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
152
|
+
}
|
|
153
|
+
function arrayField(source, key, errors) {
|
|
154
|
+
const value = source[key];
|
|
155
|
+
if (value === undefined)
|
|
156
|
+
return [];
|
|
157
|
+
if (!Array.isArray(value)) {
|
|
158
|
+
errors.push(`creates.${key} must be an array when present.`);
|
|
159
|
+
return [];
|
|
160
|
+
}
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
163
|
+
function stringId(value) {
|
|
164
|
+
return typeof value === "string" && value.length > 0 ? value : "<missing>";
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=validate-proposal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-proposal.js","sourceRoot":"","sources":["../../../libs/knowledge-graph/validate-proposal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import { mkdirSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { greplicaHome } from "../../config/greplica-home.js";
|
|
5
|
+
import { migrate } from "./migrate.js";
|
|
6
|
+
export function defaultDatabasePath() {
|
|
7
|
+
return join(greplicaHome(), "graph.db");
|
|
8
|
+
}
|
|
9
|
+
export function openDatabase(path = defaultDatabasePath()) {
|
|
10
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
11
|
+
const db = new Database(path);
|
|
12
|
+
db.pragma("foreign_keys = ON");
|
|
13
|
+
migrate(db);
|
|
14
|
+
return db;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../../../libs/storage/sqlite/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,CAAC,YAAY,EAAE,EAAE,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAI,GAAG,mBAAmB,EAAE;IACvD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { schemaSql } from "./schema.js";
|
|
2
|
+
export function migrate(db) {
|
|
3
|
+
db.exec(schemaSql);
|
|
4
|
+
migrateReposTable(db);
|
|
5
|
+
}
|
|
6
|
+
function migrateReposTable(db) {
|
|
7
|
+
const columns = db.prepare("PRAGMA table_info(repos)").all();
|
|
8
|
+
const remoteUrl = columns.find((column) => column.name === "remote_url");
|
|
9
|
+
const hasRootPath = columns.some((column) => column.name === "root_path");
|
|
10
|
+
if (hasRootPath && remoteUrl?.notnull === 0)
|
|
11
|
+
return;
|
|
12
|
+
const foreignKeys = db.pragma("foreign_keys", { simple: true });
|
|
13
|
+
const legacyAlterTable = db.pragma("legacy_alter_table", { simple: true });
|
|
14
|
+
db.pragma("foreign_keys = OFF");
|
|
15
|
+
db.pragma("legacy_alter_table = ON");
|
|
16
|
+
try {
|
|
17
|
+
db.exec(`
|
|
18
|
+
BEGIN;
|
|
19
|
+
ALTER TABLE repos RENAME TO repos_old;
|
|
20
|
+
CREATE TABLE repos (
|
|
21
|
+
id TEXT PRIMARY KEY,
|
|
22
|
+
remote_url TEXT UNIQUE,
|
|
23
|
+
root_path TEXT UNIQUE,
|
|
24
|
+
repo_name TEXT NOT NULL,
|
|
25
|
+
default_branch TEXT NOT NULL
|
|
26
|
+
);
|
|
27
|
+
INSERT INTO repos (id, remote_url, root_path, repo_name, default_branch)
|
|
28
|
+
SELECT
|
|
29
|
+
id,
|
|
30
|
+
CASE
|
|
31
|
+
WHEN remote_url LIKE 'folder:%' THEN NULL
|
|
32
|
+
WHEN remote_url LIKE 'local:%' THEN NULL
|
|
33
|
+
ELSE remote_url
|
|
34
|
+
END,
|
|
35
|
+
CASE
|
|
36
|
+
WHEN remote_url LIKE 'folder:%' THEN substr(remote_url, 8)
|
|
37
|
+
WHEN remote_url LIKE 'local:%' THEN substr(remote_url, 7)
|
|
38
|
+
ELSE NULL
|
|
39
|
+
END,
|
|
40
|
+
repo_name,
|
|
41
|
+
default_branch
|
|
42
|
+
FROM repos_old;
|
|
43
|
+
DROP TABLE repos_old;
|
|
44
|
+
COMMIT;
|
|
45
|
+
`);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
db.exec("ROLLBACK;");
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
db.pragma(`legacy_alter_table = ${legacyAlterTable ? "ON" : "OFF"}`);
|
|
53
|
+
db.pragma(`foreign_keys = ${foreignKeys ? "ON" : "OFF"}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../../libs/storage/sqlite/migrate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,UAAU,OAAO,CAAC,EAAqB;IAC3C,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAqB;IAC9C,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,GAAG,EAGxD,CAAC;IACH,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;IAC1E,IAAI,WAAW,IAAI,SAAS,EAAE,OAAO,KAAK,CAAC;QAAE,OAAO;IAEpD,MAAM,WAAW,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAW,CAAC;IAC1E,MAAM,gBAAgB,GAAG,EAAE,CAAC,MAAM,CAAC,oBAAoB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAW,CAAC;IACrF,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;IACrC,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4BP,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACrB,MAAM,KAAK,CAAC;IACd,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,MAAM,CAAC,wBAAwB,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACrE,EAAE,CAAC,MAAM,CAAC,kBAAkB,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC"}
|