@kabirlikestocode/engram 1.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 (41) hide show
  1. package/dist/commands/index-cmd.d.ts +4 -0
  2. package/dist/commands/index-cmd.d.ts.map +1 -0
  3. package/dist/commands/index-cmd.js +123 -0
  4. package/dist/commands/index-cmd.js.map +1 -0
  5. package/dist/commands/init.d.ts +2 -0
  6. package/dist/commands/init.d.ts.map +1 -0
  7. package/dist/commands/init.js +154 -0
  8. package/dist/commands/init.js.map +1 -0
  9. package/dist/commands/login.d.ts +2 -0
  10. package/dist/commands/login.d.ts.map +1 -0
  11. package/dist/commands/login.js +88 -0
  12. package/dist/commands/login.js.map +1 -0
  13. package/dist/commands/serve.d.ts +4 -0
  14. package/dist/commands/serve.d.ts.map +1 -0
  15. package/dist/commands/serve.js +45 -0
  16. package/dist/commands/serve.js.map +1 -0
  17. package/dist/commands/status.d.ts +4 -0
  18. package/dist/commands/status.d.ts.map +1 -0
  19. package/dist/commands/status.js +85 -0
  20. package/dist/commands/status.js.map +1 -0
  21. package/dist/commands/sync.d.ts +10 -0
  22. package/dist/commands/sync.d.ts.map +1 -0
  23. package/dist/commands/sync.js +106 -0
  24. package/dist/commands/sync.js.map +1 -0
  25. package/dist/commands/team.d.ts +9 -0
  26. package/dist/commands/team.d.ts.map +1 -0
  27. package/dist/commands/team.js +85 -0
  28. package/dist/commands/team.js.map +1 -0
  29. package/dist/config.d.ts +29 -0
  30. package/dist/config.d.ts.map +1 -0
  31. package/dist/config.js +81 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/daemon.d.ts +8 -0
  34. package/dist/daemon.d.ts.map +1 -0
  35. package/dist/daemon.js +124 -0
  36. package/dist/daemon.js.map +1 -0
  37. package/dist/index.d.ts +21 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +123 -0
  40. package/dist/index.js.map +1 -0
  41. package/package.json +39 -0
