@akanjs/devkit 0.0.143 → 0.0.145
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.
- package/cjs/src/aiEditor.js +152 -16
- package/cjs/src/builder.js +1 -2
- package/cjs/src/commandDecorators/command.js +0 -1
- package/cjs/src/executors.js +151 -60
- package/cjs/src/guideline.js +15 -0
- package/cjs/src/index.js +5 -1
- package/cjs/src/linter.js +238 -0
- package/cjs/src/prompter.js +78 -0
- package/cjs/src/typeChecker.js +203 -0
- package/cjs/src/uploadRelease.js +59 -33
- package/esm/src/aiEditor.js +158 -17
- package/esm/src/builder.js +1 -2
- package/esm/src/commandDecorators/command.js +0 -1
- package/esm/src/executors.js +152 -61
- package/esm/src/guideline.js +0 -0
- package/esm/src/index.js +2 -0
- package/esm/src/linter.js +205 -0
- package/esm/src/prompter.js +45 -0
- package/esm/src/typeChecker.js +170 -0
- package/esm/src/uploadRelease.js +59 -33
- package/package.json +3 -1
- package/src/aiEditor.d.ts +23 -4
- package/src/executors.d.ts +63 -23
- package/src/guideline.d.ts +19 -0
- package/src/index.d.ts +2 -0
- package/src/linter.d.ts +109 -0
- package/src/prompter.d.ts +13 -0
- package/src/typeChecker.d.ts +49 -0
- package/src/types.d.ts +4 -0
- package/src/uploadRelease.d.ts +1 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { select } from "@inquirer/prompts";
|
|
2
|
+
import fsPromise from "fs/promises";
|
|
3
|
+
class Prompter {
|
|
4
|
+
static async selectGuideline() {
|
|
5
|
+
const guideNames = (await fsPromise.readdir(`${__dirname}/src/guidelines`)).filter((name) => !name.startsWith("_"));
|
|
6
|
+
return await select({ message: "Select a guideline", choices: guideNames.map((name) => ({ name, value: name })) });
|
|
7
|
+
}
|
|
8
|
+
static async getGuideJson(guideName) {
|
|
9
|
+
const filePath = `${__dirname}/src/guidelines/${guideName}/${guideName}.generate.json`;
|
|
10
|
+
const guideJson = await fsPromise.readFile(filePath, "utf-8");
|
|
11
|
+
return JSON.parse(guideJson);
|
|
12
|
+
}
|
|
13
|
+
static async getInstruction(guideName) {
|
|
14
|
+
const filePath = `${__dirname}/src/guidelines/${guideName}/${guideName}.instruction.md`;
|
|
15
|
+
const content = await fsPromise.readFile(filePath, "utf-8");
|
|
16
|
+
return content;
|
|
17
|
+
}
|
|
18
|
+
async makeTsFileUpdatePrompt({ context, request }) {
|
|
19
|
+
return `You are a senior developer writing TypeScript-based programs using Akan.js, an in-house framework. Here's an overview of the Akan.js framework:
|
|
20
|
+
${await this.getDocumentation("framework")}
|
|
21
|
+
Please understand the following background information, write code that meets the requirements, verify that it satisfies the validation conditions, and return the result.
|
|
22
|
+
|
|
23
|
+
# Background Information
|
|
24
|
+
\`\`\`markdown
|
|
25
|
+
${context}
|
|
26
|
+
\`\`\`
|
|
27
|
+
|
|
28
|
+
# Requirements
|
|
29
|
+
\`\`\`markdown
|
|
30
|
+
${request}
|
|
31
|
+
\`\`\`
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
async getDocumentation(guideName) {
|
|
35
|
+
const filePath = `${__dirname}/src/guidelines/${guideName}/${guideName}.instruction.md`;
|
|
36
|
+
const document = await fsPromise.readFile(filePath, "utf-8");
|
|
37
|
+
return `\`\`\`markdown
|
|
38
|
+
${document}
|
|
39
|
+
\`\`\`
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
Prompter
|
|
45
|
+
};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as ts from "typescript";
|
|
5
|
+
class TypeChecker {
|
|
6
|
+
configPath;
|
|
7
|
+
configFile;
|
|
8
|
+
config;
|
|
9
|
+
constructor(executor) {
|
|
10
|
+
const configPath = this.#findConfigFile(executor.cwdPath);
|
|
11
|
+
if (!configPath)
|
|
12
|
+
throw new Error("No tsconfig.json found in the project");
|
|
13
|
+
this.configPath = configPath;
|
|
14
|
+
this.configFile = ts.readConfigFile(this.configPath, (fileName) => ts.sys.readFile(fileName));
|
|
15
|
+
const parsedConfig = ts.parseJsonConfigFileContent(
|
|
16
|
+
this.configFile.config,
|
|
17
|
+
ts.sys,
|
|
18
|
+
path.dirname(this.configPath),
|
|
19
|
+
void 0,
|
|
20
|
+
this.configPath
|
|
21
|
+
);
|
|
22
|
+
if (parsedConfig.errors.length > 0) {
|
|
23
|
+
const errorMessages = parsedConfig.errors.map((error) => ts.flattenDiagnosticMessageText(error.messageText, "\n")).join("\n");
|
|
24
|
+
throw new Error(`Error parsing tsconfig.json:
|
|
25
|
+
${errorMessages}`);
|
|
26
|
+
}
|
|
27
|
+
this.config = parsedConfig;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Find tsconfig.json by walking up the directory tree
|
|
31
|
+
*/
|
|
32
|
+
#findConfigFile(searchPath) {
|
|
33
|
+
return ts.findConfigFile(searchPath, (fileName) => ts.sys.fileExists(fileName), "tsconfig.json");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Type-check a single TypeScript file
|
|
37
|
+
* @param filePath - Path to the TypeScript file to check
|
|
38
|
+
* @returns Array of diagnostic messages
|
|
39
|
+
*/
|
|
40
|
+
check(filePath) {
|
|
41
|
+
const program = ts.createProgram([filePath], this.config.options);
|
|
42
|
+
const diagnostics = [
|
|
43
|
+
...program.getSemanticDiagnostics(),
|
|
44
|
+
...program.getSyntacticDiagnostics(),
|
|
45
|
+
...program.getDeclarationDiagnostics()
|
|
46
|
+
];
|
|
47
|
+
const errors = diagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error);
|
|
48
|
+
const warnings = diagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Warning);
|
|
49
|
+
return { diagnostics, errors, warnings };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Format diagnostics for console output
|
|
53
|
+
* @param diagnostics - Array of TypeScript diagnostics
|
|
54
|
+
* @returns Formatted string
|
|
55
|
+
*/
|
|
56
|
+
formatDiagnostics(diagnostics) {
|
|
57
|
+
if (diagnostics.length === 0)
|
|
58
|
+
return chalk.bold("\u2705 No type errors found");
|
|
59
|
+
const output = [];
|
|
60
|
+
let errorCount = 0;
|
|
61
|
+
let warningCount = 0;
|
|
62
|
+
let suggestionCount = 0;
|
|
63
|
+
const diagnosticsByFile = /* @__PURE__ */ new Map();
|
|
64
|
+
diagnostics.forEach((diagnostic) => {
|
|
65
|
+
if (diagnostic.category === ts.DiagnosticCategory.Error)
|
|
66
|
+
errorCount++;
|
|
67
|
+
else if (diagnostic.category === ts.DiagnosticCategory.Warning)
|
|
68
|
+
warningCount++;
|
|
69
|
+
else if (diagnostic.category === ts.DiagnosticCategory.Suggestion)
|
|
70
|
+
suggestionCount++;
|
|
71
|
+
if (diagnostic.file) {
|
|
72
|
+
const fileName = diagnostic.file.fileName;
|
|
73
|
+
if (!diagnosticsByFile.has(fileName))
|
|
74
|
+
diagnosticsByFile.set(fileName, []);
|
|
75
|
+
const fileDiagnostics = diagnosticsByFile.get(fileName);
|
|
76
|
+
if (fileDiagnostics)
|
|
77
|
+
fileDiagnostics.push(diagnostic);
|
|
78
|
+
} else {
|
|
79
|
+
if (!diagnosticsByFile.has(""))
|
|
80
|
+
diagnosticsByFile.set("", []);
|
|
81
|
+
const fileDiagnostics = diagnosticsByFile.get("");
|
|
82
|
+
if (fileDiagnostics)
|
|
83
|
+
fileDiagnostics.push(diagnostic);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
diagnosticsByFile.forEach((fileDiagnostics, fileName) => {
|
|
87
|
+
if (fileName)
|
|
88
|
+
output.push(`
|
|
89
|
+
${chalk.cyan(fileName)}`);
|
|
90
|
+
fileDiagnostics.forEach((diagnostic) => {
|
|
91
|
+
const categoryText = diagnostic.category === ts.DiagnosticCategory.Error ? "error" : diagnostic.category === ts.DiagnosticCategory.Warning ? "warning" : "suggestion";
|
|
92
|
+
const categoryColor = diagnostic.category === ts.DiagnosticCategory.Error ? chalk.red : diagnostic.category === ts.DiagnosticCategory.Warning ? chalk.yellow : chalk.blue;
|
|
93
|
+
const icon = diagnostic.category === ts.DiagnosticCategory.Error ? "\u274C" : diagnostic.category === ts.DiagnosticCategory.Warning ? "\u26A0\uFE0F" : "\u{1F4A1}";
|
|
94
|
+
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
|
95
|
+
const tsCode = chalk.dim(`(TS${diagnostic.code})`);
|
|
96
|
+
if (diagnostic.file && diagnostic.start !== void 0) {
|
|
97
|
+
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
98
|
+
output.push(`
|
|
99
|
+
${icon} ${categoryColor(categoryText)}: ${message} ${tsCode}`);
|
|
100
|
+
output.push(` ${chalk.gray("at")} ${fileName}:${chalk.bold(`${line + 1}:${character + 1}`)}`);
|
|
101
|
+
const sourceLines = diagnostic.file.text.split("\n");
|
|
102
|
+
if (line < sourceLines.length) {
|
|
103
|
+
const sourceLine = sourceLines[line];
|
|
104
|
+
const lineNumber = (line + 1).toString().padStart(5, " ");
|
|
105
|
+
output.push(`
|
|
106
|
+
${chalk.dim(lineNumber + " |")} ${sourceLine}`);
|
|
107
|
+
const underlinePrefix = " ".repeat(character);
|
|
108
|
+
const length = diagnostic.length ?? 1;
|
|
109
|
+
const underline = "~".repeat(Math.max(1, length));
|
|
110
|
+
output.push(
|
|
111
|
+
`${chalk.dim(" ".repeat(lineNumber.length) + " |")} ${underlinePrefix}${categoryColor(underline)}`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
} else
|
|
115
|
+
output.push(`
|
|
116
|
+
${icon} ${categoryColor(categoryText)}: ${message} ${tsCode}`);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
const summary = [];
|
|
120
|
+
if (errorCount > 0)
|
|
121
|
+
summary.push(chalk.red(`${errorCount} error(s)`));
|
|
122
|
+
if (warningCount > 0)
|
|
123
|
+
summary.push(chalk.yellow(`${warningCount} warning(s)`));
|
|
124
|
+
if (suggestionCount > 0)
|
|
125
|
+
summary.push(chalk.blue(`${suggestionCount} suggestion(s)`));
|
|
126
|
+
return `
|
|
127
|
+
${summary.join(", ")} found` + output.join("\n");
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get detailed diagnostic information with code snippet
|
|
131
|
+
* @param filePath - Path to the TypeScript file to check
|
|
132
|
+
* @returns Object containing diagnostics and detailed information
|
|
133
|
+
*/
|
|
134
|
+
getDetailedDiagnostics(filePath) {
|
|
135
|
+
const { diagnostics } = this.check(filePath);
|
|
136
|
+
const sourceFile = ts.createSourceFile(filePath, fs.readFileSync(filePath, "utf8"), ts.ScriptTarget.Latest, true);
|
|
137
|
+
const details = diagnostics.map((diagnostic) => {
|
|
138
|
+
if (diagnostic.file && diagnostic.start !== void 0) {
|
|
139
|
+
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
140
|
+
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
|
141
|
+
const lines = sourceFile.text.split("\n");
|
|
142
|
+
const codeSnippet = line < lines.length ? lines[line] : void 0;
|
|
143
|
+
return { line: line + 1, column: character + 1, message, code: diagnostic.code, codeSnippet };
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
line: 0,
|
|
147
|
+
column: 0,
|
|
148
|
+
message: ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"),
|
|
149
|
+
code: diagnostic.code
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
return { diagnostics, details };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Check if a file has type errors
|
|
156
|
+
* @param filePath - Path to the TypeScript file to check
|
|
157
|
+
* @returns true if there are no type errors, false otherwise
|
|
158
|
+
*/
|
|
159
|
+
hasNoTypeErrors(filePath) {
|
|
160
|
+
try {
|
|
161
|
+
const { diagnostics } = this.check(filePath);
|
|
162
|
+
return diagnostics.length === 0;
|
|
163
|
+
} catch (error) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export {
|
|
169
|
+
TypeChecker
|
|
170
|
+
};
|
package/esm/src/uploadRelease.js
CHANGED
|
@@ -1,49 +1,75 @@
|
|
|
1
|
+
import { Logger } from "@akanjs/common";
|
|
1
2
|
import axios from "axios";
|
|
2
3
|
import FormData from "form-data";
|
|
3
4
|
import fs from "fs";
|
|
4
|
-
|
|
5
|
+
import { Spinner } from "./spinner";
|
|
6
|
+
const spinning = (message) => {
|
|
7
|
+
const spinner = new Spinner(message, { prefix: message, enableSpin: true }).start();
|
|
8
|
+
return spinner;
|
|
9
|
+
};
|
|
10
|
+
const uploadRelease = async (appName, {
|
|
5
11
|
workspaceRoot,
|
|
6
12
|
environment,
|
|
7
13
|
buildNum,
|
|
8
14
|
platformVersion,
|
|
9
15
|
local
|
|
10
16
|
}) => {
|
|
17
|
+
const logger = new Logger("uploadRelease");
|
|
11
18
|
const basePath = local ? "http://localhost:8080/backend" : "https://akasys.akamir.com/backend";
|
|
12
|
-
const buildPath = `${workspaceRoot}/releases/builds/${
|
|
13
|
-
const appBuildPath = `${workspaceRoot}/releases/builds/${
|
|
14
|
-
const sourcePath = `${workspaceRoot}/releases/sources/${
|
|
15
|
-
const
|
|
16
|
-
const build = fs.readFileSync(buildPath);
|
|
17
|
-
const source = fs.readFileSync(sourcePath);
|
|
18
|
-
const appBuild = fs.readFileSync(appBuildPath);
|
|
19
|
-
const buildStat = fs.statSync(buildPath);
|
|
20
|
-
const sourceStat = fs.statSync(sourcePath);
|
|
21
|
-
const appBuildStat = fs.statSync(appBuildPath);
|
|
22
|
-
formData.append("files", build, `${projectName}-release.tar.gz`);
|
|
23
|
-
formData.append("files", source, `${projectName}-source.tar.gz`);
|
|
24
|
-
formData.append("files", appBuild, `${projectName}-appBuild.zip`);
|
|
25
|
-
formData.append(
|
|
26
|
-
"metas",
|
|
27
|
-
JSON.stringify([
|
|
28
|
-
{ lastModifiedAt: buildStat.mtime, size: buildStat.size },
|
|
29
|
-
{ lastModifiedAt: sourceStat.mtime, size: sourceStat.size },
|
|
30
|
-
{ lastModifiedAt: appBuildStat.mtime, size: appBuildStat.size }
|
|
31
|
-
])
|
|
32
|
-
);
|
|
33
|
-
formData.append("type", "release");
|
|
19
|
+
const buildPath = `${workspaceRoot}/releases/builds/${appName}-release.tar.gz`;
|
|
20
|
+
const appBuildPath = `${workspaceRoot}/releases/builds/${appName}-appBuild.zip`;
|
|
21
|
+
const sourcePath = `${workspaceRoot}/releases/sources/${appName}-source.tar.gz`;
|
|
22
|
+
const readingFilesSpinner = spinning("Reading files...");
|
|
34
23
|
try {
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
24
|
+
const build = fs.readFileSync(buildPath);
|
|
25
|
+
const source = fs.readFileSync(sourcePath);
|
|
26
|
+
const appBuild = fs.readFileSync(appBuildPath);
|
|
27
|
+
const buildStat = fs.statSync(buildPath);
|
|
28
|
+
const sourceStat = fs.statSync(sourcePath);
|
|
29
|
+
const appBuildStat = fs.statSync(appBuildPath);
|
|
30
|
+
readingFilesSpinner.succeed("Reading files... done");
|
|
31
|
+
const preparingFormSpinner = spinning("Preparing form data...");
|
|
32
|
+
const formData = new FormData();
|
|
33
|
+
formData.append("files", build, `${appName}-release.tar.gz`);
|
|
34
|
+
formData.append("files", source, `${appName}-source.tar.gz`);
|
|
35
|
+
formData.append("files", appBuild, `${appName}-appBuild.zip`);
|
|
36
|
+
formData.append(
|
|
37
|
+
"metas",
|
|
38
|
+
JSON.stringify([
|
|
39
|
+
{ lastModifiedAt: buildStat.mtime, size: buildStat.size },
|
|
40
|
+
{ lastModifiedAt: sourceStat.mtime, size: sourceStat.size },
|
|
41
|
+
{ lastModifiedAt: appBuildStat.mtime, size: appBuildStat.size }
|
|
42
|
+
])
|
|
41
43
|
);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
formData.append("type", "release");
|
|
45
|
+
preparingFormSpinner.succeed("Preparing form data... done");
|
|
46
|
+
try {
|
|
47
|
+
const uploadingFilesSpinner = spinning("Uploading files to server...");
|
|
48
|
+
const [buildFile, sourceFile, appBuildFile] = (await axios.post(`${basePath}/file/addFilesRestApi`, formData)).data;
|
|
49
|
+
uploadingFilesSpinner.succeed("Uploading files to server... done");
|
|
50
|
+
const fetchingAppSpinner = spinning(`Fetching dev app information for ${appName}...`);
|
|
51
|
+
const major = platformVersion ? parseInt(platformVersion.split(".")[0]) : 1;
|
|
52
|
+
const minor = platformVersion ? parseInt(platformVersion.split(".")[1]) : 0;
|
|
53
|
+
const patch = platformVersion ? parseInt(platformVersion.split(".")[2]) : 0;
|
|
54
|
+
const devApp = (await axios.get(`${basePath}/devApp/devAppInName/${appName}`)).data;
|
|
55
|
+
fetchingAppSpinner.succeed(`Fetching dev app information for ${appName}... done`);
|
|
56
|
+
const pushingReleaseSpinner = spinning(`Pushing release to ${environment} environment...`);
|
|
57
|
+
const release = (await axios.post(
|
|
58
|
+
`${basePath}/release/pushRelease/${devApp.id}/${environment}/${major}/${minor}/${sourceFile.id}/${buildFile.id}/${appBuildFile.id}`
|
|
59
|
+
)).data;
|
|
60
|
+
pushingReleaseSpinner.succeed(`Pushing release to ${environment} environment... done`);
|
|
61
|
+
new Spinner(`Successfully pushed release to ${appName}-${environment} server. `, {
|
|
62
|
+
prefix: `Successfully pushed release to ${appName}-${environment} server. `,
|
|
63
|
+
enableSpin: false
|
|
64
|
+
}).succeed(`Successfully pushed release to ${appName}-${environment} server. `);
|
|
65
|
+
return release;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
const errorMessage = e instanceof Error ? e.message : "Unknown error";
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
46
70
|
} catch (e) {
|
|
71
|
+
const errorMessage = e instanceof Error ? e.message : "Unknown error";
|
|
72
|
+
readingFilesSpinner.fail(`Reading files failed: ${errorMessage}`);
|
|
47
73
|
return null;
|
|
48
74
|
}
|
|
49
75
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/devkit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.145",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@inquirer/prompts": "^7.2.1",
|
|
19
19
|
"@langchain/core": "^0.3.56",
|
|
20
|
+
"@langchain/deepseek": "^0.0.1",
|
|
20
21
|
"@langchain/openai": "^0.5.10",
|
|
21
22
|
"@trapezedev/project": "^7.1.3",
|
|
22
23
|
"axios": "^1.7.9",
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
"dotenv": "^16.4.7",
|
|
26
27
|
"esbuild": "^0.19.2",
|
|
27
28
|
"esbuild-plugin-d.ts": "^1.3.1",
|
|
29
|
+
"eslint": "^9.19.0",
|
|
28
30
|
"form-data": "^4.0.1",
|
|
29
31
|
"js-yaml": "^4.1.0",
|
|
30
32
|
"ora": "^3.4.0",
|
package/src/aiEditor.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { BaseMessage } from "@langchain/core/messages";
|
|
2
|
+
import type { Executor, WorkspaceExecutor } from "./executors";
|
|
3
|
+
import type { FileContent } from "./types";
|
|
2
4
|
export declare const supportedLlmModels: readonly ["deepseek-chat", "deepseek-reasoner"];
|
|
3
5
|
export type SupportedLlmModel = (typeof supportedLlmModels)[number];
|
|
4
6
|
interface EditOptions {
|
|
7
|
+
onReasoning?: (reasoning: string) => void;
|
|
5
8
|
onChunk?: (chunk: string) => void;
|
|
6
9
|
maxTry?: number;
|
|
10
|
+
validate?: string[];
|
|
11
|
+
approve?: boolean;
|
|
7
12
|
}
|
|
8
13
|
export declare class AiSession {
|
|
9
14
|
#private;
|
|
@@ -19,13 +24,27 @@ export declare class AiSession {
|
|
|
19
24
|
model: SupportedLlmModel;
|
|
20
25
|
apiKey: string;
|
|
21
26
|
} | null): typeof AiSession;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
static clearCache(workspaceRoot: string): void;
|
|
28
|
+
messageHistory: BaseMessage[];
|
|
29
|
+
readonly sessionKey: string;
|
|
30
|
+
isCacheLoaded: boolean;
|
|
31
|
+
workspace: WorkspaceExecutor;
|
|
32
|
+
constructor(type: string, { workspace, cacheKey, isContinued }: {
|
|
33
|
+
workspace: WorkspaceExecutor;
|
|
34
|
+
cacheKey?: string;
|
|
35
|
+
isContinued?: boolean;
|
|
36
|
+
});
|
|
37
|
+
ask(question: string, { onReasoning, onChunk, }?: EditOptions): Promise<{
|
|
25
38
|
content: string;
|
|
26
39
|
messageHistory: BaseMessage[];
|
|
27
40
|
}>;
|
|
28
|
-
edit(question: string, { onChunk, maxTry }?: EditOptions): Promise<string>;
|
|
41
|
+
edit(question: string, { onChunk, onReasoning, maxTry, validate, approve }?: EditOptions): Promise<string>;
|
|
29
42
|
editTypescript(question: string, options?: EditOptions): Promise<string>;
|
|
43
|
+
addToolMessgaes(messages: {
|
|
44
|
+
type: string;
|
|
45
|
+
content: string;
|
|
46
|
+
}[]): this;
|
|
47
|
+
writeTypescripts(question: string, executor: Executor, options?: EditOptions): Promise<FileContent[]>;
|
|
48
|
+
editMarkdown(request: string, options?: EditOptions): Promise<string>;
|
|
30
49
|
}
|
|
31
50
|
export {};
|
package/src/executors.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Logger } from "@akanjs/common";
|
|
2
2
|
import { type AppConfigResult, AppScanResult, type LibConfigResult, LibScanResult, PkgScanResult, WorkspaceScanResult } from "@akanjs/config";
|
|
3
3
|
import { type ExecOptions, type ForkOptions, type SpawnOptions } from "child_process";
|
|
4
|
+
import { Linter } from "./linter";
|
|
4
5
|
import { Spinner } from "./spinner";
|
|
5
|
-
import
|
|
6
|
+
import { TypeChecker } from "./typeChecker";
|
|
7
|
+
import type { FileContent, PackageJson, TsConfigJson } from "./types";
|
|
6
8
|
export declare const execEmoji: {
|
|
7
9
|
workspace: string;
|
|
8
10
|
app: string;
|
|
@@ -20,23 +22,24 @@ export declare class Executor {
|
|
|
20
22
|
logger: Logger;
|
|
21
23
|
cwdPath: string;
|
|
22
24
|
emoji: string;
|
|
25
|
+
typeChecker: TypeChecker | null;
|
|
26
|
+
linter: Linter | null;
|
|
23
27
|
constructor(name: string, cwdPath: string);
|
|
24
28
|
exec(command: string, options?: ExecOptions): Promise<unknown>;
|
|
25
|
-
spawn(command: string, args?: string[], options?: SpawnOptions): Promise<
|
|
26
|
-
code: number | null;
|
|
27
|
-
signal: string | null;
|
|
28
|
-
}>;
|
|
29
|
+
spawn(command: string, args?: string[], options?: SpawnOptions): Promise<string>;
|
|
29
30
|
fork(modulePath: string, args?: string[], options?: ForkOptions): Promise<unknown>;
|
|
31
|
+
getPath(filePath: string): string;
|
|
30
32
|
mkdir(dirPath: string): this;
|
|
33
|
+
readdir(dirPath: string): Promise<string[]>;
|
|
31
34
|
exists(filePath: string): boolean;
|
|
32
35
|
remove(filePath: string): this;
|
|
33
36
|
removeDir(dirPath: string): this;
|
|
34
37
|
writeFile(filePath: string, content: string | object, { overwrite }?: {
|
|
35
38
|
overwrite?: boolean;
|
|
36
|
-
}):
|
|
39
|
+
}): FileContent;
|
|
37
40
|
writeJson(filePath: string, content: object): this;
|
|
38
|
-
getLocalFile(
|
|
39
|
-
|
|
41
|
+
getLocalFile(targetPath: string): {
|
|
42
|
+
filePath: string;
|
|
40
43
|
content: string;
|
|
41
44
|
};
|
|
42
45
|
readFile(filePath: string): string;
|
|
@@ -50,7 +53,7 @@ export declare class Executor {
|
|
|
50
53
|
enableSpin?: boolean | undefined;
|
|
51
54
|
}): Spinner;
|
|
52
55
|
getTsConfig(pathname?: string): TsConfigJson;
|
|
53
|
-
|
|
56
|
+
_applyTemplate({ basePath, template, scanResult, dict, overwrite, }: {
|
|
54
57
|
basePath: string;
|
|
55
58
|
template: string;
|
|
56
59
|
scanResult?: AppScanResult | LibScanResult | null;
|
|
@@ -58,7 +61,32 @@ export declare class Executor {
|
|
|
58
61
|
[key: string]: string;
|
|
59
62
|
};
|
|
60
63
|
overwrite?: boolean;
|
|
61
|
-
}): Promise<
|
|
64
|
+
}): Promise<FileContent[]>;
|
|
65
|
+
applyTemplate(options: {
|
|
66
|
+
basePath: string;
|
|
67
|
+
template: string;
|
|
68
|
+
dict?: {
|
|
69
|
+
[key: string]: string;
|
|
70
|
+
};
|
|
71
|
+
overwrite?: boolean;
|
|
72
|
+
}): Promise<FileContent[]>;
|
|
73
|
+
getTypeChecker(): TypeChecker;
|
|
74
|
+
typeCheck(filePath: string): {
|
|
75
|
+
diagnostics: import("typescript").Diagnostic[];
|
|
76
|
+
errors: import("typescript").Diagnostic[];
|
|
77
|
+
warnings: import("typescript").Diagnostic[];
|
|
78
|
+
message: string;
|
|
79
|
+
};
|
|
80
|
+
getLinter(): Linter;
|
|
81
|
+
lint(filePath: string, { fix, dryRun }?: {
|
|
82
|
+
fix?: boolean;
|
|
83
|
+
dryRun?: boolean;
|
|
84
|
+
}): Promise<{
|
|
85
|
+
results: import("eslint").ESLint.LintResult[];
|
|
86
|
+
message: string;
|
|
87
|
+
errors: import("eslint").Linter.LintMessage[];
|
|
88
|
+
warnings: import("eslint").Linter.LintMessage[];
|
|
89
|
+
}>;
|
|
62
90
|
}
|
|
63
91
|
interface ExecutorOptions {
|
|
64
92
|
workspaceRoot: string;
|
|
@@ -91,19 +119,19 @@ export declare class WorkspaceExecutor extends Executor {
|
|
|
91
119
|
add?: boolean;
|
|
92
120
|
}): Promise<void>;
|
|
93
121
|
getScalarConstantFiles(): Promise<{
|
|
94
|
-
|
|
122
|
+
filePath: string;
|
|
95
123
|
content: string;
|
|
96
124
|
}[]>;
|
|
97
125
|
getConstantFiles(): Promise<{
|
|
98
|
-
|
|
126
|
+
filePath: string;
|
|
99
127
|
content: string;
|
|
100
128
|
}[]>;
|
|
101
129
|
getDictionaryFiles(): Promise<{
|
|
102
|
-
|
|
130
|
+
filePath: string;
|
|
103
131
|
content: string;
|
|
104
132
|
}[]>;
|
|
105
133
|
getViewFiles(): Promise<{
|
|
106
|
-
|
|
134
|
+
filePath: string;
|
|
107
135
|
content: string;
|
|
108
136
|
}[]>;
|
|
109
137
|
}
|
|
@@ -126,8 +154,8 @@ export declare class SysExecutor extends Executor {
|
|
|
126
154
|
}, libScanResults?: {
|
|
127
155
|
[key: string]: LibScanResult;
|
|
128
156
|
}): Promise<AppScanResult | LibScanResult>;
|
|
129
|
-
getLocalFile(
|
|
130
|
-
|
|
157
|
+
getLocalFile(targetPath: string): {
|
|
158
|
+
filePath: string;
|
|
131
159
|
content: string;
|
|
132
160
|
};
|
|
133
161
|
getDatabaseModules(): Promise<string[]>;
|
|
@@ -137,33 +165,45 @@ export declare class SysExecutor extends Executor {
|
|
|
137
165
|
getUnitComponents(): Promise<string[]>;
|
|
138
166
|
getTemplateComponents(): Promise<string[]>;
|
|
139
167
|
getViewsSourceCode(): Promise<{
|
|
140
|
-
|
|
168
|
+
filePath: string;
|
|
141
169
|
content: string;
|
|
142
170
|
}[]>;
|
|
143
171
|
getUnitsSourceCode(): Promise<{
|
|
144
|
-
|
|
172
|
+
filePath: string;
|
|
145
173
|
content: string;
|
|
146
174
|
}[]>;
|
|
147
175
|
getTemplatesSourceCode(): Promise<{
|
|
148
|
-
|
|
176
|
+
filePath: string;
|
|
149
177
|
content: string;
|
|
150
178
|
}[]>;
|
|
151
179
|
getScalarConstantFiles(): Promise<{
|
|
152
|
-
|
|
180
|
+
filePath: string;
|
|
153
181
|
content: string;
|
|
154
182
|
}[]>;
|
|
155
183
|
getScalarDictionaryFiles(): Promise<{
|
|
156
|
-
|
|
184
|
+
filePath: string;
|
|
157
185
|
content: string;
|
|
158
186
|
}[]>;
|
|
159
187
|
getConstantFiles(): Promise<{
|
|
160
|
-
|
|
188
|
+
filePath: string;
|
|
189
|
+
content: string;
|
|
190
|
+
}[]>;
|
|
191
|
+
getConstantFilesWithLibs(): Promise<{
|
|
192
|
+
filePath: string;
|
|
161
193
|
content: string;
|
|
162
194
|
}[]>;
|
|
163
195
|
getDictionaryFiles(): Promise<{
|
|
164
|
-
|
|
196
|
+
filePath: string;
|
|
165
197
|
content: string;
|
|
166
198
|
}[]>;
|
|
199
|
+
applyTemplate(options: {
|
|
200
|
+
basePath: string;
|
|
201
|
+
template: string;
|
|
202
|
+
dict?: {
|
|
203
|
+
[key: string]: string;
|
|
204
|
+
};
|
|
205
|
+
overwrite?: boolean;
|
|
206
|
+
}): Promise<FileContent[]>;
|
|
167
207
|
setTsPaths(): this;
|
|
168
208
|
}
|
|
169
209
|
interface AppExecutorOptions {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface GuideScan {
|
|
2
|
+
type: "example" | "source" | "usage" | (string & {});
|
|
3
|
+
description: string;
|
|
4
|
+
path: string;
|
|
5
|
+
filterText?: string;
|
|
6
|
+
sample?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface GuideUpdate {
|
|
9
|
+
filePath: string;
|
|
10
|
+
contents: string[];
|
|
11
|
+
rules: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface GuideGenerateJson {
|
|
14
|
+
title: string;
|
|
15
|
+
description: string;
|
|
16
|
+
scans: GuideScan[];
|
|
17
|
+
update: GuideUpdate;
|
|
18
|
+
page: string;
|
|
19
|
+
}
|