pi-automem-bridge 0.2.0 → 0.2.2

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.
@@ -1,94 +1,96 @@
1
- /**
2
- * project-detect.ts - Infer the current project from cwd, git remote, and prompt text.
3
- */
4
-
5
- import { existsSync, readFileSync } from "node:fs";
6
- import { resolve } from "node:path";
7
- import type { AutoMemConfig } from "./config";
8
-
9
- export interface ProjectDetection {
10
- projectTag: string | null;
11
- projectLabel: string | null;
12
- }
13
-
14
- function detectFromGit(cwd: string, gitRepoToTag: Record<string, string>): ProjectDetection {
15
- // Walk up the directory tree to handle running from a subdirectory of a repo
16
- let dir = cwd;
17
- while (true) {
18
- const gitConfigPath = resolve(dir, ".git", "config");
19
- if (existsSync(gitConfigPath)) {
20
- try {
21
- const gitConfig = readFileSync(gitConfigPath, "utf8");
22
- const urlMatch = gitConfig.match(/\[remote "[^"]+"\][\s\S]*?url\s*=\s*(.+)/);
23
- if (urlMatch) {
24
- const remoteUrl = urlMatch[1].trim().toLowerCase();
25
- const keys = Object.keys(gitRepoToTag);
26
- for (let i = 0; i < keys.length; i++) {
27
- const substring = keys[i].toLowerCase();
28
- if (remoteUrl.indexOf(substring) !== -1) {
29
- const tag = gitRepoToTag[keys[i]];
30
- return { projectTag: tag, projectLabel: tag.replace(/^[^:]+:/, "") };
31
- }
32
- }
33
- }
34
- } catch (_e) {
35
- // ignore unreadable config
36
- }
37
- // Found .git but no matching remote — stop traversing
38
- break;
39
- }
40
- const parent = resolve(dir, "..");
41
- if (parent === dir) break; // reached filesystem root
42
- dir = parent;
43
- }
44
-
45
- return { projectTag: null, projectLabel: null };
46
- }
47
-
48
- function detectFromFolder(cwd: string, folderTags: Record<string, string[]>): ProjectDetection {
49
- const normalizedFolderTags: Record<string, string[]> = {};
50
- const keys = Object.keys(folderTags);
51
- for (let i = 0; i < keys.length; i++) {
52
- normalizedFolderTags[keys[i].toLowerCase()] = folderTags[keys[i]];
53
- }
54
-
55
- const parts = cwd.split(/[\\/]/);
56
- for (let i = 0; i < parts.length; i++) {
57
- const lower = parts[i].toLowerCase();
58
- if (normalizedFolderTags[lower] && normalizedFolderTags[lower].length > 0) {
59
- const tag = normalizedFolderTags[lower][0];
60
- return { projectTag: tag, projectLabel: lower };
61
- }
62
- }
63
- return { projectTag: null, projectLabel: null };
64
- }
65
-
66
- function detectFromPrompt(prompt: string, gitRepoToTag: Record<string, string>): ProjectDetection {
67
- const lower = prompt.toLowerCase();
68
- const keys = Object.keys(gitRepoToTag);
69
- for (let i = 0; i < keys.length; i++) {
70
- if (lower.indexOf(keys[i].toLowerCase()) !== -1) {
71
- const tag = gitRepoToTag[keys[i]];
72
- return { projectTag: tag, projectLabel: tag.replace(/^[^:]+:/, "") };
73
- }
74
- }
75
- return { projectTag: null, projectLabel: null };
76
- }
77
-
78
- export function detectProject(
79
- cwd: string,
80
- prompt: string,
81
- config: AutoMemConfig,
82
- ): ProjectDetection {
83
- if (!config.projectDetection.enabled) {
84
- return { projectTag: null, projectLabel: null };
85
- }
86
-
87
- const gitResult = detectFromGit(cwd, config.projectDetection.gitRepoToTag);
88
- if (gitResult.projectTag) return gitResult;
89
-
90
- const folderResult = detectFromFolder(cwd, config.projectDetection.folderTags);
91
- if (folderResult.projectTag) return folderResult;
92
-
93
- return detectFromPrompt(prompt, config.projectDetection.gitRepoToTag);
94
- }
1
+ /**
2
+ * project-detect.ts - Infer the current project from cwd, git remote, and prompt text.
3
+ */
4
+
5
+ import { existsSync, readFileSync } from "node:fs";
6
+ import { resolve } from "node:path";
7
+ import type { AutoMemConfig } from "./config";
8
+
9
+ export interface ProjectDetection {
10
+ projectTag: string | null;
11
+ projectLabel: string | null;
12
+ }
13
+
14
+ function detectFromGit(cwd: string, gitRepoToTag: Record<string, string>): ProjectDetection {
15
+ // Walk up the directory tree to handle running from a subdirectory of a repo
16
+ let dir = cwd;
17
+ while (true) {
18
+ const gitConfigPath = resolve(dir, ".git", "config");
19
+ if (existsSync(gitConfigPath)) {
20
+ try {
21
+ const gitConfig = readFileSync(gitConfigPath, "utf8");
22
+ // Examine every remote url, not just the first — a repo's configured
23
+ // tag may match a non-first remote (e.g. `upstream`).
24
+ const remoteUrls = Array.from(gitConfig.matchAll(/^\s*url\s*=\s*(.+)$/gim))
25
+ .map(function(m) { return m[1].trim().toLowerCase(); });
26
+ const keys = Object.keys(gitRepoToTag);
27
+ for (let u = 0; u < remoteUrls.length; u++) {
28
+ for (let i = 0; i < keys.length; i++) {
29
+ const substring = keys[i].toLowerCase();
30
+ if (remoteUrls[u].indexOf(substring) !== -1) {
31
+ const tag = gitRepoToTag[keys[i]];
32
+ return { projectTag: tag, projectLabel: tag.replace(/^[^:]+:/, "") };
33
+ }
34
+ }
35
+ }
36
+ } catch (_e) {
37
+ // ignore unreadable config
38
+ }
39
+ // Found .git but no matching remote — stop traversing
40
+ break;
41
+ }
42
+ const parent = resolve(dir, "..");
43
+ if (parent === dir) break; // reached filesystem root
44
+ dir = parent;
45
+ }
46
+
47
+ return { projectTag: null, projectLabel: null };
48
+ }
49
+
50
+ function detectFromFolder(cwd: string, folderTags: Record<string, string[]>): ProjectDetection {
51
+ const normalizedFolderTags: Record<string, string[]> = {};
52
+ const keys = Object.keys(folderTags);
53
+ for (let i = 0; i < keys.length; i++) {
54
+ normalizedFolderTags[keys[i].toLowerCase()] = folderTags[keys[i]];
55
+ }
56
+
57
+ const parts = cwd.split(/[\\/]/);
58
+ for (let i = 0; i < parts.length; i++) {
59
+ const lower = parts[i].toLowerCase();
60
+ if (normalizedFolderTags[lower] && normalizedFolderTags[lower].length > 0) {
61
+ const tag = normalizedFolderTags[lower][0];
62
+ return { projectTag: tag, projectLabel: lower };
63
+ }
64
+ }
65
+ return { projectTag: null, projectLabel: null };
66
+ }
67
+
68
+ function detectFromPrompt(prompt: string, gitRepoToTag: Record<string, string>): ProjectDetection {
69
+ const lower = prompt.toLowerCase();
70
+ const keys = Object.keys(gitRepoToTag);
71
+ for (let i = 0; i < keys.length; i++) {
72
+ if (lower.indexOf(keys[i].toLowerCase()) !== -1) {
73
+ const tag = gitRepoToTag[keys[i]];
74
+ return { projectTag: tag, projectLabel: tag.replace(/^[^:]+:/, "") };
75
+ }
76
+ }
77
+ return { projectTag: null, projectLabel: null };
78
+ }
79
+
80
+ export function detectProject(
81
+ cwd: string,
82
+ prompt: string,
83
+ config: AutoMemConfig,
84
+ ): ProjectDetection {
85
+ if (!config.projectDetection.enabled) {
86
+ return { projectTag: null, projectLabel: null };
87
+ }
88
+
89
+ const gitResult = detectFromGit(cwd, config.projectDetection.gitRepoToTag);
90
+ if (gitResult.projectTag) return gitResult;
91
+
92
+ const folderResult = detectFromFolder(cwd, config.projectDetection.folderTags);
93
+ if (folderResult.projectTag) return folderResult;
94
+
95
+ return detectFromPrompt(prompt, config.projectDetection.gitRepoToTag);
96
+ }