@@ -0,0 +1,106 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { resolve } from 'node:path';
4
+ import { CodeGraph, SyncClient, syncSymbolToLocal, syncEdgeToLocal } from '@kabirlikestocode/engram-core';
5
+ import { readCredentials, readProjectConfig, getApiUrl, getProjectDbPath, } from '../config.js';
6
+ async function getContext(opts) {
7
+ const creds = await readCredentials();
8
+ if (!creds || creds.expiresAt < Date.now()) {
9
+ console.error(chalk.red(' ✗ Not logged in. Run `engram login` first.\n'));
10
+ process.exit(1);
11
+ }
12
+ const projectRoot = resolve(opts.project ?? process.cwd());
13
+ const config = await readProjectConfig(projectRoot);
14
+ if (!config) {
15
+ console.error(chalk.red(' ✗ No Engram project here. Run `engram init` first.\n'));
16
+ process.exit(1);
17
+ }
18
+ if (!config.teamId) {
19
+ console.error(chalk.red(' ✗ No teamId in .engram/config.json. Set it with `engram team create`.\n'));
20
+ process.exit(1);
21
+ }
22
+ const client = new SyncClient(getApiUrl(), creds.token);
23
+ const dbPath = getProjectDbPath(projectRoot);
24
+ const graph = new CodeGraph(dbPath);
25
+ const projectName = projectRoot.split('/').pop() ?? 'unknown';
26
+ return { client, graph, config, projectRoot, projectName };
27
+ }
28
+ export async function syncPushCommand(opts) {
29
+ const { client, graph, config, projectName } = await getContext(opts);
30
+ const spinner = ora('Exporting local graph...').start();
31
+ try {
32
+ const data = graph.exportGraph();
33
+ spinner.text = `Pushing ${data.symbols.length} symbols, ${data.edges.length} edges, ${data.files.length} files...`;
34
+ const result = await client.pushGraph(config.teamId, projectName, data);
35
+ graph.close();
36
+ spinner.succeed(chalk.green(`Pushed to team cloud `) +
37
+ chalk.dim(`(v${result.version}) — `) +
38
+ chalk.dim(`${result.pushed.symbols} symbols, ${result.pushed.edges} edges, ${result.pushed.files} files`));
39
+ }
40
+ catch (err) {
41
+ graph.close();
42
+ spinner.fail(chalk.red(`Push failed: ${err.message}`));
43
+ }
44
+ }
45
+ export async function syncPullCommand(opts) {
46
+ const { client, graph, config, projectName } = await getContext(opts);
47
+ const spinner = ora('Pulling from team cloud...').start();
48
+ try {
49
+ const data = await client.pullGraph(config.teamId, projectName);
50
+ spinner.text = `Importing ${data.symbols.length} symbols, ${data.edges.length} edges, ${data.files.length} files...`;
51
+ const symbols = data.symbols.map(syncSymbolToLocal);
52
+ const edges = data.edges.map(syncEdgeToLocal);
53
+ const files = data.files.map((f) => ({
54
+ filePath: f.file_path,
55
+ checksum: f.checksum,
56
+ symbolCount: f.symbol_count,
57
+ language: f.language,
58
+ lastIndexed: f.last_indexed,
59
+ }));
60
+ const result = graph.importGraph({ symbols, edges, files });
61
+ graph.close();
62
+ spinner.succeed(chalk.green(`Pulled v${data.version} — `) +
63
+ chalk.dim(`merged ${result.imported.symbols} symbols, ${result.imported.edges} edges, ${result.imported.files} files`));
64
+ }
65
+ catch (err) {
66
+ graph.close();
67
+ spinner.fail(chalk.red(`Pull failed: ${err.message}`));
68
+ }
69
+ }
70
+ export async function syncStatusCommand(opts) {
71
+ const creds = await readCredentials();
72
+ if (!creds || creds.expiresAt < Date.now()) {
73
+ console.error(chalk.red(' ✗ Not logged in.\n'));
74
+ process.exit(1);
75
+ }
76
+ const projectRoot = resolve(opts.project ?? process.cwd());
77
+ const config = await readProjectConfig(projectRoot);
78
+ if (!config) {
79
+ console.error(chalk.red(' ✗ No Engram project here.\n'));
80
+ process.exit(1);
81
+ }
82
+ console.log(chalk.bold.green('\n ⬡ Sync Status\n'));
83
+ if (!config.teamId) {
84
+ console.log(chalk.dim(' Team: none'));
85
+ console.log(chalk.dim(' Set "teamId" in .engram/config.json to enable sync.\n'));
86
+ return;
87
+ }
88
+ const client = new SyncClient(getApiUrl(), creds.token);
89
+ const dbPath = getProjectDbPath(projectRoot);
90
+ const graph = new CodeGraph(dbPath);
91
+ const projectName = projectRoot.split('/').pop() ?? 'unknown';
92
+ const stats = graph.getStats();
93
+ graph.close();
94
+ console.log(` Team: ${chalk.bold(config.teamId)}`);
95
+ console.log(` Project: ${chalk.bold(projectName)}`);
96
+ console.log(` Local: ${chalk.cyan(stats.totalSymbols)} symbols, ${chalk.cyan(stats.totalEdges)} edges, ${chalk.cyan(stats.totalFiles)} files`);
97
+ try {
98
+ const data = await client.pullGraph(config.teamId, projectName);
99
+ console.log(` Cloud: ${chalk.cyan(data.symbols.length)} symbols, ${chalk.cyan(data.edges.length)} edges, ${chalk.cyan(data.files.length)} files (v${data.version})`);
100
+ }
101
+ catch {
102
+ console.log(chalk.dim(' Cloud: unable to connect'));
103
+ }
104
+ console.log();
105
+ }
106
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare function teamCreateCommand(name: string): Promise<void>;
2
+ export declare function teamListCommand(): Promise<void>;
3
+ export declare function teamInviteCommand(email: string, opts: {
4
+ team?: string;
5
+ }): Promise<void>;
6
+ export declare function teamMembersCommand(opts: {
7
+ team?: string;
8
+ }): Promise<void>;
9
+ //# sourceMappingURL=team.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.d.ts","sourceRoot":"","sources":["../../src/commands/team.ts"],"names":[],"mappings":"AAcA,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYnE;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBrD;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB7F;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB/E"}
@@ -0,0 +1,85 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { SyncClient } from '@kabirlikestocode/engram-core';
4
+ import { readCredentials, getApiUrl } from '../config.js';
5
+ async function getClient() {
6
+ const creds = await readCredentials();
7
+ if (!creds || creds.expiresAt < Date.now()) {
8
+ console.error(chalk.red(' ✗ Not logged in. Run `engram login` first.\n'));
9
+ process.exit(1);
10
+ }
11
+ return new SyncClient(getApiUrl(), creds.token);
12
+ }
13
+ export async function teamCreateCommand(name) {
14
+ const client = await getClient();
15
+ const spinner = ora(`Creating team "${name}"...`).start();
16
+ try {
17
+ const { team } = await client.createTeam(name);
18
+ spinner.succeed(chalk.green(`Team created: ${chalk.bold(team.name)}`));
19
+ console.log(chalk.dim(` ID: ${team.id}`));
20
+ console.log(chalk.dim(` Add this to .engram/config.json as "teamId" to enable sync.\n`));
21
+ }
22
+ catch (err) {
23
+ spinner.fail(chalk.red(`Failed: ${err.message}`));
24
+ }
25
+ }
26
+ export async function teamListCommand() {
27
+ const client = await getClient();
28
+ const spinner = ora('Loading teams...').start();
29
+ try {
30
+ const { teams } = await client.listTeams();
31
+ spinner.stop();
32
+ if (teams.length === 0) {
33
+ console.log(chalk.dim(' No teams. Create one with `engram team create <name>`.\n'));
34
+ return;
35
+ }
36
+ console.log(chalk.bold.green('\n ⬡ Your Teams\n'));
37
+ for (const t of teams) {
38
+ const role = t.role === 'owner' ? chalk.yellow('owner') : chalk.dim(t.role);
39
+ console.log(` ${chalk.bold(t.name)} ${chalk.dim(t.id)} ${role} ${chalk.dim(`${t.member_count} members`)}`);
40
+ }
41
+ console.log();
42
+ }
43
+ catch (err) {
44
+ spinner.fail(chalk.red(`Failed: ${err.message}`));
45
+ }
46
+ }
47
+ export async function teamInviteCommand(email, opts) {
48
+ const teamId = opts.team;
49
+ if (!teamId) {
50
+ console.error(chalk.red(' ✗ Specify --team <id>. Use `engram team list` to find IDs.\n'));
51
+ process.exit(1);
52
+ }
53
+ const client = await getClient();
54
+ const spinner = ora(`Inviting ${email}...`).start();
55
+ try {
56
+ await client.inviteMember(teamId, email);
57
+ spinner.succeed(chalk.green(`Invited ${chalk.bold(email)} to team.`));
58
+ }
59
+ catch (err) {
60
+ spinner.fail(chalk.red(`Failed: ${err.message}`));
61
+ }
62
+ }
63
+ export async function teamMembersCommand(opts) {
64
+ const teamId = opts.team;
65
+ if (!teamId) {
66
+ console.error(chalk.red(' ✗ Specify --team <id>.\n'));
67
+ process.exit(1);
68
+ }
69
+ const client = await getClient();
70
+ const spinner = ora('Loading members...').start();
71
+ try {
72
+ const { members } = await client.listMembers(teamId);
73
+ spinner.stop();
74
+ console.log(chalk.bold.green('\n ⬡ Team Members\n'));
75
+ for (const m of members) {
76
+ const role = m.role === 'owner' ? chalk.yellow('owner') : chalk.dim(m.role);
77
+ console.log(` ${chalk.bold(m.email ?? m.user_id)} ${role}`);
78
+ }
79
+ console.log();
80
+ }
81
+ catch (err) {
82
+ spinner.fail(chalk.red(`Failed: ${err.message}`));
83
+ }
84
+ }
85
+ //# sourceMappingURL=team.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.js","sourceRoot":"","sources":["../../src/commands/team.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface ProjectConfig {
2
+ projectRoot: string;
3
+ teamId?: string;
4
+ ignorePaths: string[];
5
+ languages: ('typescript' | 'python')[];
6
+ dbPath: string;
7
+ }
8
+ export interface Credentials {
9
+ token: string;
10
+ userId: string;
11
+ email: string;
12
+ tier: 'free' | 'pro' | 'team' | 'enterprise';
13
+ expiresAt: number;
14
+ }
15
+ export declare function getGlobalConfigDir(): string;
16
+ export declare function getLogsDir(): string;
17
+ export declare function getProjectConfigDir(projectRoot: string): string;
18
+ export declare function getProjectConfigPath(projectRoot: string): string;
19
+ export declare function getProjectDbPath(projectRoot: string): string;
20
+ export declare function isProjectInitialized(projectRoot: string): boolean;
21
+ export declare function ensureGlobalConfig(): Promise<void>;
22
+ export declare function readProjectConfig(projectRoot: string): Promise<ProjectConfig | null>;
23
+ export declare function writeProjectConfig(config: ProjectConfig): Promise<void>;
24
+ export declare function readCredentials(): Promise<Credentials | null>;
25
+ export declare function writeCredentials(creds: Credentials): Promise<void>;
26
+ export declare function getEngramToken(): string | null;
27
+ export declare function getApiUrl(): string;
28
+ export declare function getSocketPath(projectRoot: string): string;
29
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,CAAC,YAAY,GAAG,QAAQ,CAAC,EAAE,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,YAAY,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAOxD;AAED,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAW/B;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAUnE;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAOxE;AAED,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAGzD"}
package/dist/config.js ADDED
@@ -0,0 +1,81 @@
1
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { homedir } from 'node:os';
5
+ import { createHash } from 'node:crypto';
6
+ const GLOBAL_CONFIG_DIR = join(homedir(), '.engram');
7
+ const CREDENTIALS_PATH = join(GLOBAL_CONFIG_DIR, 'credentials.json');
8
+ const LOGS_DIR = join(GLOBAL_CONFIG_DIR, 'logs');
9
+ export function getGlobalConfigDir() {
10
+ return GLOBAL_CONFIG_DIR;
11
+ }
12
+ export function getLogsDir() {
13
+ return LOGS_DIR;
14
+ }
15
+ export function getProjectConfigDir(projectRoot) {
16
+ return join(projectRoot, '.engram');
17
+ }
18
+ export function getProjectConfigPath(projectRoot) {
19
+ return join(projectRoot, '.engram', 'config.json');
20
+ }
21
+ export function getProjectDbPath(projectRoot) {
22
+ return join(projectRoot, '.engram', 'graph.db');
23
+ }
24
+ export function isProjectInitialized(projectRoot) {
25
+ return existsSync(getProjectConfigPath(projectRoot));
26
+ }
27
+ export async function ensureGlobalConfig() {
28
+ if (!existsSync(GLOBAL_CONFIG_DIR)) {
29
+ await mkdir(GLOBAL_CONFIG_DIR, { recursive: true });
30
+ }
31
+ if (!existsSync(LOGS_DIR)) {
32
+ await mkdir(LOGS_DIR, { recursive: true });
33
+ }
34
+ }
35
+ export async function readProjectConfig(projectRoot) {
36
+ const configPath = getProjectConfigPath(projectRoot);
37
+ if (!existsSync(configPath)) {
38
+ return null;
39
+ }
40
+ try {
41
+ const raw = await readFile(configPath, 'utf-8');
42
+ return JSON.parse(raw);
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }
48
+ export async function writeProjectConfig(config) {
49
+ const configDir = getProjectConfigDir(config.projectRoot);
50
+ if (!existsSync(configDir)) {
51
+ await mkdir(configDir, { recursive: true });
52
+ }
53
+ await writeFile(getProjectConfigPath(config.projectRoot), JSON.stringify(config, null, 2) + '\n', 'utf-8');
54
+ }
55
+ export async function readCredentials() {
56
+ if (!existsSync(CREDENTIALS_PATH)) {
57
+ return null;
58
+ }
59
+ try {
60
+ const raw = await readFile(CREDENTIALS_PATH, 'utf-8');
61
+ return JSON.parse(raw);
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ export async function writeCredentials(creds) {
68
+ await ensureGlobalConfig();
69
+ await writeFile(CREDENTIALS_PATH, JSON.stringify(creds, null, 2) + '\n', { mode: 0o600 });
70
+ }
71
+ export function getEngramToken() {
72
+ return process.env['ENGRAM_TOKEN'] ?? null;
73
+ }
74
+ export function getApiUrl() {
75
+ return process.env['ENGRAM_API_URL'] ?? 'https://api.engram.dev';
76
+ }
77
+ export function getSocketPath(projectRoot) {
78
+ const hash = createHash('sha256').update(projectRoot).digest('hex').slice(0, 12);
79
+ return join(GLOBAL_CONFIG_DIR, `engram-${hash}.sock`);
80
+ }
81
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { getSocketPath } from './config.js';
2
+ declare function getLogFile(projectRoot: string): string;
3
+ export declare function startDaemon(projectRoot: string): Promise<number>;
4
+ export declare function stopDaemon(projectRoot: string): Promise<boolean>;
5
+ export declare function getDaemonPid(projectRoot: string): Promise<number | null>;
6
+ export declare function isDaemonRunning(projectRoot: string): Promise<boolean>;
7
+ export { getLogFile, getSocketPath };
8
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAMA,OAAO,EAAkC,aAAa,EAAsB,MAAM,aAAa,CAAC;AAUhG,iBAAS,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE/C;AAwBD,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsDtE;AAED,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBtE;AAED,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBxB;AAED,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG3E;AAED,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC"}
package/dist/daemon.js ADDED
@@ -0,0 +1,124 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { readFile, writeFile, unlink } from 'node:fs/promises';
3
+ import { existsSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { createHash } from 'node:crypto';
6
+ import { createConnection } from 'node:net';
7
+ import { getGlobalConfigDir, getLogsDir, getSocketPath, ensureGlobalConfig } from './config.js';
8
+ function projectHash(projectRoot) {
9
+ return createHash('sha256').update(projectRoot).digest('hex').slice(0, 12);
10
+ }
11
+ function getPidFile(projectRoot) {
12
+ return join(getGlobalConfigDir(), `daemon-${projectHash(projectRoot)}.pid`);
13
+ }
14
+ function getLogFile(projectRoot) {
15
+ return join(getLogsDir(), `${projectHash(projectRoot)}.log`);
16
+ }
17
+ /**
18
+ * Check if a daemon is reachable on its Unix socket.
19
+ */
20
+ function isSocketAlive(socketPath) {
21
+ return new Promise((resolve) => {
22
+ const conn = createConnection(socketPath);
23
+ const timeout = setTimeout(() => {
24
+ conn.destroy();
25
+ resolve(false);
26
+ }, 500);
27
+ conn.on('connect', () => {
28
+ clearTimeout(timeout);
29
+ conn.destroy();
30
+ resolve(true);
31
+ });
32
+ conn.on('error', () => {
33
+ clearTimeout(timeout);
34
+ resolve(false);
35
+ });
36
+ });
37
+ }
38
+ export async function startDaemon(projectRoot) {
39
+ // Ensure ~/.engram and ~/.engram/logs exist before writing PID/log files
40
+ await ensureGlobalConfig();
41
+ const socketPath = getSocketPath(projectRoot);
42
+ // Already running?
43
+ if (await isSocketAlive(socketPath)) {
44
+ const pid = await getDaemonPid(projectRoot);
45
+ return pid ?? -1;
46
+ }
47
+ const logPath = getLogFile(projectRoot);
48
+ const mcpServerBin = join(import.meta.dirname ?? '.', '..', '..', 'mcp-server', 'dist', 'server.js');
49
+ // Open log file in advance so we can pass the fd to the child.
50
+ // Using 'ignore' for stdin/stdout avoids keeping the parent event loop alive.
51
+ const { openSync, closeSync } = await import('node:fs');
52
+ const logFd = openSync(logPath, 'a');
53
+ const child = spawn('node', [mcpServerBin], {
54
+ cwd: projectRoot,
55
+ env: {
56
+ ...process.env,
57
+ ENGRAM_PROJECT_ROOT: projectRoot,
58
+ ENGRAM_DB_PATH: join(projectRoot, '.engram', 'graph.db'),
59
+ ENGRAM_SOCKET_PATH: socketPath,
60
+ },
61
+ stdio: ['ignore', 'ignore', logFd],
62
+ detached: true,
63
+ });
64
+ child.unref();
65
+ closeSync(logFd);
66
+ const pid = child.pid;
67
+ if (pid) {
68
+ await writeFile(getPidFile(projectRoot), String(pid), 'utf-8');
69
+ }
70
+ // Wait briefly for the socket to become available
71
+ for (let attempt = 0; attempt < 20; attempt++) {
72
+ if (await isSocketAlive(socketPath))
73
+ break;
74
+ await new Promise((r) => setTimeout(r, 100));
75
+ }
76
+ return pid ?? -1;
77
+ }
78
+ export async function stopDaemon(projectRoot) {
79
+ const pid = await getDaemonPid(projectRoot);
80
+ if (pid !== null) {
81
+ try {
82
+ process.kill(pid, 'SIGTERM');
83
+ }
84
+ catch {
85
+ // Process already dead
86
+ }
87
+ }
88
+ // Always clean up PID and socket files even if process was already dead
89
+ const pidFile = getPidFile(projectRoot);
90
+ if (existsSync(pidFile)) {
91
+ await unlink(pidFile);
92
+ }
93
+ const socketPath = getSocketPath(projectRoot);
94
+ if (existsSync(socketPath)) {
95
+ await unlink(socketPath);
96
+ }
97
+ return pid !== null;
98
+ }
99
+ export async function getDaemonPid(projectRoot) {
100
+ const pidFile = getPidFile(projectRoot);
101
+ if (!existsSync(pidFile)) {
102
+ return null;
103
+ }
104
+ try {
105
+ const pidStr = await readFile(pidFile, 'utf-8');
106
+ const pid = parseInt(pidStr.trim(), 10);
107
+ // Check if process is still alive
108
+ process.kill(pid, 0);
109
+ return pid;
110
+ }
111
+ catch {
112
+ // PID file exists but process is dead — clean up
113
+ if (existsSync(pidFile)) {
114
+ await unlink(pidFile);
115
+ }
116
+ return null;
117
+ }
118
+ }
119
+ export async function isDaemonRunning(projectRoot) {
120
+ const socketPath = getSocketPath(projectRoot);
121
+ return isSocketAlive(socketPath);
122
+ }
123
+ export { getLogFile, getSocketPath };
124
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Engram CLI
4
+ * Your codebase, remembered.
5
+ *
6
+ * Usage:
7
+ * engram init [--project <path>] Initialize Engram for a project
8
+ * engram serve [--project <path>] Start the MCP server (stdio)
9
+ * engram login Authenticate with Engram cloud
10
+ * engram status [--project <path>] Show index health and daemon status
11
+ * engram index [--project <path>] Force a full reindex
12
+ * engram team create <name> Create a team
13
+ * engram team list List your teams
14
+ * engram team invite <email> Invite a member
15
+ * engram team members Show team members
16
+ * engram sync push Push local graph to team cloud
17
+ * engram sync pull Pull team graph to local
18
+ * engram sync status Show sync state
19
+ */
20
+ export {};
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;GAiBG"}
package/dist/index.js ADDED
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Engram CLI
4
+ * Your codebase, remembered.
5
+ *
6
+ * Usage:
7
+ * engram init [--project <path>] Initialize Engram for a project
8
+ * engram serve [--project <path>] Start the MCP server (stdio)
9
+ * engram login Authenticate with Engram cloud
10
+ * engram status [--project <path>] Show index health and daemon status
11
+ * engram index [--project <path>] Force a full reindex
12
+ * engram team create <name> Create a team
13
+ * engram team list List your teams
14
+ * engram team invite <email> Invite a member
15
+ * engram team members Show team members
16
+ * engram sync push Push local graph to team cloud
17
+ * engram sync pull Pull team graph to local
18
+ * engram sync status Show sync state
19
+ */
20
+ import { Command } from 'commander';
21
+ import { initCommand } from './commands/init.js';
22
+ import { serveCommand } from './commands/serve.js';
23
+ import { loginCommand } from './commands/login.js';
24
+ import { statusCommand } from './commands/status.js';
25
+ import { indexCommand } from './commands/index-cmd.js';
26
+ import { teamCreateCommand, teamListCommand, teamInviteCommand, teamMembersCommand, } from './commands/team.js';
27
+ import { syncPushCommand, syncPullCommand, syncStatusCommand, } from './commands/sync.js';
28
+ const program = new Command();
29
+ program
30
+ .name('engram')
31
+ .description('Persistent codebase context for AI coding agents')
32
+ .version('0.1.0');
33
+ program
34
+ .command('init')
35
+ .description('Initialize Engram for the current project')
36
+ .option('-p, --project <path>', 'Project root directory')
37
+ .action(async (opts) => {
38
+ await initCommand(opts.project);
39
+ });
40
+ program
41
+ .command('serve')
42
+ .description('Start the MCP server on stdio')
43
+ .option('-p, --project <path>', 'Project root directory')
44
+ .action(async (opts) => {
45
+ await serveCommand({ project: opts.project });
46
+ });
47
+ program
48
+ .command('login')
49
+ .description('Authenticate with Engram cloud')
50
+ .action(async () => {
51
+ await loginCommand();
52
+ });
53
+ program
54
+ .command('status')
55
+ .description('Show index health and server status')
56
+ .option('-p, --project <path>', 'Project root directory')
57
+ .action(async (opts) => {
58
+ await statusCommand({ project: opts.project });
59
+ });
60
+ program
61
+ .command('index')
62
+ .description('Force a full reindex of the project')
63
+ .option('-p, --project <path>', 'Project root directory')
64
+ .action(async (opts) => {
65
+ await indexCommand({ project: opts.project });
66
+ });
67
+ // ─── Team Commands ────────────────────────────────────────────────
68
+ const team = program
69
+ .command('team')
70
+ .description('Manage teams for shared codebase sync');
71
+ team
72
+ .command('create <name>')
73
+ .description('Create a new team')
74
+ .action(async (name) => {
75
+ await teamCreateCommand(name);
76
+ });
77
+ team
78
+ .command('list')
79
+ .description('List your teams')
80
+ .action(async () => {
81
+ await teamListCommand();
82
+ });
83
+ team
84
+ .command('invite <email>')
85
+ .description('Invite a member by email')
86
+ .option('-t, --team <id>', 'Team ID')
87
+ .action(async (email, opts) => {
88
+ await teamInviteCommand(email, opts);
89
+ });
90
+ team
91
+ .command('members')
92
+ .description('List team members')
93
+ .option('-t, --team <id>', 'Team ID')
94
+ .action(async (opts) => {
95
+ await teamMembersCommand(opts);
96
+ });
97
+ // ─── Sync Commands ────────────────────────────────────────────────
98
+ const sync = program
99
+ .command('sync')
100
+ .description('Push/pull codebase context with your team');
101
+ sync
102
+ .command('push')
103
+ .description('Push local graph to team cloud')
104
+ .option('-p, --project <path>', 'Project root directory')
105
+ .action(async (opts) => {
106
+ await syncPushCommand(opts);
107
+ });
108
+ sync
109
+ .command('pull')
110
+ .description('Pull team graph to local')
111
+ .option('-p, --project <path>', 'Project root directory')
112
+ .action(async (opts) => {
113
+ await syncPullCommand(opts);
114
+ });
115
+ sync
116
+ .command('status')
117
+ .description('Show sync state')
118
+ .option('-p, --project <path>', 'Project root directory')
119
+ .action(async (opts) => {
120
+ await syncStatusCommand(opts);
121
+ });
122
+ program.parse();
123
+ //# sourceMappingURL=index.js.map