@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.
Files changed (134) hide show
  1. package/README.md +69 -0
  2. package/THIRD_PARTY_NOTICES.md +206 -0
  3. package/dist/bin/agent-server-stdio.d.ts +1 -0
  4. package/dist/bin/agent-server-stdio.js +4 -0
  5. package/dist/capability-runtime.d.ts +22 -0
  6. package/dist/capability-runtime.js +88 -0
  7. package/dist/cc-orchestrator/agent-adapter.d.ts +55 -0
  8. package/dist/cc-orchestrator/agent-adapter.js +143 -0
  9. package/dist/cc-orchestrator/cc-capability.d.ts +20 -0
  10. package/dist/cc-orchestrator/cc-capability.js +57 -0
  11. package/dist/cc-orchestrator/codex-session-discovery.d.ts +45 -0
  12. package/dist/cc-orchestrator/codex-session-discovery.js +251 -0
  13. package/dist/cc-orchestrator/codex-session-history.d.ts +39 -0
  14. package/dist/cc-orchestrator/codex-session-history.js +249 -0
  15. package/dist/cc-orchestrator/codex-user-text.d.ts +9 -0
  16. package/dist/cc-orchestrator/codex-user-text.js +25 -0
  17. package/dist/cc-orchestrator/external-agent-bindings.d.ts +27 -0
  18. package/dist/cc-orchestrator/external-agent-bindings.js +150 -0
  19. package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
  20. package/dist/cc-orchestrator/external-agent-changes.js +231 -0
  21. package/dist/cc-orchestrator/external-agent-driver.d.ts +19 -0
  22. package/dist/cc-orchestrator/external-agent-driver.js +284 -0
  23. package/dist/cc-orchestrator/external-agent-session-store.d.ts +36 -0
  24. package/dist/cc-orchestrator/external-agent-session-store.js +185 -0
  25. package/dist/cc-orchestrator/index.d.ts +10 -0
  26. package/dist/cc-orchestrator/index.js +10 -0
  27. package/dist/cc-orchestrator/related-session-discovery.d.ts +21 -0
  28. package/dist/cc-orchestrator/related-session-discovery.js +77 -0
  29. package/dist/cc-orchestrator/relevance-judge.d.ts +16 -0
  30. package/dist/cc-orchestrator/relevance-judge.js +38 -0
  31. package/dist/cc-orchestrator/session-discovery.d.ts +99 -0
  32. package/dist/cc-orchestrator/session-discovery.js +295 -0
  33. package/dist/cc-orchestrator/session-history.d.ts +55 -0
  34. package/dist/cc-orchestrator/session-history.js +150 -0
  35. package/dist/external-agents/config.d.ts +3 -0
  36. package/dist/external-agents/config.js +16 -0
  37. package/dist/external-agents/types.d.ts +32 -0
  38. package/dist/external-agents/types.js +1 -0
  39. package/dist/external-runtimes/claude-code/event-translator.d.ts +54 -0
  40. package/dist/external-runtimes/claude-code/event-translator.js +201 -0
  41. package/dist/external-runtimes/claude-code/mcp-config.d.ts +84 -0
  42. package/dist/external-runtimes/claude-code/mcp-config.js +175 -0
  43. package/dist/external-runtimes/claude-code/runtime.d.ts +56 -0
  44. package/dist/external-runtimes/claude-code/runtime.js +168 -0
  45. package/dist/external-runtimes/codex/app-server-client.d.ts +66 -0
  46. package/dist/external-runtimes/codex/app-server-client.js +244 -0
  47. package/dist/external-runtimes/codex/event-translator.d.ts +68 -0
  48. package/dist/external-runtimes/codex/event-translator.js +187 -0
  49. package/dist/external-runtimes/codex/index.d.ts +7 -0
  50. package/dist/external-runtimes/codex/index.js +6 -0
  51. package/dist/external-runtimes/codex/runtime.d.ts +128 -0
  52. package/dist/external-runtimes/codex/runtime.js +216 -0
  53. package/dist/external-runtimes/index.d.ts +37 -0
  54. package/dist/external-runtimes/index.js +27 -0
  55. package/dist/external-runtimes/session-factory.d.ts +97 -0
  56. package/dist/external-runtimes/session-factory.js +110 -0
  57. package/dist/external-runtimes/shared/mcp-bridge.d.ts +66 -0
  58. package/dist/external-runtimes/shared/mcp-bridge.js +365 -0
  59. package/dist/external-runtimes/shared/session-context-store.d.ts +83 -0
  60. package/dist/external-runtimes/shared/session-context-store.js +114 -0
  61. package/dist/external-runtimes/shared/spawn-env.d.ts +30 -0
  62. package/dist/external-runtimes/shared/spawn-env.js +41 -0
  63. package/dist/git/parse-log.d.ts +14 -0
  64. package/dist/git/parse-log.js +21 -0
  65. package/dist/git/utils.d.ts +49 -0
  66. package/dist/git/utils.js +161 -0
  67. package/dist/git/worktree/crud.d.ts +108 -0
  68. package/dist/git/worktree/crud.js +415 -0
  69. package/dist/git/worktree/diff.d.ts +14 -0
  70. package/dist/git/worktree/diff.js +83 -0
  71. package/dist/git/worktree/git-exec.d.ts +7 -0
  72. package/dist/git/worktree/git-exec.js +86 -0
  73. package/dist/git/worktree/index.d.ts +6 -0
  74. package/dist/git/worktree/index.js +6 -0
  75. package/dist/git/worktree/query.d.ts +43 -0
  76. package/dist/git/worktree/query.js +128 -0
  77. package/dist/git/worktree/slug.d.ts +12 -0
  78. package/dist/git/worktree/slug.js +59 -0
  79. package/dist/git/worktree.d.ts +1 -0
  80. package/dist/git/worktree.js +5 -0
  81. package/dist/index.capability.d.ts +7 -0
  82. package/dist/index.capability.js +190 -0
  83. package/dist/index.d.ts +18 -0
  84. package/dist/index.git.d.ts +4 -0
  85. package/dist/index.git.js +4 -0
  86. package/dist/index.js +18 -0
  87. package/dist/index.orchestration.d.ts +7 -0
  88. package/dist/index.orchestration.js +5 -0
  89. package/dist/lsp/client.d.ts +41 -0
  90. package/dist/lsp/client.js +192 -0
  91. package/dist/lsp/manager.d.ts +53 -0
  92. package/dist/lsp/manager.js +248 -0
  93. package/dist/lsp/root-path.d.ts +9 -0
  94. package/dist/lsp/root-path.js +12 -0
  95. package/dist/lsp/servers.d.ts +16 -0
  96. package/dist/lsp/servers.js +60 -0
  97. package/dist/prompt/coding.md +42 -0
  98. package/dist/quota/credentials.d.ts +3 -0
  99. package/dist/quota/credentials.js +80 -0
  100. package/dist/quota/index.d.ts +36 -0
  101. package/dist/quota/index.js +161 -0
  102. package/dist/quota/types.d.ts +48 -0
  103. package/dist/quota/types.js +13 -0
  104. package/dist/review/review-prompt.d.ts +28 -0
  105. package/dist/review/review-prompt.js +81 -0
  106. package/dist/tools/apply-patch/LICENSE-codex +201 -0
  107. package/dist/tools/apply-patch/NOTICE.md +29 -0
  108. package/dist/tools/apply-patch/applier.d.ts +26 -0
  109. package/dist/tools/apply-patch/applier.js +306 -0
  110. package/dist/tools/apply-patch/backup-targets.d.ts +10 -0
  111. package/dist/tools/apply-patch/backup-targets.js +30 -0
  112. package/dist/tools/apply-patch/eol.d.ts +4 -0
  113. package/dist/tools/apply-patch/eol.js +9 -0
  114. package/dist/tools/apply-patch/index.d.ts +20 -0
  115. package/dist/tools/apply-patch/index.js +106 -0
  116. package/dist/tools/apply-patch/parser.d.ts +17 -0
  117. package/dist/tools/apply-patch/parser.js +209 -0
  118. package/dist/tools/apply-patch/seek-sequence.d.ts +18 -0
  119. package/dist/tools/apply-patch/seek-sequence.js +123 -0
  120. package/dist/tools/apply-patch/types.d.ts +49 -0
  121. package/dist/tools/apply-patch/types.js +13 -0
  122. package/dist/tools/brief.d.ts +6 -0
  123. package/dist/tools/brief.js +41 -0
  124. package/dist/tools/check-quota.d.ts +14 -0
  125. package/dist/tools/check-quota.js +38 -0
  126. package/dist/tools/drive-agent.d.ts +52 -0
  127. package/dist/tools/drive-agent.js +1184 -0
  128. package/dist/tools/lsp.d.ts +6 -0
  129. package/dist/tools/lsp.js +220 -0
  130. package/dist/tools/notebook-edit.d.ts +6 -0
  131. package/dist/tools/notebook-edit.js +127 -0
  132. package/dist/tools/worktree.d.ts +10 -0
  133. package/dist/tools/worktree.js +363 -0
  134. package/package.json +60 -0
