feat(infra): port tool system ke TypeScript (37 tools + registry + executor)
Fase 3b rewrite Zesdex dari Rust ke TypeScript/Bun: - Tool interface, ToolCtx + ToolCtxBuilder, InfrastructureToolExecutor - Registry: allTools (37 tool), toolDefs, toolIsRisky, toolIsParallelSafe - FS tools: read, write, edit, delete - Search: grep, glob (glob matcher ringan) - Shell: bash (timeout + timeout_spawn), bash_output, bash_kill - Git: git_operator, git_worktree, git_cred + checkGitDestructive, checkCredentialRead - Memory: remember, forget, recall via MarkdownMemoryRepository - Utilitas: cd, dir_list, dir_cache_update, pong, todowrite, todofinish - Best-practice: best_practice, commit_convention + BestPracticeEngine - Web search (async fetch ke SearXNG), semantic_search/rebuild_index/list_symbols - Workflow/spawn/parallel_delegate (delegasi ke engine 3c/3d dengan placeholder) - Graduated checks + resolve_path sandbox (anti path-escape) - 16 test tool system (registry, guards, resolve_path, fs roundtrip) 54 test hijau (38 lama + 16 baru), tsc strict bersih.
This commit is contained in:
1 parent
a2c7e5d44c
commit
82b51f7921
47 files changed
+3277
-2
No files matched your search
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Background bash process output and kill tools.
|
||||
* Mirrors `tools/bash_tools.rs`.
|
||||
*/
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import type { JsonValue } from "@zesdex/domain";
|
||||
import { type Tool, type ToolCtx } from "./mod.ts";
|
||||
import { argStr } from "./util.ts";
|
||||
|
||||
/** Get the output of a background bash job by ID. */
|
||||
export class BashOutput implements Tool {
|
||||
name = "bash_output";
|
||||
description = "Get the output of a background bash job by ID";
|
||||
|
||||
parameters = {
|
||||
type: "object",
|
||||
properties: {
|
||||
job_id: { type: "string", description: "Background job ID" },
|
||||
},
|
||||
required: ["job_id"],
|
||||
};
|
||||
|
||||
run(ctx: ToolCtx, args: JsonValue): string {
|
||||
const jobId = argStr(args, "job_id");
|
||||
|
||||
// Prevent path traversal
|
||||
if (jobId.includes("/") || jobId.includes("\\") || jobId.includes("..")) {
|
||||
throw new Error(`invalid job_id '${jobId}': must not contain path separators`);
|
||||
}
|
||||
|
||||
const outputDir = path.join(ctx.sessionDir, "bash-outputs");
|
||||
const outputFile = path.join(outputDir, jobId);
|
||||
|
||||
if (fs.existsSync(outputFile)) {
|
||||
try {
|
||||
const content = fs.readFileSync(outputFile, "utf8");
|
||||
return `Output for job '${jobId}':\n${content}`;
|
||||
} catch (e) {
|
||||
return `Error reading output: ${(e as Error).message}`;
|
||||
}
|
||||
}
|
||||
return `No output found for job '${jobId}'. The job may still be running.`;
|
||||
}
|
||||
}
|
||||
|
||||
/** Kill a background bash job by ID. */
|
||||
export class BashKill implements Tool {
|
||||
name = "bash_kill";
|
||||
description = "Kill a background bash job by ID";
|
||||
|
||||
parameters = {
|
||||
type: "object",
|
||||
properties: {
|
||||
job_id: { type: "string", description: "Background job ID to kill" },
|
||||
},
|
||||
required: ["job_id"],
|
||||
};
|
||||
|
||||
run(_ctx: ToolCtx, args: JsonValue): string {
|
||||
const jobId = argStr(args, "job_id");
|
||||
// Background job control is a global registry — not yet ported (bgbash 3g).
|
||||
throw new Error(`no active background job found with ID '${jobId}'`);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user