@sudosandwich/limps 0.2.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.
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/dist/agent-parser.d.ts +146 -0
- package/dist/agent-parser.d.ts.map +1 -0
- package/dist/agent-parser.js +448 -0
- package/dist/agent-parser.js.map +1 -0
- package/dist/config.d.ts +54 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +146 -0
- package/dist/config.js.map +1 -0
- package/dist/coordination.d.ts +102 -0
- package/dist/coordination.d.ts.map +1 -0
- package/dist/coordination.js +157 -0
- package/dist/coordination.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +256 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer.d.ts +83 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +467 -0
- package/dist/indexer.js.map +1 -0
- package/dist/resources/agents-status.d.ts +32 -0
- package/dist/resources/agents-status.d.ts.map +1 -0
- package/dist/resources/agents-status.js +73 -0
- package/dist/resources/agents-status.js.map +1 -0
- package/dist/resources/decisions-log.d.ts +21 -0
- package/dist/resources/decisions-log.d.ts.map +1 -0
- package/dist/resources/decisions-log.js +146 -0
- package/dist/resources/decisions-log.js.map +1 -0
- package/dist/resources/index.d.ts +10 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +74 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/plans-full.d.ts +11 -0
- package/dist/resources/plans-full.d.ts.map +1 -0
- package/dist/resources/plans-full.js +71 -0
- package/dist/resources/plans-full.js.map +1 -0
- package/dist/resources/plans-index.d.ts +30 -0
- package/dist/resources/plans-index.d.ts.map +1 -0
- package/dist/resources/plans-index.js +177 -0
- package/dist/resources/plans-index.js.map +1 -0
- package/dist/resources/plans-summary.d.ts +33 -0
- package/dist/resources/plans-summary.d.ts.map +1 -0
- package/dist/resources/plans-summary.js +238 -0
- package/dist/resources/plans-summary.js.map +1 -0
- package/dist/rlm/extractors.d.ts +39 -0
- package/dist/rlm/extractors.d.ts.map +1 -0
- package/dist/rlm/extractors.js +291 -0
- package/dist/rlm/extractors.js.map +1 -0
- package/dist/rlm/helpers-inject.d.ts +13 -0
- package/dist/rlm/helpers-inject.d.ts.map +1 -0
- package/dist/rlm/helpers-inject.js +586 -0
- package/dist/rlm/helpers-inject.js.map +1 -0
- package/dist/rlm/helpers.d.ts +124 -0
- package/dist/rlm/helpers.d.ts.map +1 -0
- package/dist/rlm/helpers.js +381 -0
- package/dist/rlm/helpers.js.map +1 -0
- package/dist/rlm/index.d.ts +12 -0
- package/dist/rlm/index.d.ts.map +1 -0
- package/dist/rlm/index.js +19 -0
- package/dist/rlm/index.js.map +1 -0
- package/dist/rlm/parallel.d.ts +45 -0
- package/dist/rlm/parallel.d.ts.map +1 -0
- package/dist/rlm/parallel.js +76 -0
- package/dist/rlm/parallel.js.map +1 -0
- package/dist/rlm/recursion.d.ts +96 -0
- package/dist/rlm/recursion.d.ts.map +1 -0
- package/dist/rlm/recursion.js +113 -0
- package/dist/rlm/recursion.js.map +1 -0
- package/dist/rlm/sampling.d.ts +100 -0
- package/dist/rlm/sampling.d.ts.map +1 -0
- package/dist/rlm/sampling.js +96 -0
- package/dist/rlm/sampling.js.map +1 -0
- package/dist/rlm/sandbox.d.ts +73 -0
- package/dist/rlm/sandbox.d.ts.map +1 -0
- package/dist/rlm/sandbox.js +160 -0
- package/dist/rlm/sandbox.js.map +1 -0
- package/dist/rlm/security.d.ts +28 -0
- package/dist/rlm/security.d.ts.map +1 -0
- package/dist/rlm/security.js +154 -0
- package/dist/rlm/security.js.map +1 -0
- package/dist/server.d.ts +21 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +107 -0
- package/dist/server.js.map +1 -0
- package/dist/task-parser.d.ts +47 -0
- package/dist/task-parser.d.ts.map +1 -0
- package/dist/task-parser.js +112 -0
- package/dist/task-parser.js.map +1 -0
- package/dist/test-setup.d.ts +6 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +37 -0
- package/dist/test-setup.js.map +1 -0
- package/dist/tools/claim-task.d.ts +28 -0
- package/dist/tools/claim-task.d.ts.map +1 -0
- package/dist/tools/claim-task.js +288 -0
- package/dist/tools/claim-task.js.map +1 -0
- package/dist/tools/create-doc.d.ts +47 -0
- package/dist/tools/create-doc.d.ts.map +1 -0
- package/dist/tools/create-doc.js +137 -0
- package/dist/tools/create-doc.js.map +1 -0
- package/dist/tools/create-plan.d.ts +25 -0
- package/dist/tools/create-plan.d.ts.map +1 -0
- package/dist/tools/create-plan.js +179 -0
- package/dist/tools/create-plan.js.map +1 -0
- package/dist/tools/delete-doc.d.ts +51 -0
- package/dist/tools/delete-doc.d.ts.map +1 -0
- package/dist/tools/delete-doc.js +194 -0
- package/dist/tools/delete-doc.js.map +1 -0
- package/dist/tools/get-next-task.d.ts +49 -0
- package/dist/tools/get-next-task.d.ts.map +1 -0
- package/dist/tools/get-next-task.js +204 -0
- package/dist/tools/get-next-task.js.map +1 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +122 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-docs.d.ts +53 -0
- package/dist/tools/list-docs.d.ts.map +1 -0
- package/dist/tools/list-docs.js +236 -0
- package/dist/tools/list-docs.js.map +1 -0
- package/dist/tools/open-document-in-cursor.d.ts +62 -0
- package/dist/tools/open-document-in-cursor.d.ts.map +1 -0
- package/dist/tools/open-document-in-cursor.js +211 -0
- package/dist/tools/open-document-in-cursor.js.map +1 -0
- package/dist/tools/read-doc.d.ts +44 -0
- package/dist/tools/read-doc.d.ts.map +1 -0
- package/dist/tools/read-doc.js +174 -0
- package/dist/tools/read-doc.js.map +1 -0
- package/dist/tools/release-task.d.ts +28 -0
- package/dist/tools/release-task.d.ts.map +1 -0
- package/dist/tools/release-task.js +154 -0
- package/dist/tools/release-task.js.map +1 -0
- package/dist/tools/rlm-multi-query.d.ts +110 -0
- package/dist/tools/rlm-multi-query.d.ts.map +1 -0
- package/dist/tools/rlm-multi-query.js +348 -0
- package/dist/tools/rlm-multi-query.js.map +1 -0
- package/dist/tools/rlm-query.d.ts +56 -0
- package/dist/tools/rlm-query.d.ts.map +1 -0
- package/dist/tools/rlm-query.js +228 -0
- package/dist/tools/rlm-query.js.map +1 -0
- package/dist/tools/search-docs.d.ts +34 -0
- package/dist/tools/search-docs.d.ts.map +1 -0
- package/dist/tools/search-docs.js +292 -0
- package/dist/tools/search-docs.js.map +1 -0
- package/dist/tools/update-doc.d.ts +149 -0
- package/dist/tools/update-doc.d.ts.map +1 -0
- package/dist/tools/update-doc.js +195 -0
- package/dist/tools/update-doc.js.map +1 -0
- package/dist/tools/update-task-status.d.ts +31 -0
- package/dist/tools/update-task-status.d.ts.map +1 -0
- package/dist/tools/update-task-status.js +303 -0
- package/dist/tools/update-task-status.js.map +1 -0
- package/dist/types.d.ts +50 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/backup.d.ts +76 -0
- package/dist/utils/backup.d.ts.map +1 -0
- package/dist/utils/backup.js +172 -0
- package/dist/utils/backup.js.map +1 -0
- package/dist/utils/errors.d.ts +93 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +125 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/os-paths.d.ts +45 -0
- package/dist/utils/os-paths.d.ts.map +1 -0
- package/dist/utils/os-paths.js +81 -0
- package/dist/utils/os-paths.js.map +1 -0
- package/dist/utils/paths.d.ts +71 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +165 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/watcher.d.ts +19 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +109 -0
- package/dist/watcher.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OS-specific path resolution utilities for global npm installation.
|
|
3
|
+
* Provides default configuration and data paths based on the operating system.
|
|
4
|
+
*/
|
|
5
|
+
import { homedir } from 'os';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
const DEFAULT_APP_NAME = 'mcp-planning-server';
|
|
8
|
+
/**
|
|
9
|
+
* Get the OS-specific base directory for application data.
|
|
10
|
+
*
|
|
11
|
+
* @param appName - Application/project name (defaults to mcp-planning-server)
|
|
12
|
+
* @returns Absolute path to the base directory
|
|
13
|
+
*/
|
|
14
|
+
export function getOSBasePath(appName = DEFAULT_APP_NAME) {
|
|
15
|
+
const home = homedir();
|
|
16
|
+
switch (process.platform) {
|
|
17
|
+
case 'darwin':
|
|
18
|
+
return join(home, 'Library', 'Application Support', appName);
|
|
19
|
+
case 'win32':
|
|
20
|
+
return join(process.env.APPDATA || join(home, 'AppData', 'Roaming'), appName);
|
|
21
|
+
default:
|
|
22
|
+
return join(process.env.XDG_CONFIG_HOME || join(home, '.config'), appName);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get the OS-specific default configuration file path.
|
|
27
|
+
*
|
|
28
|
+
* - macOS: ~/Library/Application Support/{appName}/config.json
|
|
29
|
+
* - Windows: %APPDATA%\{appName}\config.json
|
|
30
|
+
* - Linux/others: ~/.config/{appName}/config.json (XDG_CONFIG_HOME)
|
|
31
|
+
*
|
|
32
|
+
* @param appName - Application/project name (defaults to mcp-planning-server)
|
|
33
|
+
* @returns Absolute path to the default config file location
|
|
34
|
+
*/
|
|
35
|
+
export function getOSConfigPath(appName = DEFAULT_APP_NAME) {
|
|
36
|
+
return join(getOSBasePath(appName), 'config.json');
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the OS-specific default data directory path.
|
|
40
|
+
*
|
|
41
|
+
* - macOS: ~/Library/Application Support/{appName}/data
|
|
42
|
+
* - Windows: %APPDATA%\{appName}\data
|
|
43
|
+
* - Linux/others: ~/.local/share/{appName}/data (XDG_DATA_HOME)
|
|
44
|
+
*
|
|
45
|
+
* @param appName - Application/project name (defaults to mcp-planning-server)
|
|
46
|
+
* @returns Absolute path to the default data directory
|
|
47
|
+
*/
|
|
48
|
+
export function getOSDataPath(appName = DEFAULT_APP_NAME) {
|
|
49
|
+
const home = homedir();
|
|
50
|
+
switch (process.platform) {
|
|
51
|
+
case 'darwin':
|
|
52
|
+
return join(getOSBasePath(appName), 'data');
|
|
53
|
+
case 'win32':
|
|
54
|
+
return join(getOSBasePath(appName), 'data');
|
|
55
|
+
default:
|
|
56
|
+
// Linux: data goes to XDG_DATA_HOME, not XDG_CONFIG_HOME
|
|
57
|
+
return join(process.env.XDG_DATA_HOME || join(home, '.local', 'share'), appName, 'data');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get the OS-specific default coordination file path.
|
|
62
|
+
*
|
|
63
|
+
* - macOS: ~/Library/Application Support/{appName}/coordination.json
|
|
64
|
+
* - Windows: %APPDATA%\{appName}\coordination.json
|
|
65
|
+
* - Linux/others: ~/.local/share/{appName}/coordination.json (XDG_DATA_HOME)
|
|
66
|
+
*
|
|
67
|
+
* @param appName - Application/project name (defaults to mcp-planning-server)
|
|
68
|
+
* @returns Absolute path to the default coordination file
|
|
69
|
+
*/
|
|
70
|
+
export function getOSCoordinationPath(appName = DEFAULT_APP_NAME) {
|
|
71
|
+
const home = homedir();
|
|
72
|
+
switch (process.platform) {
|
|
73
|
+
case 'darwin':
|
|
74
|
+
return join(getOSBasePath(appName), 'coordination.json');
|
|
75
|
+
case 'win32':
|
|
76
|
+
return join(getOSBasePath(appName), 'coordination.json');
|
|
77
|
+
default:
|
|
78
|
+
return join(process.env.XDG_DATA_HOME || join(home, '.local', 'share'), appName, 'coordination.json');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=os-paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"os-paths.js","sourceRoot":"","sources":["../../src/utils/os-paths.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB,gBAAgB;IAC9D,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,OAAO,CAAC,CAAC;QAC/D,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;QAChF;YACE,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB,gBAAgB;IAChE,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB,gBAAgB;IAC9D,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9C,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9C;YACE,yDAAyD;YACzD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC7F,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,UAAkB,gBAAgB;IACtE,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,mBAAmB,CAAC,CAAC;QAC3D,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,mBAAmB,CAAC,CAAC;QAC3D;YACE,OAAO,IAAI,CACT,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,EAC1D,OAAO,EACP,mBAAmB,CACpB,CAAC;IACN,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path validation utilities for MCP document CRUD operations.
|
|
3
|
+
* Validates paths, prevents directory traversal, and enforces access restrictions.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Document type based on file extension.
|
|
7
|
+
*/
|
|
8
|
+
export type DocType = 'md' | 'jsx' | 'tsx' | 'ts' | 'json' | 'yaml' | 'other';
|
|
9
|
+
/**
|
|
10
|
+
* Result of path validation.
|
|
11
|
+
*/
|
|
12
|
+
export interface ValidatedPath {
|
|
13
|
+
/** Path relative to repo root */
|
|
14
|
+
relative: string;
|
|
15
|
+
/** Absolute path */
|
|
16
|
+
absolute: string;
|
|
17
|
+
/** Document type based on extension */
|
|
18
|
+
type: DocType;
|
|
19
|
+
/** Directory portion (empty string for root) */
|
|
20
|
+
directory: string;
|
|
21
|
+
/** Filename with extension */
|
|
22
|
+
filename: string;
|
|
23
|
+
/** File extension including dot (e.g., '.md') */
|
|
24
|
+
extension: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Options for path validation.
|
|
28
|
+
*/
|
|
29
|
+
export interface PathValidationOptions {
|
|
30
|
+
/** Whether to check if path is in a writable directory (default: false) */
|
|
31
|
+
requireWritable?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Paths that are restricted and cannot be accessed.
|
|
35
|
+
*/
|
|
36
|
+
export declare const RESTRICTED_PATHS: readonly string[];
|
|
37
|
+
/**
|
|
38
|
+
* Directories that allow write operations.
|
|
39
|
+
*/
|
|
40
|
+
export declare const WRITABLE_DIRS: readonly string[];
|
|
41
|
+
/**
|
|
42
|
+
* Plan files that require confirmation before overwrite (protected, not blocked).
|
|
43
|
+
* These files can be written, but require explicit confirmation (force: true).
|
|
44
|
+
*/
|
|
45
|
+
export declare const PROTECTED_PLAN_FILES: readonly RegExp[];
|
|
46
|
+
/**
|
|
47
|
+
* Check if a path is a protected plan file that requires confirmation.
|
|
48
|
+
*
|
|
49
|
+
* @param relativePath - Path relative to repo root
|
|
50
|
+
* @returns True if the path matches a protected plan file pattern
|
|
51
|
+
*/
|
|
52
|
+
export declare function isProtectedPlanFile(relativePath: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Get document type from file path based on extension.
|
|
55
|
+
*/
|
|
56
|
+
export declare function getDocType(filePath: string): DocType;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a path is writable (in allowed directories or root .md file).
|
|
59
|
+
*/
|
|
60
|
+
export declare function isWritablePath(relativePath: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Validate a path relative to the repository root.
|
|
63
|
+
*
|
|
64
|
+
* @param path - Path to validate (relative to repo root)
|
|
65
|
+
* @param repoRoot - Absolute path to repository root
|
|
66
|
+
* @param options - Validation options
|
|
67
|
+
* @returns Validated path information
|
|
68
|
+
* @throws DocumentError if validation fails
|
|
69
|
+
*/
|
|
70
|
+
export declare function validatePath(path: string, repoRoot: string, options?: PathValidationOptions): ValidatedPath;
|
|
71
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAQ7C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAAmD,CAAC;AAE/F;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAEjD,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAoBpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAuB5D;AAoCD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,qBAA0B,GAClC,aAAa,CAgDf"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path validation utilities for MCP document CRUD operations.
|
|
3
|
+
* Validates paths, prevents directory traversal, and enforces access restrictions.
|
|
4
|
+
*/
|
|
5
|
+
import { resolve, dirname, basename, extname, isAbsolute, relative } from 'path';
|
|
6
|
+
import { restrictedPath, validationError } from './errors.js';
|
|
7
|
+
/**
|
|
8
|
+
* Paths that are restricted and cannot be accessed.
|
|
9
|
+
*/
|
|
10
|
+
export const RESTRICTED_PATHS = [
|
|
11
|
+
'.git',
|
|
12
|
+
'node_modules',
|
|
13
|
+
'.env',
|
|
14
|
+
'.env.local',
|
|
15
|
+
'.env.development',
|
|
16
|
+
'.env.production',
|
|
17
|
+
'.env.test',
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* Directories that allow write operations.
|
|
21
|
+
*/
|
|
22
|
+
export const WRITABLE_DIRS = ['addendums', 'examples', 'research', 'plans'];
|
|
23
|
+
/**
|
|
24
|
+
* Plan files that require confirmation before overwrite (protected, not blocked).
|
|
25
|
+
* These files can be written, but require explicit confirmation (force: true).
|
|
26
|
+
*/
|
|
27
|
+
export const PROTECTED_PLAN_FILES = [
|
|
28
|
+
/^plans\/\d{4}-[^/]+\/plan\.md$/, // Existing plan.md files
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* Check if a path is a protected plan file that requires confirmation.
|
|
32
|
+
*
|
|
33
|
+
* @param relativePath - Path relative to repo root
|
|
34
|
+
* @returns True if the path matches a protected plan file pattern
|
|
35
|
+
*/
|
|
36
|
+
export function isProtectedPlanFile(relativePath) {
|
|
37
|
+
const normalized = normalizePath(relativePath);
|
|
38
|
+
return PROTECTED_PLAN_FILES.some((pattern) => pattern.test(normalized));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get document type from file path based on extension.
|
|
42
|
+
*/
|
|
43
|
+
export function getDocType(filePath) {
|
|
44
|
+
const ext = extname(filePath).toLowerCase();
|
|
45
|
+
switch (ext) {
|
|
46
|
+
case '.md':
|
|
47
|
+
return 'md';
|
|
48
|
+
case '.jsx':
|
|
49
|
+
return 'jsx';
|
|
50
|
+
case '.tsx':
|
|
51
|
+
return 'tsx';
|
|
52
|
+
case '.ts':
|
|
53
|
+
return 'ts';
|
|
54
|
+
case '.json':
|
|
55
|
+
return 'json';
|
|
56
|
+
case '.yaml':
|
|
57
|
+
case '.yml':
|
|
58
|
+
return 'yaml';
|
|
59
|
+
default:
|
|
60
|
+
return 'other';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if a path is writable (in allowed directories or root .md file).
|
|
65
|
+
*/
|
|
66
|
+
export function isWritablePath(relativePath) {
|
|
67
|
+
const normalized = normalizePath(relativePath);
|
|
68
|
+
// Empty path (root) is not writable
|
|
69
|
+
if (!normalized) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
// Get the top-level directory
|
|
73
|
+
const parts = normalized.split('/');
|
|
74
|
+
const topDir = parts[0];
|
|
75
|
+
// Check if in writable directories
|
|
76
|
+
if (WRITABLE_DIRS.includes(topDir)) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
// Root-level markdown files are writable
|
|
80
|
+
if (parts.length === 1 && extname(normalized).toLowerCase() === '.md') {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Normalize a path: remove trailing slashes, collapse double slashes.
|
|
87
|
+
*/
|
|
88
|
+
function normalizePath(path) {
|
|
89
|
+
// Remove trailing slashes
|
|
90
|
+
let normalized = path.replace(/\/+$/, '');
|
|
91
|
+
// Collapse double slashes
|
|
92
|
+
normalized = normalized.replace(/\/+/g, '/');
|
|
93
|
+
// Remove leading ./
|
|
94
|
+
normalized = normalized.replace(/^\.\//, '');
|
|
95
|
+
return normalized;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Check if path matches any restricted patterns.
|
|
99
|
+
*/
|
|
100
|
+
function isRestrictedPath(relativePath) {
|
|
101
|
+
const normalized = normalizePath(relativePath);
|
|
102
|
+
const parts = normalized.split('/');
|
|
103
|
+
for (const part of parts) {
|
|
104
|
+
// Check exact matches
|
|
105
|
+
if (RESTRICTED_PATHS.includes(part)) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
// Check .env* patterns
|
|
109
|
+
if (part.startsWith('.env')) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Validate a path relative to the repository root.
|
|
117
|
+
*
|
|
118
|
+
* @param path - Path to validate (relative to repo root)
|
|
119
|
+
* @param repoRoot - Absolute path to repository root
|
|
120
|
+
* @param options - Validation options
|
|
121
|
+
* @returns Validated path information
|
|
122
|
+
* @throws DocumentError if validation fails
|
|
123
|
+
*/
|
|
124
|
+
export function validatePath(path, repoRoot, options = {}) {
|
|
125
|
+
// Reject absolute paths
|
|
126
|
+
if (isAbsolute(path)) {
|
|
127
|
+
throw validationError('path', 'Path must be relative to repo root');
|
|
128
|
+
}
|
|
129
|
+
// Check for path traversal attempts before resolving
|
|
130
|
+
if (path.includes('..')) {
|
|
131
|
+
throw validationError('path', 'Path traversal not allowed');
|
|
132
|
+
}
|
|
133
|
+
// Normalize the path
|
|
134
|
+
const normalized = normalizePath(path);
|
|
135
|
+
// Resolve to absolute path
|
|
136
|
+
const absolutePath = resolve(repoRoot, normalized);
|
|
137
|
+
// Double-check the resolved path is within repo root
|
|
138
|
+
// This catches edge cases the simple .. check might miss
|
|
139
|
+
const resolvedRelative = relative(repoRoot, absolutePath);
|
|
140
|
+
if (resolvedRelative.startsWith('..') || isAbsolute(resolvedRelative)) {
|
|
141
|
+
throw validationError('path', 'Path traversal not allowed');
|
|
142
|
+
}
|
|
143
|
+
// Check for restricted paths
|
|
144
|
+
if (isRestrictedPath(normalized)) {
|
|
145
|
+
throw restrictedPath(path);
|
|
146
|
+
}
|
|
147
|
+
// Check writable requirement
|
|
148
|
+
if (options.requireWritable && !isWritablePath(normalized)) {
|
|
149
|
+
throw restrictedPath(path);
|
|
150
|
+
}
|
|
151
|
+
// Extract path components
|
|
152
|
+
const dir = dirname(normalized);
|
|
153
|
+
const filename = basename(normalized);
|
|
154
|
+
const extension = extname(normalized);
|
|
155
|
+
const type = getDocType(normalized);
|
|
156
|
+
return {
|
|
157
|
+
relative: normalized,
|
|
158
|
+
absolute: absolutePath,
|
|
159
|
+
type,
|
|
160
|
+
directory: dir === '.' ? '' : dir,
|
|
161
|
+
filename: filename || normalized, // Handle directory-only paths
|
|
162
|
+
extension,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type FSWatcher } from 'chokidar';
|
|
2
|
+
/**
|
|
3
|
+
* Start a file watcher for specified file types.
|
|
4
|
+
*
|
|
5
|
+
* @param watchPaths - Path(s) to watch (file or directory, single or array)
|
|
6
|
+
* @param onChange - Callback when file changes (path, event)
|
|
7
|
+
* @param fileExtensions - File extensions to watch (e.g., ['.md', '.jsx', '.tsx'])
|
|
8
|
+
* @param ignorePatterns - Patterns to ignore (e.g., ['.git', 'node_modules'])
|
|
9
|
+
* @param debounceDelay - Debounce delay in milliseconds (default: 200ms)
|
|
10
|
+
* @returns Chokidar watcher instance
|
|
11
|
+
*/
|
|
12
|
+
export declare function startWatcher(watchPaths: string | string[], onChange: (path: string, event: 'add' | 'change' | 'unlink') => Promise<void>, fileExtensions?: string[], ignorePatterns?: string[], debounceDelay?: number): FSWatcher;
|
|
13
|
+
/**
|
|
14
|
+
* Stop a file watcher.
|
|
15
|
+
*
|
|
16
|
+
* @param watcher - Chokidar watcher instance
|
|
17
|
+
*/
|
|
18
|
+
export declare function stopWatcher(watcher: FSWatcher): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAAA,OAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAcpD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,EAC7B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,EAC7E,cAAc,GAAE,MAAM,EAA4B,EAClD,cAAc,GAAE,MAAM,EAAqC,EAC3D,aAAa,SAAM,GAClB,SAAS,CAwFX;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE"}
|
package/dist/watcher.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import chokidar from 'chokidar';
|
|
2
|
+
/**
|
|
3
|
+
* Default file extensions to watch.
|
|
4
|
+
*/
|
|
5
|
+
const DEFAULT_FILE_EXTENSIONS = ['.md'];
|
|
6
|
+
/**
|
|
7
|
+
* Check if a file path matches any of the given extensions.
|
|
8
|
+
*/
|
|
9
|
+
function matchesExtension(filePath, extensions) {
|
|
10
|
+
return extensions.some((ext) => filePath.endsWith(ext));
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Start a file watcher for specified file types.
|
|
14
|
+
*
|
|
15
|
+
* @param watchPaths - Path(s) to watch (file or directory, single or array)
|
|
16
|
+
* @param onChange - Callback when file changes (path, event)
|
|
17
|
+
* @param fileExtensions - File extensions to watch (e.g., ['.md', '.jsx', '.tsx'])
|
|
18
|
+
* @param ignorePatterns - Patterns to ignore (e.g., ['.git', 'node_modules'])
|
|
19
|
+
* @param debounceDelay - Debounce delay in milliseconds (default: 200ms)
|
|
20
|
+
* @returns Chokidar watcher instance
|
|
21
|
+
*/
|
|
22
|
+
export function startWatcher(watchPaths, onChange, fileExtensions = DEFAULT_FILE_EXTENSIONS, ignorePatterns = ['.git', 'node_modules', '.tmp'], debounceDelay = 200) {
|
|
23
|
+
// Build ignore patterns for Chokidar
|
|
24
|
+
const ignored = ignorePatterns.map((pattern) => {
|
|
25
|
+
// Convert simple patterns to glob patterns
|
|
26
|
+
if (pattern.includes('*')) {
|
|
27
|
+
return pattern;
|
|
28
|
+
}
|
|
29
|
+
// Match directories and files with this name
|
|
30
|
+
return `**/${pattern}/**`;
|
|
31
|
+
});
|
|
32
|
+
// Build complete ignore patterns
|
|
33
|
+
const allIgnored = [
|
|
34
|
+
...ignored,
|
|
35
|
+
/(^|[/\\])\../, // Ignore dotfiles
|
|
36
|
+
];
|
|
37
|
+
// Watch the directory (or file if it's a single file)
|
|
38
|
+
const watcher = chokidar.watch(watchPaths, {
|
|
39
|
+
ignored: allIgnored,
|
|
40
|
+
persistent: true,
|
|
41
|
+
ignoreInitial: false,
|
|
42
|
+
awaitWriteFinish: {
|
|
43
|
+
stabilityThreshold: 100,
|
|
44
|
+
pollInterval: 100,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
// Debounce map to track pending callbacks
|
|
48
|
+
const debounceMap = new Map();
|
|
49
|
+
const debouncedOnChange = (path, event) => {
|
|
50
|
+
// Clear existing timeout for this path
|
|
51
|
+
const existing = debounceMap.get(path);
|
|
52
|
+
if (existing) {
|
|
53
|
+
clearTimeout(existing);
|
|
54
|
+
}
|
|
55
|
+
// Set new timeout
|
|
56
|
+
const timeout = setTimeout(async () => {
|
|
57
|
+
debounceMap.delete(path);
|
|
58
|
+
try {
|
|
59
|
+
await onChange(path, event);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
// Log error but don't throw (watcher should continue)
|
|
63
|
+
console.error(`Error in onChange callback for ${path}:`, error);
|
|
64
|
+
}
|
|
65
|
+
}, debounceDelay);
|
|
66
|
+
debounceMap.set(path, timeout);
|
|
67
|
+
};
|
|
68
|
+
// Watch for file additions (only files with matching extensions)
|
|
69
|
+
watcher.on('add', (path) => {
|
|
70
|
+
if (matchesExtension(path, fileExtensions)) {
|
|
71
|
+
debouncedOnChange(path, 'add');
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
// Watch for file changes (only files with matching extensions)
|
|
75
|
+
watcher.on('change', (path) => {
|
|
76
|
+
if (matchesExtension(path, fileExtensions)) {
|
|
77
|
+
debouncedOnChange(path, 'change');
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
// Watch for file deletions (only files with matching extensions)
|
|
81
|
+
watcher.on('unlink', (path) => {
|
|
82
|
+
if (matchesExtension(path, fileExtensions)) {
|
|
83
|
+
// Clear any pending debounce for this path
|
|
84
|
+
const existing = debounceMap.get(path);
|
|
85
|
+
if (existing) {
|
|
86
|
+
clearTimeout(existing);
|
|
87
|
+
debounceMap.delete(path);
|
|
88
|
+
}
|
|
89
|
+
// Handle deletion immediately (no debounce needed)
|
|
90
|
+
onChange(path, 'unlink').catch((error) => {
|
|
91
|
+
console.error(`Error handling file deletion for ${path}:`, error);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
// Handle errors
|
|
96
|
+
watcher.on('error', (error) => {
|
|
97
|
+
console.error('Watcher error:', error);
|
|
98
|
+
});
|
|
99
|
+
return watcher;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Stop a file watcher.
|
|
103
|
+
*
|
|
104
|
+
* @param watcher - Chokidar watcher instance
|
|
105
|
+
*/
|
|
106
|
+
export async function stopWatcher(watcher) {
|
|
107
|
+
await watcher.close();
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sudosandwich/limps",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Local Intelligent MCP Planning Server - AI agent plan management and coordination",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"limps": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "vitest run",
|
|
12
|
+
"test:watch": "vitest",
|
|
13
|
+
"test:coverage": "vitest run --coverage",
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsc --watch",
|
|
16
|
+
"lint": "eslint src/ tests/",
|
|
17
|
+
"lint:fix": "eslint src/ tests/ --fix",
|
|
18
|
+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
19
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
20
|
+
"prepare": "husky"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"mcp",
|
|
24
|
+
"model-context-protocol",
|
|
25
|
+
"planning",
|
|
26
|
+
"document-management",
|
|
27
|
+
"ai",
|
|
28
|
+
"cursor",
|
|
29
|
+
"claude",
|
|
30
|
+
"anthropic",
|
|
31
|
+
"ai-agent",
|
|
32
|
+
"local-first",
|
|
33
|
+
"llm",
|
|
34
|
+
"mcp-server",
|
|
35
|
+
"rlm",
|
|
36
|
+
"recursive-language-model"
|
|
37
|
+
],
|
|
38
|
+
"author": "Paul Breuler",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/paulbreuler/mcp-planning-server.git"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"README.md",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
],
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@modelcontextprotocol/sdk": "^1.22.0",
|
|
51
|
+
"better-sqlite3": "^11.7.0",
|
|
52
|
+
"chokidar": "^4.0.3",
|
|
53
|
+
"micromatch": "^4.0.8",
|
|
54
|
+
"open": "^10.2.0",
|
|
55
|
+
"quickjs-emscripten": "^0.31.0",
|
|
56
|
+
"which": "^4.0.0",
|
|
57
|
+
"yaml": "^2.7.0",
|
|
58
|
+
"zod": "^3.23.8"
|
|
59
|
+
},
|
|
60
|
+
"lint-staged": {
|
|
61
|
+
"src/**/*.ts": [
|
|
62
|
+
"prettier --write",
|
|
63
|
+
"eslint --fix"
|
|
64
|
+
],
|
|
65
|
+
"tests/**/*.ts": [
|
|
66
|
+
"prettier --write",
|
|
67
|
+
"eslint --fix"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@eslint/js": "^9.39.2",
|
|
72
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
73
|
+
"@types/micromatch": "^4.0.10",
|
|
74
|
+
"@types/node": "^25.0.9",
|
|
75
|
+
"@types/which": "^3.0.4",
|
|
76
|
+
"@vitest/coverage-v8": "^4.0.17",
|
|
77
|
+
"eslint": "^9.39.2",
|
|
78
|
+
"husky": "^9.1.7",
|
|
79
|
+
"lint-staged": "^16.2.7",
|
|
80
|
+
"prettier": "^3.8.0",
|
|
81
|
+
"typescript": "^5.9.3",
|
|
82
|
+
"typescript-eslint": "^8.53.1",
|
|
83
|
+
"vitest": "^4.0.17"
|
|
84
|
+
}
|
|
85
|
+
}
|