mirror of
https://github.com/Hmbown/DeepSeek-TUI.git
synced 2026-09-03 06:50:13 +08:00
chore: clean generated artifacts and toolchain hygiene
This commit is contained in:
31
.cnb.yml
31
.cnb.yml
@@ -17,6 +17,17 @@
|
||||
npm run check
|
||||
npm test
|
||||
|
||||
.rust_workspace_gates_stage: &rust_workspace_gates_stage
|
||||
name: rust workspace gates
|
||||
script: |
|
||||
set -eu
|
||||
./scripts/release/check-versions.sh
|
||||
./scripts/release/check-ohos-deps.sh
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace --all-targets --locked
|
||||
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
|
||||
cargo test --workspace --all-features --locked
|
||||
|
||||
.linux_rust_gates: &linux_rust_gates
|
||||
name: linux rust gates
|
||||
runner:
|
||||
@@ -34,15 +45,7 @@
|
||||
rustup component add rustfmt clippy
|
||||
fi
|
||||
|
||||
- name: rust workspace gates
|
||||
script: |
|
||||
set -eu
|
||||
./scripts/release/check-versions.sh
|
||||
./scripts/release/check-ohos-deps.sh
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace --all-targets --locked
|
||||
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
|
||||
cargo test --workspace --all-features --locked
|
||||
- *rust_workspace_gates_stage
|
||||
|
||||
- name: linux npm wrapper smoke
|
||||
script: |
|
||||
@@ -70,15 +73,7 @@
|
||||
rustup component add rustfmt clippy
|
||||
fi
|
||||
|
||||
- name: rust workspace gates
|
||||
script: |
|
||||
set -eu
|
||||
./scripts/release/check-versions.sh
|
||||
./scripts/release/check-ohos-deps.sh
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace --all-targets --locked
|
||||
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
|
||||
cargo test --workspace --all-features --locked
|
||||
- *rust_workspace_gates_stage
|
||||
|
||||
- name: crate publish dry-run
|
||||
script: |
|
||||
|
||||
2
.github/workflows/web.yml
vendored
2
.github/workflows/web.yml
vendored
@@ -46,7 +46,7 @@ jobs:
|
||||
run:
|
||||
working-directory: web
|
||||
env:
|
||||
CLOUDFLARE_ACCOUNT_ID: cf50f793171d7cb3b2ce23368b69cdcb
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
# Build artifacts
|
||||
/target
|
||||
/extensions/vscode/out/
|
||||
*.pdb
|
||||
*.exe
|
||||
*.dll
|
||||
@@ -40,6 +41,7 @@ dist/
|
||||
outputs/
|
||||
tmp/
|
||||
backup/
|
||||
/web/lib/facts.generated.ts
|
||||
|
||||
# Reference papers / large research blobs (keep locally if needed, don't ship)
|
||||
docs/DeepSeek_V4.pdf
|
||||
@@ -131,7 +133,10 @@ scripts/**/__pycache__/
|
||||
.harbor-datasets/
|
||||
.pinchbench-skill/
|
||||
.terminal-bench-datasets/
|
||||
.venv-bench/
|
||||
.uv-bin/
|
||||
.uv-cache/
|
||||
.uv-tools/
|
||||
codewhale__*.json
|
||||
issues/
|
||||
logs/
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.activate = activate;
|
||||
exports.deactivate = deactivate;
|
||||
const vscode = __importStar(require("vscode"));
|
||||
const runtime_1 = require("./runtime");
|
||||
const status_1 = require("./status");
|
||||
function activate(context) {
|
||||
const output = vscode.window.createOutputChannel("CodeWhale");
|
||||
const status = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100);
|
||||
const statusView = new status_1.RuntimeStatusView();
|
||||
let autoRefreshTimer;
|
||||
let autoRefreshInFlight = false;
|
||||
status.command = "codewhale.checkRuntime";
|
||||
context.subscriptions.push(output, status);
|
||||
context.subscriptions.push(vscode.window.registerWebviewViewProvider(status_1.RuntimeStatusView.viewType, statusView));
|
||||
const refreshAgentView = async () => {
|
||||
const config = (0, runtime_1.readRuntimeConfig)();
|
||||
const threads = await (0, runtime_1.listThreadSummaries)(config);
|
||||
statusView.updateThreads(threads, "Showing recent runtime threads.");
|
||||
output.appendLine(`Loaded ${threads.length} runtime thread summaries.`);
|
||||
};
|
||||
const refreshSnapshots = async () => {
|
||||
const config = (0, runtime_1.readRuntimeConfig)();
|
||||
const snapshots = await (0, runtime_1.listSnapshots)(config);
|
||||
statusView.updateSnapshots(snapshots, "Showing recent restore points.");
|
||||
output.appendLine(`Loaded ${snapshots.length} runtime restore points.`);
|
||||
};
|
||||
const refreshAgentViewDetails = async (showWarning) => {
|
||||
try {
|
||||
await refreshAgentView();
|
||||
}
|
||||
catch (error) {
|
||||
const detail = error instanceof Error ? error.message : String(error);
|
||||
statusView.updateThreads([], "Runtime thread summaries unavailable.");
|
||||
output.appendLine(`Runtime thread summaries unavailable: ${detail}`);
|
||||
if (showWarning) {
|
||||
void vscode.window.showWarningMessage(detail);
|
||||
}
|
||||
}
|
||||
try {
|
||||
await refreshSnapshots();
|
||||
}
|
||||
catch (error) {
|
||||
const detail = error instanceof Error ? error.message : String(error);
|
||||
statusView.updateSnapshots([], detail);
|
||||
output.appendLine(`Runtime restore points unavailable: ${detail}`);
|
||||
if (showWarning) {
|
||||
void vscode.window.showWarningMessage(detail);
|
||||
}
|
||||
}
|
||||
};
|
||||
const updateStatus = (text, tooltip) => {
|
||||
status.text = text;
|
||||
status.tooltip = tooltip;
|
||||
status.show();
|
||||
};
|
||||
const checkAndRefreshRuntime = async (showSpinner, logResult) => {
|
||||
const config = (0, runtime_1.readRuntimeConfig)();
|
||||
if (showSpinner) {
|
||||
updateStatus("$(sync~spin) CodeWhale", "Checking CodeWhale runtime...");
|
||||
}
|
||||
const state = await (0, runtime_1.checkRuntime)(config);
|
||||
statusView.update(state);
|
||||
switch (state.kind) {
|
||||
case "connected":
|
||||
updateStatus("$(check) CodeWhale", state.detail);
|
||||
await refreshAgentViewDetails(false);
|
||||
break;
|
||||
case "auth-required":
|
||||
updateStatus("$(lock) CodeWhale", state.detail);
|
||||
statusView.updateThreads([], "Runtime token is required before threads can load.");
|
||||
statusView.updateSnapshots([], "Runtime token is required before restore points can load.");
|
||||
break;
|
||||
case "offline":
|
||||
case "error":
|
||||
updateStatus("$(warning) CodeWhale", state.detail);
|
||||
statusView.updateThreads([], "Connect to the runtime to load recent threads.");
|
||||
statusView.updateSnapshots([], "Connect to the runtime to load restore points.");
|
||||
break;
|
||||
}
|
||||
if (logResult) {
|
||||
output.appendLine(`${new Date().toISOString()} ${state.kind}: ${state.detail}`);
|
||||
}
|
||||
return state;
|
||||
};
|
||||
const runAutoRefresh = async () => {
|
||||
if (autoRefreshInFlight) {
|
||||
return;
|
||||
}
|
||||
autoRefreshInFlight = true;
|
||||
try {
|
||||
await checkAndRefreshRuntime(false, false);
|
||||
}
|
||||
finally {
|
||||
autoRefreshInFlight = false;
|
||||
}
|
||||
};
|
||||
const scheduleAutoRefresh = () => {
|
||||
if (autoRefreshTimer) {
|
||||
clearInterval(autoRefreshTimer);
|
||||
autoRefreshTimer = undefined;
|
||||
}
|
||||
const intervalSeconds = (0, runtime_1.readRuntimeConfig)().agentViewRefreshIntervalSeconds;
|
||||
if (intervalSeconds === 0) {
|
||||
output.appendLine("Agent View auto-refresh is disabled.");
|
||||
return;
|
||||
}
|
||||
autoRefreshTimer = setInterval(() => {
|
||||
void runAutoRefresh();
|
||||
}, intervalSeconds * 1000);
|
||||
output.appendLine(`Agent View auto-refresh scheduled every ${intervalSeconds}s.`);
|
||||
};
|
||||
updateStatus("$(terminal) CodeWhale", "Check CodeWhale runtime");
|
||||
scheduleAutoRefresh();
|
||||
context.subscriptions.push(new vscode.Disposable(() => {
|
||||
if (autoRefreshTimer) {
|
||||
clearInterval(autoRefreshTimer);
|
||||
}
|
||||
}), vscode.workspace.onDidChangeConfiguration((event) => {
|
||||
if (event.affectsConfiguration("codewhale.agentViewRefreshIntervalSeconds")) {
|
||||
scheduleAutoRefresh();
|
||||
}
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand("codewhale.openTerminal", () => {
|
||||
const config = (0, runtime_1.readRuntimeConfig)();
|
||||
(0, runtime_1.openCodeWhaleTerminal)(config);
|
||||
output.appendLine(`Opened CodeWhale terminal using ${config.commandPath}.`);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand("codewhale.startRuntime", () => {
|
||||
const config = (0, runtime_1.readRuntimeConfig)();
|
||||
(0, runtime_1.startRuntimeTerminal)(config);
|
||||
const baseUrl = (0, runtime_1.runtimeBaseUrl)(config);
|
||||
updateStatus("$(sync~spin) CodeWhale", `Runtime terminal started for ${baseUrl}`);
|
||||
output.appendLine(`Started CodeWhale runtime terminal at ${baseUrl}.`);
|
||||
void vscode.window.showInformationMessage(`CodeWhale runtime starting at ${baseUrl}`);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand("codewhale.checkRuntime", async () => {
|
||||
return await checkAndRefreshRuntime(true, true);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand("codewhale.refreshAgentView", async () => {
|
||||
await refreshAgentViewDetails(true);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand("codewhale.refreshSnapshots", async () => {
|
||||
try {
|
||||
await refreshSnapshots();
|
||||
}
|
||||
catch (error) {
|
||||
const detail = error instanceof Error ? error.message : String(error);
|
||||
statusView.updateSnapshots([], detail);
|
||||
output.appendLine(`Runtime restore points unavailable: ${detail}`);
|
||||
void vscode.window.showWarningMessage(detail);
|
||||
}
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand("codewhale.openRuntimeDocs", () => {
|
||||
void vscode.env.openExternal(vscode.Uri.parse("https://github.com/Hmbown/CodeWhale/blob/main/docs/RUNTIME_API.md"));
|
||||
}));
|
||||
void vscode.commands.executeCommand("codewhale.checkRuntime");
|
||||
}
|
||||
function deactivate() {
|
||||
// No background process is owned by the extension; runtime starts in a user-visible terminal.
|
||||
}
|
||||
//# sourceMappingURL=extension.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1,251 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.readRuntimeConfig = readRuntimeConfig;
|
||||
exports.runtimeBaseUrl = runtimeBaseUrl;
|
||||
exports.checkRuntime = checkRuntime;
|
||||
exports.listThreadSummaries = listThreadSummaries;
|
||||
exports.listSnapshots = listSnapshots;
|
||||
exports.startRuntimeTerminal = startRuntimeTerminal;
|
||||
exports.openCodeWhaleTerminal = openCodeWhaleTerminal;
|
||||
const http = __importStar(require("node:http"));
|
||||
const vscode = __importStar(require("vscode"));
|
||||
function readRuntimeConfig() {
|
||||
const config = vscode.workspace.getConfiguration("codewhale");
|
||||
const commandPath = config.get("commandPath", "codewhale").trim() || "codewhale";
|
||||
const host = config.get("runtimeHost", "127.0.0.1").trim() || "127.0.0.1";
|
||||
const port = config.get("runtimePort", 7878);
|
||||
const token = config.get("runtimeToken", "").trim();
|
||||
const interval = config.get("agentViewRefreshIntervalSeconds", 15);
|
||||
return {
|
||||
commandPath,
|
||||
host,
|
||||
port,
|
||||
token: token.length > 0 ? token : undefined,
|
||||
agentViewRefreshIntervalSeconds: clampRefreshInterval(interval),
|
||||
};
|
||||
}
|
||||
function runtimeBaseUrl(config) {
|
||||
return `http://${config.host}:${config.port}`;
|
||||
}
|
||||
async function checkRuntime(config) {
|
||||
const baseUrl = runtimeBaseUrl(config);
|
||||
const health = await requestJson(`${baseUrl}/health`, config.token);
|
||||
if (health.statusCode === 0) {
|
||||
return { kind: "offline", baseUrl, detail: "Runtime is not reachable." };
|
||||
}
|
||||
if (health.statusCode === 401) {
|
||||
return { kind: "auth-required", baseUrl, detail: "Runtime requires a token." };
|
||||
}
|
||||
if (health.statusCode !== 200) {
|
||||
return {
|
||||
kind: "error",
|
||||
baseUrl,
|
||||
detail: `Health check returned HTTP ${health.statusCode}.`,
|
||||
};
|
||||
}
|
||||
const info = await requestJson(`${baseUrl}/v1/runtime/info`, config.token);
|
||||
if (info.statusCode === 401) {
|
||||
return { kind: "auth-required", baseUrl, detail: "Runtime info requires a token." };
|
||||
}
|
||||
const version = readVersion(info.body);
|
||||
return {
|
||||
kind: "connected",
|
||||
baseUrl,
|
||||
detail: version ? `Connected to CodeWhale ${version}.` : "Connected to CodeWhale runtime.",
|
||||
version,
|
||||
};
|
||||
}
|
||||
async function listThreadSummaries(config, limit = 8) {
|
||||
const baseUrl = runtimeBaseUrl(config);
|
||||
const response = await requestJson(`${baseUrl}/v1/threads/summary?limit=${encodeURIComponent(String(limit))}`, config.token);
|
||||
if (response.statusCode === 401) {
|
||||
throw new Error("Thread summaries require the runtime bearer token.");
|
||||
}
|
||||
if (response.statusCode !== 200) {
|
||||
throw new Error(`Thread summary returned HTTP ${response.statusCode}.`);
|
||||
}
|
||||
return readThreadSummaries(response.body);
|
||||
}
|
||||
async function listSnapshots(config, limit = 8) {
|
||||
const baseUrl = runtimeBaseUrl(config);
|
||||
const response = await requestJson(`${baseUrl}/v1/snapshots?limit=${encodeURIComponent(String(limit))}`, config.token);
|
||||
if (response.statusCode === 401) {
|
||||
throw new Error("Restore points require the runtime bearer token.");
|
||||
}
|
||||
if (response.statusCode !== 200) {
|
||||
throw new Error(`Restore points returned HTTP ${response.statusCode}.`);
|
||||
}
|
||||
return readSnapshots(response.body);
|
||||
}
|
||||
function startRuntimeTerminal(config) {
|
||||
const terminal = vscode.window.createTerminal("CodeWhale Runtime");
|
||||
const args = [
|
||||
"serve",
|
||||
"--http",
|
||||
"--host",
|
||||
shellQuote(config.host),
|
||||
"--port",
|
||||
String(config.port),
|
||||
];
|
||||
if (config.token) {
|
||||
args.push("--auth-token", shellQuote(config.token));
|
||||
}
|
||||
terminal.sendText(`${shellQuote(config.commandPath)} ${args.join(" ")}`);
|
||||
terminal.show();
|
||||
return terminal;
|
||||
}
|
||||
function openCodeWhaleTerminal(config) {
|
||||
const terminal = vscode.window.createTerminal("CodeWhale");
|
||||
terminal.sendText(shellQuote(config.commandPath));
|
||||
terminal.show();
|
||||
return terminal;
|
||||
}
|
||||
async function requestJson(url, token) {
|
||||
try {
|
||||
return await new Promise((resolve, reject) => {
|
||||
const request = http.get(url, {
|
||||
timeout: 2500,
|
||||
headers: token ? { Authorization: `Bearer ${token}` } : undefined,
|
||||
}, (response) => {
|
||||
let body = "";
|
||||
response.setEncoding("utf8");
|
||||
response.on("data", (chunk) => {
|
||||
body += chunk;
|
||||
});
|
||||
response.on("end", () => {
|
||||
resolve({
|
||||
statusCode: response.statusCode ?? 0,
|
||||
body: parseJson(body),
|
||||
});
|
||||
});
|
||||
});
|
||||
request.on("timeout", () => {
|
||||
request.destroy(new Error("Runtime check timed out."));
|
||||
});
|
||||
request.on("error", reject);
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
const detail = error instanceof Error ? error.message : String(error);
|
||||
return { statusCode: 0, body: { error: detail } };
|
||||
}
|
||||
}
|
||||
function parseJson(raw) {
|
||||
try {
|
||||
return JSON.parse(raw);
|
||||
}
|
||||
catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
function readVersion(value) {
|
||||
if (!value || typeof value !== "object") {
|
||||
return undefined;
|
||||
}
|
||||
const version = value.version;
|
||||
return typeof version === "string" ? version : undefined;
|
||||
}
|
||||
function readThreadSummaries(value) {
|
||||
if (!Array.isArray(value)) {
|
||||
return [];
|
||||
}
|
||||
return value.flatMap((item) => {
|
||||
if (!item || typeof item !== "object") {
|
||||
return [];
|
||||
}
|
||||
const record = item;
|
||||
const id = readString(record.id);
|
||||
if (!id) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
{
|
||||
id,
|
||||
title: readString(record.title) ?? "New Thread",
|
||||
preview: readString(record.preview) ?? "",
|
||||
model: readString(record.model) ?? "unknown",
|
||||
mode: readString(record.mode) ?? "agent",
|
||||
workspace: readString(record.workspace),
|
||||
branch: readString(record.branch),
|
||||
head: readString(record.head),
|
||||
dirty: readBoolean(record.dirty),
|
||||
archived: record.archived === true,
|
||||
updatedAt: readString(record.updated_at) ?? "",
|
||||
latestTurnStatus: readString(record.latest_turn_status),
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
function readSnapshots(value) {
|
||||
if (!Array.isArray(value)) {
|
||||
return [];
|
||||
}
|
||||
return value.flatMap((item) => {
|
||||
if (!item || typeof item !== "object") {
|
||||
return [];
|
||||
}
|
||||
const record = item;
|
||||
const id = readString(record.id);
|
||||
const label = readString(record.label);
|
||||
const timestamp = readNumber(record.timestamp);
|
||||
if (!id || !label || timestamp === undefined) {
|
||||
return [];
|
||||
}
|
||||
return [{ id, label, timestamp }];
|
||||
});
|
||||
}
|
||||
function readString(value) {
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
function readNumber(value) {
|
||||
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
||||
}
|
||||
function readBoolean(value) {
|
||||
return value === true;
|
||||
}
|
||||
function clampRefreshInterval(value) {
|
||||
if (!Number.isFinite(value)) {
|
||||
return 15;
|
||||
}
|
||||
return Math.max(0, Math.min(300, Math.floor(value)));
|
||||
}
|
||||
function shellQuote(value) {
|
||||
if (/^[A-Za-z0-9_./:=+-]+$/.test(value)) {
|
||||
return value;
|
||||
}
|
||||
return `'${value.replace(/'/g, "'\\''")}'`;
|
||||
}
|
||||
//# sourceMappingURL=runtime.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1,217 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RuntimeStatusView = void 0;
|
||||
const vscode = __importStar(require("vscode"));
|
||||
class RuntimeStatusView {
|
||||
static viewType = "codewhale.runtimeStatus";
|
||||
view;
|
||||
state = {
|
||||
kind: "offline",
|
||||
baseUrl: "http://127.0.0.1:7878",
|
||||
detail: "Runtime has not been checked yet.",
|
||||
};
|
||||
threads = [];
|
||||
threadsDetail = "Connect to the runtime to load recent threads.";
|
||||
snapshots = [];
|
||||
snapshotsDetail = "Connect to the runtime to load restore points.";
|
||||
resolveWebviewView(view) {
|
||||
this.view = view;
|
||||
view.webview.options = { enableScripts: true };
|
||||
view.webview.onDidReceiveMessage((message) => {
|
||||
if (message.command === "check") {
|
||||
void vscode.commands.executeCommand("codewhale.checkRuntime");
|
||||
}
|
||||
else if (message.command === "start") {
|
||||
void vscode.commands.executeCommand("codewhale.startRuntime");
|
||||
}
|
||||
else if (message.command === "terminal") {
|
||||
void vscode.commands.executeCommand("codewhale.openTerminal");
|
||||
}
|
||||
else if (message.command === "threads") {
|
||||
void vscode.commands.executeCommand("codewhale.refreshAgentView");
|
||||
}
|
||||
else if (message.command === "snapshots") {
|
||||
void vscode.commands.executeCommand("codewhale.refreshSnapshots");
|
||||
}
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
update(state) {
|
||||
this.state = state;
|
||||
this.render();
|
||||
}
|
||||
updateThreads(threads, detail) {
|
||||
this.threads = threads;
|
||||
this.threadsDetail = detail;
|
||||
this.render();
|
||||
}
|
||||
updateSnapshots(snapshots, detail) {
|
||||
this.snapshots = snapshots;
|
||||
this.snapshotsDetail = detail;
|
||||
this.render();
|
||||
}
|
||||
render() {
|
||||
if (!this.view) {
|
||||
return;
|
||||
}
|
||||
const badge = labelFor(this.state.kind);
|
||||
const nonce = makeNonce();
|
||||
const threadsHtml = this.threads.length > 0
|
||||
? this.threads.map((thread) => renderThread(thread)).join("")
|
||||
: `<p class="detail">${escapeHtml(this.threadsDetail)}</p>`;
|
||||
const snapshotsHtml = this.snapshots.length > 0
|
||||
? this.snapshots.map((snapshot) => renderSnapshot(snapshot)).join("")
|
||||
: `<p class="detail">${escapeHtml(this.snapshotsDetail)}</p>`;
|
||||
this.view.webview.html = `<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-${nonce}';">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
body { padding: 14px; color: var(--vscode-foreground); font-family: var(--vscode-font-family); }
|
||||
.status { margin-bottom: 12px; font-weight: 600; }
|
||||
.detail { margin: 0 0 14px; color: var(--vscode-descriptionForeground); line-height: 1.45; }
|
||||
.section-title { margin: 18px 0 8px; font-size: 11px; font-weight: 700; letter-spacing: 0; text-transform: uppercase; color: var(--vscode-descriptionForeground); }
|
||||
.thread { padding: 8px 0; border-top: 1px solid var(--vscode-sideBarSectionHeader-border, var(--vscode-panel-border)); }
|
||||
.snapshot { padding: 8px 0; border-top: 1px solid var(--vscode-sideBarSectionHeader-border, var(--vscode-panel-border)); }
|
||||
.thread-title, .snapshot-title { margin-bottom: 4px; font-weight: 600; overflow-wrap: anywhere; }
|
||||
.thread-preview { margin-bottom: 5px; color: var(--vscode-descriptionForeground); line-height: 1.35; overflow-wrap: anywhere; }
|
||||
.thread-meta { color: var(--vscode-descriptionForeground); font-size: 11px; overflow-wrap: anywhere; }
|
||||
code { color: var(--vscode-textLink-foreground); }
|
||||
button { width: 100%; margin: 4px 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="status">${escapeHtml(badge)}</div>
|
||||
<p class="detail">${escapeHtml(this.state.detail)}</p>
|
||||
<p class="detail"><code>${escapeHtml(this.state.baseUrl)}</code></p>
|
||||
<button data-command="check">Check Runtime</button>
|
||||
<button data-command="threads">Refresh Threads</button>
|
||||
<button data-command="snapshots">Refresh Restore Points</button>
|
||||
<button data-command="start">Start Local Runtime</button>
|
||||
<button data-command="terminal">Open CodeWhale Terminal</button>
|
||||
<div class="section-title">Agent View</div>
|
||||
${threadsHtml}
|
||||
<div class="section-title">Restore Points</div>
|
||||
${snapshotsHtml}
|
||||
<script nonce="${nonce}">
|
||||
const vscode = acquireVsCodeApi();
|
||||
for (const button of document.querySelectorAll("button[data-command]")) {
|
||||
button.addEventListener("click", () => vscode.postMessage({ command: button.dataset.command }));
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
}
|
||||
exports.RuntimeStatusView = RuntimeStatusView;
|
||||
function renderSnapshot(snapshot) {
|
||||
return `<div class="snapshot">
|
||||
<div class="snapshot-title">${escapeHtml(snapshot.label)}</div>
|
||||
<div class="thread-meta">${escapeHtml(`${snapshot.id} · ${formatUnixTimestamp(snapshot.timestamp)}`)}</div>
|
||||
</div>`;
|
||||
}
|
||||
function renderThread(thread) {
|
||||
const status = thread.latestTurnStatus ? ` · ${thread.latestTurnStatus}` : "";
|
||||
const archived = thread.archived ? " · archived" : "";
|
||||
const git = renderGitMetadata(thread);
|
||||
const workspace = thread.workspace ? ` · ${thread.workspace}` : "";
|
||||
const updated = thread.updatedAt ? ` · ${formatTimestamp(thread.updatedAt)}` : "";
|
||||
return `<div class="thread">
|
||||
<div class="thread-title">${escapeHtml(thread.title)}</div>
|
||||
<div class="thread-preview">${escapeHtml(thread.preview || "No recent message.")}</div>
|
||||
<div class="thread-meta">${escapeHtml(`${thread.mode} · ${thread.model}${status}${git}${archived}${updated}${workspace}`)}</div>
|
||||
</div>`;
|
||||
}
|
||||
function renderGitMetadata(thread) {
|
||||
if (!thread.branch && !thread.head && !thread.dirty) {
|
||||
return "";
|
||||
}
|
||||
const parts = [];
|
||||
if (thread.branch) {
|
||||
parts.push(`branch ${thread.branch}`);
|
||||
}
|
||||
if (thread.head) {
|
||||
parts.push(`@ ${thread.head}`);
|
||||
}
|
||||
if (thread.dirty) {
|
||||
parts.push("dirty");
|
||||
}
|
||||
return ` · ${parts.join(" ")}`;
|
||||
}
|
||||
function labelFor(kind) {
|
||||
switch (kind) {
|
||||
case "connected":
|
||||
return "Connected";
|
||||
case "auth-required":
|
||||
return "Token Required";
|
||||
case "error":
|
||||
return "Runtime Error";
|
||||
case "offline":
|
||||
return "Offline";
|
||||
}
|
||||
}
|
||||
function formatTimestamp(value) {
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return value;
|
||||
}
|
||||
return date.toLocaleString();
|
||||
}
|
||||
function formatUnixTimestamp(value) {
|
||||
const date = new Date(value * 1000);
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return String(value);
|
||||
}
|
||||
return date.toLocaleString();
|
||||
}
|
||||
function escapeHtml(value) {
|
||||
return value
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """);
|
||||
}
|
||||
function makeNonce() {
|
||||
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
let nonce = "";
|
||||
for (let index = 0; index < 32; index += 1) {
|
||||
nonce += alphabet.charAt(Math.floor(Math.random() * alphabet.length));
|
||||
}
|
||||
return nonce;
|
||||
}
|
||||
//# sourceMappingURL=status.js.map
|
||||
File diff suppressed because one or more lines are too long
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "1.88"
|
||||
@@ -1,180 +0,0 @@
|
||||
// AUTO-GENERATED by web/scripts/derive-facts.mjs at prebuild.
|
||||
// DO NOT EDIT — re-run `npm run prebuild` (or just `npm run build`) after changing the parent repo.
|
||||
// To override at runtime, write the same shape to KV under key "facts:current".
|
||||
|
||||
export interface ProviderFact { id: string; label: string; env: string }
|
||||
|
||||
export interface RepoFacts {
|
||||
generatedAt: string;
|
||||
version: string | null;
|
||||
crates: string[];
|
||||
sandboxBackends: string[];
|
||||
providers: ProviderFact[];
|
||||
defaultModel: string | null;
|
||||
nodeEngines: string | null;
|
||||
toolCount: number | null;
|
||||
license: string | null;
|
||||
latestRelease: string | null;
|
||||
}
|
||||
|
||||
export const FACTS: RepoFacts = {
|
||||
"generatedAt": "2026-06-16T08:03:17.993Z",
|
||||
"version": "0.8.61",
|
||||
"crates": [
|
||||
"agent",
|
||||
"app-server",
|
||||
"cli",
|
||||
"config",
|
||||
"core",
|
||||
"execpolicy",
|
||||
"hooks",
|
||||
"mcp",
|
||||
"protocol",
|
||||
"release",
|
||||
"secrets",
|
||||
"state",
|
||||
"tools",
|
||||
"tui",
|
||||
"tui-core",
|
||||
"whaleflow"
|
||||
],
|
||||
"sandboxBackends": [
|
||||
"bwrap",
|
||||
"landlock (Linux)",
|
||||
"process_hardening",
|
||||
"seatbelt (macOS)",
|
||||
"seccomp"
|
||||
],
|
||||
"providers": [
|
||||
{
|
||||
"id": "deepseek",
|
||||
"label": "DeepSeek",
|
||||
"env": "DEEPSEEK_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "nvidia-nim",
|
||||
"label": "NVIDIA NIM",
|
||||
"env": "NVIDIA_API_KEY / NVIDIA_NIM_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "openai",
|
||||
"label": "OpenAI-compatible",
|
||||
"env": "OPENAI_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "atlascloud",
|
||||
"label": "AtlasCloud",
|
||||
"env": "ATLASCLOUD_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "wanjie-ark",
|
||||
"label": "Wanjie Ark",
|
||||
"env": "WANJIE_ARK_API_KEY / WANJIE_API_KEY / WANJIE_MAAS_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "volcengine",
|
||||
"label": "Volcengine Ark",
|
||||
"env": "VOLCENGINE_API_KEY / VOLCENGINE_ARK_API_KEY / ARK_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "openrouter",
|
||||
"label": "OpenRouter",
|
||||
"env": "OPENROUTER_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "xiaomi-mimo",
|
||||
"label": "Xiaomi MiMo",
|
||||
"env": "XIAOMI_MIMO_API_KEY / XIAOMI_API_KEY / MIMO_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "novita",
|
||||
"label": "Novita AI",
|
||||
"env": "NOVITA_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "fireworks",
|
||||
"label": "Fireworks AI",
|
||||
"env": "FIREWORKS_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "siliconflow",
|
||||
"label": "SiliconFlow",
|
||||
"env": "SILICONFLOW_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "siliconflow-CN",
|
||||
"label": "SiliconFlow CN",
|
||||
"env": "SILICONFLOW_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "arcee",
|
||||
"label": "Arcee AI",
|
||||
"env": "ARCEE_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "moonshot",
|
||||
"label": "Moonshot/Kimi",
|
||||
"env": "MOONSHOT_API_KEY / KIMI_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "sglang",
|
||||
"label": "SGLang",
|
||||
"env": "SGLANG_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "vllm",
|
||||
"label": "vLLM",
|
||||
"env": "VLLM_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "ollama",
|
||||
"label": "Ollama",
|
||||
"env": "OLLAMA_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "huggingface",
|
||||
"label": "Hugging Face",
|
||||
"env": "HUGGINGFACE_API_KEY / HF_TOKEN"
|
||||
},
|
||||
{
|
||||
"id": "together",
|
||||
"label": "Together AI",
|
||||
"env": "TOGETHER_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "openai-codex",
|
||||
"label": "OpenAI Codex",
|
||||
"env": "ChatGPT/Codex OAuth via `codex login` (OPENAI_CODEX_ACCESS_TOKEN / CODEX_ACCESS_TOKEN override)"
|
||||
},
|
||||
{
|
||||
"id": "anthropic",
|
||||
"label": "Anthropic",
|
||||
"env": "ANTHROPIC_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "zai",
|
||||
"label": "Z.ai",
|
||||
"env": "ZAI_API_KEY / Z_AI_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "stepfun",
|
||||
"label": "StepFun",
|
||||
"env": "STEPFUN_API_KEY / STEP_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "minimax",
|
||||
"label": "MiniMax",
|
||||
"env": "MINIMAX_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "deepinfra",
|
||||
"label": "DeepInfra",
|
||||
"env": "DEEPINFRA_API_KEY / DEEPINFRA_TOKEN"
|
||||
}
|
||||
],
|
||||
"defaultModel": "deepseek-v4-pro",
|
||||
"nodeEngines": ">=18",
|
||||
"toolCount": 76,
|
||||
"license": "MIT",
|
||||
"latestRelease": null
|
||||
};
|
||||
Reference in New Issue
Block a user