@ajvikram/relay 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 (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +538 -0
  3. package/dist/cli/commands/branch.d.ts +9 -0
  4. package/dist/cli/commands/branch.d.ts.map +1 -0
  5. package/dist/cli/commands/branch.js +69 -0
  6. package/dist/cli/commands/branch.js.map +1 -0
  7. package/dist/cli/commands/diff.d.ts +8 -0
  8. package/dist/cli/commands/diff.d.ts.map +1 -0
  9. package/dist/cli/commands/diff.js +61 -0
  10. package/dist/cli/commands/diff.js.map +1 -0
  11. package/dist/cli/commands/history.d.ts +8 -0
  12. package/dist/cli/commands/history.d.ts.map +1 -0
  13. package/dist/cli/commands/history.js +32 -0
  14. package/dist/cli/commands/history.js.map +1 -0
  15. package/dist/cli/commands/hook.d.ts +6 -0
  16. package/dist/cli/commands/hook.d.ts.map +1 -0
  17. package/dist/cli/commands/hook.js +118 -0
  18. package/dist/cli/commands/hook.js.map +1 -0
  19. package/dist/cli/commands/init.d.ts +4 -0
  20. package/dist/cli/commands/init.d.ts.map +1 -0
  21. package/dist/cli/commands/init.js +41 -0
  22. package/dist/cli/commands/init.js.map +1 -0
  23. package/dist/cli/commands/install.d.ts +18 -0
  24. package/dist/cli/commands/install.d.ts.map +1 -0
  25. package/dist/cli/commands/install.js +203 -0
  26. package/dist/cli/commands/install.js.map +1 -0
  27. package/dist/cli/commands/load.d.ts +9 -0
  28. package/dist/cli/commands/load.d.ts.map +1 -0
  29. package/dist/cli/commands/load.js +69 -0
  30. package/dist/cli/commands/load.js.map +1 -0
  31. package/dist/cli/commands/repos.d.ts +7 -0
  32. package/dist/cli/commands/repos.d.ts.map +1 -0
  33. package/dist/cli/commands/repos.js +53 -0
  34. package/dist/cli/commands/repos.js.map +1 -0
  35. package/dist/cli/commands/save.d.ts +9 -0
  36. package/dist/cli/commands/save.d.ts.map +1 -0
  37. package/dist/cli/commands/save.js +267 -0
  38. package/dist/cli/commands/save.js.map +1 -0
  39. package/dist/cli/commands/status.d.ts +23 -0
  40. package/dist/cli/commands/status.d.ts.map +1 -0
  41. package/dist/cli/commands/status.js +134 -0
  42. package/dist/cli/commands/status.js.map +1 -0
  43. package/dist/cli/commands/ui.d.ts +9 -0
  44. package/dist/cli/commands/ui.d.ts.map +1 -0
  45. package/dist/cli/commands/ui.js +54 -0
  46. package/dist/cli/commands/ui.js.map +1 -0
  47. package/dist/cli/commands/vscode.d.ts +6 -0
  48. package/dist/cli/commands/vscode.d.ts.map +1 -0
  49. package/dist/cli/commands/vscode.js +86 -0
  50. package/dist/cli/commands/vscode.js.map +1 -0
  51. package/dist/cli/index.d.ts +3 -0
  52. package/dist/cli/index.d.ts.map +1 -0
  53. package/dist/cli/index.js +143 -0
  54. package/dist/cli/index.js.map +1 -0
  55. package/dist/format/renderer.d.ts +5 -0
  56. package/dist/format/renderer.d.ts.map +1 -0
  57. package/dist/format/renderer.js +207 -0
  58. package/dist/format/renderer.js.map +1 -0
  59. package/dist/format/schema.d.ts +516 -0
  60. package/dist/format/schema.d.ts.map +1 -0
  61. package/dist/format/schema.js +90 -0
  62. package/dist/format/schema.js.map +1 -0
  63. package/dist/format/template.d.ts +44 -0
  64. package/dist/format/template.d.ts.map +1 -0
  65. package/dist/format/template.js +131 -0
  66. package/dist/format/template.js.map +1 -0
  67. package/dist/git/context.d.ts +23 -0
  68. package/dist/git/context.d.ts.map +1 -0
  69. package/dist/git/context.js +121 -0
  70. package/dist/git/context.js.map +1 -0
  71. package/dist/index.d.ts +8 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +8 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/mcp/server.d.ts +2 -0
  76. package/dist/mcp/server.d.ts.map +1 -0
  77. package/dist/mcp/server.js +164 -0
  78. package/dist/mcp/server.js.map +1 -0
  79. package/dist/server/index.d.ts +12 -0
  80. package/dist/server/index.d.ts.map +1 -0
  81. package/dist/server/index.js +143 -0
  82. package/dist/server/index.js.map +1 -0
  83. package/dist/server/ui.d.ts +2 -0
  84. package/dist/server/ui.d.ts.map +1 -0
  85. package/dist/server/ui.js +797 -0
  86. package/dist/server/ui.js.map +1 -0
  87. package/dist/storage/global.d.ts +40 -0
  88. package/dist/storage/global.d.ts.map +1 -0
  89. package/dist/storage/global.js +126 -0
  90. package/dist/storage/global.js.map +1 -0
  91. package/dist/storage/index.d.ts +59 -0
  92. package/dist/storage/index.d.ts.map +1 -0
  93. package/dist/storage/index.js +253 -0
  94. package/dist/storage/index.js.map +1 -0
  95. package/package.json +54 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/server/ui.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB;IAC9B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyxBD,CAAC;AACT,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { Handoff } from '../format/schema.js';
2
+ export interface RegisteredRepo {
3
+ path: string;
4
+ name: string;
5
+ registeredAt: string;
6
+ lastHandoffAt?: string;
7
+ lastHandoffId?: string;
8
+ lastGoal?: string;
9
+ lastStatus?: string;
10
+ lastPlatform?: string;
11
+ }
12
+ export interface GlobalRegistry {
13
+ version: string;
14
+ repos: RegisteredRepo[];
15
+ }
16
+ export declare function getGlobalRelayDir(): string;
17
+ export declare function getGlobalRegistryPath(): string;
18
+ /**
19
+ * Loads the global registry of Relay repositories.
20
+ */
21
+ export declare function readGlobalRegistry(): GlobalRegistry;
22
+ /**
23
+ * Saves the global registry of Relay repositories.
24
+ */
25
+ export declare function saveGlobalRegistry(registry: GlobalRegistry): void;
26
+ /**
27
+ * Registers or updates a repository in the global registry.
28
+ */
29
+ export declare function registerRepo(repoRoot: string, handoff?: Handoff | null): RegisteredRepo;
30
+ /**
31
+ * Unregisters a repository from the global registry.
32
+ */
33
+ export declare function unregisterRepo(repoRoot: string): boolean;
34
+ /**
35
+ * Returns all registered repositories, refreshing live handoff status and pruning non-existent directories.
36
+ */
37
+ export declare function listRegisteredRepos(opts?: {
38
+ pruneStale?: boolean;
39
+ }): RegisteredRepo[];
40
+ //# sourceMappingURL=global.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../../src/storage/global.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CAenD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAIjE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,cAAc,CAqCvF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAUxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAyB,GAAG,cAAc,EAAE,CAoC3G"}
@@ -0,0 +1,126 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ import { readHandoff } from './index.js';
5
+ export function getGlobalRelayDir() {
6
+ return join(homedir(), '.relay');
7
+ }
8
+ export function getGlobalRegistryPath() {
9
+ return join(getGlobalRelayDir(), 'registry.json');
10
+ }
11
+ /**
12
+ * Loads the global registry of Relay repositories.
13
+ */
14
+ export function readGlobalRegistry() {
15
+ const registryPath = getGlobalRegistryPath();
16
+ if (!existsSync(registryPath)) {
17
+ return { version: '1.0.0', repos: [] };
18
+ }
19
+ try {
20
+ const raw = JSON.parse(readFileSync(registryPath, 'utf-8'));
21
+ return {
22
+ version: raw.version || '1.0.0',
23
+ repos: Array.isArray(raw.repos) ? raw.repos : [],
24
+ };
25
+ }
26
+ catch {
27
+ return { version: '1.0.0', repos: [] };
28
+ }
29
+ }
30
+ /**
31
+ * Saves the global registry of Relay repositories.
32
+ */
33
+ export function saveGlobalRegistry(registry) {
34
+ const relayDir = getGlobalRelayDir();
35
+ mkdirSync(relayDir, { recursive: true });
36
+ writeFileSync(getGlobalRegistryPath(), JSON.stringify(registry, null, 2));
37
+ }
38
+ /**
39
+ * Registers or updates a repository in the global registry.
40
+ */
41
+ export function registerRepo(repoRoot, handoff) {
42
+ const registry = readGlobalRegistry();
43
+ const repoName = repoRoot.split('/').filter(Boolean).pop() || repoRoot;
44
+ const currentHandoff = handoff !== undefined ? handoff : readHandoff(repoRoot);
45
+ const existingIndex = registry.repos.findIndex((r) => r.path === repoRoot);
46
+ const repoEntry = {
47
+ path: repoRoot,
48
+ name: repoName,
49
+ registeredAt: existingIndex >= 0 ? registry.repos[existingIndex].registeredAt : new Date().toISOString(),
50
+ ...(currentHandoff
51
+ ? {
52
+ lastHandoffAt: currentHandoff.timestamp,
53
+ lastHandoffId: currentHandoff.id,
54
+ lastGoal: currentHandoff.session.goal,
55
+ lastStatus: currentHandoff.session.status,
56
+ lastPlatform: currentHandoff.source_platform,
57
+ }
58
+ : existingIndex >= 0
59
+ ? {
60
+ lastHandoffAt: registry.repos[existingIndex].lastHandoffAt,
61
+ lastHandoffId: registry.repos[existingIndex].lastHandoffId,
62
+ lastGoal: registry.repos[existingIndex].lastGoal,
63
+ lastStatus: registry.repos[existingIndex].lastStatus,
64
+ lastPlatform: registry.repos[existingIndex].lastPlatform,
65
+ }
66
+ : {}),
67
+ };
68
+ if (existingIndex >= 0) {
69
+ registry.repos[existingIndex] = repoEntry;
70
+ }
71
+ else {
72
+ registry.repos.push(repoEntry);
73
+ }
74
+ saveGlobalRegistry(registry);
75
+ return repoEntry;
76
+ }
77
+ /**
78
+ * Unregisters a repository from the global registry.
79
+ */
80
+ export function unregisterRepo(repoRoot) {
81
+ const registry = readGlobalRegistry();
82
+ const initialCount = registry.repos.length;
83
+ registry.repos = registry.repos.filter((r) => r.path !== repoRoot);
84
+ if (registry.repos.length !== initialCount) {
85
+ saveGlobalRegistry(registry);
86
+ return true;
87
+ }
88
+ return false;
89
+ }
90
+ /**
91
+ * Returns all registered repositories, refreshing live handoff status and pruning non-existent directories.
92
+ */
93
+ export function listRegisteredRepos(opts = { pruneStale: true }) {
94
+ const registry = readGlobalRegistry();
95
+ const validRepos = [];
96
+ let modified = false;
97
+ for (const repo of registry.repos) {
98
+ if (!existsSync(repo.path)) {
99
+ if (opts.pruneStale) {
100
+ modified = true;
101
+ continue;
102
+ }
103
+ }
104
+ // Refresh with latest handoff if repo exists
105
+ try {
106
+ const currentHandoff = readHandoff(repo.path);
107
+ if (currentHandoff) {
108
+ repo.lastHandoffAt = currentHandoff.timestamp;
109
+ repo.lastHandoffId = currentHandoff.id;
110
+ repo.lastGoal = currentHandoff.session.goal;
111
+ repo.lastStatus = currentHandoff.session.status;
112
+ repo.lastPlatform = currentHandoff.source_platform;
113
+ }
114
+ }
115
+ catch {
116
+ // Keep existing snapshot if error
117
+ }
118
+ validRepos.push(repo);
119
+ }
120
+ if (modified) {
121
+ registry.repos = validRepos;
122
+ saveGlobalRegistry(registry);
123
+ }
124
+ return validRepos;
125
+ }
126
+ //# sourceMappingURL=global.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global.js","sourceRoot":"","sources":["../../src/storage/global.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { Handoff, HistoryEntry } from '../format/schema.js';
2
+ export * from './global.js';
3
+ export declare const RELAY_DIR = ".relay";
4
+ export declare const HANDOFF_FILE = "handoff.md";
5
+ export declare const HISTORY_DIR = "history";
6
+ export declare const BRANCHES_DIR = "branches";
7
+ export declare const HISTORY_INDEX_FILE = "history-index.json";
8
+ export declare const CONFIG_FILE = "config.yaml";
9
+ export declare function getRelayDir(repoRoot: string): string;
10
+ export declare function getHandoffPath(repoRoot: string): string;
11
+ export declare function getHistoryDir(repoRoot: string): string;
12
+ export declare function getBranchesDir(repoRoot: string): string;
13
+ export declare function getHistoryIndexPath(repoRoot: string): string;
14
+ export declare function sanitizeBranchName(branch: string): string;
15
+ export declare function getBranchHandoffJsonPath(repoRoot: string, branch: string): string;
16
+ export declare function getBranchHandoffPath(repoRoot: string, branch: string): string;
17
+ /**
18
+ * Returns true if the .relay directory exists in the given repo root.
19
+ */
20
+ export declare function isRelayInitialized(repoRoot: string): boolean;
21
+ /**
22
+ * Creates the .relay directory structure.
23
+ */
24
+ export declare function initRelayDir(repoRoot: string): void;
25
+ /**
26
+ * Saves a handoff to .relay/handoff.md (as Markdown) and archives
27
+ * the previous handoff to .relay/history/{id}.md.
28
+ * Also persists branch-scoped copy to .relay/branches/<branch>.json.
29
+ */
30
+ export declare function saveHandoff(repoRoot: string, handoff: Handoff, branchOverride?: string): void;
31
+ /**
32
+ * Reads and parses the handoff.
33
+ * Checks branch-specific file first if branch is provided, then falls back to root handoff.json.
34
+ */
35
+ export declare function readHandoff(repoRoot: string, branch?: string): Handoff | null;
36
+ /**
37
+ * Lists all saved branch handoffs.
38
+ */
39
+ export declare function listSavedBranches(repoRoot: string): Array<{
40
+ branch: string;
41
+ id: string;
42
+ timestamp: string;
43
+ goal: string;
44
+ status: string;
45
+ }>;
46
+ /**
47
+ * Returns all history entries, most recent first.
48
+ */
49
+ export declare function readHistory(repoRoot: string): HistoryEntry[];
50
+ /**
51
+ * Reads a specific historical handoff by ID.
52
+ * Returns the raw Markdown content.
53
+ */
54
+ export declare function readHistoryEntry(repoRoot: string, id: string): string | null;
55
+ /**
56
+ * Resolves the working directory — uses the provided path or process.cwd().
57
+ */
58
+ export declare function resolveCwd(dir?: string): string;
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAgB,MAAM,qBAAqB,CAAC;AAK/E,cAAc,aAAa,CAAC;AAI5B,eAAO,MAAM,SAAS,WAAW,CAAC;AAClC,eAAO,MAAM,YAAY,eAAe,CAAC;AACzC,eAAO,MAAM,WAAW,YAAY,CAAC;AACrC,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGjF;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAG7E;AAID;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAoDnD;AAID;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAyC7F;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAsB7E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB1I;AAgCD;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAW5D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI5E;AAID;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/C"}
@@ -0,0 +1,253 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync } from 'fs';
2
+ import { join, resolve } from 'path';
3
+ import { HandoffSchema, HistoryIndexSchema } from '../format/schema.js';
4
+ import { renderMarkdown } from '../format/renderer.js';
5
+ import { registerRepo } from './global.js';
6
+ export * from './global.js';
7
+ // ─── Directory and File Paths ─────────────────────────────────────────────────
8
+ export const RELAY_DIR = '.relay';
9
+ export const HANDOFF_FILE = 'handoff.md';
10
+ export const HISTORY_DIR = 'history';
11
+ export const BRANCHES_DIR = 'branches';
12
+ export const HISTORY_INDEX_FILE = 'history-index.json';
13
+ export const CONFIG_FILE = 'config.yaml';
14
+ export function getRelayDir(repoRoot) {
15
+ return join(repoRoot, RELAY_DIR);
16
+ }
17
+ export function getHandoffPath(repoRoot) {
18
+ return join(repoRoot, RELAY_DIR, HANDOFF_FILE);
19
+ }
20
+ export function getHistoryDir(repoRoot) {
21
+ return join(repoRoot, RELAY_DIR, HISTORY_DIR);
22
+ }
23
+ export function getBranchesDir(repoRoot) {
24
+ return join(repoRoot, RELAY_DIR, BRANCHES_DIR);
25
+ }
26
+ export function getHistoryIndexPath(repoRoot) {
27
+ return join(repoRoot, RELAY_DIR, HISTORY_DIR, HISTORY_INDEX_FILE);
28
+ }
29
+ export function sanitizeBranchName(branch) {
30
+ return branch.replace(/[\/\\:*?"<>|]/g, '-').replace(/^-+|-+$/g, '') || 'main';
31
+ }
32
+ export function getBranchHandoffJsonPath(repoRoot, branch) {
33
+ const safeName = sanitizeBranchName(branch);
34
+ return join(getBranchesDir(repoRoot), `${safeName}.json`);
35
+ }
36
+ export function getBranchHandoffPath(repoRoot, branch) {
37
+ const safeName = sanitizeBranchName(branch);
38
+ return join(getBranchesDir(repoRoot), `${safeName}.md`);
39
+ }
40
+ // ─── Relay Directory Management ───────────────────────────────────────────────
41
+ /**
42
+ * Returns true if the .relay directory exists in the given repo root.
43
+ */
44
+ export function isRelayInitialized(repoRoot) {
45
+ return existsSync(getRelayDir(repoRoot));
46
+ }
47
+ /**
48
+ * Creates the .relay directory structure.
49
+ */
50
+ export function initRelayDir(repoRoot) {
51
+ const relayDir = getRelayDir(repoRoot);
52
+ const historyDir = getHistoryDir(repoRoot);
53
+ const branchesDir = getBranchesDir(repoRoot);
54
+ mkdirSync(relayDir, { recursive: true });
55
+ mkdirSync(historyDir, { recursive: true });
56
+ mkdirSync(branchesDir, { recursive: true });
57
+ // Write default config
58
+ const configPath = join(relayDir, CONFIG_FILE);
59
+ if (!existsSync(configPath)) {
60
+ writeFileSync(configPath, [
61
+ '# Relay Configuration',
62
+ '# https://github.com/relay-ai/relay',
63
+ '',
64
+ '# Include raw git diff in handoff files (can be large)',
65
+ 'include_diff: true',
66
+ '',
67
+ '# Maximum diff size in bytes before truncation (default: 50KB)',
68
+ 'max_diff_size: 51200',
69
+ '',
70
+ '# Keep history files in git (default: false — history is local-only)',
71
+ 'git_track_history: false',
72
+ '',
73
+ '# Track the current handoff.md in git (default: true)',
74
+ 'git_track_handoff: true',
75
+ ].join('\n'));
76
+ }
77
+ // Update .gitignore if present
78
+ const gitignorePath = join(repoRoot, '.gitignore');
79
+ if (existsSync(gitignorePath)) {
80
+ const content = readFileSync(gitignorePath, 'utf-8');
81
+ const entries = ['.relay/history/', '.relay/config.yaml'];
82
+ const toAdd = entries.filter((e) => !content.includes(e));
83
+ if (toAdd.length > 0) {
84
+ writeFileSync(gitignorePath, content.trimEnd() + '\n\n# Relay — local-only context files\n' + toAdd.join('\n') + '\n');
85
+ }
86
+ }
87
+ else {
88
+ writeFileSync(gitignorePath, '# Relay — local-only context files\n.relay/history/\n.relay/config.yaml\n');
89
+ }
90
+ // Register in global registry
91
+ try {
92
+ registerRepo(repoRoot);
93
+ }
94
+ catch {
95
+ // Non-fatal if global directory isn't accessible
96
+ }
97
+ }
98
+ // ─── Handoff Read/Write ───────────────────────────────────────────────────────
99
+ /**
100
+ * Saves a handoff to .relay/handoff.md (as Markdown) and archives
101
+ * the previous handoff to .relay/history/{id}.md.
102
+ * Also persists branch-scoped copy to .relay/branches/<branch>.json.
103
+ */
104
+ export function saveHandoff(repoRoot, handoff, branchOverride) {
105
+ const relayDir = getRelayDir(repoRoot);
106
+ const handoffPath = getHandoffPath(repoRoot);
107
+ const historyDir = getHistoryDir(repoRoot);
108
+ const branchesDir = getBranchesDir(repoRoot);
109
+ // Ensure directories exist
110
+ mkdirSync(relayDir, { recursive: true });
111
+ mkdirSync(historyDir, { recursive: true });
112
+ mkdirSync(branchesDir, { recursive: true });
113
+ // Archive the existing handoff if present
114
+ if (existsSync(handoffPath)) {
115
+ const existing = readFileSync(handoffPath, 'utf-8');
116
+ const idMatch = existing.match(/relay:id=([^\s]+)/);
117
+ const archiveId = idMatch?.[1] ?? `archived-${Date.now()}`;
118
+ writeFileSync(join(historyDir, `${archiveId}.md`), existing);
119
+ }
120
+ // Write new active handoff as Markdown & JSON
121
+ const markdown = renderMarkdown(handoff);
122
+ writeFileSync(handoffPath, markdown);
123
+ writeFileSync(join(relayDir, 'handoff.json'), JSON.stringify(handoff, null, 2));
124
+ // Write branch-scoped copy
125
+ const targetBranch = branchOverride || handoff.repository.branch || 'main';
126
+ const branchJsonPath = getBranchHandoffJsonPath(repoRoot, targetBranch);
127
+ const branchMdPath = getBranchHandoffPath(repoRoot, targetBranch);
128
+ writeFileSync(branchJsonPath, JSON.stringify(handoff, null, 2));
129
+ writeFileSync(branchMdPath, markdown);
130
+ // Update history index
131
+ updateHistoryIndex(repoRoot, handoff);
132
+ // Update global registry with latest handoff info
133
+ try {
134
+ registerRepo(repoRoot, handoff);
135
+ }
136
+ catch {
137
+ // Non-fatal
138
+ }
139
+ }
140
+ /**
141
+ * Reads and parses the handoff.
142
+ * Checks branch-specific file first if branch is provided, then falls back to root handoff.json.
143
+ */
144
+ export function readHandoff(repoRoot, branch) {
145
+ if (branch) {
146
+ const branchJsonPath = getBranchHandoffJsonPath(repoRoot, branch);
147
+ if (existsSync(branchJsonPath)) {
148
+ try {
149
+ const raw = JSON.parse(readFileSync(branchJsonPath, 'utf-8'));
150
+ return HandoffSchema.parse(raw);
151
+ }
152
+ catch {
153
+ // Fall back to root
154
+ }
155
+ }
156
+ }
157
+ const jsonPath = join(getRelayDir(repoRoot), 'handoff.json');
158
+ if (!existsSync(jsonPath))
159
+ return null;
160
+ try {
161
+ const raw = JSON.parse(readFileSync(jsonPath, 'utf-8'));
162
+ return HandoffSchema.parse(raw);
163
+ }
164
+ catch {
165
+ return null;
166
+ }
167
+ }
168
+ /**
169
+ * Lists all saved branch handoffs.
170
+ */
171
+ export function listSavedBranches(repoRoot) {
172
+ const branchesDir = getBranchesDir(repoRoot);
173
+ if (!existsSync(branchesDir))
174
+ return [];
175
+ const files = readdirSync(branchesDir).filter((f) => f.endsWith('.json'));
176
+ const results = [];
177
+ for (const file of files) {
178
+ try {
179
+ const raw = JSON.parse(readFileSync(join(branchesDir, file), 'utf-8'));
180
+ const parsed = HandoffSchema.parse(raw);
181
+ results.push({
182
+ branch: parsed.repository.branch,
183
+ id: parsed.id,
184
+ timestamp: parsed.timestamp,
185
+ goal: parsed.session.goal,
186
+ status: parsed.session.status,
187
+ });
188
+ }
189
+ catch {
190
+ // Ignore invalid files
191
+ }
192
+ }
193
+ return results;
194
+ }
195
+ // ─── History Management ───────────────────────────────────────────────────────
196
+ function updateHistoryIndex(repoRoot, handoff) {
197
+ const indexPath = getHistoryIndexPath(repoRoot);
198
+ let index = { entries: [] };
199
+ if (existsSync(indexPath)) {
200
+ try {
201
+ const raw = JSON.parse(readFileSync(indexPath, 'utf-8'));
202
+ index = HistoryIndexSchema.parse(raw);
203
+ }
204
+ catch {
205
+ index = { entries: [] };
206
+ }
207
+ }
208
+ const entry = {
209
+ id: handoff.id,
210
+ timestamp: handoff.timestamp,
211
+ source_platform: handoff.source_platform,
212
+ goal: handoff.session.goal,
213
+ status: handoff.session.status,
214
+ file: `${handoff.id}.md`,
215
+ };
216
+ // Prepend new entry (most recent first)
217
+ index.entries = [entry, ...index.entries.filter((e) => e.id !== handoff.id)];
218
+ writeFileSync(indexPath, JSON.stringify(index, null, 2));
219
+ }
220
+ /**
221
+ * Returns all history entries, most recent first.
222
+ */
223
+ export function readHistory(repoRoot) {
224
+ const indexPath = getHistoryIndexPath(repoRoot);
225
+ if (!existsSync(indexPath))
226
+ return [];
227
+ try {
228
+ const raw = JSON.parse(readFileSync(indexPath, 'utf-8'));
229
+ const index = HistoryIndexSchema.parse(raw);
230
+ return index.entries;
231
+ }
232
+ catch {
233
+ return [];
234
+ }
235
+ }
236
+ /**
237
+ * Reads a specific historical handoff by ID.
238
+ * Returns the raw Markdown content.
239
+ */
240
+ export function readHistoryEntry(repoRoot, id) {
241
+ const filePath = join(getHistoryDir(repoRoot), `${id}.md`);
242
+ if (!existsSync(filePath))
243
+ return null;
244
+ return readFileSync(filePath, 'utf-8');
245
+ }
246
+ // ─── Working directory resolution ────────────────────────────────────────────
247
+ /**
248
+ * Resolves the working directory — uses the provided path or process.cwd().
249
+ */
250
+ export function resolveCwd(dir) {
251
+ return dir ? resolve(dir) : process.cwd();
252
+ }
253
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@ajvikram/relay",
3
+ "version": "0.1.0",
4
+ "description": "Seamless context handoff between AI coding platforms (Claude, Cursor, Copilot, Antigravity)",
5
+ "keywords": ["ai", "context", "handoff", "mcp", "claude", "cursor", "copilot", "antigravity"],
6
+ "author": "Relay Contributors",
7
+ "license": "MIT",
8
+ "type": "module",
9
+ "bin": {
10
+ "relay": "./dist/cli/index.js"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsc --watch",
22
+ "start": "node dist/cli/index.js",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "test:coverage": "vitest run --coverage",
26
+ "lint": "eslint src --ext .ts",
27
+ "typecheck": "tsc --noEmit",
28
+ "publish:npm": "npm publish --access public",
29
+ "prepublishOnly": "npm run typecheck && npm run build && npm test"
30
+ },
31
+ "dependencies": {
32
+ "@modelcontextprotocol/server": "^2.0.0",
33
+ "chalk": "^5.3.0",
34
+ "commander": "^12.0.0",
35
+ "inquirer": "^10.0.0",
36
+ "simple-git": "^3.25.0",
37
+ "zod": "^3.23.0",
38
+ "clipboardy": "^4.0.0",
39
+ "yaml": "^2.4.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^20.0.0",
43
+ "@vitest/coverage-v8": "^1.0.0",
44
+ "typescript": "^5.4.0",
45
+ "vitest": "^1.0.0"
46
+ },
47
+ "engines": {
48
+ "node": ">=18.0.0"
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://github.com/ajvikram/relay"
53
+ }
54
+ }