atris 3.74.7 → 3.74.9
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/commands/gm.js +41 -14
- package/commands/member.js +41 -7
- package/lib/gm-bet.js +768 -188
- package/lib/gm-card.js +45 -4
- package/lib/gm-phone-page.js +508 -74
- package/lib/text-table.js +138 -12
- package/lib/zen-apply.js +1 -1
- package/lib/zen.js +15 -2
- package/package.json +1 -1
- package/scripts/det/ytnotes +9 -3
package/commands/gm.js
CHANGED
|
@@ -797,19 +797,20 @@ function tail(text, used, width) {
|
|
|
797
797
|
return clip(text, Math.max(10, width - used));
|
|
798
798
|
}
|
|
799
799
|
|
|
800
|
-
// Last guard on width: a long line breaks after a
|
|
801
|
-
// line; anything still too long ends in "...".
|
|
800
|
+
// Last guard on width, in terminal columns: a long line breaks after a
|
|
801
|
+
// comma onto an indented line; anything still too long ends in "...".
|
|
802
802
|
function fitLines(lines, width) {
|
|
803
|
+
const { displayWidth, sliceColumns } = require('../lib/text-table');
|
|
803
804
|
const out = [];
|
|
804
805
|
for (const line of lines) {
|
|
805
806
|
let rest = line;
|
|
806
|
-
while (rest
|
|
807
|
-
const cut = rest.lastIndexOf(', ', width - 1);
|
|
807
|
+
while (displayWidth(rest) > width) {
|
|
808
|
+
const cut = rest.lastIndexOf(', ', sliceColumns(rest, width).length - 1);
|
|
808
809
|
if (cut <= 0) break;
|
|
809
810
|
out.push(rest.slice(0, cut + 1));
|
|
810
811
|
rest = ` ${rest.slice(cut + 2)}`;
|
|
811
812
|
}
|
|
812
|
-
out.push(rest
|
|
813
|
+
out.push(displayWidth(rest) > width ? `${sliceColumns(rest, width - 3)}...` : rest);
|
|
813
814
|
}
|
|
814
815
|
return out;
|
|
815
816
|
}
|
|
@@ -830,13 +831,30 @@ function boardWorkspaceRoot(args = []) {
|
|
|
830
831
|
return taskDb.workspaceRoot(path.resolve(workspaceArg));
|
|
831
832
|
}
|
|
832
833
|
|
|
834
|
+
// The team page's cells (role, ovr, engine) for each roster member, read
|
|
835
|
+
// only when the board draws its box in a terminal; null otherwise.
|
|
836
|
+
function boardCells(board, workspaceRoot, ratings) {
|
|
837
|
+
if (!process.stdout.isTTY || !workspaceRoot) return null;
|
|
838
|
+
return require('../lib/gm-bet').teamCells(workspaceRoot, board.roster.map(r => r.name), { ratings });
|
|
839
|
+
}
|
|
840
|
+
|
|
833
841
|
function loadBoard(workspaceRoot, options = {}) {
|
|
842
|
+
return loadSeasonBoard(workspaceRoot, options).board;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// The board and every member's rating (gm-season memberRatings, the same
|
|
846
|
+
// numbers the orb's team page reads) from one read of the season.
|
|
847
|
+
function loadSeasonBoard(workspaceRoot, options = {}) {
|
|
834
848
|
const season = require('../lib/gm-season');
|
|
835
|
-
|
|
849
|
+
const played = season.loadSeason(workspaceRoot, { lastSeen: options.lastSeen });
|
|
850
|
+
return { board: season.seasonBoard(played, options), ratings: season.memberRatings(played.outcomes || []) };
|
|
836
851
|
}
|
|
837
852
|
|
|
838
853
|
// One screen, about 40 rows at most. Pure: board in, lines out.
|
|
839
|
-
|
|
854
|
+
// In a terminal, given the team page's cells, the roster is the orb's team
|
|
855
|
+
// table as a divided box (member, role, ovr, engine, status); piped, or when
|
|
856
|
+
// the box cannot fit the width, it keeps the plain columns.
|
|
857
|
+
function renderBoardLines(board, { interactive = false, width = termWidth(), bordered = Boolean(process.stdout.isTTY), cells = null } = {}) {
|
|
840
858
|
const { clockLabel } = require('../lib/gm-season');
|
|
841
859
|
const lines = [];
|
|
842
860
|
const nameW = nameWidth([
|
|
@@ -856,7 +874,12 @@ function renderBoardLines(board, { interactive = false, width = termWidth() } =
|
|
|
856
874
|
lines.push('');
|
|
857
875
|
|
|
858
876
|
lines.push('roster, last 30 days');
|
|
859
|
-
|
|
877
|
+
const boxed = bordered && cells && board.roster.length
|
|
878
|
+
? require('../lib/gm-bet').teamBox(board.roster.map(r => ({ member: r.name, status: r.status })), cells, { width: width - 2 })
|
|
879
|
+
: null;
|
|
880
|
+
if (boxed) {
|
|
881
|
+
lines.push(...boxed.split('\n').map(line => ` ${line}`));
|
|
882
|
+
} else if (board.roster.length) {
|
|
860
883
|
lines.push(` ${pad('name', nameW)}${pad('ovr', 8)}${pad('form', 7)}${pad('record', 18)}status`);
|
|
861
884
|
for (const row of board.roster) {
|
|
862
885
|
const record = `landed ${row.landed} of ${row.jobs}`;
|
|
@@ -913,9 +936,10 @@ function renderBoardLines(board, { interactive = false, width = termWidth() } =
|
|
|
913
936
|
}
|
|
914
937
|
lines.push('');
|
|
915
938
|
|
|
916
|
-
lines.push(
|
|
939
|
+
lines.push(`key: ovr 60 to 99 = share of finished jobs landed, ${boxed ? 'new' : 'rookie'} under 3 finished,`);
|
|
917
940
|
lines.push(' stricter than the website rating on purpose (drops and abandons count)');
|
|
918
|
-
lines.push('
|
|
941
|
+
if (boxed) lines.push(' ·· = nothing to show yet: no finished job, no role, or no pinned model');
|
|
942
|
+
else lines.push(' form: last 5, newest right: k landed, d dropped, x sent back, a abandoned');
|
|
919
943
|
lines.push(' hours: claim to result. on a job: moved in the last 6h. review: pending');
|
|
920
944
|
if (interactive) for (const line of PLAY_KEYS) lines.push(line);
|
|
921
945
|
else lines.push(' run atris gm in a terminal to play');
|
|
@@ -990,9 +1014,10 @@ function printLeague() {
|
|
|
990
1014
|
}
|
|
991
1015
|
|
|
992
1016
|
function printBoard(args = []) {
|
|
993
|
-
const
|
|
1017
|
+
const root = boardWorkspaceRoot(args);
|
|
1018
|
+
const { board, ratings } = loadSeasonBoard(root);
|
|
994
1019
|
if (board.error) return failRead(board.error);
|
|
995
|
-
console.log(renderBoardLines(board).join('\n'));
|
|
1020
|
+
console.log(renderBoardLines(board, { cells: boardCells(board, root, ratings) }).join('\n'));
|
|
996
1021
|
return undefined;
|
|
997
1022
|
}
|
|
998
1023
|
|
|
@@ -1107,11 +1132,11 @@ async function gmPlay(args = []) {
|
|
|
1107
1132
|
leagueRowsSeen = [...board.rows, ...(board.hidden_clubs || [])];
|
|
1108
1133
|
write(renderLeagueLines(board, { interactive: true }).join('\n'));
|
|
1109
1134
|
} else {
|
|
1110
|
-
const board =
|
|
1135
|
+
const { board, ratings } = loadSeasonBoard(workspaceRoot, { seen, lastSeen });
|
|
1111
1136
|
lastBoard = board;
|
|
1112
1137
|
seen = new Set(board.last_plays.map(play => play.id));
|
|
1113
1138
|
stuck = board.stuck || [];
|
|
1114
|
-
write(renderBoardLines(board, { interactive: true }).join('\n'));
|
|
1139
|
+
write(renderBoardLines(board, { interactive: true, cells: boardCells(board, workspaceRoot, ratings) }).join('\n'));
|
|
1115
1140
|
season.writeLastSeen(workspaceRoot, board.now);
|
|
1116
1141
|
}
|
|
1117
1142
|
} catch (err) {
|
|
@@ -1986,9 +2011,11 @@ async function gmCommand(...args) {
|
|
|
1986
2011
|
}
|
|
1987
2012
|
|
|
1988
2013
|
module.exports = {
|
|
2014
|
+
boardCells,
|
|
1989
2015
|
displayCommand,
|
|
1990
2016
|
ensureStarterMission,
|
|
1991
2017
|
gmCommand,
|
|
2018
|
+
loadSeasonBoard,
|
|
1992
2019
|
pickClub,
|
|
1993
2020
|
playAction,
|
|
1994
2021
|
renderBoardLines,
|
package/commands/member.js
CHANGED
|
@@ -11664,6 +11664,44 @@ async function memberStandupWalk(room, args = []) {
|
|
|
11664
11664
|
return payload;
|
|
11665
11665
|
}
|
|
11666
11666
|
|
|
11667
|
+
// The team page's cells (role, ovr, engine) per standup member, read only
|
|
11668
|
+
// when the standup can draw its table (a terminal); --json never carries
|
|
11669
|
+
// them. ovr comes from gm-season memberRatings, as on the orb's team page.
|
|
11670
|
+
function standupTableData(standup, cwd = process.cwd()) {
|
|
11671
|
+
if (!process.stdout.isTTY) return { bordered: false };
|
|
11672
|
+
const season = require('../lib/gm-season');
|
|
11673
|
+
const root = require('../lib/task-db').workspaceRoot(path.resolve(cwd));
|
|
11674
|
+
let ratings = new Map();
|
|
11675
|
+
try {
|
|
11676
|
+
const played = season.loadSeason(root, { lastSeen: null });
|
|
11677
|
+
if (played && !played.error) ratings = season.memberRatings(played.outcomes || []);
|
|
11678
|
+
} catch { ratings = new Map(); }
|
|
11679
|
+
const cells = require('../lib/gm-bet').teamCells(root, standup.map((s) => s.member), { ratings });
|
|
11680
|
+
return { bordered: true, cells };
|
|
11681
|
+
}
|
|
11682
|
+
|
|
11683
|
+
// The standup: in a terminal the orb's team table as a divided box
|
|
11684
|
+
// (member, role, ovr, engine, status) with each member's found and push
|
|
11685
|
+
// lines under it; piped, or when the box cannot fit, the boxes it always had.
|
|
11686
|
+
function memberStandupLines(standup, { bordered = false, width = process.stdout.columns, cells = null } = {}) {
|
|
11687
|
+
if (bordered && cells && standup.length) {
|
|
11688
|
+
const table = require('../lib/gm-bet').teamBox(standup.map((s) => ({ member: s.member, status: s.status })), cells, { width: Number(width) - 2 });
|
|
11689
|
+
if (table) {
|
|
11690
|
+
return [
|
|
11691
|
+
...table.split('\n').map((line) => ` ${line}`),
|
|
11692
|
+
...standup.flatMap((s) => [` ${s.member}`, ` found: ${s.latest_update}`, ` push: ${s.next_push}`]),
|
|
11693
|
+
];
|
|
11694
|
+
}
|
|
11695
|
+
}
|
|
11696
|
+
return standup.flatMap((s, idx) => [
|
|
11697
|
+
`+-----------------------------------------------------------------------+`,
|
|
11698
|
+
`| ${idx + 1}. ${s.member.toUpperCase()} (${s.role}) · ${s.status} · engine:${s.engine}`,
|
|
11699
|
+
`| Found: ${s.latest_update}`,
|
|
11700
|
+
`| Push: ${s.next_push}`,
|
|
11701
|
+
`+-----------------------------------------------------------------------+`,
|
|
11702
|
+
]);
|
|
11703
|
+
}
|
|
11704
|
+
|
|
11667
11705
|
async function memberRoom(...args) {
|
|
11668
11706
|
if (hasFlag(args, '--help') || hasFlag(args, '-h')) {
|
|
11669
11707
|
console.log('Usage: atris member [day|standup|room] [--walk] [--limit N] [--decisions "y|idea|n"] [--json]');
|
|
@@ -11680,13 +11718,7 @@ async function memberRoom(...args) {
|
|
|
11680
11718
|
? `Your team runs on ${teamEngines.length > 1 ? `${teamEngines.slice(0, -1).join(', ')} and ${teamEngines[teamEngines.length - 1]}` : teamEngines[0]}.`
|
|
11681
11719
|
: 'Your team picks an engine for each job.';
|
|
11682
11720
|
|
|
11683
|
-
const standupRows = room.standup
|
|
11684
|
-
`+-----------------------------------------------------------------------+`,
|
|
11685
|
-
`| ${idx + 1}. ${s.member.toUpperCase()} (${s.role}) · ${s.status} · engine:${s.engine}`,
|
|
11686
|
-
`| Found: ${s.latest_update}`,
|
|
11687
|
-
`| Push: ${s.next_push}`,
|
|
11688
|
-
`+-----------------------------------------------------------------------+`,
|
|
11689
|
-
]);
|
|
11721
|
+
const standupRows = memberStandupLines(room.standup, standupTableData(room.standup));
|
|
11690
11722
|
|
|
11691
11723
|
const handoffRows = room.handoffs.length
|
|
11692
11724
|
? room.handoffs.map((h) => ` - ${h.from} -> ${h.to}: ${h.summary} (run: ${h.next_command})`)
|
|
@@ -12019,6 +12051,8 @@ async function memberCommand(subcommand, ...args) {
|
|
|
12019
12051
|
|
|
12020
12052
|
module.exports = {
|
|
12021
12053
|
logDateForScan,
|
|
12054
|
+
memberStandupLines,
|
|
12055
|
+
standupTableData,
|
|
12022
12056
|
memberRunDefaultWallSeconds,
|
|
12023
12057
|
memberRunWantsReferee,
|
|
12024
12058
|
proposalPromptForGoal,
|