@@ -0,0 +1,209 @@
1
+ // Coding capability parser adapted from openai/codex codex-rs/apply-patch/src/parser.rs.
2
+ //
3
+ // V4A patch grammar (lenient form):
4
+ //
5
+ // start := begin_patch hunk* end_patch
6
+ // begin_patch := "*** Begin Patch" LF
7
+ // end_patch := "*** End Patch" LF?
8
+ // hunk := add_hunk | delete_hunk | update_hunk
9
+ // add_hunk := "*** Add File: " path LF ("+" line LF)+
10
+ // delete_hunk := "*** Delete File: " path LF
11
+ // update_hunk := "*** Update File: " path LF change_move? change?
12
+ // change_move := "*** Move to: " path LF
13
+ // change := (change_context | change_line)+ eof_line?
14
+ // change_line := (" " | "+" | "-") text LF
15
+ // eof_line := "*** End of File" LF
16
+ //
17
+ // Lenient extras:
18
+ // - Leading/trailing whitespace around begin/end markers tolerated.
19
+ // - First Update chunk may omit the leading `@@` context marker.
20
+ // - Patch text may be wrapped in <<EOF / <<'EOF' / <<"EOF" heredoc; we strip
21
+ // it so misformatted shell-style invocations still parse.
22
+ import { PatchParseError } from "./types.js";
23
+ export const BEGIN_PATCH_MARKER = "*** Begin Patch";
24
+ export const END_PATCH_MARKER = "*** End Patch";
25
+ export const ADD_FILE_MARKER = "*** Add File: ";
26
+ export const DELETE_FILE_MARKER = "*** Delete File: ";
27
+ export const UPDATE_FILE_MARKER = "*** Update File: ";
28
+ export const MOVE_TO_MARKER = "*** Move to: ";
29
+ export const EOF_MARKER = "*** End of File";
30
+ export const CHANGE_CONTEXT_MARKER = "@@ ";
31
+ export const EMPTY_CHANGE_CONTEXT_MARKER = "@@";
32
+ export function parsePatch(text, mode = "lenient") {
33
+ const trimmed = text.trim();
34
+ const lines = trimmed.length === 0 ? [] : trimmed.split("\n");
35
+ const inner = mode === "strict" ? checkBoundariesStrict(lines) : checkBoundariesLenient(lines);
36
+ const hunks = [];
37
+ let lineNumber = 2;
38
+ let i = 0;
39
+ while (i < inner.body.length) {
40
+ const { hunk, consumed } = parseOneHunk(inner.body, i, lineNumber);
41
+ hunks.push(hunk);
42
+ lineNumber += consumed;
43
+ i += consumed;
44
+ }
45
+ return { hunks, patch: inner.allLines.join("\n") };
46
+ }
47
+ function checkBoundariesStrict(lines) {
48
+ const first = lines[0]?.trim();
49
+ const last = lines[lines.length - 1]?.trim();
50
+ if (first !== BEGIN_PATCH_MARKER) {
51
+ throw new PatchParseError("InvalidPatch", "The first line of the patch must be '*** Begin Patch'");
52
+ }
53
+ if (lines.length < 2 || last !== END_PATCH_MARKER) {
54
+ throw new PatchParseError("InvalidPatch", "The last line of the patch must be '*** End Patch'");
55
+ }
56
+ return { allLines: lines, body: lines.slice(1, lines.length - 1) };
57
+ }
58
+ function checkBoundariesLenient(lines) {
59
+ try {
60
+ return checkBoundariesStrict(lines);
61
+ }
62
+ catch (err) {
63
+ const original = err;
64
+ if (lines.length >= 4) {
65
+ const first = lines[0];
66
+ const last = lines[lines.length - 1];
67
+ const isHeredoc = (first === "<<EOF" || first === "<<'EOF'" || first === '<<"EOF"') && last.endsWith("EOF");
68
+ if (isHeredoc) {
69
+ return checkBoundariesStrict(lines.slice(1, lines.length - 1));
70
+ }
71
+ }
72
+ throw original;
73
+ }
74
+ }
75
+ function parseOneHunk(lines, offset, lineNumber) {
76
+ const first = lines[offset].trim();
77
+ if (first.startsWith(ADD_FILE_MARKER)) {
78
+ const path = first.slice(ADD_FILE_MARKER.length);
79
+ let contents = "";
80
+ let consumed = 1;
81
+ for (let i = offset + 1; i < lines.length; i++) {
82
+ const line = lines[i];
83
+ if (line.startsWith("+")) {
84
+ contents += line.slice(1) + "\n";
85
+ consumed++;
86
+ }
87
+ else {
88
+ break;
89
+ }
90
+ }
91
+ return { hunk: { kind: "add", path, contents }, consumed };
92
+ }
93
+ if (first.startsWith(DELETE_FILE_MARKER)) {
94
+ return {
95
+ hunk: { kind: "delete", path: first.slice(DELETE_FILE_MARKER.length) },
96
+ consumed: 1,
97
+ };
98
+ }
99
+ if (first.startsWith(UPDATE_FILE_MARKER)) {
100
+ const path = first.slice(UPDATE_FILE_MARKER.length);
101
+ let cursor = offset + 1;
102
+ let consumed = 1;
103
+ let movePath;
104
+ if (cursor < lines.length && lines[cursor].startsWith(MOVE_TO_MARKER)) {
105
+ movePath = lines[cursor].slice(MOVE_TO_MARKER.length);
106
+ cursor++;
107
+ consumed++;
108
+ }
109
+ const chunks = [];
110
+ while (cursor < lines.length) {
111
+ // Skip blank lines between chunks.
112
+ if (lines[cursor].trim() === "") {
113
+ cursor++;
114
+ consumed++;
115
+ continue;
116
+ }
117
+ // Stop at any other top-level marker (`*** ...`).
118
+ if (lines[cursor].startsWith("*"))
119
+ break;
120
+ const result = parseUpdateChunk(lines, cursor, lineNumber + consumed, chunks.length === 0);
121
+ chunks.push(result.chunk);
122
+ cursor += result.consumed;
123
+ consumed += result.consumed;
124
+ }
125
+ if (chunks.length === 0) {
126
+ throw new PatchParseError("InvalidHunk", `Update file hunk for path '${path}' is empty`, lineNumber);
127
+ }
128
+ return {
129
+ hunk: { kind: "update", path, movePath, chunks },
130
+ consumed,
131
+ };
132
+ }
133
+ throw new PatchParseError("InvalidHunk", `'${first}' is not a valid hunk header. Valid hunk headers: ` +
134
+ `'*** Add File: {path}', '*** Delete File: {path}', '*** Update File: {path}'`, lineNumber);
135
+ }
136
+ function parseUpdateChunk(lines, offset, lineNumber, allowMissingContext) {
137
+ if (offset >= lines.length) {
138
+ throw new PatchParseError("InvalidHunk", "Update hunk does not contain any lines", lineNumber);
139
+ }
140
+ const head = lines[offset];
141
+ let changeContext;
142
+ let cursor = offset;
143
+ if (head === EMPTY_CHANGE_CONTEXT_MARKER) {
144
+ cursor = offset + 1;
145
+ }
146
+ else if (head.startsWith(CHANGE_CONTEXT_MARKER)) {
147
+ changeContext = head.slice(CHANGE_CONTEXT_MARKER.length);
148
+ cursor = offset + 1;
149
+ }
150
+ else if (!allowMissingContext) {
151
+ throw new PatchParseError("InvalidHunk", `Expected update hunk to start with a @@ context marker, got: '${head}'`, lineNumber);
152
+ }
153
+ if (cursor >= lines.length) {
154
+ throw new PatchParseError("InvalidHunk", "Update hunk does not contain any lines", lineNumber + 1);
155
+ }
156
+ const oldLines = [];
157
+ const newLines = [];
158
+ let isEndOfFile = false;
159
+ let bodyConsumed = 0;
160
+ for (let i = cursor; i < lines.length; i++) {
161
+ const line = lines[i];
162
+ if (line === EOF_MARKER) {
163
+ if (bodyConsumed === 0) {
164
+ throw new PatchParseError("InvalidHunk", "Update hunk does not contain any lines", lineNumber + 1);
165
+ }
166
+ isEndOfFile = true;
167
+ bodyConsumed++;
168
+ break;
169
+ }
170
+ if (line.length === 0) {
171
+ // Blank line — treat as a context line containing the empty string.
172
+ oldLines.push("");
173
+ newLines.push("");
174
+ bodyConsumed++;
175
+ continue;
176
+ }
177
+ const marker = line[0];
178
+ const rest = line.slice(1);
179
+ if (marker === " ") {
180
+ oldLines.push(rest);
181
+ newLines.push(rest);
182
+ }
183
+ else if (marker === "+") {
184
+ newLines.push(rest);
185
+ }
186
+ else if (marker === "-") {
187
+ oldLines.push(rest);
188
+ }
189
+ else {
190
+ // First unrecognized character at position 0 with no body yet → error.
191
+ // Otherwise, assume this is the start of the next hunk.
192
+ if (bodyConsumed === 0) {
193
+ throw new PatchParseError("InvalidHunk", `Unexpected line found in update hunk: '${line}'. Every line should start ` +
194
+ `with ' ' (context line), '+' (added line), or '-' (removed line)`, lineNumber + 1);
195
+ }
196
+ break;
197
+ }
198
+ bodyConsumed++;
199
+ }
200
+ return {
201
+ chunk: {
202
+ changeContext,
203
+ oldLines,
204
+ newLines,
205
+ isEndOfFile,
206
+ },
207
+ consumed: bodyConsumed + (cursor - offset),
208
+ };
209
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Locate `pattern` within `lines` starting at or after `start`.
3
+ *
4
+ * Tries four passes with decreasing strictness:
5
+ * 1. exact equality
6
+ * 2. trailing whitespace ignored
7
+ * 3. leading + trailing whitespace ignored
8
+ * 4. Unicode punctuation normalized to ASCII (smart quotes, em-dashes, NBSP, …)
9
+ *
10
+ * When `eof` is true, search begins at the position that would let `pattern`
11
+ * end exactly at the end of `lines` — useful for chunks marked
12
+ * `*** End of File`. Falls back to `start` if that position is out of range.
13
+ *
14
+ * Defensive cases:
15
+ * - Empty pattern returns `start` (no-op match).
16
+ * - Pattern longer than input returns `null`.
17
+ */
18
+ export declare function seekSequence(lines: string[], pattern: string[], start: number, eof: boolean): number | null;
@@ -0,0 +1,123 @@
1
+ // Coding capability matcher adapted from openai/codex codex-rs/apply-patch/src/seek_sequence.rs.
2
+ /**
3
+ * Locate `pattern` within `lines` starting at or after `start`.
4
+ *
5
+ * Tries four passes with decreasing strictness:
6
+ * 1. exact equality
7
+ * 2. trailing whitespace ignored
8
+ * 3. leading + trailing whitespace ignored
9
+ * 4. Unicode punctuation normalized to ASCII (smart quotes, em-dashes, NBSP, …)
10
+ *
11
+ * When `eof` is true, search begins at the position that would let `pattern`
12
+ * end exactly at the end of `lines` — useful for chunks marked
13
+ * `*** End of File`. Falls back to `start` if that position is out of range.
14
+ *
15
+ * Defensive cases:
16
+ * - Empty pattern returns `start` (no-op match).
17
+ * - Pattern longer than input returns `null`.
18
+ */
19
+ export function seekSequence(lines, pattern, start, eof) {
20
+ if (pattern.length === 0)
21
+ return start;
22
+ if (pattern.length > lines.length)
23
+ return null;
24
+ const searchStart = eof && lines.length >= pattern.length ? lines.length - pattern.length : start;
25
+ const lastStart = lines.length - pattern.length;
26
+ // Pass 1: exact equality.
27
+ for (let i = searchStart; i <= lastStart; i++) {
28
+ let ok = true;
29
+ for (let p = 0; p < pattern.length; p++) {
30
+ if (lines[i + p] !== pattern[p]) {
31
+ ok = false;
32
+ break;
33
+ }
34
+ }
35
+ if (ok)
36
+ return i;
37
+ }
38
+ // Pass 2: trim trailing whitespace.
39
+ for (let i = searchStart; i <= lastStart; i++) {
40
+ let ok = true;
41
+ for (let p = 0; p < pattern.length; p++) {
42
+ if (rtrim(lines[i + p]) !== rtrim(pattern[p])) {
43
+ ok = false;
44
+ break;
45
+ }
46
+ }
47
+ if (ok)
48
+ return i;
49
+ }
50
+ // Pass 3: trim both sides.
51
+ for (let i = searchStart; i <= lastStart; i++) {
52
+ let ok = true;
53
+ for (let p = 0; p < pattern.length; p++) {
54
+ if (lines[i + p].trim() !== pattern[p].trim()) {
55
+ ok = false;
56
+ break;
57
+ }
58
+ }
59
+ if (ok)
60
+ return i;
61
+ }
62
+ // Pass 4: Unicode normalize (smart quotes / dashes / NBSP → ASCII).
63
+ for (let i = searchStart; i <= lastStart; i++) {
64
+ let ok = true;
65
+ for (let p = 0; p < pattern.length; p++) {
66
+ if (normalize(lines[i + p]) !== normalize(pattern[p])) {
67
+ ok = false;
68
+ break;
69
+ }
70
+ }
71
+ if (ok)
72
+ return i;
73
+ }
74
+ return null;
75
+ }
76
+ function rtrim(s) {
77
+ return s.replace(/[\s\uFEFF\xA0]+$/u, "");
78
+ }
79
+ function normalize(s) {
80
+ let out = "";
81
+ for (const ch of s.trim()) {
82
+ const code = ch.codePointAt(0);
83
+ // Various dash / hyphen code-points → ASCII '-'
84
+ if (code === 0x2010 ||
85
+ code === 0x2011 ||
86
+ code === 0x2012 ||
87
+ code === 0x2013 ||
88
+ code === 0x2014 ||
89
+ code === 0x2015 ||
90
+ code === 0x2212) {
91
+ out += "-";
92
+ }
93
+ else if (
94
+ // Fancy single quotes → '
95
+ code === 0x2018 ||
96
+ code === 0x2019 ||
97
+ code === 0x201a ||
98
+ code === 0x201b) {
99
+ out += "'";
100
+ }
101
+ else if (
102
+ // Fancy double quotes → "
103
+ code === 0x201c ||
104
+ code === 0x201d ||
105
+ code === 0x201e ||
106
+ code === 0x201f) {
107
+ out += '"';
108
+ }
109
+ else if (
110
+ // Non-breaking and exotic spaces → regular space
111
+ code === 0x00a0 ||
112
+ (code >= 0x2002 && code <= 0x200a) ||
113
+ code === 0x202f ||
114
+ code === 0x205f ||
115
+ code === 0x3000) {
116
+ out += " ";
117
+ }
118
+ else {
119
+ out += ch;
120
+ }
121
+ }
122
+ return out;
123
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * V4A patch AST. A parsed patch is a list of Hunks; each Hunk targets one file.
3
+ *
4
+ * Three variants:
5
+ * - AddFile: create a new file with the given contents
6
+ * - DeleteFile: remove an existing file
7
+ * - UpdateFile: in-place edit (optionally with a rename via movePath),
8
+ * expressed as one or more UpdateFileChunks.
9
+ */
10
+ export type Hunk = {
11
+ kind: "add";
12
+ path: string;
13
+ contents: string;
14
+ } | {
15
+ kind: "delete";
16
+ path: string;
17
+ } | {
18
+ kind: "update";
19
+ path: string;
20
+ movePath?: string;
21
+ chunks: UpdateFileChunk[];
22
+ };
23
+ export interface UpdateFileChunk {
24
+ /** Optional `@@ <context>` anchor that narrows where this chunk applies. */
25
+ changeContext?: string;
26
+ /** Lines that must match in the existing file (` ` and `-` markers). */
27
+ oldLines: string[];
28
+ /** Lines that should appear after the edit (` ` and `+` markers). */
29
+ newLines: string[];
30
+ /** True if this chunk ended with `*** End of File`; matches only at EOF. */
31
+ isEndOfFile: boolean;
32
+ }
33
+ export declare class PatchParseError extends Error {
34
+ readonly kind: "InvalidPatch" | "InvalidHunk";
35
+ readonly lineNumber?: number;
36
+ constructor(kind: "InvalidPatch" | "InvalidHunk", message: string, lineNumber?: number);
37
+ }
38
+ /**
39
+ * Result of staging (dry-run) a single file's planned change.
40
+ *
41
+ * A rename is represented as two PlannedFileChange entries: one for the
42
+ * source path with `newContent: null` (delete) and one for the destination
43
+ * path with the new content.
44
+ */
45
+ export interface PlannedFileChange {
46
+ path: string;
47
+ /** null = delete; string = create-or-overwrite with this content. */
48
+ newContent: string | null;
49
+ }
@@ -0,0 +1,13 @@
1
+ // Coding capability types adapted from openai/codex codex-rs/apply-patch.
2
+ // Original Rust source: https://github.com/openai/codex/tree/main/codex-rs/apply-patch
3
+ // See LICENSE-codex in this directory.
4
+ export class PatchParseError extends Error {
5
+ kind;
6
+ lineNumber;
7
+ constructor(kind, message, lineNumber) {
8
+ super(message);
9
+ this.name = "PatchParseError";
10
+ this.kind = kind;
11
+ this.lineNumber = lineNumber;
12
+ }
13
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * BriefTool — send structured messages with markdown support.
3
+ */
4
+ import type { ToolDefinition } from "@cjhyy/code-shell-core/extension";
5
+ export declare const briefToolDef: ToolDefinition;
6
+ export declare function briefTool(args: Record<string, unknown>): Promise<string>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * BriefTool — send structured messages with markdown support.
3
+ */
4
+ export const briefToolDef = {
5
+ name: "Brief",
6
+ description: "Send a structured brief/summary message. Useful for providing concise status updates, " +
7
+ "summaries, or formatted output to the user.",
8
+ inputSchema: {
9
+ type: "object",
10
+ properties: {
11
+ title: {
12
+ type: "string",
13
+ description: "Brief title or heading",
14
+ },
15
+ content: {
16
+ type: "string",
17
+ description: "Markdown-formatted content of the brief",
18
+ },
19
+ status: {
20
+ type: "string",
21
+ enum: ["info", "success", "warning", "error"],
22
+ description: "Status level for the brief (default: info)",
23
+ },
24
+ },
25
+ required: ["content"],
26
+ },
27
+ };
28
+ export async function briefTool(args) {
29
+ const title = args.title;
30
+ const content = args.content;
31
+ const status = args.status ?? "info";
32
+ const icons = {
33
+ info: "ℹ",
34
+ success: "✓",
35
+ warning: "⚠",
36
+ error: "✗",
37
+ };
38
+ const icon = icons[status] ?? "ℹ";
39
+ const header = title ? `${icon} ${title}\n\n` : "";
40
+ return `${header}${content}`;
41
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * CheckQuota builtin — thin shell over the `quota/` module.
3
+ *
4
+ * Lets an orchestrating agent read how much CC/Codex quota is left before/while
5
+ * delegating work (DriveAgent), so it can plan: how many to spawn, whether to
6
+ * wait for a reset, or switch providers. See quota/index.ts for the sources.
7
+ *
8
+ * NOTE the cost asymmetry (surfaced in the description): Codex is a free GET;
9
+ * Claude costs ~1 output token because Anthropic only returns quota via
10
+ * response headers. So restrict with `provider` when you only need one.
11
+ */
12
+ import type { ToolContext, ToolDefinition } from "@cjhyy/code-shell-core/extension";
13
+ export declare const checkQuotaToolDef: ToolDefinition;
14
+ export declare function checkQuotaTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
@@ -0,0 +1,38 @@
1
+ import { checkQuota, formatQuota } from "../quota/index.js";
2
+ import { resolveQuotaCredentials } from "../quota/credentials.js";
3
+ export const checkQuotaToolDef = {
4
+ name: "CheckQuota",
5
+ description: "Check remaining usage/rate-limit quota for the external coding-agent CLIs (Claude Code and/or " +
6
+ "Codex) — the same 5h/7d subscription windows their status lines show. Use before or during " +
7
+ "orchestration (DriveAgent) to plan how much work to hand off, whether to wait for a reset, or " +
8
+ "which provider to use. Returns each provider's 5h/7d used-% and reset time. " +
9
+ "COST: 'codex' is free (reads a usage endpoint). 'claude' costs ~1 token (Anthropic exposes " +
10
+ "quota only via a response header, so this sends a 1-token probe). Pass `provider` to query " +
11
+ "just one and avoid the other's cost/latency.",
12
+ inputSchema: {
13
+ type: "object",
14
+ properties: {
15
+ provider: {
16
+ type: "string",
17
+ enum: ["claude", "codex", "both"],
18
+ description: "Which to check. 'both' (default) queries Claude Code and Codex. 'claude' sends a 1-token probe; 'codex' is free.",
19
+ },
20
+ },
21
+ required: [],
22
+ },
23
+ };
24
+ export async function checkQuotaTool(args, ctx) {
25
+ const which = args.provider === "claude"
26
+ ? ["claude"]
27
+ : args.provider === "codex"
28
+ ? ["codex"]
29
+ : ["claude", "codex"];
30
+ const creds = await resolveQuotaCredentials();
31
+ const result = await checkQuota({
32
+ creds,
33
+ providers: which,
34
+ signal: ctx?.signal,
35
+ });
36
+ const nowSec = Math.floor(Date.now() / 1000);
37
+ return formatQuota(result, nowSec);
38
+ }
@@ -0,0 +1,52 @@
1
+ import { type ToolContext, type ToolDefinition } from "@cjhyy/code-shell-core/extension";
2
+ import { type AgentRunResult } from "../cc-orchestrator/external-agent-driver.js";
3
+ import { readExternalChangedFiles } from "../cc-orchestrator/external-agent-changes.js";
4
+ import { type ExternalAgentSessionBinding, type ExternalAgentSessionRecord } from "../cc-orchestrator/external-agent-session-store.js";
5
+ export type DriveCli = "claude" | "codex";
6
+ export type DriveIsolation = "current" | "worktree" | "none";
7
+ export type DriveWorktreeCleanup = "auto" | "keep" | "detach" | "discard";
8
+ export declare const DRIVE_AGENT_FOREGROUND_HANDOFF_MS = 110000;
9
+ export declare const DRIVE_AGENT_TOOL_TIMEOUT_MS = 1800000;
10
+ export declare const driveAgentToolDef: ToolDefinition;
11
+ type PermMode = "default" | "acceptEdits" | "bypassPermissions";
12
+ type Runner = (opts: {
13
+ cli: DriveCli;
14
+ prompt: string;
15
+ resumeSessionId?: string;
16
+ model?: string;
17
+ cwd: string;
18
+ permissionMode?: PermMode;
19
+ signal?: AbortSignal;
20
+ imagePaths?: string[];
21
+ }) => Promise<AgentRunResult>;
22
+ type SessionStore = {
23
+ get(cli: DriveCli, sessionId: string): ExternalAgentSessionBinding | undefined;
24
+ record(binding: ExternalAgentSessionRecord): void;
25
+ };
26
+ export interface DriveAgentToolOptions {
27
+ foregroundHandoffMs?: number;
28
+ sessionStore?: SessionStore;
29
+ /** Test seam for external transcript attribution. */
30
+ readChangedFiles?: typeof readExternalChangedFiles;
31
+ }
32
+ /** Factory so tests can inject a fake runner. `fixedCli` (back-compat) forces a
33
+ * cli and hides the `cli` arg — that's how DriveClaudeCode stays a thin alias. */
34
+ export declare function makeDriveAgentTool(runner?: Runner, fixedCli?: DriveCli, options?: DriveAgentToolOptions): (args: Record<string, unknown>, ctx?: ToolContext) => Promise<string>;
35
+ export declare const driveAgentTool: (args: Record<string, unknown>, ctx?: ToolContext) => Promise<string>;
36
+ export declare const driveAgentJobsToolDef: ToolDefinition;
37
+ export declare function driveAgentJobsTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
38
+ export declare const driveClaudeCodeToolDef: ToolDefinition;
39
+ /** Back-compat factory: a DriveAgent pinned to cli:"claude" with the `cli` arg
40
+ * hidden. The injected `runner` here keeps the old shape (no `cli` field); we
41
+ * adapt it to the generic Runner so existing tests' fakes still work. */
42
+ type LegacyRunner = (opts: {
43
+ prompt: string;
44
+ resumeSessionId?: string;
45
+ model?: string;
46
+ cwd: string;
47
+ permissionMode?: PermMode;
48
+ signal?: AbortSignal;
49
+ }) => Promise<AgentRunResult>;
50
+ export declare function makeDriveClaudeCodeTool(runner?: LegacyRunner, options?: DriveAgentToolOptions): (args: Record<string, unknown>, ctx?: ToolContext) => Promise<string>;
51
+ export declare const driveClaudeCodeTool: (args: Record<string, unknown>, ctx?: ToolContext) => Promise<string>;
52
+ export {};