farming-code 2.2.16 → 2.2.18
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 +2 -2
- package/README.zh_cn.md +2 -2
- package/THIRD_PARTY_NOTICES.md +16 -0
- package/backend/acp-runtime.js +221 -10
- package/backend/agent-manager.js +477 -54
- package/backend/agent-provider-session.js +15 -1
- package/backend/codex-rollout-follower.js +83 -0
- package/backend/codex-session-archive.js +12 -1
- package/backend/codex-session-history.js +94 -0
- package/backend/config-manager.js +3 -3
- package/backend/farming-app-cli.js +8 -0
- package/backend/native-pty-host-client.js +59 -2
- package/backend/provider-adapters.js +117 -36
- package/backend/provider-session-service.js +138 -34
- package/backend/server.js +5 -1
- package/backend/storage-layout.js +5 -0
- package/backend/usage-history-client.js +305 -0
- package/backend/usage-history-scanner.generated.js +2250 -0
- package/backend/usage-history-scanner.ts +2718 -0
- package/backend/usage-history-smoke.js +64 -0
- package/backend/usage-history-worker.js +34 -0
- package/backend/usage-monitor.js +188 -588
- package/backend/vendor/usage-parsers/CC_STATISTICS_LICENSE +21 -0
- package/backend/vendor/usage-parsers/CODEXBAR_LICENSE +21 -0
- package/backend/vendor/usage-parsers/VENDOR.json +45 -0
- package/dist/assets/App-DTAQilnX.js +210 -0
- package/dist/assets/code-dark-5esj0bRu.css +1 -0
- package/dist/assets/{index-iKBvPjWS.js → index-fp8VhOes.js} +2 -2
- package/dist/assets/main-DSO3i_Gs.css +1 -0
- package/dist/index.html +1 -1
- package/frontend/skins/crt/app.js +9 -3
- package/package.json +12 -8
- package/shared/backend-connection-status.d.ts +25 -0
- package/shared/backend-connection-status.js +40 -0
- package/dist/assets/App-y6p2yRar.js +0 -206
- package/dist/assets/code-dark-DKBGxoPX.css +0 -1
- package/dist/assets/main-CdkLOXYl.css +0 -1
package/dist/index.html
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<link rel="apple-touch-icon" sizes="180x180" href="/farming/farming-2/app-icon-v2-180.png" />
|
|
16
16
|
<link rel="manifest" href="/farming/farming-2/site.webmanifest" />
|
|
17
17
|
<title>Farming 2</title>
|
|
18
|
-
<script type="module" crossorigin src="/farming/assets/index-
|
|
18
|
+
<script type="module" crossorigin src="/farming/assets/index-fp8VhOes.js"></script>
|
|
19
19
|
<link rel="modulepreload" crossorigin href="/farming/assets/chunk-DECur_0Z.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="/farming/assets/preload-helper-mJowh_hw.js">
|
|
21
21
|
<link rel="modulepreload" crossorigin href="/farming/assets/jsx-runtime-BthL93pI.js">
|
|
@@ -3856,11 +3856,17 @@ function renderCrtBillingSelectedDay({ preferSummary = false } = {}) {
|
|
|
3856
3856
|
updateCrtBillingExactMetric('billing-day-cache-read', displayPoint && displayPoint.cacheReadTokens, { date: selectedDate, live: isToday });
|
|
3857
3857
|
updateCrtBillingExactMetric('billing-day-cache-write', displayPoint && displayPoint.cacheWriteTokens, { date: selectedDate, live: isToday });
|
|
3858
3858
|
if (providers) {
|
|
3859
|
-
const providerTotals = displayProviders
|
|
3860
|
-
|
|
3859
|
+
const providerTotals = displayProviders
|
|
3860
|
+
? Object.entries(displayProviders).filter(([, usage]) => (
|
|
3861
|
+
Math.max(0, Number(usage && usage.totalTokens) || 0) > 0
|
|
3862
|
+
))
|
|
3863
|
+
: [];
|
|
3864
|
+
providers.textContent = providerTotals.length > 0
|
|
3865
|
+
? `${providerTotals.length} ${providerTotals.length === 1 ? 'SOURCE' : 'SOURCES'}`
|
|
3866
|
+
: '--';
|
|
3867
|
+
providers.title = providerTotals
|
|
3861
3868
|
.map(([provider, usage]) => `${provider.toUpperCase()} ${formatCrtExactUsageValue(usage && usage.totalTokens)}`)
|
|
3862
3869
|
.join(' · ') || '--';
|
|
3863
|
-
providers.title = providers.textContent;
|
|
3864
3870
|
}
|
|
3865
3871
|
if (stateLabel) {
|
|
3866
3872
|
const notes = isToday ? ['LIVE 5S', 'PARTIAL DAY', 'INCL CACHE'] : ['COMPLETE DAY', 'INCL CACHE'];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "farming-code",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.18",
|
|
4
4
|
"description": "Remote browser workspace for supervising AI coding agents",
|
|
5
5
|
"main": "backend/server.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"backend/*.js",
|
|
11
|
+
"backend/usage-history-scanner.ts",
|
|
11
12
|
"backend/acp/",
|
|
12
13
|
"backend/data/",
|
|
14
|
+
"backend/vendor/usage-parsers/",
|
|
13
15
|
"bin/",
|
|
14
16
|
"config/*.example",
|
|
15
17
|
"dist/",
|
|
@@ -29,16 +31,17 @@
|
|
|
29
31
|
"scripts": {
|
|
30
32
|
"sync:ghostty-vendor": "node scripts/sync-ghostty-vendor.js",
|
|
31
33
|
"prepare:acp-vendor": "node scripts/prepare-codex-acp-vendor.js --copy",
|
|
32
|
-
"
|
|
34
|
+
"build:usage-history": "node scripts/build-usage-history-scanner.js",
|
|
35
|
+
"prebuild": "node scripts/build-usage-history-scanner.js && node scripts/sync-ghostty-vendor.js && node scripts/prepare-codex-acp-vendor.js",
|
|
33
36
|
"prepack": "FARMING_BASE_PATH=/farming npm run build",
|
|
34
|
-
"pretest": "npm run prepare:acp-vendor",
|
|
37
|
+
"pretest": "npm run prepare:acp-vendor && npm run build:usage-history",
|
|
35
38
|
"start": "npm run build && node backend/server.js",
|
|
36
39
|
"start:net": "node backend/farming-net-server.js",
|
|
37
40
|
"start:no-auth": "FARMING_DISABLE_AUTH=1 npm start",
|
|
38
|
-
"predev:backend": "npm run prepare:acp-vendor && npm run build:crt-markdown",
|
|
41
|
+
"predev:backend": "npm run prepare:acp-vendor && npm run build:usage-history && npm run build:crt-markdown",
|
|
39
42
|
"dev:backend": "node backend/server.js",
|
|
40
43
|
"dev:frontend": "vite",
|
|
41
|
-
"predev": "npm run prepare:acp-vendor && npm run build:crt-markdown",
|
|
44
|
+
"predev": "npm run prepare:acp-vendor && npm run build:usage-history && npm run build:crt-markdown",
|
|
42
45
|
"dev": "node backend/server.js & vite --open & wait",
|
|
43
46
|
"build:crt-markdown": "node -e \"require('fs').rmSync('dist/crt-markdown-assets',{recursive:true,force:true})\" && esbuild src/crt-markdown-renderer.tsx --bundle --outdir=dist --entry-names=crt-markdown-renderer --asset-names=crt-markdown-assets/[name]-[hash] --platform=browser --format=iife --target=es2022 --loader:.woff=file --loader:.woff2=file --loader:.ttf=file --minify && esbuild src/crt-mermaid-runtime.ts --bundle --outfile=dist/crt-mermaid-renderer.js --platform=browser --format=iife --target=es2022 --minify",
|
|
44
47
|
"build": "vite build && npm run build:crt-markdown && npm run prepare:acp-vendor",
|
|
@@ -71,8 +74,8 @@
|
|
|
71
74
|
"test:remote-terminal:chaos": "node scripts/smoke-remote-terminal-chaos.js",
|
|
72
75
|
"test:e2e:workspaces:local": "FARMING_BASE_PATH=/farming npm run build && node scripts/e2e-workspaces.js local",
|
|
73
76
|
"test:e2e:workspaces:remote": "FARMING_BASE_PATH=/farming npm run build && node scripts/e2e-workspaces.js remote",
|
|
74
|
-
"typecheck": "tsc --noEmit",
|
|
75
|
-
"lint": "eslint --max-warnings=0 \"backend/**/*.js\" \"frontend/**/*.js\" \"scripts/**/*.js\" bin/farming --ignore-pattern \"frontend/vendor/**\" --ignore-pattern \"frontend/themes/**\"",
|
|
77
|
+
"typecheck": "tsc --noEmit && tsc -p tsconfig.usage.json",
|
|
78
|
+
"lint": "eslint --max-warnings=0 \"backend/**/*.js\" \"frontend/**/*.js\" \"scripts/**/*.js\" bin/farming --ignore-pattern \"backend/usage-history-scanner.generated.js\" --ignore-pattern \"frontend/vendor/**\" --ignore-pattern \"frontend/themes/**\"",
|
|
76
79
|
"check": "npm run typecheck && npm run lint && npm test"
|
|
77
80
|
},
|
|
78
81
|
"keywords": [
|
|
@@ -97,7 +100,7 @@
|
|
|
97
100
|
"access": "public"
|
|
98
101
|
},
|
|
99
102
|
"engines": {
|
|
100
|
-
"node": ">=
|
|
103
|
+
"node": "^22.13.0 || >=24.0.0"
|
|
101
104
|
},
|
|
102
105
|
"dependencies": {
|
|
103
106
|
"@agentclientprotocol/claude-agent-acp": "0.59.0",
|
|
@@ -137,6 +140,7 @@
|
|
|
137
140
|
"devDependencies": {
|
|
138
141
|
"@eslint/js": "^10.0.1",
|
|
139
142
|
"@playwright/test": "^1.59.1",
|
|
143
|
+
"@types/node": "^26.1.1",
|
|
140
144
|
"@types/react": "^19.2.14",
|
|
141
145
|
"@types/react-dom": "^19.2.3",
|
|
142
146
|
"@vitejs/plugin-react": "^6.0.1",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const BACKEND_INITIAL_CONNECT_GRACE_MS: number
|
|
2
|
+
export const BACKEND_HEARTBEAT_STALE_MS: number
|
|
3
|
+
|
|
4
|
+
export type BackendConnectionState = 'connecting' | 'lost' | 'stale' | null
|
|
5
|
+
export interface PageVisibilitySnapshot {
|
|
6
|
+
visible: boolean
|
|
7
|
+
visibleSince: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function classifyBackendConnection(input: {
|
|
11
|
+
connected: boolean
|
|
12
|
+
everConnected: boolean
|
|
13
|
+
lastMessageAt: number
|
|
14
|
+
visibleSince: number
|
|
15
|
+
now: number
|
|
16
|
+
}): BackendConnectionState
|
|
17
|
+
|
|
18
|
+
export function reducePageVisibilitySnapshot(
|
|
19
|
+
current: PageVisibilitySnapshot,
|
|
20
|
+
event: {
|
|
21
|
+
eventType: string
|
|
22
|
+
documentVisible: boolean
|
|
23
|
+
changedAt: number
|
|
24
|
+
},
|
|
25
|
+
): PageVisibilitySnapshot
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const BACKEND_INITIAL_CONNECT_GRACE_MS = 3000;
|
|
2
|
+
const BACKEND_HEARTBEAT_STALE_MS = 6000;
|
|
3
|
+
|
|
4
|
+
function classifyBackendConnection({
|
|
5
|
+
connected,
|
|
6
|
+
everConnected,
|
|
7
|
+
lastMessageAt,
|
|
8
|
+
visibleSince,
|
|
9
|
+
now,
|
|
10
|
+
}) {
|
|
11
|
+
const observationStartedAt = Math.max(lastMessageAt, visibleSince);
|
|
12
|
+
const elapsed = Math.max(0, now - observationStartedAt);
|
|
13
|
+
if (!connected && everConnected) return 'lost';
|
|
14
|
+
if (!connected && elapsed >= BACKEND_INITIAL_CONNECT_GRACE_MS) return 'connecting';
|
|
15
|
+
if (connected && elapsed >= BACKEND_HEARTBEAT_STALE_MS) return 'stale';
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function reducePageVisibilitySnapshot(current, {
|
|
20
|
+
eventType,
|
|
21
|
+
documentVisible,
|
|
22
|
+
changedAt,
|
|
23
|
+
}) {
|
|
24
|
+
const visible = eventType === 'pagehide' ? false : documentVisible;
|
|
25
|
+
if (visible === current.visible) {
|
|
26
|
+
if (!visible || eventType !== 'pageshow') return current;
|
|
27
|
+
return { visible: true, visibleSince: changedAt };
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
visible,
|
|
31
|
+
visibleSince: visible ? changedAt : current.visibleSince,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
BACKEND_INITIAL_CONNECT_GRACE_MS,
|
|
37
|
+
BACKEND_HEARTBEAT_STALE_MS,
|
|
38
|
+
classifyBackendConnection,
|
|
39
|
+
reducePageVisibilitySnapshot,
|
|
40
|
+
};
|