@cjhyy/code-shell-capability-coding 0.8.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 +69 -0
- package/THIRD_PARTY_NOTICES.md +206 -0
- package/dist/bin/agent-server-stdio.d.ts +1 -0
- package/dist/bin/agent-server-stdio.js +4 -0
- package/dist/capability-runtime.d.ts +22 -0
- package/dist/capability-runtime.js +88 -0
- package/dist/cc-orchestrator/agent-adapter.d.ts +55 -0
- package/dist/cc-orchestrator/agent-adapter.js +143 -0
- package/dist/cc-orchestrator/cc-capability.d.ts +20 -0
- package/dist/cc-orchestrator/cc-capability.js +57 -0
- package/dist/cc-orchestrator/codex-session-discovery.d.ts +45 -0
- package/dist/cc-orchestrator/codex-session-discovery.js +251 -0
- package/dist/cc-orchestrator/codex-session-history.d.ts +39 -0
- package/dist/cc-orchestrator/codex-session-history.js +249 -0
- package/dist/cc-orchestrator/codex-user-text.d.ts +9 -0
- package/dist/cc-orchestrator/codex-user-text.js +25 -0
- package/dist/cc-orchestrator/external-agent-bindings.d.ts +27 -0
- package/dist/cc-orchestrator/external-agent-bindings.js +150 -0
- package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
- package/dist/cc-orchestrator/external-agent-changes.js +231 -0
- package/dist/cc-orchestrator/external-agent-driver.d.ts +19 -0
- package/dist/cc-orchestrator/external-agent-driver.js +284 -0
- package/dist/cc-orchestrator/external-agent-session-store.d.ts +36 -0
- package/dist/cc-orchestrator/external-agent-session-store.js +185 -0
- package/dist/cc-orchestrator/index.d.ts +10 -0
- package/dist/cc-orchestrator/index.js +10 -0
- package/dist/cc-orchestrator/related-session-discovery.d.ts +21 -0
- package/dist/cc-orchestrator/related-session-discovery.js +77 -0
- package/dist/cc-orchestrator/relevance-judge.d.ts +16 -0
- package/dist/cc-orchestrator/relevance-judge.js +38 -0
- package/dist/cc-orchestrator/session-discovery.d.ts +99 -0
- package/dist/cc-orchestrator/session-discovery.js +295 -0
- package/dist/cc-orchestrator/session-history.d.ts +55 -0
- package/dist/cc-orchestrator/session-history.js +150 -0
- package/dist/external-agents/config.d.ts +3 -0
- package/dist/external-agents/config.js +16 -0
- package/dist/external-agents/types.d.ts +32 -0
- package/dist/external-agents/types.js +1 -0
- package/dist/external-runtimes/claude-code/event-translator.d.ts +54 -0
- package/dist/external-runtimes/claude-code/event-translator.js +201 -0
- package/dist/external-runtimes/claude-code/mcp-config.d.ts +84 -0
- package/dist/external-runtimes/claude-code/mcp-config.js +175 -0
- package/dist/external-runtimes/claude-code/runtime.d.ts +56 -0
- package/dist/external-runtimes/claude-code/runtime.js +168 -0
- package/dist/external-runtimes/codex/app-server-client.d.ts +66 -0
- package/dist/external-runtimes/codex/app-server-client.js +244 -0
- package/dist/external-runtimes/codex/event-translator.d.ts +68 -0
- package/dist/external-runtimes/codex/event-translator.js +187 -0
- package/dist/external-runtimes/codex/index.d.ts +7 -0
- package/dist/external-runtimes/codex/index.js +6 -0
- package/dist/external-runtimes/codex/runtime.d.ts +128 -0
- package/dist/external-runtimes/codex/runtime.js +216 -0
- package/dist/external-runtimes/index.d.ts +37 -0
- package/dist/external-runtimes/index.js +27 -0
- package/dist/external-runtimes/session-factory.d.ts +97 -0
- package/dist/external-runtimes/session-factory.js +110 -0
- package/dist/external-runtimes/shared/mcp-bridge.d.ts +66 -0
- package/dist/external-runtimes/shared/mcp-bridge.js +365 -0
- package/dist/external-runtimes/shared/session-context-store.d.ts +83 -0
- package/dist/external-runtimes/shared/session-context-store.js +114 -0
- package/dist/external-runtimes/shared/spawn-env.d.ts +30 -0
- package/dist/external-runtimes/shared/spawn-env.js +41 -0
- package/dist/git/parse-log.d.ts +14 -0
- package/dist/git/parse-log.js +21 -0
- package/dist/git/utils.d.ts +49 -0
- package/dist/git/utils.js +161 -0
- package/dist/git/worktree/crud.d.ts +108 -0
- package/dist/git/worktree/crud.js +415 -0
- package/dist/git/worktree/diff.d.ts +14 -0
- package/dist/git/worktree/diff.js +83 -0
- package/dist/git/worktree/git-exec.d.ts +7 -0
- package/dist/git/worktree/git-exec.js +86 -0
- package/dist/git/worktree/index.d.ts +6 -0
- package/dist/git/worktree/index.js +6 -0
- package/dist/git/worktree/query.d.ts +43 -0
- package/dist/git/worktree/query.js +128 -0
- package/dist/git/worktree/slug.d.ts +12 -0
- package/dist/git/worktree/slug.js +59 -0
- package/dist/git/worktree.d.ts +1 -0
- package/dist/git/worktree.js +5 -0
- package/dist/index.capability.d.ts +7 -0
- package/dist/index.capability.js +190 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.git.d.ts +4 -0
- package/dist/index.git.js +4 -0
- package/dist/index.js +18 -0
- package/dist/index.orchestration.d.ts +7 -0
- package/dist/index.orchestration.js +5 -0
- package/dist/lsp/client.d.ts +41 -0
- package/dist/lsp/client.js +192 -0
- package/dist/lsp/manager.d.ts +53 -0
- package/dist/lsp/manager.js +248 -0
- package/dist/lsp/root-path.d.ts +9 -0
- package/dist/lsp/root-path.js +12 -0
- package/dist/lsp/servers.d.ts +16 -0
- package/dist/lsp/servers.js +60 -0
- package/dist/prompt/coding.md +42 -0
- package/dist/quota/credentials.d.ts +3 -0
- package/dist/quota/credentials.js +80 -0
- package/dist/quota/index.d.ts +36 -0
- package/dist/quota/index.js +161 -0
- package/dist/quota/types.d.ts +48 -0
- package/dist/quota/types.js +13 -0
- package/dist/review/review-prompt.d.ts +28 -0
- package/dist/review/review-prompt.js +81 -0
- package/dist/tools/apply-patch/LICENSE-codex +201 -0
- package/dist/tools/apply-patch/NOTICE.md +29 -0
- package/dist/tools/apply-patch/applier.d.ts +26 -0
- package/dist/tools/apply-patch/applier.js +306 -0
- package/dist/tools/apply-patch/backup-targets.d.ts +10 -0
- package/dist/tools/apply-patch/backup-targets.js +30 -0
- package/dist/tools/apply-patch/eol.d.ts +4 -0
- package/dist/tools/apply-patch/eol.js +9 -0
- package/dist/tools/apply-patch/index.d.ts +20 -0
- package/dist/tools/apply-patch/index.js +106 -0
- package/dist/tools/apply-patch/parser.d.ts +17 -0
- package/dist/tools/apply-patch/parser.js +209 -0
- package/dist/tools/apply-patch/seek-sequence.d.ts +18 -0
- package/dist/tools/apply-patch/seek-sequence.js +123 -0
- package/dist/tools/apply-patch/types.d.ts +49 -0
- package/dist/tools/apply-patch/types.js +13 -0
- package/dist/tools/brief.d.ts +6 -0
- package/dist/tools/brief.js +41 -0
- package/dist/tools/check-quota.d.ts +14 -0
- package/dist/tools/check-quota.js +38 -0
- package/dist/tools/drive-agent.d.ts +52 -0
- package/dist/tools/drive-agent.js +1184 -0
- package/dist/tools/lsp.d.ts +6 -0
- package/dist/tools/lsp.js +220 -0
- package/dist/tools/notebook-edit.d.ts +6 -0
- package/dist/tools/notebook-edit.js +127 -0
- package/dist/tools/worktree.d.ts +10 -0
- package/dist/tools/worktree.js +363 -0
- package/package.json +60 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { getWorktreeDiff } from "./diff.js";
|
|
4
|
+
import { execGit, gitOutput, normalizeBranchName } from "./git-exec.js";
|
|
5
|
+
import { isManagedWorktreeBranch } from "./slug.js";
|
|
6
|
+
/**
|
|
7
|
+
* Find the canonical git root (resolves worktree -> main repo).
|
|
8
|
+
*/
|
|
9
|
+
export async function findGitRoot(cwd, signal) {
|
|
10
|
+
return await findMainWorktreeRoot(cwd, signal);
|
|
11
|
+
}
|
|
12
|
+
export async function findMainWorktreeRoot(cwd, signal) {
|
|
13
|
+
const commonDir = (await execGit(cwd, ["rev-parse", "--path-format=absolute", "--git-common-dir"], 5000, signal)).trim();
|
|
14
|
+
return dirname(commonDir);
|
|
15
|
+
}
|
|
16
|
+
export async function findWorktreeForBranch(cwd, branch, signal) {
|
|
17
|
+
const normalized = normalizeBranchName(branch);
|
|
18
|
+
return (await listWorktreesFast(cwd, { signal })).find((entry) => entry.branch === normalized)
|
|
19
|
+
?.path;
|
|
20
|
+
}
|
|
21
|
+
export async function assertBranchNotCheckedOut(cwd, branch, signal) {
|
|
22
|
+
const existingPath = await findWorktreeForBranch(cwd, branch, signal);
|
|
23
|
+
if (existingPath) {
|
|
24
|
+
throw new Error(`branch ${normalizeBranchName(branch)} already checked out at ${existingPath}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export async function branchExists(cwd, branch, signal) {
|
|
28
|
+
const out = await gitOutput(cwd, ["branch", "--list", normalizeBranchName(branch)], 10000, signal);
|
|
29
|
+
return (out?.trim().length ?? 0) > 0;
|
|
30
|
+
}
|
|
31
|
+
export async function isGitWorktreeRoot(cwd, signal) {
|
|
32
|
+
if (!existsSync(join(cwd, ".git")))
|
|
33
|
+
return false;
|
|
34
|
+
try {
|
|
35
|
+
const inside = (await execGit(cwd, ["rev-parse", "--is-inside-work-tree"], 5000, signal)).trim();
|
|
36
|
+
if (inside !== "true")
|
|
37
|
+
return false;
|
|
38
|
+
const topLevel = (await execGit(cwd, ["rev-parse", "--path-format=absolute", "--show-toplevel"], 5000, signal)).trim();
|
|
39
|
+
return resolve(topLevel) === resolve(cwd);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (signal?.aborted)
|
|
43
|
+
throw error;
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function currentBranch(cwd, signal) {
|
|
48
|
+
const branch = (await gitOutput(cwd, ["branch", "--show-current"], 5000, signal))?.trim();
|
|
49
|
+
return branch || undefined;
|
|
50
|
+
}
|
|
51
|
+
export async function listWorktreesFast(cwd, opts = {}) {
|
|
52
|
+
let raw;
|
|
53
|
+
try {
|
|
54
|
+
raw = (await execGit(cwd, ["worktree", "list", "--porcelain"], 10000, opts.signal)).trim();
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (opts.signal?.aborted)
|
|
58
|
+
throw error;
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
if (!raw)
|
|
62
|
+
return [];
|
|
63
|
+
const entries = [];
|
|
64
|
+
let current = { path: "", branch: "", head: "" };
|
|
65
|
+
for (const line of raw.split("\n")) {
|
|
66
|
+
if (line.startsWith("worktree ")) {
|
|
67
|
+
if (current.path)
|
|
68
|
+
entries.push(current);
|
|
69
|
+
current = { path: line.slice(9), branch: "", head: "" };
|
|
70
|
+
}
|
|
71
|
+
else if (line.startsWith("HEAD ")) {
|
|
72
|
+
current.head = line.slice(5, 13);
|
|
73
|
+
}
|
|
74
|
+
else if (line.startsWith("branch ")) {
|
|
75
|
+
current.branch = normalizeBranchName(line.slice(7));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (current.path)
|
|
79
|
+
entries.push(current);
|
|
80
|
+
let mainRoot = "";
|
|
81
|
+
try {
|
|
82
|
+
mainRoot = await findMainWorktreeRoot(cwd, opts.signal);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
if (opts.signal?.aborted)
|
|
86
|
+
throw error;
|
|
87
|
+
mainRoot = entries[0]?.path ?? "";
|
|
88
|
+
}
|
|
89
|
+
const owners = opts.workspaceOwners ?? opts.owners ?? [];
|
|
90
|
+
return entries.map((entry) => {
|
|
91
|
+
const ownerIds = ownersForWorktree(entry.path, owners);
|
|
92
|
+
return {
|
|
93
|
+
...entry,
|
|
94
|
+
...(mainRoot ? { isMain: resolve(entry.path) === resolve(mainRoot) } : {}),
|
|
95
|
+
isManaged: Boolean(entry.branch) && isManagedWorktreeBranch(entry.branch, opts.prefix),
|
|
96
|
+
...(ownerIds.length > 0
|
|
97
|
+
? {
|
|
98
|
+
occupiedBySessionIds: ownerIds,
|
|
99
|
+
occupiedByOtherSession: ownerIds.some((id) => id !== opts.currentSessionId),
|
|
100
|
+
}
|
|
101
|
+
: {}),
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* List active worktrees. Kept for internal/test compatibility; use
|
|
107
|
+
* listWorktreesFast for UI lists that should not block on diff work.
|
|
108
|
+
*/
|
|
109
|
+
export async function listWorktrees(cwd, opts = {}) {
|
|
110
|
+
const entries = await listWorktreesFast(cwd, opts);
|
|
111
|
+
if (!opts.includeDiffSummary)
|
|
112
|
+
return entries;
|
|
113
|
+
return Promise.all(entries.map(async (entry) => ({
|
|
114
|
+
...entry,
|
|
115
|
+
diff: await getWorktreeDiff(entry.path),
|
|
116
|
+
})));
|
|
117
|
+
}
|
|
118
|
+
export function ownersForWorktree(path, owners) {
|
|
119
|
+
const target = resolve(path);
|
|
120
|
+
return owners
|
|
121
|
+
.filter((owner) => {
|
|
122
|
+
const workspace = owner.workspace;
|
|
123
|
+
if (!workspace)
|
|
124
|
+
return false;
|
|
125
|
+
return resolve(workspace.root) === target;
|
|
126
|
+
})
|
|
127
|
+
.map((owner) => owner.sessionId);
|
|
128
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Default branch namespace for coding worktrees. */
|
|
2
|
+
export declare const DEFAULT_WORKTREE_BRANCH_PREFIX = "worktree/";
|
|
3
|
+
export declare const HISTORICAL_WORKTREE_BRANCH_PREFIX = "worktree/";
|
|
4
|
+
/**
|
|
5
|
+
* Validate worktree slug to prevent path traversal attacks.
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateWorktreeSlug(slug: string): void;
|
|
8
|
+
export declare function normalizeWorktreeBranchPrefix(prefix?: string | undefined): string;
|
|
9
|
+
export declare function isValidWorktreeBranchPrefix(prefix: string): boolean;
|
|
10
|
+
export declare function applyPrefix(prefix: string | undefined, slug: string, sessionId: string): string;
|
|
11
|
+
export declare function managedBranchPrefixes(prefix?: string): string[];
|
|
12
|
+
export declare function isManagedWorktreeBranch(branch: string, prefix?: string): boolean;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Default branch namespace for coding worktrees. */
|
|
2
|
+
export const DEFAULT_WORKTREE_BRANCH_PREFIX = "worktree/";
|
|
3
|
+
export const HISTORICAL_WORKTREE_BRANCH_PREFIX = "worktree/";
|
|
4
|
+
/**
|
|
5
|
+
* Validate worktree slug to prevent path traversal attacks.
|
|
6
|
+
*/
|
|
7
|
+
export function validateWorktreeSlug(slug) {
|
|
8
|
+
if (slug.trim().length === 0)
|
|
9
|
+
throw new Error("Worktree slug cannot be empty");
|
|
10
|
+
if (slug.length > 64)
|
|
11
|
+
throw new Error("Worktree slug too long (max 64 chars)");
|
|
12
|
+
if (/[^a-zA-Z0-9._-]/.test(slug))
|
|
13
|
+
throw new Error("Worktree slug contains invalid characters");
|
|
14
|
+
if (slug.startsWith(".") || slug.includes(".."))
|
|
15
|
+
throw new Error("Worktree slug cannot start with '.' or contain '..'");
|
|
16
|
+
}
|
|
17
|
+
export function normalizeWorktreeBranchPrefix(prefix = DEFAULT_WORKTREE_BRANCH_PREFIX) {
|
|
18
|
+
const raw = (prefix ?? DEFAULT_WORKTREE_BRANCH_PREFIX).trim();
|
|
19
|
+
if (!isValidWorktreeBranchPrefix(raw)) {
|
|
20
|
+
throw new Error(`Invalid worktree branch prefix: ${prefix ?? ""}`);
|
|
21
|
+
}
|
|
22
|
+
return raw.endsWith("/") ? raw : `${raw}/`;
|
|
23
|
+
}
|
|
24
|
+
export function isValidWorktreeBranchPrefix(prefix) {
|
|
25
|
+
const raw = prefix.trim();
|
|
26
|
+
if (!raw)
|
|
27
|
+
return false;
|
|
28
|
+
if (raw.startsWith("/") || raw.includes("//"))
|
|
29
|
+
return false;
|
|
30
|
+
if (raw.includes("..") || raw.includes("@{"))
|
|
31
|
+
return false;
|
|
32
|
+
if (/[\x00-\x20~^:?*[\]\\]/.test(raw))
|
|
33
|
+
return false;
|
|
34
|
+
const withoutTrailingSlash = raw.endsWith("/") ? raw.slice(0, -1) : raw;
|
|
35
|
+
if (!withoutTrailingSlash)
|
|
36
|
+
return false;
|
|
37
|
+
return withoutTrailingSlash.split("/").every((part) => {
|
|
38
|
+
if (!part)
|
|
39
|
+
return false;
|
|
40
|
+
if (part.startsWith(".") || part.endsWith("."))
|
|
41
|
+
return false;
|
|
42
|
+
if (part.endsWith(".lock"))
|
|
43
|
+
return false;
|
|
44
|
+
return true;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function applyPrefix(prefix, slug, sessionId) {
|
|
48
|
+
validateWorktreeSlug(slug);
|
|
49
|
+
return `${normalizeWorktreeBranchPrefix(prefix)}${slug}-${sessionId.slice(0, 8)}`;
|
|
50
|
+
}
|
|
51
|
+
export function managedBranchPrefixes(prefix) {
|
|
52
|
+
const configured = normalizeWorktreeBranchPrefix(prefix);
|
|
53
|
+
return configured === HISTORICAL_WORKTREE_BRANCH_PREFIX
|
|
54
|
+
? [configured]
|
|
55
|
+
: [configured, HISTORICAL_WORKTREE_BRANCH_PREFIX];
|
|
56
|
+
}
|
|
57
|
+
export function isManagedWorktreeBranch(branch, prefix) {
|
|
58
|
+
return managedBranchPrefixes(prefix).some((candidate) => branch.startsWith(candidate));
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./worktree/index.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Coding capability barrel for the split worktree module. The split made the
|
|
2
|
+
// query/create APIs async because they now share the async git executor; all
|
|
3
|
+
// in-repo callers await them, so this barrel intentionally does not add sync
|
|
4
|
+
// wrappers.
|
|
5
|
+
export * from "./worktree/index.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type AgentPreset, type BuiltinTool, type CapabilityModule } from "@cjhyy/code-shell-core/extension";
|
|
2
|
+
export declare const CODING_TOOLS: readonly BuiltinTool[];
|
|
3
|
+
/** Preserve the general host profile while adding coding-package tools tagged for it. */
|
|
4
|
+
export declare const CODING_GENERAL_PRESET: AgentPreset;
|
|
5
|
+
/** Full coding preset assembled from the core baseline plus this package's tools. */
|
|
6
|
+
export declare const TERMINAL_CODING_PRESET: AgentPreset;
|
|
7
|
+
export declare const CODING_CAPABILITY: CapabilityModule;
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { BUILTIN_AGENT_PRESETS, BUILTIN_TOOLS, derivePresetExposure, } from "@cjhyy/code-shell-core/extension";
|
|
4
|
+
import { briefTool, briefToolDef } from "./tools/brief.js";
|
|
5
|
+
import { lspTool, lspToolDef } from "./tools/lsp.js";
|
|
6
|
+
import { notebookEditTool, notebookEditToolDef } from "./tools/notebook-edit.js";
|
|
7
|
+
import { applyPatchTool, applyPatchToolDef } from "./tools/apply-patch/index.js";
|
|
8
|
+
import { parsePatch } from "./tools/apply-patch/parser.js";
|
|
9
|
+
import { patchBackupTargets } from "./tools/apply-patch/backup-targets.js";
|
|
10
|
+
import { enterWorktreeTool, enterWorktreeToolDef, exitWorktreeTool, exitWorktreeToolDef, switchSessionWorkspaceTool, switchSessionWorkspaceToolDef, } from "./tools/worktree.js";
|
|
11
|
+
import { branchExists, isGitWorktreeRoot } from "./git/worktree.js";
|
|
12
|
+
import { checkQuotaTool, checkQuotaToolDef } from "./tools/check-quota.js";
|
|
13
|
+
import { DRIVE_AGENT_TOOL_TIMEOUT_MS, driveAgentJobsTool, driveAgentJobsToolDef, driveAgentTool, driveAgentToolDef, driveClaudeCodeTool, driveClaudeCodeToolDef, } from "./tools/drive-agent.js";
|
|
14
|
+
import { codingArtifactDetector, createCodingToolService, findCodingInstructionBoundary, gitDynamicContextProvider, } from "./capability-runtime.js";
|
|
15
|
+
function defineTool(definition, execute, exposure) {
|
|
16
|
+
return { definition, execute, exposure };
|
|
17
|
+
}
|
|
18
|
+
export const CODING_TOOLS = [
|
|
19
|
+
defineTool({
|
|
20
|
+
...driveAgentToolDef,
|
|
21
|
+
source: "builtin",
|
|
22
|
+
permissionDefault: "ask",
|
|
23
|
+
isReadOnly: false,
|
|
24
|
+
isConcurrencySafe: false,
|
|
25
|
+
timeoutMs: DRIVE_AGENT_TOOL_TIMEOUT_MS,
|
|
26
|
+
pathPolicy: [{ kind: "arg", arg: "attachmentPaths", operation: "read" }],
|
|
27
|
+
}, driveAgentTool, { presetTags: ["general", "terminal-coding"] }),
|
|
28
|
+
defineTool({
|
|
29
|
+
...driveAgentJobsToolDef,
|
|
30
|
+
source: "builtin",
|
|
31
|
+
permissionDefault: "allow",
|
|
32
|
+
isReadOnly: false,
|
|
33
|
+
isConcurrencySafe: false,
|
|
34
|
+
}, driveAgentJobsTool, { presetTags: ["general", "terminal-coding"] }),
|
|
35
|
+
defineTool({
|
|
36
|
+
...driveClaudeCodeToolDef,
|
|
37
|
+
source: "builtin",
|
|
38
|
+
permissionDefault: "ask",
|
|
39
|
+
isReadOnly: false,
|
|
40
|
+
isConcurrencySafe: false,
|
|
41
|
+
timeoutMs: DRIVE_AGENT_TOOL_TIMEOUT_MS,
|
|
42
|
+
pathPolicy: [{ kind: "arg", arg: "attachmentPaths", operation: "read" }],
|
|
43
|
+
}, driveClaudeCodeTool, { presetTags: ["general", "terminal-coding"] }),
|
|
44
|
+
defineTool({
|
|
45
|
+
...checkQuotaToolDef,
|
|
46
|
+
source: "builtin",
|
|
47
|
+
permissionDefault: "allow",
|
|
48
|
+
isReadOnly: true,
|
|
49
|
+
isConcurrencySafe: true,
|
|
50
|
+
}, checkQuotaTool, {
|
|
51
|
+
presetTags: ["terminal-coding"],
|
|
52
|
+
defaultPermissionRules: [{ tool: "CheckQuota", decision: "allow" }],
|
|
53
|
+
}),
|
|
54
|
+
defineTool({
|
|
55
|
+
...enterWorktreeToolDef,
|
|
56
|
+
source: "builtin",
|
|
57
|
+
permissionDefault: "ask",
|
|
58
|
+
isReadOnly: false,
|
|
59
|
+
isConcurrencySafe: false,
|
|
60
|
+
}, enterWorktreeTool, { presetTags: ["terminal-coding"] }),
|
|
61
|
+
defineTool({
|
|
62
|
+
...exitWorktreeToolDef,
|
|
63
|
+
source: "builtin",
|
|
64
|
+
permissionDefault: "ask",
|
|
65
|
+
isReadOnly: false,
|
|
66
|
+
isConcurrencySafe: false,
|
|
67
|
+
}, exitWorktreeTool, { presetTags: ["terminal-coding"] }),
|
|
68
|
+
defineTool({
|
|
69
|
+
...switchSessionWorkspaceToolDef,
|
|
70
|
+
source: "builtin",
|
|
71
|
+
permissionDefault: "ask",
|
|
72
|
+
isReadOnly: false,
|
|
73
|
+
isConcurrencySafe: false,
|
|
74
|
+
}, switchSessionWorkspaceTool, { presetTags: [] }),
|
|
75
|
+
defineTool({
|
|
76
|
+
...applyPatchToolDef,
|
|
77
|
+
source: "builtin",
|
|
78
|
+
permissionDefault: "ask",
|
|
79
|
+
isReadOnly: false,
|
|
80
|
+
isConcurrencySafe: false,
|
|
81
|
+
pathResolver: {
|
|
82
|
+
operation: "write",
|
|
83
|
+
resolve: (args, cwd) => {
|
|
84
|
+
const patch = typeof args.patch === "string" ? args.patch : "";
|
|
85
|
+
if (!patch)
|
|
86
|
+
return [];
|
|
87
|
+
const parsed = parsePatch(patch, "lenient");
|
|
88
|
+
return parsed.hunks.flatMap((hunk) => [
|
|
89
|
+
resolve(cwd, hunk.path),
|
|
90
|
+
...(hunk.kind === "update" && hunk.movePath ? [resolve(cwd, hunk.movePath)] : []),
|
|
91
|
+
]);
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
}, applyPatchTool, { presetTags: ["terminal-coding"] }),
|
|
95
|
+
defineTool({
|
|
96
|
+
...briefToolDef,
|
|
97
|
+
source: "builtin",
|
|
98
|
+
permissionDefault: "allow",
|
|
99
|
+
isReadOnly: true,
|
|
100
|
+
isConcurrencySafe: true,
|
|
101
|
+
}, briefTool, {
|
|
102
|
+
presetTags: ["terminal-coding"],
|
|
103
|
+
defaultPermissionRules: [{ tool: "Brief", decision: "allow" }],
|
|
104
|
+
}),
|
|
105
|
+
defineTool({
|
|
106
|
+
...notebookEditToolDef,
|
|
107
|
+
source: "builtin",
|
|
108
|
+
permissionDefault: "ask",
|
|
109
|
+
isReadOnly: false,
|
|
110
|
+
isConcurrencySafe: false,
|
|
111
|
+
pathPolicy: [
|
|
112
|
+
{
|
|
113
|
+
kind: "arg",
|
|
114
|
+
arg: "file_path",
|
|
115
|
+
operation: { fromArg: "action", readValues: ["read"], default: "write" },
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
}, notebookEditTool, { presetTags: ["terminal-coding"] }),
|
|
119
|
+
defineTool({
|
|
120
|
+
...lspToolDef,
|
|
121
|
+
source: "builtin",
|
|
122
|
+
permissionDefault: "allow",
|
|
123
|
+
isReadOnly: true,
|
|
124
|
+
isConcurrencySafe: true,
|
|
125
|
+
pathPolicy: [{ kind: "arg", arg: "file_path", operation: "read" }],
|
|
126
|
+
}, lspTool, {
|
|
127
|
+
presetTags: ["terminal-coding"],
|
|
128
|
+
defaultPermissionRules: [{ tool: "LSP", decision: "allow" }],
|
|
129
|
+
}),
|
|
130
|
+
];
|
|
131
|
+
const generalBase = BUILTIN_AGENT_PRESETS.general;
|
|
132
|
+
const generalCodingExposure = derivePresetExposure("general", CODING_TOOLS);
|
|
133
|
+
const terminalCodingExposure = derivePresetExposure("terminal-coding", CODING_TOOLS);
|
|
134
|
+
const productFullExposure = derivePresetExposure("product-full", BUILTIN_TOOLS);
|
|
135
|
+
/** Preserve the general host profile while adding coding-package tools tagged for it. */
|
|
136
|
+
export const CODING_GENERAL_PRESET = {
|
|
137
|
+
...generalBase,
|
|
138
|
+
builtinTools: [...generalBase.builtinTools, ...generalCodingExposure.builtinTools],
|
|
139
|
+
defaultPermissionRules: [
|
|
140
|
+
...generalBase.defaultPermissionRules,
|
|
141
|
+
...generalCodingExposure.defaultPermissionRules,
|
|
142
|
+
],
|
|
143
|
+
};
|
|
144
|
+
/** Full coding preset assembled from the core baseline plus this package's tools. */
|
|
145
|
+
export const TERMINAL_CODING_PRESET = {
|
|
146
|
+
name: "terminal-coding",
|
|
147
|
+
label: "Terminal Coding Assistant",
|
|
148
|
+
description: "General orchestration plus coding-focused guidance and code-navigation tools.",
|
|
149
|
+
promptSections: ["base", "orchestration", "coding", "browser", "tone"],
|
|
150
|
+
builtinTools: [
|
|
151
|
+
...generalBase.builtinTools,
|
|
152
|
+
...productFullExposure.builtinTools,
|
|
153
|
+
...terminalCodingExposure.builtinTools,
|
|
154
|
+
],
|
|
155
|
+
defaultPermissionRules: [
|
|
156
|
+
...generalBase.defaultPermissionRules,
|
|
157
|
+
...productFullExposure.defaultPermissionRules,
|
|
158
|
+
...terminalCodingExposure.defaultPermissionRules,
|
|
159
|
+
],
|
|
160
|
+
};
|
|
161
|
+
export const CODING_CAPABILITY = {
|
|
162
|
+
id: "coding",
|
|
163
|
+
defaultPreset: "terminal-coding",
|
|
164
|
+
tools: CODING_TOOLS,
|
|
165
|
+
presets: [CODING_GENERAL_PRESET, TERMINAL_CODING_PRESET],
|
|
166
|
+
promptSections: {
|
|
167
|
+
coding: readFileSync(new URL("./prompt/coding.md", import.meta.url), "utf-8"),
|
|
168
|
+
},
|
|
169
|
+
dynamicContextProviders: [gitDynamicContextProvider],
|
|
170
|
+
instructionBoundary: findCodingInstructionBoundary,
|
|
171
|
+
createToolService: createCodingToolService,
|
|
172
|
+
artifactDetectors: [codingArtifactDetector],
|
|
173
|
+
fileHistory: [
|
|
174
|
+
{
|
|
175
|
+
toolName: "ApplyPatch",
|
|
176
|
+
resolveTargets: (args, cwd) => typeof args.patch === "string" ? patchBackupTargets(args.patch, cwd) : [],
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
sessionWorkspace: {
|
|
180
|
+
validateRoot: (root) => isGitWorktreeRoot(root),
|
|
181
|
+
branchExists: (mainRoot, branch) => branchExists(mainRoot, branch),
|
|
182
|
+
},
|
|
183
|
+
adjustToolSelection: (names, context) => {
|
|
184
|
+
if (context.host !== "desktop")
|
|
185
|
+
return;
|
|
186
|
+
names.delete("EnterWorktree");
|
|
187
|
+
names.delete("ExitWorktree");
|
|
188
|
+
names.add("SwitchSessionWorkspace");
|
|
189
|
+
},
|
|
190
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility root for the coding capability package.
|
|
3
|
+
*
|
|
4
|
+
* New hosts should prefer /capability, /git, or /orchestration so importing
|
|
5
|
+
* one concern does not evaluate every coding implementation.
|
|
6
|
+
*/
|
|
7
|
+
export * from "./index.capability.js";
|
|
8
|
+
export { briefTool } from "./tools/brief.js";
|
|
9
|
+
export { lspTool } from "./tools/lsp.js";
|
|
10
|
+
export { notebookEditTool } from "./tools/notebook-edit.js";
|
|
11
|
+
export * from "./tools/drive-agent.js";
|
|
12
|
+
export { applyPatchTool, applyPatchToolDef, applyPatch } from "./tools/apply-patch/index.js";
|
|
13
|
+
export { parsePatch } from "./tools/apply-patch/parser.js";
|
|
14
|
+
export { seekSequence } from "./tools/apply-patch/seek-sequence.js";
|
|
15
|
+
export { LSPClient } from "./lsp/client.js";
|
|
16
|
+
export { getLSPManager, initializeLSPManager, LSPServerManager } from "./lsp/manager.js";
|
|
17
|
+
export * from "./index.git.js";
|
|
18
|
+
export * from "./index.orchestration.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility root for the coding capability package.
|
|
3
|
+
*
|
|
4
|
+
* New hosts should prefer /capability, /git, or /orchestration so importing
|
|
5
|
+
* one concern does not evaluate every coding implementation.
|
|
6
|
+
*/
|
|
7
|
+
export * from "./index.capability.js";
|
|
8
|
+
export { briefTool } from "./tools/brief.js";
|
|
9
|
+
export { lspTool } from "./tools/lsp.js";
|
|
10
|
+
export { notebookEditTool } from "./tools/notebook-edit.js";
|
|
11
|
+
export * from "./tools/drive-agent.js";
|
|
12
|
+
export { applyPatchTool, applyPatchToolDef, applyPatch } from "./tools/apply-patch/index.js";
|
|
13
|
+
export { parsePatch } from "./tools/apply-patch/parser.js";
|
|
14
|
+
export { seekSequence } from "./tools/apply-patch/seek-sequence.js";
|
|
15
|
+
export { LSPClient } from "./lsp/client.js";
|
|
16
|
+
export { getLSPManager, initializeLSPManager, LSPServerManager } from "./lsp/manager.js";
|
|
17
|
+
export * from "./index.git.js";
|
|
18
|
+
export * from "./index.orchestration.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** External Claude Code/Codex orchestration and quota surface. */
|
|
2
|
+
export * from "./cc-orchestrator/index.js";
|
|
3
|
+
export { resolveExternalAgentConfig } from "./external-agents/config.js";
|
|
4
|
+
export type { ExternalAgentMode, ExternalAgentsSettings, ResolvedClaudeCodeSettings, ResolvedCodexSettings, ResolvedExternalAgentsConfig, } from "./external-agents/types.js";
|
|
5
|
+
export { checkQuota, formatQuota } from "./quota/index.js";
|
|
6
|
+
export { resolveQuotaCredentials } from "./quota/credentials.js";
|
|
7
|
+
export type { ProviderQuota, QuotaCredentials, QuotaResult, QuotaWindow } from "./quota/types.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** External Claude Code/Codex orchestration and quota surface. */
|
|
2
|
+
export * from "./cc-orchestrator/index.js";
|
|
3
|
+
export { resolveExternalAgentConfig } from "./external-agents/config.js";
|
|
4
|
+
export { checkQuota, formatQuota } from "./quota/index.js";
|
|
5
|
+
export { resolveQuotaCredentials } from "./quota/credentials.js";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LSP client — JSON-RPC over stdio communication with coding language servers.
|
|
3
|
+
*/
|
|
4
|
+
import { EventEmitter } from "node:events";
|
|
5
|
+
export interface LSPRequest {
|
|
6
|
+
method: string;
|
|
7
|
+
params?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface LSPResponse {
|
|
10
|
+
id: number;
|
|
11
|
+
result?: unknown;
|
|
12
|
+
error?: {
|
|
13
|
+
code: number;
|
|
14
|
+
message: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface LSPNotification {
|
|
18
|
+
method: string;
|
|
19
|
+
params?: Record<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
export declare class LSPClient extends EventEmitter {
|
|
22
|
+
private readonly command;
|
|
23
|
+
private readonly args;
|
|
24
|
+
private readonly cwd?;
|
|
25
|
+
private process;
|
|
26
|
+
private nextId;
|
|
27
|
+
private pending;
|
|
28
|
+
private buffer;
|
|
29
|
+
private contentLength;
|
|
30
|
+
private initialized;
|
|
31
|
+
constructor(command: string, args?: string[], cwd?: string | undefined);
|
|
32
|
+
start(): Promise<void>;
|
|
33
|
+
initialize(rootUri: string): Promise<unknown>;
|
|
34
|
+
request(method: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
35
|
+
notify(method: string, params?: Record<string, unknown>): Promise<void>;
|
|
36
|
+
shutdown(): Promise<void>;
|
|
37
|
+
get isInitialized(): boolean;
|
|
38
|
+
get isAlive(): boolean;
|
|
39
|
+
private handleData;
|
|
40
|
+
private rejectAll;
|
|
41
|
+
}
|