@nogataka/smart-edit 0.0.14

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 (186) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +244 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +7 -0
  5. package/dist/devtools/generate_prompt_factory.d.ts +5 -0
  6. package/dist/devtools/generate_prompt_factory.js +114 -0
  7. package/dist/index.d.ts +34 -0
  8. package/dist/index.js +34 -0
  9. package/dist/interprompt/index.d.ts +2 -0
  10. package/dist/interprompt/index.js +1 -0
  11. package/dist/interprompt/jinja_template.d.ts +10 -0
  12. package/dist/interprompt/jinja_template.js +174 -0
  13. package/dist/interprompt/multilang_prompt.d.ts +54 -0
  14. package/dist/interprompt/multilang_prompt.js +302 -0
  15. package/dist/interprompt/prompt_factory.d.ts +16 -0
  16. package/dist/interprompt/prompt_factory.js +189 -0
  17. package/dist/interprompt/util/class_decorators.d.ts +1 -0
  18. package/dist/interprompt/util/class_decorators.js +1 -0
  19. package/dist/interprompt/util/index.d.ts +1 -0
  20. package/dist/interprompt/util/index.js +1 -0
  21. package/dist/serena/agent.d.ts +118 -0
  22. package/dist/serena/agent.js +675 -0
  23. package/dist/serena/agno.d.ts +111 -0
  24. package/dist/serena/agno.js +278 -0
  25. package/dist/serena/analytics.d.ts +24 -0
  26. package/dist/serena/analytics.js +119 -0
  27. package/dist/serena/cli.d.ts +9 -0
  28. package/dist/serena/cli.js +731 -0
  29. package/dist/serena/code_editor.d.ts +42 -0
  30. package/dist/serena/code_editor.js +239 -0
  31. package/dist/serena/config/context_mode.d.ts +41 -0
  32. package/dist/serena/config/context_mode.js +239 -0
  33. package/dist/serena/config/serena_config.d.ts +134 -0
  34. package/dist/serena/config/serena_config.js +718 -0
  35. package/dist/serena/constants.d.ts +18 -0
  36. package/dist/serena/constants.js +27 -0
  37. package/dist/serena/dashboard.d.ts +55 -0
  38. package/dist/serena/dashboard.js +472 -0
  39. package/dist/serena/generated/generated_prompt_factory.d.ts +27 -0
  40. package/dist/serena/generated/generated_prompt_factory.js +42 -0
  41. package/dist/serena/gui_log_viewer.d.ts +41 -0
  42. package/dist/serena/gui_log_viewer.js +436 -0
  43. package/dist/serena/mcp.d.ts +118 -0
  44. package/dist/serena/mcp.js +904 -0
  45. package/dist/serena/project.d.ts +62 -0
  46. package/dist/serena/project.js +321 -0
  47. package/dist/serena/prompt_factory.d.ts +20 -0
  48. package/dist/serena/prompt_factory.js +42 -0
  49. package/dist/serena/resources/config/contexts/agent.yml +8 -0
  50. package/dist/serena/resources/config/contexts/chatgpt.yml +28 -0
  51. package/dist/serena/resources/config/contexts/codex.yml +27 -0
  52. package/dist/serena/resources/config/contexts/context.template.yml +11 -0
  53. package/dist/serena/resources/config/contexts/desktop-app.yml +17 -0
  54. package/dist/serena/resources/config/contexts/ide-assistant.yml +26 -0
  55. package/dist/serena/resources/config/contexts/oaicompat-agent.yml +8 -0
  56. package/dist/serena/resources/config/internal_modes/jetbrains.yml +15 -0
  57. package/dist/serena/resources/config/modes/editing.yml +112 -0
  58. package/dist/serena/resources/config/modes/interactive.yml +11 -0
  59. package/dist/serena/resources/config/modes/mode.template.yml +7 -0
  60. package/dist/serena/resources/config/modes/no-onboarding.yml +8 -0
  61. package/dist/serena/resources/config/modes/onboarding.yml +16 -0
  62. package/dist/serena/resources/config/modes/one-shot.yml +15 -0
  63. package/dist/serena/resources/config/modes/planning.yml +15 -0
  64. package/dist/serena/resources/config/prompt_templates/simple_tool_outputs.yml +75 -0
  65. package/dist/serena/resources/config/prompt_templates/system_prompt.yml +66 -0
  66. package/dist/serena/resources/dashboard/dashboard.js +815 -0
  67. package/dist/serena/resources/dashboard/index.html +314 -0
  68. package/dist/serena/resources/dashboard/jquery.min.js +3 -0
  69. package/dist/serena/resources/dashboard/serena-icon-16.png +0 -0
  70. package/dist/serena/resources/dashboard/serena-icon-32.png +0 -0
  71. package/dist/serena/resources/dashboard/serena-icon-48.png +0 -0
  72. package/dist/serena/resources/dashboard/serena-logs-dark-mode.png +0 -0
  73. package/dist/serena/resources/dashboard/serena-logs.png +0 -0
  74. package/dist/serena/resources/project.template.yml +67 -0
  75. package/dist/serena/resources/serena_config.template.yml +85 -0
  76. package/dist/serena/symbol.d.ts +199 -0
  77. package/dist/serena/symbol.js +616 -0
  78. package/dist/serena/text_utils.d.ts +51 -0
  79. package/dist/serena/text_utils.js +267 -0
  80. package/dist/serena/tools/cmd_tools.d.ts +31 -0
  81. package/dist/serena/tools/cmd_tools.js +48 -0
  82. package/dist/serena/tools/config_tools.d.ts +53 -0
  83. package/dist/serena/tools/config_tools.js +176 -0
  84. package/dist/serena/tools/file_tools.d.ts +231 -0
  85. package/dist/serena/tools/file_tools.js +511 -0
  86. package/dist/serena/tools/index.d.ts +7 -0
  87. package/dist/serena/tools/index.js +7 -0
  88. package/dist/serena/tools/memory_tools.d.ts +60 -0
  89. package/dist/serena/tools/memory_tools.js +135 -0
  90. package/dist/serena/tools/symbol_tools.d.ts +165 -0
  91. package/dist/serena/tools/symbol_tools.js +362 -0
  92. package/dist/serena/tools/tools_base.d.ts +162 -0
  93. package/dist/serena/tools/tools_base.js +378 -0
  94. package/dist/serena/tools/workflow_tools.d.ts +35 -0
  95. package/dist/serena/tools/workflow_tools.js +161 -0
  96. package/dist/serena/util/class_decorators.d.ts +7 -0
  97. package/dist/serena/util/class_decorators.js +37 -0
  98. package/dist/serena/util/exception.d.ts +8 -0
  99. package/dist/serena/util/exception.js +53 -0
  100. package/dist/serena/util/file_system.d.ts +30 -0
  101. package/dist/serena/util/file_system.js +352 -0
  102. package/dist/serena/util/general.d.ts +11 -0
  103. package/dist/serena/util/general.js +42 -0
  104. package/dist/serena/util/git.d.ts +11 -0
  105. package/dist/serena/util/git.js +37 -0
  106. package/dist/serena/util/inspection.d.ts +45 -0
  107. package/dist/serena/util/inspection.js +221 -0
  108. package/dist/serena/util/logging.d.ts +46 -0
  109. package/dist/serena/util/logging.js +205 -0
  110. package/dist/serena/util/shell.d.ts +21 -0
  111. package/dist/serena/util/shell.js +95 -0
  112. package/dist/serena/util/thread.d.ts +23 -0
  113. package/dist/serena/util/thread.js +88 -0
  114. package/dist/serena/version.d.ts +1 -0
  115. package/dist/serena/version.js +23 -0
  116. package/dist/solidlsp/language_servers/autoload.d.ts +23 -0
  117. package/dist/solidlsp/language_servers/autoload.js +25 -0
  118. package/dist/solidlsp/language_servers/bash_language_server.d.ts +10 -0
  119. package/dist/solidlsp/language_servers/bash_language_server.js +64 -0
  120. package/dist/solidlsp/language_servers/clangd_language_server.d.ts +13 -0
  121. package/dist/solidlsp/language_servers/clangd_language_server.js +110 -0
  122. package/dist/solidlsp/language_servers/clojure_lsp.d.ts +13 -0
  123. package/dist/solidlsp/language_servers/clojure_lsp.js +137 -0
  124. package/dist/solidlsp/language_servers/common.d.ts +41 -0
  125. package/dist/solidlsp/language_servers/common.js +365 -0
  126. package/dist/solidlsp/language_servers/csharp_language_server.d.ts +21 -0
  127. package/dist/solidlsp/language_servers/csharp_language_server.js +694 -0
  128. package/dist/solidlsp/language_servers/dart_language_server.d.ts +10 -0
  129. package/dist/solidlsp/language_servers/dart_language_server.js +122 -0
  130. package/dist/solidlsp/language_servers/eclipse_jdtls.d.ts +24 -0
  131. package/dist/solidlsp/language_servers/eclipse_jdtls.js +671 -0
  132. package/dist/solidlsp/language_servers/erlang_language_server.d.ts +22 -0
  133. package/dist/solidlsp/language_servers/erlang_language_server.js +327 -0
  134. package/dist/solidlsp/language_servers/gopls.d.ts +12 -0
  135. package/dist/solidlsp/language_servers/gopls.js +59 -0
  136. package/dist/solidlsp/language_servers/intelephense.d.ts +13 -0
  137. package/dist/solidlsp/language_servers/intelephense.js +121 -0
  138. package/dist/solidlsp/language_servers/jedi_server.d.ts +18 -0
  139. package/dist/solidlsp/language_servers/jedi_server.js +234 -0
  140. package/dist/solidlsp/language_servers/kotlin_language_server.d.ts +19 -0
  141. package/dist/solidlsp/language_servers/kotlin_language_server.js +474 -0
  142. package/dist/solidlsp/language_servers/lua_ls.d.ts +18 -0
  143. package/dist/solidlsp/language_servers/lua_ls.js +319 -0
  144. package/dist/solidlsp/language_servers/nixd_language_server.d.ts +17 -0
  145. package/dist/solidlsp/language_servers/nixd_language_server.js +341 -0
  146. package/dist/solidlsp/language_servers/pyright_server.d.ts +19 -0
  147. package/dist/solidlsp/language_servers/pyright_server.js +180 -0
  148. package/dist/solidlsp/language_servers/r_language_server.d.ts +19 -0
  149. package/dist/solidlsp/language_servers/r_language_server.js +184 -0
  150. package/dist/solidlsp/language_servers/ruby_common.d.ts +10 -0
  151. package/dist/solidlsp/language_servers/ruby_common.js +136 -0
  152. package/dist/solidlsp/language_servers/ruby_lsp.d.ts +18 -0
  153. package/dist/solidlsp/language_servers/ruby_lsp.js +230 -0
  154. package/dist/solidlsp/language_servers/rust_analyzer.d.ts +13 -0
  155. package/dist/solidlsp/language_servers/rust_analyzer.js +96 -0
  156. package/dist/solidlsp/language_servers/solargraph.d.ts +18 -0
  157. package/dist/solidlsp/language_servers/solargraph.js +208 -0
  158. package/dist/solidlsp/language_servers/sourcekit_lsp.d.ts +24 -0
  159. package/dist/solidlsp/language_servers/sourcekit_lsp.js +449 -0
  160. package/dist/solidlsp/language_servers/terraform_ls.d.ts +13 -0
  161. package/dist/solidlsp/language_servers/terraform_ls.js +139 -0
  162. package/dist/solidlsp/language_servers/typescript_language_server.d.ts +20 -0
  163. package/dist/solidlsp/language_servers/typescript_language_server.js +237 -0
  164. package/dist/solidlsp/language_servers/vts_language_server.d.ts +13 -0
  165. package/dist/solidlsp/language_servers/vts_language_server.js +121 -0
  166. package/dist/solidlsp/language_servers/zls.d.ts +20 -0
  167. package/dist/solidlsp/language_servers/zls.js +254 -0
  168. package/dist/solidlsp/ls.d.ts +197 -0
  169. package/dist/solidlsp/ls.js +507 -0
  170. package/dist/solidlsp/ls_config.d.ts +43 -0
  171. package/dist/solidlsp/ls_config.js +157 -0
  172. package/dist/solidlsp/ls_exceptions.d.ts +5 -0
  173. package/dist/solidlsp/ls_exceptions.js +14 -0
  174. package/dist/solidlsp/ls_handler.d.ts +54 -0
  175. package/dist/solidlsp/ls_handler.js +406 -0
  176. package/dist/solidlsp/ls_request.d.ts +31 -0
  177. package/dist/solidlsp/ls_request.js +42 -0
  178. package/dist/solidlsp/ls_types.d.ts +7 -0
  179. package/dist/solidlsp/ls_types.js +8 -0
  180. package/dist/solidlsp/lsp_protocol_handler/server.d.ts +61 -0
  181. package/dist/solidlsp/lsp_protocol_handler/server.js +68 -0
  182. package/dist/solidlsp/util/subprocess_util.d.ts +6 -0
  183. package/dist/solidlsp/util/subprocess_util.js +11 -0
  184. package/dist/solidlsp/util/zip.d.ts +25 -0
  185. package/dist/solidlsp/util/zip.js +188 -0
  186. package/package.json +65 -0
