Skip to content

chore: add more git commands #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a4c673a
chore: add more git commands
ChiragAgg5k Apr 2, 2025
4d951df
fix: error trying to look for eslintrc
ChiragAgg5k Apr 2, 2025
8bdb7d1
fix: type errors
ChiragAgg5k Apr 2, 2025
336be7d
chore: standardize return format
ChiragAgg5k Apr 2, 2025
a36d4a5
chore: improve git service
ChiragAgg5k Apr 2, 2025
166251d
chore: standardize output
ChiragAgg5k Apr 3, 2025
b01f389
chore: improve error handling for terminal
ChiragAgg5k Apr 3, 2025
8bde53e
fix: error handling
ChiragAgg5k Apr 3, 2025
aeaa3c3
chore: update on data callback for termina;
ChiragAgg5k Apr 3, 2025
b2002bb
chore: add username and email commands to git
ChiragAgg5k Apr 3, 2025
724f364
chore: add different work dir
ChiragAgg5k Apr 3, 2025
77645fa
chore: add working dir to filesystem
ChiragAgg5k Apr 3, 2025
bb480ed
chore: improve logging for terminal error
ChiragAgg5k Apr 3, 2025
1d8afd4
chore: add more error logging
ChiragAgg5k Apr 3, 2025
ba0ebed
chore: add cleanup for ANSI characters
ChiragAgg5k Apr 3, 2025
77e0e0c
chore: handle not send last message
ChiragAgg5k Apr 3, 2025
db4fc6a
chore: link message ids
ChiragAgg5k Apr 3, 2025
f40bf4b
chore: add success callback
ChiragAgg5k Apr 3, 2025
47b0fc3
chore: fix tests
ChiragAgg5k Apr 3, 2025
f755f70
fix: test
ChiragAgg5k Apr 3, 2025
8d5e239
refactor: reduce tests
ChiragAgg5k Apr 3, 2025
67020f6
chore: update class name from codestyle to code
ChiragAgg5k Apr 3, 2025
a5e6f67
chore: fix createCommand
ChiragAgg5k Apr 3, 2025
8a4be7f
chore: remove sending of command in terminal response
ChiragAgg5k Apr 3, 2025
17de6d1
chore: return ansii as well
ChiragAgg5k Apr 3, 2025
1f3c10b
chore: add one central working dir
ChiragAgg5k Apr 3, 2025
1d3a4c1
fix: changes
ChiragAgg5k Apr 3, 2025
84519e3
chore: remove last data hiding logic
ChiragAgg5k Apr 3, 2025
9cb9aae
chore: initialized micro server inside synapse
ChiragAgg5k Apr 4, 2025
977cc4c
chore: add http server handler
ChiragAgg5k Apr 4, 2025
4d60a07
Revert "chore: add http server handler"
ChiragAgg5k Apr 4, 2025
dfd15b9
chore: add workdir creation if not exists
ChiragAgg5k Apr 5, 2025
2bbe0c1
chore: adjust code
ChiragAgg5k Apr 7, 2025
b8b9b11
chore: remove HTTP server logic
ChiragAgg5k Apr 7, 2025
068801d
chore: add back ping pong
ChiragAgg5k Apr 7, 2025
b10c041
chore: added synapse.workDir to git service
ChiragAgg5k Apr 7, 2025
4b85fcc
chore: update dependencies
ChiragAgg5k Apr 7, 2025
de90378
chore: better error catching for filesystem service
ChiragAgg5k Apr 10, 2025
7e1eef0
chore: add logic to update workdir correctly
ChiragAgg5k Apr 10, 2025
f6b7c30
log full path for debugging
ChiragAgg5k Apr 10, 2025
1f92cd5
chore: fix lint issues
ChiragAgg5k Apr 14, 2025
b7fe28b
chore: remove type module
ChiragAgg5k Apr 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Synapse

Operating system gateway for remote serverless environments. Synapse provides a WebSocket-based interface to interact with terminal sessions, manage files, and monitor system resources remotely.
Operating system gateway for remote serverless environments. Synapse provides a WebSocket-based interface to interact with terminal sessions, manage files, monitor system resources, perform Git operations, and more.

## Features

Expand Down Expand Up @@ -137,17 +137,17 @@ await git.push();

