@hellcoder/companion 0.96.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/bin/cli.ts +168 -0
- package/bin/ctl.ts +528 -0
- package/bin/generate-token.ts +28 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/assets/AgentsPage-DCFhrJ28.js +13 -0
- package/dist/assets/CronManager-EGwLJONv.js +1 -0
- package/dist/assets/IntegrationsPage-CTMRnbQS.js +1 -0
- package/dist/assets/LinearOAuthSettingsPage-CgQFMIgr.js +1 -0
- package/dist/assets/LinearSettingsPage-C9nok1qi.js +1 -0
- package/dist/assets/Playground-BV3k0RbV.js +109 -0
- package/dist/assets/PromptsPage-CFojqNKP.js +4 -0
- package/dist/assets/RunsPage-DUJ1QUSa.js +1 -0
- package/dist/assets/SandboxManager-CrVQ-VU_.js +8 -0
- package/dist/assets/SettingsPage-D1fPCL19.js +1 -0
- package/dist/assets/TailscalePage-D06cyvyC.js +1 -0
- package/dist/assets/index-BhUa1e6X.css +1 -0
- package/dist/assets/index-DkqeP-R9.js +134 -0
- package/dist/assets/sw-register-BibwRdvC.js +1 -0
- package/dist/assets/workbox-window.prod.es5-BIl4cyR9.js +2 -0
- package/dist/favicon.svg +8 -0
- package/dist/fonts/MesloLGSNerdFontMono-Bold.woff2 +0 -0
- package/dist/fonts/MesloLGSNerdFontMono-Regular.woff2 +0 -0
- package/dist/icon-192.png +0 -0
- package/dist/icon-512.png +0 -0
- package/dist/index.html +20 -0
- package/dist/logo-codex.svg +14 -0
- package/dist/logo-docker.svg +4 -0
- package/dist/logo.svg +14 -0
- package/dist/manifest.json +24 -0
- package/dist/sw.js +2 -0
- package/package.json +104 -0
- package/server/agent-cron-migrator.test.ts +610 -0
- package/server/agent-cron-migrator.ts +85 -0
- package/server/agent-executor.test.ts +1108 -0
- package/server/agent-executor.ts +346 -0
- package/server/agent-store.test.ts +588 -0
- package/server/agent-store.ts +185 -0
- package/server/agent-types.ts +138 -0
- package/server/ai-validation-settings.test.ts +128 -0
- package/server/ai-validation-settings.ts +35 -0
- package/server/ai-validator.test.ts +387 -0
- package/server/ai-validator.ts +271 -0
- package/server/auth-manager.test.ts +83 -0
- package/server/auth-manager.ts +150 -0
- package/server/auto-namer.test.ts +252 -0
- package/server/auto-namer.ts +78 -0
- package/server/backend-adapter.test.ts +38 -0
- package/server/backend-adapter.ts +54 -0
- package/server/cache-headers.test.ts +98 -0
- package/server/cache-headers.ts +61 -0
- package/server/claude-adapter.test.ts +1363 -0
- package/server/claude-adapter.ts +889 -0
- package/server/claude-container-auth.test.ts +44 -0
- package/server/claude-container-auth.ts +30 -0
- package/server/claude-protocol-contract.test.ts +71 -0
- package/server/claude-protocol-drift.test.ts +78 -0
- package/server/claude-session-discovery.test.ts +132 -0
- package/server/claude-session-discovery.ts +157 -0
- package/server/claude-session-history.test.ts +158 -0
- package/server/claude-session-history.ts +410 -0
- package/server/cli-launcher.test.ts +1343 -0
- package/server/cli-launcher.ts +1298 -0
- package/server/cli.test.ts +16 -0
- package/server/codex-adapter.test.ts +5545 -0
- package/server/codex-adapter.ts +3062 -0
- package/server/codex-container-auth.test.ts +50 -0
- package/server/codex-container-auth.ts +24 -0
- package/server/codex-home.test.ts +61 -0
- package/server/codex-home.ts +26 -0
- package/server/codex-protocol-contract.test.ts +96 -0
- package/server/codex-protocol-drift.test.ts +123 -0
- package/server/codex-ws-proxy.cjs +226 -0
- package/server/commands-discovery.test.ts +179 -0
- package/server/commands-discovery.ts +81 -0
- package/server/constants.ts +7 -0
- package/server/container-manager.test.ts +1211 -0
- package/server/container-manager.ts +1053 -0
- package/server/cron-scheduler.test.ts +957 -0
- package/server/cron-scheduler.ts +243 -0
- package/server/cron-store.test.ts +422 -0
- package/server/cron-store.ts +148 -0
- package/server/cron-types.ts +63 -0
- package/server/env-manager.test.ts +268 -0
- package/server/env-manager.ts +161 -0
- package/server/event-bus-types.ts +64 -0
- package/server/event-bus.test.ts +244 -0
- package/server/event-bus.ts +124 -0
- package/server/execution-store.test.ts +307 -0
- package/server/execution-store.ts +170 -0
- package/server/fs-utils.ts +15 -0
- package/server/git-utils.test.ts +938 -0
- package/server/git-utils.ts +421 -0
- package/server/github-pr.test.ts +498 -0
- package/server/github-pr.ts +379 -0
- package/server/image-pull-manager.test.ts +303 -0
- package/server/image-pull-manager.ts +279 -0
- package/server/index.ts +396 -0
- package/server/linear-agent-bridge.test.ts +1157 -0
- package/server/linear-agent-bridge.ts +629 -0
- package/server/linear-agent.test.ts +473 -0
- package/server/linear-agent.ts +479 -0
- package/server/linear-cache.test.ts +136 -0
- package/server/linear-cache.ts +113 -0
- package/server/linear-connections.test.ts +350 -0
- package/server/linear-connections.ts +231 -0
- package/server/linear-credential-migration.test.ts +337 -0
- package/server/linear-credential-migration.ts +63 -0
- package/server/linear-oauth-connections-migration.test.ts +268 -0
- package/server/linear-oauth-connections.test.ts +365 -0
- package/server/linear-oauth-connections.ts +294 -0
- package/server/linear-project-manager.test.ts +162 -0
- package/server/linear-project-manager.ts +111 -0
- package/server/linear-prompt-builder.test.ts +74 -0
- package/server/linear-prompt-builder.ts +61 -0
- package/server/linear-staging.test.ts +276 -0
- package/server/linear-staging.ts +142 -0
- package/server/logger.test.ts +393 -0
- package/server/logger.ts +259 -0
- package/server/metrics-collector.test.ts +413 -0
- package/server/metrics-collector.ts +350 -0
- package/server/metrics-types.ts +108 -0
- package/server/middleware/managed-auth.test.ts +264 -0
- package/server/middleware/managed-auth.ts +195 -0
- package/server/novnc-proxy.test.ts +333 -0
- package/server/novnc-proxy.ts +99 -0
- package/server/path-resolver.test.ts +552 -0
- package/server/path-resolver.ts +186 -0
- package/server/paths.test.ts +31 -0
- package/server/paths.ts +11 -0
- package/server/pr-poller.test.ts +191 -0
- package/server/pr-poller.ts +162 -0
- package/server/prompt-manager.test.ts +211 -0
- package/server/prompt-manager.ts +211 -0
- package/server/protocol/claude-upstream/README.md +19 -0
- package/server/protocol/claude-upstream/sdk.d.ts.txt +1943 -0
- package/server/protocol/codex-upstream/ClientNotification.ts.txt +5 -0
- package/server/protocol/codex-upstream/ClientRequest.ts.txt +60 -0
- package/server/protocol/codex-upstream/README.md +18 -0
- package/server/protocol/codex-upstream/ServerNotification.ts.txt +41 -0
- package/server/protocol/codex-upstream/ServerRequest.ts.txt +16 -0
- package/server/protocol/codex-upstream/v2/DynamicToolCallParams.ts.txt +6 -0
- package/server/protocol/codex-upstream/v2/DynamicToolCallResponse.ts.txt +6 -0
- package/server/protocol-monitor.ts +50 -0
- package/server/recorder.test.ts +454 -0
- package/server/recorder.ts +374 -0
- package/server/recording-hub/compat-validator.test.ts +150 -0
- package/server/recording-hub/compat-validator.ts +284 -0
- package/server/recording-hub/diagnostics.test.ts +140 -0
- package/server/recording-hub/diagnostics.ts +299 -0
- package/server/recording-hub/hub-config.test.ts +44 -0
- package/server/recording-hub/hub-config.ts +19 -0
- package/server/recording-hub/hub-routes.test.ts +417 -0
- package/server/recording-hub/hub-routes.ts +236 -0
- package/server/recording-hub/hub-store.test.ts +262 -0
- package/server/recording-hub/hub-store.ts +265 -0
- package/server/recording-hub/replay-adapter.test.ts +294 -0
- package/server/recording-hub/replay-adapter.ts +207 -0
- package/server/relay-client.test.ts +337 -0
- package/server/relay-client.ts +320 -0
- package/server/replay.test.ts +200 -0
- package/server/replay.ts +78 -0
- package/server/routes/agent-routes.test.ts +1400 -0
- package/server/routes/agent-routes.ts +409 -0
- package/server/routes/cron-routes.test.ts +881 -0
- package/server/routes/cron-routes.ts +103 -0
- package/server/routes/env-routes.test.ts +383 -0
- package/server/routes/env-routes.ts +95 -0
- package/server/routes/fs-routes.test.ts +1198 -0
- package/server/routes/fs-routes.ts +605 -0
- package/server/routes/git-routes.test.ts +813 -0
- package/server/routes/git-routes.ts +97 -0
- package/server/routes/linear-agent-routes.test.ts +721 -0
- package/server/routes/linear-agent-routes.ts +304 -0
- package/server/routes/linear-connection-routes.test.ts +927 -0
- package/server/routes/linear-connection-routes.ts +244 -0
- package/server/routes/linear-oauth-connection-routes.test.ts +406 -0
- package/server/routes/linear-oauth-connection-routes.ts +129 -0
- package/server/routes/linear-routes.test.ts +1510 -0
- package/server/routes/linear-routes.ts +953 -0
- package/server/routes/metrics-routes.test.ts +103 -0
- package/server/routes/metrics-routes.ts +13 -0
- package/server/routes/prompt-routes.ts +67 -0
- package/server/routes/sandbox-routes.test.ts +513 -0
- package/server/routes/sandbox-routes.ts +127 -0
- package/server/routes/settings-routes.ts +270 -0
- package/server/routes/skills-routes.test.ts +690 -0
- package/server/routes/skills-routes.ts +100 -0
- package/server/routes/system-routes.test.ts +637 -0
- package/server/routes/system-routes.ts +228 -0
- package/server/routes/tailscale-routes.test.ts +176 -0
- package/server/routes/tailscale-routes.ts +22 -0
- package/server/routes.test.ts +4655 -0
- package/server/routes.ts +1277 -0
- package/server/sandbox-manager.test.ts +378 -0
- package/server/sandbox-manager.ts +168 -0
- package/server/service.test.ts +1419 -0
- package/server/service.ts +718 -0
- package/server/session-creation-service.test.ts +661 -0
- package/server/session-creation-service.ts +473 -0
- package/server/session-git-info.ts +104 -0
- package/server/session-linear-issues.test.ts +118 -0
- package/server/session-linear-issues.ts +88 -0
- package/server/session-names.test.ts +94 -0
- package/server/session-names.ts +67 -0
- package/server/session-orchestrator.test.ts +1784 -0
- package/server/session-orchestrator.ts +973 -0
- package/server/session-state-machine.test.ts +606 -0
- package/server/session-state-machine.ts +207 -0
- package/server/session-store.test.ts +290 -0
- package/server/session-store.ts +146 -0
- package/server/session-types.ts +509 -0
- package/server/settings-manager.test.ts +275 -0
- package/server/settings-manager.ts +173 -0
- package/server/tailscale-manager.test.ts +553 -0
- package/server/tailscale-manager.ts +451 -0
- package/server/terminal-manager.ts +240 -0
- package/server/update-checker.test.ts +306 -0
- package/server/update-checker.ts +197 -0
- package/server/usage-limits.test.ts +536 -0
- package/server/usage-limits.ts +225 -0
- package/server/worktree-tracker.test.ts +243 -0
- package/server/worktree-tracker.ts +84 -0
- package/server/ws-auth.test.ts +59 -0
- package/server/ws-auth.ts +41 -0
- package/server/ws-bridge-browser-ingest.test.ts +272 -0
- package/server/ws-bridge-browser-ingest.ts +72 -0
- package/server/ws-bridge-browser.ts +112 -0
- package/server/ws-bridge-cli-ingest.test.ts +302 -0
- package/server/ws-bridge-cli-ingest.ts +81 -0
- package/server/ws-bridge-codex.test.ts +1837 -0
- package/server/ws-bridge-codex.ts +266 -0
- package/server/ws-bridge-controls.test.ts +124 -0
- package/server/ws-bridge-controls.ts +20 -0
- package/server/ws-bridge-persist.test.ts +296 -0
- package/server/ws-bridge-persist.ts +66 -0
- package/server/ws-bridge-publish.test.ts +234 -0
- package/server/ws-bridge-publish.ts +79 -0
- package/server/ws-bridge-replay.test.ts +44 -0
- package/server/ws-bridge-replay.ts +61 -0
- package/server/ws-bridge-types.ts +106 -0
- package/server/ws-bridge.test.ts +4777 -0
- package/server/ws-bridge.ts +1279 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// ─── Execution Store ────────────────────────────────────────────────────────
|
|
2
|
+
// Persists AgentExecution records to disk as JSONL (one file per day).
|
|
3
|
+
// Used by the Runs view to display execution history across server restarts.
|
|
4
|
+
|
|
5
|
+
import { mkdirSync, appendFileSync, readdirSync, readFileSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import type { AgentExecution } from "./agent-types.js";
|
|
9
|
+
|
|
10
|
+
const EXECUTIONS_DIR = join(homedir(), ".companion", "executions");
|
|
11
|
+
|
|
12
|
+
export interface ExecutionQuery {
|
|
13
|
+
agentId?: string;
|
|
14
|
+
triggerType?: string;
|
|
15
|
+
status?: "running" | "success" | "error";
|
|
16
|
+
limit?: number;
|
|
17
|
+
offset?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ExecutionListResult {
|
|
21
|
+
executions: AgentExecution[];
|
|
22
|
+
total: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class ExecutionStore {
|
|
26
|
+
private dir: string;
|
|
27
|
+
/** In-memory cache of recent executions for fast access */
|
|
28
|
+
private recentCache: AgentExecution[] = [];
|
|
29
|
+
private static readonly MAX_CACHE_SIZE = 200;
|
|
30
|
+
|
|
31
|
+
constructor(dir?: string) {
|
|
32
|
+
this.dir = dir || EXECUTIONS_DIR;
|
|
33
|
+
mkdirSync(this.dir, { recursive: true });
|
|
34
|
+
this.loadRecentIntoCache();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Append an execution record to the daily JSONL file and in-memory cache. */
|
|
38
|
+
append(execution: AgentExecution): void {
|
|
39
|
+
const filename = this.dailyFilename(execution.startedAt);
|
|
40
|
+
const filepath = join(this.dir, filename);
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
appendFileSync(filepath, JSON.stringify(execution) + "\n", "utf-8");
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.error("[execution-store] Failed to append execution:", err);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Update cache
|
|
49
|
+
this.recentCache.unshift(execution);
|
|
50
|
+
if (this.recentCache.length > ExecutionStore.MAX_CACHE_SIZE) {
|
|
51
|
+
this.recentCache.length = ExecutionStore.MAX_CACHE_SIZE;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Update an existing execution in the cache and persist to disk. */
|
|
56
|
+
update(sessionId: string, updates: Partial<AgentExecution>): void {
|
|
57
|
+
const idx = this.recentCache.findIndex((e) => e.sessionId === sessionId);
|
|
58
|
+
if (idx < 0) {
|
|
59
|
+
console.warn(`[execution-store] update() called for unknown sessionId: ${sessionId} (not in cache)`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
Object.assign(this.recentCache[idx], updates);
|
|
63
|
+
// Re-append the updated record to disk for durability.
|
|
64
|
+
// On next load, dedup by sessionId keeps the latest entry.
|
|
65
|
+
const updated = this.recentCache[idx];
|
|
66
|
+
const filename = this.dailyFilename(updated.startedAt);
|
|
67
|
+
const filepath = join(this.dir, filename);
|
|
68
|
+
try {
|
|
69
|
+
appendFileSync(filepath, JSON.stringify(updated) + "\n", "utf-8");
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.error("[execution-store] Failed to persist update:", err);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Query executions with pagination and filtering. */
|
|
76
|
+
list(opts?: ExecutionQuery): ExecutionListResult {
|
|
77
|
+
const limit = opts?.limit ?? 50;
|
|
78
|
+
const offset = opts?.offset ?? 0;
|
|
79
|
+
|
|
80
|
+
let filtered = this.getAllExecutions();
|
|
81
|
+
|
|
82
|
+
if (opts?.agentId) {
|
|
83
|
+
filtered = filtered.filter((e) => e.agentId === opts.agentId);
|
|
84
|
+
}
|
|
85
|
+
if (opts?.triggerType) {
|
|
86
|
+
filtered = filtered.filter((e) => e.triggerType === opts.triggerType);
|
|
87
|
+
}
|
|
88
|
+
if (opts?.status) {
|
|
89
|
+
filtered = filtered.filter((e) => {
|
|
90
|
+
if (opts.status === "running") return !e.completedAt;
|
|
91
|
+
if (opts.status === "success") return e.success === true;
|
|
92
|
+
if (opts.status === "error") return e.error !== undefined;
|
|
93
|
+
return true;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Sort by startedAt descending (most recent first)
|
|
98
|
+
filtered.sort((a, b) => b.startedAt - a.startedAt);
|
|
99
|
+
|
|
100
|
+
const total = filtered.length;
|
|
101
|
+
const executions = filtered.slice(offset, offset + limit);
|
|
102
|
+
|
|
103
|
+
return { executions, total };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Get all executions from cache + disk. */
|
|
107
|
+
private getAllExecutions(): AgentExecution[] {
|
|
108
|
+
// For now, use the in-memory cache which is loaded from disk on startup.
|
|
109
|
+
// This is fast and sufficient for the Runs view.
|
|
110
|
+
return [...this.recentCache];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Load recent executions from disk into cache on startup. */
|
|
114
|
+
private loadRecentIntoCache(): void {
|
|
115
|
+
try {
|
|
116
|
+
const files = readdirSync(this.dir)
|
|
117
|
+
.filter((f) => f.startsWith("executions-") && f.endsWith(".jsonl"))
|
|
118
|
+
.sort()
|
|
119
|
+
.reverse(); // Most recent day first
|
|
120
|
+
|
|
121
|
+
const allLoaded: AgentExecution[] = [];
|
|
122
|
+
|
|
123
|
+
for (const file of files) {
|
|
124
|
+
if (allLoaded.length >= ExecutionStore.MAX_CACHE_SIZE * 2) break;
|
|
125
|
+
|
|
126
|
+
const filepath = join(this.dir, file);
|
|
127
|
+
const content = readFileSync(filepath, "utf-8");
|
|
128
|
+
const lines = content.trim().split("\n").filter(Boolean);
|
|
129
|
+
|
|
130
|
+
// Parse lines in reverse (most recent last in file = most up-to-date)
|
|
131
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
132
|
+
try {
|
|
133
|
+
const execution = JSON.parse(lines[i]) as AgentExecution;
|
|
134
|
+
allLoaded.push(execution);
|
|
135
|
+
} catch {
|
|
136
|
+
// Skip malformed lines
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Dedup by sessionId: since we read most-recent-last first, the first
|
|
142
|
+
// occurrence of a sessionId is the most up-to-date version.
|
|
143
|
+
const seen = new Set<string>();
|
|
144
|
+
for (const exec of allLoaded) {
|
|
145
|
+
if (seen.has(exec.sessionId)) continue;
|
|
146
|
+
seen.add(exec.sessionId);
|
|
147
|
+
this.recentCache.push(exec);
|
|
148
|
+
if (this.recentCache.length >= ExecutionStore.MAX_CACHE_SIZE) break;
|
|
149
|
+
}
|
|
150
|
+
} catch (err) {
|
|
151
|
+
// Log errors that aren't simply "directory not found" (ENOENT)
|
|
152
|
+
if (err && typeof err === "object" && "code" in err && (err as { code: string }).code !== "ENOENT") {
|
|
153
|
+
console.error("[execution-store] Failed to load executions from disk:", err);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Generate a daily JSONL filename from a timestamp. */
|
|
159
|
+
private dailyFilename(timestamp: number): string {
|
|
160
|
+
const date = new Date(timestamp);
|
|
161
|
+
const yyyy = date.getUTCFullYear();
|
|
162
|
+
const mm = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
163
|
+
const dd = String(date.getUTCDate()).padStart(2, "0");
|
|
164
|
+
return `executions-${yyyy}-${mm}-${dd}.jsonl`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
get directory(): string {
|
|
168
|
+
return this.dir;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
/** Count newlines in a file. Fast: reads raw buffer, counts 0x0A bytes. */
|
|
4
|
+
export function countFileLines(path: string): number {
|
|
5
|
+
try {
|
|
6
|
+
const buf = readFileSync(path);
|
|
7
|
+
let count = 0;
|
|
8
|
+
for (let i = 0; i < buf.length; i++) {
|
|
9
|
+
if (buf[i] === 0x0a) count++;
|
|
10
|
+
}
|
|
11
|
+
return count;
|
|
12
|
+
} catch {
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
}
|