@@ -0,0 +1,31 @@
1
+ import type { DidChangeTextDocumentParams, DidCloseTextDocumentParams, DidOpenTextDocumentParams, DocumentSymbolResult, DocumentSymbolsOptions, FullSymbolTreeOptions, ReferenceInSymbol, ReferencingSymbolsOptions, SolidLanguageServerHandler, SolidLanguageServerNotifications, SolidLanguageServerRequests, UnifiedSymbolInformation } from './ls.js';
2
+ export interface DocumentSymbolRequestParams {
3
+ textDocument: {
4
+ uri: string;
5
+ };
6
+ options?: DocumentSymbolsOptions;
7
+ }
8
+ export interface LanguageServerRequestDelegate {
9
+ sendRequest(method: string, params?: unknown): unknown;
10
+ }
11
+ export declare class LanguageServerRequest implements SolidLanguageServerRequests {
12
+ private readonly delegate;
13
+ constructor(handler: LanguageServerRequestDelegate);
14
+ documentSymbol(params: DocumentSymbolRequestParams): DocumentSymbolResult | null;
15
+ fullSymbolTree(params: FullSymbolTreeOptions): UnifiedSymbolInformation[] | null;
16
+ referencingSymbols(params: ReferencingSymbolsOptions): ReferenceInSymbol[] | null;
17
+ overview(relativeFilePath: string): Record<string, UnifiedSymbolInformation[]> | null;
18
+ shutdown(): void;
19
+ }
20
+ export declare class LspNotification implements SolidLanguageServerNotifications {
21
+ private readonly send;
22
+ constructor(sender: (method: string, params?: unknown) => void);
23
+ initialized(params?: unknown): void;
24
+ exit(): void;
25
+ didOpenTextDocument(params: DidOpenTextDocumentParams): void;
26
+ didChangeTextDocument(params: DidChangeTextDocumentParams): void;
27
+ didCloseTextDocument(params: DidCloseTextDocumentParams): void;
28
+ }
29
+ export type SolidLanguageServerHandlerLike = SolidLanguageServerHandler & {
30
+ sendRequest(method: string, params?: unknown): unknown;
31
+ };
@@ -0,0 +1,42 @@
1
+ export class LanguageServerRequest {
2
+ delegate;
3
+ constructor(handler) {
4
+ this.delegate = handler;
5
+ }
6
+ documentSymbol(params) {
7
+ return this.delegate.sendRequest('textDocument/documentSymbol', params);
8
+ }
9
+ fullSymbolTree(params) {
10
+ return this.delegate.sendRequest('serena/fullSymbolTree', params);
11
+ }
12
+ referencingSymbols(params) {
13
+ return this.delegate.sendRequest('serena/referencingSymbols', params);
14
+ }
15
+ overview(relativeFilePath) {
16
+ return this.delegate.sendRequest('serena/overview', relativeFilePath);
17
+ }
18
+ shutdown() {
19
+ void this.delegate.sendRequest('shutdown');
20
+ }
21
+ }
22
+ export class LspNotification {
23
+ send;
24
+ constructor(sender) {
25
+ this.send = sender;
26
+ }
27
+ initialized(params = null) {
28
+ this.send('initialized', params);
29
+ }
30
+ exit() {
31
+ this.send('exit');
32
+ }
33
+ didOpenTextDocument(params) {
34
+ this.send('textDocument/didOpen', params ?? null);
35
+ }
36
+ didChangeTextDocument(params) {
37
+ this.send('textDocument/didChange', params ?? null);
38
+ }
39
+ didCloseTextDocument(params) {
40
+ this.send('textDocument/didClose', params ?? null);
41
+ }
42
+ }
@@ -0,0 +1,7 @@
1
+ export declare enum ErrorCodes {
2
+ ParseError = -32700,
3
+ InvalidRequest = -32600,
4
+ MethodNotFound = -32601,
5
+ InvalidParams = -32602,
6
+ InternalError = -32603
7
+ }
@@ -0,0 +1,8 @@
1
+ export var ErrorCodes;
2
+ (function (ErrorCodes) {
3
+ ErrorCodes[ErrorCodes["ParseError"] = -32700] = "ParseError";
4
+ ErrorCodes[ErrorCodes["InvalidRequest"] = -32600] = "InvalidRequest";
5
+ ErrorCodes[ErrorCodes["MethodNotFound"] = -32601] = "MethodNotFound";
6
+ ErrorCodes[ErrorCodes["InvalidParams"] = -32602] = "InvalidParams";
7
+ ErrorCodes[ErrorCodes["InternalError"] = -32603] = "InternalError";
8
+ })(ErrorCodes || (ErrorCodes = {}));
@@ -0,0 +1,61 @@
1
+ import { Buffer } from 'node:buffer';
2
+ export type JsonPrimitive = string | number | boolean | null;
3
+ export type JsonValue = JsonPrimitive | JsonObject | JsonArray;
4
+ export interface JsonObject {
5
+ [key: string]: JsonValue;
6
+ }
7
+ export type JsonArray = JsonValue[];
8
+ export type StringDict = Record<string, JsonValue>;
9
+ export type PayloadLike = StringDict | JsonArray | null;
10
+ export declare const ENCODING = "utf-8";
11
+ export interface ProcessLaunchInfo {
12
+ /** Command to launch the language server process. */
13
+ cmd: string | string[];
14
+ /** Additional environment variables to inject when spawning the process. */
15
+ env?: Record<string, string>;
16
+ /** Working directory for the spawned process. Defaults to the current process CWD. */
17
+ cwd?: string;
18
+ }
19
+ export declare class LSPError extends Error {
20
+ readonly code: number;
21
+ constructor(code: number, message: string);
22
+ toLsp(): {
23
+ code: number;
24
+ message: string;
25
+ data?: JsonValue;
26
+ };
27
+ static fromLsp(payload: {
28
+ code?: JsonValue;
29
+ message?: JsonValue;
30
+ }): LSPError;
31
+ }
32
+ export interface JsonRpcResponse {
33
+ jsonrpc: '2.0';
34
+ id: number | string | null;
35
+ result?: JsonValue;
36
+ error?: {
37
+ code: number;
38
+ message: string;
39
+ data?: JsonValue;
40
+ };
41
+ }
42
+ export interface JsonRpcRequest {
43
+ jsonrpc: '2.0';
44
+ id?: number | string | null;
45
+ method: string;
46
+ params?: PayloadLike;
47
+ }
48
+ export type JsonRpcMessage = JsonRpcRequest | JsonRpcResponse;
49
+ export declare function makeResponse(requestId: number | string | null, params: PayloadLike): JsonRpcResponse;
50
+ export declare function makeErrorResponse(requestId: number | string | null, err: LSPError): JsonRpcResponse;
51
+ export declare function makeNotification(method: string, params: PayloadLike): JsonRpcRequest;
52
+ export declare function makeRequest(method: string, requestId: number | string, params: PayloadLike): JsonRpcRequest;
53
+ export declare function createMessage(payload: JsonRpcMessage): Buffer;
54
+ export declare enum MessageType {
55
+ error = 1,
56
+ warning = 2,
57
+ info = 3,
58
+ log = 4
59
+ }
60
+ export declare function contentLength(line: Buffer): number | null;
61
+ export declare function defaultCwd(): string;
@@ -0,0 +1,68 @@
1
+ import { Buffer } from 'node:buffer';
2
+ import os from 'node:os';
3
+ export const ENCODING = 'utf-8';
4
+ export class LSPError extends Error {
5
+ code;
6
+ constructor(code, message) {
7
+ super(message);
8
+ this.name = 'LSPError';
9
+ this.code = code;
10
+ }
11
+ toLsp() {
12
+ return { code: this.code, message: this.message };
13
+ }
14
+ static fromLsp(payload) {
15
+ const code = typeof payload.code === 'number' ? payload.code : -32603;
16
+ const message = typeof payload.message === 'string' ? payload.message : 'Unknown LSP error';
17
+ return new LSPError(code, message);
18
+ }
19
+ }
20
+ export function makeResponse(requestId, params) {
21
+ return { jsonrpc: '2.0', id: requestId, result: params ?? null };
22
+ }
23
+ export function makeErrorResponse(requestId, err) {
24
+ return { jsonrpc: '2.0', id: requestId, error: err.toLsp() };
25
+ }
26
+ export function makeNotification(method, params) {
27
+ const payload = { jsonrpc: '2.0', method };
28
+ if (params !== undefined) {
29
+ payload.params = params;
30
+ }
31
+ return payload;
32
+ }
33
+ export function makeRequest(method, requestId, params) {
34
+ const payload = { jsonrpc: '2.0', method, id: requestId };
35
+ if (params !== undefined) {
36
+ payload.params = params;
37
+ }
38
+ return payload;
39
+ }
40
+ export function createMessage(payload) {
41
+ const body = Buffer.from(JSON.stringify(payload), ENCODING);
42
+ const header = Buffer.from(`Content-Length: ${body.byteLength}\r\nContent-Type: application/vscode-jsonrpc; charset=${ENCODING}\r\n\r\n`, ENCODING);
43
+ return Buffer.concat([header, body]);
44
+ }
45
+ export var MessageType;
46
+ (function (MessageType) {
47
+ MessageType[MessageType["error"] = 1] = "error";
48
+ MessageType[MessageType["warning"] = 2] = "warning";
49
+ MessageType[MessageType["info"] = 3] = "info";
50
+ MessageType[MessageType["log"] = 4] = "log";
51
+ })(MessageType || (MessageType = {}));
52
+ export function contentLength(line) {
53
+ // Content-Length header is case insensitive per RFC7230.
54
+ const normalized = line.toString(ENCODING).trim();
55
+ const prefix = 'content-length:';
56
+ if (!normalized.toLowerCase().startsWith(prefix)) {
57
+ return null;
58
+ }
59
+ const value = normalized.slice(prefix.length).trim();
60
+ const parsed = Number.parseInt(value, 10);
61
+ if (Number.isNaN(parsed)) {
62
+ throw new Error(`Invalid Content-Length header: ${value}`);
63
+ }
64
+ return parsed;
65
+ }
66
+ export function defaultCwd() {
67
+ return process.cwd?.() ?? os.homedir();
68
+ }
@@ -0,0 +1,6 @@
1
+ import type { SpawnOptions, SpawnSyncOptions } from 'node:child_process';
2
+ export type PlatformSubprocessOptions = (SpawnOptions | SpawnSyncOptions) & {
3
+ windowsHide?: boolean;
4
+ };
5
+ export declare function defaultSubprocessOptions(platform?: NodeJS.Platform): PlatformSubprocessOptions;
6
+ export declare function ensureDefaultSubprocessOptions<T extends PlatformSubprocessOptions>(options: T, platform?: NodeJS.Platform): T;
@@ -0,0 +1,11 @@
1
+ import process from 'node:process';
2
+ export function defaultSubprocessOptions(platform = process.platform) {
3
+ return platform === 'win32' ? { windowsHide: true } : {};
4
+ }
5
+ export function ensureDefaultSubprocessOptions(options, platform = process.platform) {
6
+ const defaults = defaultSubprocessOptions(platform);
7
+ if (defaults.windowsHide && options.windowsHide === undefined) {
8
+ options.windowsHide = defaults.windowsHide;
9
+ }
10
+ return options;
11
+ }
@@ -0,0 +1,25 @@
1
+ export interface SafeZipExtractorOptions {
2
+ verbose?: boolean;
3
+ includePatterns?: string[];
4
+ excludePatterns?: string[];
5
+ logger?: ZipLogger;
6
+ }
7
+ export interface ZipLogger {
8
+ info(message: string): void;
9
+ error(message: string, error?: unknown): void;
10
+ }
11
+ export declare class SafeZipExtractor {
12
+ private readonly archivePath;
13
+ private readonly extractDir;
14
+ private readonly verbose;
15
+ private readonly includePatterns;
16
+ private readonly excludePatterns;
17
+ private readonly logger?;
18
+ constructor(archivePath: string, extractDir: string, options?: SafeZipExtractorOptions);
19
+ extractAll(): void;
20
+ protected shouldExtract(filename: string): boolean;
21
+ protected resolveTargetPath(filename: string): string | null;
22
+ protected normalizePath(targetPath: string): string;
23
+ private logInfo;
24
+ private logError;
25
+ }
@@ -0,0 +1,188 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import process from 'node:process';
4
+ import AdmZip from 'adm-zip';
5
+ export class SafeZipExtractor {
6
+ archivePath;
7
+ extractDir;
8
+ verbose;
9
+ includePatterns;
10
+ excludePatterns;
11
+ logger;
12
+ constructor(archivePath, extractDir, options = {}) {
13
+ this.archivePath = path.resolve(archivePath);
14
+ this.extractDir = path.resolve(extractDir);
15
+ this.verbose = options.verbose ?? true;
16
+ this.includePatterns = options.includePatterns ?? [];
17
+ this.excludePatterns = options.excludePatterns ?? [];
18
+ this.logger = options.logger;
19
+ }
20
+ extractAll() {
21
+ if (!fs.existsSync(this.archivePath)) {
22
+ throw new Error(`Archive not found: ${this.archivePath}`);
23
+ }
24
+ if (this.verbose) {
25
+ this.logInfo(`Extracting from: ${this.archivePath} to ${this.extractDir}`);
26
+ }
27
+ const zip = new AdmZip(this.archivePath);
28
+ for (const entry of zip.getEntries()) {
29
+ const filename = entry.entryName;
30
+ if (!this.shouldExtract(filename)) {
31
+ if (this.verbose) {
32
+ this.logInfo(`Skipped: ${filename}`);
33
+ }
34
+ continue;
35
+ }
36
+ try {
37
+ const outputPath = this.resolveTargetPath(filename);
38
+ if (!outputPath) {
39
+ if (this.verbose) {
40
+ this.logInfo(`Skipping outside-path entry: ${filename}`);
41
+ }
42
+ continue;
43
+ }
44
+ if (entry.isDirectory) {
45
+ fs.mkdirSync(outputPath, { recursive: true });
46
+ continue;
47
+ }
48
+ const directory = path.dirname(outputPath);
49
+ fs.mkdirSync(directory, { recursive: true });
50
+ const finalPath = this.normalizePath(outputPath);
51
+ const data = entry.getData();
52
+ fs.writeFileSync(finalPath, data);
53
+ if (this.verbose) {
54
+ this.logInfo(`Extracted: ${filename}`);
55
+ }
56
+ }
57
+ catch (error) {
58
+ this.logError(`Failed to extract ${filename}`, error);
59
+ }
60
+ }
61
+ }
62
+ shouldExtract(filename) {
63
+ if (this.includePatterns.length > 0 && !this.includePatterns.some((pattern) => matchesGlob(filename, pattern))) {
64
+ return false;
65
+ }
66
+ if (this.excludePatterns.length > 0 && this.excludePatterns.some((pattern) => matchesGlob(filename, pattern))) {
67
+ return false;
68
+ }
69
+ return true;
70
+ }
71
+ resolveTargetPath(filename) {
72
+ const sanitized = filename.replace(/^\/+/, '');
73
+ const target = path.resolve(this.extractDir, sanitized);
74
+ const relative = path.relative(this.extractDir, target);
75
+ if (relative.startsWith('..') || path.isAbsolute(relative)) {
76
+ return null;
77
+ }
78
+ return target;
79
+ }
80
+ normalizePath(targetPath) {
81
+ if (process.platform === 'win32') {
82
+ const absolute = path.resolve(targetPath);
83
+ if (!absolute.startsWith('\\\\?\\')) {
84
+ return `\\\\?\\${absolute}`;
85
+ }
86
+ return absolute;
87
+ }
88
+ return targetPath;
89
+ }
90
+ logInfo(message) {
91
+ if (this.logger) {
92
+ this.logger.info(message);
93
+ }
94
+ else {
95
+ console.info(message);
96
+ }
97
+ }
98
+ logError(message, error) {
99
+ if (this.logger) {
100
+ this.logger.error(message, error);
101
+ return;
102
+ }
103
+ console.error(`${message}:`, error);
104
+ }
105
+ }
106
+ function matchesGlob(filename, pattern) {
107
+ const regex = globToRegExp(pattern);
108
+ return regex.test(filename);
109
+ }
110
+ function globToRegExp(pattern) {
111
+ let regex = '^';
112
+ for (let i = 0; i < pattern.length; i += 1) {
113
+ const char = pattern[i];
114
+ if (char === '*') {
115
+ regex += '.*';
116
+ continue;
117
+ }
118
+ if (char === '?') {
119
+ regex += '.';
120
+ continue;
121
+ }
122
+ if (char === '[') {
123
+ const { expression, length } = convertCharacterClass(pattern, i);
124
+ regex += expression;
125
+ i += length;
126
+ continue;
127
+ }
128
+ regex += escapeRegexChar(char);
129
+ }
130
+ regex += '$';
131
+ return new RegExp(regex);
132
+ }
133
+ function convertCharacterClass(pattern, startIndex) {
134
+ let index = startIndex + 1;
135
+ let negate = false;
136
+ if (index >= pattern.length) {
137
+ return { expression: '\\[', length: 0 };
138
+ }
139
+ let firstChar = pattern[index];
140
+ if (firstChar === '!' || firstChar === '^') {
141
+ negate = true;
142
+ index += 1;
143
+ firstChar = pattern[index];
144
+ }
145
+ if (index >= pattern.length) {
146
+ return { expression: '\\[', length: 0 };
147
+ }
148
+ const classChars = [];
149
+ let closed = false;
150
+ if (firstChar === ']') {
151
+ classChars.push('\\]');
152
+ index += 1;
153
+ }
154
+ for (; index < pattern.length; index += 1) {
155
+ const char = pattern[index];
156
+ if (char === ']') {
157
+ closed = true;
158
+ break;
159
+ }
160
+ if (char === '\\' && index + 1 < pattern.length) {
161
+ index += 1;
162
+ classChars.push(escapeClassChar(pattern[index]));
163
+ continue;
164
+ }
165
+ classChars.push(escapeClassChar(char));
166
+ }
167
+ if (!closed) {
168
+ return { expression: '\\[', length: 0 };
169
+ }
170
+ const expression = `[${negate ? '^' : ''}${classChars.join('')}]`;
171
+ const consumedLength = index - startIndex;
172
+ return { expression, length: consumedLength };
173
+ }
174
+ function escapeRegexChar(char) {
175
+ if (/[[\]{}()*+?.\\^$|]/.test(char)) {
176
+ return `\\${char}`;
177
+ }
178
+ return char;
179
+ }
180
+ function escapeClassChar(char) {
181
+ if (char === '-') {
182
+ return '-';
183
+ }
184
+ if (char === '^' || char === ']' || char === '\\') {
185
+ return `\\${char}`;
186
+ }
187
+ return char;
188
+ }
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@nogataka/smart-edit",
3
+ "version": "0.0.14",
4
+ "description": "TypeScript版 Serena",
5
+ "private": false,
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "engines": {
9
+ "node": ">=20.11.0"
10
+ },
11
+ "bin": {
12
+ "smart-edit": "./dist/cli.js"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ }
22
+ },
23
+ "dependencies": {
24
+ "@dqbd/tiktoken": "^1.0.22",
25
+ "@modelcontextprotocol/sdk": "^1.16.0",
26
+ "adm-zip": "^0.5.16",
27
+ "commander": "^12.1.0",
28
+ "ignore": "^7.0.5",
29
+ "nunjucks": "^3.2.4",
30
+ "tar": "^7.5.1",
31
+ "yaml": "^2.4.2",
32
+ "zod": "^3.25.0",
33
+ "zod-to-json-schema": "^3.24.1"
34
+ },
35
+ "devDependencies": {
36
+ "@eslint/js": "^9.12.0",
37
+ "@types/adm-zip": "^0.5.7",
38
+ "@types/node": "^20.11.0",
39
+ "@types/nunjucks": "^3.2.5",
40
+ "@typescript-eslint/eslint-plugin": "^8.9.0",
41
+ "@typescript-eslint/parser": "^8.9.0",
42
+ "@vitest/coverage-v8": "^2.1.1",
43
+ "eslint": "^9.12.0",
44
+ "eslint-config-prettier": "^9.1.0",
45
+ "prettier": "^3.3.3",
46
+ "rimraf": "^5.0.5",
47
+ "ts-node": "^10.9.2",
48
+ "tslib": "^2.7.0",
49
+ "tsx": "^4.17.0",
50
+ "typescript": "5.5.4",
51
+ "vitest": "^2.1.1"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc -p tsconfig.build.json && node ./scripts/copy-resources.mjs",
55
+ "clean": "rimraf dist",
56
+ "format": "prettier --write .",
57
+ "format:check": "prettier --check .",
58
+ "lint": "eslint .",
59
+ "lint:fix": "pnpm lint --fix",
60
+ "test": "vitest run",
61
+ "test:watch": "vitest",
62
+ "typecheck": "tsc --noEmit",
63
+ "prompts:generate": "tsx src/devtools/generate_prompt_factory.ts"
64
+ }
65
+ }