@mrciphersmith/keryx 0.2.64 → 0.2.66
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/cli.js +476 -81
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -28105,6 +28105,332 @@ function looksLikeUnifiedDiff(text) {
|
|
|
28105
28105
|
}
|
|
28106
28106
|
return false;
|
|
28107
28107
|
}
|
|
28108
|
+
var CODE_LANG_ALIASES = {
|
|
28109
|
+
js: "javascript",
|
|
28110
|
+
mjs: "javascript",
|
|
28111
|
+
cjs: "javascript",
|
|
28112
|
+
jsx: "javascript",
|
|
28113
|
+
ts: "typescript",
|
|
28114
|
+
tsx: "typescript",
|
|
28115
|
+
py: "python",
|
|
28116
|
+
py3: "python",
|
|
28117
|
+
sh: "bash",
|
|
28118
|
+
shell: "bash",
|
|
28119
|
+
zsh: "bash",
|
|
28120
|
+
console: "bash",
|
|
28121
|
+
yml: "yaml",
|
|
28122
|
+
rb: "ruby",
|
|
28123
|
+
rs: "rust",
|
|
28124
|
+
kt: "kotlin",
|
|
28125
|
+
cs: "csharp",
|
|
28126
|
+
"c++": "cpp",
|
|
28127
|
+
cc: "cpp",
|
|
28128
|
+
cxx: "cpp",
|
|
28129
|
+
hpp: "cpp"
|
|
28130
|
+
};
|
|
28131
|
+
var GENERIC_KEYWORDS = new Set([
|
|
28132
|
+
"if",
|
|
28133
|
+
"else",
|
|
28134
|
+
"for",
|
|
28135
|
+
"while",
|
|
28136
|
+
"return",
|
|
28137
|
+
"function",
|
|
28138
|
+
"class",
|
|
28139
|
+
"const",
|
|
28140
|
+
"let",
|
|
28141
|
+
"var",
|
|
28142
|
+
"import",
|
|
28143
|
+
"export",
|
|
28144
|
+
"from",
|
|
28145
|
+
"true",
|
|
28146
|
+
"false",
|
|
28147
|
+
"null",
|
|
28148
|
+
"new",
|
|
28149
|
+
"this",
|
|
28150
|
+
"try",
|
|
28151
|
+
"catch",
|
|
28152
|
+
"throw",
|
|
28153
|
+
"switch",
|
|
28154
|
+
"case",
|
|
28155
|
+
"break",
|
|
28156
|
+
"continue",
|
|
28157
|
+
"default",
|
|
28158
|
+
"static",
|
|
28159
|
+
"public",
|
|
28160
|
+
"private"
|
|
28161
|
+
]);
|
|
28162
|
+
var CODE_LANG_KEYWORDS = {
|
|
28163
|
+
javascript: new Set([
|
|
28164
|
+
...GENERIC_KEYWORDS,
|
|
28165
|
+
"async",
|
|
28166
|
+
"await",
|
|
28167
|
+
"yield",
|
|
28168
|
+
"typeof",
|
|
28169
|
+
"instanceof",
|
|
28170
|
+
"in",
|
|
28171
|
+
"of",
|
|
28172
|
+
"void",
|
|
28173
|
+
"undefined",
|
|
28174
|
+
"super",
|
|
28175
|
+
"extends",
|
|
28176
|
+
"finally",
|
|
28177
|
+
"do",
|
|
28178
|
+
"delete"
|
|
28179
|
+
]),
|
|
28180
|
+
typescript: new Set([
|
|
28181
|
+
...GENERIC_KEYWORDS,
|
|
28182
|
+
"async",
|
|
28183
|
+
"await",
|
|
28184
|
+
"yield",
|
|
28185
|
+
"typeof",
|
|
28186
|
+
"instanceof",
|
|
28187
|
+
"in",
|
|
28188
|
+
"of",
|
|
28189
|
+
"void",
|
|
28190
|
+
"undefined",
|
|
28191
|
+
"super",
|
|
28192
|
+
"extends",
|
|
28193
|
+
"implements",
|
|
28194
|
+
"interface",
|
|
28195
|
+
"type",
|
|
28196
|
+
"enum",
|
|
28197
|
+
"namespace",
|
|
28198
|
+
"declare",
|
|
28199
|
+
"readonly",
|
|
28200
|
+
"abstract",
|
|
28201
|
+
"as",
|
|
28202
|
+
"satisfies",
|
|
28203
|
+
"finally",
|
|
28204
|
+
"do",
|
|
28205
|
+
"delete"
|
|
28206
|
+
]),
|
|
28207
|
+
python: new Set([
|
|
28208
|
+
"def",
|
|
28209
|
+
"return",
|
|
28210
|
+
"if",
|
|
28211
|
+
"elif",
|
|
28212
|
+
"else",
|
|
28213
|
+
"for",
|
|
28214
|
+
"while",
|
|
28215
|
+
"break",
|
|
28216
|
+
"continue",
|
|
28217
|
+
"class",
|
|
28218
|
+
"import",
|
|
28219
|
+
"from",
|
|
28220
|
+
"as",
|
|
28221
|
+
"try",
|
|
28222
|
+
"except",
|
|
28223
|
+
"finally",
|
|
28224
|
+
"raise",
|
|
28225
|
+
"with",
|
|
28226
|
+
"lambda",
|
|
28227
|
+
"yield",
|
|
28228
|
+
"pass",
|
|
28229
|
+
"None",
|
|
28230
|
+
"True",
|
|
28231
|
+
"False",
|
|
28232
|
+
"and",
|
|
28233
|
+
"or",
|
|
28234
|
+
"not",
|
|
28235
|
+
"in",
|
|
28236
|
+
"is",
|
|
28237
|
+
"global",
|
|
28238
|
+
"nonlocal",
|
|
28239
|
+
"assert",
|
|
28240
|
+
"async",
|
|
28241
|
+
"await",
|
|
28242
|
+
"del",
|
|
28243
|
+
"self"
|
|
28244
|
+
]),
|
|
28245
|
+
bash: new Set([
|
|
28246
|
+
"if",
|
|
28247
|
+
"then",
|
|
28248
|
+
"else",
|
|
28249
|
+
"elif",
|
|
28250
|
+
"fi",
|
|
28251
|
+
"for",
|
|
28252
|
+
"while",
|
|
28253
|
+
"do",
|
|
28254
|
+
"done",
|
|
28255
|
+
"case",
|
|
28256
|
+
"esac",
|
|
28257
|
+
"function",
|
|
28258
|
+
"return",
|
|
28259
|
+
"local",
|
|
28260
|
+
"export",
|
|
28261
|
+
"exit",
|
|
28262
|
+
"break",
|
|
28263
|
+
"continue",
|
|
28264
|
+
"in",
|
|
28265
|
+
"select",
|
|
28266
|
+
"until"
|
|
28267
|
+
]),
|
|
28268
|
+
go: new Set([
|
|
28269
|
+
"func",
|
|
28270
|
+
"return",
|
|
28271
|
+
"if",
|
|
28272
|
+
"else",
|
|
28273
|
+
"for",
|
|
28274
|
+
"range",
|
|
28275
|
+
"switch",
|
|
28276
|
+
"case",
|
|
28277
|
+
"default",
|
|
28278
|
+
"break",
|
|
28279
|
+
"continue",
|
|
28280
|
+
"package",
|
|
28281
|
+
"import",
|
|
28282
|
+
"var",
|
|
28283
|
+
"const",
|
|
28284
|
+
"type",
|
|
28285
|
+
"struct",
|
|
28286
|
+
"interface",
|
|
28287
|
+
"map",
|
|
28288
|
+
"chan",
|
|
28289
|
+
"go",
|
|
28290
|
+
"defer",
|
|
28291
|
+
"select",
|
|
28292
|
+
"fallthrough",
|
|
28293
|
+
"nil",
|
|
28294
|
+
"true",
|
|
28295
|
+
"false"
|
|
28296
|
+
]),
|
|
28297
|
+
rust: new Set([
|
|
28298
|
+
"fn",
|
|
28299
|
+
"let",
|
|
28300
|
+
"mut",
|
|
28301
|
+
"return",
|
|
28302
|
+
"if",
|
|
28303
|
+
"else",
|
|
28304
|
+
"for",
|
|
28305
|
+
"while",
|
|
28306
|
+
"loop",
|
|
28307
|
+
"match",
|
|
28308
|
+
"struct",
|
|
28309
|
+
"enum",
|
|
28310
|
+
"impl",
|
|
28311
|
+
"trait",
|
|
28312
|
+
"pub",
|
|
28313
|
+
"use",
|
|
28314
|
+
"mod",
|
|
28315
|
+
"crate",
|
|
28316
|
+
"self",
|
|
28317
|
+
"Self",
|
|
28318
|
+
"super",
|
|
28319
|
+
"const",
|
|
28320
|
+
"static",
|
|
28321
|
+
"async",
|
|
28322
|
+
"await",
|
|
28323
|
+
"move",
|
|
28324
|
+
"ref",
|
|
28325
|
+
"dyn",
|
|
28326
|
+
"where",
|
|
28327
|
+
"unsafe",
|
|
28328
|
+
"true",
|
|
28329
|
+
"false",
|
|
28330
|
+
"None",
|
|
28331
|
+
"Some",
|
|
28332
|
+
"Ok",
|
|
28333
|
+
"Err"
|
|
28334
|
+
]),
|
|
28335
|
+
json: new Set(["true", "false", "null"])
|
|
28336
|
+
};
|
|
28337
|
+
function codeCommentPrefix(normalizedLang) {
|
|
28338
|
+
switch (normalizedLang) {
|
|
28339
|
+
case "javascript":
|
|
28340
|
+
case "typescript":
|
|
28341
|
+
case "go":
|
|
28342
|
+
case "rust":
|
|
28343
|
+
case "java":
|
|
28344
|
+
case "c":
|
|
28345
|
+
case "cpp":
|
|
28346
|
+
case "csharp":
|
|
28347
|
+
case "swift":
|
|
28348
|
+
case "kotlin":
|
|
28349
|
+
case "scala":
|
|
28350
|
+
case "php":
|
|
28351
|
+
return "//";
|
|
28352
|
+
case "python":
|
|
28353
|
+
case "bash":
|
|
28354
|
+
case "ruby":
|
|
28355
|
+
case "yaml":
|
|
28356
|
+
case "toml":
|
|
28357
|
+
case "r":
|
|
28358
|
+
case "perl":
|
|
28359
|
+
return "#";
|
|
28360
|
+
case "sql":
|
|
28361
|
+
case "lua":
|
|
28362
|
+
case "haskell":
|
|
28363
|
+
return "--";
|
|
28364
|
+
default:
|
|
28365
|
+
return "";
|
|
28366
|
+
}
|
|
28367
|
+
}
|
|
28368
|
+
function normalizeCodeLang(lang) {
|
|
28369
|
+
const key = lang.trim().toLowerCase();
|
|
28370
|
+
return CODE_LANG_ALIASES[key] ?? key;
|
|
28371
|
+
}
|
|
28372
|
+
var CODE_WORD_OR_NUMBER = /[A-Za-z_$][A-Za-z0-9_$]*|\d+(?:\.\d+)?/g;
|
|
28373
|
+
function tokenizeCodeWords(text, keywords) {
|
|
28374
|
+
const tokens = [];
|
|
28375
|
+
let last = 0;
|
|
28376
|
+
CODE_WORD_OR_NUMBER.lastIndex = 0;
|
|
28377
|
+
let m;
|
|
28378
|
+
while ((m = CODE_WORD_OR_NUMBER.exec(text)) !== null) {
|
|
28379
|
+
if (m.index > last) {
|
|
28380
|
+
tokens.push({ kind: "plain", text: text.slice(last, m.index) });
|
|
28381
|
+
}
|
|
28382
|
+
const word = m[0];
|
|
28383
|
+
if (/^[0-9]/.test(word)) {
|
|
28384
|
+
tokens.push({ kind: "number", text: word });
|
|
28385
|
+
} else if (keywords.has(word)) {
|
|
28386
|
+
tokens.push({ kind: "keyword", text: word });
|
|
28387
|
+
} else {
|
|
28388
|
+
tokens.push({ kind: "plain", text: word });
|
|
28389
|
+
}
|
|
28390
|
+
last = m.index + word.length;
|
|
28391
|
+
}
|
|
28392
|
+
if (last < text.length) {
|
|
28393
|
+
tokens.push({ kind: "plain", text: text.slice(last) });
|
|
28394
|
+
}
|
|
28395
|
+
return tokens;
|
|
28396
|
+
}
|
|
28397
|
+
function tokenizeCodeLine(line, lang) {
|
|
28398
|
+
const normalized = normalizeCodeLang(lang);
|
|
28399
|
+
const keywords = CODE_LANG_KEYWORDS[normalized] ?? GENERIC_KEYWORDS;
|
|
28400
|
+
const commentPrefix = codeCommentPrefix(normalized);
|
|
28401
|
+
const tokens = [];
|
|
28402
|
+
let plainBuf = "";
|
|
28403
|
+
const flushPlain = () => {
|
|
28404
|
+
if (plainBuf.length > 0) {
|
|
28405
|
+
tokens.push(...tokenizeCodeWords(plainBuf, keywords));
|
|
28406
|
+
plainBuf = "";
|
|
28407
|
+
}
|
|
28408
|
+
};
|
|
28409
|
+
let i = 0;
|
|
28410
|
+
while (i < line.length) {
|
|
28411
|
+
if (commentPrefix.length > 0 && line.startsWith(commentPrefix, i)) {
|
|
28412
|
+
flushPlain();
|
|
28413
|
+
tokens.push({ kind: "comment", text: line.slice(i) });
|
|
28414
|
+
break;
|
|
28415
|
+
}
|
|
28416
|
+
const ch = line[i];
|
|
28417
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
28418
|
+
flushPlain();
|
|
28419
|
+
let j = i + 1;
|
|
28420
|
+
while (j < line.length && line[j] !== ch) {
|
|
28421
|
+
j += line[j] === "\\" ? 2 : 1;
|
|
28422
|
+
}
|
|
28423
|
+
j = Math.min(j + 1, line.length);
|
|
28424
|
+
tokens.push({ kind: "string", text: line.slice(i, j) });
|
|
28425
|
+
i = j;
|
|
28426
|
+
continue;
|
|
28427
|
+
}
|
|
28428
|
+
plainBuf += ch;
|
|
28429
|
+
i += 1;
|
|
28430
|
+
}
|
|
28431
|
+
flushPlain();
|
|
28432
|
+
return tokens;
|
|
28433
|
+
}
|
|
28108
28434
|
function payloadKind(lang, _lineCount) {
|
|
28109
28435
|
const normalized = lang.toLowerCase();
|
|
28110
28436
|
if (MARKDOWN_LANGS.has(normalized)) {
|
|
@@ -28121,6 +28447,18 @@ function blockLabel({ kind, lineCount, collapsed, hint }) {
|
|
|
28121
28447
|
const suffix = hint !== undefined && hint.length > 0 ? ` \xB7 ${hint}` : "";
|
|
28122
28448
|
return `${marker} ${kind} (${lineCount} ${unit})${suffix}`;
|
|
28123
28449
|
}
|
|
28450
|
+
function summarizeSubmittedLine(line) {
|
|
28451
|
+
const normalized = line.replace(/\r\n/g, `
|
|
28452
|
+
`).replace(/\r/g, `
|
|
28453
|
+
`);
|
|
28454
|
+
const nonEmpty = normalized.split(`
|
|
28455
|
+
`).filter((linePart) => linePart.length > 0);
|
|
28456
|
+
if (nonEmpty.length <= 1) {
|
|
28457
|
+
return line;
|
|
28458
|
+
}
|
|
28459
|
+
const [first, ...rest] = nonEmpty;
|
|
28460
|
+
return `${first} [+ ${rest.length} pasted line${rest.length === 1 ? "" : "s"}]`;
|
|
28461
|
+
}
|
|
28124
28462
|
var ZERO_WIDTH = /^[\u0300-\u036F\u200B-\u200F\uFE00-\uFE0F\u2060-\u2064]$/u;
|
|
28125
28463
|
var WIDE_RANGES = [
|
|
28126
28464
|
[4352, 4447],
|
|
@@ -53556,7 +53894,7 @@ import { spawnSync as spawnSync2 } from "child_process";
|
|
|
53556
53894
|
// package.json
|
|
53557
53895
|
var package_default = {
|
|
53558
53896
|
name: "@mrciphersmith/keryx",
|
|
53559
|
-
version: "0.2.
|
|
53897
|
+
version: "0.2.66",
|
|
53560
53898
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
53561
53899
|
private: false,
|
|
53562
53900
|
publishConfig: {
|
|
@@ -53919,7 +54257,7 @@ function diffChunks(otui, text) {
|
|
|
53919
54257
|
}
|
|
53920
54258
|
return out;
|
|
53921
54259
|
}
|
|
53922
|
-
function
|
|
54260
|
+
function flatDimChunks(otui, text) {
|
|
53923
54261
|
const out = [];
|
|
53924
54262
|
for (const [index, line] of splitLines(text).entries()) {
|
|
53925
54263
|
if (index > 0) {
|
|
@@ -53930,6 +54268,34 @@ function codeChunks(otui, text) {
|
|
|
53930
54268
|
}
|
|
53931
54269
|
return out;
|
|
53932
54270
|
}
|
|
54271
|
+
function codeChunks(otui, text, lang) {
|
|
54272
|
+
const out = [];
|
|
54273
|
+
for (const [index, line] of splitLines(text).entries()) {
|
|
54274
|
+
if (index > 0) {
|
|
54275
|
+
out.push(...otui.stringToStyledText(`
|
|
54276
|
+
`).chunks);
|
|
54277
|
+
}
|
|
54278
|
+
for (const token of tokenizeCodeLine(line, lang)) {
|
|
54279
|
+
switch (token.kind) {
|
|
54280
|
+
case "comment":
|
|
54281
|
+
out.push(otui.dim(token.text));
|
|
54282
|
+
break;
|
|
54283
|
+
case "string":
|
|
54284
|
+
out.push(otui.green(token.text));
|
|
54285
|
+
break;
|
|
54286
|
+
case "number":
|
|
54287
|
+
out.push(otui.yellow(token.text));
|
|
54288
|
+
break;
|
|
54289
|
+
case "keyword":
|
|
54290
|
+
out.push(otui.cyan(token.text));
|
|
54291
|
+
break;
|
|
54292
|
+
default:
|
|
54293
|
+
out.push(...otui.stringToStyledText(token.text).chunks);
|
|
54294
|
+
}
|
|
54295
|
+
}
|
|
54296
|
+
}
|
|
54297
|
+
return out;
|
|
54298
|
+
}
|
|
53933
54299
|
function payloadChunks(otui, text, lang = "") {
|
|
53934
54300
|
const kind2 = payloadKind(lang, lineCountOf(text));
|
|
53935
54301
|
if (kind2 === "diff" || looksLikeUnifiedDiff(text)) {
|
|
@@ -53938,7 +54304,7 @@ function payloadChunks(otui, text, lang = "") {
|
|
|
53938
54304
|
if (kind2 === "markdown" || lang.length === 0) {
|
|
53939
54305
|
return markdownToChunks(otui, text);
|
|
53940
54306
|
}
|
|
53941
|
-
return codeChunks(otui, text);
|
|
54307
|
+
return codeChunks(otui, text, lang);
|
|
53942
54308
|
}
|
|
53943
54309
|
function createSegmentView(otui, renderer, parent, segment) {
|
|
53944
54310
|
viewSeq += 1;
|
|
@@ -53966,7 +54332,7 @@ function createSegmentView(otui, renderer, parent, segment) {
|
|
|
53966
54332
|
}
|
|
53967
54333
|
const tag = (lang, body2) => {
|
|
53968
54334
|
const n = lineCountOf(body2);
|
|
53969
|
-
return `${lang.length > 0 ? lang : "text"} \xB7 ${n} ${n === 1 ? "line" : "lines"}`;
|
|
54335
|
+
return `${lang.length > 0 ? lang : "text"} \xB7 ${n} ${n === 1 ? "line" : "lines"} \xB7 y copy`;
|
|
53970
54336
|
};
|
|
53971
54337
|
const frameWidth = (lang, body2) => Math.max(hugWidth(body2, FRAME_CHROME), hugWidth(tag(lang, body2), FRAME_CHROME));
|
|
53972
54338
|
const frame = new otui.BoxRenderable(renderer, {
|
|
@@ -54012,6 +54378,7 @@ function createSegmentView(otui, renderer, parent, segment) {
|
|
|
54012
54378
|
var messageSeq = 0;
|
|
54013
54379
|
function createAssistantMessageStream(otui, renderer, parent) {
|
|
54014
54380
|
let message2;
|
|
54381
|
+
let lastCode;
|
|
54015
54382
|
const start = () => {
|
|
54016
54383
|
messageSeq += 1;
|
|
54017
54384
|
const container = new otui.BoxRenderable(renderer, {
|
|
@@ -54040,6 +54407,11 @@ function createAssistantMessageStream(otui, renderer, parent) {
|
|
|
54040
54407
|
stale.destroy();
|
|
54041
54408
|
}
|
|
54042
54409
|
m.frozen = frozen;
|
|
54410
|
+
for (const segment of segments2) {
|
|
54411
|
+
if (segment.kind === "code") {
|
|
54412
|
+
lastCode = { lang: segment.lang, body: segment.body };
|
|
54413
|
+
}
|
|
54414
|
+
}
|
|
54043
54415
|
};
|
|
54044
54416
|
return {
|
|
54045
54417
|
push: (chunk) => {
|
|
@@ -54077,7 +54449,8 @@ function createAssistantMessageStream(otui, renderer, parent) {
|
|
|
54077
54449
|
parent.remove(message2.container);
|
|
54078
54450
|
} catch {}
|
|
54079
54451
|
message2 = undefined;
|
|
54080
|
-
}
|
|
54452
|
+
},
|
|
54453
|
+
lastCodeSegment: () => lastCode
|
|
54081
54454
|
};
|
|
54082
54455
|
}
|
|
54083
54456
|
function createBlockView(otui, renderer, parent, block, options = {}) {
|
|
@@ -54134,7 +54507,7 @@ function createBlockView(otui, renderer, parent, block, options = {}) {
|
|
|
54134
54507
|
return;
|
|
54135
54508
|
}
|
|
54136
54509
|
const shown = clipBody(text, options.maxLines ?? MAX_BODY_LINES);
|
|
54137
|
-
const content = new otui.StyledText(options.dim === true ?
|
|
54510
|
+
const content = new otui.StyledText(options.dim === true ? flatDimChunks(otui, shown) : payloadChunks(otui, shown));
|
|
54138
54511
|
painted = text;
|
|
54139
54512
|
if (bodyText !== undefined) {
|
|
54140
54513
|
bodyText.content = content;
|
|
@@ -54542,7 +54915,11 @@ function mountTab(state, input2, tabId) {
|
|
|
54542
54915
|
unmountActiveTab(state);
|
|
54543
54916
|
state.active = tabId;
|
|
54544
54917
|
paintTabs(state);
|
|
54545
|
-
const
|
|
54918
|
+
const size = resolveModalPanelSize(state.chrome.renderer.width, state.chrome.renderer.height);
|
|
54919
|
+
const cleanup = input2.renderTab(tabId, state.body, {
|
|
54920
|
+
width: resolveModalInnerWidth(size.width),
|
|
54921
|
+
height: modalBodyRows(size.height)
|
|
54922
|
+
});
|
|
54546
54923
|
state.tabCleanup = typeof cleanup === "function" ? cleanup : undefined;
|
|
54547
54924
|
}
|
|
54548
54925
|
function closeHost(state, opts) {
|
|
@@ -57575,6 +57952,10 @@ function formatTokens(n) {
|
|
|
57575
57952
|
|
|
57576
57953
|
// src/tui/games/constants.ts
|
|
57577
57954
|
var GAME_MODEL_TIMEOUT_MS = 60000;
|
|
57955
|
+
var PROMPT_MIN_ROWS = 5;
|
|
57956
|
+
var PROMPT_MAX_ROWS = 14;
|
|
57957
|
+
var PANEL_FIXED_ROWS = 7;
|
|
57958
|
+
var PANEL_MIN_ROWS = PANEL_FIXED_ROWS + PROMPT_MIN_ROWS;
|
|
57578
57959
|
var GAMES_FOOTER = [
|
|
57579
57960
|
{ key: "arrows", label: "move" },
|
|
57580
57961
|
{ key: "enter", label: "place" },
|
|
@@ -57736,14 +58117,39 @@ var GAME_CELL_GAP = 1;
|
|
|
57736
58117
|
var GAME_BOARD_CHROME_X = 4;
|
|
57737
58118
|
var GAME_CELL_SIZES = {
|
|
57738
58119
|
large: { width: 9, height: 5 },
|
|
57739
|
-
|
|
58120
|
+
medium: { width: 7, height: 4 },
|
|
58121
|
+
small: { width: 5, height: 3 },
|
|
58122
|
+
tiny: { width: 3, height: 2 }
|
|
57740
58123
|
};
|
|
57741
58124
|
function gameBoardWidth(cellWidth) {
|
|
57742
58125
|
return cellWidth * 3 + GAME_CELL_GAP * 2 + GAME_BOARD_CHROME_X;
|
|
57743
58126
|
}
|
|
57744
|
-
function
|
|
57745
|
-
|
|
57746
|
-
|
|
58127
|
+
function boardRows(cellHeight) {
|
|
58128
|
+
return cellHeight * 3 + 2;
|
|
58129
|
+
}
|
|
58130
|
+
function boardRegionRows(cellHeight) {
|
|
58131
|
+
return boardRows(cellHeight) + 4;
|
|
58132
|
+
}
|
|
58133
|
+
function resolveCellSize(availableWidth, availableHeight) {
|
|
58134
|
+
const candidates = [
|
|
58135
|
+
GAME_CELL_SIZES.large,
|
|
58136
|
+
GAME_CELL_SIZES.medium,
|
|
58137
|
+
GAME_CELL_SIZES.small,
|
|
58138
|
+
GAME_CELL_SIZES.tiny
|
|
58139
|
+
];
|
|
58140
|
+
for (const size of candidates) {
|
|
58141
|
+
if (gameBoardWidth(size.width) <= availableWidth && boardRegionRows(size.height) <= availableHeight) {
|
|
58142
|
+
return size;
|
|
58143
|
+
}
|
|
58144
|
+
}
|
|
58145
|
+
return GAME_CELL_SIZES.tiny;
|
|
58146
|
+
}
|
|
58147
|
+
function resolveGameBudget(availableWidth, bodyRows) {
|
|
58148
|
+
const boardBudgetRows = Math.max(1, bodyRows - PANEL_MIN_ROWS);
|
|
58149
|
+
const cellSize = resolveCellSize(availableWidth, boardBudgetRows);
|
|
58150
|
+
const boardUsedRows = boardRegionRows(cellSize.height);
|
|
58151
|
+
const promptRows = Math.max(PROMPT_MIN_ROWS, Math.min(PROMPT_MAX_ROWS, bodyRows - PANEL_FIXED_ROWS - boardUsedRows));
|
|
58152
|
+
return { cellSize, boardUsedRows, promptRows, boardBudgetRows };
|
|
57747
58153
|
}
|
|
57748
58154
|
|
|
57749
58155
|
// src/tui/games/tic-tac-toe/render.ts
|
|
@@ -57763,7 +58169,7 @@ function render2(state, ctx) {
|
|
|
57763
58169
|
const core = ctx.core;
|
|
57764
58170
|
const r = ctx.renderer;
|
|
57765
58171
|
const theme = ctx.theme;
|
|
57766
|
-
const cellSize = resolveCellSize(ctx.width);
|
|
58172
|
+
const cellSize = resolveCellSize(ctx.width, ctx.height);
|
|
57767
58173
|
const wrap2 = new core.BoxRenderable(r, {
|
|
57768
58174
|
id: "game-wrap",
|
|
57769
58175
|
width: "100%",
|
|
@@ -57925,12 +58331,6 @@ function renderAgentPanel(game, parent, core, renderer, args2) {
|
|
|
57925
58331
|
paddingRight: 1,
|
|
57926
58332
|
...extra
|
|
57927
58333
|
});
|
|
57928
|
-
const statRow = (owner, label, value, id, valueFg = theme.text) => {
|
|
57929
|
-
const rowBox = box({ flexDirection: "row", gap: 1 });
|
|
57930
|
-
rowBox.add(text({ content: label, fg: theme.muted }));
|
|
57931
|
-
rowBox.add(text({ id, content: value, fg: valueFg }));
|
|
57932
|
-
owner.add(rowBox);
|
|
57933
|
-
};
|
|
57934
58334
|
const idle = args2.notice === undefined || args2.notice === "";
|
|
57935
58335
|
const statusCard = card("game-status-card", { width: "100%", marginTop: 1 });
|
|
57936
58336
|
statusCard.add(text({
|
|
@@ -57938,12 +58338,35 @@ function renderAgentPanel(game, parent, core, renderer, args2) {
|
|
|
57938
58338
|
content: args2.modelBusy ? "agent is thinking\u2026" : idle ? "waiting for your move" : args2.notice,
|
|
57939
58339
|
fg: args2.modelBusy ? theme.focus : idle ? theme.text : theme.error
|
|
57940
58340
|
}));
|
|
58341
|
+
const lt = args2.lastTurn;
|
|
58342
|
+
const tot = args2.totals;
|
|
58343
|
+
const shownModel = lt !== undefined && lt.provider !== "\u2013" ? truncate4(`${lt.provider}/${lt.model}`, MODEL_MAX) : args2.modelParam;
|
|
58344
|
+
statusCard.add(text({ id: "game-stats-model", content: `model: ${shownModel}`, fg: theme.muted }));
|
|
58345
|
+
const lastCore = lt === undefined ? "no turns yet" : `${formatMs(lt.totalMs)} \xB7 in ${formatTokens(lt.inputTokens)}/out ${formatTokens(lt.outputTokens)}`;
|
|
58346
|
+
const flags = [];
|
|
58347
|
+
if (lt?.reasoning) {
|
|
58348
|
+
flags.push("reasoning");
|
|
58349
|
+
}
|
|
58350
|
+
if (lt?.localFallback) {
|
|
58351
|
+
flags.push("fallback");
|
|
58352
|
+
}
|
|
58353
|
+
if (lt?.error) {
|
|
58354
|
+
flags.push("error");
|
|
58355
|
+
}
|
|
58356
|
+
statusCard.add(text({
|
|
58357
|
+
id: "game-stats-line",
|
|
58358
|
+
content: `last: ${lastCore}${flags.length > 0 ? ` \xB7 ${flags.join(", ")}` : ""} \xB7 session: ${tot.turns} turn${tot.turns === 1 ? "" : "s"} \xB7 ${tot.localFallbacks} fb \xB7 ${tot.errors} err \xB7 in ${formatTokens(tot.inputTokens)}/out ${formatTokens(tot.outputTokens)}`,
|
|
58359
|
+
fg: theme.muted
|
|
58360
|
+
}));
|
|
57941
58361
|
parent.add(statusCard);
|
|
57942
58362
|
const sysCard = new core.ScrollBoxRenderable(renderer, {
|
|
57943
58363
|
id: "game-system-card",
|
|
57944
58364
|
width: "100%",
|
|
57945
|
-
|
|
57946
|
-
minHeight:
|
|
58365
|
+
height: args2.promptRows,
|
|
58366
|
+
minHeight: args2.promptRows,
|
|
58367
|
+
maxHeight: args2.promptRows,
|
|
58368
|
+
flexShrink: 0,
|
|
58369
|
+
flexGrow: 0,
|
|
57947
58370
|
marginTop: 1,
|
|
57948
58371
|
border: true,
|
|
57949
58372
|
borderStyle: "rounded",
|
|
@@ -57954,41 +58377,11 @@ function renderAgentPanel(game, parent, core, renderer, args2) {
|
|
|
57954
58377
|
scrollY: true,
|
|
57955
58378
|
contentOptions: { flexDirection: "column" }
|
|
57956
58379
|
});
|
|
58380
|
+
sysCard.add(text({ id: "game-user-title", content: "your turn prompt (board)", fg: theme.muted }));
|
|
58381
|
+
sysCard.add(text({ id: "game-user-prompt", content: args2.userPrompt, fg: theme.muted }));
|
|
57957
58382
|
sysCard.add(text({ id: "game-system-title", content: "system prompt", fg: theme.muted }));
|
|
57958
58383
|
sysCard.add(text({ id: "game-system", content: game.systemPrompt(), fg: theme.muted }));
|
|
57959
58384
|
parent.add(sysCard);
|
|
57960
|
-
const lt = args2.lastTurn;
|
|
57961
|
-
const tot = args2.totals;
|
|
57962
|
-
const statsRow = box({ id: "game-stats-row", width: "100%", flexDirection: "row", gap: 1, marginTop: 1 });
|
|
57963
|
-
const lastTurnCard = card("game-last-turn", { flexGrow: 1, flexShrink: 0 });
|
|
57964
|
-
lastTurnCard.add(text({ id: "game-last-turn-title", content: "last turn", fg: theme.muted }));
|
|
57965
|
-
if (lt === undefined) {
|
|
57966
|
-
lastTurnCard.add(text({ id: "game-stats-empty", content: "no turns yet", fg: theme.muted }));
|
|
57967
|
-
} else {
|
|
57968
|
-
const model = lt.provider === "\u2013" ? "\u2013" : truncate4(`${lt.provider}/${lt.model}`, MODEL_MAX);
|
|
57969
|
-
statRow(lastTurnCard, "model", model, "game-stats-model");
|
|
57970
|
-
statRow(lastTurnCard, "first byte", formatMs(lt.latencyMs), "game-stats-latency");
|
|
57971
|
-
statRow(lastTurnCard, "total", formatMs(lt.totalMs), "game-stats-total");
|
|
57972
|
-
statRow(lastTurnCard, "tokens", `in ${formatTokens(lt.inputTokens)} \xB7 out ${formatTokens(lt.outputTokens)}`, "game-stats-tokens");
|
|
57973
|
-
if (lt.reasoning) {
|
|
57974
|
-
statRow(lastTurnCard, "reasoning", "yes", "game-stats-reasoning", theme.focus);
|
|
57975
|
-
}
|
|
57976
|
-
if (lt.localFallback) {
|
|
57977
|
-
statRow(lastTurnCard, "fallback", "local", "game-stats-fallback", theme.error);
|
|
57978
|
-
}
|
|
57979
|
-
if (lt.error) {
|
|
57980
|
-
statRow(lastTurnCard, "error", "yes", "game-stats-error", theme.error);
|
|
57981
|
-
}
|
|
57982
|
-
}
|
|
57983
|
-
const sessionCard = card("game-session", { flexGrow: 1, flexShrink: 0 });
|
|
57984
|
-
sessionCard.add(text({ id: "game-session-title", content: "session", fg: theme.muted }));
|
|
57985
|
-
statRow(sessionCard, "turns", String(tot.turns), "game-session-turns");
|
|
57986
|
-
statRow(sessionCard, "fallbacks", String(tot.localFallbacks), "game-session-fallbacks");
|
|
57987
|
-
statRow(sessionCard, "errors", String(tot.errors), "game-session-errors");
|
|
57988
|
-
statRow(sessionCard, "tokens", `in ${formatTokens(tot.inputTokens)} \xB7 out ${formatTokens(tot.outputTokens)}`, "game-session-tokens");
|
|
57989
|
-
statsRow.add(lastTurnCard);
|
|
57990
|
-
statsRow.add(sessionCard);
|
|
57991
|
-
parent.add(statsRow);
|
|
57992
58385
|
}
|
|
57993
58386
|
|
|
57994
58387
|
// src/tui/games/otui.ts
|
|
@@ -58023,6 +58416,8 @@ function presentGamesModal(openModalFn, otui, chrome, options = {}, registry = c
|
|
|
58023
58416
|
let unsubscribeKey;
|
|
58024
58417
|
let bodyRef;
|
|
58025
58418
|
let bodyWidth = 0;
|
|
58419
|
+
let bodyHeight = 0;
|
|
58420
|
+
const modelParam = `${options.provider ?? "auto"}/${options.model ?? "auto"}`;
|
|
58026
58421
|
const stateOf = (id) => {
|
|
58027
58422
|
const game = registry.get(id);
|
|
58028
58423
|
if (game === undefined) {
|
|
@@ -58053,19 +58448,24 @@ function presentGamesModal(openModalFn, otui, chrome, options = {}, registry = c
|
|
|
58053
58448
|
return;
|
|
58054
58449
|
}
|
|
58055
58450
|
const state = stateOf(activeId);
|
|
58451
|
+
const budget = resolveGameBudget(bodyWidth, Math.max(1, bodyHeight));
|
|
58056
58452
|
const ctx = {
|
|
58057
58453
|
core,
|
|
58058
58454
|
renderer,
|
|
58059
58455
|
theme: getTheme(),
|
|
58060
58456
|
parent: bodyRef,
|
|
58061
|
-
width: bodyWidth
|
|
58457
|
+
width: bodyWidth,
|
|
58458
|
+
height: budget.boardBudgetRows
|
|
58062
58459
|
};
|
|
58063
58460
|
game.render(state, ctx);
|
|
58064
58461
|
renderAgentPanel(game, bodyRef, core, renderer, {
|
|
58065
58462
|
notice,
|
|
58066
58463
|
modelBusy,
|
|
58067
58464
|
lastTurn: lastTurn.get(activeId),
|
|
58068
|
-
totals: totalsOf(activeId)
|
|
58465
|
+
totals: totalsOf(activeId),
|
|
58466
|
+
userPrompt: game.stateForModel(state),
|
|
58467
|
+
promptRows: budget.promptRows,
|
|
58468
|
+
modelParam
|
|
58069
58469
|
});
|
|
58070
58470
|
};
|
|
58071
58471
|
const restart = () => {
|
|
@@ -58172,6 +58572,7 @@ function presentGamesModal(openModalFn, otui, chrome, options = {}, registry = c
|
|
|
58172
58572
|
}
|
|
58173
58573
|
bodyRef = body;
|
|
58174
58574
|
bodyWidth = ctx.width;
|
|
58575
|
+
bodyHeight = ctx.height;
|
|
58175
58576
|
paint();
|
|
58176
58577
|
},
|
|
58177
58578
|
onClose: () => {
|
|
@@ -61712,7 +62113,8 @@ function createTuiAgentIo(otui, renderer, transcript) {
|
|
|
61712
62113
|
onSystem: (text) => append(text.includes("[error]") ? otui.t`${otui.red(text)}` : otui.t`${otui.dim(text)}`),
|
|
61713
62114
|
resetStream: () => {
|
|
61714
62115
|
messages.reset();
|
|
61715
|
-
}
|
|
62116
|
+
},
|
|
62117
|
+
lastCodeSegment: () => messages.lastCodeSegment()
|
|
61716
62118
|
};
|
|
61717
62119
|
}
|
|
61718
62120
|
function attachBlockIo(io, addBlock, chrome = {}) {
|
|
@@ -62898,6 +63300,23 @@ async function launchTuiAgentShell(opts) {
|
|
|
62898
63300
|
const newestBlock = (kind2) => nav.newest(kind2);
|
|
62899
63301
|
const toggleNewestBlock = (kind2) => nav.toggleNewest(kind2);
|
|
62900
63302
|
const copyBlock = (id) => nav.copy(id);
|
|
63303
|
+
const copyNewestOrLastCode = () => {
|
|
63304
|
+
const target = newestBlock();
|
|
63305
|
+
if (target !== undefined) {
|
|
63306
|
+
return copyBlock(target.id);
|
|
63307
|
+
}
|
|
63308
|
+
const code = io.lastCodeSegment();
|
|
63309
|
+
if (code === undefined) {
|
|
63310
|
+
return false;
|
|
63311
|
+
}
|
|
63312
|
+
try {
|
|
63313
|
+
r.copyToClipboardOSC52(code.body);
|
|
63314
|
+
chrome.showToast("Copied to clipboard");
|
|
63315
|
+
return true;
|
|
63316
|
+
} catch {
|
|
63317
|
+
return false;
|
|
63318
|
+
}
|
|
63319
|
+
};
|
|
62901
63320
|
const addBlock = (input3, options = {}) => {
|
|
62902
63321
|
const id = blockMount.add(input3, options);
|
|
62903
63322
|
nav.paint(id);
|
|
@@ -63889,17 +64308,6 @@ Staying in the current session.
|
|
|
63889
64308
|
} catch {}
|
|
63890
64309
|
}, 12000);
|
|
63891
64310
|
};
|
|
63892
|
-
const summarizeSubmittedLine = (line) => {
|
|
63893
|
-
const normalized = line.replace(/\r\n/g, `
|
|
63894
|
-
`).replace(/\r/g, `
|
|
63895
|
-
`);
|
|
63896
|
-
const count = normalized.split(`
|
|
63897
|
-
`).filter((linePart) => linePart.length > 0).length;
|
|
63898
|
-
if (count <= 1) {
|
|
63899
|
-
return line;
|
|
63900
|
-
}
|
|
63901
|
-
return `[pasted ${count} lines]`;
|
|
63902
|
-
};
|
|
63903
64311
|
const spawnSideWorker = (question, displayQuestion = question) => {
|
|
63904
64312
|
sideQueue.push({ question, displayQuestion });
|
|
63905
64313
|
if (sideQueue.length > 1 || sideWorkerRunning) {
|
|
@@ -64112,8 +64520,7 @@ Staying in the current session.
|
|
|
64112
64520
|
return;
|
|
64113
64521
|
}
|
|
64114
64522
|
case "copy": {
|
|
64115
|
-
|
|
64116
|
-
if (target === undefined || !copyBlock(target.id)) {
|
|
64523
|
+
if (!copyNewestOrLastCode()) {
|
|
64117
64524
|
io.onSystem?.(`Nothing to copy yet.
|
|
64118
64525
|
`);
|
|
64119
64526
|
}
|
|
@@ -64372,8 +64779,7 @@ Staying in the current session.
|
|
|
64372
64779
|
return;
|
|
64373
64780
|
}
|
|
64374
64781
|
if (command.name === "/copy") {
|
|
64375
|
-
|
|
64376
|
-
if (target === undefined || !copyBlock(target.id)) {
|
|
64782
|
+
if (!copyNewestOrLastCode()) {
|
|
64377
64783
|
io.onSystem?.(`Nothing to copy yet.
|
|
64378
64784
|
`);
|
|
64379
64785
|
}
|
|
@@ -64856,17 +65262,6 @@ async function mountChatShell(otui, renderer, opts) {
|
|
|
64856
65262
|
chrome.setStatus(label());
|
|
64857
65263
|
sbModel.content = otui.t`${otui.dim(label())}`;
|
|
64858
65264
|
};
|
|
64859
|
-
const summarizeSubmittedLine = (line) => {
|
|
64860
|
-
const normalized = line.replace(/\r\n/g, `
|
|
64861
|
-
`).replace(/\r/g, `
|
|
64862
|
-
`);
|
|
64863
|
-
const count = normalized.split(`
|
|
64864
|
-
`).filter((linePart) => linePart.length > 0).length;
|
|
64865
|
-
if (count <= 1) {
|
|
64866
|
-
return line;
|
|
64867
|
-
}
|
|
64868
|
-
return `[pasted ${count} lines]`;
|
|
64869
|
-
};
|
|
64870
65265
|
const bridge = createChatBridge({
|
|
64871
65266
|
onAccepted: (line) => {
|
|
64872
65267
|
const displayLine = line.startsWith("/") ? line : summarizeSubmittedLine(line);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.66",
|
|
4
4
|
"description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|