@mrciphersmith/keryx 0.2.59 → 0.2.60
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 +86 -25
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -53454,7 +53454,7 @@ import { spawnSync as spawnSync2 } from "child_process";
|
|
|
53454
53454
|
// package.json
|
|
53455
53455
|
var package_default = {
|
|
53456
53456
|
name: "@mrciphersmith/keryx",
|
|
53457
|
-
version: "0.2.
|
|
53457
|
+
version: "0.2.60",
|
|
53458
53458
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
53459
53459
|
private: false,
|
|
53460
53460
|
publishConfig: {
|
|
@@ -57441,6 +57441,31 @@ function checkWinner(board) {
|
|
|
57441
57441
|
}
|
|
57442
57442
|
return null;
|
|
57443
57443
|
}
|
|
57444
|
+
function freeCells(board) {
|
|
57445
|
+
return board.flatMap((cell, index) => cell === null ? [index] : []);
|
|
57446
|
+
}
|
|
57447
|
+
function bestLocalMove(board, mark) {
|
|
57448
|
+
const free = freeCells(board);
|
|
57449
|
+
if (free.length === 0) {
|
|
57450
|
+
return;
|
|
57451
|
+
}
|
|
57452
|
+
const opponent = mark === "X" ? "O" : "X";
|
|
57453
|
+
for (const candidate of [mark, opponent]) {
|
|
57454
|
+
for (const index of free) {
|
|
57455
|
+
const next = board.slice();
|
|
57456
|
+
next[index] = candidate;
|
|
57457
|
+
if (checkWinner(next)?.winner === candidate) {
|
|
57458
|
+
return index;
|
|
57459
|
+
}
|
|
57460
|
+
}
|
|
57461
|
+
}
|
|
57462
|
+
for (const index of [4, 0, 2, 6, 8]) {
|
|
57463
|
+
if (board[index] === null) {
|
|
57464
|
+
return index;
|
|
57465
|
+
}
|
|
57466
|
+
}
|
|
57467
|
+
return free[0];
|
|
57468
|
+
}
|
|
57444
57469
|
function placeMark(board, index, mark) {
|
|
57445
57470
|
if (index < 0 || index > 8 || board[index] !== null) {
|
|
57446
57471
|
return;
|
|
@@ -57482,7 +57507,8 @@ function gameSystemPrompt() {
|
|
|
57482
57507
|
"3 4 5",
|
|
57483
57508
|
"6 7 8",
|
|
57484
57509
|
"Reply with ONLY the index of the cell you choose, as a single digit 0-8.",
|
|
57485
|
-
"Choose an empty cell. Prefer winning, then blocking, then center/corner."
|
|
57510
|
+
"Choose an empty cell. Prefer winning, then blocking, then center/corner.",
|
|
57511
|
+
"Answer immediately. No explanation, no working out \u2014 one character."
|
|
57486
57512
|
].join(`
|
|
57487
57513
|
`);
|
|
57488
57514
|
}
|
|
@@ -57500,7 +57526,7 @@ async function modelMove(board, opts = {}) {
|
|
|
57500
57526
|
user: gameUserPrompt(board),
|
|
57501
57527
|
...opts.provider !== undefined ? { provider: opts.provider } : {},
|
|
57502
57528
|
...opts.model !== undefined ? { model: opts.model } : {},
|
|
57503
|
-
maxOutputTokens:
|
|
57529
|
+
maxOutputTokens: 256,
|
|
57504
57530
|
requestId: "keryx-game",
|
|
57505
57531
|
...opts.providerFactory !== undefined ? { providerFactory: opts.providerFactory } : {},
|
|
57506
57532
|
...opts.env !== undefined ? { env: opts.env } : {}
|
|
@@ -57519,9 +57545,20 @@ var GAME_FOOTER = [
|
|
|
57519
57545
|
{ key: "r", label: "new game" },
|
|
57520
57546
|
{ key: "esc", label: "minimize" }
|
|
57521
57547
|
];
|
|
57522
|
-
var GAME_CELL_WIDTH = 5;
|
|
57523
|
-
var GAME_CELL_HEIGHT = 3;
|
|
57524
57548
|
var GAME_CELL_GAP = 1;
|
|
57549
|
+
var GAME_BOARD_CHROME_X = 4;
|
|
57550
|
+
var GAME_CELL_SIZES = {
|
|
57551
|
+
large: { width: 9, height: 5 },
|
|
57552
|
+
small: { width: 5, height: 3 }
|
|
57553
|
+
};
|
|
57554
|
+
function gameBoardWidth(cellWidth) {
|
|
57555
|
+
return cellWidth * 3 + GAME_CELL_GAP * 2 + GAME_BOARD_CHROME_X;
|
|
57556
|
+
}
|
|
57557
|
+
function resolveCellSize(availableWidth) {
|
|
57558
|
+
const large = GAME_CELL_SIZES.large;
|
|
57559
|
+
return gameBoardWidth(large.width) <= availableWidth ? large : GAME_CELL_SIZES.small;
|
|
57560
|
+
}
|
|
57561
|
+
var GAME_MODEL_TIMEOUT_MS = 12000;
|
|
57525
57562
|
function asOtui2(otui) {
|
|
57526
57563
|
if (otui === undefined || otui === null) {
|
|
57527
57564
|
return;
|
|
@@ -57548,7 +57585,7 @@ function statusText(state) {
|
|
|
57548
57585
|
if (state.draw) {
|
|
57549
57586
|
return "Draw! (r \u2014 new game)";
|
|
57550
57587
|
}
|
|
57551
|
-
return
|
|
57588
|
+
return state.turn === "X" ? "Your turn \u2014 X" : "Agent's turn \u2014 O";
|
|
57552
57589
|
}
|
|
57553
57590
|
function presentGame(openModalFn, otui, chrome, options = {}) {
|
|
57554
57591
|
const renderer = options.renderer;
|
|
@@ -57591,23 +57628,42 @@ function presentGame(openModalFn, otui, chrome, options = {}) {
|
|
|
57591
57628
|
modelBusy = true;
|
|
57592
57629
|
notice = undefined;
|
|
57593
57630
|
paint();
|
|
57594
|
-
const
|
|
57595
|
-
|
|
57596
|
-
|
|
57597
|
-
|
|
57598
|
-
...options.env !== undefined ? { env: options.env } : {}
|
|
57631
|
+
const timeoutMs = options.timeoutMs ?? GAME_MODEL_TIMEOUT_MS;
|
|
57632
|
+
let timer;
|
|
57633
|
+
const deadline = new Promise((resolve3) => {
|
|
57634
|
+
timer = setTimeout(() => resolve3("timeout"), timeoutMs);
|
|
57599
57635
|
});
|
|
57636
|
+
const outcome = await Promise.race([
|
|
57637
|
+
modelMove(currentGame.board, {
|
|
57638
|
+
...options.provider !== undefined ? { provider: options.provider } : {},
|
|
57639
|
+
...options.model !== undefined ? { model: options.model } : {},
|
|
57640
|
+
...options.providerFactory !== undefined ? { providerFactory: options.providerFactory } : {},
|
|
57641
|
+
...options.env !== undefined ? { env: options.env } : {}
|
|
57642
|
+
}),
|
|
57643
|
+
deadline
|
|
57644
|
+
]);
|
|
57645
|
+
if (timer !== undefined) {
|
|
57646
|
+
clearTimeout(timer);
|
|
57647
|
+
}
|
|
57600
57648
|
modelBusy = false;
|
|
57601
|
-
|
|
57602
|
-
|
|
57603
|
-
|
|
57604
|
-
|
|
57605
|
-
|
|
57606
|
-
|
|
57607
|
-
|
|
57649
|
+
const timedOut = outcome === "timeout";
|
|
57650
|
+
const result = timedOut ? { move: undefined, error: undefined } : outcome;
|
|
57651
|
+
let move = result.move;
|
|
57652
|
+
let playedLocally = false;
|
|
57653
|
+
if (move === undefined && result.error === undefined) {
|
|
57654
|
+
move = bestLocalMove(currentGame.board, "O");
|
|
57655
|
+
playedLocally = move !== undefined;
|
|
57656
|
+
}
|
|
57657
|
+
const placed = move === undefined ? undefined : placeMark(currentGame.board, move, "O");
|
|
57658
|
+
currentGame = placed ?? { ...currentGame, turn: "X" };
|
|
57659
|
+
if (result.error !== undefined) {
|
|
57660
|
+
notice = `agent: ${result.error}`;
|
|
57661
|
+
} else if (timedOut && playedLocally) {
|
|
57662
|
+
notice = `agent timed out after ${Math.round(timeoutMs / 1000)}s \u2014 played a local move`;
|
|
57663
|
+
} else if (playedLocally) {
|
|
57664
|
+
notice = "agent gave no usable answer \u2014 played a local move";
|
|
57608
57665
|
} else {
|
|
57609
|
-
|
|
57610
|
-
notice = result.error === undefined ? undefined : `agent: ${result.error}`;
|
|
57666
|
+
notice = undefined;
|
|
57611
57667
|
}
|
|
57612
57668
|
paint();
|
|
57613
57669
|
};
|
|
@@ -57645,7 +57701,11 @@ function presentGame(openModalFn, otui, chrome, options = {}) {
|
|
|
57645
57701
|
title: "/game",
|
|
57646
57702
|
tabs: [{ id: "game", label: "Tic-tac-toe" }],
|
|
57647
57703
|
footer: GAME_FOOTER,
|
|
57648
|
-
|
|
57704
|
+
onArrowKeys: (_key, direction) => {
|
|
57705
|
+
moveCursor(0, direction === "left" ? -1 : 1);
|
|
57706
|
+
return true;
|
|
57707
|
+
},
|
|
57708
|
+
renderTab: (_tabId, body, ctx) => {
|
|
57649
57709
|
if (body === undefined || body === null) {
|
|
57650
57710
|
return;
|
|
57651
57711
|
}
|
|
@@ -57655,6 +57715,7 @@ function presentGame(openModalFn, otui, chrome, options = {}) {
|
|
|
57655
57715
|
}
|
|
57656
57716
|
const theme = getTheme();
|
|
57657
57717
|
const r = renderer;
|
|
57718
|
+
const cellSize = resolveCellSize(ctx.width);
|
|
57658
57719
|
const wrap2 = new core.BoxRenderable(r, {
|
|
57659
57720
|
id: "game-wrap",
|
|
57660
57721
|
width: "100%",
|
|
@@ -57693,8 +57754,8 @@ function presentGame(openModalFn, otui, chrome, options = {}) {
|
|
|
57693
57754
|
const index = row * 3 + col;
|
|
57694
57755
|
const cellBox = new core.BoxRenderable(r, {
|
|
57695
57756
|
id: `game-cell-${index}`,
|
|
57696
|
-
width:
|
|
57697
|
-
height:
|
|
57757
|
+
width: cellSize.width,
|
|
57758
|
+
height: cellSize.height,
|
|
57698
57759
|
flexShrink: 0,
|
|
57699
57760
|
flexGrow: 0,
|
|
57700
57761
|
flexDirection: "row",
|
|
@@ -57750,11 +57811,11 @@ function presentGame(openModalFn, otui, chrome, options = {}) {
|
|
|
57750
57811
|
moveCursor(1, 0);
|
|
57751
57812
|
return;
|
|
57752
57813
|
}
|
|
57753
|
-
if (token === "
|
|
57814
|
+
if (token === "h") {
|
|
57754
57815
|
moveCursor(0, -1);
|
|
57755
57816
|
return;
|
|
57756
57817
|
}
|
|
57757
|
-
if (token === "
|
|
57818
|
+
if (token === "l") {
|
|
57758
57819
|
moveCursor(0, 1);
|
|
57759
57820
|
return;
|
|
57760
57821
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.60",
|
|
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": {
|