devsmind-mcp 2.2.2 → 2.4.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 (54) hide show
  1. package/README.md +234 -606
  2. package/dist/cli/analyze.d.ts +13 -0
  3. package/dist/cli/analyze.js +143 -0
  4. package/dist/cli/analyze.js.map +1 -0
  5. package/dist/cli/index.js +62 -0
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/init.js +9 -0
  8. package/dist/cli/init.js.map +1 -1
  9. package/dist/cli/integrations/memory.js +9 -3
  10. package/dist/cli/integrations/memory.js.map +1 -1
  11. package/dist/cli/integrations/prompt.d.ts +2 -0
  12. package/dist/cli/integrations/prompt.js +21 -7
  13. package/dist/cli/integrations/prompt.js.map +1 -1
  14. package/dist/cli/prune.js +4 -3
  15. package/dist/cli/prune.js.map +1 -1
  16. package/dist/cli/rule.js +43 -83
  17. package/dist/cli/rule.js.map +1 -1
  18. package/dist/cli/sync.d.ts +7 -0
  19. package/dist/cli/sync.js +40 -7
  20. package/dist/cli/sync.js.map +1 -1
  21. package/dist/cli/workflow.d.ts +8 -0
  22. package/dist/cli/workflow.js +156 -0
  23. package/dist/cli/workflow.js.map +1 -0
  24. package/dist/db/analyze.d.ts +67 -0
  25. package/dist/db/analyze.js +167 -0
  26. package/dist/db/analyze.js.map +1 -0
  27. package/dist/db/database.d.ts +195 -2
  28. package/dist/db/database.js +870 -74
  29. package/dist/db/database.js.map +1 -1
  30. package/dist/db/schema.d.ts +28 -1
  31. package/dist/db/schema.js +34 -0
  32. package/dist/db/schema.js.map +1 -1
  33. package/dist/db/staging.d.ts +4 -0
  34. package/dist/db/staging.js +16 -2
  35. package/dist/db/staging.js.map +1 -1
  36. package/dist/db/workflow-import.d.ts +22 -0
  37. package/dist/db/workflow-import.js +116 -0
  38. package/dist/db/workflow-import.js.map +1 -0
  39. package/dist/mcp/server.d.ts +1 -1
  40. package/dist/mcp/server.js +641 -48
  41. package/dist/mcp/server.js.map +1 -1
  42. package/dist/utils/ast.d.ts +98 -0
  43. package/dist/utils/ast.js +262 -10
  44. package/dist/utils/ast.js.map +1 -1
  45. package/dist/utils/config.d.ts +2 -0
  46. package/dist/utils/config.js +11 -0
  47. package/dist/utils/config.js.map +1 -1
  48. package/dist/utils/edit.d.ts +41 -0
  49. package/dist/utils/edit.js +163 -0
  50. package/dist/utils/edit.js.map +1 -0
  51. package/dist/utils/git.d.ts +14 -0
  52. package/dist/utils/git.js +43 -0
  53. package/dist/utils/git.js.map +1 -0
  54. package/package.json +1 -1
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.writeFileAtomic = writeFileAtomic;
37
+ exports.createFileWithContent = createFileWithContent;
38
+ exports.replaceTextInFile = replaceTextInFile;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ /**
42
+ * Write via temp file + rename, so a reader never observes a half-written source file and a
43
+ * failed write leaves the original intact.
44
+ */
45
+ function writeFileAtomic(filePath, content) {
46
+ const tmp = `${filePath}.${process.pid}.tmp`;
47
+ try {
48
+ fs.writeFileSync(tmp, content, 'utf-8');
49
+ fs.renameSync(tmp, filePath);
50
+ }
51
+ catch (e) {
52
+ try {
53
+ if (fs.existsSync(tmp))
54
+ fs.unlinkSync(tmp);
55
+ }
56
+ catch { /* ignore */ }
57
+ throw e;
58
+ }
59
+ }
60
+ /**
61
+ * Create a file that does not exist yet, with its parent directories.
62
+ *
63
+ * Reported in the same shape as a replacement — one range spanning the whole file, against an
64
+ * empty "before" — so a new file's contents trace exactly like any other edit, and every symbol
65
+ * in it is new by construction. That keeps creating a file from being a special case the caller
66
+ * has to route somewhere else.
67
+ */
68
+ function createFileWithContent(filePath, content) {
69
+ if (fs.existsSync(filePath)) {
70
+ return { ok: false, error: `${path.basename(filePath)} already exists — pass the exact old_string you want to replace inside it.` };
71
+ }
72
+ try {
73
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
74
+ writeFileAtomic(filePath, content);
75
+ }
76
+ catch (e) {
77
+ return { ok: false, error: `could not create ${filePath}: ${e?.message || e}` };
78
+ }
79
+ return { ok: true, replacements: 1, ranges: [{ start: 0, end: content.length }], before: '', created: true };
80
+ }
81
+ /**
82
+ * Exact-match text replacement — the fallback for files no parser can address by symbol
83
+ * (stylesheets, markup, config, and every non-TS/JS language).
84
+ *
85
+ * Deliberately mirrors the semantics of a standard editor edit tool, including the
86
+ * single-occurrence requirement: a caller that meant one site and matched three would
87
+ * otherwise silently corrupt two of them. `replaceAll` opts out of that check explicitly.
88
+ */
89
+ function replaceTextInFile(filePath, oldString, newString, replaceAll = false) {
90
+ if (oldString === newString) {
91
+ return { ok: false, error: 'old_string and new_string are identical — nothing to do.' };
92
+ }
93
+ let original;
94
+ try {
95
+ original = fs.readFileSync(filePath, 'utf-8');
96
+ }
97
+ catch (e) {
98
+ return { ok: false, error: `could not read ${filePath}: ${e?.message || e}` };
99
+ }
100
+ // An empty needle matches at every position and would advance the scan by zero — the loop
101
+ // below would never terminate. Reserve it for the one case it can mean unambiguously: the
102
+ // file exists but is genuinely empty, so "replace nothing" and "replace everything" coincide
103
+ // and there is no other way to address that content. Any other file gets a real error instead
104
+ // of hanging, and is told to supply the actual text to replace.
105
+ if (oldString === '') {
106
+ if (original.length === 0) {
107
+ try {
108
+ writeFileAtomic(filePath, newString);
109
+ }
110
+ catch (e) {
111
+ return { ok: false, error: `write failed: ${e?.message || e}` };
112
+ }
113
+ return { ok: true, replacements: 1, ranges: [{ start: 0, end: newString.length }], before: '' };
114
+ }
115
+ return {
116
+ ok: false,
117
+ error: 'old_string is empty, but this file already exists and has content. An empty old_string only means "create this file" (or populate an EMPTY one); to change an existing non-empty file, give the exact text to replace.'
118
+ };
119
+ }
120
+ // Count occurrences without regex, so the needle is never interpreted as a pattern.
121
+ let count = 0;
122
+ for (let i = original.indexOf(oldString); i !== -1; i = original.indexOf(oldString, i + oldString.length)) {
123
+ count++;
124
+ if (!replaceAll && count > 1)
125
+ break;
126
+ }
127
+ if (count === 0) {
128
+ return {
129
+ ok: false,
130
+ error: 'old_string was not found in the file. It must match the file byte-for-byte, including indentation. Re-read the file and copy the exact text.'
131
+ };
132
+ }
133
+ if (count > 1 && !replaceAll) {
134
+ return {
135
+ ok: false,
136
+ error: `old_string matches more than one place in the file — nothing was written. Include surrounding lines to make it unique, or pass replace_all: true if every occurrence should change.`
137
+ };
138
+ }
139
+ // Built by hand rather than via replace()/split-join, so each replacement's span in the NEW
140
+ // content is known exactly — later replacements shift as earlier ones change length, and
141
+ // only accumulating as we go accounts for that.
142
+ const ranges = [];
143
+ let updated = '';
144
+ let cursor = 0;
145
+ for (let i = original.indexOf(oldString); i !== -1; i = original.indexOf(oldString, cursor)) {
146
+ updated += original.slice(cursor, i);
147
+ const start = updated.length;
148
+ updated += newString;
149
+ ranges.push({ start, end: updated.length });
150
+ cursor = i + oldString.length;
151
+ if (!replaceAll)
152
+ break;
153
+ }
154
+ updated += original.slice(cursor);
155
+ try {
156
+ writeFileAtomic(filePath, updated);
157
+ }
158
+ catch (e) {
159
+ return { ok: false, error: `write failed: ${e?.message || e}` };
160
+ }
161
+ return { ok: true, replacements: ranges.length, ranges, before: original };
162
+ }
163
+ //# sourceMappingURL=edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/utils/edit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Local git-shelling helpers for `devsmind analyze`. Never throw — a missing git
3
+ * binary, a repo path that isn't a git repo, or an empty history are all treated
4
+ * as "nothing to report" rather than a hard failure, since analyze must still run
5
+ * its non-git checks even when git is unavailable.
6
+ */
7
+ export interface RenamedFile {
8
+ from: string;
9
+ to: string;
10
+ }
11
+ /** Files renamed (via `git log`'s rename detection) since `sinceIso`, deduped by destination path. */
12
+ export declare function getRenamedFilesSince(repoPath: string, sinceIso: string): RenamedFile[];
13
+ /** Distinct file paths touched by any commit since `sinceIso`. */
14
+ export declare function getChangedFilesSince(repoPath: string, sinceIso: string): string[];
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRenamedFilesSince = getRenamedFilesSince;
4
+ exports.getChangedFilesSince = getChangedFilesSince;
5
+ const child_process_1 = require("child_process");
6
+ /** Files renamed (via `git log`'s rename detection) since `sinceIso`, deduped by destination path. */
7
+ function getRenamedFilesSince(repoPath, sinceIso) {
8
+ const out = runGit(repoPath, `log --since="${sinceIso}" --name-status --diff-filter=R --pretty=format:`);
9
+ if (!out)
10
+ return [];
11
+ const byTo = new Map();
12
+ for (const line of out.split('\n')) {
13
+ const trimmed = line.trim();
14
+ if (!trimmed.startsWith('R'))
15
+ continue;
16
+ const parts = trimmed.split('\t');
17
+ if (parts.length < 3)
18
+ continue;
19
+ const [, from, to] = parts;
20
+ if (from && to)
21
+ byTo.set(to, { from, to });
22
+ }
23
+ return Array.from(byTo.values());
24
+ }
25
+ /** Distinct file paths touched by any commit since `sinceIso`. */
26
+ function getChangedFilesSince(repoPath, sinceIso) {
27
+ const out = runGit(repoPath, `log --since="${sinceIso}" --name-only --pretty=format:`);
28
+ if (!out)
29
+ return [];
30
+ return Array.from(new Set(out.split('\n').map(l => l.trim()).filter(Boolean)));
31
+ }
32
+ function runGit(repoPath, args) {
33
+ try {
34
+ // stdio: pipe on all three streams — a non-repo/no-git "fatal: ..." is an EXPECTED,
35
+ // silently-handled case here (falls back to an empty result), not something worth
36
+ // leaking to the user's terminal on every sync/analyze run.
37
+ return (0, child_process_1.execSync)(`git ${args}`, { cwd: repoPath, encoding: 'utf-8', maxBuffer: 1024 * 1024 * 32, stdio: ['ignore', 'pipe', 'ignore'] }).trim();
38
+ }
39
+ catch {
40
+ return '';
41
+ }
42
+ }
43
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":";;AAeA,oDAcC;AAGD,oDAIC;AApCD,iDAAyC;AAczC,sGAAsG;AACtG,SAAgB,oBAAoB,CAAC,QAAgB,EAAE,QAAgB;IACrE,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,gBAAgB,QAAQ,kDAAkD,CAAC,CAAC;IACzG,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IAEpB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC/B,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC;QAC3B,IAAI,IAAI,IAAI,EAAE;YAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,kEAAkE;AAClE,SAAgB,oBAAoB,CAAC,QAAgB,EAAE,QAAgB;IACrE,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,gBAAgB,QAAQ,gCAAgC,CAAC,CAAC;IACvF,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACjF,CAAC;AAED,SAAS,MAAM,CAAC,QAAgB,EAAE,IAAY;IAC5C,IAAI,CAAC;QACH,oFAAoF;QACpF,kFAAkF;QAClF,4DAA4D;QAC5D,OAAO,IAAA,wBAAQ,EAAC,OAAO,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devsmind-mcp",
3
- "version": "2.2.2",
3
+ "version": "2.4.0",
4
4
  "description": "DevsMind — Team AI Brain",
5
5
  "main": "dist/cli/index.js",
6
6
  "bin": {