@octocodeai/octocode-engine 16.5.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/README.md +558 -0
- package/dist/lsp/client.d.ts +28 -0
- package/dist/lsp/client.js +98 -0
- package/dist/lsp/config.d.ts +3 -0
- package/dist/lsp/config.js +7 -0
- package/dist/lsp/evidence.d.ts +4 -0
- package/dist/lsp/evidence.js +28 -0
- package/dist/lsp/index.d.ts +7 -0
- package/dist/lsp/index.js +6 -0
- package/dist/lsp/initConstants.d.ts +4 -0
- package/dist/lsp/initConstants.js +27 -0
- package/dist/lsp/lspClientPool.d.ts +27 -0
- package/dist/lsp/lspClientPool.js +87 -0
- package/dist/lsp/lspErrorCodes.d.ts +12 -0
- package/dist/lsp/lspErrorCodes.js +12 -0
- package/dist/lsp/manager.d.ts +23 -0
- package/dist/lsp/manager.js +94 -0
- package/dist/lsp/native.d.ts +35 -0
- package/dist/lsp/native.js +3 -0
- package/dist/lsp/resolver.d.ts +26 -0
- package/dist/lsp/resolver.js +73 -0
- package/dist/lsp/schemas.d.ts +9 -0
- package/dist/lsp/schemas.js +30 -0
- package/dist/lsp/types.d.ts +85 -0
- package/dist/lsp/types.js +1 -0
- package/dist/lsp/uri.d.ts +15 -0
- package/dist/lsp/uri.js +24 -0
- package/dist/lsp/validation.d.ts +6 -0
- package/dist/lsp/validation.js +23 -0
- package/dist/lsp/workspaceRoot.d.ts +2 -0
- package/dist/lsp/workspaceRoot.js +7 -0
- package/dist/security/commandUtils.d.ts +1 -0
- package/dist/security/commandUtils.js +7 -0
- package/dist/security/commandValidator.d.ts +7 -0
- package/dist/security/commandValidator.js +472 -0
- package/dist/security/contentSanitizer.d.ts +2 -0
- package/dist/security/contentSanitizer.js +181 -0
- package/dist/security/filePatterns.d.ts +1 -0
- package/dist/security/filePatterns.js +209 -0
- package/dist/security/ignoredPathFilter.d.ts +3 -0
- package/dist/security/ignoredPathFilter.js +72 -0
- package/dist/security/index.d.ts +16 -0
- package/dist/security/index.js +13 -0
- package/dist/security/mask.d.ts +1 -0
- package/dist/security/mask.js +49 -0
- package/dist/security/maskUtils.d.ts +1 -0
- package/dist/security/maskUtils.js +7 -0
- package/dist/security/native.d.ts +9 -0
- package/dist/security/native.js +161 -0
- package/dist/security/paramExtractors.d.ts +7 -0
- package/dist/security/paramExtractors.js +75 -0
- package/dist/security/pathPatterns.d.ts +1 -0
- package/dist/security/pathPatterns.js +26 -0
- package/dist/security/pathUtils.d.ts +1 -0
- package/dist/security/pathUtils.js +37 -0
- package/dist/security/pathValidator.d.ts +22 -0
- package/dist/security/pathValidator.js +229 -0
- package/dist/security/regexes/ai-providers.d.ts +2 -0
- package/dist/security/regexes/ai-providers.js +177 -0
- package/dist/security/regexes/analytics.d.ts +2 -0
- package/dist/security/regexes/analytics.js +50 -0
- package/dist/security/regexes/auth-crypto.d.ts +6 -0
- package/dist/security/regexes/auth-crypto.js +255 -0
- package/dist/security/regexes/aws.d.ts +2 -0
- package/dist/security/regexes/aws.js +68 -0
- package/dist/security/regexes/cloudProviders.d.ts +2 -0
- package/dist/security/regexes/cloudProviders.js +328 -0
- package/dist/security/regexes/communications.d.ts +4 -0
- package/dist/security/regexes/communications.js +260 -0
- package/dist/security/regexes/databases.d.ts +2 -0
- package/dist/security/regexes/databases.js +135 -0
- package/dist/security/regexes/devTools.d.ts +2 -0
- package/dist/security/regexes/devTools.js +236 -0
- package/dist/security/regexes/index.d.ts +3 -0
- package/dist/security/regexes/index.js +31 -0
- package/dist/security/regexes/monitoring.d.ts +2 -0
- package/dist/security/regexes/monitoring.js +92 -0
- package/dist/security/regexes/payments-commerce.d.ts +3 -0
- package/dist/security/regexes/payments-commerce.js +197 -0
- package/dist/security/regexes/types.d.ts +2 -0
- package/dist/security/regexes/types.js +1 -0
- package/dist/security/regexes/vcs.d.ts +2 -0
- package/dist/security/regexes/vcs.js +105 -0
- package/dist/security/registry.d.ts +48 -0
- package/dist/security/registry.js +156 -0
- package/dist/security/securityConstants.d.ts +3 -0
- package/dist/security/securityConstants.js +12 -0
- package/dist/security/types.d.ts +35 -0
- package/dist/security/types.js +1 -0
- package/dist/security/withSecurityValidation.d.ts +21 -0
- package/dist/security/withSecurityValidation.js +107 -0
- package/index.cjs +97 -0
- package/index.d.ts +934 -0
- package/index.js +652 -0
- package/package.json +311 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { ContentSanitizer } from './contentSanitizer.js';
|
|
2
|
+
import { extractResearchFields, extractRepoOwnerFromParams, } from './paramExtractors.js';
|
|
3
|
+
const SECURITY_VALIDATION_FAILED_CODE = 'TOOL_SECURITY_VALIDATION_FAILED';
|
|
4
|
+
const DEFAULT_TOOL_TIMEOUT_MS = 60_000;
|
|
5
|
+
let _deps = {};
|
|
6
|
+
function getSanitizer() {
|
|
7
|
+
return _deps.sanitizer ?? ContentSanitizer;
|
|
8
|
+
}
|
|
9
|
+
function getTimeoutMs(override) {
|
|
10
|
+
return override ?? _deps.defaultTimeoutMs ?? DEFAULT_TOOL_TIMEOUT_MS;
|
|
11
|
+
}
|
|
12
|
+
export function configureSecurity(deps) {
|
|
13
|
+
_deps = { ..._deps, ...deps };
|
|
14
|
+
}
|
|
15
|
+
function createErrorResult(text) {
|
|
16
|
+
return { content: [{ type: 'text', text }], isError: true };
|
|
17
|
+
}
|
|
18
|
+
function withToolTimeout(toolName, promise, signal, timeoutMs) {
|
|
19
|
+
const timeout = getTimeoutMs(timeoutMs);
|
|
20
|
+
if (signal?.aborted) {
|
|
21
|
+
return Promise.resolve(createErrorResult(`Tool '${toolName}' was cancelled before execution.`));
|
|
22
|
+
}
|
|
23
|
+
return new Promise(resolve => {
|
|
24
|
+
const timer = setTimeout(() => {
|
|
25
|
+
resolve(createErrorResult(`Tool '${toolName}' timed out after ${timeout / 1000}s. Try reducing query complexity or scope.`));
|
|
26
|
+
}, timeout);
|
|
27
|
+
const onAbort = () => {
|
|
28
|
+
clearTimeout(timer);
|
|
29
|
+
resolve(createErrorResult(`Tool '${toolName}' was cancelled by the client.`));
|
|
30
|
+
};
|
|
31
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
32
|
+
if (signal?.aborted) {
|
|
33
|
+
clearTimeout(timer);
|
|
34
|
+
signal.removeEventListener('abort', onAbort);
|
|
35
|
+
resolve(createErrorResult(`Tool '${toolName}' was cancelled before execution.`));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
promise
|
|
39
|
+
.then(result => {
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
signal?.removeEventListener('abort', onAbort);
|
|
42
|
+
resolve(result);
|
|
43
|
+
})
|
|
44
|
+
.catch(error => {
|
|
45
|
+
clearTimeout(timer);
|
|
46
|
+
signal?.removeEventListener('abort', onAbort);
|
|
47
|
+
resolve(createErrorResult(`Tool '${toolName}' failed: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async function runSecure(opts) {
|
|
52
|
+
const { toolName, handler, args, authInfo, sessionId, signal, timeoutMs } = opts;
|
|
53
|
+
try {
|
|
54
|
+
const sanitizer = getSanitizer();
|
|
55
|
+
const validation = sanitizer.validateInputParameters(args);
|
|
56
|
+
if (!validation.isValid) {
|
|
57
|
+
return createErrorResult(`Security validation failed: ${validation.warnings.join('; ')}`);
|
|
58
|
+
}
|
|
59
|
+
const sanitizedParams = validation.sanitizedParams;
|
|
60
|
+
const rawResult = await withToolTimeout(toolName, handler(sanitizedParams, authInfo, sessionId), signal, timeoutMs);
|
|
61
|
+
if (!rawResult.isError && _deps.isLoggingEnabled?.()) {
|
|
62
|
+
handleBulk(toolName, sanitizedParams);
|
|
63
|
+
}
|
|
64
|
+
return rawResult;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
_deps
|
|
68
|
+
.logSessionError?.(toolName, SECURITY_VALIDATION_FAILED_CODE)
|
|
69
|
+
.catch(() => { });
|
|
70
|
+
return createErrorResult(`Security validation error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export function withSecurityValidation(toolName, toolHandler, options) {
|
|
74
|
+
return (args, { authInfo, sessionId, signal, } = {}) => runSecure({
|
|
75
|
+
toolName,
|
|
76
|
+
handler: toolHandler,
|
|
77
|
+
args,
|
|
78
|
+
authInfo,
|
|
79
|
+
sessionId,
|
|
80
|
+
signal,
|
|
81
|
+
timeoutMs: options?.timeoutMs,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
export function withBasicSecurityValidation(toolHandler, toolName, options) {
|
|
85
|
+
const handler = (sanitizedArgs) => toolHandler(sanitizedArgs);
|
|
86
|
+
const effectiveName = toolName ?? 'tool';
|
|
87
|
+
return (args, extra) => runSecure({
|
|
88
|
+
toolName: effectiveName,
|
|
89
|
+
handler,
|
|
90
|
+
args,
|
|
91
|
+
signal: extra?.signal,
|
|
92
|
+
timeoutMs: options?.timeoutMs,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function handleBulk(toolName, params) {
|
|
96
|
+
const queries = params.queries;
|
|
97
|
+
const items = queries && Array.isArray(queries) && queries.length > 0
|
|
98
|
+
? queries
|
|
99
|
+
: [params];
|
|
100
|
+
for (const item of items) {
|
|
101
|
+
const repos = extractRepoOwnerFromParams(item);
|
|
102
|
+
const fields = extractResearchFields(item);
|
|
103
|
+
_deps
|
|
104
|
+
.logToolCall?.(toolName, repos, fields.mainResearchGoal, fields.researchGoal, fields.reasoning)
|
|
105
|
+
.catch(() => { });
|
|
106
|
+
}
|
|
107
|
+
}
|
package/index.cjs
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { existsSync } = require('fs')
|
|
4
|
+
const { join } = require('path')
|
|
5
|
+
|
|
6
|
+
const packageName = '@octocodeai/octocode-engine'
|
|
7
|
+
const binaryName = 'octocode-engine'
|
|
8
|
+
const { platform, arch } = process
|
|
9
|
+
|
|
10
|
+
const { readFileSync } = require('fs')
|
|
11
|
+
|
|
12
|
+
const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
|
|
13
|
+
|
|
14
|
+
function isMuslFromFilesystem() {
|
|
15
|
+
try {
|
|
16
|
+
return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
|
|
17
|
+
} catch {
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isMuslFromReport() {
|
|
23
|
+
let report = null
|
|
24
|
+
if (typeof process.report?.getReport === 'function') {
|
|
25
|
+
process.report.excludeNetwork = true
|
|
26
|
+
report = process.report.getReport()
|
|
27
|
+
}
|
|
28
|
+
if (!report) return null
|
|
29
|
+
if (report.header && report.header.glibcVersionRuntime) return false
|
|
30
|
+
if (Array.isArray(report.sharedObjects)) {
|
|
31
|
+
if (report.sharedObjects.some(isFileMusl)) return true
|
|
32
|
+
}
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function isMuslFromChildProcess() {
|
|
37
|
+
try {
|
|
38
|
+
return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
|
|
39
|
+
} catch {
|
|
40
|
+
return false
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function isMusl() {
|
|
45
|
+
if (process.platform !== 'linux') return false
|
|
46
|
+
let result = isMuslFromFilesystem()
|
|
47
|
+
if (result === null) result = isMuslFromReport()
|
|
48
|
+
if (result === null) result = isMuslFromChildProcess()
|
|
49
|
+
return !!result
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getPlatformKey() {
|
|
53
|
+
if (platform === 'darwin') {
|
|
54
|
+
if (arch === 'arm64') return 'darwin-arm64'
|
|
55
|
+
if (arch === 'x64') return 'darwin-x64'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (platform === 'linux') {
|
|
59
|
+
const libc = isMusl() ? 'musl' : 'gnu'
|
|
60
|
+
if (arch === 'x64') return `linux-x64-${libc}`
|
|
61
|
+
if (arch === 'arm64' && libc === 'gnu') return 'linux-arm64-gnu'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (platform === 'win32' && arch === 'x64') return 'win32-x64-msvc'
|
|
65
|
+
|
|
66
|
+
throw new Error(`${packageName} does not ship a native binary for ${platform}-${arch}`)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function loadNativeBinding() {
|
|
70
|
+
const key = getPlatformKey()
|
|
71
|
+
const candidates = [
|
|
72
|
+
join(__dirname, `${binaryName}.${key}.node`),
|
|
73
|
+
join(__dirname, 'runtime', 'engine', `${binaryName}.${key}.node`),
|
|
74
|
+
join(__dirname, '..', 'runtime', 'engine', `${binaryName}.${key}.node`),
|
|
75
|
+
join(__dirname, '..', '..', 'runtime', 'engine', `${binaryName}.${key}.node`),
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
for (const candidate of candidates) {
|
|
79
|
+
if (existsSync(candidate)) {
|
|
80
|
+
return require(candidate)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return require(`${packageName}-${key}`)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const nativeBinding = loadNativeBinding()
|
|
88
|
+
|
|
89
|
+
nativeBinding.MINIFY_CONFIG = nativeBinding.getMINIFY_CONFIG()
|
|
90
|
+
nativeBinding.SUPPORTED_SIGNATURE_EXTENSIONS = Object.freeze(
|
|
91
|
+
nativeBinding.getSupportedSignatureExtensions().sort()
|
|
92
|
+
)
|
|
93
|
+
nativeBinding.SUPPORTED_STRUCTURAL_EXTENSIONS = Object.freeze(
|
|
94
|
+
nativeBinding.getSupportedStructuralExtensions().sort()
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
module.exports = nativeBinding
|