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.
Files changed (115) hide show
  1. package/README.md +177 -0
  2. package/dist/apps/cli/main.d.ts +2 -0
  3. package/dist/apps/cli/main.js +404 -0
  4. package/dist/apps/cli/main.js.map +1 -0
  5. package/dist/apps/cli/repo-context.d.ts +2 -0
  6. package/dist/apps/cli/repo-context.js +58 -0
  7. package/dist/apps/cli/repo-context.js.map +1 -0
  8. package/dist/libs/agent-runner/codex.d.ts +2 -0
  9. package/dist/libs/agent-runner/codex.js +53 -0
  10. package/dist/libs/agent-runner/codex.js.map +1 -0
  11. package/dist/libs/agent-runner/metrics.d.ts +10 -0
  12. package/dist/libs/agent-runner/metrics.js +72 -0
  13. package/dist/libs/agent-runner/metrics.js.map +1 -0
  14. package/dist/libs/agent-runner/types.d.ts +23 -0
  15. package/dist/libs/agent-runner/types.js +2 -0
  16. package/dist/libs/agent-runner/types.js.map +1 -0
  17. package/dist/libs/config/greplica-config.d.ts +24 -0
  18. package/dist/libs/config/greplica-config.js +121 -0
  19. package/dist/libs/config/greplica-config.js.map +1 -0
  20. package/dist/libs/config/greplica-home.d.ts +1 -0
  21. package/dist/libs/config/greplica-home.js +6 -0
  22. package/dist/libs/config/greplica-home.js.map +1 -0
  23. package/dist/libs/env/load-local-env.d.ts +19 -0
  24. package/dist/libs/env/load-local-env.js +69 -0
  25. package/dist/libs/env/load-local-env.js.map +1 -0
  26. package/dist/libs/install/edit-marked-section.d.ts +1 -0
  27. package/dist/libs/install/edit-marked-section.js +22 -0
  28. package/dist/libs/install/edit-marked-section.js.map +1 -0
  29. package/dist/libs/install/install.d.ts +18 -0
  30. package/dist/libs/install/install.js +80 -0
  31. package/dist/libs/install/install.js.map +1 -0
  32. package/dist/libs/install/instruction-blocks.d.ts +1 -0
  33. package/dist/libs/install/instruction-blocks.js +13 -0
  34. package/dist/libs/install/instruction-blocks.js.map +1 -0
  35. package/dist/libs/install/paths.d.ts +12 -0
  36. package/dist/libs/install/paths.js +31 -0
  37. package/dist/libs/install/paths.js.map +1 -0
  38. package/dist/libs/knowledge-graph/claim.d.ts +11 -0
  39. package/dist/libs/knowledge-graph/claim.js +2 -0
  40. package/dist/libs/knowledge-graph/claim.js.map +1 -0
  41. package/dist/libs/knowledge-graph/commit.d.ts +10 -0
  42. package/dist/libs/knowledge-graph/commit.js +2 -0
  43. package/dist/libs/knowledge-graph/commit.js.map +1 -0
  44. package/dist/libs/knowledge-graph/edge.d.ts +13 -0
  45. package/dist/libs/knowledge-graph/edge.js +17 -0
  46. package/dist/libs/knowledge-graph/edge.js.map +1 -0
  47. package/dist/libs/knowledge-graph/folder-export.d.ts +6 -0
  48. package/dist/libs/knowledge-graph/folder-export.js +337 -0
  49. package/dist/libs/knowledge-graph/folder-export.js.map +1 -0
  50. package/dist/libs/knowledge-graph/graph-context/bm25.d.ts +9 -0
  51. package/dist/libs/knowledge-graph/graph-context/bm25.js +62 -0
  52. package/dist/libs/knowledge-graph/graph-context/bm25.js.map +1 -0
  53. package/dist/libs/knowledge-graph/graph-context/config.d.ts +39 -0
  54. package/dist/libs/knowledge-graph/graph-context/config.js +48 -0
  55. package/dist/libs/knowledge-graph/graph-context/config.js.map +1 -0
  56. package/dist/libs/knowledge-graph/graph-context/context-builder.d.ts +18 -0
  57. package/dist/libs/knowledge-graph/graph-context/context-builder.js +276 -0
  58. package/dist/libs/knowledge-graph/graph-context/context-builder.js.map +1 -0
  59. package/dist/libs/knowledge-graph/graph-context/documents.d.ts +20 -0
  60. package/dist/libs/knowledge-graph/graph-context/documents.js +81 -0
  61. package/dist/libs/knowledge-graph/graph-context/documents.js.map +1 -0
  62. package/dist/libs/knowledge-graph/graph-context/embedder.d.ts +6 -0
  63. package/dist/libs/knowledge-graph/graph-context/embedder.js +8 -0
  64. package/dist/libs/knowledge-graph/graph-context/embedder.js.map +1 -0
  65. package/dist/libs/knowledge-graph/graph-context/exact.d.ts +3 -0
  66. package/dist/libs/knowledge-graph/graph-context/exact.js +37 -0
  67. package/dist/libs/knowledge-graph/graph-context/exact.js.map +1 -0
  68. package/dist/libs/knowledge-graph/graph-context/local-embedder.d.ts +13 -0
  69. package/dist/libs/knowledge-graph/graph-context/local-embedder.js +74 -0
  70. package/dist/libs/knowledge-graph/graph-context/local-embedder.js.map +1 -0
  71. package/dist/libs/knowledge-graph/graph-context/openai-embedder.d.ts +14 -0
  72. package/dist/libs/knowledge-graph/graph-context/openai-embedder.js +59 -0
  73. package/dist/libs/knowledge-graph/graph-context/openai-embedder.js.map +1 -0
  74. package/dist/libs/knowledge-graph/graph-context/rank.d.ts +16 -0
  75. package/dist/libs/knowledge-graph/graph-context/rank.js +52 -0
  76. package/dist/libs/knowledge-graph/graph-context/rank.js.map +1 -0
  77. package/dist/libs/knowledge-graph/graph-context/render.d.ts +38 -0
  78. package/dist/libs/knowledge-graph/graph-context/render.js +114 -0
  79. package/dist/libs/knowledge-graph/graph-context/render.js.map +1 -0
  80. package/dist/libs/knowledge-graph/graph-context/types.d.ts +58 -0
  81. package/dist/libs/knowledge-graph/graph-context/types.js +2 -0
  82. package/dist/libs/knowledge-graph/graph-context/types.js.map +1 -0
  83. package/dist/libs/knowledge-graph/graph-context/vector.d.ts +3 -0
  84. package/dist/libs/knowledge-graph/graph-context/vector.js +25 -0
  85. package/dist/libs/knowledge-graph/graph-context/vector.js.map +1 -0
  86. package/dist/libs/knowledge-graph/proposal.d.ts +65 -0
  87. package/dist/libs/knowledge-graph/proposal.js +135 -0
  88. package/dist/libs/knowledge-graph/proposal.js.map +1 -0
  89. package/dist/libs/knowledge-graph/schema.d.ts +32 -0
  90. package/dist/libs/knowledge-graph/schema.js +2 -0
  91. package/dist/libs/knowledge-graph/schema.js.map +1 -0
  92. package/dist/libs/knowledge-graph/scope.d.ts +16 -0
  93. package/dist/libs/knowledge-graph/scope.js +2 -0
  94. package/dist/libs/knowledge-graph/scope.js.map +1 -0
  95. package/dist/libs/knowledge-graph/service.d.ts +54 -0
  96. package/dist/libs/knowledge-graph/service.js +89 -0
  97. package/dist/libs/knowledge-graph/service.js.map +1 -0
  98. package/dist/libs/knowledge-graph/validate-proposal.d.ts +9 -0
  99. package/dist/libs/knowledge-graph/validate-proposal.js +166 -0
  100. package/dist/libs/knowledge-graph/validate-proposal.js.map +1 -0
  101. package/dist/libs/storage/sqlite/db.d.ts +3 -0
  102. package/dist/libs/storage/sqlite/db.js +16 -0
  103. package/dist/libs/storage/sqlite/db.js.map +1 -0
  104. package/dist/libs/storage/sqlite/migrate.d.ts +2 -0
  105. package/dist/libs/storage/sqlite/migrate.js +56 -0
  106. package/dist/libs/storage/sqlite/migrate.js.map +1 -0
  107. package/dist/libs/storage/sqlite/repository.d.ts +95 -0
  108. package/dist/libs/storage/sqlite/repository.js +310 -0
  109. package/dist/libs/storage/sqlite/repository.js.map +1 -0
  110. package/dist/libs/storage/sqlite/schema.d.ts +1 -0
  111. package/dist/libs/storage/sqlite/schema.js +93 -0
  112. package/dist/libs/storage/sqlite/schema.js.map +1 -0
  113. package/package.json +37 -0
  114. package/skills/greplica-bootstrap/SKILL.md +116 -0
  115. package/skills/greplica-update-working-memory/SKILL.md +183 -0
