surfcode 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +325 -2
- package/assets/surfcode-logo.gif +0 -0
- package/dist/cli/auth.js +315 -0
- package/dist/cli/auth.js.map +1 -0
- package/dist/cli/config.js +228 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/headless.js +355 -0
- package/dist/cli/headless.js.map +1 -0
- package/dist/cli/inspect.js +462 -0
- package/dist/cli/inspect.js.map +1 -0
- package/dist/cli/interactive.js +130 -0
- package/dist/cli/interactive.js.map +1 -0
- package/dist/cli/sessions.js +170 -0
- package/dist/cli/sessions.js.map +1 -0
- package/dist/cli/sync.js +190 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli/util.js +345 -0
- package/dist/cli/util.js.map +1 -0
- package/dist/cli.js +485 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/agent.js +298 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/agents.js +55 -0
- package/dist/core/agents.js.map +1 -0
- package/dist/core/auth.js +107 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/catalog.js +306 -0
- package/dist/core/catalog.js.map +1 -0
- package/dist/core/chat/anthropic.js +222 -0
- package/dist/core/chat/anthropic.js.map +1 -0
- package/dist/core/chat/common.js +367 -0
- package/dist/core/chat/common.js.map +1 -0
- package/dist/core/chat/google.js +180 -0
- package/dist/core/chat/google.js.map +1 -0
- package/dist/core/chat/index.js +80 -0
- package/dist/core/chat/index.js.map +1 -0
- package/dist/core/chat/openai.js +164 -0
- package/dist/core/chat/openai.js.map +1 -0
- package/dist/core/chat/types.js +2 -0
- package/dist/core/chat/types.js.map +1 -0
- package/dist/core/clipboard.js +34 -0
- package/dist/core/clipboard.js.map +1 -0
- package/dist/core/compact.js +39 -0
- package/dist/core/compact.js.map +1 -0
- package/dist/core/config.js +211 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/delegate.js +184 -0
- package/dist/core/delegate.js.map +1 -0
- package/dist/core/effort.js +80 -0
- package/dist/core/effort.js.map +1 -0
- package/dist/core/errors.js +32 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/free.js +21 -0
- package/dist/core/free.js.map +1 -0
- package/dist/core/github.js +445 -0
- package/dist/core/github.js.map +1 -0
- package/dist/core/paths.js +51 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/prompt.js +95 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/provider.js +298 -0
- package/dist/core/provider.js.map +1 -0
- package/dist/core/session.js +159 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/sync.js +126 -0
- package/dist/core/sync.js.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/usage.js +127 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/core/workspace.js +70 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/data/models.json +1 -0
- package/dist/sync/server.js +179 -0
- package/dist/sync/server.js.map +1 -0
- package/dist/tools/diff.js +21 -0
- package/dist/tools/diff.js.map +1 -0
- package/dist/tools/files.js +227 -0
- package/dist/tools/files.js.map +1 -0
- package/dist/tools/github.js +238 -0
- package/dist/tools/github.js.map +1 -0
- package/dist/tools/index.js +34 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/search.js +231 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/shell.js +118 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/tools/todos.js +50 -0
- package/dist/tools/todos.js.map +1 -0
- package/dist/tools/webfetch.js +108 -0
- package/dist/tools/webfetch.js.map +1 -0
- package/dist/tui/App.js +2984 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/ansi.js +151 -0
- package/dist/tui/ansi.js.map +1 -0
- package/dist/tui/commands.js +61 -0
- package/dist/tui/commands.js.map +1 -0
- package/dist/tui/explorer.js +152 -0
- package/dist/tui/explorer.js.map +1 -0
- package/dist/tui/icons.js +21 -0
- package/dist/tui/icons.js.map +1 -0
- package/dist/tui/layout.js +324 -0
- package/dist/tui/layout.js.map +1 -0
- package/dist/tui/markdown.js +355 -0
- package/dist/tui/markdown.js.map +1 -0
- package/dist/tui/overlays.js +316 -0
- package/dist/tui/overlays.js.map +1 -0
- package/dist/tui/render.js +234 -0
- package/dist/tui/render.js.map +1 -0
- package/dist/tui/theme.js +148 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/tui/types.js +73 -0
- package/dist/tui/types.js.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +75 -4
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export function emptyUsage() {
|
|
2
|
+
return {
|
|
3
|
+
inputTokens: 0,
|
|
4
|
+
outputTokens: 0,
|
|
5
|
+
reasoningTokens: 0,
|
|
6
|
+
cacheReadTokens: 0,
|
|
7
|
+
cacheWriteTokens: 0,
|
|
8
|
+
cost: 0,
|
|
9
|
+
requests: 0
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function addUsage(total, delta) {
|
|
13
|
+
for (const key of [
|
|
14
|
+
'inputTokens',
|
|
15
|
+
'outputTokens',
|
|
16
|
+
'reasoningTokens',
|
|
17
|
+
'cacheReadTokens',
|
|
18
|
+
'cacheWriteTokens',
|
|
19
|
+
'cost',
|
|
20
|
+
'requests'
|
|
21
|
+
]) {
|
|
22
|
+
total[key] = (total[key] ?? 0) + (delta[key] ?? 0);
|
|
23
|
+
}
|
|
24
|
+
return total;
|
|
25
|
+
}
|
|
26
|
+
export function costForUsage(meta, usage, dialect) {
|
|
27
|
+
const cost = meta?.cost;
|
|
28
|
+
if (!cost)
|
|
29
|
+
return 0;
|
|
30
|
+
const perMillion = 1_000_000;
|
|
31
|
+
const inputRate = Number(cost.input ?? 0);
|
|
32
|
+
const outputRate = Number(cost.output ?? 0);
|
|
33
|
+
const cacheReadRate = Number(cost.cache_read ?? inputRate);
|
|
34
|
+
const cacheWriteRate = Number(cost.cache_write ?? inputRate);
|
|
35
|
+
const reasoningRate = Number(cost.reasoning ?? outputRate);
|
|
36
|
+
const input = Number(usage.inputTokens ?? 0);
|
|
37
|
+
const output = Number(usage.outputTokens ?? 0);
|
|
38
|
+
const reasoning = Number(usage.reasoningTokens ?? 0);
|
|
39
|
+
const cacheRead = Number(usage.cacheReadTokens ?? 0);
|
|
40
|
+
const cacheWrite = Number(usage.cacheWriteTokens ?? 0);
|
|
41
|
+
// Anthropic reports non-cached input in input_tokens and bills cached input
|
|
42
|
+
// separately. OpenAI-compatible APIs and Google report total prompt tokens,
|
|
43
|
+
// so cached tokens must be subtracted before applying the input rate.
|
|
44
|
+
if (dialect === 'anthropic') {
|
|
45
|
+
// Anthropic's output_tokens already includes thinking tokens.
|
|
46
|
+
return ((input * inputRate +
|
|
47
|
+
output * outputRate +
|
|
48
|
+
cacheRead * cacheReadRate +
|
|
49
|
+
cacheWrite * cacheWriteRate) /
|
|
50
|
+
perMillion);
|
|
51
|
+
}
|
|
52
|
+
// Gemini reports thinking tokens separately from candidatesTokenCount.
|
|
53
|
+
// OpenAI-compatible APIs already include reasoning inside completion_tokens.
|
|
54
|
+
const isGoogle = dialect === 'google' || dialect === 'google-vertex';
|
|
55
|
+
const billableInput = Math.max(0, input - cacheRead - cacheWrite);
|
|
56
|
+
const outputCost = output * outputRate + (isGoogle ? reasoning * reasoningRate : 0);
|
|
57
|
+
return ((billableInput * inputRate + outputCost + cacheRead * cacheReadRate + cacheWrite * cacheWriteRate) /
|
|
58
|
+
perMillion);
|
|
59
|
+
}
|
|
60
|
+
export function estimateTokens(value) {
|
|
61
|
+
if (!value)
|
|
62
|
+
return 0;
|
|
63
|
+
// A deliberately conservative approximation that works across providers.
|
|
64
|
+
let ascii = 0;
|
|
65
|
+
let other = 0;
|
|
66
|
+
for (const char of value) {
|
|
67
|
+
if (char.charCodeAt(0) < 128)
|
|
68
|
+
ascii += 1;
|
|
69
|
+
else
|
|
70
|
+
other += 1;
|
|
71
|
+
}
|
|
72
|
+
return Math.ceil(ascii / 3.7 + other / 1.6);
|
|
73
|
+
}
|
|
74
|
+
export function estimateMessageTokens(message) {
|
|
75
|
+
if (message.role === 'tool')
|
|
76
|
+
return estimateTokens(message.content) + 8;
|
|
77
|
+
if (message.role === 'user')
|
|
78
|
+
return estimateTokens(message.content) + 6;
|
|
79
|
+
let total = estimateTokens(message.content) + estimateTokens(message.reasoning ?? '') + 8;
|
|
80
|
+
for (const call of message.toolCalls ?? []) {
|
|
81
|
+
total += estimateTokens(call.name) + estimateTokens(JSON.stringify(call.arguments)) + 12;
|
|
82
|
+
}
|
|
83
|
+
return total;
|
|
84
|
+
}
|
|
85
|
+
export function estimateContextTokens(messages, system) {
|
|
86
|
+
let total = estimateTokens(system) + 20;
|
|
87
|
+
for (const message of messages)
|
|
88
|
+
total += estimateMessageTokens(message);
|
|
89
|
+
return total;
|
|
90
|
+
}
|
|
91
|
+
export function formatTokens(value) {
|
|
92
|
+
if (value >= 1_000_000)
|
|
93
|
+
return `${(value / 1_000_000).toFixed(value >= 10_000_000 ? 0 : 1)}m`;
|
|
94
|
+
if (value >= 10_000)
|
|
95
|
+
return `${Math.round(value / 1000)}k`;
|
|
96
|
+
if (value >= 1000)
|
|
97
|
+
return `${(value / 1000).toFixed(1)}k`;
|
|
98
|
+
return String(Math.max(0, Math.round(value)));
|
|
99
|
+
}
|
|
100
|
+
export function formatCost(value) {
|
|
101
|
+
if (!Number.isFinite(value) || value <= 0)
|
|
102
|
+
return '$0.00';
|
|
103
|
+
if (value < 0.0001)
|
|
104
|
+
return `$${value.toFixed(6).replace(/0+$/, '').replace(/\.$/, '.0')}`;
|
|
105
|
+
if (value < 0.01)
|
|
106
|
+
return `$${value.toFixed(4)}`;
|
|
107
|
+
if (value < 1)
|
|
108
|
+
return `$${value.toFixed(3)}`;
|
|
109
|
+
return `$${value.toFixed(2)}`;
|
|
110
|
+
}
|
|
111
|
+
export function formatPrice(model) {
|
|
112
|
+
if (!model?.cost?.input && !model?.cost?.output)
|
|
113
|
+
return 'free';
|
|
114
|
+
const input = Number(model.cost.input ?? 0);
|
|
115
|
+
const output = Number(model.cost.output ?? 0);
|
|
116
|
+
return `$${formatRate(input)} / $${formatRate(output)} per Mtok`;
|
|
117
|
+
}
|
|
118
|
+
function formatRate(value) {
|
|
119
|
+
if (value === 0)
|
|
120
|
+
return '0';
|
|
121
|
+
if (value < 0.01)
|
|
122
|
+
return value.toFixed(3);
|
|
123
|
+
if (value < 1)
|
|
124
|
+
return value.toFixed(2);
|
|
125
|
+
return value.toFixed(value % 1 === 0 ? 0 : 2);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/core/usage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { isAbsolute, relative, resolve, sep } from 'node:path';
|
|
3
|
+
import ignore from 'ignore';
|
|
4
|
+
import { SurfError } from './errors.js';
|
|
5
|
+
export function resolveWorkspacePath(input, cwd, allowOutsideWorkspace) {
|
|
6
|
+
if (!input || input.includes('\0'))
|
|
7
|
+
throw new SurfError('A file path is required.');
|
|
8
|
+
const absolute = isAbsolute(input) ? resolve(input) : resolve(cwd, input);
|
|
9
|
+
const rel = relative(cwd, absolute);
|
|
10
|
+
const outside = rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel);
|
|
11
|
+
if (outside && !allowOutsideWorkspace) {
|
|
12
|
+
throw new SurfError(`Path is outside the workspace: ${input}`, {
|
|
13
|
+
hint: 'Enable allowOutsideWorkspace in config, or use a path inside the project.'
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return { absolute, relative: rel === '' ? '.' : rel };
|
|
17
|
+
}
|
|
18
|
+
export function displayPath(cwd, absolute) {
|
|
19
|
+
const rel = relative(cwd, absolute);
|
|
20
|
+
if (!rel || rel === '')
|
|
21
|
+
return '.';
|
|
22
|
+
if (rel.startsWith('..'))
|
|
23
|
+
return absolute;
|
|
24
|
+
return rel.split(sep).join('/');
|
|
25
|
+
}
|
|
26
|
+
export async function loadIgnore(cwd) {
|
|
27
|
+
const matcher = ignore();
|
|
28
|
+
matcher.add(['.git/', 'node_modules/', 'dist/', 'build/', 'coverage/', '.next/', '.turbo/', '.cache/']);
|
|
29
|
+
for (const name of ['.gitignore', '.surfcodeignore']) {
|
|
30
|
+
try {
|
|
31
|
+
const content = await readFile(resolve(cwd, name), 'utf8');
|
|
32
|
+
matcher.add(content);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Optional.
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return matcher;
|
|
39
|
+
}
|
|
40
|
+
export function filterIgnored(matcher, cwd, paths) {
|
|
41
|
+
return paths.filter((path) => {
|
|
42
|
+
const normalized = path.split(sep).join('/');
|
|
43
|
+
return !matcher.ignores(normalized);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
export function isProbablyBinary(buffer) {
|
|
47
|
+
const sample = buffer.subarray(0, Math.min(buffer.length, 8_192));
|
|
48
|
+
if (sample.includes(0))
|
|
49
|
+
return true;
|
|
50
|
+
let control = 0;
|
|
51
|
+
for (const byte of sample) {
|
|
52
|
+
if (byte === 9 || byte === 10 || byte === 13)
|
|
53
|
+
continue;
|
|
54
|
+
if (byte < 7 || (byte > 13 && byte < 32))
|
|
55
|
+
control += 1;
|
|
56
|
+
}
|
|
57
|
+
return control / Math.max(sample.length, 1) > 0.05;
|
|
58
|
+
}
|
|
59
|
+
export function clip(text, max) {
|
|
60
|
+
if (text.length <= max)
|
|
61
|
+
return { text, truncated: false };
|
|
62
|
+
return {
|
|
63
|
+
text: `${text.slice(0, max)}\n\n… output truncated (${text.length - max} characters omitted)`,
|
|
64
|
+
truncated: true
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function normalizeOutput(text) {
|
|
68
|
+
return text.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/core/workspace.ts"],"names":[],"mappings":"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"}
|