contextgit 0.0.2 → 0.0.4

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 (163) hide show
  1. package/dist/bootstrap.d.ts +10 -0
  2. package/dist/bootstrap.d.ts.map +1 -0
  3. package/dist/bootstrap.js +43 -0
  4. package/dist/bootstrap.js.map +1 -0
  5. package/dist/commands/branch.d.ts +13 -0
  6. package/dist/commands/branch.d.ts.map +1 -0
  7. package/dist/commands/branch.js +52 -0
  8. package/dist/commands/branch.js.map +1 -0
  9. package/dist/commands/claim.d.ts +15 -0
  10. package/dist/commands/claim.d.ts.map +1 -0
  11. package/dist/commands/claim.js +60 -0
  12. package/dist/commands/claim.js.map +1 -0
  13. package/dist/commands/commit.d.ts +17 -0
  14. package/dist/commands/commit.d.ts.map +1 -0
  15. package/dist/commands/commit.js +83 -0
  16. package/dist/commands/commit.js.map +1 -0
  17. package/dist/commands/context.d.ts +9 -0
  18. package/dist/commands/context.d.ts.map +1 -0
  19. package/dist/commands/context.js +38 -0
  20. package/dist/commands/context.js.map +1 -0
  21. package/dist/commands/doctor.d.ts +6 -0
  22. package/dist/commands/doctor.d.ts.map +1 -0
  23. package/dist/commands/doctor.js +84 -0
  24. package/dist/commands/doctor.js.map +1 -0
  25. package/dist/commands/init.d.ts +10 -0
  26. package/dist/commands/init.d.ts.map +1 -0
  27. package/dist/commands/init.js +184 -0
  28. package/dist/commands/init.js.map +1 -0
  29. package/dist/commands/keygen.d.ts +10 -0
  30. package/dist/commands/keygen.d.ts.map +1 -0
  31. package/dist/commands/keygen.js +57 -0
  32. package/dist/commands/keygen.js.map +1 -0
  33. package/dist/commands/log.d.ts +13 -0
  34. package/dist/commands/log.d.ts.map +1 -0
  35. package/dist/commands/log.js +91 -0
  36. package/dist/commands/log.js.map +1 -0
  37. package/dist/commands/merge.d.ts +12 -0
  38. package/dist/commands/merge.d.ts.map +1 -0
  39. package/dist/commands/merge.js +29 -0
  40. package/dist/commands/merge.js.map +1 -0
  41. package/dist/commands/pull.d.ts +10 -0
  42. package/dist/commands/pull.d.ts.map +1 -0
  43. package/dist/commands/pull.js +123 -0
  44. package/dist/commands/pull.js.map +1 -0
  45. package/dist/commands/push.d.ts +10 -0
  46. package/dist/commands/push.d.ts.map +1 -0
  47. package/dist/commands/push.js +141 -0
  48. package/dist/commands/push.js.map +1 -0
  49. package/dist/commands/remote-show.d.ts +6 -0
  50. package/dist/commands/remote-show.d.ts.map +1 -0
  51. package/dist/commands/remote-show.js +71 -0
  52. package/dist/commands/remote-show.js.map +1 -0
  53. package/dist/commands/search.d.ts +11 -0
  54. package/dist/commands/search.d.ts.map +1 -0
  55. package/dist/commands/search.js +47 -0
  56. package/dist/commands/search.js.map +1 -0
  57. package/dist/commands/serve.d.ts +9 -0
  58. package/dist/commands/serve.d.ts.map +1 -0
  59. package/dist/commands/serve.js +51 -0
  60. package/dist/commands/serve.js.map +1 -0
  61. package/dist/commands/set-remote.d.ts +9 -0
  62. package/dist/commands/set-remote.d.ts.map +1 -0
  63. package/dist/commands/set-remote.js +26 -0
  64. package/dist/commands/set-remote.js.map +1 -0
  65. package/dist/commands/status.d.ts +6 -0
  66. package/dist/commands/status.d.ts.map +1 -0
  67. package/dist/commands/status.js +54 -0
  68. package/dist/commands/status.js.map +1 -0
  69. package/dist/commands/unclaim.d.ts +9 -0
  70. package/dist/commands/unclaim.d.ts.map +1 -0
  71. package/dist/commands/unclaim.js +22 -0
  72. package/dist/commands/unclaim.js.map +1 -0
  73. package/dist/config.d.ts +19 -0
  74. package/dist/config.d.ts.map +1 -0
  75. package/dist/config.js +58 -0
  76. package/dist/config.js.map +1 -0
  77. package/dist/git-hooks.d.ts +6 -0
  78. package/dist/git-hooks.d.ts.map +1 -0
  79. package/dist/git-hooks.js +58 -0
  80. package/dist/git-hooks.js.map +1 -0
  81. package/package.json +24 -18
  82. package/.claude/settings.local.json +0 -41
  83. package/.contextgit/config.json +0 -10
  84. package/.contextgit/system-prompt.md +0 -4
  85. package/.github/workflows/contextgit-ci.yml +0 -40
  86. package/CLAUDE.md +0 -123
  87. package/CLAUDE.md.next +0 -65
  88. package/docs/ContextGit_ARCHITECTURE_v3.md +0 -1141
  89. package/docs/ContextGit_DELTA.md +0 -84
  90. package/docs/ContextGit_PHASE1_PLAN.md +0 -177
  91. package/docs/ContextGit_PHASE2_PLAN.md +0 -535
  92. package/docs/ContextGit_PRD_v4.md +0 -488
  93. package/docs/decisions.md +0 -370
  94. package/packages/api/package.json +0 -25
  95. package/packages/api/src/bootstrap.ts +0 -64
  96. package/packages/api/src/config.ts +0 -45
  97. package/packages/api/src/index.ts +0 -17
  98. package/packages/api/src/middleware/auth.test.ts +0 -83
  99. package/packages/api/src/middleware/auth.ts +0 -41
  100. package/packages/api/src/remote-store.test.ts +0 -301
  101. package/packages/api/src/router.ts +0 -121
  102. package/packages/api/src/server-config.ts +0 -34
  103. package/packages/api/src/server.ts +0 -38
  104. package/packages/api/src/store-router.ts +0 -241
  105. package/packages/api/tsconfig.json +0 -8
  106. package/packages/cli/package.json +0 -29
  107. package/packages/cli/src/bootstrap.ts +0 -68
  108. package/packages/cli/src/commands/branch.ts +0 -58
  109. package/packages/cli/src/commands/claim.ts +0 -58
  110. package/packages/cli/src/commands/commit.ts +0 -79
  111. package/packages/cli/src/commands/context.ts +0 -46
  112. package/packages/cli/src/commands/doctor.ts +0 -99
  113. package/packages/cli/src/commands/init.ts +0 -141
  114. package/packages/cli/src/commands/keygen.ts +0 -65
  115. package/packages/cli/src/commands/log.ts +0 -103
  116. package/packages/cli/src/commands/merge.ts +0 -36
  117. package/packages/cli/src/commands/pull.ts +0 -145
  118. package/packages/cli/src/commands/push.ts +0 -158
  119. package/packages/cli/src/commands/remote-show.ts +0 -87
  120. package/packages/cli/src/commands/search.ts +0 -54
  121. package/packages/cli/src/commands/serve.ts +0 -61
  122. package/packages/cli/src/commands/set-remote.ts +0 -30
  123. package/packages/cli/src/commands/status.ts +0 -62
  124. package/packages/cli/src/commands/unclaim.ts +0 -28
  125. package/packages/cli/src/config.ts +0 -64
  126. package/packages/cli/src/git-hooks.ts +0 -61
  127. package/packages/cli/tsconfig.json +0 -9
  128. package/packages/core/package.json +0 -28
  129. package/packages/core/src/embeddings.test.ts +0 -58
  130. package/packages/core/src/embeddings.ts +0 -75
  131. package/packages/core/src/engine.ts +0 -274
  132. package/packages/core/src/index.ts +0 -6
  133. package/packages/core/src/snapshot.ts +0 -82
  134. package/packages/core/src/summarizer.test.ts +0 -120
  135. package/packages/core/src/summarizer.ts +0 -113
  136. package/packages/core/src/threads.ts +0 -29
  137. package/packages/core/src/types.ts +0 -240
  138. package/packages/core/tsconfig.json +0 -9
  139. package/packages/mcp/package.json +0 -31
  140. package/packages/mcp/src/auto-snapshot.ts +0 -83
  141. package/packages/mcp/src/config.ts +0 -53
  142. package/packages/mcp/src/git-sync.ts +0 -94
  143. package/packages/mcp/src/index.ts +0 -19
  144. package/packages/mcp/src/server.ts +0 -377
  145. package/packages/mcp/tsconfig.json +0 -9
  146. package/packages/store/package.json +0 -30
  147. package/packages/store/src/branch-merge.test.ts +0 -127
  148. package/packages/store/src/engine-integration.test.ts +0 -93
  149. package/packages/store/src/index.ts +0 -3
  150. package/packages/store/src/interface.ts +0 -62
  151. package/packages/store/src/local/claims.test.ts +0 -190
  152. package/packages/store/src/local/index.ts +0 -380
  153. package/packages/store/src/local/local-store.test.ts +0 -164
  154. package/packages/store/src/local/migrations.ts +0 -99
  155. package/packages/store/src/local/queries.ts +0 -760
  156. package/packages/store/src/local/schema.ts +0 -157
  157. package/packages/store/src/remote/index.ts +0 -300
  158. package/packages/store/tsconfig.json +0 -9
  159. package/pnpm-workspace.yaml +0 -2
  160. package/scripts/build.sh +0 -28
  161. package/tsconfig.base.json +0 -14
  162. package/vitest.config.ts +0 -15
  163. /package/{packages/cli/bin → bin}/run.js +0 -0