@@ -0,0 +1,58 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { realpathSync } from "node:fs";
3
+ import { basename, resolve } from "node:path";
4
+ export function detectRepoContext(cwd = process.cwd()) {
5
+ const repoRoot = canonicalPath(gitOptional(cwd, ["rev-parse", "--show-toplevel"]));
6
+ if (repoRoot === undefined)
7
+ return folderContext(cwd);
8
+ const remoteUrl = gitOptional(repoRoot, ["config", "--get", "remote.origin.url"]);
9
+ return {
10
+ repo_root: repoRoot,
11
+ remote_url: remoteUrl,
12
+ repo_name: remoteUrl === undefined ? basename(repoRoot) : repoName(remoteUrl, repoRoot),
13
+ default_branch: defaultBranch(repoRoot),
14
+ };
15
+ }
16
+ function folderContext(cwd) {
17
+ const folderRoot = canonicalPath(cwd) ?? resolve(cwd);
18
+ return {
19
+ repo_root: folderRoot,
20
+ repo_name: basename(folderRoot),
21
+ default_branch: "main",
22
+ };
23
+ }
24
+ function canonicalPath(path) {
25
+ if (path === undefined)
26
+ return undefined;
27
+ try {
28
+ return realpathSync(path);
29
+ }
30
+ catch {
31
+ return resolve(path);
32
+ }
33
+ }
34
+ function defaultBranch(repoRoot) {
35
+ const remoteHead = gitOptional(repoRoot, ["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"]);
36
+ if (remoteHead?.startsWith("origin/"))
37
+ return remoteHead.slice("origin/".length);
38
+ return "main";
39
+ }
40
+ function repoName(remoteUrl, repoRoot) {
41
+ const withoutGit = remoteUrl.endsWith(".git") ? remoteUrl.slice(0, -4) : remoteUrl;
42
+ const lastPart = withoutGit.split(/[/:]/).filter(Boolean).at(-1);
43
+ return lastPart ?? basename(repoRoot);
44
+ }
45
+ function gitOptional(cwd, args) {
46
+ try {
47
+ const output = execFileSync("git", args, {
48
+ cwd,
49
+ encoding: "utf8",
50
+ stdio: ["ignore", "pipe", "ignore"],
51
+ }).trim();
52
+ return output.length > 0 ? output : undefined;
53
+ }
54
+ catch {
55
+ return undefined;
56
+ }
57
+ }
58
+ //# sourceMappingURL=repo-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-context.js","sourceRoot":"","sources":["../../../apps/cli/repo-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { AgentRunInput, AgentRunResult } from "./types.js";
2
+ export declare function runCodexAgent(input: AgentRunInput): Promise<AgentRunResult>;
@@ -0,0 +1,53 @@
1
+ import { createWriteStream } from "node:fs";
2
+ import { spawn } from "node:child_process";
3
+ import { collectAgentMetrics } from "./metrics.js";
4
+ export async function runCodexAgent(input) {
5
+ const startedAt = Date.now();
6
+ const transcript = createWriteStream(input.transcriptPath, { flags: "w" });
7
+ const result = await runCodexProcess(input, transcript);
8
+ transcript.end();
9
+ const elapsedMs = Date.now() - startedAt;
10
+ const metrics = collectAgentMetrics({
11
+ transcriptPath: input.transcriptPath,
12
+ });
13
+ return {
14
+ agent: "codex",
15
+ model: input.model,
16
+ elapsed_ms: elapsedMs,
17
+ transcript_path: input.transcriptPath,
18
+ final_message_path: input.finalMessagePath,
19
+ exit_code: result.exitCode,
20
+ signal: result.signal,
21
+ ...metrics,
22
+ };
23
+ }
24
+ function runCodexProcess(input, transcript) {
25
+ return new Promise((resolve, reject) => {
26
+ const child = spawn("codex", [
27
+ "--ask-for-approval",
28
+ "never",
29
+ "exec",
30
+ "--json",
31
+ "--model",
32
+ input.model,
33
+ "--cd",
34
+ input.cwd,
35
+ "--sandbox",
36
+ "danger-full-access",
37
+ "--output-last-message",
38
+ input.finalMessagePath,
39
+ "-",
40
+ ], {
41
+ cwd: input.cwd,
42
+ env: input.env,
43
+ stdio: ["pipe", "pipe", "inherit"],
44
+ });
45
+ child.once("error", reject);
46
+ child.stdout.pipe(transcript);
47
+ child.stdin.end(input.prompt);
48
+ child.once("close", (exitCode, signal) => {
49
+ resolve({ exitCode, signal });
50
+ });
51
+ });
52
+ }
53
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../libs/agent-runner/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGnD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAoB;IACtD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAC3E,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACxD,UAAU,CAAC,GAAG,EAAE,CAAC;IAEjB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACzC,MAAM,OAAO,GAAG,mBAAmB,CAAC;QAClC,cAAc,EAAE,KAAK,CAAC,cAAc;KACrC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,OAAO;QACd,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,UAAU,EAAE,SAAS;QACrB,eAAe,EAAE,KAAK,CAAC,cAAc;QACrC,kBAAkB,EAAE,KAAK,CAAC,gBAAgB;QAC1C,SAAS,EAAE,MAAM,CAAC,QAAQ;QAC1B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,GAAG,OAAO;KACX,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,KAAoB,EACpB,UAAiC;IAEjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CACjB,OAAO,EACP;YACE,oBAAoB;YACpB,OAAO;YACP,MAAM;YACN,QAAQ;YACR,SAAS;YACT,KAAK,CAAC,KAAK;YACX,MAAM;YACN,KAAK,CAAC,GAAG;YACT,WAAW;YACX,oBAAoB;YACpB,uBAAuB;YACvB,KAAK,CAAC,gBAAgB;YACtB,GAAG;SACJ,EACD;YACE,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;SACnC,CACF,CAAC;QAEF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;YACvC,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface AgentMetricInput {
2
+ transcriptPath: string;
3
+ }
4
+ export interface AgentMetrics {
5
+ tool_calls: number;
6
+ input_tokens: number | null;
7
+ output_tokens: number | null;
8
+ total_tokens: number | null;
9
+ }
10
+ export declare function collectAgentMetrics(input: AgentMetricInput): AgentMetrics;
@@ -0,0 +1,72 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ export function collectAgentMetrics(input) {
3
+ const transcript = readOptional(input.transcriptPath);
4
+ const toolCalls = countToolCalls(transcript);
5
+ const usage = usageFromTranscript(transcript);
6
+ const inputTokens = usage?.input_tokens ?? null;
7
+ const outputTokens = usage?.output_tokens ?? null;
8
+ return {
9
+ tool_calls: toolCalls,
10
+ input_tokens: inputTokens,
11
+ output_tokens: outputTokens,
12
+ total_tokens: inputTokens === null || outputTokens === null ? null : inputTokens + outputTokens,
13
+ };
14
+ }
15
+ function countToolCalls(jsonl) {
16
+ if (jsonl.trim().length === 0)
17
+ return 0;
18
+ let count = 0;
19
+ for (const line of jsonl.split("\n")) {
20
+ const event = parseJsonLine(line);
21
+ if (!event)
22
+ continue;
23
+ if (isRecord(event) && event.type === "item.started" && isRecord(event.item) && event.item.type === "command_execution") {
24
+ count += 1;
25
+ continue;
26
+ }
27
+ const text = JSON.stringify(event).toLowerCase();
28
+ if (text.includes("exec_command") ||
29
+ text.includes("command_begin") ||
30
+ text.includes("command_start") ||
31
+ text.includes("\"type\":\"tool_call\"") ||
32
+ text.includes("\"type\":\"function_call\"")) {
33
+ count += 1;
34
+ }
35
+ }
36
+ return count;
37
+ }
38
+ function usageFromTranscript(jsonl) {
39
+ let latest;
40
+ for (const line of jsonl.split("\n")) {
41
+ const event = parseJsonLine(line);
42
+ if (!isRecord(event) || !isRecord(event.usage))
43
+ continue;
44
+ const inputTokens = event.usage.input_tokens;
45
+ const outputTokens = event.usage.output_tokens;
46
+ if (typeof inputTokens === "number" && typeof outputTokens === "number") {
47
+ latest = {
48
+ input_tokens: inputTokens,
49
+ output_tokens: outputTokens,
50
+ };
51
+ }
52
+ }
53
+ return latest;
54
+ }
55
+ function parseJsonLine(line) {
56
+ const trimmed = line.trim();
57
+ if (trimmed.length === 0)
58
+ return undefined;
59
+ try {
60
+ return JSON.parse(trimmed);
61
+ }
62
+ catch {
63
+ return undefined;
64
+ }
65
+ }
66
+ function readOptional(path) {
67
+ return existsSync(path) ? readFileSync(path, "utf8") : "";
68
+ }
69
+ function isRecord(value) {
70
+ return typeof value === "object" && value !== null && !Array.isArray(value);
71
+ }
72
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../libs/agent-runner/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export type AgentKind = "codex";
2
+ export interface AgentRunInput {
3
+ cwd: string;
4
+ env: NodeJS.ProcessEnv;
5
+ model: string;
6
+ prompt: string;
7
+ transcriptPath: string;
8
+ finalMessagePath: string;
9
+ proposalPath?: string;
10
+ }
11
+ export interface AgentRunResult {
12
+ agent: AgentKind;
13
+ model: string;
14
+ elapsed_ms: number;
15
+ tool_calls: number;
16
+ input_tokens: number | null;
17
+ output_tokens: number | null;
18
+ total_tokens: number | null;
19
+ transcript_path: string;
20
+ final_message_path: string;
21
+ exit_code: number | null;
22
+ signal: string | null;
23
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../libs/agent-runner/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ export type EmbeddingProvider = "local" | "openai";
2
+ export interface EmbeddingConfig {
3
+ provider: EmbeddingProvider;
4
+ model: string;
5
+ dimensions: number;
6
+ batchSize: number;
7
+ }
8
+ export interface GreplicaConfig {
9
+ version: 1;
10
+ embedding: EmbeddingConfig;
11
+ }
12
+ export interface EmbeddingConfigInput {
13
+ provider: EmbeddingProvider;
14
+ model?: string;
15
+ dimensions?: number;
16
+ batchSize?: number;
17
+ }
18
+ export declare const defaultGreplicaConfig: GreplicaConfig;
19
+ export declare function defaultEmbeddingConfig(provider: EmbeddingProvider): EmbeddingConfig;
20
+ export declare function greplicaConfigPath(): string;
21
+ export declare function ensureGreplicaConfig(path?: string): GreplicaConfig;
22
+ export declare function readGreplicaConfig(path?: string): GreplicaConfig;
23
+ export declare function writeGreplicaConfig(config: GreplicaConfig, path?: string): void;
24
+ export declare function updateEmbeddingConfig(input: EmbeddingConfigInput, path?: string): GreplicaConfig;
@@ -0,0 +1,121 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { greplicaHome } from "./greplica-home.js";
4
+ const embeddingDefaults = {
5
+ local: {
6
+ provider: "local",
7
+ model: "all-mpnet-base-v2",
8
+ dimensions: 768,
9
+ batchSize: 16,
10
+ },
11
+ openai: {
12
+ provider: "openai",
13
+ model: "text-embedding-3-small",
14
+ dimensions: 1536,
15
+ batchSize: 100,
16
+ },
17
+ };
18
+ export const defaultGreplicaConfig = {
19
+ version: 1,
20
+ embedding: { ...embeddingDefaults.local },
21
+ };
22
+ export function defaultEmbeddingConfig(provider) {
23
+ return { ...embeddingDefaults[provider] };
24
+ }
25
+ export function greplicaConfigPath() {
26
+ return join(greplicaHome(), "config.json");
27
+ }
28
+ export function ensureGreplicaConfig(path = greplicaConfigPath()) {
29
+ if (!existsSync(path)) {
30
+ writeGreplicaConfig(defaultGreplicaConfig, path);
31
+ return cloneConfig(defaultGreplicaConfig);
32
+ }
33
+ return readGreplicaConfig(path);
34
+ }
35
+ export function readGreplicaConfig(path = greplicaConfigPath()) {
36
+ if (!existsSync(path))
37
+ return cloneConfig(defaultGreplicaConfig);
38
+ let parsed;
39
+ try {
40
+ parsed = JSON.parse(readFileSync(path, "utf8"));
41
+ }
42
+ catch (error) {
43
+ const message = error instanceof Error ? error.message : String(error);
44
+ throw new Error(`Invalid Greplica config at ${path}: ${message}`);
45
+ }
46
+ return normalizeConfig(parsed, path);
47
+ }
48
+ export function writeGreplicaConfig(config, path = greplicaConfigPath()) {
49
+ mkdirSync(dirname(path), { recursive: true });
50
+ writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`, "utf8");
51
+ }
52
+ export function updateEmbeddingConfig(input, path = greplicaConfigPath()) {
53
+ const base = defaultEmbeddingConfig(input.provider);
54
+ const config = {
55
+ version: 1,
56
+ embedding: {
57
+ ...base,
58
+ model: input.model ?? base.model,
59
+ dimensions: input.dimensions ?? base.dimensions,
60
+ batchSize: input.batchSize ?? base.batchSize,
61
+ },
62
+ };
63
+ writeGreplicaConfig(config, path);
64
+ return config;
65
+ }
66
+ function normalizeConfig(value, path) {
67
+ if (!isRecord(value))
68
+ throw new Error(`Invalid Greplica config at ${path}: expected an object.`);
69
+ const version = value.version === undefined ? 1 : value.version;
70
+ if (version !== 1)
71
+ throw new Error(`Invalid Greplica config at ${path}: unsupported version ${String(version)}.`);
72
+ const embeddingValue = value.embedding;
73
+ if (!isRecord(embeddingValue)) {
74
+ return cloneConfig(defaultGreplicaConfig);
75
+ }
76
+ const provider = parseProvider(embeddingValue.provider, path);
77
+ const defaults = defaultEmbeddingConfig(provider);
78
+ const model = parseString(embeddingValue.model, defaults.model, "embedding.model", path);
79
+ const dimensions = parsePositiveInteger(embeddingValue.dimensions, defaults.dimensions, "embedding.dimensions", path);
80
+ const batchSize = parsePositiveInteger(embeddingValue.batchSize, defaults.batchSize, "embedding.batchSize", path);
81
+ return {
82
+ version: 1,
83
+ embedding: {
84
+ provider,
85
+ model,
86
+ dimensions,
87
+ batchSize,
88
+ },
89
+ };
90
+ }
91
+ function parseProvider(value, path) {
92
+ if (value === "local" || value === "openai")
93
+ return value;
94
+ if (value === undefined)
95
+ return defaultGreplicaConfig.embedding.provider;
96
+ throw new Error(`Invalid Greplica config at ${path}: embedding.provider must be local or openai.`);
97
+ }
98
+ function parseString(value, fallback, field, path) {
99
+ if (value === undefined)
100
+ return fallback;
101
+ if (typeof value === "string" && value.trim().length > 0)
102
+ return value.trim();
103
+ throw new Error(`Invalid Greplica config at ${path}: ${field} must be a non-empty string.`);
104
+ }
105
+ function parsePositiveInteger(value, fallback, field, path) {
106
+ if (value === undefined)
107
+ return fallback;
108
+ if (typeof value === "number" && Number.isInteger(value) && value > 0)
109
+ return value;
110
+ throw new Error(`Invalid Greplica config at ${path}: ${field} must be a positive integer.`);
111
+ }
112
+ function isRecord(value) {
113
+ return typeof value === "object" && value !== null && !Array.isArray(value);
114
+ }
115
+ function cloneConfig(config) {
116
+ return {
117
+ version: config.version,
118
+ embedding: { ...config.embedding },
119
+ };
120
+ }
121
+ //# sourceMappingURL=greplica-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"greplica-config.js","sourceRoot":"","sources":["../../../libs/config/greplica-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function greplicaHome(): string;
@@ -0,0 +1,6 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ export function greplicaHome() {
4
+ return process.env.GREPLICA_HOME ?? process.env.ENGINEERING_CONTEXT_HOME ?? join(homedir(), ".greplica");
5
+ }
6
+ //# sourceMappingURL=greplica-home.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"greplica-home.js","sourceRoot":"","sources":["../../../libs/config/greplica-home.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,YAAY;IAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAC3G,CAAC"}
@@ -0,0 +1,19 @@
1
+ export declare function loadLocalEnv(file?: string): void;
2
+ export interface LoadedEnvFile {
3
+ path: string;
4
+ loaded_keys: string[];
5
+ skipped_existing_keys: string[];
6
+ }
7
+ export interface LoadedRepoEnv {
8
+ repo_root: string;
9
+ initial_env_keys: Set<string>;
10
+ files: LoadedEnvFile[];
11
+ }
12
+ export type EnvVarSource = {
13
+ kind: "environment";
14
+ } | {
15
+ kind: "file";
16
+ path: string;
17
+ };
18
+ export declare function loadRepoEnv(repoRoot: string): LoadedRepoEnv;
19
+ export declare function envVarSource(name: string, env: LoadedRepoEnv): EnvVarSource | undefined;
@@ -0,0 +1,69 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ export function loadLocalEnv(file = ".env.local") {
4
+ const path = resolve(process.cwd(), file);
5
+ if (!existsSync(path))
6
+ return;
7
+ loadEnvFile(path);
8
+ }
9
+ export function loadRepoEnv(repoRoot) {
10
+ const initialEnvKeys = new Set(Object.keys(process.env).filter(hasEnvValue));
11
+ const repoEnvKeys = new Set(["OPENAI_API_KEY"]);
12
+ const files = [".env.local", ".env"]
13
+ .map((file) => loadEnvFile(resolve(repoRoot, file), repoEnvKeys))
14
+ .filter((file) => file !== undefined);
15
+ return {
16
+ repo_root: repoRoot,
17
+ initial_env_keys: initialEnvKeys,
18
+ files,
19
+ };
20
+ }
21
+ export function envVarSource(name, env) {
22
+ if (env.initial_env_keys.has(name) && hasEnvValue(name))
23
+ return { kind: "environment" };
24
+ const loadedFromFile = env.files.find((file) => file.loaded_keys.includes(name));
25
+ if (loadedFromFile)
26
+ return { kind: "file", path: loadedFromFile.path };
27
+ return hasEnvValue(name) ? { kind: "environment" } : undefined;
28
+ }
29
+ function loadEnvFile(path, allowedKeys) {
30
+ if (!existsSync(path))
31
+ return undefined;
32
+ const loadedKeys = [];
33
+ const skippedExistingKeys = [];
34
+ for (const line of readFileSync(path, "utf8").split(/\r?\n/)) {
35
+ const trimmed = line.trim();
36
+ if (trimmed.length === 0 || trimmed.startsWith("#"))
37
+ continue;
38
+ const match = /^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(trimmed);
39
+ if (!match)
40
+ continue;
41
+ const [, key, rawValue] = match;
42
+ if (allowedKeys && !allowedKeys.has(key))
43
+ continue;
44
+ if (hasEnvValue(key)) {
45
+ skippedExistingKeys.push(key);
46
+ continue;
47
+ }
48
+ process.env[key] = unquoteEnvValue(rawValue ?? "");
49
+ loadedKeys.push(key);
50
+ }
51
+ return {
52
+ path,
53
+ loaded_keys: loadedKeys,
54
+ skipped_existing_keys: skippedExistingKeys,
55
+ };
56
+ }
57
+ function unquoteEnvValue(value) {
58
+ const trimmed = value.trim();
59
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
60
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
61
+ return trimmed.slice(1, -1);
62
+ }
63
+ return trimmed;
64
+ }
65
+ function hasEnvValue(key) {
66
+ const value = process.env[key];
67
+ return value !== undefined && value.trim().length > 0;
68
+ }
69
+ //# sourceMappingURL=load-local-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-local-env.js","sourceRoot":"","sources":["../../../libs/env/load-local-env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function replaceOrAppendSection(content: string, marker: string, newSection: string): string;
@@ -0,0 +1,22 @@
1
+ export function replaceOrAppendSection(content, marker, newSection) {
2
+ const section = newSection.trim();
3
+ if (!content.includes(marker)) {
4
+ return content.trim().length === 0 ? `${section}\n` : `${content.trimEnd()}\n\n${section}\n`;
5
+ }
6
+ const lines = content.split("\n");
7
+ const start = lines.findIndex((line) => line.includes(marker));
8
+ if (start < 0)
9
+ return `${content.trimEnd()}\n\n${section}\n`;
10
+ let end = lines.length;
11
+ for (let index = start + 1; index < lines.length; index += 1) {
12
+ if (lines[index].startsWith("## ")) {
13
+ end = index;
14
+ break;
15
+ }
16
+ }
17
+ const before = lines.slice(0, start).join("\n").trimEnd();
18
+ const after = lines.slice(end).join("\n").trimStart();
19
+ const parts = [before, section, after].filter((part) => part.length > 0);
20
+ return `${parts.join("\n\n")}\n`;
21
+ }
22
+ //# sourceMappingURL=edit-marked-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-marked-section.js","sourceRoot":"","sources":["../../../libs/install/edit-marked-section.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,sBAAsB,CAAC,OAAe,EAAE,MAAc,EAAE,UAAkB;IACxF,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,OAAO,OAAO,IAAI,CAAC;IAC/F,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,OAAO,OAAO,IAAI,CAAC;IAE7D,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;IACvB,KAAK,IAAI,KAAK,GAAG,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC7D,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,GAAG,GAAG,KAAK,CAAC;YACZ,MAAM;QACR,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IAC1D,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;IACtD,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzE,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;AACnC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { RepoRef } from "../knowledge-graph/service.js";
2
+ import { type InstallEmbedding, type InstallPlatform, type InstructionScope } from "./paths.js";
3
+ export interface InstallOptions {
4
+ platform: InstallPlatform;
5
+ instructions: InstructionScope;
6
+ embedding: InstallEmbedding;
7
+ repo: RepoRef;
8
+ }
9
+ export interface InstallResult {
10
+ platform: InstallPlatform;
11
+ skills: string[];
12
+ instructionFile?: string;
13
+ embedding: InstallEmbedding;
14
+ configFile: string;
15
+ databasePath: string;
16
+ notes: string[];
17
+ }
18
+ export declare function installGreplica(options: InstallOptions): Promise<InstallResult>;
@@ -0,0 +1,80 @@
1
+ import { cpSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { envVarSource, loadRepoEnv } from "../env/load-local-env.js";
4
+ import { greplicaConfigPath, updateEmbeddingConfig } from "../config/greplica-config.js";
5
+ import { graphContextConfigFromGreplicaConfig } from "../knowledge-graph/graph-context/config.js";
6
+ import { createLocalKnowledgeGraphService } from "../knowledge-graph/service.js";
7
+ import { greplicaInstructionBlock } from "./instruction-blocks.js";
8
+ import { replaceOrAppendSection } from "./edit-marked-section.js";
9
+ import { packageRoot, platformPaths, skillNames, } from "./paths.js";
10
+ export async function installGreplica(options) {
11
+ const projectRoot = options.repo.repo_root ?? process.cwd();
12
+ const paths = platformPaths(options.platform, projectRoot);
13
+ const skills = installSkills(paths.skillsRoot);
14
+ const instructionFile = installInstructions(options.instructions, paths.userInstructionFile, paths.projectInstructionFile);
15
+ const embedding = configureEmbedding(options.embedding, options.repo);
16
+ const service = createLocalKnowledgeGraphService(graphContextConfigFromGreplicaConfig(embedding.config));
17
+ const init = service.initRepo(options.repo);
18
+ const notes = [];
19
+ if (options.embedding === "local") {
20
+ notes.push("Local embeddings were configured without prewarming; the first graph-context query may download the local model.");
21
+ }
22
+ if (options.platform === "codex") {
23
+ notes.push("Restart Codex if the new skills do not appear immediately.");
24
+ }
25
+ else {
26
+ notes.push("Restart Claude Code if the new skills do not appear immediately.");
27
+ }
28
+ return {
29
+ platform: options.platform,
30
+ skills,
31
+ instructionFile,
32
+ embedding: options.embedding,
33
+ configFile: embedding.configPath,
34
+ databasePath: init.database_path,
35
+ notes,
36
+ };
37
+ }
38
+ function installSkills(skillsRoot) {
39
+ const root = packageRoot();
40
+ const installed = [];
41
+ mkdirSync(skillsRoot, { recursive: true });
42
+ for (const skillName of skillNames) {
43
+ const source = join(root, "skills", skillName);
44
+ if (!existsSync(join(source, "SKILL.md")))
45
+ throw new Error(`Bundled skill is missing: ${source}`);
46
+ const destination = join(skillsRoot, skillName);
47
+ const staged = `${destination}.tmp`;
48
+ rmSync(staged, { recursive: true, force: true });
49
+ cpSync(source, staged, { recursive: true });
50
+ rmSync(destination, { recursive: true, force: true });
51
+ renameSync(staged, destination);
52
+ installed.push(join(destination, "SKILL.md"));
53
+ }
54
+ return installed;
55
+ }
56
+ function installInstructions(scope, userFile, projectFile) {
57
+ if (scope === "none")
58
+ return undefined;
59
+ const file = scope === "user" ? userFile : projectFile;
60
+ const existing = existsSync(file) ? readFileSync(file, "utf8") : "";
61
+ const updated = replaceOrAppendSection(existing, "## Greplica", greplicaInstructionBlock);
62
+ mkdirSync(dirname(file), { recursive: true });
63
+ writeFileSync(file, updated, "utf8");
64
+ return resolve(file);
65
+ }
66
+ function configureEmbedding(provider, repo) {
67
+ const repoRoot = repo.repo_root ?? process.cwd();
68
+ if (provider === "openai") {
69
+ const env = loadRepoEnv(repoRoot);
70
+ if (envVarSource("OPENAI_API_KEY", env) === undefined) {
71
+ throw new Error("OPENAI_API_KEY is required for --embedding openai. Set it in the shell, target-root .env.local, or target-root .env.");
72
+ }
73
+ }
74
+ const config = updateEmbeddingConfig({ provider });
75
+ return {
76
+ config,
77
+ configPath: resolve(greplicaConfigPath()),
78
+ };
79
+ }
80
+ //# sourceMappingURL=install.js.map