tinker-agent 1.0.65
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 +173 -0
- package/package.json +78 -0
- package/patches/markdansi@0.3.2.patch +37 -0
- package/src/agent/context-builder.ts +43 -0
- package/src/agent/context-meter.ts +310 -0
- package/src/agent/loop.ts +525 -0
- package/src/agent/runtime-session.ts +1212 -0
- package/src/agent/session-ledger.ts +828 -0
- package/src/agent/turn-cancellation.ts +44 -0
- package/src/agent/types.ts +77 -0
- package/src/cli/config.ts +283 -0
- package/src/cli/index.ts +29 -0
- package/src/cli/model-profiles.ts +289 -0
- package/src/cli/run-runner.ts +107 -0
- package/src/cli/tui-runner.tsx +290 -0
- package/src/context/compiled-context-hash.ts +138 -0
- package/src/context/compiled-context-validator.ts +209 -0
- package/src/context/context-manager.ts +362 -0
- package/src/context/context-policy.ts +8 -0
- package/src/context/context-protocol-validator.ts +463 -0
- package/src/context/context-revision-compiler.ts +281 -0
- package/src/context/context-revision.ts +111 -0
- package/src/context/context-source.ts +30 -0
- package/src/context/context-swap-renderer.ts +272 -0
- package/src/context/protocol-frame.ts +240 -0
- package/src/context/swap-planner.ts +725 -0
- package/src/events/append-private-file.ts +16 -0
- package/src/events/bash-result-detail.ts +70 -0
- package/src/events/composite-event-sink.ts +82 -0
- package/src/events/event-sink.ts +16 -0
- package/src/events/jsonl-event-log.ts +13 -0
- package/src/events/observation-text-log.ts +195 -0
- package/src/events/stdout-event-printer.ts +396 -0
- package/src/events/types.ts +263 -0
- package/src/ids/runtime-id.ts +68 -0
- package/src/ids/uuid-v7.ts +5 -0
- package/src/instructions/project-instructions.ts +242 -0
- package/src/mcp/mcp-config.ts +144 -0
- package/src/mcp/mcp-manager.ts +216 -0
- package/src/mcp/mcp-tool-executor.ts +178 -0
- package/src/model/committed-prefix-auditor.ts +68 -0
- package/src/model/fake-model-client.ts +280 -0
- package/src/model/model-client.ts +64 -0
- package/src/model/model-context-profile.ts +134 -0
- package/src/model/model-request-preflight.ts +120 -0
- package/src/model/openai-chat-mapping.ts +444 -0
- package/src/model/openai-chat-model-client.ts +190 -0
- package/src/model/prompt-prefix-hash.ts +47 -0
- package/src/model/token-estimator.ts +148 -0
- package/src/observation/observation-builder.ts +481 -0
- package/src/session/resume-projection.ts +616 -0
- package/src/session/session-catalog.ts +270 -0
- package/src/session/session-errors.ts +121 -0
- package/src/session/session-history-reader.ts +535 -0
- package/src/session/session-lock.ts +291 -0
- package/src/session/session-schema.ts +741 -0
- package/src/session/session-store.ts +3067 -0
- package/src/session/sqlite-session-ledger.ts +153 -0
- package/src/tools/bash-task.ts +617 -0
- package/src/tools/bash.ts +450 -0
- package/src/tools/cwd-state.ts +22 -0
- package/src/tools/edit.ts +428 -0
- package/src/tools/file-diff.ts +116 -0
- package/src/tools/glob.ts +202 -0
- package/src/tools/grep.ts +550 -0
- package/src/tools/hash.ts +9 -0
- package/src/tools/path-safety.ts +33 -0
- package/src/tools/read.ts +319 -0
- package/src/tools/recall.ts +400 -0
- package/src/tools/registry.ts +213 -0
- package/src/tools/ripgrep.ts +220 -0
- package/src/tools/task-list.ts +59 -0
- package/src/tools/task-output-snapshot.ts +47 -0
- package/src/tools/task-output-tool.ts +62 -0
- package/src/tools/task-output.ts +159 -0
- package/src/tools/task-stop.ts +59 -0
- package/src/tools/task-tool-args.ts +29 -0
- package/src/tools/types.ts +330 -0
- package/src/tools/web-fetch/backend.ts +27 -0
- package/src/tools/web-fetch/browser-backend.ts +126 -0
- package/src/tools/web-fetch/exa-backend.ts +172 -0
- package/src/tools/web-fetch/index.ts +298 -0
- package/src/tools/web-fetch/local-backend.ts +267 -0
- package/src/tools/web-fetch/refiner.ts +78 -0
- package/src/tools/web-fetch/route.ts +95 -0
- package/src/tools/web-search.ts +300 -0
- package/src/tools/write.ts +244 -0
- package/src/tui/app.tsx +497 -0
- package/src/tui/components/assistant-markdown.tsx +47 -0
- package/src/tui/components/background-tasks.tsx +92 -0
- package/src/tui/components/bash-result-view.tsx +47 -0
- package/src/tui/components/context-status.tsx +127 -0
- package/src/tui/components/diff-view.tsx +151 -0
- package/src/tui/components/file-viewer.tsx +212 -0
- package/src/tui/components/footer.tsx +60 -0
- package/src/tui/components/header.tsx +21 -0
- package/src/tui/components/model-picker.tsx +142 -0
- package/src/tui/components/prompt-input.tsx +432 -0
- package/src/tui/components/resume-session-picker.tsx +273 -0
- package/src/tui/components/timeline.tsx +121 -0
- package/src/tui/context-format.ts +24 -0
- package/src/tui/event-store.ts +865 -0
- package/src/tui/git-branch.ts +23 -0
- package/src/tui/line-editor.ts +157 -0
- package/src/tui/prompt-history.ts +94 -0
- package/src/tui/slash-commands.ts +126 -0
- package/src/tui/tui-projection-policy.ts +35 -0
- package/src/tui/tui-projection-store.ts +123 -0
- package/src/tui/tui-session-controller.ts +170 -0
- package/src/tui/view-file.ts +122 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { stat } from "node:fs/promises";
|
|
3
|
+
import { glob } from "glob";
|
|
4
|
+
import { cancellationError, throwIfTurnCancelled } from "../agent/turn-cancellation";
|
|
5
|
+
import { resolveWorkspacePath, toDisplayPath } from "./path-safety";
|
|
6
|
+
import { defineToolExecutor } from "./types";
|
|
7
|
+
import type { GlobRawResult, ToolExecutionContext, ToolExecutor } from "./types";
|
|
8
|
+
|
|
9
|
+
type GlobArgs = {
|
|
10
|
+
pattern: string;
|
|
11
|
+
path?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type GlobToolOptions = {
|
|
15
|
+
workspaceRoot: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const ignoredDirectories = ["node_modules", ".git"];
|
|
19
|
+
|
|
20
|
+
export function createGlobToolExecutor(options: GlobToolOptions): ToolExecutor {
|
|
21
|
+
return defineToolExecutor("glob", {
|
|
22
|
+
definition: {
|
|
23
|
+
name: "Glob",
|
|
24
|
+
description: "Find files by glob pattern. node_modules and .git are ignored.",
|
|
25
|
+
parameters: {
|
|
26
|
+
type: "object",
|
|
27
|
+
additionalProperties: false,
|
|
28
|
+
properties: {
|
|
29
|
+
pattern: {
|
|
30
|
+
type: "string",
|
|
31
|
+
description: 'Glob pattern such as "**/*.ts" or "src/**/*.tsx".',
|
|
32
|
+
},
|
|
33
|
+
path: {
|
|
34
|
+
type: "string",
|
|
35
|
+
description:
|
|
36
|
+
"Optional workspace-relative or absolute search directory. Defaults to the workspace root.",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ["pattern"],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
async execute(args, _call, context: ToolExecutionContext): Promise<GlobRawResult> {
|
|
43
|
+
throwIfTurnCancelled(context.signal);
|
|
44
|
+
const parsed = parseGlobArgs(args);
|
|
45
|
+
|
|
46
|
+
if (!parsed.ok) {
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
pattern: "",
|
|
50
|
+
searchPath: ".",
|
|
51
|
+
ignored: ignoredDirectories,
|
|
52
|
+
error: parsed.error,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const input = parsed.value;
|
|
57
|
+
let absoluteSearchPath: string;
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
absoluteSearchPath = resolveWorkspacePath(
|
|
61
|
+
options.workspaceRoot,
|
|
62
|
+
input.path ?? ".",
|
|
63
|
+
);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
pattern: input.pattern,
|
|
68
|
+
searchPath: input.path ?? ".",
|
|
69
|
+
ignored: ignoredDirectories,
|
|
70
|
+
error: errorMessage(error),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const searchPath = toDisplayPath(options.workspaceRoot, absoluteSearchPath);
|
|
75
|
+
|
|
76
|
+
const directoryCheck = await ensureDirectory(absoluteSearchPath);
|
|
77
|
+
throwIfTurnCancelled(context.signal);
|
|
78
|
+
if (!directoryCheck.ok) {
|
|
79
|
+
return {
|
|
80
|
+
ok: false,
|
|
81
|
+
pattern: input.pattern,
|
|
82
|
+
searchPath,
|
|
83
|
+
absoluteSearchPath,
|
|
84
|
+
ignored: ignoredDirectories,
|
|
85
|
+
error: directoryCheck.error,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const matches = await glob(input.pattern, {
|
|
91
|
+
cwd: absoluteSearchPath,
|
|
92
|
+
nodir: true,
|
|
93
|
+
dot: true,
|
|
94
|
+
follow: false,
|
|
95
|
+
signal: context.signal,
|
|
96
|
+
ignore: ["**/node_modules/**", "**/.git/**"],
|
|
97
|
+
});
|
|
98
|
+
const displayMatches = toDisplayMatches({
|
|
99
|
+
workspaceRoot: options.workspaceRoot,
|
|
100
|
+
absoluteSearchPath,
|
|
101
|
+
matches,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
ok: true,
|
|
106
|
+
pattern: input.pattern,
|
|
107
|
+
searchPath,
|
|
108
|
+
absoluteSearchPath,
|
|
109
|
+
matches: displayMatches,
|
|
110
|
+
matchCount: displayMatches.length,
|
|
111
|
+
ignored: ignoredDirectories,
|
|
112
|
+
};
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (context.signal.aborted) {
|
|
115
|
+
throw cancellationError(context.signal, error);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
ok: false,
|
|
120
|
+
pattern: input.pattern,
|
|
121
|
+
searchPath,
|
|
122
|
+
absoluteSearchPath,
|
|
123
|
+
ignored: ignoredDirectories,
|
|
124
|
+
error: errorMessage(error),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function parseGlobArgs(
|
|
132
|
+
args: unknown,
|
|
133
|
+
): { ok: true; value: GlobArgs } | { ok: false; error: string } {
|
|
134
|
+
if (!isRecord(args)) {
|
|
135
|
+
return { ok: false, error: "Glob arguments must be an object." };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (typeof args.pattern !== "string" || args.pattern.trim() === "") {
|
|
139
|
+
return { ok: false, error: "Glob.pattern must be a non-empty string." };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (path.isAbsolute(args.pattern)) {
|
|
143
|
+
return { ok: false, error: "Glob.pattern must be relative to Glob.path." };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (hasParentDirectorySegment(args.pattern)) {
|
|
147
|
+
return { ok: false, error: "Glob.pattern must not contain '..' segments." };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (args.path !== undefined && typeof args.path !== "string") {
|
|
151
|
+
return { ok: false, error: "Glob.path must be a string." };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
ok: true,
|
|
156
|
+
value: {
|
|
157
|
+
pattern: args.pattern,
|
|
158
|
+
path: args.path,
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function hasParentDirectorySegment(pattern: string): boolean {
|
|
164
|
+
return pattern.split(/[\\/]+/).some((segment) => segment === "..");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function ensureDirectory(
|
|
168
|
+
directoryPath: string,
|
|
169
|
+
): Promise<{ ok: true } | { ok: false; error: string }> {
|
|
170
|
+
try {
|
|
171
|
+
const info = await stat(directoryPath);
|
|
172
|
+
return info.isDirectory()
|
|
173
|
+
? { ok: true }
|
|
174
|
+
: { ok: false, error: "Glob.path is not a directory." };
|
|
175
|
+
} catch {
|
|
176
|
+
return { ok: false, error: "Glob.path does not exist." };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function toDisplayMatches(input: {
|
|
181
|
+
workspaceRoot: string;
|
|
182
|
+
absoluteSearchPath: string;
|
|
183
|
+
matches: string[];
|
|
184
|
+
}): string[] {
|
|
185
|
+
const normalized = input.matches.map((match) => {
|
|
186
|
+
const absolutePath = resolveWorkspacePath(
|
|
187
|
+
input.workspaceRoot,
|
|
188
|
+
path.resolve(input.absoluteSearchPath, match),
|
|
189
|
+
);
|
|
190
|
+
return toDisplayPath(input.workspaceRoot, absolutePath);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
return [...new Set(normalized)].sort((left, right) => left.localeCompare(right));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
197
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function errorMessage(error: unknown): string {
|
|
201
|
+
return error instanceof Error ? error.message : String(error);
|
|
202
|
+
}
|