```typescript
// Lint and format code
import { Synapse, CodeStyle } from "@appwrite.io/synapse";
import { Synapse, Code } from "@appwrite.io/synapse";

const synapse = new Synapse();
const codeStyle = new CodeStyle(synapse);
const code = new Code(synapse);

// Format code with specific options
const code = `function hello(name) {
return "Hello, " + name;
}`;

const formatResult = await codeStyle.format(code, {
const formatResult = await code.format(code, {
language: "javascript",
indent: 2,
singleQuote: true,
Expand All @@ -157,7 +157,7 @@ const formatResult = await codeStyle.format(code, {
console.log("Formatted code:", formatResult.data);

// Lint code for potential issues
const lintResult = await codeStyle.lint(code, {
const lintResult = await code.lint(code, {
language: "javascript",
rules: {
semi: "error",
Expand Down
22 changes: 12 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@appwrite.io/synapse",
"version": "0.2.0",
"version": "0.3.0",
"description": "Operating system gateway for remote serverless environments",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand All @@ -22,23 +22,25 @@
},
"license": "MIT",
"dependencies": {
"eslint": "^9.24.0",
"node-pty": "^1.0.0",
"ws": "^8.18.1",
"eslint": "^9.23.0",
"prettier": "^3.5.3"
"prettier": "^3.5.3",
"ws": "^8.18.1"
},
"devDependencies": {
"@types/jest": "^29.5.14",
"@types/node": "^22.13.13",
"@types/ws": "^8.18.0",
"@typescript-eslint/eslint-plugin": "^8.28.0",
"@typescript-eslint/parser": "^8.28.0",
"@types/node": "^22.14.1",
"@types/node-fetch": "^2.6.12",
"@types/ws": "^8.18.1",
"@typescript-eslint/eslint-plugin": "^8.29.1",
"@typescript-eslint/parser": "^8.29.1",
"esbuild": "^0.25.2",
"esbuild-plugin-file-path-extensions": "^2.1.4",
"jest": "^29.7.0",
"ts-jest": "^29.3.0",
"node-fetch": "^3.3.2",
"ts-jest": "^29.3.2",
"tsup": "^8.4.0",
"typescript": "^5.8.2"
"typescript": "^5.8.3"
},
"bugs": {
"url": "https://github.com/appwrite/synapse/issues"
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { CodeStyle } from "./services/codestyle";
export { Code } from "./services/code";
export { Filesystem } from "./services/filesystem";
export { Git } from "./services/git";
export { System } from "./services/system";
Expand Down
189 changes: 189 additions & 0 deletions src/services/code.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import { ESLint } from "eslint";
import { format, Options } from "prettier";
import { Synapse } from "../synapse";

export interface FormatOptions {
language: string;
indent?: number;
useTabs?: boolean;
semi?: boolean;
singleQuote?: boolean;
printWidth?: number;
}

export interface LintOptions {
language: string;
rules?: Record<string, "error" | "warn" | "off">;
}

export interface FormatResult {
success: boolean;
data?: string;
error?: string;
}

export interface LintResult {
success: boolean;
data?: {
issues: Array<{
line: number;
column: number;
severity: "error" | "warning";
rule: string;
message: string;
}>;
};
error?: string;
}

export class Code {
private synapse: Synapse;

/**
* Creates a new CodeStyle instance
* @param synapse The Synapse instance for WebSocket communication
*/
constructor(synapse: Synapse) {
this.synapse = synapse;
}

private log(message: string): void {
const timestamp = new Date().toISOString();
console.log(`[Code][${timestamp}] ${message}`);
}

private getParserForLanguage(language: string): string {
const languageMap: Record<string, string> = {
javascript: "babel",
typescript: "typescript",
json: "json",
html: "html",
css: "css",
markdown: "markdown",
yaml: "yaml",
};

return languageMap[language.toLowerCase()] || "babel";
}

private toPrettierOptions(
language: string,
options?: FormatOptions,
): Options {
const parser = this.getParserForLanguage(language);

return {
parser,
tabWidth: options?.indent || 2,
useTabs: options?.useTabs || false,
semi: options?.semi !== undefined ? options.semi : true,
singleQuote: options?.singleQuote || false,
printWidth: options?.printWidth || 80,
};
}

/**
* Format code according to specified options
* @param code The code to format
* @param options Formatting options
* @returns A promise resolving to the formatting result
*/
async format(code: string, options: FormatOptions): Promise<FormatResult> {
try {
if (!code || typeof code !== "string") {
return {
success: false,
error: "Invalid code input: code must be a non-empty string",
};
}

if (!options.language) {
return {
success: false,
error: "Language must be specified in format options",
};
}

this.log(`Formatting code with language: ${options.language}`);

const prettierOptions = this.toPrettierOptions(options.language, options);
const formattedCode = await format(code, prettierOptions);

return {
success: true,
data: formattedCode,
};
} catch (error) {
this.log(
`Formatting failed: ${error instanceof Error ? error.message : "Unknown error"}`,
);
return {
success: false,
error: `Formatting failed: ${error instanceof Error ? error.message : "Unknown error"}`,
};
}
}

/**
* Lint code to identify issues
* @param code The code to lint
* @param options Linting options
* @returns A promise resolving to the linting result
*/
async lint(code: string, options: LintOptions): Promise<LintResult> {
try {
if (!code || typeof code !== "string") {
return {
success: false,
error: "Invalid code input: code must be a non-empty string",
};
}

if (!options.language) {
return {
success: false,
error: "Language must be specified in lint options",
};
}

this.log(`Linting code with language: ${options.language}`);

const eslintOptions = {
overrideConfig: {
languageOptions: {
ecmaVersion: 2020,
sourceType: "module",
},
rules: options.rules || {},
},
overrideConfigFile: true,
} as ESLint.Options;

const linter = new ESLint(eslintOptions);
const eslintResult = await linter.lintText(code);

return {
success: true,
data: {
issues: eslintResult.flatMap((result) =>
result.messages.map((message) => ({
line: message.line,
column: message.column,
severity: message.severity === 2 ? "error" : "warning",
rule: message.ruleId || "",
message: message.message,
})),
),
},
};
} catch (error) {
this.log(
`Linting failed: ${error instanceof Error ? error.message : "Unknown error"}`,
);
return {
success: false,
error: `Linting failed: ${error instanceof Error ? error.message : "Unknown error"}`,
};
}
}
}
Loading