@amrishkhan05/frankly 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 (123) hide show
  1. package/.claude-plugin/marketplace.json +27 -0
  2. package/.claude-plugin/plugin.json +11 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
  4. package/.github/ISSUE_TEMPLATE/documentation.md +15 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +15 -0
  6. package/.github/PULL_REQUEST_TEMPLATE.md +20 -0
  7. package/.github/copilot-instructions.md +12 -0
  8. package/.github/plugin/marketplace.json +20 -0
  9. package/.github/plugin/plugin.json +16 -0
  10. package/.mcp.json +10 -0
  11. package/LICENSE +21 -0
  12. package/README.md +394 -0
  13. package/commands/frankly-help.toml +2 -0
  14. package/commands/frankly-plan.toml +2 -0
  15. package/commands/frankly-review.toml +2 -0
  16. package/commands/frankly-verify.toml +2 -0
  17. package/commands/frankly.toml +2 -0
  18. package/dist/analysis/change-classifier.d.ts +65 -0
  19. package/dist/analysis/change-classifier.d.ts.map +1 -0
  20. package/dist/analysis/change-classifier.js +241 -0
  21. package/dist/analysis/change-classifier.js.map +1 -0
  22. package/dist/analysis/repository-intelligence.d.ts +15 -0
  23. package/dist/analysis/repository-intelligence.d.ts.map +1 -0
  24. package/dist/analysis/repository-intelligence.js +179 -0
  25. package/dist/analysis/repository-intelligence.js.map +1 -0
  26. package/dist/core/config.d.ts +393 -0
  27. package/dist/core/config.d.ts.map +1 -0
  28. package/dist/core/config.js +130 -0
  29. package/dist/core/config.js.map +1 -0
  30. package/dist/core/engine.d.ts +20 -0
  31. package/dist/core/engine.d.ts.map +1 -0
  32. package/dist/core/engine.js +117 -0
  33. package/dist/core/engine.js.map +1 -0
  34. package/dist/core/errors.d.ts +27 -0
  35. package/dist/core/errors.d.ts.map +1 -0
  36. package/dist/core/errors.js +48 -0
  37. package/dist/core/errors.js.map +1 -0
  38. package/dist/core/index.d.ts +8 -0
  39. package/dist/core/index.d.ts.map +1 -0
  40. package/dist/core/index.js +8 -0
  41. package/dist/core/index.js.map +1 -0
  42. package/dist/core/models.d.ts +155 -0
  43. package/dist/core/models.d.ts.map +1 -0
  44. package/dist/core/models.js +6 -0
  45. package/dist/core/models.js.map +1 -0
  46. package/dist/git/index.d.ts +7 -0
  47. package/dist/git/index.d.ts.map +1 -0
  48. package/dist/git/index.js +6 -0
  49. package/dist/git/index.js.map +1 -0
  50. package/dist/git/repository.d.ts +44 -0
  51. package/dist/git/repository.d.ts.map +1 -0
  52. package/dist/git/repository.js +198 -0
  53. package/dist/git/repository.js.map +1 -0
  54. package/dist/graph/symbols.d.ts +45 -0
  55. package/dist/graph/symbols.d.ts.map +1 -0
  56. package/dist/graph/symbols.js +204 -0
  57. package/dist/graph/symbols.js.map +1 -0
  58. package/dist/integrations/claude/checkpoint.d.ts +2 -0
  59. package/dist/integrations/claude/checkpoint.d.ts.map +1 -0
  60. package/dist/integrations/claude/checkpoint.js +33 -0
  61. package/dist/integrations/claude/checkpoint.js.map +1 -0
  62. package/dist/integrations/cli/demo.d.ts +3 -0
  63. package/dist/integrations/cli/demo.d.ts.map +1 -0
  64. package/dist/integrations/cli/demo.js +31 -0
  65. package/dist/integrations/cli/demo.js.map +1 -0
  66. package/dist/integrations/cli/index.d.ts +7 -0
  67. package/dist/integrations/cli/index.d.ts.map +1 -0
  68. package/dist/integrations/cli/index.js +181 -0
  69. package/dist/integrations/cli/index.js.map +1 -0
  70. package/dist/integrations/mcp/index.d.ts +3 -0
  71. package/dist/integrations/mcp/index.d.ts.map +1 -0
  72. package/dist/integrations/mcp/index.js +7 -0
  73. package/dist/integrations/mcp/index.js.map +1 -0
  74. package/dist/integrations/mcp/server.d.ts +14 -0
  75. package/dist/integrations/mcp/server.d.ts.map +1 -0
  76. package/dist/integrations/mcp/server.js +232 -0
  77. package/dist/integrations/mcp/server.js.map +1 -0
  78. package/dist/project/detector.d.ts +70 -0
  79. package/dist/project/detector.d.ts.map +1 -0
  80. package/dist/project/detector.js +214 -0
  81. package/dist/project/detector.js.map +1 -0
  82. package/dist/report/json.d.ts +26 -0
  83. package/dist/report/json.d.ts.map +1 -0
  84. package/dist/report/json.js +148 -0
  85. package/dist/report/json.js.map +1 -0
  86. package/dist/review/red-ink-review.d.ts +26 -0
  87. package/dist/review/red-ink-review.d.ts.map +1 -0
  88. package/dist/review/red-ink-review.js +103 -0
  89. package/dist/review/red-ink-review.js.map +1 -0
  90. package/fixtures/retry-429/README.md +8 -0
  91. package/fixtures/retry-429/baseline/package.json +4 -0
  92. package/fixtures/retry-429/baseline/src/client.test.ts +8 -0
  93. package/fixtures/retry-429/baseline/src/client.ts +3 -0
  94. package/fixtures/retry-429/baseline/src/retry-policy.ts +1 -0
  95. package/fixtures/retry-429/baseline/tsconfig.json +7 -0
  96. package/fixtures/retry-429/candidate/src/client.ts +5 -0
  97. package/fixtures/retry-429/candidate/src/retry-strategy.ts +9 -0
  98. package/fixtures/retry-429/candidate/src/unrelated-format.ts +1 -0
  99. package/hooks/copilot-activate.js +9 -0
  100. package/hooks/copilot-hooks.json +13 -0
  101. package/hooks/hooks.json +13 -0
  102. package/package.json +70 -0
  103. package/scripts/run.cjs +32 -0
  104. package/skills/frankly/SKILL.md +12 -0
  105. package/src/analysis/change-classifier.ts +285 -0
  106. package/src/analysis/repository-intelligence.ts +236 -0
  107. package/src/core/config.ts +149 -0
  108. package/src/core/engine.ts +143 -0
  109. package/src/core/errors.ts +56 -0
  110. package/src/core/index.ts +8 -0
  111. package/src/core/models.ts +280 -0
  112. package/src/git/index.ts +7 -0
  113. package/src/git/repository.ts +207 -0
  114. package/src/graph/symbols.ts +254 -0
  115. package/src/integrations/claude/checkpoint.ts +40 -0
  116. package/src/integrations/cli/demo.ts +34 -0
  117. package/src/integrations/cli/index.ts +211 -0
  118. package/src/integrations/mcp/index.ts +7 -0
  119. package/src/integrations/mcp/server.ts +257 -0
  120. package/src/project/detector.ts +242 -0
  121. package/src/report/json.ts +175 -0
  122. package/src/review/red-ink-review.ts +125 -0
  123. package/src/tests/phase1.test.ts +57 -0
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Frankly CLI
4
+ * Command-line interface for Frankly analysis
5
+ */
6
+ import { createAnalysisEngine } from "../../core/engine.js";
7
+ import { createReportFormatter } from "../../report/json.js";
8
+ import { spawnSync } from "node:child_process";
9
+ import * as fs from "node:fs";
10
+ import * as path from "node:path";
11
+ async function main() {
12
+ const args = process.argv.slice(2);
13
+ if (args.length === 0 || args[0] === "help") {
14
+ printHelp();
15
+ return;
16
+ }
17
+ const command = args[0];
18
+ const cwd = process.cwd();
19
+ try {
20
+ switch (command) {
21
+ case "review": {
22
+ await handleReview(args.slice(1), cwd);
23
+ break;
24
+ }
25
+ case "plan": {
26
+ await handlePlan(args.slice(1), cwd);
27
+ break;
28
+ }
29
+ case "verify": {
30
+ await handleVerify(args.slice(1), cwd);
31
+ break;
32
+ }
33
+ case "mcp": {
34
+ const { startMcpServer } = await import("../mcp/server.js");
35
+ console.log("Starting MCP server...");
36
+ await startMcpServer(cwd);
37
+ break;
38
+ }
39
+ case "config": {
40
+ await handleConfig(args.slice(1), cwd);
41
+ break;
42
+ }
43
+ default:
44
+ console.error(`Unknown command: ${command}`);
45
+ printHelp();
46
+ process.exit(1);
47
+ }
48
+ }
49
+ catch (error) {
50
+ console.error("Error:", error instanceof Error ? error.message : String(error));
51
+ process.exit(1);
52
+ }
53
+ }
54
+ async function handleReview(args, cwd) {
55
+ let task = "Review current changes";
56
+ // Parse arguments
57
+ for (let i = 0; i < args.length; i++) {
58
+ if (args[i] === "--task" && args[i + 1]) {
59
+ task = args[++i];
60
+ }
61
+ }
62
+ const engine = await createAnalysisEngine(cwd);
63
+ const result = await engine.analyze(task, reviewOverrides(args), args.includes("--run-tests") ? runTests(cwd) : []);
64
+ const formatter = createReportFormatter();
65
+ console.log(args.includes("--json") ? formatter.formatAsJson(result) : args.includes("--markdown") ? formatter.formatAsMarkdown(result) : args.includes("--ci") ? formatter.formatAsCi(result) : formatter.formatAsTerminal(result));
66
+ if (args.includes("--ci") && result.review.verdict !== "CLEAN") {
67
+ process.exit(1);
68
+ }
69
+ }
70
+ async function handlePlan(args, cwd) {
71
+ let task = "Plan changes";
72
+ for (let i = 0; i < args.length; i++) {
73
+ if (args[i] === "--task" && args[i + 1]) {
74
+ task = args[++i];
75
+ }
76
+ }
77
+ const engine = await createAnalysisEngine(cwd);
78
+ const plan = await engine.plan(task);
79
+ console.log(`FRANKLY · PLAN
80
+
81
+ Task: ${task}
82
+ Normalized intent: ${plan.normalizedIntent}
83
+ Keywords: ${plan.keywords.join(", ") || "none"}
84
+ Estimated files: ${plan.estimatedFiles}
85
+ Likely touched areas: ${plan.likelyTouchedAreas.length > 0 ? plan.likelyTouchedAreas.join(", ") : "none"}
86
+ Reuse candidates: ${plan.reuseCandidates.join(", ") || "none"}
87
+ Confidence: ${plan.confidence}
88
+
89
+ Concerns:
90
+ ${plan.concerns.length > 0 ? plan.concerns.map((item) => `- ${item}`).join("\n") : "- none"}
91
+ `);
92
+ }
93
+ async function handleVerify(args, cwd) {
94
+ let task = "Verify changes";
95
+ for (let i = 0; i < args.length; i++) {
96
+ if (args[i] === "--task" && args[i + 1]) {
97
+ task = args[++i];
98
+ }
99
+ }
100
+ const engine = await createAnalysisEngine(cwd);
101
+ const result = await engine.analyze(task, reviewOverrides(args), args.includes("--run-tests") ? runTests(cwd) : []);
102
+ const formatter = createReportFormatter();
103
+ if (result.review.verdict === "CLEAN") {
104
+ console.log("✓ Verification passed");
105
+ console.log(formatter.formatAsSummary(result));
106
+ }
107
+ else {
108
+ console.log("✗ Verification failed");
109
+ console.log(formatter.formatAsTerminal(result));
110
+ process.exit(1);
111
+ }
112
+ }
113
+ function runTests(cwd) {
114
+ const command = fs.existsSync(path.join(cwd, "pnpm-lock.yaml")) ? "pnpm" : fs.existsSync(path.join(cwd, "yarn.lock")) ? "yarn" : "npm";
115
+ const args = ["test"];
116
+ const started = Date.now();
117
+ const result = spawnSync(command, args, { cwd, encoding: "utf8", stdio: "inherit" });
118
+ return [{ path: cwd, name: "project test command", status: result.status === 0 ? "PASSED" : "FAILED", duration: Date.now() - started }];
119
+ }
120
+ function reviewOverrides(args) {
121
+ const intensity = args[args.indexOf("--intensity") + 1];
122
+ const personality = args[args.indexOf("--personality") + 1];
123
+ return {
124
+ ...(args.includes("--intensity") && intensity ? { intensity } : {}),
125
+ ...(args.includes("--personality") && personality ? { personality } : {}),
126
+ };
127
+ }
128
+ async function handleConfig(args, cwd) {
129
+ if (args.length === 0 || args[0] === "show") {
130
+ console.log(`Frankly configuration for ${cwd}`);
131
+ console.log(`
132
+ Default configuration:
133
+ trigger: checkpoint
134
+ action: correct
135
+ intensity: full
136
+ personality: senior
137
+ maxCorrectionPasses: 1
138
+
139
+ Configuration file: frankly.config.json
140
+ `);
141
+ }
142
+ else {
143
+ console.error("Unknown config subcommand");
144
+ }
145
+ }
146
+ function printHelp() {
147
+ console.log(`
148
+ Frankly - Change Intelligence for AI Coding Agents
149
+
150
+ Usage:
151
+ frankly <command> [options]
152
+
153
+ Commands:
154
+ review Analyze current changes and produce Red Ink Review
155
+ plan Plan a change and estimate scope
156
+ verify Verify that a change is complete and correct
157
+ mcp Start MCP server for agent integration
158
+ config Show or manage configuration
159
+ help Show this help message
160
+
161
+ Options:
162
+ --task <text> Task description
163
+ --intensity <level> Analysis intensity: lite, full, ultra, off
164
+ --personality Review personality: conservative, senior, witty
165
+ --run-tests Execute the repository test script and record the result
166
+ --json|--markdown Select an output format
167
+ --ci Emit compact CI JSON and fail on non-clean verdict
168
+
169
+ Examples:
170
+ frankly review --task "Fix HTTP 429 retry"
171
+ frankly verify --task "Add retry logic"
172
+ frankly mcp
173
+
174
+ Documentation: https://github.com/amrishkhan05/frankly
175
+ `);
176
+ }
177
+ main().catch((error) => {
178
+ console.error("Fatal error:", error);
179
+ process.exit(1);
180
+ });
181
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/integrations/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/integrations/mcp/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { startMcpServer } from "./server.js";
3
+ startMcpServer().catch((error) => {
4
+ console.error("Frankly MCP server failed:", error);
5
+ process.exit(1);
6
+ });
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/integrations/mcp/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC/B,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * MCP (Model Context Protocol) Server
3
+ * Exposes Frankly analysis to coding agents
4
+ */
5
+ export declare class FranklyMcpServer {
6
+ private repositoryRoot;
7
+ private server;
8
+ constructor(repositoryRoot?: string);
9
+ private setupHandlers;
10
+ private handleToolCall;
11
+ start(): Promise<void>;
12
+ }
13
+ export declare function startMcpServer(repositoryRoot?: string): Promise<void>;
14
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/integrations/mcp/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuCH,qBAAa,gBAAgB;IAGb,OAAO,CAAC,cAAc;IAFpC,OAAO,CAAC,MAAM,CAAS;gBAED,cAAc,GAAE,MAAsB;IAS1D,OAAO,CAAC,aAAa;YAkIP,cAAc;IA8DtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B;AAED,wBAAsB,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E"}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * MCP (Model Context Protocol) Server
3
+ * Exposes Frankly analysis to coding agents
4
+ */
5
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
7
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
+ import { z } from "zod";
9
+ import { createAnalysisEngine } from "../../core/engine.js";
10
+ import { createReportFormatter } from "../../report/json.js";
11
+ const AnalyzeChangeSchema = z.object({
12
+ task: z.string().describe("The task or change description"),
13
+ repositoryRoot: z.string().optional().describe("Path to repository root"),
14
+ intensity: z.enum(["lite", "full", "ultra", "off"]).optional(),
15
+ personality: z.enum(["conservative", "senior", "witty"]).optional(),
16
+ executedTests: z.array(z.object({
17
+ path: z.string(),
18
+ name: z.string(),
19
+ status: z.enum(["PASSED", "FAILED", "SKIPPED", "NOT_RUN"]),
20
+ duration: z.number().optional(),
21
+ })).optional(),
22
+ });
23
+ const PlanChangeSchema = z.object({
24
+ task: z.string().describe("The planned task"),
25
+ repositoryRoot: z.string().optional().describe("Path to repository root"),
26
+ });
27
+ const VerifyChangeSchema = z.object({
28
+ task: z.string().describe("The task that was completed"),
29
+ repositoryRoot: z.string().optional().describe("Path to repository root"),
30
+ executedTests: AnalyzeChangeSchema.shape.executedTests,
31
+ });
32
+ const MinimizeChangeSchema = z.object({
33
+ task: z.string(),
34
+ repositoryRoot: z.string().optional(),
35
+ });
36
+ export class FranklyMcpServer {
37
+ constructor(repositoryRoot = process.cwd()) {
38
+ this.repositoryRoot = repositoryRoot;
39
+ this.server = new Server({ name: "frankly", version: "0.1.0" }, { capabilities: { tools: {} } });
40
+ this.setupHandlers();
41
+ }
42
+ setupHandlers() {
43
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
44
+ return {
45
+ tools: [
46
+ {
47
+ name: "analyze_change",
48
+ description: "Analyze a code change and provide Red Ink Review with findings and recommendations",
49
+ inputSchema: {
50
+ type: "object",
51
+ properties: {
52
+ task: {
53
+ type: "string",
54
+ description: "The task or change description",
55
+ },
56
+ repositoryRoot: {
57
+ type: "string",
58
+ description: "Path to repository root (optional, uses current working directory)",
59
+ },
60
+ intensity: {
61
+ type: "string",
62
+ enum: ["lite", "full", "ultra", "off"],
63
+ description: "Analysis intensity level",
64
+ },
65
+ personality: {
66
+ type: "string",
67
+ enum: ["conservative", "senior", "witty"],
68
+ description: "Review personality style",
69
+ },
70
+ executedTests: {
71
+ type: "array",
72
+ description: "Tests actually run by the caller; never use this for predictions",
73
+ items: {
74
+ type: "object",
75
+ properties: {
76
+ path: { type: "string" },
77
+ name: { type: "string" },
78
+ status: { type: "string", enum: ["PASSED", "FAILED", "SKIPPED", "NOT_RUN"] },
79
+ duration: { type: "number" },
80
+ },
81
+ required: ["path", "name", "status"],
82
+ },
83
+ },
84
+ },
85
+ required: ["task"],
86
+ },
87
+ },
88
+ {
89
+ name: "plan_change",
90
+ description: "Plan a change and get expected scope, budget, and potential issues before implementation",
91
+ inputSchema: {
92
+ type: "object",
93
+ properties: {
94
+ task: {
95
+ type: "string",
96
+ description: "The planned task",
97
+ },
98
+ repositoryRoot: {
99
+ type: "string",
100
+ description: "Path to repository root (optional)",
101
+ },
102
+ },
103
+ required: ["task"],
104
+ },
105
+ },
106
+ {
107
+ name: "minimize_change",
108
+ description: "Return one constrained correction pass backed by the current analysis",
109
+ inputSchema: {
110
+ type: "object",
111
+ properties: {
112
+ task: { type: "string", description: "The task or change description" },
113
+ repositoryRoot: { type: "string", description: "Path to repository root (optional)" },
114
+ },
115
+ required: ["task"],
116
+ },
117
+ },
118
+ {
119
+ name: "verify_change",
120
+ description: "Verify that a completed change correctly addresses the task with no excess modifications",
121
+ inputSchema: {
122
+ type: "object",
123
+ properties: {
124
+ task: {
125
+ type: "string",
126
+ description: "The task that was completed",
127
+ },
128
+ repositoryRoot: {
129
+ type: "string",
130
+ description: "Path to repository root (optional)",
131
+ },
132
+ },
133
+ required: ["task"],
134
+ },
135
+ },
136
+ ],
137
+ };
138
+ });
139
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
140
+ const { params } = request;
141
+ const name = params.name;
142
+ const args = params.arguments || {};
143
+ try {
144
+ const result = await this.handleToolCall(name, args);
145
+ return {
146
+ content: [
147
+ {
148
+ type: "text",
149
+ text: result,
150
+ },
151
+ ],
152
+ };
153
+ }
154
+ catch (error) {
155
+ return {
156
+ content: [
157
+ {
158
+ type: "text",
159
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`,
160
+ },
161
+ ],
162
+ isError: true,
163
+ };
164
+ }
165
+ });
166
+ }
167
+ async handleToolCall(name, args) {
168
+ switch (name) {
169
+ case "analyze_change": {
170
+ const parsed = AnalyzeChangeSchema.parse(args);
171
+ const repo = parsed.repositoryRoot || this.repositoryRoot;
172
+ const engine = await createAnalysisEngine(repo);
173
+ const configOverrides = {};
174
+ if (parsed.intensity)
175
+ configOverrides.intensity = parsed.intensity;
176
+ if (parsed.personality)
177
+ configOverrides.personality = parsed.personality;
178
+ const result = await engine.analyze(parsed.task, configOverrides, parsed.executedTests);
179
+ const formatter = createReportFormatter();
180
+ return formatter.formatAsTerminal(result);
181
+ }
182
+ case "plan_change": {
183
+ const parsed = PlanChangeSchema.parse(args);
184
+ const repo = parsed.repositoryRoot || this.repositoryRoot;
185
+ const engine = await createAnalysisEngine(repo);
186
+ const plan = await engine.plan(parsed.task);
187
+ return `FRANKLY · PLAN CHANGE
188
+
189
+ Task: ${parsed.task}
190
+ Normalized intent: ${plan.normalizedIntent}
191
+ Keywords: ${plan.keywords.join(", ") || "none"}
192
+ Estimated files: ${plan.estimatedFiles}
193
+ Likely touched areas: ${plan.likelyTouchedAreas.join(", ") || "none"}
194
+ Reuse candidates: ${plan.reuseCandidates.join(", ") || "none"}
195
+ Confidence: ${plan.confidence}
196
+
197
+ Concerns:
198
+ ${plan.concerns.length > 0 ? plan.concerns.map((item) => `- ${item}`).join("\n") : "- none"}`;
199
+ }
200
+ case "verify_change": {
201
+ const parsed = VerifyChangeSchema.parse(args);
202
+ const repo = parsed.repositoryRoot || this.repositoryRoot;
203
+ const engine = await createAnalysisEngine(repo);
204
+ const result = await engine.analyze(parsed.task, { action: "observe" }, parsed.executedTests);
205
+ if (result.review.verdict === "CLEAN") {
206
+ return "✓ Change verified successfully";
207
+ }
208
+ else {
209
+ return `⚠ Verification found issues:\n${result.review.recommendation}`;
210
+ }
211
+ }
212
+ case "minimize_change": {
213
+ const parsed = MinimizeChangeSchema.parse(args);
214
+ const engine = await createAnalysisEngine(parsed.repositoryRoot || this.repositoryRoot);
215
+ const result = await engine.analyze(parsed.task, { action: "correct" });
216
+ return result.review.correction?.instruction || "No correction pass is warranted by the current evidence.";
217
+ }
218
+ default:
219
+ throw new Error(`Unknown tool: ${name}`);
220
+ }
221
+ }
222
+ async start() {
223
+ const transport = new StdioServerTransport();
224
+ await this.server.connect(transport);
225
+ console.error("Frankly MCP Server started");
226
+ }
227
+ }
228
+ export async function startMcpServer(repositoryRoot) {
229
+ const server = new FranklyMcpServer(repositoryRoot);
230
+ await server.start();
231
+ }
232
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/integrations/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Project detection and analysis
3
+ * Identifies TypeScript/JavaScript projects, workspaces, and configuration
4
+ */
5
+ export type PackageManager = "npm" | "pnpm" | "yarn";
6
+ export interface Project {
7
+ root: string;
8
+ type: "typescript" | "javascript";
9
+ packageManager: PackageManager;
10
+ isWorkspace: boolean;
11
+ workspaceRoot?: string;
12
+ packages?: string[];
13
+ hasTsConfig: boolean;
14
+ testRunner?: "jest" | "vitest" | "nx";
15
+ }
16
+ export declare class ProjectDetector {
17
+ private rootPath;
18
+ private cache;
19
+ constructor(rootPath: string);
20
+ /**
21
+ * Detect project configuration
22
+ */
23
+ detectProject(): Promise<Project>;
24
+ /**
25
+ * Detect language type from tsconfig or file extensions
26
+ */
27
+ private detectLanguageType;
28
+ /**
29
+ * Check if tsconfig.json exists
30
+ */
31
+ private hasTsConfig;
32
+ /**
33
+ * Check for TypeScript files
34
+ */
35
+ private hasTypeScriptFiles;
36
+ /**
37
+ * Detect package manager from lock files
38
+ */
39
+ private detectPackageManager;
40
+ /**
41
+ * Check if project is a workspace
42
+ */
43
+ private isWorkspace;
44
+ /**
45
+ * Detect workspace packages
46
+ */
47
+ private detectWorkspacePackages;
48
+ /**
49
+ * Resolve glob pattern to actual directories
50
+ */
51
+ private resolveGlobPattern;
52
+ /**
53
+ * Detect test runner from package.json
54
+ */
55
+ private detectTestRunner;
56
+ /**
57
+ * Read package.json from directory
58
+ */
59
+ private readPackageJson;
60
+ /**
61
+ * Find package.json for a given file path
62
+ */
63
+ findPackageJsonForFile(filePath: string): string | null;
64
+ /**
65
+ * Read tsconfig.json
66
+ */
67
+ readTsConfig(dir?: string): Record<string, unknown> | null;
68
+ }
69
+ export declare function createProjectDetector(rootPath: string): Promise<ProjectDetector>;
70
+ //# sourceMappingURL=detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/project/detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,OAAO;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,GAAG,YAAY,CAAC;IAClC,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;CACzC;AAED,qBAAa,eAAe;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAmC;gBAEpC,QAAQ,EAAE,MAAM;IAI5B;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IA6BvC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAM5B;;OAEG;IACH,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAwB/B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkC1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACH,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAYvD;;OAEG;IACH,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAS5E;AAED,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAEtF"}