omnius 1.0.326 → 1.0.328
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/dist/index.js +1192 -838
- package/docs/reference/rest-api.md +1 -0
- package/npm-shrinkwrap.json +28 -89
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1699,12 +1699,12 @@ var init_model_broker = __esm({
|
|
|
1699
1699
|
// packages/execution/dist/broker-mediated-backend.js
|
|
1700
1700
|
function wrapWithBroker(backend, options2) {
|
|
1701
1701
|
const broker = getModelBroker();
|
|
1702
|
-
const
|
|
1702
|
+
const clamp10 = options2.clampNumCtx !== false;
|
|
1703
1703
|
const wrapped = Object.create(backend);
|
|
1704
1704
|
wrapped.chatCompletion = async (request) => {
|
|
1705
1705
|
const model = backend.model || request.model || "unknown";
|
|
1706
1706
|
let effectiveRequest = request;
|
|
1707
|
-
if (
|
|
1707
|
+
if (clamp10) {
|
|
1708
1708
|
const trainCtx = await broker.getNctxTrain(model).catch(() => null);
|
|
1709
1709
|
const requestedNumCtx = request.numCtx;
|
|
1710
1710
|
if (trainCtx && trainCtx > 0) {
|
|
@@ -1738,7 +1738,7 @@ function wrapWithBroker(backend, options2) {
|
|
|
1738
1738
|
wrapped.chatCompletionStream = async function* (request) {
|
|
1739
1739
|
const model = backend.model || request.model || "unknown";
|
|
1740
1740
|
let effectiveRequest = request;
|
|
1741
|
-
if (
|
|
1741
|
+
if (clamp10) {
|
|
1742
1742
|
const trainCtx = await broker.getNctxTrain(model).catch(() => null);
|
|
1743
1743
|
const requestedNumCtx = request.numCtx;
|
|
1744
1744
|
if (trainCtx && trainCtx > 0) {
|
|
@@ -294217,7 +294217,7 @@ var init_codebase_indexer = __esm({
|
|
|
294217
294217
|
};
|
|
294218
294218
|
}
|
|
294219
294219
|
async index() {
|
|
294220
|
-
const ig = ignore
|
|
294220
|
+
const ig = ignore();
|
|
294221
294221
|
if (this.config.respectGitignore) {
|
|
294222
294222
|
try {
|
|
294223
294223
|
const gitignoreContent = await readFile22(join69(this.config.rootDir, ".gitignore"), "utf-8");
|
|
@@ -554070,7 +554070,7 @@ var init_messages = __esm({
|
|
|
554070
554070
|
role: z2.enum(["user", "assistant", "system", "tool"]),
|
|
554071
554071
|
content: z2.string(),
|
|
554072
554072
|
timestamp: z2.string().datetime(),
|
|
554073
|
-
metadata: z2.record(z2.unknown()).optional()
|
|
554073
|
+
metadata: z2.record(z2.string(), z2.unknown()).optional()
|
|
554074
554074
|
});
|
|
554075
554075
|
}
|
|
554076
554076
|
});
|
|
@@ -554084,7 +554084,7 @@ var init_tools = __esm({
|
|
|
554084
554084
|
ToolCallSchema = z3.object({
|
|
554085
554085
|
id: z3.string().uuid(),
|
|
554086
554086
|
name: z3.string(),
|
|
554087
|
-
arguments: z3.record(z3.unknown()),
|
|
554087
|
+
arguments: z3.record(z3.string(), z3.unknown()),
|
|
554088
554088
|
result: z3.unknown().optional(),
|
|
554089
554089
|
status: z3.enum(["pending", "running", "completed", "failed"]),
|
|
554090
554090
|
startedAt: z3.string().datetime().optional(),
|
|
@@ -554106,7 +554106,7 @@ var init_session3 = __esm({
|
|
|
554106
554106
|
createdAt: z4.string().datetime(),
|
|
554107
554107
|
updatedAt: z4.string().datetime(),
|
|
554108
554108
|
status: z4.enum(["active", "paused", "completed", "error"]),
|
|
554109
|
-
config: z4.record(z4.unknown()).optional()
|
|
554109
|
+
config: z4.record(z4.string(), z4.unknown()).optional()
|
|
554110
554110
|
});
|
|
554111
554111
|
}
|
|
554112
554112
|
});
|
|
@@ -554637,25 +554637,25 @@ var init_config5 = __esm({
|
|
|
554637
554637
|
* Maximum context length for the model.
|
|
554638
554638
|
* Should be discovered by startup probing rather than hard-coded.
|
|
554639
554639
|
*/
|
|
554640
|
-
AGENT_MAX_MODEL_LEN: z14.string().transform((v) => parseInt(v, 10)).pipe(z14.number().int().positive()).default(
|
|
554640
|
+
AGENT_MAX_MODEL_LEN: z14.string().transform((v) => parseInt(v, 10)).pipe(z14.number().int().positive()).default(65536),
|
|
554641
554641
|
/** Enable vLLM automatic prefix caching (1 = enabled) */
|
|
554642
|
-
AGENT_ENABLE_PREFIX_CACHING: z14.string().transform((v) => v === "1" || v.toLowerCase() === "true").pipe(z14.boolean()).default(
|
|
554642
|
+
AGENT_ENABLE_PREFIX_CACHING: z14.string().transform((v) => v === "1" || v.toLowerCase() === "true").pipe(z14.boolean()).default(true),
|
|
554643
554643
|
/** Enable vLLM sleep mode when idle (1 = enabled) */
|
|
554644
|
-
AGENT_ENABLE_SLEEP_MODE: z14.string().transform((v) => v === "1" || v.toLowerCase() === "true").pipe(z14.boolean()).default(
|
|
554644
|
+
AGENT_ENABLE_SLEEP_MODE: z14.string().transform((v) => v === "1" || v.toLowerCase() === "true").pipe(z14.boolean()).default(true),
|
|
554645
554645
|
// -----------------------------------------------------------------------
|
|
554646
554646
|
// Agent behaviour
|
|
554647
554647
|
// -----------------------------------------------------------------------
|
|
554648
554648
|
/** Maximum retry cycles per subtask */
|
|
554649
|
-
AGENT_MAX_RETRIES: z14.string().transform((v) => parseInt(v, 10)).pipe(z14.number().int().nonnegative()).default(
|
|
554649
|
+
AGENT_MAX_RETRIES: z14.string().transform((v) => parseInt(v, 10)).pipe(z14.number().int().nonnegative()).default(3),
|
|
554650
554650
|
/** Maximum number of parallel subagents that may run simultaneously */
|
|
554651
|
-
AGENT_MAX_PARALLEL_SUBAGENTS: z14.string().transform((v) => parseInt(v, 10)).pipe(z14.number().int().positive()).default(
|
|
554651
|
+
AGENT_MAX_PARALLEL_SUBAGENTS: z14.string().transform((v) => parseInt(v, 10)).pipe(z14.number().int().positive()).default(4),
|
|
554652
554652
|
// -----------------------------------------------------------------------
|
|
554653
554653
|
// Retrieval limits
|
|
554654
554654
|
// -----------------------------------------------------------------------
|
|
554655
554655
|
/** Maximum files included in a single retrieval packet */
|
|
554656
|
-
AGENT_RETRIEVAL_MAX_FILES: z14.string().transform((v) => parseInt(v, 10)).pipe(z14.number().int().positive()).default(
|
|
554656
|
+
AGENT_RETRIEVAL_MAX_FILES: z14.string().transform((v) => parseInt(v, 10)).pipe(z14.number().int().positive()).default(8),
|
|
554657
554657
|
/** Maximum snippets included in a single retrieval packet */
|
|
554658
|
-
AGENT_RETRIEVAL_MAX_SNIPPETS: z14.string().transform((v) => parseInt(v, 10)).pipe(z14.number().int().positive()).default(
|
|
554658
|
+
AGENT_RETRIEVAL_MAX_SNIPPETS: z14.string().transform((v) => parseInt(v, 10)).pipe(z14.number().int().positive()).default(16),
|
|
554659
554659
|
// -----------------------------------------------------------------------
|
|
554660
554660
|
// File paths
|
|
554661
554661
|
// -----------------------------------------------------------------------
|
|
@@ -568169,7 +568169,7 @@ ${context2 ?? ""}`;
|
|
|
568169
568169
|
}
|
|
568170
568170
|
}
|
|
568171
568171
|
_applyTaskAffectFromResult(result, events) {
|
|
568172
|
-
const
|
|
568172
|
+
const clamp10 = (n2) => Math.max(0, Math.min(1, n2));
|
|
568173
568173
|
let uncertainty = this._taskAffectState.uncertainty * 0.94;
|
|
568174
568174
|
let frustration = this._taskAffectState.frustration * 0.94;
|
|
568175
568175
|
let confidence2 = this._taskAffectState.confidence * 0.94;
|
|
@@ -568202,11 +568202,11 @@ ${context2 ?? ""}`;
|
|
|
568202
568202
|
}
|
|
568203
568203
|
const level = frustration >= 0.72 || uncertainty >= 0.78 ? 4 : frustration >= 0.52 || uncertainty >= 0.58 ? 3 : frustration >= 0.32 || uncertainty >= 0.38 ? 2 : frustration >= 0.18 || uncertainty >= 0.22 ? 1 : 0;
|
|
568204
568204
|
this._taskAffectState = {
|
|
568205
|
-
uncertainty:
|
|
568206
|
-
frustration:
|
|
568207
|
-
confidence:
|
|
568208
|
-
novelty:
|
|
568209
|
-
momentum:
|
|
568205
|
+
uncertainty: clamp10(uncertainty),
|
|
568206
|
+
frustration: clamp10(frustration),
|
|
568207
|
+
confidence: clamp10(confidence2),
|
|
568208
|
+
novelty: clamp10(novelty),
|
|
568209
|
+
momentum: clamp10(momentum),
|
|
568210
568210
|
adversaryLevel: level,
|
|
568211
568211
|
lastUpdatedIso: (/* @__PURE__ */ new Date()).toISOString()
|
|
568212
568212
|
};
|
|
@@ -596755,6 +596755,7 @@ __export(render_exports, {
|
|
|
596755
596755
|
renderBoxedBlock: () => renderBoxedBlock,
|
|
596756
596756
|
renderCompactHeader: () => renderCompactHeader,
|
|
596757
596757
|
renderConfig: () => renderConfig,
|
|
596758
|
+
renderContentBlock: () => renderContentBlock,
|
|
596758
596759
|
renderContextIntakeBox: () => renderContextIntakeBox,
|
|
596759
596760
|
renderError: () => renderError,
|
|
596760
596761
|
renderHeader: () => renderHeader,
|
|
@@ -598194,6 +598195,18 @@ ${lines.map((l2) => l2 + "\x1B[0m").join("\n")}
|
|
|
598194
598195
|
process.stdout.write(text2);
|
|
598195
598196
|
_contentWriteHook?.end();
|
|
598196
598197
|
}
|
|
598198
|
+
function renderContentBlock(text2) {
|
|
598199
|
+
breakTelegramCoalesce();
|
|
598200
|
+
const body = text2.endsWith("\n") ? text2 : text2 + "\n";
|
|
598201
|
+
const redir = _contentWriteHook?.redirect?.();
|
|
598202
|
+
if (redir) {
|
|
598203
|
+
redir(body);
|
|
598204
|
+
return;
|
|
598205
|
+
}
|
|
598206
|
+
_contentWriteHook?.begin();
|
|
598207
|
+
process.stdout.write(body);
|
|
598208
|
+
_contentWriteHook?.end();
|
|
598209
|
+
}
|
|
598197
598210
|
function renderInfo(message2) {
|
|
598198
598211
|
breakTelegramCoalesce();
|
|
598199
598212
|
const redir = _contentWriteHook?.redirect?.();
|
|
@@ -604388,623 +604401,6 @@ var init_profiles = __esm({
|
|
|
604388
604401
|
}
|
|
604389
604402
|
});
|
|
604390
604403
|
|
|
604391
|
-
// packages/cli/src/tui/cad-model-viewer.ts
|
|
604392
|
-
import { createServer as createServer7 } from "node:http";
|
|
604393
|
-
import { existsSync as existsSync107, readFileSync as readFileSync86, statSync as statSync41 } from "node:fs";
|
|
604394
|
-
import { basename as basename22, extname as extname15, resolve as resolve52 } from "node:path";
|
|
604395
|
-
function getCurrentCadModelViewer() {
|
|
604396
|
-
return currentViewer;
|
|
604397
|
-
}
|
|
604398
|
-
async function startCadModelViewer(filePath) {
|
|
604399
|
-
const resolved = filePath ? resolve52(filePath) : void 0;
|
|
604400
|
-
if (resolved && (!existsSync107(resolved) || !statSync41(resolved).isFile())) {
|
|
604401
|
-
throw new Error(`3D model file not found: ${resolved}`);
|
|
604402
|
-
}
|
|
604403
|
-
if (currentViewer) {
|
|
604404
|
-
await currentViewer.close().catch(() => {
|
|
604405
|
-
});
|
|
604406
|
-
currentViewer = null;
|
|
604407
|
-
}
|
|
604408
|
-
const server2 = createServer7((req3, res) => handleViewerRequest(req3, res, resolved));
|
|
604409
|
-
const port = await listenOnEphemeralPort(server2);
|
|
604410
|
-
const session = {
|
|
604411
|
-
url: `http://127.0.0.1:${port}/`,
|
|
604412
|
-
port,
|
|
604413
|
-
filePath: resolved,
|
|
604414
|
-
close: () => new Promise((resolveClose) => server2.close(() => resolveClose()))
|
|
604415
|
-
};
|
|
604416
|
-
currentViewer = session;
|
|
604417
|
-
server2.on("close", () => {
|
|
604418
|
-
if (currentViewer === session) currentViewer = null;
|
|
604419
|
-
});
|
|
604420
|
-
return session;
|
|
604421
|
-
}
|
|
604422
|
-
function listenOnEphemeralPort(server2) {
|
|
604423
|
-
return new Promise((resolveListen, reject) => {
|
|
604424
|
-
server2.once("error", reject);
|
|
604425
|
-
server2.listen(0, "127.0.0.1", () => {
|
|
604426
|
-
server2.off("error", reject);
|
|
604427
|
-
const addr = server2.address();
|
|
604428
|
-
if (!addr || typeof addr === "string") {
|
|
604429
|
-
reject(new Error("viewer server did not bind to a TCP port"));
|
|
604430
|
-
return;
|
|
604431
|
-
}
|
|
604432
|
-
resolveListen(addr.port);
|
|
604433
|
-
});
|
|
604434
|
-
});
|
|
604435
|
-
}
|
|
604436
|
-
function handleViewerRequest(req3, res, filePath) {
|
|
604437
|
-
const url = new URL(req3.url || "/", "http://127.0.0.1");
|
|
604438
|
-
if (url.pathname === "/health") {
|
|
604439
|
-
sendJson(res, 200, { ok: true, file: filePath ?? null });
|
|
604440
|
-
return;
|
|
604441
|
-
}
|
|
604442
|
-
if (url.pathname === "/asset") {
|
|
604443
|
-
if (!filePath) {
|
|
604444
|
-
sendText(res, 404, "No model file attached to this viewer.");
|
|
604445
|
-
return;
|
|
604446
|
-
}
|
|
604447
|
-
try {
|
|
604448
|
-
res.writeHead(200, {
|
|
604449
|
-
"Content-Type": contentTypeFor(filePath),
|
|
604450
|
-
"Content-Disposition": `inline; filename="${basename22(filePath).replace(/"/g, "")}"`,
|
|
604451
|
-
"Cache-Control": "no-store"
|
|
604452
|
-
});
|
|
604453
|
-
res.end(readFileSync86(filePath));
|
|
604454
|
-
} catch (err) {
|
|
604455
|
-
sendText(res, 500, err instanceof Error ? err.message : String(err));
|
|
604456
|
-
}
|
|
604457
|
-
return;
|
|
604458
|
-
}
|
|
604459
|
-
if (url.pathname !== "/") {
|
|
604460
|
-
sendText(res, 404, "Not found");
|
|
604461
|
-
return;
|
|
604462
|
-
}
|
|
604463
|
-
sendHtml(res, viewerHtml(filePath));
|
|
604464
|
-
}
|
|
604465
|
-
function contentTypeFor(path12) {
|
|
604466
|
-
const ext = extname15(path12).toLowerCase();
|
|
604467
|
-
if (ext === ".glb") return "model/gltf-binary";
|
|
604468
|
-
if (ext === ".gltf") return "model/gltf+json";
|
|
604469
|
-
if (ext === ".obj") return "text/plain; charset=utf-8";
|
|
604470
|
-
if (ext === ".stl") return "model/stl";
|
|
604471
|
-
if (ext === ".ply") return "application/octet-stream";
|
|
604472
|
-
return "application/octet-stream";
|
|
604473
|
-
}
|
|
604474
|
-
function sendJson(res, status, value2) {
|
|
604475
|
-
res.writeHead(status, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-store" });
|
|
604476
|
-
res.end(JSON.stringify(value2));
|
|
604477
|
-
}
|
|
604478
|
-
function sendText(res, status, text2) {
|
|
604479
|
-
res.writeHead(status, { "Content-Type": "text/plain; charset=utf-8", "Cache-Control": "no-store" });
|
|
604480
|
-
res.end(text2);
|
|
604481
|
-
}
|
|
604482
|
-
function sendHtml(res, html) {
|
|
604483
|
-
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" });
|
|
604484
|
-
res.end(html);
|
|
604485
|
-
}
|
|
604486
|
-
function viewerHtml(filePath) {
|
|
604487
|
-
const fileName = filePath ? basename22(filePath) : "";
|
|
604488
|
-
const ext = filePath ? extname15(filePath).toLowerCase().replace(/^\./, "") : "";
|
|
604489
|
-
return `<!doctype html>
|
|
604490
|
-
<html lang="en">
|
|
604491
|
-
<head>
|
|
604492
|
-
<meta charset="utf-8">
|
|
604493
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
604494
|
-
<title>Omnius CAD/3D Viewer</title>
|
|
604495
|
-
<style>
|
|
604496
|
-
:root { color-scheme: dark; --bg:#101214; --panel:#181b1f; --line:#2a3037; --fg:#e7edf3; --muted:#9aa7b5; --accent:#5ec6a8; }
|
|
604497
|
-
* { box-sizing: border-box; }
|
|
604498
|
-
body { margin:0; min-height:100vh; background:var(--bg); color:var(--fg); font:14px/1.4 ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; display:grid; grid-template-columns:minmax(280px,360px) 1fr; }
|
|
604499
|
-
aside { border-right:1px solid var(--line); background:var(--panel); padding:14px; display:flex; flex-direction:column; gap:12px; min-height:100vh; }
|
|
604500
|
-
main { position:relative; min-height:100vh; overflow:hidden; }
|
|
604501
|
-
h1 { margin:0; font-size:16px; font-weight:650; }
|
|
604502
|
-
.meta { color:var(--muted); font-size:12px; word-break:break-word; }
|
|
604503
|
-
textarea { width:100%; min-height:280px; resize:vertical; border:1px solid var(--line); border-radius:6px; background:#0c0e10; color:var(--fg); padding:10px; font:12px/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; }
|
|
604504
|
-
button { border:1px solid var(--line); border-radius:6px; background:#20262d; color:var(--fg); padding:8px 10px; cursor:pointer; }
|
|
604505
|
-
button:hover { border-color:var(--accent); }
|
|
604506
|
-
#status { color:var(--muted); min-height:20px; font-size:12px; }
|
|
604507
|
-
canvas { display:block; width:100%; height:100%; }
|
|
604508
|
-
.row { display:flex; gap:8px; flex-wrap:wrap; }
|
|
604509
|
-
@media (max-width: 760px) { body { grid-template-columns:1fr; grid-template-rows:auto 60vh; } aside { min-height:auto; border-right:0; border-bottom:1px solid var(--line); } }
|
|
604510
|
-
</style>
|
|
604511
|
-
</head>
|
|
604512
|
-
<body>
|
|
604513
|
-
<aside>
|
|
604514
|
-
<div>
|
|
604515
|
-
<h1>Omnius CAD/3D Viewer</h1>
|
|
604516
|
-
<div class="meta">${escapeHtml(fileName ? `Viewing ${fileName}` : "No file attached. Rendering Compact IR sample.")}</div>
|
|
604517
|
-
</div>
|
|
604518
|
-
<textarea id="ir">C 50 30 5
|
|
604519
|
-
Y 3 8
|
|
604520
|
-
T 1 -18 -10 2.5
|
|
604521
|
-
Y 3 8
|
|
604522
|
-
T 3 18 -10 2.5
|
|
604523
|
-
Y 3 8
|
|
604524
|
-
T 5 -18 10 2.5
|
|
604525
|
-
Y 3 8
|
|
604526
|
-
T 7 18 10 2.5</textarea>
|
|
604527
|
-
<div class="row">
|
|
604528
|
-
<button id="render-ir">Render Compact IR</button>
|
|
604529
|
-
<button id="reset-camera">Reset Camera</button>
|
|
604530
|
-
</div>
|
|
604531
|
-
<div id="status"></div>
|
|
604532
|
-
</aside>
|
|
604533
|
-
<main id="viewport"></main>
|
|
604534
|
-
<script type="module">
|
|
604535
|
-
import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.164.1/build/three.module.js';
|
|
604536
|
-
import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/controls/OrbitControls.js';
|
|
604537
|
-
import { GLTFLoader } from 'https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/loaders/GLTFLoader.js';
|
|
604538
|
-
import { STLLoader } from 'https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/loaders/STLLoader.js';
|
|
604539
|
-
import { OBJLoader } from 'https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/loaders/OBJLoader.js';
|
|
604540
|
-
import { PLYLoader } from 'https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/loaders/PLYLoader.js';
|
|
604541
|
-
|
|
604542
|
-
const assetUrl = ${JSON.stringify(filePath ? "/asset" : "")};
|
|
604543
|
-
const assetExt = ${JSON.stringify(ext)};
|
|
604544
|
-
const viewport = document.getElementById('viewport');
|
|
604545
|
-
const status = document.getElementById('status');
|
|
604546
|
-
const scene = new THREE.Scene();
|
|
604547
|
-
scene.background = new THREE.Color(0x101214);
|
|
604548
|
-
const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 5000);
|
|
604549
|
-
const renderer = new THREE.WebGLRenderer({ antialias:true });
|
|
604550
|
-
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
|
|
604551
|
-
viewport.appendChild(renderer.domElement);
|
|
604552
|
-
const controls = new OrbitControls(camera, renderer.domElement);
|
|
604553
|
-
controls.enableDamping = true;
|
|
604554
|
-
scene.add(new THREE.HemisphereLight(0xffffff, 0x223344, 1.7));
|
|
604555
|
-
const key = new THREE.DirectionalLight(0xffffff, 2.2);
|
|
604556
|
-
key.position.set(120, 160, 100);
|
|
604557
|
-
scene.add(key);
|
|
604558
|
-
const grid = new THREE.GridHelper(160, 32, 0x31404a, 0x253039);
|
|
604559
|
-
scene.add(grid);
|
|
604560
|
-
let objectRoot = new THREE.Group();
|
|
604561
|
-
scene.add(objectRoot);
|
|
604562
|
-
|
|
604563
|
-
function setStatus(text) { status.textContent = text || ''; }
|
|
604564
|
-
function clearObject() {
|
|
604565
|
-
scene.remove(objectRoot);
|
|
604566
|
-
objectRoot.traverse((o) => {
|
|
604567
|
-
if (o.geometry) o.geometry.dispose?.();
|
|
604568
|
-
if (o.material) {
|
|
604569
|
-
if (Array.isArray(o.material)) o.material.forEach((m) => m.dispose?.());
|
|
604570
|
-
else o.material.dispose?.();
|
|
604571
|
-
}
|
|
604572
|
-
});
|
|
604573
|
-
objectRoot = new THREE.Group();
|
|
604574
|
-
scene.add(objectRoot);
|
|
604575
|
-
}
|
|
604576
|
-
function frameObject() {
|
|
604577
|
-
const box = new THREE.Box3().setFromObject(objectRoot);
|
|
604578
|
-
if (box.isEmpty()) {
|
|
604579
|
-
camera.position.set(70, 70, 70);
|
|
604580
|
-
controls.target.set(0, 0, 0);
|
|
604581
|
-
return;
|
|
604582
|
-
}
|
|
604583
|
-
const size = box.getSize(new THREE.Vector3());
|
|
604584
|
-
const center = box.getCenter(new THREE.Vector3());
|
|
604585
|
-
const max = Math.max(size.x, size.y, size.z, 1);
|
|
604586
|
-
camera.position.copy(center).add(new THREE.Vector3(max * 1.35, max * 1.05, max * 1.35));
|
|
604587
|
-
controls.target.copy(center);
|
|
604588
|
-
camera.near = Math.max(0.01, max / 1000);
|
|
604589
|
-
camera.far = Math.max(1000, max * 20);
|
|
604590
|
-
camera.updateProjectionMatrix();
|
|
604591
|
-
controls.update();
|
|
604592
|
-
}
|
|
604593
|
-
function makeMaterial(index) {
|
|
604594
|
-
const colors = [0x5ec6a8, 0xf0b35a, 0x87a8ff, 0xdc6f7e, 0xb6d96a];
|
|
604595
|
-
return new THREE.MeshStandardMaterial({ color: colors[index % colors.length], metalness:0.05, roughness:0.48 });
|
|
604596
|
-
}
|
|
604597
|
-
function renderCompactIr(text) {
|
|
604598
|
-
clearObject();
|
|
604599
|
-
const nodes = [];
|
|
604600
|
-
const lines = String(text || '').split(/\\r?\\n/).map((l) => l.trim()).filter((l) => l && !l.startsWith('#'));
|
|
604601
|
-
for (const line of lines) {
|
|
604602
|
-
const parts = line.split(/\\s+/);
|
|
604603
|
-
const op = parts[0].toUpperCase();
|
|
604604
|
-
const nums = parts.slice(1).map(Number);
|
|
604605
|
-
let mesh = null;
|
|
604606
|
-
if (op === 'C' && nums.length >= 3) {
|
|
604607
|
-
mesh = new THREE.Mesh(new THREE.BoxGeometry(nums[0], nums[1], nums[2]), makeMaterial(nodes.length));
|
|
604608
|
-
} else if (op === 'Y' && nums.length >= 2) {
|
|
604609
|
-
mesh = new THREE.Mesh(new THREE.CylinderGeometry(nums[0], nums[0], nums[1], 48), makeMaterial(nodes.length));
|
|
604610
|
-
mesh.rotation.x = Math.PI / 2;
|
|
604611
|
-
} else if (op === 'S' && nums.length >= 1) {
|
|
604612
|
-
mesh = new THREE.Mesh(new THREE.SphereGeometry(nums[0], 48, 24), makeMaterial(nodes.length));
|
|
604613
|
-
} else if (op === 'K' && nums.length >= 3) {
|
|
604614
|
-
mesh = new THREE.Mesh(new THREE.CylinderGeometry(nums[1], nums[0], nums[2], 48), makeMaterial(nodes.length));
|
|
604615
|
-
mesh.rotation.x = Math.PI / 2;
|
|
604616
|
-
} else if ((op === 'U' || op === 'D' || op === 'I') && nums.length >= 2) {
|
|
604617
|
-
const group = new THREE.Group();
|
|
604618
|
-
const a = nodes[nums[0]]?.clone();
|
|
604619
|
-
const b = nodes[nums[1]]?.clone();
|
|
604620
|
-
if (a) group.add(a);
|
|
604621
|
-
if (b) {
|
|
604622
|
-
if (op === 'D') b.traverse((o) => { if (o.material) o.material = new THREE.MeshStandardMaterial({ color:0xff5570, wireframe:true }); });
|
|
604623
|
-
group.add(b);
|
|
604624
|
-
}
|
|
604625
|
-
mesh = group;
|
|
604626
|
-
} else if ((op === 'T' || op === 'R' || op === 'X') && nums.length >= 4) {
|
|
604627
|
-
const target = nodes[nums[0]];
|
|
604628
|
-
if (target) {
|
|
604629
|
-
if (op === 'T') target.position.add(new THREE.Vector3(nums[1], nums[2], nums[3]));
|
|
604630
|
-
if (op === 'R') target.rotation.set(THREE.MathUtils.degToRad(nums[1]), THREE.MathUtils.degToRad(nums[2]), THREE.MathUtils.degToRad(nums[3]));
|
|
604631
|
-
if (op === 'X') target.scale.multiply(new THREE.Vector3(nums[1], nums[2], nums[3]));
|
|
604632
|
-
}
|
|
604633
|
-
nodes.push(target ? target.clone() : new THREE.Group());
|
|
604634
|
-
continue;
|
|
604635
|
-
} else if ((op === 'F' || op === 'CH' || op === 'SH') && nums.length >= 1) {
|
|
604636
|
-
const target = nodes[nums[0]];
|
|
604637
|
-
nodes.push(target ? target.clone() : new THREE.Group());
|
|
604638
|
-
continue;
|
|
604639
|
-
}
|
|
604640
|
-
if (mesh) {
|
|
604641
|
-
nodes.push(mesh);
|
|
604642
|
-
objectRoot.add(mesh);
|
|
604643
|
-
}
|
|
604644
|
-
}
|
|
604645
|
-
if (nodes.length === 0) setStatus('No renderable Compact IR primitives found.');
|
|
604646
|
-
else setStatus('Rendered ' + nodes.length + ' Compact IR node(s). Boolean difference is shown as wireframe preview.');
|
|
604647
|
-
frameObject();
|
|
604648
|
-
}
|
|
604649
|
-
async function loadAsset() {
|
|
604650
|
-
if (!assetUrl) {
|
|
604651
|
-
renderCompactIr(document.getElementById('ir').value);
|
|
604652
|
-
return;
|
|
604653
|
-
}
|
|
604654
|
-
setStatus('Loading attached model...');
|
|
604655
|
-
clearObject();
|
|
604656
|
-
const done = (obj) => {
|
|
604657
|
-
objectRoot.add(obj);
|
|
604658
|
-
setStatus('Loaded attached model.');
|
|
604659
|
-
frameObject();
|
|
604660
|
-
};
|
|
604661
|
-
if (assetExt === 'glb' || assetExt === 'gltf') {
|
|
604662
|
-
new GLTFLoader().load(assetUrl, (gltf) => done(gltf.scene), undefined, (e) => setStatus(e.message || String(e)));
|
|
604663
|
-
} else if (assetExt === 'stl') {
|
|
604664
|
-
new STLLoader().load(assetUrl, (geo) => done(new THREE.Mesh(geo, makeMaterial(0))), undefined, (e) => setStatus(e.message || String(e)));
|
|
604665
|
-
} else if (assetExt === 'obj') {
|
|
604666
|
-
new OBJLoader().load(assetUrl, done, undefined, (e) => setStatus(e.message || String(e)));
|
|
604667
|
-
} else if (assetExt === 'ply') {
|
|
604668
|
-
new PLYLoader().load(assetUrl, (geo) => done(new THREE.Mesh(geo, makeMaterial(0))), undefined, (e) => setStatus(e.message || String(e)));
|
|
604669
|
-
} else {
|
|
604670
|
-
setStatus('Unsupported file extension for browser preview. Use GLB, GLTF, OBJ, STL, or PLY.');
|
|
604671
|
-
renderCompactIr(document.getElementById('ir').value);
|
|
604672
|
-
}
|
|
604673
|
-
}
|
|
604674
|
-
function resize() {
|
|
604675
|
-
const rect = viewport.getBoundingClientRect();
|
|
604676
|
-
renderer.setSize(rect.width, rect.height, false);
|
|
604677
|
-
camera.aspect = Math.max(1, rect.width) / Math.max(1, rect.height);
|
|
604678
|
-
camera.updateProjectionMatrix();
|
|
604679
|
-
}
|
|
604680
|
-
window.addEventListener('resize', resize);
|
|
604681
|
-
document.getElementById('render-ir').addEventListener('click', () => renderCompactIr(document.getElementById('ir').value));
|
|
604682
|
-
document.getElementById('reset-camera').addEventListener('click', frameObject);
|
|
604683
|
-
renderer.setAnimationLoop(() => { controls.update(); renderer.render(scene, camera); });
|
|
604684
|
-
resize();
|
|
604685
|
-
loadAsset();
|
|
604686
|
-
</script>
|
|
604687
|
-
</body>
|
|
604688
|
-
</html>`;
|
|
604689
|
-
}
|
|
604690
|
-
function escapeHtml(value2) {
|
|
604691
|
-
return value2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
604692
|
-
}
|
|
604693
|
-
var currentViewer;
|
|
604694
|
-
var init_cad_model_viewer = __esm({
|
|
604695
|
-
"packages/cli/src/tui/cad-model-viewer.ts"() {
|
|
604696
|
-
"use strict";
|
|
604697
|
-
currentViewer = null;
|
|
604698
|
-
}
|
|
604699
|
-
});
|
|
604700
|
-
|
|
604701
|
-
// packages/cli/src/tui/hf-token-prompt.ts
|
|
604702
|
-
import * as fs9 from "node:fs";
|
|
604703
|
-
import * as os8 from "node:os";
|
|
604704
|
-
import * as path10 from "node:path";
|
|
604705
|
-
function loadHfToken() {
|
|
604706
|
-
const fromEnv = process.env["HF_TOKEN"]?.trim() || process.env["HUGGING_FACE_HUB_TOKEN"]?.trim() || "";
|
|
604707
|
-
if (fromEnv) return fromEnv;
|
|
604708
|
-
try {
|
|
604709
|
-
if (fs9.existsSync(TOKEN_FILE)) {
|
|
604710
|
-
const fromFile = fs9.readFileSync(TOKEN_FILE, "utf8").trim();
|
|
604711
|
-
if (fromFile) {
|
|
604712
|
-
process.env["HF_TOKEN"] = fromFile;
|
|
604713
|
-
return fromFile;
|
|
604714
|
-
}
|
|
604715
|
-
}
|
|
604716
|
-
} catch {
|
|
604717
|
-
}
|
|
604718
|
-
return null;
|
|
604719
|
-
}
|
|
604720
|
-
function saveHfToken(token) {
|
|
604721
|
-
const trimmed = token.trim();
|
|
604722
|
-
if (!trimmed) throw new Error("HF token cannot be empty");
|
|
604723
|
-
fs9.mkdirSync(TOKEN_DIR, { recursive: true, mode: 448 });
|
|
604724
|
-
fs9.writeFileSync(TOKEN_FILE, trimmed + "\n", { mode: 384 });
|
|
604725
|
-
try {
|
|
604726
|
-
fs9.chmodSync(TOKEN_FILE, 384);
|
|
604727
|
-
} catch {
|
|
604728
|
-
}
|
|
604729
|
-
process.env["HF_TOKEN"] = trimmed;
|
|
604730
|
-
}
|
|
604731
|
-
function clearHfToken() {
|
|
604732
|
-
try {
|
|
604733
|
-
if (fs9.existsSync(TOKEN_FILE)) fs9.unlinkSync(TOKEN_FILE);
|
|
604734
|
-
} catch {
|
|
604735
|
-
}
|
|
604736
|
-
delete process.env["HF_TOKEN"];
|
|
604737
|
-
}
|
|
604738
|
-
function isHfTokenPromptPending() {
|
|
604739
|
-
return pending !== null;
|
|
604740
|
-
}
|
|
604741
|
-
function describePendingHfTokenPrompt() {
|
|
604742
|
-
if (!pending) return null;
|
|
604743
|
-
return { model: pending.model, ageMs: Date.now() - pending.startedAt };
|
|
604744
|
-
}
|
|
604745
|
-
function requestHfToken(opts) {
|
|
604746
|
-
const existing = loadHfToken();
|
|
604747
|
-
if (existing) return Promise.resolve(existing);
|
|
604748
|
-
if (pending) {
|
|
604749
|
-
opts.onMessage(
|
|
604750
|
-
`Another HF token prompt is already active (for ${pending.model}). Run \`/hf <token>\` to satisfy both, or wait for the existing prompt to time out.`
|
|
604751
|
-
);
|
|
604752
|
-
return Promise.resolve(null);
|
|
604753
|
-
}
|
|
604754
|
-
const timeoutMs = Math.max(1e3, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS4);
|
|
604755
|
-
const timeoutSec = Math.round(timeoutMs / 1e3);
|
|
604756
|
-
const fallbackBit = opts.fallbackModel ? `
|
|
604757
|
-
If you don't supply one within ${timeoutSec}s, I will fall back to ${opts.fallbackModel} (no token needed).` : `
|
|
604758
|
-
If you don't supply one within ${timeoutSec}s, I will fall back to a non-gated alternative.`;
|
|
604759
|
-
opts.onMessage(
|
|
604760
|
-
[
|
|
604761
|
-
`Hugging Face model "${opts.model}" is gated and needs an access token.`,
|
|
604762
|
-
`Get one at https://huggingface.co/settings/tokens (read-only is fine),`,
|
|
604763
|
-
`accept the model license at https://huggingface.co/${opts.model},`,
|
|
604764
|
-
`then run: /hf <your-token>`,
|
|
604765
|
-
fallbackBit.trim()
|
|
604766
|
-
].join("\n")
|
|
604767
|
-
);
|
|
604768
|
-
return new Promise((resolve71) => {
|
|
604769
|
-
const timer = setTimeout(() => {
|
|
604770
|
-
const ref = pending;
|
|
604771
|
-
pending = null;
|
|
604772
|
-
if (ref) {
|
|
604773
|
-
ref.onMessage(
|
|
604774
|
-
`No HF token supplied within ${timeoutSec}s — falling back to a non-gated alternative for ${opts.model}.`
|
|
604775
|
-
);
|
|
604776
|
-
}
|
|
604777
|
-
resolve71(null);
|
|
604778
|
-
}, timeoutMs);
|
|
604779
|
-
if (typeof timer.unref === "function") timer.unref();
|
|
604780
|
-
pending = {
|
|
604781
|
-
model: opts.model,
|
|
604782
|
-
onMessage: opts.onMessage,
|
|
604783
|
-
resolve: resolve71,
|
|
604784
|
-
timer,
|
|
604785
|
-
startedAt: Date.now()
|
|
604786
|
-
};
|
|
604787
|
-
});
|
|
604788
|
-
}
|
|
604789
|
-
function fulfillHfTokenPrompt(token) {
|
|
604790
|
-
const trimmed = token.trim();
|
|
604791
|
-
if (!trimmed) return false;
|
|
604792
|
-
saveHfToken(trimmed);
|
|
604793
|
-
if (!pending) return false;
|
|
604794
|
-
const ref = pending;
|
|
604795
|
-
pending = null;
|
|
604796
|
-
clearTimeout(ref.timer);
|
|
604797
|
-
ref.resolve(trimmed);
|
|
604798
|
-
return true;
|
|
604799
|
-
}
|
|
604800
|
-
function cancelHfTokenPrompt() {
|
|
604801
|
-
if (!pending) return false;
|
|
604802
|
-
const ref = pending;
|
|
604803
|
-
pending = null;
|
|
604804
|
-
clearTimeout(ref.timer);
|
|
604805
|
-
ref.resolve(null);
|
|
604806
|
-
return true;
|
|
604807
|
-
}
|
|
604808
|
-
function isHfGatedError(blob) {
|
|
604809
|
-
if (!blob) return false;
|
|
604810
|
-
const text2 = blob.toLowerCase();
|
|
604811
|
-
if (text2.includes("[hf_token_required")) return true;
|
|
604812
|
-
if (text2.includes("gatedrepoerror")) return true;
|
|
604813
|
-
if (text2.includes("access to model")) return true;
|
|
604814
|
-
if (text2.includes("you need to accept")) return true;
|
|
604815
|
-
if (text2.includes("you must be authenticated")) return true;
|
|
604816
|
-
if (/(401|403)/.test(text2) && /(gated|access|unauthor|forbid|auth)/.test(text2)) {
|
|
604817
|
-
return true;
|
|
604818
|
-
}
|
|
604819
|
-
return false;
|
|
604820
|
-
}
|
|
604821
|
-
function extractGatedRepoId(blob) {
|
|
604822
|
-
if (!blob) return null;
|
|
604823
|
-
const tokenMarker = blob.match(/\[HF_TOKEN_REQUIRED:([^\]\s]+)\]/);
|
|
604824
|
-
if (tokenMarker?.[1]) return tokenMarker[1].trim();
|
|
604825
|
-
const hfUrl = blob.match(/huggingface\.co\/([A-Za-z0-9._-]+\/[A-Za-z0-9._-]+)/);
|
|
604826
|
-
if (hfUrl?.[1]) return hfUrl[1];
|
|
604827
|
-
const genericRepo = blob.match(/['"`]([A-Za-z0-9._-]+\/[A-Za-z0-9._-]+)['"`]/);
|
|
604828
|
-
if (genericRepo?.[1] && /\/(.+)/.test(genericRepo[1])) return genericRepo[1];
|
|
604829
|
-
return null;
|
|
604830
|
-
}
|
|
604831
|
-
var TOKEN_DIR, TOKEN_FILE, DEFAULT_TIMEOUT_MS4, pending;
|
|
604832
|
-
var init_hf_token_prompt = __esm({
|
|
604833
|
-
"packages/cli/src/tui/hf-token-prompt.ts"() {
|
|
604834
|
-
"use strict";
|
|
604835
|
-
TOKEN_DIR = path10.join(os8.homedir(), ".omnius");
|
|
604836
|
-
TOKEN_FILE = path10.join(TOKEN_DIR, "hf_token");
|
|
604837
|
-
DEFAULT_TIMEOUT_MS4 = 3e4;
|
|
604838
|
-
pending = null;
|
|
604839
|
-
}
|
|
604840
|
-
});
|
|
604841
|
-
|
|
604842
|
-
// packages/prompts/dist/loader.js
|
|
604843
|
-
var init_loader = __esm({
|
|
604844
|
-
"packages/prompts/dist/loader.js"() {
|
|
604845
|
-
"use strict";
|
|
604846
|
-
}
|
|
604847
|
-
});
|
|
604848
|
-
|
|
604849
|
-
// packages/prompts/dist/render.js
|
|
604850
|
-
var init_render2 = __esm({
|
|
604851
|
-
"packages/prompts/dist/render.js"() {
|
|
604852
|
-
"use strict";
|
|
604853
|
-
}
|
|
604854
|
-
});
|
|
604855
|
-
|
|
604856
|
-
// packages/prompts/dist/promptLoader.js
|
|
604857
|
-
import { readFileSync as readFileSync88, existsSync as existsSync109 } from "node:fs";
|
|
604858
|
-
import { join as join123, dirname as dirname38 } from "node:path";
|
|
604859
|
-
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
604860
|
-
function loadPrompt2(promptPath, vars) {
|
|
604861
|
-
let content = cache6.get(promptPath);
|
|
604862
|
-
if (content === void 0) {
|
|
604863
|
-
const fullPath = join123(PROMPTS_DIR2, promptPath);
|
|
604864
|
-
if (!existsSync109(fullPath)) {
|
|
604865
|
-
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
604866
|
-
}
|
|
604867
|
-
content = readFileSync88(fullPath, "utf-8");
|
|
604868
|
-
cache6.set(promptPath, content);
|
|
604869
|
-
}
|
|
604870
|
-
if (!vars)
|
|
604871
|
-
return content;
|
|
604872
|
-
return content.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
604873
|
-
}
|
|
604874
|
-
var __filename4, __dirname5, devPath, publishedPath, PROMPTS_DIR2, cache6;
|
|
604875
|
-
var init_promptLoader2 = __esm({
|
|
604876
|
-
"packages/prompts/dist/promptLoader.js"() {
|
|
604877
|
-
"use strict";
|
|
604878
|
-
__filename4 = fileURLToPath13(import.meta.url);
|
|
604879
|
-
__dirname5 = dirname38(__filename4);
|
|
604880
|
-
devPath = join123(__dirname5, "..", "templates");
|
|
604881
|
-
publishedPath = join123(__dirname5, "..", "prompts", "templates");
|
|
604882
|
-
PROMPTS_DIR2 = existsSync109(devPath) ? devPath : publishedPath;
|
|
604883
|
-
cache6 = /* @__PURE__ */ new Map();
|
|
604884
|
-
}
|
|
604885
|
-
});
|
|
604886
|
-
|
|
604887
|
-
// packages/prompts/dist/task-templates.js
|
|
604888
|
-
function getTaskTemplate(type) {
|
|
604889
|
-
return TEMPLATES[type];
|
|
604890
|
-
}
|
|
604891
|
-
function getTaskTypes() {
|
|
604892
|
-
return Object.keys(TEMPLATES);
|
|
604893
|
-
}
|
|
604894
|
-
function buildTaskContext(type) {
|
|
604895
|
-
const template = TEMPLATES[type];
|
|
604896
|
-
return `${template.systemPromptAddition}
|
|
604897
|
-
|
|
604898
|
-
### Output Guidance
|
|
604899
|
-
${template.outputGuidance}`;
|
|
604900
|
-
}
|
|
604901
|
-
var TEMPLATES;
|
|
604902
|
-
var init_task_templates = __esm({
|
|
604903
|
-
"packages/prompts/dist/task-templates.js"() {
|
|
604904
|
-
"use strict";
|
|
604905
|
-
init_promptLoader2();
|
|
604906
|
-
TEMPLATES = {
|
|
604907
|
-
code: {
|
|
604908
|
-
type: "code",
|
|
604909
|
-
label: "Software Development",
|
|
604910
|
-
description: "Writing, debugging, refactoring, or reviewing code.",
|
|
604911
|
-
systemPromptAddition: loadPrompt2("code.md"),
|
|
604912
|
-
recommendedTools: [
|
|
604913
|
-
"file_read",
|
|
604914
|
-
"file_write",
|
|
604915
|
-
"file_edit",
|
|
604916
|
-
"shell",
|
|
604917
|
-
"grep_search",
|
|
604918
|
-
"glob_find",
|
|
604919
|
-
"git_info",
|
|
604920
|
-
"codebase_map"
|
|
604921
|
-
],
|
|
604922
|
-
outputGuidance: "Deliver working code with tests passing. Summarize what was changed and why."
|
|
604923
|
-
},
|
|
604924
|
-
document: {
|
|
604925
|
-
type: "document",
|
|
604926
|
-
label: "Document Drafting",
|
|
604927
|
-
description: "Creating reports, specifications, guides, proposals, or other professional documents.",
|
|
604928
|
-
systemPromptAddition: loadPrompt2("document.md"),
|
|
604929
|
-
recommendedTools: [
|
|
604930
|
-
"file_read",
|
|
604931
|
-
"file_write",
|
|
604932
|
-
"web_search",
|
|
604933
|
-
"web_fetch",
|
|
604934
|
-
"create_structured_file",
|
|
604935
|
-
"memory_read"
|
|
604936
|
-
],
|
|
604937
|
-
outputGuidance: "Deliver a complete, well-structured document. Specify the output format (Markdown, PDF, etc.)."
|
|
604938
|
-
},
|
|
604939
|
-
analysis: {
|
|
604940
|
-
type: "analysis",
|
|
604941
|
-
label: "Analysis & Research",
|
|
604942
|
-
description: "Analyzing data, evaluating options, conducting research, or producing insights.",
|
|
604943
|
-
systemPromptAddition: loadPrompt2("analysis.md"),
|
|
604944
|
-
recommendedTools: [
|
|
604945
|
-
"file_read",
|
|
604946
|
-
"grep_search",
|
|
604947
|
-
"glob_find",
|
|
604948
|
-
"web_search",
|
|
604949
|
-
"web_fetch",
|
|
604950
|
-
"codebase_map",
|
|
604951
|
-
"create_structured_file",
|
|
604952
|
-
"shell"
|
|
604953
|
-
],
|
|
604954
|
-
outputGuidance: "Deliver a structured analysis with findings, data tables, and actionable recommendations."
|
|
604955
|
-
},
|
|
604956
|
-
plan: {
|
|
604957
|
-
type: "plan",
|
|
604958
|
-
label: "Planning & Design",
|
|
604959
|
-
description: "Creating project plans, system designs, architecture proposals, or roadmaps.",
|
|
604960
|
-
systemPromptAddition: loadPrompt2("plan.md"),
|
|
604961
|
-
recommendedTools: [
|
|
604962
|
-
"file_read",
|
|
604963
|
-
"grep_search",
|
|
604964
|
-
"glob_find",
|
|
604965
|
-
"codebase_map",
|
|
604966
|
-
"web_search",
|
|
604967
|
-
"create_structured_file",
|
|
604968
|
-
"file_write",
|
|
604969
|
-
"git_info"
|
|
604970
|
-
],
|
|
604971
|
-
outputGuidance: "Deliver a structured plan with phases, milestones, risks, and action items."
|
|
604972
|
-
},
|
|
604973
|
-
general: {
|
|
604974
|
-
type: "general",
|
|
604975
|
-
label: "General Task",
|
|
604976
|
-
description: "Tasks that don't clearly fit another category.",
|
|
604977
|
-
systemPromptAddition: loadPrompt2("general.md"),
|
|
604978
|
-
recommendedTools: [
|
|
604979
|
-
"file_read",
|
|
604980
|
-
"file_write",
|
|
604981
|
-
"shell",
|
|
604982
|
-
"grep_search",
|
|
604983
|
-
"web_search",
|
|
604984
|
-
"memory_read"
|
|
604985
|
-
],
|
|
604986
|
-
outputGuidance: "Deliver complete results with a clear summary of what was done."
|
|
604987
|
-
}
|
|
604988
|
-
};
|
|
604989
|
-
}
|
|
604990
|
-
});
|
|
604991
|
-
|
|
604992
|
-
// packages/prompts/dist/index.js
|
|
604993
|
-
import { join as join124, dirname as dirname39 } from "node:path";
|
|
604994
|
-
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
604995
|
-
var _dir, _packageRoot;
|
|
604996
|
-
var init_dist9 = __esm({
|
|
604997
|
-
"packages/prompts/dist/index.js"() {
|
|
604998
|
-
"use strict";
|
|
604999
|
-
init_loader();
|
|
605000
|
-
init_render2();
|
|
605001
|
-
init_task_templates();
|
|
605002
|
-
init_render2();
|
|
605003
|
-
_dir = dirname39(fileURLToPath14(import.meta.url));
|
|
605004
|
-
_packageRoot = join124(_dir, "..");
|
|
605005
|
-
}
|
|
605006
|
-
});
|
|
605007
|
-
|
|
605008
604404
|
// packages/cli/src/tui/omnius-directory.ts
|
|
605009
604405
|
var omnius_directory_exports = {};
|
|
605010
604406
|
__export(omnius_directory_exports, {
|
|
@@ -605043,24 +604439,25 @@ __export(omnius_directory_exports, {
|
|
|
605043
604439
|
saveSessionHistory: () => saveSessionHistory,
|
|
605044
604440
|
sessionContextToHistoryBoxData: () => sessionContextToHistoryBoxData,
|
|
605045
604441
|
stopOmniusGitignoreWatcher: () => stopOmniusGitignoreWatcher,
|
|
604442
|
+
updateSessionEntry: () => updateSessionEntry,
|
|
605046
604443
|
writeIndexData: () => writeIndexData,
|
|
605047
604444
|
writeIndexMeta: () => writeIndexMeta,
|
|
605048
604445
|
writeTaskHandoff: () => writeTaskHandoff2
|
|
605049
604446
|
});
|
|
605050
|
-
import { appendFileSync as appendFileSync9, cpSync as cpSync2, existsSync as
|
|
605051
|
-
import { join as
|
|
605052
|
-
import { homedir as
|
|
604447
|
+
import { appendFileSync as appendFileSync9, cpSync as cpSync2, existsSync as existsSync107, mkdirSync as mkdirSync65, readFileSync as readFileSync86, writeFileSync as writeFileSync55, readdirSync as readdirSync37, statSync as statSync41, unlinkSync as unlinkSync21, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync8, watch as fsWatch2 } from "node:fs";
|
|
604448
|
+
import { join as join122, relative as relative12, basename as basename22, dirname as dirname38, resolve as resolve52 } from "node:path";
|
|
604449
|
+
import { homedir as homedir37 } from "node:os";
|
|
605053
604450
|
import { createHash as createHash34 } from "node:crypto";
|
|
605054
604451
|
function isGitRoot(dir) {
|
|
605055
|
-
const gitPath =
|
|
605056
|
-
if (!
|
|
604452
|
+
const gitPath = join122(dir, ".git");
|
|
604453
|
+
if (!existsSync107(gitPath)) return false;
|
|
605057
604454
|
try {
|
|
605058
|
-
const stat8 =
|
|
604455
|
+
const stat8 = statSync41(gitPath);
|
|
605059
604456
|
if (stat8.isFile()) {
|
|
605060
|
-
return
|
|
604457
|
+
return readFileSync86(gitPath, "utf-8").trim().startsWith("gitdir:");
|
|
605061
604458
|
}
|
|
605062
604459
|
if (!stat8.isDirectory()) return false;
|
|
605063
|
-
return
|
|
604460
|
+
return existsSync107(join122(gitPath, "HEAD")) || existsSync107(join122(gitPath, "config")) || existsSync107(join122(gitPath, "commondir"));
|
|
605064
604461
|
} catch {
|
|
605065
604462
|
return false;
|
|
605066
604463
|
}
|
|
@@ -605071,7 +604468,7 @@ function findGitRoot(startDir) {
|
|
|
605071
604468
|
while (dir && !visited.has(dir)) {
|
|
605072
604469
|
visited.add(dir);
|
|
605073
604470
|
if (isGitRoot(dir)) return dir;
|
|
605074
|
-
const parent =
|
|
604471
|
+
const parent = join122(dir, "..");
|
|
605075
604472
|
if (parent === dir) break;
|
|
605076
604473
|
dir = parent;
|
|
605077
604474
|
}
|
|
@@ -605082,10 +604479,10 @@ function findNearestExistingGitignore(startDir, gitRoot) {
|
|
|
605082
604479
|
const visited = /* @__PURE__ */ new Set();
|
|
605083
604480
|
while (dir && !visited.has(dir)) {
|
|
605084
604481
|
visited.add(dir);
|
|
605085
|
-
const candidate =
|
|
605086
|
-
if (
|
|
604482
|
+
const candidate = join122(dir, ".gitignore");
|
|
604483
|
+
if (existsSync107(candidate)) return candidate;
|
|
605087
604484
|
if (dir === gitRoot) break;
|
|
605088
|
-
const parent =
|
|
604485
|
+
const parent = join122(dir, "..");
|
|
605089
604486
|
if (parent === dir) break;
|
|
605090
604487
|
dir = parent;
|
|
605091
604488
|
}
|
|
@@ -605099,7 +604496,7 @@ function candidateGitignoreDirs(startDir, gitRoot) {
|
|
|
605099
604496
|
visited.add(dir);
|
|
605100
604497
|
dirs.push(dir);
|
|
605101
604498
|
if (dir === gitRoot) break;
|
|
605102
|
-
const parent =
|
|
604499
|
+
const parent = join122(dir, "..");
|
|
605103
604500
|
if (parent === dir) break;
|
|
605104
604501
|
dir = parent;
|
|
605105
604502
|
}
|
|
@@ -605113,10 +604510,10 @@ function ensureOmniusIgnored(repoRoot) {
|
|
|
605113
604510
|
if (!gitRoot) return;
|
|
605114
604511
|
const gitignorePath = findNearestExistingGitignore(repoRoot, gitRoot);
|
|
605115
604512
|
if (!gitignorePath) return;
|
|
605116
|
-
const gitignoreDir =
|
|
604513
|
+
const gitignoreDir = dirname38(gitignorePath);
|
|
605117
604514
|
const relDir = relative12(gitignoreDir || ".", repoRoot).replace(/\\/g, "/");
|
|
605118
604515
|
const ignorePattern = relDir && relDir !== "." ? `${relDir}/.omnius/` : ".omnius/";
|
|
605119
|
-
const content =
|
|
604516
|
+
const content = readFileSync86(gitignorePath, "utf-8");
|
|
605120
604517
|
const normalizedTarget = normalizeIgnoreRule(ignorePattern);
|
|
605121
604518
|
const alreadyIgnored = content.split(/\r?\n/).some((line) => {
|
|
605122
604519
|
const trimmed = line.trim();
|
|
@@ -605124,7 +604521,7 @@ function ensureOmniusIgnored(repoRoot) {
|
|
|
605124
604521
|
return normalizeIgnoreRule(trimmed) === normalizedTarget;
|
|
605125
604522
|
});
|
|
605126
604523
|
if (alreadyIgnored) return;
|
|
605127
|
-
|
|
604524
|
+
writeFileSync55(
|
|
605128
604525
|
gitignorePath,
|
|
605129
604526
|
(content.trimEnd() ? `${content.trimEnd()}
|
|
605130
604527
|
` : "") + `${ignorePattern}
|
|
@@ -605135,7 +604532,7 @@ function ensureOmniusIgnored(repoRoot) {
|
|
|
605135
604532
|
function watchForOmniusGitignore(repoRoot) {
|
|
605136
604533
|
const gitRoot = findGitRoot(repoRoot);
|
|
605137
604534
|
if (!gitRoot) return;
|
|
605138
|
-
const key =
|
|
604535
|
+
const key = resolve52(repoRoot);
|
|
605139
604536
|
if (gitignoreWatchers.has(key)) return;
|
|
605140
604537
|
const watchers = [];
|
|
605141
604538
|
for (const dir of candidateGitignoreDirs(repoRoot, gitRoot)) {
|
|
@@ -605161,7 +604558,7 @@ function watchForOmniusGitignore(repoRoot) {
|
|
|
605161
604558
|
if (watchers.length > 0) gitignoreWatchers.set(key, watchers);
|
|
605162
604559
|
}
|
|
605163
604560
|
function stopOmniusGitignoreWatcher(repoRoot) {
|
|
605164
|
-
const keys = repoRoot ? [
|
|
604561
|
+
const keys = repoRoot ? [resolve52(repoRoot)] : Array.from(gitignoreWatchers.keys());
|
|
605165
604562
|
for (const key of keys) {
|
|
605166
604563
|
const watchers = gitignoreWatchers.get(key) ?? [];
|
|
605167
604564
|
for (const watcher of watchers) {
|
|
@@ -605175,8 +604572,8 @@ function stopOmniusGitignoreWatcher(repoRoot) {
|
|
|
605175
604572
|
}
|
|
605176
604573
|
function migrateLegacyDirectories(repoRoot, omniusPath) {
|
|
605177
604574
|
for (const legacyDir of LEGACY_DIRS) {
|
|
605178
|
-
const legacyPath =
|
|
605179
|
-
if (!
|
|
604575
|
+
const legacyPath = join122(repoRoot, legacyDir);
|
|
604576
|
+
if (!existsSync107(legacyPath) || legacyPath === omniusPath) continue;
|
|
605180
604577
|
try {
|
|
605181
604578
|
cpSync2(legacyPath, omniusPath, {
|
|
605182
604579
|
recursive: true,
|
|
@@ -605188,11 +604585,11 @@ function migrateLegacyDirectories(repoRoot, omniusPath) {
|
|
|
605188
604585
|
}
|
|
605189
604586
|
}
|
|
605190
604587
|
function initOmniusDirectory(repoRoot) {
|
|
605191
|
-
const omniusPath =
|
|
605192
|
-
|
|
604588
|
+
const omniusPath = join122(repoRoot, OMNIUS_DIR);
|
|
604589
|
+
mkdirSync65(omniusPath, { recursive: true });
|
|
605193
604590
|
migrateLegacyDirectories(repoRoot, omniusPath);
|
|
605194
604591
|
for (const sub2 of SUBDIRS) {
|
|
605195
|
-
|
|
604592
|
+
mkdirSync65(join122(omniusPath, sub2), { recursive: true });
|
|
605196
604593
|
}
|
|
605197
604594
|
try {
|
|
605198
604595
|
ensureOmniusIgnored(repoRoot);
|
|
@@ -605205,41 +604602,41 @@ function initOmniusDirectory(repoRoot) {
|
|
|
605205
604602
|
return omniusPath;
|
|
605206
604603
|
}
|
|
605207
604604
|
function hasOmniusDirectory(repoRoot) {
|
|
605208
|
-
return
|
|
604605
|
+
return existsSync107(join122(repoRoot, OMNIUS_DIR, "index"));
|
|
605209
604606
|
}
|
|
605210
604607
|
function loadProjectSettings(repoRoot) {
|
|
605211
|
-
const settingsPath =
|
|
604608
|
+
const settingsPath = join122(repoRoot, OMNIUS_DIR, "settings.json");
|
|
605212
604609
|
try {
|
|
605213
|
-
if (
|
|
605214
|
-
return JSON.parse(
|
|
604610
|
+
if (existsSync107(settingsPath)) {
|
|
604611
|
+
return JSON.parse(readFileSync86(settingsPath, "utf-8"));
|
|
605215
604612
|
}
|
|
605216
604613
|
} catch {
|
|
605217
604614
|
}
|
|
605218
604615
|
return {};
|
|
605219
604616
|
}
|
|
605220
604617
|
function saveProjectSettings(repoRoot, settings) {
|
|
605221
|
-
const omniusPath =
|
|
605222
|
-
|
|
604618
|
+
const omniusPath = join122(repoRoot, OMNIUS_DIR);
|
|
604619
|
+
mkdirSync65(omniusPath, { recursive: true });
|
|
605223
604620
|
const existing = loadProjectSettings(repoRoot);
|
|
605224
604621
|
const merged = { ...existing, ...settings };
|
|
605225
|
-
|
|
604622
|
+
writeFileSync55(join122(omniusPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
605226
604623
|
}
|
|
605227
604624
|
function loadGlobalSettings() {
|
|
605228
|
-
const settingsPath =
|
|
604625
|
+
const settingsPath = join122(homedir37(), ".omnius", "settings.json");
|
|
605229
604626
|
try {
|
|
605230
|
-
if (
|
|
605231
|
-
return JSON.parse(
|
|
604627
|
+
if (existsSync107(settingsPath)) {
|
|
604628
|
+
return JSON.parse(readFileSync86(settingsPath, "utf-8"));
|
|
605232
604629
|
}
|
|
605233
604630
|
} catch {
|
|
605234
604631
|
}
|
|
605235
604632
|
return {};
|
|
605236
604633
|
}
|
|
605237
604634
|
function saveGlobalSettings(settings) {
|
|
605238
|
-
const dir =
|
|
605239
|
-
|
|
604635
|
+
const dir = join122(homedir37(), ".omnius");
|
|
604636
|
+
mkdirSync65(dir, { recursive: true });
|
|
605240
604637
|
const existing = loadGlobalSettings();
|
|
605241
604638
|
const merged = { ...existing, ...settings };
|
|
605242
|
-
|
|
604639
|
+
writeFileSync55(join122(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
605243
604640
|
}
|
|
605244
604641
|
function resolveSettings(repoRoot) {
|
|
605245
604642
|
const global2 = loadGlobalSettings();
|
|
@@ -605254,12 +604651,12 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
605254
604651
|
while (dir && !visited.has(dir)) {
|
|
605255
604652
|
visited.add(dir);
|
|
605256
604653
|
for (const name10 of CONTEXT_FILES) {
|
|
605257
|
-
const filePath =
|
|
604654
|
+
const filePath = join122(dir, name10);
|
|
605258
604655
|
const normalizedName = name10.toLowerCase();
|
|
605259
|
-
if (
|
|
604656
|
+
if (existsSync107(filePath) && !seen.has(filePath)) {
|
|
605260
604657
|
seen.add(filePath);
|
|
605261
604658
|
try {
|
|
605262
|
-
let content =
|
|
604659
|
+
let content = readFileSync86(filePath, "utf-8");
|
|
605263
604660
|
if (content.length > maxContentLen) {
|
|
605264
604661
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
605265
604662
|
}
|
|
@@ -605273,7 +604670,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
605273
604670
|
}
|
|
605274
604671
|
}
|
|
605275
604672
|
}
|
|
605276
|
-
const parent =
|
|
604673
|
+
const parent = join122(dir, "..");
|
|
605277
604674
|
if (parent === dir) break;
|
|
605278
604675
|
dir = parent;
|
|
605279
604676
|
}
|
|
@@ -605290,34 +604687,34 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
605290
604687
|
return found;
|
|
605291
604688
|
}
|
|
605292
604689
|
function readIndexMeta(repoRoot) {
|
|
605293
|
-
const metaPath =
|
|
604690
|
+
const metaPath = join122(repoRoot, OMNIUS_DIR, "index", "meta.json");
|
|
605294
604691
|
try {
|
|
605295
|
-
return JSON.parse(
|
|
604692
|
+
return JSON.parse(readFileSync86(metaPath, "utf-8"));
|
|
605296
604693
|
} catch {
|
|
605297
604694
|
return null;
|
|
605298
604695
|
}
|
|
605299
604696
|
}
|
|
605300
604697
|
function writeIndexMeta(repoRoot, meta) {
|
|
605301
|
-
const metaPath =
|
|
605302
|
-
|
|
605303
|
-
|
|
604698
|
+
const metaPath = join122(repoRoot, OMNIUS_DIR, "index", "meta.json");
|
|
604699
|
+
mkdirSync65(join122(repoRoot, OMNIUS_DIR, "index"), { recursive: true });
|
|
604700
|
+
writeFileSync55(metaPath, JSON.stringify(meta, null, 2), "utf-8");
|
|
605304
604701
|
}
|
|
605305
604702
|
function readIndexData(repoRoot, filename) {
|
|
605306
|
-
const filePath =
|
|
604703
|
+
const filePath = join122(repoRoot, OMNIUS_DIR, "index", filename);
|
|
605307
604704
|
try {
|
|
605308
|
-
return JSON.parse(
|
|
604705
|
+
return JSON.parse(readFileSync86(filePath, "utf-8"));
|
|
605309
604706
|
} catch {
|
|
605310
604707
|
return null;
|
|
605311
604708
|
}
|
|
605312
604709
|
}
|
|
605313
604710
|
function writeIndexData(repoRoot, filename, data) {
|
|
605314
|
-
const filePath =
|
|
605315
|
-
|
|
605316
|
-
|
|
604711
|
+
const filePath = join122(repoRoot, OMNIUS_DIR, "index", filename);
|
|
604712
|
+
mkdirSync65(join122(repoRoot, OMNIUS_DIR, "index"), { recursive: true });
|
|
604713
|
+
writeFileSync55(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
605317
604714
|
}
|
|
605318
604715
|
function generateProjectMap(repoRoot) {
|
|
605319
604716
|
const sections = [];
|
|
605320
|
-
const repoName2 =
|
|
604717
|
+
const repoName2 = basename22(repoRoot);
|
|
605321
604718
|
sections.push(`# Project Map: ${repoName2}
|
|
605322
604719
|
`);
|
|
605323
604720
|
sections.push(`> Auto-generated by omnius. Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -605360,31 +604757,31 @@ ${tree2}\`\`\`
|
|
|
605360
604757
|
sections.push("");
|
|
605361
604758
|
}
|
|
605362
604759
|
const content = sections.join("\n");
|
|
605363
|
-
const contextDir =
|
|
605364
|
-
|
|
605365
|
-
|
|
604760
|
+
const contextDir = join122(repoRoot, OMNIUS_DIR, "context");
|
|
604761
|
+
mkdirSync65(contextDir, { recursive: true });
|
|
604762
|
+
writeFileSync55(join122(contextDir, "project-map.md"), content, "utf-8");
|
|
605366
604763
|
return content;
|
|
605367
604764
|
}
|
|
605368
604765
|
function saveSession(repoRoot, session) {
|
|
605369
|
-
const historyDir =
|
|
605370
|
-
|
|
605371
|
-
|
|
605372
|
-
|
|
604766
|
+
const historyDir = join122(repoRoot, OMNIUS_DIR, "history");
|
|
604767
|
+
mkdirSync65(historyDir, { recursive: true });
|
|
604768
|
+
writeFileSync55(
|
|
604769
|
+
join122(historyDir, `${session.id}.json`),
|
|
605373
604770
|
JSON.stringify(session, null, 2),
|
|
605374
604771
|
"utf-8"
|
|
605375
604772
|
);
|
|
605376
604773
|
}
|
|
605377
604774
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
605378
|
-
const historyDir =
|
|
605379
|
-
if (!
|
|
604775
|
+
const historyDir = join122(repoRoot, OMNIUS_DIR, "history");
|
|
604776
|
+
if (!existsSync107(historyDir)) return [];
|
|
605380
604777
|
try {
|
|
605381
604778
|
const files = readdirSync37(historyDir).filter((f2) => f2.endsWith(".json") && f2 !== "pending-task.json").map((f2) => {
|
|
605382
|
-
const stat8 =
|
|
604779
|
+
const stat8 = statSync41(join122(historyDir, f2));
|
|
605383
604780
|
return { file: f2, mtime: stat8.mtimeMs };
|
|
605384
604781
|
}).sort((a2, b) => b.mtime - a2.mtime).slice(0, limit);
|
|
605385
604782
|
return files.map((f2) => {
|
|
605386
604783
|
try {
|
|
605387
|
-
return JSON.parse(
|
|
604784
|
+
return JSON.parse(readFileSync86(join122(historyDir, f2.file), "utf-8"));
|
|
605388
604785
|
} catch {
|
|
605389
604786
|
return null;
|
|
605390
604787
|
}
|
|
@@ -605396,21 +604793,21 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
605396
604793
|
}
|
|
605397
604794
|
}
|
|
605398
604795
|
function savePendingTask(repoRoot, task) {
|
|
605399
|
-
const historyDir =
|
|
605400
|
-
|
|
605401
|
-
|
|
605402
|
-
|
|
604796
|
+
const historyDir = join122(repoRoot, OMNIUS_DIR, "history");
|
|
604797
|
+
mkdirSync65(historyDir, { recursive: true });
|
|
604798
|
+
writeFileSync55(
|
|
604799
|
+
join122(historyDir, PENDING_TASK_FILE),
|
|
605403
604800
|
JSON.stringify(task, null, 2) + "\n",
|
|
605404
604801
|
"utf-8"
|
|
605405
604802
|
);
|
|
605406
604803
|
}
|
|
605407
604804
|
function loadPendingTask(repoRoot) {
|
|
605408
|
-
const filePath =
|
|
604805
|
+
const filePath = join122(repoRoot, OMNIUS_DIR, "history", PENDING_TASK_FILE);
|
|
605409
604806
|
try {
|
|
605410
|
-
if (!
|
|
605411
|
-
const data = JSON.parse(
|
|
604807
|
+
if (!existsSync107(filePath)) return null;
|
|
604808
|
+
const data = JSON.parse(readFileSync86(filePath, "utf-8"));
|
|
605412
604809
|
try {
|
|
605413
|
-
|
|
604810
|
+
unlinkSync21(filePath);
|
|
605414
604811
|
} catch {
|
|
605415
604812
|
}
|
|
605416
604813
|
return data;
|
|
@@ -605419,26 +604816,26 @@ function loadPendingTask(repoRoot) {
|
|
|
605419
604816
|
}
|
|
605420
604817
|
}
|
|
605421
604818
|
function writeTaskHandoff2(repoRoot, handoff) {
|
|
605422
|
-
const contextDir =
|
|
605423
|
-
|
|
605424
|
-
const filePath =
|
|
604819
|
+
const contextDir = join122(repoRoot, OMNIUS_DIR, "context");
|
|
604820
|
+
mkdirSync65(contextDir, { recursive: true });
|
|
604821
|
+
const filePath = join122(contextDir, HANDOFF_FILE);
|
|
605425
604822
|
const tempPath = filePath + ".tmp";
|
|
605426
|
-
|
|
604823
|
+
writeFileSync55(tempPath, JSON.stringify(handoff, null, 2) + "\n", "utf-8");
|
|
605427
604824
|
try {
|
|
605428
604825
|
renameSync8(tempPath, filePath);
|
|
605429
604826
|
} catch {
|
|
605430
|
-
|
|
604827
|
+
writeFileSync55(filePath, JSON.stringify(handoff, null, 2) + "\n", "utf-8");
|
|
605431
604828
|
try {
|
|
605432
|
-
|
|
604829
|
+
unlinkSync21(tempPath);
|
|
605433
604830
|
} catch {
|
|
605434
604831
|
}
|
|
605435
604832
|
}
|
|
605436
604833
|
}
|
|
605437
604834
|
function readTaskHandoff2(repoRoot) {
|
|
605438
|
-
const filePath =
|
|
604835
|
+
const filePath = join122(repoRoot, OMNIUS_DIR, "context", HANDOFF_FILE);
|
|
605439
604836
|
try {
|
|
605440
|
-
if (!
|
|
605441
|
-
const data = JSON.parse(
|
|
604837
|
+
if (!existsSync107(filePath)) return null;
|
|
604838
|
+
const data = JSON.parse(readFileSync86(filePath, "utf-8"));
|
|
605442
604839
|
const handoffTime = new Date(data.handoffAt).getTime();
|
|
605443
604840
|
const now2 = Date.now();
|
|
605444
604841
|
const ageMs = now2 - handoffTime;
|
|
@@ -605452,10 +604849,10 @@ function readTaskHandoff2(repoRoot) {
|
|
|
605452
604849
|
}
|
|
605453
604850
|
}
|
|
605454
604851
|
function clearTaskHandoff(repoRoot) {
|
|
605455
|
-
const filePath =
|
|
604852
|
+
const filePath = join122(repoRoot, OMNIUS_DIR, "context", HANDOFF_FILE);
|
|
605456
604853
|
try {
|
|
605457
|
-
if (
|
|
605458
|
-
|
|
604854
|
+
if (existsSync107(filePath)) {
|
|
604855
|
+
unlinkSync21(filePath);
|
|
605459
604856
|
}
|
|
605460
604857
|
} catch {
|
|
605461
604858
|
}
|
|
@@ -605518,24 +604915,24 @@ function acquireLock(lockPath) {
|
|
|
605518
604915
|
try {
|
|
605519
604916
|
const fd = openSync2(lockPath, "wx");
|
|
605520
604917
|
const lockData = JSON.stringify({ pid, acquiredAt: Date.now() });
|
|
605521
|
-
|
|
604918
|
+
writeFileSync55(fd, lockData);
|
|
605522
604919
|
closeSync2(fd);
|
|
605523
604920
|
return true;
|
|
605524
604921
|
} catch (err) {
|
|
605525
|
-
if (
|
|
604922
|
+
if (existsSync107(lockPath)) {
|
|
605526
604923
|
try {
|
|
605527
|
-
const lockContent =
|
|
604924
|
+
const lockContent = readFileSync86(lockPath, "utf-8");
|
|
605528
604925
|
const lock = JSON.parse(lockContent);
|
|
605529
604926
|
const lockAge = Date.now() - lock.acquiredAt;
|
|
605530
604927
|
if (lockAge > LOCK_TIMEOUT_MS) {
|
|
605531
604928
|
try {
|
|
605532
|
-
|
|
604929
|
+
unlinkSync21(lockPath);
|
|
605533
604930
|
} catch {
|
|
605534
604931
|
}
|
|
605535
604932
|
}
|
|
605536
604933
|
} catch {
|
|
605537
604934
|
try {
|
|
605538
|
-
|
|
604935
|
+
unlinkSync21(lockPath);
|
|
605539
604936
|
} catch {
|
|
605540
604937
|
}
|
|
605541
604938
|
}
|
|
@@ -605549,11 +604946,11 @@ function acquireLock(lockPath) {
|
|
|
605549
604946
|
}
|
|
605550
604947
|
function releaseLock(lockPath) {
|
|
605551
604948
|
try {
|
|
605552
|
-
if (
|
|
605553
|
-
const lockContent =
|
|
604949
|
+
if (existsSync107(lockPath)) {
|
|
604950
|
+
const lockContent = readFileSync86(lockPath, "utf-8");
|
|
605554
604951
|
const lock = JSON.parse(lockContent);
|
|
605555
604952
|
if (lock.pid === process.pid) {
|
|
605556
|
-
|
|
604953
|
+
unlinkSync21(lockPath);
|
|
605557
604954
|
}
|
|
605558
604955
|
}
|
|
605559
604956
|
} catch {
|
|
@@ -605639,29 +605036,29 @@ function mergeSessionContextEntry(previous, incoming) {
|
|
|
605639
605036
|
}
|
|
605640
605037
|
function pruneContextLedger(ledgerPath) {
|
|
605641
605038
|
try {
|
|
605642
|
-
if (!
|
|
605643
|
-
const st =
|
|
605039
|
+
if (!existsSync107(ledgerPath)) return;
|
|
605040
|
+
const st = statSync41(ledgerPath);
|
|
605644
605041
|
if (st.size <= MAX_CONTEXT_LEDGER_BYTES) return;
|
|
605645
|
-
const lines =
|
|
605042
|
+
const lines = readFileSync86(ledgerPath, "utf-8").split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
605646
605043
|
if (lines.length <= MAX_CONTEXT_LEDGER_LINES) return;
|
|
605647
605044
|
const kept = lines.slice(-MAX_CONTEXT_LEDGER_LINES);
|
|
605648
|
-
const archiveDir =
|
|
605649
|
-
|
|
605650
|
-
const archivePath =
|
|
605045
|
+
const archiveDir = join122(dirname38(ledgerPath), "archive");
|
|
605046
|
+
mkdirSync65(archiveDir, { recursive: true });
|
|
605047
|
+
const archivePath = join122(
|
|
605651
605048
|
archiveDir,
|
|
605652
605049
|
`session-context.events.${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.jsonl`
|
|
605653
605050
|
);
|
|
605654
|
-
|
|
605655
|
-
|
|
605051
|
+
writeFileSync55(archivePath, lines.slice(0, -MAX_CONTEXT_LEDGER_LINES).join("\n") + "\n", "utf-8");
|
|
605052
|
+
writeFileSync55(ledgerPath, kept.join("\n") + "\n", "utf-8");
|
|
605656
605053
|
} catch {
|
|
605657
605054
|
}
|
|
605658
605055
|
}
|
|
605659
605056
|
function saveSessionContext(repoRoot, entry) {
|
|
605660
|
-
const contextDir =
|
|
605661
|
-
|
|
605662
|
-
const filePath =
|
|
605663
|
-
const ledgerPath =
|
|
605664
|
-
const lockPath =
|
|
605057
|
+
const contextDir = join122(repoRoot, OMNIUS_DIR, "context");
|
|
605058
|
+
mkdirSync65(contextDir, { recursive: true });
|
|
605059
|
+
const filePath = join122(contextDir, CONTEXT_SAVE_FILE);
|
|
605060
|
+
const ledgerPath = join122(contextDir, CONTEXT_LEDGER_FILE);
|
|
605061
|
+
const lockPath = join122(contextDir, CONTEXT_SAVE_FILE + ".lock");
|
|
605665
605062
|
const locked = acquireLock(lockPath);
|
|
605666
605063
|
if (!locked) {
|
|
605667
605064
|
console.warn("[saveSessionContext] Could not acquire lock, proceeding without mutex");
|
|
@@ -605669,8 +605066,8 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
605669
605066
|
try {
|
|
605670
605067
|
let ctx3;
|
|
605671
605068
|
try {
|
|
605672
|
-
if (
|
|
605673
|
-
ctx3 = JSON.parse(
|
|
605069
|
+
if (existsSync107(filePath)) {
|
|
605070
|
+
ctx3 = JSON.parse(readFileSync86(filePath, "utf-8"));
|
|
605674
605071
|
} else {
|
|
605675
605072
|
ctx3 = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
605676
605073
|
}
|
|
@@ -605733,19 +605130,19 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
605733
605130
|
}
|
|
605734
605131
|
ctx3.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
605735
605132
|
const tempFilePath = filePath + ".tmp";
|
|
605736
|
-
|
|
605133
|
+
writeFileSync55(tempFilePath, JSON.stringify(ctx3, null, 2) + "\n", "utf-8");
|
|
605737
605134
|
try {
|
|
605738
605135
|
renameSync8(tempFilePath, filePath);
|
|
605739
605136
|
} catch {
|
|
605740
|
-
|
|
605137
|
+
writeFileSync55(filePath, JSON.stringify(ctx3, null, 2) + "\n", "utf-8");
|
|
605741
605138
|
try {
|
|
605742
|
-
|
|
605139
|
+
unlinkSync21(tempFilePath);
|
|
605743
605140
|
} catch {
|
|
605744
605141
|
}
|
|
605745
605142
|
}
|
|
605746
605143
|
try {
|
|
605747
|
-
|
|
605748
|
-
|
|
605144
|
+
writeFileSync55(
|
|
605145
|
+
join122(contextDir, "session-diary.md"),
|
|
605749
605146
|
renderSessionDiary(ctx3.entries.slice(-MAX_SESSION_DIARY_ENTRIES)),
|
|
605750
605147
|
"utf-8"
|
|
605751
605148
|
);
|
|
@@ -605829,10 +605226,10 @@ function renderSessionDiary(entries) {
|
|
|
605829
605226
|
return lines.join("\n");
|
|
605830
605227
|
}
|
|
605831
605228
|
function loadSessionContext(repoRoot) {
|
|
605832
|
-
const filePath =
|
|
605229
|
+
const filePath = join122(repoRoot, OMNIUS_DIR, "context", CONTEXT_SAVE_FILE);
|
|
605833
605230
|
try {
|
|
605834
|
-
if (!
|
|
605835
|
-
return JSON.parse(
|
|
605231
|
+
if (!existsSync107(filePath)) return null;
|
|
605232
|
+
return JSON.parse(readFileSync86(filePath, "utf-8"));
|
|
605836
605233
|
} catch {
|
|
605837
605234
|
return null;
|
|
605838
605235
|
}
|
|
@@ -605916,6 +605313,20 @@ function getLastTaskSummary(repoRoot) {
|
|
|
605916
605313
|
const clean5 = text2.replace(/^\[.*?\]\s*/, "").replace(/\s+/g, " ").trim();
|
|
605917
605314
|
return clean5.length > 40 ? clean5.slice(0, 37) + "..." : clean5;
|
|
605918
605315
|
}
|
|
605316
|
+
function updateSessionEntry(repoRoot, sessionId, patch) {
|
|
605317
|
+
const indexPath = join122(repoRoot, OMNIUS_DIR, SESSIONS_DIR, SESSIONS_INDEX);
|
|
605318
|
+
try {
|
|
605319
|
+
if (!existsSync107(indexPath)) return false;
|
|
605320
|
+
const index = JSON.parse(readFileSync86(indexPath, "utf-8"));
|
|
605321
|
+
const idx = index.findIndex((e2) => e2.id === sessionId);
|
|
605322
|
+
if (idx < 0) return false;
|
|
605323
|
+
index[idx] = { ...index[idx], ...patch };
|
|
605324
|
+
writeFileSync55(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
605325
|
+
return true;
|
|
605326
|
+
} catch {
|
|
605327
|
+
return false;
|
|
605328
|
+
}
|
|
605329
|
+
}
|
|
605919
605330
|
function cleanSessionHistoryDisplayLine(line) {
|
|
605920
605331
|
return String(line || "").replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "").replace(/^[>❯▹∙•*+\-\s]+/, "").replace(/^\[.*?\]\s*/, "").replace(/^(?:User|Assistant|You|Open Agent|Omnius)\s*:\s*/i, "").replace(/\s+/g, " ").trim();
|
|
605921
605332
|
}
|
|
@@ -605942,20 +605353,20 @@ function sanitizeSessionHistoryEntry(repoRoot, entry) {
|
|
|
605942
605353
|
};
|
|
605943
605354
|
}
|
|
605944
605355
|
function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
|
|
605945
|
-
const sessDir =
|
|
605946
|
-
|
|
605356
|
+
const sessDir = join122(repoRoot, OMNIUS_DIR, SESSIONS_DIR);
|
|
605357
|
+
mkdirSync65(sessDir, { recursive: true });
|
|
605947
605358
|
const stripped = contentLines.map(
|
|
605948
605359
|
(line) => typeof line === "string" ? line.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "") : ""
|
|
605949
605360
|
);
|
|
605950
605361
|
const autoName = meta.name || generateSessionName(stripped);
|
|
605951
605362
|
const autoDesc = meta.description || generateSessionDescription(stripped);
|
|
605952
|
-
const contentPath =
|
|
605953
|
-
|
|
605954
|
-
const indexPath =
|
|
605363
|
+
const contentPath = join122(sessDir, `${sessionId}.jsonl`);
|
|
605364
|
+
writeFileSync55(contentPath, stripped.join("\n"), "utf-8");
|
|
605365
|
+
const indexPath = join122(sessDir, SESSIONS_INDEX);
|
|
605955
605366
|
let index = [];
|
|
605956
605367
|
try {
|
|
605957
|
-
if (
|
|
605958
|
-
index = JSON.parse(
|
|
605368
|
+
if (existsSync107(indexPath)) {
|
|
605369
|
+
index = JSON.parse(readFileSync86(indexPath, "utf-8"));
|
|
605959
605370
|
}
|
|
605960
605371
|
} catch {
|
|
605961
605372
|
}
|
|
@@ -605977,41 +605388,41 @@ function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
|
|
|
605977
605388
|
if (index.length > 50) {
|
|
605978
605389
|
const removed = index.shift();
|
|
605979
605390
|
try {
|
|
605980
|
-
|
|
605391
|
+
unlinkSync21(join122(sessDir, `${removed.id}.jsonl`));
|
|
605981
605392
|
} catch {
|
|
605982
605393
|
}
|
|
605983
605394
|
}
|
|
605984
|
-
|
|
605395
|
+
writeFileSync55(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
605985
605396
|
}
|
|
605986
605397
|
function listSessions(repoRoot) {
|
|
605987
|
-
const indexPath =
|
|
605398
|
+
const indexPath = join122(repoRoot, OMNIUS_DIR, SESSIONS_DIR, SESSIONS_INDEX);
|
|
605988
605399
|
try {
|
|
605989
|
-
if (!
|
|
605990
|
-
const index = JSON.parse(
|
|
605400
|
+
if (!existsSync107(indexPath)) return [];
|
|
605401
|
+
const index = JSON.parse(readFileSync86(indexPath, "utf-8"));
|
|
605991
605402
|
return index.map((entry) => sanitizeSessionHistoryEntry(repoRoot, entry)).sort((a2, b) => b.updatedAt.localeCompare(a2.updatedAt));
|
|
605992
605403
|
} catch {
|
|
605993
605404
|
return [];
|
|
605994
605405
|
}
|
|
605995
605406
|
}
|
|
605996
605407
|
function loadSessionHistory(repoRoot, sessionId) {
|
|
605997
|
-
const contentPath =
|
|
605408
|
+
const contentPath = join122(repoRoot, OMNIUS_DIR, SESSIONS_DIR, `${sessionId}.jsonl`);
|
|
605998
605409
|
try {
|
|
605999
|
-
if (!
|
|
606000
|
-
return
|
|
605410
|
+
if (!existsSync107(contentPath)) return null;
|
|
605411
|
+
return readFileSync86(contentPath, "utf-8").split("\n");
|
|
606001
605412
|
} catch {
|
|
606002
605413
|
return null;
|
|
606003
605414
|
}
|
|
606004
605415
|
}
|
|
606005
605416
|
function deleteSession(repoRoot, sessionId) {
|
|
606006
|
-
const sessDir =
|
|
606007
|
-
const indexPath =
|
|
605417
|
+
const sessDir = join122(repoRoot, OMNIUS_DIR, SESSIONS_DIR);
|
|
605418
|
+
const indexPath = join122(sessDir, SESSIONS_INDEX);
|
|
606008
605419
|
try {
|
|
606009
|
-
const contentPath =
|
|
606010
|
-
if (
|
|
606011
|
-
if (
|
|
606012
|
-
let index = JSON.parse(
|
|
605420
|
+
const contentPath = join122(sessDir, `${sessionId}.jsonl`);
|
|
605421
|
+
if (existsSync107(contentPath)) unlinkSync21(contentPath);
|
|
605422
|
+
if (existsSync107(indexPath)) {
|
|
605423
|
+
let index = JSON.parse(readFileSync86(indexPath, "utf-8"));
|
|
606013
605424
|
index = index.filter((s2) => s2.id !== sessionId);
|
|
606014
|
-
|
|
605425
|
+
writeFileSync55(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
606015
605426
|
}
|
|
606016
605427
|
return true;
|
|
606017
605428
|
} catch {
|
|
@@ -606061,12 +605472,12 @@ function detectManifests(repoRoot) {
|
|
|
606061
605472
|
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
606062
605473
|
];
|
|
606063
605474
|
for (const check of checks) {
|
|
606064
|
-
const filePath =
|
|
606065
|
-
if (
|
|
605475
|
+
const filePath = join122(repoRoot, check.file);
|
|
605476
|
+
if (existsSync107(filePath)) {
|
|
606066
605477
|
let name10;
|
|
606067
605478
|
if (check.nameField) {
|
|
606068
605479
|
try {
|
|
606069
|
-
const data = JSON.parse(
|
|
605480
|
+
const data = JSON.parse(readFileSync86(filePath, "utf-8"));
|
|
606070
605481
|
name10 = data[check.nameField];
|
|
606071
605482
|
} catch {
|
|
606072
605483
|
}
|
|
@@ -606095,7 +605506,7 @@ function findKeyFiles(repoRoot) {
|
|
|
606095
605506
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
606096
605507
|
];
|
|
606097
605508
|
for (const check of checks) {
|
|
606098
|
-
if (
|
|
605509
|
+
if (existsSync107(join122(repoRoot, check.pattern))) {
|
|
606099
605510
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
606100
605511
|
}
|
|
606101
605512
|
}
|
|
@@ -606104,7 +605515,7 @@ function findKeyFiles(repoRoot) {
|
|
|
606104
605515
|
function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
606105
605516
|
if (depth > maxDepth) return "";
|
|
606106
605517
|
let result = "";
|
|
606107
|
-
const isHomeRoot = depth === 0 && root ===
|
|
605518
|
+
const isHomeRoot = depth === 0 && root === homedir37();
|
|
606108
605519
|
try {
|
|
606109
605520
|
const entries = readdirSync37(root, { withFileTypes: true }).filter((e2) => !e2.name.startsWith(".") || e2.name === ".github").filter((e2) => !SKIP_DIRS3.has(e2.name)).filter((e2) => !(isHomeRoot && HOME_SKIP_DIRS.has(e2.name))).sort((a2, b) => {
|
|
606110
605521
|
if (a2.isDirectory() && !b.isDirectory()) return -1;
|
|
@@ -606119,12 +605530,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
606119
605530
|
if (entry.isDirectory()) {
|
|
606120
605531
|
let fileCount = 0;
|
|
606121
605532
|
try {
|
|
606122
|
-
fileCount = readdirSync37(
|
|
605533
|
+
fileCount = readdirSync37(join122(root, entry.name)).filter((f2) => !f2.startsWith(".")).length;
|
|
606123
605534
|
} catch {
|
|
606124
605535
|
}
|
|
606125
605536
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
606126
605537
|
`;
|
|
606127
|
-
result += buildDirTree(
|
|
605538
|
+
result += buildDirTree(join122(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
606128
605539
|
} else if (depth < maxDepth) {
|
|
606129
605540
|
result += `${prefix}${connector}${entry.name}
|
|
606130
605541
|
`;
|
|
@@ -606136,17 +605547,17 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
606136
605547
|
}
|
|
606137
605548
|
function loadUsageFile(filePath) {
|
|
606138
605549
|
try {
|
|
606139
|
-
if (
|
|
606140
|
-
return JSON.parse(
|
|
605550
|
+
if (existsSync107(filePath)) {
|
|
605551
|
+
return JSON.parse(readFileSync86(filePath, "utf-8"));
|
|
606141
605552
|
}
|
|
606142
605553
|
} catch {
|
|
606143
605554
|
}
|
|
606144
605555
|
return { records: [] };
|
|
606145
605556
|
}
|
|
606146
605557
|
function saveUsageFile(filePath, data) {
|
|
606147
|
-
const dir =
|
|
606148
|
-
|
|
606149
|
-
|
|
605558
|
+
const dir = join122(filePath, "..");
|
|
605559
|
+
mkdirSync65(dir, { recursive: true });
|
|
605560
|
+
writeFileSync55(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
606150
605561
|
}
|
|
606151
605562
|
function recordUsage(kind, value2, opts) {
|
|
606152
605563
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -606173,15 +605584,15 @@ function recordUsage(kind, value2, opts) {
|
|
|
606173
605584
|
}
|
|
606174
605585
|
saveUsageFile(filePath, data);
|
|
606175
605586
|
};
|
|
606176
|
-
update2(
|
|
605587
|
+
update2(join122(homedir37(), ".omnius", USAGE_HISTORY_FILE));
|
|
606177
605588
|
if (opts?.repoRoot) {
|
|
606178
|
-
update2(
|
|
605589
|
+
update2(join122(opts.repoRoot, OMNIUS_DIR, USAGE_HISTORY_FILE));
|
|
606179
605590
|
}
|
|
606180
605591
|
}
|
|
606181
605592
|
function loadUsageHistory(kind, repoRoot) {
|
|
606182
|
-
const globalPath =
|
|
605593
|
+
const globalPath = join122(homedir37(), ".omnius", USAGE_HISTORY_FILE);
|
|
606183
605594
|
const globalData = loadUsageFile(globalPath);
|
|
606184
|
-
const localData = repoRoot ? loadUsageFile(
|
|
605595
|
+
const localData = repoRoot ? loadUsageFile(join122(repoRoot, OMNIUS_DIR, USAGE_HISTORY_FILE)) : { records: [] };
|
|
606185
605596
|
const map2 = /* @__PURE__ */ new Map();
|
|
606186
605597
|
for (const r2 of globalData.records) {
|
|
606187
605598
|
if (r2.kind !== kind) continue;
|
|
@@ -606210,9 +605621,9 @@ function deleteUsageRecord(kind, value2, repoRoot) {
|
|
|
606210
605621
|
saveUsageFile(filePath, data);
|
|
606211
605622
|
}
|
|
606212
605623
|
};
|
|
606213
|
-
remove(
|
|
605624
|
+
remove(join122(homedir37(), ".omnius", USAGE_HISTORY_FILE));
|
|
606214
605625
|
if (repoRoot) {
|
|
606215
|
-
remove(
|
|
605626
|
+
remove(join122(repoRoot, OMNIUS_DIR, USAGE_HISTORY_FILE));
|
|
606216
605627
|
}
|
|
606217
605628
|
}
|
|
606218
605629
|
var OMNIUS_DIR, LEGACY_DIRS, SUBDIRS, gitignoreWatchers, CONTEXT_FILES, PENDING_TASK_FILE, HANDOFF_FILE, CONTEXT_SAVE_FILE, CONTEXT_LEDGER_FILE, MAX_CONTEXT_ENTRIES, MAX_SESSION_DIARY_ENTRIES, MAX_SESSION_DIARY_DETAILED_ENTRIES, MAX_CONTEXT_LEDGER_LINES, MAX_CONTEXT_LEDGER_BYTES, SAME_TASK_REPLACE_WINDOW_MS, LOCK_TIMEOUT_MS, LOCK_RETRY_MS, LOCK_RETRY_MAX, SESSIONS_DIR, SESSIONS_INDEX, SKIP_DIRS3, HOME_SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
|
|
@@ -606298,6 +605709,757 @@ var init_omnius_directory = __esm({
|
|
|
606298
605709
|
}
|
|
606299
605710
|
});
|
|
606300
605711
|
|
|
605712
|
+
// packages/cli/src/api/session-summary.ts
|
|
605713
|
+
function isNoiseLine(line) {
|
|
605714
|
+
const t2 = line.trim();
|
|
605715
|
+
if (t2.length < 3) return true;
|
|
605716
|
+
const core = t2.replace(/^[∙•·›>\-=_*#|/\\.\s]+/, "").trim();
|
|
605717
|
+
if (core.length < 3) return true;
|
|
605718
|
+
return /^(nexus|rest api|voice feedback|clone ref|connecting to|connected|http:\/\/|https:\/\/|last task:|\(manual save\)|good morning|good evening|good afternoon|cannot reach|could not|unable to|warning:|error:|loaded tui session|session restored|restored previous)/i.test(core);
|
|
605719
|
+
}
|
|
605720
|
+
function firstMeaningfulLine(transcript) {
|
|
605721
|
+
for (const raw of transcript.split("\n")) {
|
|
605722
|
+
const line = raw.replace(ANSI_RE, "").trim();
|
|
605723
|
+
if (line && !isNoiseLine(line)) return line;
|
|
605724
|
+
}
|
|
605725
|
+
for (const raw of transcript.split("\n")) {
|
|
605726
|
+
const line = raw.replace(ANSI_RE, "").trim();
|
|
605727
|
+
if (line) return line;
|
|
605728
|
+
}
|
|
605729
|
+
return "";
|
|
605730
|
+
}
|
|
605731
|
+
function clamp7(value2, max) {
|
|
605732
|
+
const v = value2.replace(/\s+/g, " ").trim();
|
|
605733
|
+
return v.length > max ? v.slice(0, max - 1).trimEnd() + "…" : v;
|
|
605734
|
+
}
|
|
605735
|
+
function deterministicSummary(transcript) {
|
|
605736
|
+
const first2 = firstMeaningfulLine(transcript);
|
|
605737
|
+
if (!first2) return { title: "Untitled session", summary: "Empty session." };
|
|
605738
|
+
const title = clamp7(first2.replace(/^[>›$#\s]+/, ""), TITLE_MAX);
|
|
605739
|
+
return { title: title || "Untitled session", summary: clamp7(first2, SUMMARY_MAX) };
|
|
605740
|
+
}
|
|
605741
|
+
function parseSummaryReply(content) {
|
|
605742
|
+
if (!content) return null;
|
|
605743
|
+
const match = content.match(/\{[\s\S]*\}/);
|
|
605744
|
+
if (!match) return null;
|
|
605745
|
+
try {
|
|
605746
|
+
const obj = JSON.parse(match[0]);
|
|
605747
|
+
const title = typeof obj.title === "string" ? obj.title.trim() : "";
|
|
605748
|
+
const summary = typeof obj.summary === "string" ? obj.summary.trim() : "";
|
|
605749
|
+
if (!title && !summary) return null;
|
|
605750
|
+
return { title, summary };
|
|
605751
|
+
} catch {
|
|
605752
|
+
return null;
|
|
605753
|
+
}
|
|
605754
|
+
}
|
|
605755
|
+
async function generateSessionSummary(args) {
|
|
605756
|
+
const fallback = deterministicSummary(args.transcript);
|
|
605757
|
+
const transcript = (args.transcript || "").replace(ANSI_RE, "").trim();
|
|
605758
|
+
if (!transcript || !args.config.model || !args.config.backendUrl) return fallback;
|
|
605759
|
+
try {
|
|
605760
|
+
const url = normalizeBaseUrl(args.config.backendUrl) + "/v1/chat/completions";
|
|
605761
|
+
const headers = { "Content-Type": "application/json" };
|
|
605762
|
+
if (args.config.apiKey) headers["Authorization"] = `Bearer ${args.config.apiKey}`;
|
|
605763
|
+
const body = {
|
|
605764
|
+
model: args.config.model,
|
|
605765
|
+
messages: [
|
|
605766
|
+
{
|
|
605767
|
+
role: "system",
|
|
605768
|
+
content: 'You name and summarize AI coding/agent terminal sessions. Reply with ONLY compact JSON and nothing else: {"title":"<3-6 word title>","summary":"<one concise sentence>"}. No markdown, no code fences, no preamble.'
|
|
605769
|
+
},
|
|
605770
|
+
{
|
|
605771
|
+
role: "user",
|
|
605772
|
+
content: "Summarize this session transcript (may include tool calls, sub-agent activity, and logs):\n\n" + transcript.slice(0, TRANSCRIPT_CHARS)
|
|
605773
|
+
}
|
|
605774
|
+
],
|
|
605775
|
+
temperature: 0.2,
|
|
605776
|
+
max_tokens: 160,
|
|
605777
|
+
stream: false
|
|
605778
|
+
};
|
|
605779
|
+
const resp = await fetch(url, {
|
|
605780
|
+
method: "POST",
|
|
605781
|
+
headers,
|
|
605782
|
+
body: JSON.stringify(body),
|
|
605783
|
+
signal: AbortSignal.timeout(args.timeoutMs ?? 25e3)
|
|
605784
|
+
});
|
|
605785
|
+
if (!resp.ok) return fallback;
|
|
605786
|
+
const data = await resp.json();
|
|
605787
|
+
const content = data?.choices?.[0]?.message?.content ?? "";
|
|
605788
|
+
const parsed = parseSummaryReply(content);
|
|
605789
|
+
if (!parsed) return fallback;
|
|
605790
|
+
return {
|
|
605791
|
+
title: clamp7(parsed.title, TITLE_MAX) || fallback.title,
|
|
605792
|
+
summary: clamp7(parsed.summary, SUMMARY_MAX) || fallback.summary
|
|
605793
|
+
};
|
|
605794
|
+
} catch {
|
|
605795
|
+
return fallback;
|
|
605796
|
+
}
|
|
605797
|
+
}
|
|
605798
|
+
async function ensureSessionSummary(args) {
|
|
605799
|
+
const entry = listSessions(args.repoRoot).find(
|
|
605800
|
+
(e2) => e2.id === args.sessionId
|
|
605801
|
+
);
|
|
605802
|
+
if (entry?.aiTitle && entry.aiSummary && !args.force) {
|
|
605803
|
+
return { title: entry.aiTitle, summary: entry.aiSummary };
|
|
605804
|
+
}
|
|
605805
|
+
const lines = loadSessionHistory(args.repoRoot, args.sessionId);
|
|
605806
|
+
const transcript = (lines ?? []).join("\n").trim();
|
|
605807
|
+
if (!transcript) return deterministicSummary("");
|
|
605808
|
+
const key = `${args.repoRoot}::${args.sessionId}`;
|
|
605809
|
+
if (_inflightSummaries.has(key) && !args.force) {
|
|
605810
|
+
return deterministicSummary(transcript);
|
|
605811
|
+
}
|
|
605812
|
+
_inflightSummaries.add(key);
|
|
605813
|
+
try {
|
|
605814
|
+
const result = await generateSessionSummary({
|
|
605815
|
+
transcript,
|
|
605816
|
+
config: args.config,
|
|
605817
|
+
timeoutMs: args.timeoutMs
|
|
605818
|
+
});
|
|
605819
|
+
updateSessionEntry(args.repoRoot, args.sessionId, {
|
|
605820
|
+
aiTitle: result.title,
|
|
605821
|
+
aiSummary: result.summary
|
|
605822
|
+
});
|
|
605823
|
+
return result;
|
|
605824
|
+
} finally {
|
|
605825
|
+
_inflightSummaries.delete(key);
|
|
605826
|
+
}
|
|
605827
|
+
}
|
|
605828
|
+
function sessionDisplayTitle(entry) {
|
|
605829
|
+
if (entry.aiTitle && entry.aiTitle.trim()) return entry.aiTitle.trim();
|
|
605830
|
+
return deterministicSummary(entry.name || "").title;
|
|
605831
|
+
}
|
|
605832
|
+
var TITLE_MAX, SUMMARY_MAX, TRANSCRIPT_CHARS, ANSI_RE, _inflightSummaries;
|
|
605833
|
+
var init_session_summary = __esm({
|
|
605834
|
+
"packages/cli/src/api/session-summary.ts"() {
|
|
605835
|
+
"use strict";
|
|
605836
|
+
init_dist6();
|
|
605837
|
+
init_omnius_directory();
|
|
605838
|
+
TITLE_MAX = 56;
|
|
605839
|
+
SUMMARY_MAX = 160;
|
|
605840
|
+
TRANSCRIPT_CHARS = 6e3;
|
|
605841
|
+
ANSI_RE = /\x1B\[[0-9;]*m|\x1B\][^\x07]*(?:\x07|\x1B\\)/g;
|
|
605842
|
+
_inflightSummaries = /* @__PURE__ */ new Set();
|
|
605843
|
+
}
|
|
605844
|
+
});
|
|
605845
|
+
|
|
605846
|
+
// packages/cli/src/tui/cad-model-viewer.ts
|
|
605847
|
+
import { createServer as createServer7 } from "node:http";
|
|
605848
|
+
import { existsSync as existsSync108, readFileSync as readFileSync87, statSync as statSync42 } from "node:fs";
|
|
605849
|
+
import { basename as basename23, extname as extname16, resolve as resolve53 } from "node:path";
|
|
605850
|
+
function getCurrentCadModelViewer() {
|
|
605851
|
+
return currentViewer;
|
|
605852
|
+
}
|
|
605853
|
+
async function startCadModelViewer(filePath) {
|
|
605854
|
+
const resolved = filePath ? resolve53(filePath) : void 0;
|
|
605855
|
+
if (resolved && (!existsSync108(resolved) || !statSync42(resolved).isFile())) {
|
|
605856
|
+
throw new Error(`3D model file not found: ${resolved}`);
|
|
605857
|
+
}
|
|
605858
|
+
if (currentViewer) {
|
|
605859
|
+
await currentViewer.close().catch(() => {
|
|
605860
|
+
});
|
|
605861
|
+
currentViewer = null;
|
|
605862
|
+
}
|
|
605863
|
+
const server2 = createServer7((req3, res) => handleViewerRequest(req3, res, resolved));
|
|
605864
|
+
const port = await listenOnEphemeralPort(server2);
|
|
605865
|
+
const session = {
|
|
605866
|
+
url: `http://127.0.0.1:${port}/`,
|
|
605867
|
+
port,
|
|
605868
|
+
filePath: resolved,
|
|
605869
|
+
close: () => new Promise((resolveClose) => server2.close(() => resolveClose()))
|
|
605870
|
+
};
|
|
605871
|
+
currentViewer = session;
|
|
605872
|
+
server2.on("close", () => {
|
|
605873
|
+
if (currentViewer === session) currentViewer = null;
|
|
605874
|
+
});
|
|
605875
|
+
return session;
|
|
605876
|
+
}
|
|
605877
|
+
function listenOnEphemeralPort(server2) {
|
|
605878
|
+
return new Promise((resolveListen, reject) => {
|
|
605879
|
+
server2.once("error", reject);
|
|
605880
|
+
server2.listen(0, "127.0.0.1", () => {
|
|
605881
|
+
server2.off("error", reject);
|
|
605882
|
+
const addr = server2.address();
|
|
605883
|
+
if (!addr || typeof addr === "string") {
|
|
605884
|
+
reject(new Error("viewer server did not bind to a TCP port"));
|
|
605885
|
+
return;
|
|
605886
|
+
}
|
|
605887
|
+
resolveListen(addr.port);
|
|
605888
|
+
});
|
|
605889
|
+
});
|
|
605890
|
+
}
|
|
605891
|
+
function handleViewerRequest(req3, res, filePath) {
|
|
605892
|
+
const url = new URL(req3.url || "/", "http://127.0.0.1");
|
|
605893
|
+
if (url.pathname === "/health") {
|
|
605894
|
+
sendJson(res, 200, { ok: true, file: filePath ?? null });
|
|
605895
|
+
return;
|
|
605896
|
+
}
|
|
605897
|
+
if (url.pathname === "/asset") {
|
|
605898
|
+
if (!filePath) {
|
|
605899
|
+
sendText(res, 404, "No model file attached to this viewer.");
|
|
605900
|
+
return;
|
|
605901
|
+
}
|
|
605902
|
+
try {
|
|
605903
|
+
res.writeHead(200, {
|
|
605904
|
+
"Content-Type": contentTypeFor(filePath),
|
|
605905
|
+
"Content-Disposition": `inline; filename="${basename23(filePath).replace(/"/g, "")}"`,
|
|
605906
|
+
"Cache-Control": "no-store"
|
|
605907
|
+
});
|
|
605908
|
+
res.end(readFileSync87(filePath));
|
|
605909
|
+
} catch (err) {
|
|
605910
|
+
sendText(res, 500, err instanceof Error ? err.message : String(err));
|
|
605911
|
+
}
|
|
605912
|
+
return;
|
|
605913
|
+
}
|
|
605914
|
+
if (url.pathname !== "/") {
|
|
605915
|
+
sendText(res, 404, "Not found");
|
|
605916
|
+
return;
|
|
605917
|
+
}
|
|
605918
|
+
sendHtml(res, viewerHtml(filePath));
|
|
605919
|
+
}
|
|
605920
|
+
function contentTypeFor(path12) {
|
|
605921
|
+
const ext = extname16(path12).toLowerCase();
|
|
605922
|
+
if (ext === ".glb") return "model/gltf-binary";
|
|
605923
|
+
if (ext === ".gltf") return "model/gltf+json";
|
|
605924
|
+
if (ext === ".obj") return "text/plain; charset=utf-8";
|
|
605925
|
+
if (ext === ".stl") return "model/stl";
|
|
605926
|
+
if (ext === ".ply") return "application/octet-stream";
|
|
605927
|
+
return "application/octet-stream";
|
|
605928
|
+
}
|
|
605929
|
+
function sendJson(res, status, value2) {
|
|
605930
|
+
res.writeHead(status, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-store" });
|
|
605931
|
+
res.end(JSON.stringify(value2));
|
|
605932
|
+
}
|
|
605933
|
+
function sendText(res, status, text2) {
|
|
605934
|
+
res.writeHead(status, { "Content-Type": "text/plain; charset=utf-8", "Cache-Control": "no-store" });
|
|
605935
|
+
res.end(text2);
|
|
605936
|
+
}
|
|
605937
|
+
function sendHtml(res, html) {
|
|
605938
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" });
|
|
605939
|
+
res.end(html);
|
|
605940
|
+
}
|
|
605941
|
+
function viewerHtml(filePath) {
|
|
605942
|
+
const fileName = filePath ? basename23(filePath) : "";
|
|
605943
|
+
const ext = filePath ? extname16(filePath).toLowerCase().replace(/^\./, "") : "";
|
|
605944
|
+
return `<!doctype html>
|
|
605945
|
+
<html lang="en">
|
|
605946
|
+
<head>
|
|
605947
|
+
<meta charset="utf-8">
|
|
605948
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
605949
|
+
<title>Omnius CAD/3D Viewer</title>
|
|
605950
|
+
<style>
|
|
605951
|
+
:root { color-scheme: dark; --bg:#101214; --panel:#181b1f; --line:#2a3037; --fg:#e7edf3; --muted:#9aa7b5; --accent:#5ec6a8; }
|
|
605952
|
+
* { box-sizing: border-box; }
|
|
605953
|
+
body { margin:0; min-height:100vh; background:var(--bg); color:var(--fg); font:14px/1.4 ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; display:grid; grid-template-columns:minmax(280px,360px) 1fr; }
|
|
605954
|
+
aside { border-right:1px solid var(--line); background:var(--panel); padding:14px; display:flex; flex-direction:column; gap:12px; min-height:100vh; }
|
|
605955
|
+
main { position:relative; min-height:100vh; overflow:hidden; }
|
|
605956
|
+
h1 { margin:0; font-size:16px; font-weight:650; }
|
|
605957
|
+
.meta { color:var(--muted); font-size:12px; word-break:break-word; }
|
|
605958
|
+
textarea { width:100%; min-height:280px; resize:vertical; border:1px solid var(--line); border-radius:6px; background:#0c0e10; color:var(--fg); padding:10px; font:12px/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; }
|
|
605959
|
+
button { border:1px solid var(--line); border-radius:6px; background:#20262d; color:var(--fg); padding:8px 10px; cursor:pointer; }
|
|
605960
|
+
button:hover { border-color:var(--accent); }
|
|
605961
|
+
#status { color:var(--muted); min-height:20px; font-size:12px; }
|
|
605962
|
+
canvas { display:block; width:100%; height:100%; }
|
|
605963
|
+
.row { display:flex; gap:8px; flex-wrap:wrap; }
|
|
605964
|
+
@media (max-width: 760px) { body { grid-template-columns:1fr; grid-template-rows:auto 60vh; } aside { min-height:auto; border-right:0; border-bottom:1px solid var(--line); } }
|
|
605965
|
+
</style>
|
|
605966
|
+
</head>
|
|
605967
|
+
<body>
|
|
605968
|
+
<aside>
|
|
605969
|
+
<div>
|
|
605970
|
+
<h1>Omnius CAD/3D Viewer</h1>
|
|
605971
|
+
<div class="meta">${escapeHtml(fileName ? `Viewing ${fileName}` : "No file attached. Rendering Compact IR sample.")}</div>
|
|
605972
|
+
</div>
|
|
605973
|
+
<textarea id="ir">C 50 30 5
|
|
605974
|
+
Y 3 8
|
|
605975
|
+
T 1 -18 -10 2.5
|
|
605976
|
+
Y 3 8
|
|
605977
|
+
T 3 18 -10 2.5
|
|
605978
|
+
Y 3 8
|
|
605979
|
+
T 5 -18 10 2.5
|
|
605980
|
+
Y 3 8
|
|
605981
|
+
T 7 18 10 2.5</textarea>
|
|
605982
|
+
<div class="row">
|
|
605983
|
+
<button id="render-ir">Render Compact IR</button>
|
|
605984
|
+
<button id="reset-camera">Reset Camera</button>
|
|
605985
|
+
</div>
|
|
605986
|
+
<div id="status"></div>
|
|
605987
|
+
</aside>
|
|
605988
|
+
<main id="viewport"></main>
|
|
605989
|
+
<script type="module">
|
|
605990
|
+
import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.164.1/build/three.module.js';
|
|
605991
|
+
import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/controls/OrbitControls.js';
|
|
605992
|
+
import { GLTFLoader } from 'https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/loaders/GLTFLoader.js';
|
|
605993
|
+
import { STLLoader } from 'https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/loaders/STLLoader.js';
|
|
605994
|
+
import { OBJLoader } from 'https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/loaders/OBJLoader.js';
|
|
605995
|
+
import { PLYLoader } from 'https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/loaders/PLYLoader.js';
|
|
605996
|
+
|
|
605997
|
+
const assetUrl = ${JSON.stringify(filePath ? "/asset" : "")};
|
|
605998
|
+
const assetExt = ${JSON.stringify(ext)};
|
|
605999
|
+
const viewport = document.getElementById('viewport');
|
|
606000
|
+
const status = document.getElementById('status');
|
|
606001
|
+
const scene = new THREE.Scene();
|
|
606002
|
+
scene.background = new THREE.Color(0x101214);
|
|
606003
|
+
const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 5000);
|
|
606004
|
+
const renderer = new THREE.WebGLRenderer({ antialias:true });
|
|
606005
|
+
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
|
|
606006
|
+
viewport.appendChild(renderer.domElement);
|
|
606007
|
+
const controls = new OrbitControls(camera, renderer.domElement);
|
|
606008
|
+
controls.enableDamping = true;
|
|
606009
|
+
scene.add(new THREE.HemisphereLight(0xffffff, 0x223344, 1.7));
|
|
606010
|
+
const key = new THREE.DirectionalLight(0xffffff, 2.2);
|
|
606011
|
+
key.position.set(120, 160, 100);
|
|
606012
|
+
scene.add(key);
|
|
606013
|
+
const grid = new THREE.GridHelper(160, 32, 0x31404a, 0x253039);
|
|
606014
|
+
scene.add(grid);
|
|
606015
|
+
let objectRoot = new THREE.Group();
|
|
606016
|
+
scene.add(objectRoot);
|
|
606017
|
+
|
|
606018
|
+
function setStatus(text) { status.textContent = text || ''; }
|
|
606019
|
+
function clearObject() {
|
|
606020
|
+
scene.remove(objectRoot);
|
|
606021
|
+
objectRoot.traverse((o) => {
|
|
606022
|
+
if (o.geometry) o.geometry.dispose?.();
|
|
606023
|
+
if (o.material) {
|
|
606024
|
+
if (Array.isArray(o.material)) o.material.forEach((m) => m.dispose?.());
|
|
606025
|
+
else o.material.dispose?.();
|
|
606026
|
+
}
|
|
606027
|
+
});
|
|
606028
|
+
objectRoot = new THREE.Group();
|
|
606029
|
+
scene.add(objectRoot);
|
|
606030
|
+
}
|
|
606031
|
+
function frameObject() {
|
|
606032
|
+
const box = new THREE.Box3().setFromObject(objectRoot);
|
|
606033
|
+
if (box.isEmpty()) {
|
|
606034
|
+
camera.position.set(70, 70, 70);
|
|
606035
|
+
controls.target.set(0, 0, 0);
|
|
606036
|
+
return;
|
|
606037
|
+
}
|
|
606038
|
+
const size = box.getSize(new THREE.Vector3());
|
|
606039
|
+
const center = box.getCenter(new THREE.Vector3());
|
|
606040
|
+
const max = Math.max(size.x, size.y, size.z, 1);
|
|
606041
|
+
camera.position.copy(center).add(new THREE.Vector3(max * 1.35, max * 1.05, max * 1.35));
|
|
606042
|
+
controls.target.copy(center);
|
|
606043
|
+
camera.near = Math.max(0.01, max / 1000);
|
|
606044
|
+
camera.far = Math.max(1000, max * 20);
|
|
606045
|
+
camera.updateProjectionMatrix();
|
|
606046
|
+
controls.update();
|
|
606047
|
+
}
|
|
606048
|
+
function makeMaterial(index) {
|
|
606049
|
+
const colors = [0x5ec6a8, 0xf0b35a, 0x87a8ff, 0xdc6f7e, 0xb6d96a];
|
|
606050
|
+
return new THREE.MeshStandardMaterial({ color: colors[index % colors.length], metalness:0.05, roughness:0.48 });
|
|
606051
|
+
}
|
|
606052
|
+
function renderCompactIr(text) {
|
|
606053
|
+
clearObject();
|
|
606054
|
+
const nodes = [];
|
|
606055
|
+
const lines = String(text || '').split(/\\r?\\n/).map((l) => l.trim()).filter((l) => l && !l.startsWith('#'));
|
|
606056
|
+
for (const line of lines) {
|
|
606057
|
+
const parts = line.split(/\\s+/);
|
|
606058
|
+
const op = parts[0].toUpperCase();
|
|
606059
|
+
const nums = parts.slice(1).map(Number);
|
|
606060
|
+
let mesh = null;
|
|
606061
|
+
if (op === 'C' && nums.length >= 3) {
|
|
606062
|
+
mesh = new THREE.Mesh(new THREE.BoxGeometry(nums[0], nums[1], nums[2]), makeMaterial(nodes.length));
|
|
606063
|
+
} else if (op === 'Y' && nums.length >= 2) {
|
|
606064
|
+
mesh = new THREE.Mesh(new THREE.CylinderGeometry(nums[0], nums[0], nums[1], 48), makeMaterial(nodes.length));
|
|
606065
|
+
mesh.rotation.x = Math.PI / 2;
|
|
606066
|
+
} else if (op === 'S' && nums.length >= 1) {
|
|
606067
|
+
mesh = new THREE.Mesh(new THREE.SphereGeometry(nums[0], 48, 24), makeMaterial(nodes.length));
|
|
606068
|
+
} else if (op === 'K' && nums.length >= 3) {
|
|
606069
|
+
mesh = new THREE.Mesh(new THREE.CylinderGeometry(nums[1], nums[0], nums[2], 48), makeMaterial(nodes.length));
|
|
606070
|
+
mesh.rotation.x = Math.PI / 2;
|
|
606071
|
+
} else if ((op === 'U' || op === 'D' || op === 'I') && nums.length >= 2) {
|
|
606072
|
+
const group = new THREE.Group();
|
|
606073
|
+
const a = nodes[nums[0]]?.clone();
|
|
606074
|
+
const b = nodes[nums[1]]?.clone();
|
|
606075
|
+
if (a) group.add(a);
|
|
606076
|
+
if (b) {
|
|
606077
|
+
if (op === 'D') b.traverse((o) => { if (o.material) o.material = new THREE.MeshStandardMaterial({ color:0xff5570, wireframe:true }); });
|
|
606078
|
+
group.add(b);
|
|
606079
|
+
}
|
|
606080
|
+
mesh = group;
|
|
606081
|
+
} else if ((op === 'T' || op === 'R' || op === 'X') && nums.length >= 4) {
|
|
606082
|
+
const target = nodes[nums[0]];
|
|
606083
|
+
if (target) {
|
|
606084
|
+
if (op === 'T') target.position.add(new THREE.Vector3(nums[1], nums[2], nums[3]));
|
|
606085
|
+
if (op === 'R') target.rotation.set(THREE.MathUtils.degToRad(nums[1]), THREE.MathUtils.degToRad(nums[2]), THREE.MathUtils.degToRad(nums[3]));
|
|
606086
|
+
if (op === 'X') target.scale.multiply(new THREE.Vector3(nums[1], nums[2], nums[3]));
|
|
606087
|
+
}
|
|
606088
|
+
nodes.push(target ? target.clone() : new THREE.Group());
|
|
606089
|
+
continue;
|
|
606090
|
+
} else if ((op === 'F' || op === 'CH' || op === 'SH') && nums.length >= 1) {
|
|
606091
|
+
const target = nodes[nums[0]];
|
|
606092
|
+
nodes.push(target ? target.clone() : new THREE.Group());
|
|
606093
|
+
continue;
|
|
606094
|
+
}
|
|
606095
|
+
if (mesh) {
|
|
606096
|
+
nodes.push(mesh);
|
|
606097
|
+
objectRoot.add(mesh);
|
|
606098
|
+
}
|
|
606099
|
+
}
|
|
606100
|
+
if (nodes.length === 0) setStatus('No renderable Compact IR primitives found.');
|
|
606101
|
+
else setStatus('Rendered ' + nodes.length + ' Compact IR node(s). Boolean difference is shown as wireframe preview.');
|
|
606102
|
+
frameObject();
|
|
606103
|
+
}
|
|
606104
|
+
async function loadAsset() {
|
|
606105
|
+
if (!assetUrl) {
|
|
606106
|
+
renderCompactIr(document.getElementById('ir').value);
|
|
606107
|
+
return;
|
|
606108
|
+
}
|
|
606109
|
+
setStatus('Loading attached model...');
|
|
606110
|
+
clearObject();
|
|
606111
|
+
const done = (obj) => {
|
|
606112
|
+
objectRoot.add(obj);
|
|
606113
|
+
setStatus('Loaded attached model.');
|
|
606114
|
+
frameObject();
|
|
606115
|
+
};
|
|
606116
|
+
if (assetExt === 'glb' || assetExt === 'gltf') {
|
|
606117
|
+
new GLTFLoader().load(assetUrl, (gltf) => done(gltf.scene), undefined, (e) => setStatus(e.message || String(e)));
|
|
606118
|
+
} else if (assetExt === 'stl') {
|
|
606119
|
+
new STLLoader().load(assetUrl, (geo) => done(new THREE.Mesh(geo, makeMaterial(0))), undefined, (e) => setStatus(e.message || String(e)));
|
|
606120
|
+
} else if (assetExt === 'obj') {
|
|
606121
|
+
new OBJLoader().load(assetUrl, done, undefined, (e) => setStatus(e.message || String(e)));
|
|
606122
|
+
} else if (assetExt === 'ply') {
|
|
606123
|
+
new PLYLoader().load(assetUrl, (geo) => done(new THREE.Mesh(geo, makeMaterial(0))), undefined, (e) => setStatus(e.message || String(e)));
|
|
606124
|
+
} else {
|
|
606125
|
+
setStatus('Unsupported file extension for browser preview. Use GLB, GLTF, OBJ, STL, or PLY.');
|
|
606126
|
+
renderCompactIr(document.getElementById('ir').value);
|
|
606127
|
+
}
|
|
606128
|
+
}
|
|
606129
|
+
function resize() {
|
|
606130
|
+
const rect = viewport.getBoundingClientRect();
|
|
606131
|
+
renderer.setSize(rect.width, rect.height, false);
|
|
606132
|
+
camera.aspect = Math.max(1, rect.width) / Math.max(1, rect.height);
|
|
606133
|
+
camera.updateProjectionMatrix();
|
|
606134
|
+
}
|
|
606135
|
+
window.addEventListener('resize', resize);
|
|
606136
|
+
document.getElementById('render-ir').addEventListener('click', () => renderCompactIr(document.getElementById('ir').value));
|
|
606137
|
+
document.getElementById('reset-camera').addEventListener('click', frameObject);
|
|
606138
|
+
renderer.setAnimationLoop(() => { controls.update(); renderer.render(scene, camera); });
|
|
606139
|
+
resize();
|
|
606140
|
+
loadAsset();
|
|
606141
|
+
</script>
|
|
606142
|
+
</body>
|
|
606143
|
+
</html>`;
|
|
606144
|
+
}
|
|
606145
|
+
function escapeHtml(value2) {
|
|
606146
|
+
return value2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
606147
|
+
}
|
|
606148
|
+
var currentViewer;
|
|
606149
|
+
var init_cad_model_viewer = __esm({
|
|
606150
|
+
"packages/cli/src/tui/cad-model-viewer.ts"() {
|
|
606151
|
+
"use strict";
|
|
606152
|
+
currentViewer = null;
|
|
606153
|
+
}
|
|
606154
|
+
});
|
|
606155
|
+
|
|
606156
|
+
// packages/cli/src/tui/hf-token-prompt.ts
|
|
606157
|
+
import * as fs9 from "node:fs";
|
|
606158
|
+
import * as os8 from "node:os";
|
|
606159
|
+
import * as path10 from "node:path";
|
|
606160
|
+
function loadHfToken() {
|
|
606161
|
+
const fromEnv = process.env["HF_TOKEN"]?.trim() || process.env["HUGGING_FACE_HUB_TOKEN"]?.trim() || "";
|
|
606162
|
+
if (fromEnv) return fromEnv;
|
|
606163
|
+
try {
|
|
606164
|
+
if (fs9.existsSync(TOKEN_FILE)) {
|
|
606165
|
+
const fromFile = fs9.readFileSync(TOKEN_FILE, "utf8").trim();
|
|
606166
|
+
if (fromFile) {
|
|
606167
|
+
process.env["HF_TOKEN"] = fromFile;
|
|
606168
|
+
return fromFile;
|
|
606169
|
+
}
|
|
606170
|
+
}
|
|
606171
|
+
} catch {
|
|
606172
|
+
}
|
|
606173
|
+
return null;
|
|
606174
|
+
}
|
|
606175
|
+
function saveHfToken(token) {
|
|
606176
|
+
const trimmed = token.trim();
|
|
606177
|
+
if (!trimmed) throw new Error("HF token cannot be empty");
|
|
606178
|
+
fs9.mkdirSync(TOKEN_DIR, { recursive: true, mode: 448 });
|
|
606179
|
+
fs9.writeFileSync(TOKEN_FILE, trimmed + "\n", { mode: 384 });
|
|
606180
|
+
try {
|
|
606181
|
+
fs9.chmodSync(TOKEN_FILE, 384);
|
|
606182
|
+
} catch {
|
|
606183
|
+
}
|
|
606184
|
+
process.env["HF_TOKEN"] = trimmed;
|
|
606185
|
+
}
|
|
606186
|
+
function clearHfToken() {
|
|
606187
|
+
try {
|
|
606188
|
+
if (fs9.existsSync(TOKEN_FILE)) fs9.unlinkSync(TOKEN_FILE);
|
|
606189
|
+
} catch {
|
|
606190
|
+
}
|
|
606191
|
+
delete process.env["HF_TOKEN"];
|
|
606192
|
+
}
|
|
606193
|
+
function isHfTokenPromptPending() {
|
|
606194
|
+
return pending !== null;
|
|
606195
|
+
}
|
|
606196
|
+
function describePendingHfTokenPrompt() {
|
|
606197
|
+
if (!pending) return null;
|
|
606198
|
+
return { model: pending.model, ageMs: Date.now() - pending.startedAt };
|
|
606199
|
+
}
|
|
606200
|
+
function requestHfToken(opts) {
|
|
606201
|
+
const existing = loadHfToken();
|
|
606202
|
+
if (existing) return Promise.resolve(existing);
|
|
606203
|
+
if (pending) {
|
|
606204
|
+
opts.onMessage(
|
|
606205
|
+
`Another HF token prompt is already active (for ${pending.model}). Run \`/hf <token>\` to satisfy both, or wait for the existing prompt to time out.`
|
|
606206
|
+
);
|
|
606207
|
+
return Promise.resolve(null);
|
|
606208
|
+
}
|
|
606209
|
+
const timeoutMs = Math.max(1e3, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS4);
|
|
606210
|
+
const timeoutSec = Math.round(timeoutMs / 1e3);
|
|
606211
|
+
const fallbackBit = opts.fallbackModel ? `
|
|
606212
|
+
If you don't supply one within ${timeoutSec}s, I will fall back to ${opts.fallbackModel} (no token needed).` : `
|
|
606213
|
+
If you don't supply one within ${timeoutSec}s, I will fall back to a non-gated alternative.`;
|
|
606214
|
+
opts.onMessage(
|
|
606215
|
+
[
|
|
606216
|
+
`Hugging Face model "${opts.model}" is gated and needs an access token.`,
|
|
606217
|
+
`Get one at https://huggingface.co/settings/tokens (read-only is fine),`,
|
|
606218
|
+
`accept the model license at https://huggingface.co/${opts.model},`,
|
|
606219
|
+
`then run: /hf <your-token>`,
|
|
606220
|
+
fallbackBit.trim()
|
|
606221
|
+
].join("\n")
|
|
606222
|
+
);
|
|
606223
|
+
return new Promise((resolve71) => {
|
|
606224
|
+
const timer = setTimeout(() => {
|
|
606225
|
+
const ref = pending;
|
|
606226
|
+
pending = null;
|
|
606227
|
+
if (ref) {
|
|
606228
|
+
ref.onMessage(
|
|
606229
|
+
`No HF token supplied within ${timeoutSec}s — falling back to a non-gated alternative for ${opts.model}.`
|
|
606230
|
+
);
|
|
606231
|
+
}
|
|
606232
|
+
resolve71(null);
|
|
606233
|
+
}, timeoutMs);
|
|
606234
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
606235
|
+
pending = {
|
|
606236
|
+
model: opts.model,
|
|
606237
|
+
onMessage: opts.onMessage,
|
|
606238
|
+
resolve: resolve71,
|
|
606239
|
+
timer,
|
|
606240
|
+
startedAt: Date.now()
|
|
606241
|
+
};
|
|
606242
|
+
});
|
|
606243
|
+
}
|
|
606244
|
+
function fulfillHfTokenPrompt(token) {
|
|
606245
|
+
const trimmed = token.trim();
|
|
606246
|
+
if (!trimmed) return false;
|
|
606247
|
+
saveHfToken(trimmed);
|
|
606248
|
+
if (!pending) return false;
|
|
606249
|
+
const ref = pending;
|
|
606250
|
+
pending = null;
|
|
606251
|
+
clearTimeout(ref.timer);
|
|
606252
|
+
ref.resolve(trimmed);
|
|
606253
|
+
return true;
|
|
606254
|
+
}
|
|
606255
|
+
function cancelHfTokenPrompt() {
|
|
606256
|
+
if (!pending) return false;
|
|
606257
|
+
const ref = pending;
|
|
606258
|
+
pending = null;
|
|
606259
|
+
clearTimeout(ref.timer);
|
|
606260
|
+
ref.resolve(null);
|
|
606261
|
+
return true;
|
|
606262
|
+
}
|
|
606263
|
+
function isHfGatedError(blob) {
|
|
606264
|
+
if (!blob) return false;
|
|
606265
|
+
const text2 = blob.toLowerCase();
|
|
606266
|
+
if (text2.includes("[hf_token_required")) return true;
|
|
606267
|
+
if (text2.includes("gatedrepoerror")) return true;
|
|
606268
|
+
if (text2.includes("access to model")) return true;
|
|
606269
|
+
if (text2.includes("you need to accept")) return true;
|
|
606270
|
+
if (text2.includes("you must be authenticated")) return true;
|
|
606271
|
+
if (/(401|403)/.test(text2) && /(gated|access|unauthor|forbid|auth)/.test(text2)) {
|
|
606272
|
+
return true;
|
|
606273
|
+
}
|
|
606274
|
+
return false;
|
|
606275
|
+
}
|
|
606276
|
+
function extractGatedRepoId(blob) {
|
|
606277
|
+
if (!blob) return null;
|
|
606278
|
+
const tokenMarker = blob.match(/\[HF_TOKEN_REQUIRED:([^\]\s]+)\]/);
|
|
606279
|
+
if (tokenMarker?.[1]) return tokenMarker[1].trim();
|
|
606280
|
+
const hfUrl = blob.match(/huggingface\.co\/([A-Za-z0-9._-]+\/[A-Za-z0-9._-]+)/);
|
|
606281
|
+
if (hfUrl?.[1]) return hfUrl[1];
|
|
606282
|
+
const genericRepo = blob.match(/['"`]([A-Za-z0-9._-]+\/[A-Za-z0-9._-]+)['"`]/);
|
|
606283
|
+
if (genericRepo?.[1] && /\/(.+)/.test(genericRepo[1])) return genericRepo[1];
|
|
606284
|
+
return null;
|
|
606285
|
+
}
|
|
606286
|
+
var TOKEN_DIR, TOKEN_FILE, DEFAULT_TIMEOUT_MS4, pending;
|
|
606287
|
+
var init_hf_token_prompt = __esm({
|
|
606288
|
+
"packages/cli/src/tui/hf-token-prompt.ts"() {
|
|
606289
|
+
"use strict";
|
|
606290
|
+
TOKEN_DIR = path10.join(os8.homedir(), ".omnius");
|
|
606291
|
+
TOKEN_FILE = path10.join(TOKEN_DIR, "hf_token");
|
|
606292
|
+
DEFAULT_TIMEOUT_MS4 = 3e4;
|
|
606293
|
+
pending = null;
|
|
606294
|
+
}
|
|
606295
|
+
});
|
|
606296
|
+
|
|
606297
|
+
// packages/prompts/dist/loader.js
|
|
606298
|
+
var init_loader = __esm({
|
|
606299
|
+
"packages/prompts/dist/loader.js"() {
|
|
606300
|
+
"use strict";
|
|
606301
|
+
}
|
|
606302
|
+
});
|
|
606303
|
+
|
|
606304
|
+
// packages/prompts/dist/render.js
|
|
606305
|
+
var init_render2 = __esm({
|
|
606306
|
+
"packages/prompts/dist/render.js"() {
|
|
606307
|
+
"use strict";
|
|
606308
|
+
}
|
|
606309
|
+
});
|
|
606310
|
+
|
|
606311
|
+
// packages/prompts/dist/promptLoader.js
|
|
606312
|
+
import { readFileSync as readFileSync89, existsSync as existsSync110 } from "node:fs";
|
|
606313
|
+
import { join as join124, dirname as dirname39 } from "node:path";
|
|
606314
|
+
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
606315
|
+
function loadPrompt2(promptPath, vars) {
|
|
606316
|
+
let content = cache6.get(promptPath);
|
|
606317
|
+
if (content === void 0) {
|
|
606318
|
+
const fullPath = join124(PROMPTS_DIR2, promptPath);
|
|
606319
|
+
if (!existsSync110(fullPath)) {
|
|
606320
|
+
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
606321
|
+
}
|
|
606322
|
+
content = readFileSync89(fullPath, "utf-8");
|
|
606323
|
+
cache6.set(promptPath, content);
|
|
606324
|
+
}
|
|
606325
|
+
if (!vars)
|
|
606326
|
+
return content;
|
|
606327
|
+
return content.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
606328
|
+
}
|
|
606329
|
+
var __filename4, __dirname5, devPath, publishedPath, PROMPTS_DIR2, cache6;
|
|
606330
|
+
var init_promptLoader2 = __esm({
|
|
606331
|
+
"packages/prompts/dist/promptLoader.js"() {
|
|
606332
|
+
"use strict";
|
|
606333
|
+
__filename4 = fileURLToPath13(import.meta.url);
|
|
606334
|
+
__dirname5 = dirname39(__filename4);
|
|
606335
|
+
devPath = join124(__dirname5, "..", "templates");
|
|
606336
|
+
publishedPath = join124(__dirname5, "..", "prompts", "templates");
|
|
606337
|
+
PROMPTS_DIR2 = existsSync110(devPath) ? devPath : publishedPath;
|
|
606338
|
+
cache6 = /* @__PURE__ */ new Map();
|
|
606339
|
+
}
|
|
606340
|
+
});
|
|
606341
|
+
|
|
606342
|
+
// packages/prompts/dist/task-templates.js
|
|
606343
|
+
function getTaskTemplate(type) {
|
|
606344
|
+
return TEMPLATES[type];
|
|
606345
|
+
}
|
|
606346
|
+
function getTaskTypes() {
|
|
606347
|
+
return Object.keys(TEMPLATES);
|
|
606348
|
+
}
|
|
606349
|
+
function buildTaskContext(type) {
|
|
606350
|
+
const template = TEMPLATES[type];
|
|
606351
|
+
return `${template.systemPromptAddition}
|
|
606352
|
+
|
|
606353
|
+
### Output Guidance
|
|
606354
|
+
${template.outputGuidance}`;
|
|
606355
|
+
}
|
|
606356
|
+
var TEMPLATES;
|
|
606357
|
+
var init_task_templates = __esm({
|
|
606358
|
+
"packages/prompts/dist/task-templates.js"() {
|
|
606359
|
+
"use strict";
|
|
606360
|
+
init_promptLoader2();
|
|
606361
|
+
TEMPLATES = {
|
|
606362
|
+
code: {
|
|
606363
|
+
type: "code",
|
|
606364
|
+
label: "Software Development",
|
|
606365
|
+
description: "Writing, debugging, refactoring, or reviewing code.",
|
|
606366
|
+
systemPromptAddition: loadPrompt2("code.md"),
|
|
606367
|
+
recommendedTools: [
|
|
606368
|
+
"file_read",
|
|
606369
|
+
"file_write",
|
|
606370
|
+
"file_edit",
|
|
606371
|
+
"shell",
|
|
606372
|
+
"grep_search",
|
|
606373
|
+
"glob_find",
|
|
606374
|
+
"git_info",
|
|
606375
|
+
"codebase_map"
|
|
606376
|
+
],
|
|
606377
|
+
outputGuidance: "Deliver working code with tests passing. Summarize what was changed and why."
|
|
606378
|
+
},
|
|
606379
|
+
document: {
|
|
606380
|
+
type: "document",
|
|
606381
|
+
label: "Document Drafting",
|
|
606382
|
+
description: "Creating reports, specifications, guides, proposals, or other professional documents.",
|
|
606383
|
+
systemPromptAddition: loadPrompt2("document.md"),
|
|
606384
|
+
recommendedTools: [
|
|
606385
|
+
"file_read",
|
|
606386
|
+
"file_write",
|
|
606387
|
+
"web_search",
|
|
606388
|
+
"web_fetch",
|
|
606389
|
+
"create_structured_file",
|
|
606390
|
+
"memory_read"
|
|
606391
|
+
],
|
|
606392
|
+
outputGuidance: "Deliver a complete, well-structured document. Specify the output format (Markdown, PDF, etc.)."
|
|
606393
|
+
},
|
|
606394
|
+
analysis: {
|
|
606395
|
+
type: "analysis",
|
|
606396
|
+
label: "Analysis & Research",
|
|
606397
|
+
description: "Analyzing data, evaluating options, conducting research, or producing insights.",
|
|
606398
|
+
systemPromptAddition: loadPrompt2("analysis.md"),
|
|
606399
|
+
recommendedTools: [
|
|
606400
|
+
"file_read",
|
|
606401
|
+
"grep_search",
|
|
606402
|
+
"glob_find",
|
|
606403
|
+
"web_search",
|
|
606404
|
+
"web_fetch",
|
|
606405
|
+
"codebase_map",
|
|
606406
|
+
"create_structured_file",
|
|
606407
|
+
"shell"
|
|
606408
|
+
],
|
|
606409
|
+
outputGuidance: "Deliver a structured analysis with findings, data tables, and actionable recommendations."
|
|
606410
|
+
},
|
|
606411
|
+
plan: {
|
|
606412
|
+
type: "plan",
|
|
606413
|
+
label: "Planning & Design",
|
|
606414
|
+
description: "Creating project plans, system designs, architecture proposals, or roadmaps.",
|
|
606415
|
+
systemPromptAddition: loadPrompt2("plan.md"),
|
|
606416
|
+
recommendedTools: [
|
|
606417
|
+
"file_read",
|
|
606418
|
+
"grep_search",
|
|
606419
|
+
"glob_find",
|
|
606420
|
+
"codebase_map",
|
|
606421
|
+
"web_search",
|
|
606422
|
+
"create_structured_file",
|
|
606423
|
+
"file_write",
|
|
606424
|
+
"git_info"
|
|
606425
|
+
],
|
|
606426
|
+
outputGuidance: "Deliver a structured plan with phases, milestones, risks, and action items."
|
|
606427
|
+
},
|
|
606428
|
+
general: {
|
|
606429
|
+
type: "general",
|
|
606430
|
+
label: "General Task",
|
|
606431
|
+
description: "Tasks that don't clearly fit another category.",
|
|
606432
|
+
systemPromptAddition: loadPrompt2("general.md"),
|
|
606433
|
+
recommendedTools: [
|
|
606434
|
+
"file_read",
|
|
606435
|
+
"file_write",
|
|
606436
|
+
"shell",
|
|
606437
|
+
"grep_search",
|
|
606438
|
+
"web_search",
|
|
606439
|
+
"memory_read"
|
|
606440
|
+
],
|
|
606441
|
+
outputGuidance: "Deliver complete results with a clear summary of what was done."
|
|
606442
|
+
}
|
|
606443
|
+
};
|
|
606444
|
+
}
|
|
606445
|
+
});
|
|
606446
|
+
|
|
606447
|
+
// packages/prompts/dist/index.js
|
|
606448
|
+
import { join as join125, dirname as dirname40 } from "node:path";
|
|
606449
|
+
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
606450
|
+
var _dir, _packageRoot;
|
|
606451
|
+
var init_dist9 = __esm({
|
|
606452
|
+
"packages/prompts/dist/index.js"() {
|
|
606453
|
+
"use strict";
|
|
606454
|
+
init_loader();
|
|
606455
|
+
init_render2();
|
|
606456
|
+
init_task_templates();
|
|
606457
|
+
init_render2();
|
|
606458
|
+
_dir = dirname40(fileURLToPath14(import.meta.url));
|
|
606459
|
+
_packageRoot = join125(_dir, "..");
|
|
606460
|
+
}
|
|
606461
|
+
});
|
|
606462
|
+
|
|
606301
606463
|
// packages/cli/src/tui/braille-spinner.ts
|
|
606302
606464
|
function buildColorRamp(ramp) {
|
|
606303
606465
|
return [...ramp, ...ramp.slice(1, -1).reverse()];
|
|
@@ -609724,7 +609886,9 @@ var init_status_bar = __esm({
|
|
|
609724
609886
|
} else {
|
|
609725
609887
|
return false;
|
|
609726
609888
|
}
|
|
609727
|
-
this.
|
|
609889
|
+
if (this.active && !isOverlayActive() && !this._suspendContentLayer) {
|
|
609890
|
+
this.repaintContent();
|
|
609891
|
+
}
|
|
609728
609892
|
return true;
|
|
609729
609893
|
}
|
|
609730
609894
|
/**
|
|
@@ -616699,7 +616863,7 @@ export PATH="${binDir}:$PATH" # Added by omnius for nvim
|
|
|
616699
616863
|
} catch {
|
|
616700
616864
|
}
|
|
616701
616865
|
}
|
|
616702
|
-
var execAsync2, OMNIUS_FIRST_RUN_BANNER,
|
|
616866
|
+
var execAsync2, OMNIUS_FIRST_RUN_BANNER, ANSI_RE2, visibleLen2, QWEN_VARIANTS, _toolSupportCache, EXPANDED_VARIANT_MIN_NUM_CTX, _cloudflaredInstallPromise;
|
|
616703
616867
|
var init_setup = __esm({
|
|
616704
616868
|
"packages/cli/src/tui/setup.ts"() {
|
|
616705
616869
|
"use strict";
|
|
@@ -616719,8 +616883,8 @@ var init_setup = __esm({
|
|
|
616719
616883
|
"░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ",
|
|
616720
616884
|
" ░▒▓██████▓▒░░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓██████▓▒░░▒▓███████▓▒░ "
|
|
616721
616885
|
].join("\n");
|
|
616722
|
-
|
|
616723
|
-
visibleLen2 = (value2) => Array.from(value2.replace(
|
|
616886
|
+
ANSI_RE2 = /\x1B\[[0-?]*[ -/]*[@-~]/g;
|
|
616887
|
+
visibleLen2 = (value2) => Array.from(value2.replace(ANSI_RE2, "")).length;
|
|
616724
616888
|
QWEN_VARIANTS = [
|
|
616725
616889
|
{ tag: "qwen3.5:0.8b", sizeGB: 1, label: "0.8B params (1.0 GB)", cloud: false },
|
|
616726
616890
|
{ tag: "qwen3.5:2b", sizeGB: 2.7, label: "2B params (2.7 GB)", cloud: false },
|
|
@@ -623927,16 +624091,16 @@ import { execFileSync as execFileSync8 } from "node:child_process";
|
|
|
623927
624091
|
import { createRequire as createRequire6 } from "node:module";
|
|
623928
624092
|
import { existsSync as existsSync125, readFileSync as readFileSync101, statSync as statSync46 } from "node:fs";
|
|
623929
624093
|
import { resolve as resolve56 } from "node:path";
|
|
623930
|
-
function
|
|
624094
|
+
function clamp8(n2, min, max) {
|
|
623931
624095
|
if (!Number.isFinite(n2)) return min;
|
|
623932
624096
|
return Math.max(min, Math.min(max, Math.floor(n2)));
|
|
623933
624097
|
}
|
|
623934
624098
|
function defaultAsciiPreviewSize(dimensions) {
|
|
623935
624099
|
const columns = process.stdout.columns || 100;
|
|
623936
624100
|
const rows = process.stdout.rows || 32;
|
|
623937
|
-
const width =
|
|
624101
|
+
const width = clamp8(columns - 14, 42, 96);
|
|
623938
624102
|
const imageAspect = dimensions && dimensions.width > 0 && dimensions.height > 0 ? dimensions.height / dimensions.width : 1;
|
|
623939
|
-
const height =
|
|
624103
|
+
const height = clamp8(Math.min(Math.round(width * imageAspect * TERMINAL_CELL_ASPECT), rows - 10), 8, 42);
|
|
623940
624104
|
return { width, height };
|
|
623941
624105
|
}
|
|
623942
624106
|
function readImageDimensions2(imagePath) {
|
|
@@ -624032,10 +624196,10 @@ function normalizeAscii(ascii2, width, height, options2 = {}) {
|
|
|
624032
624196
|
}
|
|
624033
624197
|
function byte(value2, fallback) {
|
|
624034
624198
|
const n2 = Number(value2);
|
|
624035
|
-
return Number.isFinite(n2) ?
|
|
624199
|
+
return Number.isFinite(n2) ? clamp8(n2, 0, 255) : fallback;
|
|
624036
624200
|
}
|
|
624037
624201
|
function luminance(r2, g, b) {
|
|
624038
|
-
return
|
|
624202
|
+
return clamp8(Math.round(0.2126 * r2 + 0.7152 * g + 0.0722 * b), 0, 255);
|
|
624039
624203
|
}
|
|
624040
624204
|
function matrixPixel(cell) {
|
|
624041
624205
|
if (cell && typeof cell === "object") {
|
|
@@ -624199,9 +624363,9 @@ async function buildImageAsciiPreview(inputPath, options2 = {}) {
|
|
|
624199
624363
|
}
|
|
624200
624364
|
const dimensions = readImageDimensions2(imagePath);
|
|
624201
624365
|
const defaults3 = defaultAsciiPreviewSize(dimensions);
|
|
624202
|
-
const width =
|
|
624203
|
-
const height =
|
|
624204
|
-
const timeoutMs =
|
|
624366
|
+
const width = clamp8(options2.width ?? defaults3.width, 24, 140);
|
|
624367
|
+
const height = clamp8(options2.height ?? defaults3.height, 6, 60);
|
|
624368
|
+
const timeoutMs = clamp8(options2.timeoutMs ?? 5e3, 500, 3e4);
|
|
624205
624369
|
if (options2.preferPackage !== false) {
|
|
624206
624370
|
const result = await convertWithImageToAscii(imagePath, width, height, timeoutMs);
|
|
624207
624371
|
if (result.ascii) {
|
|
@@ -634700,7 +634864,7 @@ sleep 1
|
|
|
634700
634864
|
return "handled";
|
|
634701
634865
|
}
|
|
634702
634866
|
if (arg.trim()) {
|
|
634703
|
-
restoreNamedSession(ctx3, arg.trim());
|
|
634867
|
+
await restoreNamedSession(ctx3, arg.trim());
|
|
634704
634868
|
return "handled";
|
|
634705
634869
|
}
|
|
634706
634870
|
const resumed = ctx3.resumeTask?.() ?? false;
|
|
@@ -635864,10 +636028,12 @@ async function showSessionsMenu(ctx3) {
|
|
|
635864
636028
|
const items = sessions3.map((s2) => {
|
|
635865
636029
|
const date = s2.updatedAt.slice(0, 16).replace("T", " ");
|
|
635866
636030
|
const tasks = s2.taskCount > 1 ? `${s2.taskCount} tasks` : "1 task";
|
|
636031
|
+
const title = sessionDisplayTitle(s2);
|
|
636032
|
+
const summary = s2.aiSummary ? ` ${s2.aiSummary}` : "";
|
|
635867
636033
|
return {
|
|
635868
636034
|
key: s2.id,
|
|
635869
|
-
label:
|
|
635870
|
-
detail: `${date} | ${tasks} | ${s2.model}`
|
|
636035
|
+
label: title,
|
|
636036
|
+
detail: `${date} | ${tasks} | ${s2.model}${summary}`
|
|
635871
636037
|
};
|
|
635872
636038
|
});
|
|
635873
636039
|
items.push({
|
|
@@ -635889,45 +636055,59 @@ async function showSessionsMenu(ctx3) {
|
|
|
635889
636055
|
else ctx3.clearScreen();
|
|
635890
636056
|
return;
|
|
635891
636057
|
}
|
|
635892
|
-
|
|
636058
|
+
await replaySession(ctx3, result.key);
|
|
636059
|
+
}
|
|
636060
|
+
async function replaySession(ctx3, sessionId) {
|
|
636061
|
+
const content = loadSessionHistory(ctx3.repoRoot, sessionId);
|
|
635893
636062
|
if (!content || content.length === 0) {
|
|
635894
636063
|
renderWarning("Session content not found or empty.");
|
|
635895
636064
|
return;
|
|
635896
636065
|
}
|
|
635897
|
-
const
|
|
635898
|
-
|
|
635899
|
-
|
|
635900
|
-
|
|
635901
|
-
|
|
635902
|
-
|
|
635903
|
-
|
|
636066
|
+
const sessions3 = listSessions(ctx3.repoRoot);
|
|
636067
|
+
const session = sessions3.find((s2) => s2.id === sessionId);
|
|
636068
|
+
let title = session ? sessionDisplayTitle(session) : sessionId;
|
|
636069
|
+
let summary = session?.aiSummary ?? "";
|
|
636070
|
+
if (session && !session.aiTitle) {
|
|
636071
|
+
try {
|
|
636072
|
+
const gen = await ensureSessionSummary({
|
|
636073
|
+
repoRoot: ctx3.repoRoot,
|
|
636074
|
+
sessionId,
|
|
636075
|
+
config: {
|
|
636076
|
+
backendUrl: ctx3.config.backendUrl,
|
|
636077
|
+
model: ctx3.config.model,
|
|
636078
|
+
apiKey: ctx3.config.apiKey
|
|
636079
|
+
},
|
|
636080
|
+
timeoutMs: 2e4
|
|
636081
|
+
});
|
|
636082
|
+
title = gen.title;
|
|
636083
|
+
summary = gen.summary;
|
|
636084
|
+
} catch {
|
|
636085
|
+
}
|
|
635904
636086
|
}
|
|
635905
|
-
|
|
636087
|
+
renderContentBlock(
|
|
636088
|
+
`
|
|
636089
|
+
${c3.dim("╭─")} ${c3.bold("Recovered session")} ${c3.dim("·")} ${title} ${c3.dim(`(${content.length} lines)`)}
|
|
636090
|
+
` + (summary ? `${c3.dim("│")} ${c3.dim(summary)}
|
|
636091
|
+
` : "") + `${c3.dim("╰" + "─".repeat(40))}`
|
|
636092
|
+
);
|
|
636093
|
+
renderContentBlock(content.map((line) => ` ${line}`).join("\n"));
|
|
636094
|
+
renderContentBlock(
|
|
636095
|
+
`${c3.dim("─".repeat(20))} ${c3.dim("end of recovered session")} ${c3.dim("─".repeat(20))}`
|
|
636096
|
+
);
|
|
636097
|
+
renderInfo("Previous session fully restored above. Scroll up to review.");
|
|
635906
636098
|
}
|
|
635907
|
-
function restoreNamedSession(ctx3, query) {
|
|
636099
|
+
async function restoreNamedSession(ctx3, query) {
|
|
635908
636100
|
const normalized = query.toLowerCase();
|
|
635909
636101
|
const sessions3 = listSessions(ctx3.repoRoot);
|
|
635910
|
-
const session = sessions3.find((s2) => s2.id === query) ?? sessions3.find((s2) => s2.name.toLowerCase() === normalized) ?? sessions3.find((s2) => s2.name.toLowerCase().includes(normalized));
|
|
636102
|
+
const session = sessions3.find((s2) => s2.id === query) ?? sessions3.find((s2) => sessionDisplayTitle(s2).toLowerCase() === normalized) ?? sessions3.find((s2) => s2.name.toLowerCase() === normalized) ?? sessions3.find((s2) => sessionDisplayTitle(s2).toLowerCase().includes(normalized)) ?? sessions3.find((s2) => s2.name.toLowerCase().includes(normalized));
|
|
635911
636103
|
if (!session) {
|
|
635912
636104
|
renderWarning(
|
|
635913
636105
|
`No saved session matches "${query}". Use /sessions to browse.`
|
|
635914
636106
|
);
|
|
635915
636107
|
return;
|
|
635916
636108
|
}
|
|
635917
|
-
const content = loadSessionHistory(ctx3.repoRoot, session.id);
|
|
635918
|
-
if (!content || content.length === 0) {
|
|
635919
|
-
renderWarning(`Saved session "${session.name}" has no replayable history.`);
|
|
635920
|
-
return;
|
|
635921
|
-
}
|
|
635922
636109
|
ctx3.clearScreen();
|
|
635923
|
-
|
|
635924
|
-
for (const line of content) {
|
|
635925
|
-
process.stdout.write(` ${line}
|
|
635926
|
-
`);
|
|
635927
|
-
}
|
|
635928
|
-
renderInfo(
|
|
635929
|
-
"Session history loaded. New prompts continue in the current runtime session."
|
|
635930
|
-
);
|
|
636110
|
+
await replaySession(ctx3, session.id);
|
|
635931
636111
|
}
|
|
635932
636112
|
async function showColorMenu(ctx3) {
|
|
635933
636113
|
const currentConfig = getThemeConfig();
|
|
@@ -644213,6 +644393,7 @@ var init_commands = __esm({
|
|
|
644213
644393
|
"use strict";
|
|
644214
644394
|
init_model_picker();
|
|
644215
644395
|
init_render();
|
|
644396
|
+
init_session_summary();
|
|
644216
644397
|
init_generative_progress();
|
|
644217
644398
|
init_cad_model_viewer();
|
|
644218
644399
|
init_command_registry();
|
|
@@ -645890,6 +646071,7 @@ function importTranscriptSession(opts) {
|
|
|
645890
646071
|
existing.model = opts.model || existing.model;
|
|
645891
646072
|
existing.title = title;
|
|
645892
646073
|
existing.preview = preview;
|
|
646074
|
+
existing.transcript = cappedTranscript || "(empty transcript)";
|
|
645893
646075
|
existing.lastActivity = opts.updatedAt ?? Date.now();
|
|
645894
646076
|
const idx = existing.messages.findIndex(
|
|
645895
646077
|
(m2) => m2.role === "system" && m2.content.startsWith("[Imported TUI session transcript]")
|
|
@@ -645918,7 +646100,8 @@ function importTranscriptSession(opts) {
|
|
|
645918
646100
|
projectRoot,
|
|
645919
646101
|
source: "tui",
|
|
645920
646102
|
title,
|
|
645921
|
-
preview
|
|
646103
|
+
preview,
|
|
646104
|
+
transcript: cappedTranscript || "(empty transcript)"
|
|
645922
646105
|
};
|
|
645923
646106
|
sessions2.set(id, session);
|
|
645924
646107
|
persistSession(session);
|
|
@@ -652361,7 +652544,7 @@ function appraiseEvent(event) {
|
|
|
652361
652544
|
return null;
|
|
652362
652545
|
}
|
|
652363
652546
|
}
|
|
652364
|
-
function
|
|
652547
|
+
function clamp9(value2, min, max) {
|
|
652365
652548
|
return Math.max(min, Math.min(max, value2));
|
|
652366
652549
|
}
|
|
652367
652550
|
var BASELINE_VALENCE, BASELINE_AROUSAL, DECAY_HALF_LIFE_MS, LABEL_UPDATE_INTERVAL_MS, DISTRESS_THRESHOLD, REFLECTION_COOLDOWN_MS, REFLECTION_MIN_EVENTS, LABEL_REGEN_THRESHOLD, EmotionEngine;
|
|
@@ -652500,8 +652683,8 @@ var init_emotion_engine = __esm({
|
|
|
652500
652683
|
if (this.consecutiveFailures >= 2) {
|
|
652501
652684
|
momentum = 1 + (this.consecutiveFailures - 1) * 0.25;
|
|
652502
652685
|
}
|
|
652503
|
-
this.state.valence =
|
|
652504
|
-
this.state.arousal =
|
|
652686
|
+
this.state.valence = clamp9(this.state.valence + delta.valence * momentum, -1, 1);
|
|
652687
|
+
this.state.arousal = clamp9(this.state.arousal + delta.arousal * momentum, 0, 1);
|
|
652505
652688
|
this.state.updatedAt = Date.now();
|
|
652506
652689
|
const deterministicLabel = labelFromCoordinates(this.state.valence, this.state.arousal);
|
|
652507
652690
|
this.state.label = deterministicLabel.label;
|
|
@@ -685554,6 +685737,12 @@ body { display:flex; flex-direction:column; height:100vh; margin:0; overflow:hid
|
|
|
685554
685737
|
</div>
|
|
685555
685738
|
<h3 style="color:var(--color-brand);font-size:0.7rem;margin:16px 0 8px">Inference Provider</h3>
|
|
685556
685739
|
<div id="config-endpoint" style="font-size:0.78rem;color:var(--color-fg-muted);margin-bottom:8px"></div>
|
|
685740
|
+
<div id="config-recent-providers-section" style="display:none;margin-bottom:12px">
|
|
685741
|
+
<div style="font-size:0.66rem;color:var(--color-fg-muted);margin-bottom:6px;font-weight:500">Previously connected</div>
|
|
685742
|
+
<div id="config-recent-providers" class="settings-provider-module-grid"></div>
|
|
685743
|
+
</div>
|
|
685744
|
+
<div style="font-size:0.66rem;color:var(--color-fg-faint);margin-bottom:6px">Pick a provider to pre-fill the endpoint, then add your key and press <strong>set</strong>.</div>
|
|
685745
|
+
<div id="config-provider-modules" style="margin-bottom:10px"></div>
|
|
685557
685746
|
<form onsubmit="event.preventDefault(); switchEndpoint();" autocomplete="off" style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:4px">
|
|
685558
685747
|
<input id="config-ep-url" placeholder="https://api.example.com/v1" autocomplete="off" style="flex:1;min-width:200px;background:var(--color-bg-input);border:1px solid var(--color-border);border-radius:3px;padding:4px 8px;color:var(--color-fg);font-family:inherit;font-size:0.7rem;outline:none">
|
|
685559
685748
|
<input id="config-ep-key" placeholder="Bearer key (optional)" type="password" autocomplete="new-password" style="flex:1;min-width:150px;background:var(--color-bg-input);border:1px solid var(--color-border);border-radius:3px;padding:4px 8px;color:var(--color-fg);font-family:inherit;font-size:0.7rem;outline:none">
|
|
@@ -688892,6 +689081,27 @@ async function loadConfig() {
|
|
|
688892
689081
|
'<td style="padding:4px;color:var(--color-fg)">' + (v === '[redacted]' ? '<span style="color:var(--color-fg-faint)">[redacted]</span>' : String(v)) + '</td></tr>'
|
|
688893
689082
|
).join('') + '</table>';
|
|
688894
689083
|
document.getElementById('config-endpoint').textContent = ep.url + ' (' + (ep.backendType || 'unknown') + ')';
|
|
689084
|
+
// Provider module grid (same cards as the Settings modal) wired to the
|
|
689085
|
+
// config-tab endpoint form. Pre-selects the provider matching the active URL.
|
|
689086
|
+
try {
|
|
689087
|
+
const pm = document.getElementById('config-provider-modules');
|
|
689088
|
+
if (pm) pm.innerHTML = renderSettingsProviderModules(settingsProviderIdForUrl(ep.url), ep.url, 'selectConfigProviderModule');
|
|
689089
|
+
} catch {}
|
|
689090
|
+
// Previously-connected providers — like the TUI /endpoint history, shown as
|
|
689091
|
+
// cards above the full provider list. Populated from endpoint usage history.
|
|
689092
|
+
try {
|
|
689093
|
+
const histR = await fetch('/v1/config/endpoint/history', { headers: headers() }).then(r => r.json()).catch(() => ({}));
|
|
689094
|
+
const history = (histR && Array.isArray(histR.endpoints)) ? histR.endpoints : [];
|
|
689095
|
+
const sect = document.getElementById('config-recent-providers-section');
|
|
689096
|
+
const grid = document.getElementById('config-recent-providers');
|
|
689097
|
+
if (grid && history.length > 0) {
|
|
689098
|
+
window.__omniusRecentEndpoints = history;
|
|
689099
|
+
grid.innerHTML = renderRecentProviderCards(history, ep.url);
|
|
689100
|
+
if (sect) sect.style.display = 'block';
|
|
689101
|
+
} else if (sect) {
|
|
689102
|
+
sect.style.display = 'none';
|
|
689103
|
+
}
|
|
689104
|
+
} catch {}
|
|
688895
689105
|
// Populate model switcher
|
|
688896
689106
|
const sel = document.getElementById('config-model-select');
|
|
688897
689107
|
sel.innerHTML = '';
|
|
@@ -688931,6 +689141,86 @@ async function switchEndpoint() {
|
|
|
688931
689141
|
} catch {}
|
|
688932
689142
|
}
|
|
688933
689143
|
|
|
689144
|
+
// Provider-module click handler for the /settings (config tab) endpoint form.
|
|
689145
|
+
// Fills the URL + backend-type fields, highlights the active card, and for
|
|
689146
|
+
// cloud providers opens the API-key page and focuses the key input so the user
|
|
689147
|
+
// just pastes their key and presses "set".
|
|
689148
|
+
function selectConfigProviderModule(providerId) {
|
|
689149
|
+
const provider = settingsProviderById(providerId);
|
|
689150
|
+
if (!provider) return;
|
|
689151
|
+
const urlInput = document.getElementById('config-ep-url');
|
|
689152
|
+
const typeSel = document.getElementById('config-ep-type');
|
|
689153
|
+
const keyInput = document.getElementById('config-ep-key');
|
|
689154
|
+
if (urlInput) urlInput.value = provider.url || '';
|
|
689155
|
+
if (typeSel && provider.backendType) {
|
|
689156
|
+
if (!Array.from(typeSel.options).some(o => o.value === provider.backendType)) {
|
|
689157
|
+
const opt = document.createElement('option');
|
|
689158
|
+
opt.value = provider.backendType; opt.textContent = provider.backendType;
|
|
689159
|
+
typeSel.appendChild(opt);
|
|
689160
|
+
}
|
|
689161
|
+
typeSel.value = provider.backendType;
|
|
689162
|
+
}
|
|
689163
|
+
// Highlight the chosen card.
|
|
689164
|
+
document.querySelectorAll('#config-provider-modules .settings-provider-module').forEach(btn => {
|
|
689165
|
+
btn.classList.toggle('active', btn.getAttribute('data-provider-id') === providerId);
|
|
689166
|
+
});
|
|
689167
|
+
// Cloud providers: open the key page and focus the key field.
|
|
689168
|
+
if (provider.requiresAuth && provider.apiKeyUrl) {
|
|
689169
|
+
try { window.open(provider.apiKeyUrl, '_blank', 'noopener'); } catch {}
|
|
689170
|
+
}
|
|
689171
|
+
if (keyInput) { try { keyInput.focus(); } catch {} }
|
|
689172
|
+
else if (!provider.url && urlInput) { try { urlInput.focus(); } catch {} }
|
|
689173
|
+
}
|
|
689174
|
+
window.selectConfigProviderModule = selectConfigProviderModule;
|
|
689175
|
+
|
|
689176
|
+
// Render "previously connected" provider cards from endpoint usage history.
|
|
689177
|
+
// Each card resolves to a known provider (for the favicon + label) and carries
|
|
689178
|
+
// its actual URL so clicking re-selects that exact endpoint.
|
|
689179
|
+
function renderRecentProviderCards(history, activeUrl) {
|
|
689180
|
+
const seen = new Set();
|
|
689181
|
+
return history.map(h => {
|
|
689182
|
+
const url = String(h.url || '');
|
|
689183
|
+
if (!url || seen.has(url)) return '';
|
|
689184
|
+
seen.add(url);
|
|
689185
|
+
const providerId = settingsProviderIdForUrl(url);
|
|
689186
|
+
const provider = settingsProviderById(providerId) || { id: providerId, label: providerId, domain: '' };
|
|
689187
|
+
const active = url === activeUrl;
|
|
689188
|
+
const cls = 'settings-provider-module' + (active ? ' active' : '');
|
|
689189
|
+
let host = url; try { host = new URL(url).host || url; } catch {}
|
|
689190
|
+
const label = (h.meta && h.meta.provider) ? h.meta.provider : provider.label;
|
|
689191
|
+
const uses = (h.useCount ? h.useCount + (h.useCount === 1 ? ' use' : ' uses') : '');
|
|
689192
|
+
const meta = [host, uses, h.authSet ? '🔑' : ''].filter(Boolean).join(' · ');
|
|
689193
|
+
return '<button type="button" class="' + cls + '" data-recent-url="' + escapeHtml(url) + '" onclick="selectRecentProvider(\\'' + escapeHtml(url).replace(/'/g, "'") + '\\')" title="' + escapeHtml(url) + '">' +
|
|
689194
|
+
settingsProviderIcon(provider) +
|
|
689195
|
+
'<strong>' + escapeHtml(label) + '</strong>' +
|
|
689196
|
+
'<small>' + escapeHtml(meta) + '</small>' +
|
|
689197
|
+
'</button>';
|
|
689198
|
+
}).join('');
|
|
689199
|
+
}
|
|
689200
|
+
|
|
689201
|
+
// Click handler for a previously-connected provider card: fill the form with
|
|
689202
|
+
// that exact endpoint URL + detected backend type and focus the key field.
|
|
689203
|
+
function selectRecentProvider(url) {
|
|
689204
|
+
const urlInput = document.getElementById('config-ep-url');
|
|
689205
|
+
const typeSel = document.getElementById('config-ep-type');
|
|
689206
|
+
const keyInput = document.getElementById('config-ep-key');
|
|
689207
|
+
if (urlInput) urlInput.value = url;
|
|
689208
|
+
const providerId = settingsProviderIdForUrl(url);
|
|
689209
|
+
const provider = settingsProviderById(providerId);
|
|
689210
|
+
const bt = (provider && provider.backendType) ? provider.backendType : (url.includes('11434') ? 'ollama' : 'vllm');
|
|
689211
|
+
if (typeSel) {
|
|
689212
|
+
if (!Array.from(typeSel.options).some(o => o.value === bt)) {
|
|
689213
|
+
const opt = document.createElement('option'); opt.value = bt; opt.textContent = bt; typeSel.appendChild(opt);
|
|
689214
|
+
}
|
|
689215
|
+
typeSel.value = bt;
|
|
689216
|
+
}
|
|
689217
|
+
document.querySelectorAll('#config-recent-providers .settings-provider-module').forEach(btn => {
|
|
689218
|
+
btn.classList.toggle('active', btn.getAttribute('data-recent-url') === url);
|
|
689219
|
+
});
|
|
689220
|
+
if (keyInput) { try { keyInput.focus(); } catch {} }
|
|
689221
|
+
}
|
|
689222
|
+
window.selectRecentProvider = selectRecentProvider;
|
|
689223
|
+
|
|
688934
689224
|
async function switchModel() {
|
|
688935
689225
|
const model = document.getElementById('config-model-select').value;
|
|
688936
689226
|
if (!model) return;
|
|
@@ -691246,6 +691536,23 @@ async function restoreChatSession() {
|
|
|
691246
691536
|
const conv = document.getElementById('conversation');
|
|
691247
691537
|
if (conv) {
|
|
691248
691538
|
conv.innerHTML = '';
|
|
691539
|
+
// Imported TUI session: render its FULL recorded transcript (tool calls,
|
|
691540
|
+
// decisions, sub-agent activity — everything that scrolled past in the
|
|
691541
|
+
// TUI) as a visible, scrollable block at the top so opening the session
|
|
691542
|
+
// actually shows what happened, instead of just a "loaded" notice.
|
|
691543
|
+
if (data.transcript && String(data.transcript).trim() && data.transcript !== '(empty transcript)') {
|
|
691544
|
+
const wrap = document.createElement('div');
|
|
691545
|
+
wrap.style.cssText = 'margin:6px 0 14px';
|
|
691546
|
+
const head = document.createElement('div');
|
|
691547
|
+
head.style.cssText = 'font-size:0.66rem;color:var(--color-fg-muted);margin-bottom:4px;display:flex;justify-content:space-between;align-items:center';
|
|
691548
|
+
head.innerHTML = '<span>Recovered session transcript' + (data.title ? ' — ' + escapeHtml(data.title) : '') + '</span>';
|
|
691549
|
+
const pre = document.createElement('pre');
|
|
691550
|
+
pre.style.cssText = 'max-height:380px;overflow:auto;background:var(--color-bg-elevated);border:1px solid var(--color-border);border-radius:var(--radius-sm);padding:10px 12px;font-size:0.7rem;line-height:1.35;white-space:pre-wrap;word-break:break-word;color:var(--color-fg-muted);margin:0';
|
|
691551
|
+
pre.textContent = String(data.transcript);
|
|
691552
|
+
wrap.appendChild(head);
|
|
691553
|
+
wrap.appendChild(pre);
|
|
691554
|
+
conv.appendChild(wrap);
|
|
691555
|
+
}
|
|
691249
691556
|
// WO-CHAT-RESUME-TOOLS — replay the FULL intermediate flow on
|
|
691250
691557
|
// restore: user/assistant text bubbles AND tool_call/tool_result
|
|
691251
691558
|
// dropdowns interleaved in original order. We track the current
|
|
@@ -692795,15 +693102,18 @@ function settingsProviderIcon(provider) {
|
|
|
692795
693102
|
return '<span class="settings-provider-brand"><img src="' + escapeHtml(src) + '" alt="" onerror="this.hidden=true;this.nextElementSibling.hidden=false"><span hidden>' + initial + '</span></span>';
|
|
692796
693103
|
}
|
|
692797
693104
|
|
|
692798
|
-
function renderSettingsProviderModules(selectedId, currentUrl) {
|
|
693105
|
+
function renderSettingsProviderModules(selectedId, currentUrl, handler) {
|
|
692799
693106
|
const activeId = settingsProviderIdForUrl(currentUrl);
|
|
693107
|
+
// handler is the click function name so the same grid can drive either the
|
|
693108
|
+
// Settings modal Connections pane or the /settings (config tab) form.
|
|
693109
|
+
const fn = handler || 'selectSettingsProviderModule';
|
|
692800
693110
|
return '<div class="settings-provider-module-grid">' + _OMNIUS_ENDPOINT_PROVIDERS.map(provider => {
|
|
692801
693111
|
const selected = provider.id === selectedId;
|
|
692802
693112
|
const active = provider.id === activeId;
|
|
692803
693113
|
const cls = 'settings-provider-module' + (selected ? ' active' : '');
|
|
692804
693114
|
const safeId = escapeHtml(provider.id);
|
|
692805
693115
|
const meta = provider.group + (active ? ' - active' : (provider.requiresAuth ? ' - API key' : ''));
|
|
692806
|
-
return '<button type="button" class="' + cls + '" data-provider-id="' + safeId + '" onclick="
|
|
693116
|
+
return '<button type="button" class="' + cls + '" data-provider-id="' + safeId + '" onclick="' + fn + '(\\'' + safeId + '\\', false)">' +
|
|
692807
693117
|
settingsProviderIcon(provider) +
|
|
692808
693118
|
'<strong>' + escapeHtml(provider.label) + '</strong>' +
|
|
692809
693119
|
'<small>' + escapeHtml(meta) + '</small>' +
|
|
@@ -693772,6 +694082,7 @@ function getOpenApiSpec() {
|
|
|
693772
694082
|
}
|
|
693773
694083
|
},
|
|
693774
694084
|
"/v1/chat/sessions": { get: { summary: "List active chat sessions", tags: ["Chat"], responses: { 200: { description: "Session list" } } } },
|
|
694085
|
+
"/v1/chat/sessions/{id}/summarize": { post: { summary: "Generate + cache an inference-based title/summary for a session — body {force?, root?}", tags: ["Chat"], responses: { 200: { description: "Title + summary" }, 500: { description: "Generation failed" } } } },
|
|
693775
694086
|
// ───── AIWG cascade ─────
|
|
693776
694087
|
"/v1/aiwg": { get: { summary: "AIWG installation root + control map", tags: ["AIWG"], responses: { 200: { description: "AIWG installation summary" } } } },
|
|
693777
694088
|
"/v1/aiwg/frameworks": { get: { summary: "List AIWG frameworks (paginated)", tags: ["AIWG"], responses: { 200: { description: "Framework list" } } } },
|
|
@@ -700274,7 +700585,7 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
|
|
|
700274
700585
|
return;
|
|
700275
700586
|
}
|
|
700276
700587
|
if (pathname === "/favicon.ico" && method === "GET") {
|
|
700277
|
-
const svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><rect width="16" height="16"
|
|
700588
|
+
const svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><rect width="16" height="16" fill="#000"/><rect x="3" y="3" width="10" height="10" fill="#fff"/><rect x="6" y="6" width="4" height="4" fill="#000"/></svg>';
|
|
700278
700589
|
res.writeHead(200, {
|
|
700279
700590
|
"Content-Type": "image/svg+xml",
|
|
700280
700591
|
"Cache-Control": "public, max-age=86400"
|
|
@@ -702600,9 +702911,12 @@ ${historyLines}
|
|
|
702600
702911
|
const includeTui = urlObj.searchParams.get("include_tui") !== "0";
|
|
702601
702912
|
if (includeTui && targetRoot) {
|
|
702602
702913
|
const seen = new Set(sessions3.map((s2) => s2.id));
|
|
702914
|
+
const cfg = loadConfig();
|
|
702915
|
+
const needSummary = [];
|
|
702603
702916
|
for (const t2 of listSessions(targetRoot)) {
|
|
702604
702917
|
const id = `tui:${t2.id}`;
|
|
702605
702918
|
if (seen.has(id)) continue;
|
|
702919
|
+
if (!t2.aiTitle) needSummary.push(t2.id);
|
|
702606
702920
|
sessions3.push({
|
|
702607
702921
|
id,
|
|
702608
702922
|
model: t2.model,
|
|
@@ -702612,8 +702926,16 @@ ${historyLines}
|
|
|
702612
702926
|
lastActivity: t2.updatedAt,
|
|
702613
702927
|
projectRoot: targetRoot,
|
|
702614
702928
|
source: "tui",
|
|
702615
|
-
title: t2
|
|
702616
|
-
preview: t2.description
|
|
702929
|
+
title: sessionDisplayTitle(t2),
|
|
702930
|
+
preview: t2.aiSummary || t2.description
|
|
702931
|
+
});
|
|
702932
|
+
}
|
|
702933
|
+
for (const sid of needSummary.slice(0, 6)) {
|
|
702934
|
+
void ensureSessionSummary({
|
|
702935
|
+
repoRoot: targetRoot,
|
|
702936
|
+
sessionId: sid,
|
|
702937
|
+
config: { backendUrl: cfg.backendUrl, model: cfg.model, apiKey: cfg.apiKey }
|
|
702938
|
+
}).catch(() => {
|
|
702617
702939
|
});
|
|
702618
702940
|
}
|
|
702619
702941
|
sessions3.sort((a2, b) => String(b.lastActivity).localeCompare(String(a2.lastActivity)));
|
|
@@ -702777,6 +703099,7 @@ ${historyLines}
|
|
|
702777
703099
|
preview: session.preview ?? null,
|
|
702778
703100
|
source: session.source ?? "web",
|
|
702779
703101
|
projectRoot: session.projectRoot ?? null,
|
|
703102
|
+
transcript: session.transcript ?? null,
|
|
702780
703103
|
messages: publicMessages,
|
|
702781
703104
|
message_count: publicMessages.length,
|
|
702782
703105
|
tokens_in: session.tokensIn,
|
|
@@ -702816,6 +703139,36 @@ ${historyLines}
|
|
|
702816
703139
|
return;
|
|
702817
703140
|
}
|
|
702818
703141
|
}
|
|
703142
|
+
const summarizeMatch = pathname.match(
|
|
703143
|
+
/^\/v1\/chat\/sessions\/([^/]+)\/summarize$/
|
|
703144
|
+
);
|
|
703145
|
+
if (summarizeMatch && method === "POST") {
|
|
703146
|
+
if (!checkAuth(req3, res, "run")) {
|
|
703147
|
+
status = 401;
|
|
703148
|
+
return;
|
|
703149
|
+
}
|
|
703150
|
+
const sid = decodeURIComponent(summarizeMatch[1]);
|
|
703151
|
+
const body = await parseJsonBody(req3).catch(() => ({}));
|
|
703152
|
+
const queriedRoot = body.root || urlObj.searchParams.get("root");
|
|
703153
|
+
const targetRoot = queriedRoot && String(queriedRoot).trim() ? resolve66(String(queriedRoot).trim()) : getCurrentProject()?.root ?? process.cwd();
|
|
703154
|
+
const tuiId = sid.startsWith("tui:") ? sid.slice("tui:".length) : sid;
|
|
703155
|
+
const cfg = loadConfig();
|
|
703156
|
+
try {
|
|
703157
|
+
const result = await ensureSessionSummary({
|
|
703158
|
+
repoRoot: targetRoot,
|
|
703159
|
+
sessionId: tuiId,
|
|
703160
|
+
config: { backendUrl: cfg.backendUrl, model: cfg.model, apiKey: cfg.apiKey },
|
|
703161
|
+
force: body.force === true
|
|
703162
|
+
});
|
|
703163
|
+
jsonResponse(res, 200, { session_id: sid, title: result.title, summary: result.summary });
|
|
703164
|
+
} catch (err) {
|
|
703165
|
+
jsonResponse(res, 500, {
|
|
703166
|
+
error: err instanceof Error ? err.message : String(err),
|
|
703167
|
+
session_id: sid
|
|
703168
|
+
});
|
|
703169
|
+
}
|
|
703170
|
+
return;
|
|
703171
|
+
}
|
|
702819
703172
|
if (pathname === "/v1/models" && method === "GET") {
|
|
702820
703173
|
await handleV1Models(res, ollamaUrl);
|
|
702821
703174
|
return;
|
|
@@ -705322,6 +705675,7 @@ var init_serve = __esm({
|
|
|
705322
705675
|
init_chat_session();
|
|
705323
705676
|
init_usage_tracker();
|
|
705324
705677
|
init_omnius_directory();
|
|
705678
|
+
init_session_summary();
|
|
705325
705679
|
init_omnius_directory();
|
|
705326
705680
|
init_command_registry();
|
|
705327
705681
|
init_profiles();
|