@@ -0,0 +1,141 @@
1
+ // push — push local context commits to a remote ContextGit API server.
2
+ //
3
+ // Requires `remote` in .contextgit/config.json.
4
+ // Algorithm:
5
+ // 1. Ensure project exists on remote (idempotent via ID)
6
+ // 2. For each local branch: ensure branch exists on remote
7
+ // 3. For each branch: collect local commits not present on remote, POST them
8
+ import { Command, Flags } from '@oclif/core';
9
+ import { LocalStore, RemoteStore } from '@contextgit/store';
10
+ import { loadConfig } from '../config.js';
11
+ const PAGE = 100;
12
+ async function allCommits(store, branchId) {
13
+ const acc = [];
14
+ let offset = 0;
15
+ const pg = { limit: PAGE, offset };
16
+ while (true) {
17
+ pg.offset = offset;
18
+ const page = await store.listCommits(branchId, pg);
19
+ acc.push(...page);
20
+ if (page.length < PAGE)
21
+ break;
22
+ offset += PAGE;
23
+ }
24
+ return acc;
25
+ }
26
+ export default class PushCmd extends Command {
27
+ static description = 'Push local context commits to a remote ContextGit API';
28
+ static flags = {
29
+ remote: Flags.string({
30
+ char: 'r',
31
+ description: 'Remote API URL (overrides config.remote)',
32
+ required: false,
33
+ }),
34
+ 'dry-run': Flags.boolean({
35
+ description: 'Show what would be pushed without actually pushing',
36
+ default: false,
37
+ }),
38
+ };
39
+ async run() {
40
+ const { flags } = await this.parse(PushCmd);
41
+ const config = loadConfig();
42
+ const remoteUrl = flags.remote ?? config.remote;
43
+ if (!remoteUrl) {
44
+ this.error('No remote configured. Use: contextgit set-remote <url>', { exit: 1 });
45
+ }
46
+ const local = new LocalStore(config.projectId);
47
+ const remote = new RemoteStore(remoteUrl);
48
+ const dryRun = flags['dry-run'];
49
+ // 1. Ensure project on remote
50
+ const existingProject = await remote.getProject(config.projectId).catch(() => null);
51
+ if (!existingProject) {
52
+ if (!dryRun) {
53
+ await remote.createProject({ id: config.projectId, name: config.project });
54
+ }
55
+ this.log(`[project] ${dryRun ? 'would create' : 'created'}: ${config.project}`);
56
+ }
57
+ else {
58
+ this.log(`[project] already exists: ${config.project}`);
59
+ }
60
+ // 2. List all local branches
61
+ const branches = await local.listBranches(config.projectId);
62
+ let totalPushed = 0;
63
+ for (const branch of branches) {
64
+ // Ensure branch on remote
65
+ const remoteBranch = await remote.getBranch(branch.id).catch(() => null);
66
+ if (!remoteBranch) {
67
+ if (!dryRun) {
68
+ await remote.createBranch({
69
+ id: branch.id,
70
+ projectId: branch.projectId,
71
+ name: branch.name,
72
+ gitBranch: branch.gitBranch,
73
+ parentBranchId: branch.parentBranchId,
74
+ });
75
+ }
76
+ this.log(`[branch] ${dryRun ? 'would create' : 'created'}: ${branch.name}`);
77
+ }
78
+ // Collect remote commit IDs for this branch
79
+ let remoteCommitIds;
80
+ try {
81
+ const remoteCommits = await allCommits(remote, branch.id);
82
+ remoteCommitIds = new Set(remoteCommits.map(c => c.id));
83
+ }
84
+ catch {
85
+ remoteCommitIds = new Set();
86
+ }
87
+ // Push missing commits
88
+ const localCommits = await allCommits(local, branch.id);
89
+ const missing = localCommits.filter(c => !remoteCommitIds.has(c.id));
90
+ if (missing.length === 0) {
91
+ this.log(`[branch] ${branch.name}: up to date (${localCommits.length} commits)`);
92
+ continue;
93
+ }
94
+ this.log(`[branch] ${branch.name}: pushing ${missing.length} commit(s)…`);
95
+ for (const commit of missing) {
96
+ if (!dryRun) {
97
+ await remote.createCommit({
98
+ id: commit.id,
99
+ branchId: commit.branchId,
100
+ parentId: commit.parentId,
101
+ agentId: commit.agentId,
102
+ agentRole: commit.agentRole,
103
+ tool: commit.tool,
104
+ workflowType: commit.workflowType,
105
+ loopIteration: commit.loopIteration,
106
+ ciRunId: commit.ciRunId,
107
+ pipelineName: commit.pipelineName,
108
+ message: commit.message,
109
+ content: commit.content,
110
+ summary: commit.summary,
111
+ commitType: commit.commitType,
112
+ gitCommitSha: commit.gitCommitSha,
113
+ });
114
+ }
115
+ totalPushed++;
116
+ }
117
+ }
118
+ // Thread sync: push open threads that are missing on remote
119
+ const localThreads = await local.listOpenThreads(config.projectId);
120
+ let remoteThreadIds;
121
+ try {
122
+ const remoteThreads = await remote.listOpenThreads(config.projectId);
123
+ remoteThreadIds = new Set(remoteThreads.map(t => t.id));
124
+ }
125
+ catch {
126
+ remoteThreadIds = new Set();
127
+ }
128
+ const missingThreads = localThreads.filter(t => !remoteThreadIds.has(t.id));
129
+ if (missingThreads.length > 0) {
130
+ this.log(`\n[threads] pushing ${missingThreads.length} open thread(s)…`);
131
+ for (const thread of missingThreads) {
132
+ if (!dryRun) {
133
+ await remote.syncThread(thread);
134
+ }
135
+ this.log(` ${dryRun ? 'would push' : 'pushed'}: ${thread.description}`);
136
+ }
137
+ }
138
+ this.log(`\nDone. ${dryRun ? '(dry run) ' : ''}${totalPushed} commit(s), ${missingThreads.length} thread(s) pushed to ${remoteUrl}`);
139
+ }
140
+ }
141
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class RemoteShowCmd extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
6
+ //# sourceMappingURL=remote-show.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-show.d.ts","sourceRoot":"","sources":["../../src/commands/remote-show.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AA0BrC,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IAChD,MAAM,CAAC,WAAW,SAAoD;IAEhE,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAuD3B"}
@@ -0,0 +1,71 @@
1
+ // remote-show — display remote config and connectivity status.
2
+ import { Command } from '@oclif/core';
3
+ import { LocalStore } from '@contextgit/store';
4
+ import { loadConfig } from '../config.js';
5
+ async function probeRemote(baseUrl, projectId) {
6
+ const url = `${baseUrl.replace(/\/$/, '')}/v1/store/projects/${projectId}`;
7
+ let res;
8
+ try {
9
+ res = await fetch(url, { signal: AbortSignal.timeout(5000) });
10
+ }
11
+ catch (err) {
12
+ return { kind: 'unreachable', error: err instanceof Error ? err.message : String(err) };
13
+ }
14
+ if (res.status === 401 || res.status === 403)
15
+ return { kind: 'auth-required' };
16
+ if (res.status === 404)
17
+ return { kind: 'not-found' };
18
+ if (!res.ok)
19
+ return { kind: 'error', status: res.status };
20
+ const body = (await res.json());
21
+ return { kind: 'ok', project: body };
22
+ }
23
+ export default class RemoteShowCmd extends Command {
24
+ static description = 'Show remote configuration and connection status';
25
+ async run() {
26
+ const config = loadConfig();
27
+ const store = new LocalStore(config.projectId);
28
+ this.log(`Project: ${config.project} (${config.projectId})`);
29
+ const remoteUrl = config.remote;
30
+ if (!remoteUrl) {
31
+ this.log(`Remote: (not configured)`);
32
+ this.log(``);
33
+ this.log(`Run: contextgit set-remote <url>`);
34
+ return;
35
+ }
36
+ this.log(`Remote: ${remoteUrl}`);
37
+ // Local stats
38
+ const branches = await store.listBranches(config.projectId);
39
+ let totalLocalCommits = 0;
40
+ for (const b of branches) {
41
+ const commits = await store.listCommits(b.id, { limit: 10_000, offset: 0 });
42
+ totalLocalCommits += commits.length;
43
+ }
44
+ this.log(`Local: ${branches.length} branch(es), ${totalLocalCommits} commit(s)`);
45
+ // Connectivity check
46
+ this.log(``);
47
+ this.log(`Checking connection…`);
48
+ const result = await probeRemote(remoteUrl, config.projectId);
49
+ switch (result.kind) {
50
+ case 'unreachable':
51
+ this.log(`Status: Unreachable`);
52
+ this.log(`Error: ${result.error}`);
53
+ break;
54
+ case 'auth-required':
55
+ this.log(`Status: Connected (authentication required — API key not configured in CLI)`);
56
+ break;
57
+ case 'not-found':
58
+ this.log(`Status: Connected, project not yet pushed`);
59
+ this.log(`Tip: Run 'contextgit push' to create the project on the remote.`);
60
+ break;
61
+ case 'ok':
62
+ this.log(`Status: Connected`);
63
+ this.log(`Remote project: ${result.project.name}`);
64
+ break;
65
+ case 'error':
66
+ this.log(`Status: Error (HTTP ${result.status})`);
67
+ break;
68
+ }
69
+ }
70
+ }
71
+ //# sourceMappingURL=remote-show.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-show.js","sourceRoot":"","sources":["../../src/commands/remote-show.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class SearchCmd extends Command {
3
+ static description: string;
4
+ static flags: {
5
+ query: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
6
+ limit: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ json: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAI5C,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,OAAO;IAC5C,MAAM,CAAC,WAAW,SAAiD;IAEnE,MAAM,CAAC,KAAK;;;;MAeX;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA2B3B"}
@@ -0,0 +1,47 @@
1
+ // search — full-text search over context commits.
2
+ import { Command, Flags } from '@oclif/core';
3
+ import { LocalStore } from '@contextgit/store';
4
+ import { loadConfig } from '../config.js';
5
+ export default class SearchCmd extends Command {
6
+ static description = 'Search context commits with full-text search';
7
+ static flags = {
8
+ query: Flags.string({
9
+ char: 'q',
10
+ description: 'Search query',
11
+ required: true,
12
+ }),
13
+ limit: Flags.integer({
14
+ char: 'l',
15
+ description: 'Maximum results to show',
16
+ default: 5,
17
+ }),
18
+ json: Flags.boolean({
19
+ description: 'Output as JSON',
20
+ default: false,
21
+ }),
22
+ };
23
+ async run() {
24
+ const { flags } = await this.parse(SearchCmd);
25
+ const config = loadConfig();
26
+ const store = new LocalStore(config.projectId);
27
+ const results = await store.fullTextSearch(flags.query, config.projectId);
28
+ const trimmed = results.slice(0, flags.limit);
29
+ if (flags.json) {
30
+ this.log(JSON.stringify(trimmed, null, 2));
31
+ return;
32
+ }
33
+ if (trimmed.length === 0) {
34
+ this.log(`No results for: ${flags.query}`);
35
+ return;
36
+ }
37
+ this.log(`Found ${trimmed.length} result(s) for: "${flags.query}"\n`);
38
+ for (const r of trimmed) {
39
+ const ts = new Date(r.commit.createdAt).toLocaleString();
40
+ this.log(`[${r.matchType}] ${r.commit.message}`);
41
+ this.log(` ID: ${r.commit.id} | ${ts}`);
42
+ this.log(` ${r.commit.content.slice(0, 120).replace(/\n/g, ' ')}`);
43
+ this.log('');
44
+ }
45
+ }
46
+ }
47
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAElD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,OAAO;IAC5C,MAAM,CAAC,WAAW,GAAG,8CAA8C,CAAA;IAEnE,MAAM,CAAC,KAAK,GAAG;QACb,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC;YAClB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,cAAc;YAC3B,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,yBAAyB;YACtC,OAAO,EAAE,CAAC;SACX,CAAC;QACF,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC;YAClB,WAAW,EAAE,gBAAgB;YAC7B,OAAO,EAAE,KAAK;SACf,CAAC;KACH,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;QAC3B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAE9C,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAA;QACzE,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;QAE7C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC1C,OAAM;QACR,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YAC1C,OAAM;QACR,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,SAAS,OAAO,CAAC,MAAM,oBAAoB,KAAK,CAAC,KAAK,KAAK,CAAC,CAAA;QACrE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAA;YACxD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;YAChD,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;YAC1C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;YACnE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACd,CAAC;IACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ServeCmd extends Command {
3
+ static description: string;
4
+ static flags: {
5
+ port: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
6
+ };
7
+ run(): Promise<void>;
8
+ }
9
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAc5C,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,MAAM,CAAC,WAAW,SAAoC;IAEtD,MAAM,CAAC,KAAK;;MAOX;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA6B3B"}
@@ -0,0 +1,51 @@
1
+ // serve — start the ContextGit API server from the CLI.
2
+ import os from 'os';
3
+ import { join } from 'path';
4
+ import { readFileSync } from 'fs';
5
+ import { Command, Flags } from '@oclif/core';
6
+ import { createApp } from '@contextgit/api';
7
+ const SERVER_CONFIG_PATH = join(os.homedir(), '.contextgit', 'server.json');
8
+ function hasKeyConfigured() {
9
+ try {
10
+ const cfg = JSON.parse(readFileSync(SERVER_CONFIG_PATH, 'utf-8'));
11
+ return typeof cfg['keyHash'] === 'string' && cfg['keyHash'].length > 0;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ export default class ServeCmd extends Command {
18
+ static description = 'Start the ContextGit API server';
19
+ static flags = {
20
+ port: Flags.integer({
21
+ char: 'p',
22
+ description: 'Port to listen on',
23
+ default: 3141,
24
+ env: 'PORT',
25
+ }),
26
+ };
27
+ async run() {
28
+ const { flags } = await this.parse(ServeCmd);
29
+ const port = flags.port;
30
+ const authConfigured = hasKeyConfigured();
31
+ this.log('ContextGit API server starting...');
32
+ this.log(`Port: ${port}`);
33
+ this.log(`Auth: ${authConfigured ? 'key configured' : 'OPEN (no key set — run: contextgit keygen --save)'}`);
34
+ this.log('');
35
+ const app = await createApp();
36
+ await new Promise((resolve, reject) => {
37
+ const server = app.listen(port, () => {
38
+ this.log(`Listening on http://localhost:${port}`);
39
+ this.log('Press Ctrl+C to stop.');
40
+ });
41
+ server.on('error', reject);
42
+ process.on('SIGINT', () => {
43
+ server.close(() => resolve());
44
+ });
45
+ process.on('SIGTERM', () => {
46
+ server.close(() => resolve());
47
+ });
48
+ });
49
+ }
50
+ }
51
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,MAAM,kBAAkB,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,aAAa,CAAC,CAAA;AAE3E,SAAS,gBAAgB;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAA4B,CAAA;QAC5F,OAAO,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,MAAM,CAAC,WAAW,GAAG,iCAAiC,CAAA;IAEtD,MAAM,CAAC,KAAK,GAAG;QACb,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC;YAClB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,mBAAmB;YAChC,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,MAAM;SACZ,CAAC;KACH,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAA;QAEvB,MAAM,cAAc,GAAG,gBAAgB,EAAE,CAAA;QAEzC,IAAI,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAA;QAC7C,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAA;QAC3B,IAAI,CAAC,GAAG,CAAC,WAAW,cAAc,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,mDAAmD,EAAE,CAAC,CAAA;QAC9G,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAEZ,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAA;QAE7B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;gBACnC,IAAI,CAAC,GAAG,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAA;gBACjD,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;YACnC,CAAC,CAAC,CAAA;YAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YAE1B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;gBACxB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;YAC/B,CAAC,CAAC,CAAA;YACF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;gBACzB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;YAC/B,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class SetRemoteCmd extends Command {
3
+ static description: string;
4
+ static args: {
5
+ url: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
6
+ };
7
+ run(): Promise<void>;
8
+ }
9
+ //# sourceMappingURL=set-remote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-remote.d.ts","sourceRoot":"","sources":["../../src/commands/set-remote.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAQ,MAAM,aAAa,CAAA;AAG3C,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,MAAM,CAAC,WAAW,SAAgD;IAElE,MAAM,CAAC,IAAI;;MAKV;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAc3B"}
@@ -0,0 +1,26 @@
1
+ // set-remote — write a remote ContextGit API URL to config.json.
2
+ import { Command, Args } from '@oclif/core';
3
+ import { loadConfig, saveConfig } from '../config.js';
4
+ export default class SetRemoteCmd extends Command {
5
+ static description = 'Set the remote ContextGit API URL in config';
6
+ static args = {
7
+ url: Args.string({
8
+ description: 'Remote API URL (e.g. https://api.example.com)',
9
+ required: true,
10
+ }),
11
+ };
12
+ async run() {
13
+ const { args } = await this.parse(SetRemoteCmd);
14
+ const config = loadConfig();
15
+ const previous = config.remote;
16
+ saveConfig({ remote: args.url });
17
+ if (previous) {
18
+ this.log(`Remote updated: ${previous} → ${args.url}`);
19
+ }
20
+ else {
21
+ this.log(`Remote set: ${args.url}`);
22
+ }
23
+ this.log(`Use 'contextgit push' to sync commits to this remote.`);
24
+ }
25
+ }
26
+ //# sourceMappingURL=set-remote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-remote.js","sourceRoot":"","sources":["../../src/commands/set-remote.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAErD,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,MAAM,CAAC,WAAW,GAAG,6CAA6C,CAAA;IAElE,MAAM,CAAC,IAAI,GAAG;QACZ,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC;YACf,WAAW,EAAE,+CAA+C;YAC5D,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAC/C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;QAE3B,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAA;QAC9B,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAEhC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,mBAAmB,QAAQ,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QACvD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QACrC,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAA;IACnE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class StatusCmd extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
6
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAKrC,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,OAAO;IAC5C,MAAM,CAAC,WAAW,SAAmC;IAE/C,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAmD3B"}
@@ -0,0 +1,54 @@
1
+ // status — show current project/branch/thread status.
2
+ import { Command } from '@oclif/core';
3
+ import { simpleGit } from 'simple-git';
4
+ import { LocalStore } from '@contextgit/store';
5
+ import { loadConfig } from '../config.js';
6
+ export default class StatusCmd extends Command {
7
+ static description = 'Show current ContextGit status';
8
+ async run() {
9
+ const config = loadConfig();
10
+ const store = new LocalStore(config.projectId);
11
+ const cwd = process.cwd();
12
+ // Detect current git branch
13
+ let gitBranch = 'main';
14
+ try {
15
+ gitBranch = (await simpleGit(cwd).revparse(['--abbrev-ref', 'HEAD'])).trim();
16
+ }
17
+ catch {
18
+ // fallback
19
+ }
20
+ const branch = await store.getBranchByGitName(config.projectId, gitBranch);
21
+ if (!branch) {
22
+ this.error(`No context branch found for git branch '${gitBranch}'. Run 'contextgit init' first.`);
23
+ }
24
+ const threads = await store.listOpenThreadsByBranch(branch.id);
25
+ const commits = await store.listCommits(branch.id, { limit: 5, offset: 0 });
26
+ const agents = await store.listAgents(config.projectId);
27
+ const allBranches = await store.listBranches(config.projectId);
28
+ this.log(`Project: ${config.project} (${config.projectId})`);
29
+ this.log(`Branch: ${branch.name} [${branch.status}]`);
30
+ this.log(`Git: ${gitBranch}`);
31
+ this.log(`Store: ${config.store === 'local' ? 'local SQLite' : config.store}`);
32
+ if (config.remote)
33
+ this.log(`Remote: ${config.remote}`);
34
+ this.log('');
35
+ this.log(`Branches: ${allBranches.length} total`);
36
+ this.log(`Commits: ${commits.length} recent (showing last 5)`);
37
+ this.log(`Threads: ${threads.length} open`);
38
+ this.log(`Agents: ${agents.length} registered`);
39
+ if (threads.length > 0) {
40
+ this.log('\nOpen threads:');
41
+ for (const t of threads) {
42
+ this.log(` [${t.id.slice(0, 8)}] ${t.description}`);
43
+ }
44
+ }
45
+ if (commits.length > 0) {
46
+ this.log('\nRecent commits:');
47
+ for (const c of commits) {
48
+ const ts = new Date(c.createdAt).toLocaleString();
49
+ this.log(` [${c.id.slice(0, 8)}] ${c.message} (${ts})`);
50
+ }
51
+ }
52
+ }
53
+ }
54
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class UnclaimCmd extends Command {
3
+ static description: string;
4
+ static args: {
5
+ claimId: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
6
+ };
7
+ run(): Promise<void>;
8
+ }
9
+ //# sourceMappingURL=unclaim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unclaim.d.ts","sourceRoot":"","sources":["../../src/commands/unclaim.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAQ,MAAM,aAAa,CAAA;AAI3C,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,SAAsC;IAExD,MAAM,CAAC,IAAI;;MAKV;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAW3B"}
@@ -0,0 +1,22 @@
1
+ // unclaim — manually release a task claim.
2
+ import { Command, Args } from '@oclif/core';
3
+ import { LocalStore } from '@contextgit/store';
4
+ import { loadConfig } from '../config.js';
5
+ export default class UnclaimCmd extends Command {
6
+ static description = 'Release a previously claimed task';
7
+ static args = {
8
+ claimId: Args.string({
9
+ description: 'ID of the claim to release',
10
+ required: true,
11
+ }),
12
+ };
13
+ async run() {
14
+ const { args } = await this.parse(UnclaimCmd);
15
+ const config = loadConfig();
16
+ const store = new LocalStore(config.projectId);
17
+ await store.unclaimTask(args.claimId);
18
+ this.log(`Released: ${args.claimId}`);
19
+ store.close();
20
+ }
21
+ }
22
+ //# sourceMappingURL=unclaim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unclaim.js","sourceRoot":"","sources":["../../src/commands/unclaim.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAE3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,GAAG,mCAAmC,CAAA;IAExD,MAAM,CAAC,IAAI,GAAG;QACZ,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;YACnB,WAAW,EAAE,4BAA4B;YACzC,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;QAC3B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAE9C,MAAM,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAErC,IAAI,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QAErC,KAAK,CAAC,KAAK,EAAE,CAAA;IACf,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { ContextGitConfig } from '@contextgit/core';
2
+ export declare class ConfigNotFoundError extends Error {
3
+ constructor(startDir: string);
4
+ }
5
+ /**
6
+ * Search upward from `startDir` for `.contextgit/config.json`.
7
+ * Returns the first match found, or throws ConfigNotFoundError.
8
+ */
9
+ export declare function findConfigPath(startDir?: string): string;
10
+ /**
11
+ * Load and parse `.contextgit/config.json`.
12
+ * Throws ConfigNotFoundError if not found, or Error if JSON is invalid.
13
+ */
14
+ export declare function loadConfig(startDir?: string): ContextGitConfig;
15
+ /**
16
+ * Save updated config back to the config.json it was loaded from.
17
+ */
18
+ export declare function saveConfig(updates: Partial<import('@contextgit/core').ContextGitConfig>, startDir?: string): void;
19
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,QAAQ,EAAE,MAAM;CAI7B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAevE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAa9D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,kBAAkB,EAAE,gBAAgB,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAMjH"}
package/dist/config.js ADDED
@@ -0,0 +1,58 @@
1
+ // config.ts — load and validate .contextgit/config.json
2
+ // Searches from CWD upwards until it finds the config file.
3
+ import { readFileSync, writeFileSync } from 'fs';
4
+ import { join, dirname } from 'path';
5
+ export class ConfigNotFoundError extends Error {
6
+ constructor(startDir) {
7
+ super(`No .contextgit/config.json found searching upward from: ${startDir}`);
8
+ this.name = 'ConfigNotFoundError';
9
+ }
10
+ }
11
+ /**
12
+ * Search upward from `startDir` for `.contextgit/config.json`.
13
+ * Returns the first match found, or throws ConfigNotFoundError.
14
+ */
15
+ export function findConfigPath(startDir = process.cwd()) {
16
+ let current = startDir;
17
+ while (true) {
18
+ const candidate = join(current, '.contextgit', 'config.json');
19
+ try {
20
+ readFileSync(candidate);
21
+ return candidate;
22
+ }
23
+ catch {
24
+ const parent = dirname(current);
25
+ if (parent === current) {
26
+ throw new ConfigNotFoundError(startDir);
27
+ }
28
+ current = parent;
29
+ }
30
+ }
31
+ }
32
+ /**
33
+ * Load and parse `.contextgit/config.json`.
34
+ * Throws ConfigNotFoundError if not found, or Error if JSON is invalid.
35
+ */
36
+ export function loadConfig(startDir) {
37
+ const configPath = findConfigPath(startDir);
38
+ const raw = readFileSync(configPath, 'utf-8');
39
+ const config = JSON.parse(raw);
40
+ if (!config.projectId) {
41
+ throw new Error(`Invalid config at ${configPath}: missing required field 'projectId'`);
42
+ }
43
+ if (!config.project) {
44
+ throw new Error(`Invalid config at ${configPath}: missing required field 'project'`);
45
+ }
46
+ return config;
47
+ }
48
+ /**
49
+ * Save updated config back to the config.json it was loaded from.
50
+ */
51
+ export function saveConfig(updates, startDir) {
52
+ const configPath = findConfigPath(startDir);
53
+ const raw = readFileSync(configPath, 'utf-8');
54
+ const existing = JSON.parse(raw);
55
+ const updated = { ...existing, ...updates };
56
+ writeFileSync(configPath, JSON.stringify(updated, null, 2) + '\n', 'utf-8');
57
+ }
58
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,4DAA4D;AAE5D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGpC,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,QAAgB;QAC1B,KAAK,CAAC,2DAA2D,QAAQ,EAAE,CAAC,CAAA;QAC5E,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACnC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC7D,IAAI,OAAO,GAAG,QAAQ,CAAA;IACtB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,aAAa,CAAC,CAAA;QAC7D,IAAI,CAAC;YACH,YAAY,CAAC,SAAS,CAAC,CAAA;YACvB,OAAO,SAAS,CAAA;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;YAC/B,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvB,MAAM,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAA;YACzC,CAAC;YACD,OAAO,GAAG,MAAM,CAAA;QAClB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,QAAiB;IAC1C,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IAC3C,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAA;IAElD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,sCAAsC,CAAC,CAAA;IACxF,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,oCAAoC,CAAC,CAAA;IACtF,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,OAA6D,EAAE,QAAiB;IACzG,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IAC3C,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgD,CAAA;IAC/E,MAAM,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAA;IAC3C,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;AAC7E,CAAC"}