@maka/maka-cli 5.158.0 → 5.160.0

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maka/maka-cli",
3
- "version": "5.158.0",
3
+ "version": "5.160.0",
4
4
  "type": "module",
5
5
  "summary": "A command line tool for scaffolding Meteor 3.x applications using either React.",
6
6
  "description": "A command line tool for scaffolding Meteor 3.x applications using React.",
@@ -133,14 +133,11 @@ export class BacklogCommand extends Command {
133
133
  * empty, before any subcommand (this one included) could be reached.
134
134
  */
135
135
  async webBoard() {
136
- const { buildBacklogBoardUrl } = await import('../utilities/web-character-generator.js');
136
+ const { buildBacklogBoardUrl, backlogBoardHandoff } = await import('../utilities/web-character-generator.js');
137
137
  const url = buildBacklogBoardUrl(authToken());
138
138
  const { openBrowser } = await import('../../../../tools/browser/open-browser.js');
139
139
  openBrowser(url);
140
- return [
141
- `Your backlog board is opening in the browser -- the game keeps running right here.`,
142
- ` ${url}`,
143
- ].join('\n');
140
+ return backlogBoardHandoff(url, { gameRunning: true }).join('\n');
144
141
  }
145
142
  async file(text) {
146
143
  const game = this.game;
@@ -1237,7 +1237,18 @@ export class Player extends AbstractPlayer {
1237
1237
  // Edge is a per-job pool: spend a point (see commands/edge.ts) to arm a
1238
1238
  // boost that supercharges your next strike. Refreshed to `edge` on every
1239
1239
  // new job (see Game.continueToNextScene).
1240
- edgeRemaining = 0;
1240
+ // AN ACCESSOR, like weaponDrawn (ZpgTTPgX4Hn7qL5M7, 2026-09-10): the
1241
+ // play page's HUD header shows edge remaining, and a browser run has
1242
+ // no mid-run save to carry a spend -- only the beat can. Source-
1243
+ // compatible: every `edgeRemaining =` still works; it now reports.
1244
+ _edgeRemaining = 0;
1245
+ get edgeRemaining() { return this._edgeRemaining; }
1246
+ set edgeRemaining(v) {
1247
+ if (this._edgeRemaining === v)
1248
+ return;
1249
+ this._edgeRemaining = v;
1250
+ this.noteConditionChanged();
1251
+ }
1241
1252
  edgeBoostArmed = false;
1242
1253
  // Physical condition monitor, straight from SR5: 8 + (Body / 2, rounded
1243
1254
  // up) boxes. Damage fills boxes; a full track is death.
@@ -2075,7 +2086,17 @@ export class Player extends AbstractPlayer {
2075
2086
  // Karma: the advancement currency, earned per completed job (see
2076
2087
  // Scene.checkWinCondition) and spent in the hideout via "advance" --
2077
2088
  // gear stops being the only progression axis.
2078
- karma = 0;
2089
+ // AN ACCESSOR (2026-09-10, same reason as edgeRemaining): the web's
2090
+ // HUD header follows a karma award through the beat, since a browser
2091
+ // run's save summary never moves mid-job. `karma +=` still works.
2092
+ _karma = 0;
2093
+ get karma() { return this._karma; }
2094
+ set karma(v) {
2095
+ if (this._karma === v)
2096
+ return;
2097
+ this._karma = v;
2098
+ this.noteConditionChanged();
2099
+ }
2079
2100
  /**
2080
2101
  * The effective rating for a skill: explicit rating if set; otherwise
2081
2102
  * combat skills fall back to the legacy `combatSkill` attribute (which
@@ -4189,6 +4210,10 @@ export class Player extends AbstractPlayer {
4189
4210
  break;
4190
4211
  }
4191
4212
  this._currency += remaining;
4213
+ // The wallet moved: the web's HUD header reads nuyen off the beat
4214
+ // (2026-09-10) -- a payout, a fare, a purchase all land here.
4215
+ if (delta !== 0)
4216
+ this.noteConditionChanged();
4192
4217
  }
4193
4218
  }
4194
4219
  //# sourceMappingURL=player.js.map
@@ -166,6 +166,15 @@ export function buildConditionReport(player, deps) {
166
166
  // The ONE honest AR answer (2026-09-01): muted, cut, and no-rig
167
167
  // all collapse into arSightUp, computed at fire time.
168
168
  ar: arSightUp(player),
169
+ // THE HEADER'S NUMBERS (contract 2026-09-10, web accepted first;
170
+ // ZpgTTPgX4Hn7qL5M7: the play page's HUD shows the sheet header). A
171
+ // browser run writes no mid-run save and its roster summary is
172
+ // frozen for the whole job, so an edge spend, a payout, or a karma
173
+ // award reaches the web only through the beat. The engine's own
174
+ // fields, verbatim; edge is BOTH halves or neither on the web side.
175
+ karma: player.karma,
176
+ nuyen: player.currency,
177
+ edge: { remaining: player.edgeRemaining, max: player.edge },
169
178
  // THE ROOM'S OTHER DOTS (user: the map becomes a tactical
170
179
  // readout). Current room only, read at fire time; spot-seated
171
180
  // actors carry `spot` and the web places them on the grid it
@@ -218,6 +227,7 @@ function noteRoster(report) {
218
227
  const ADDITIVE_FIELDS = [
219
228
  'ar', 'actors', 'deckLine', 'deckDamage', 'astralPerceiving', 'bodyRoom', 'sustainingPenalty',
220
229
  'matrix', 'panMarks', 'hostMarksOnYou', 'marksPlaced', 'marksOnYou', 'deckStored', 'droneDamage', 'companions', 'pools', 'initiative',
230
+ 'karma', 'nuyen', 'edge',
221
231
  ];
222
232
  /** Refusal reasons already written to the session log -- one line each. */
223
233
  const announcedRefusals = new Map();
@@ -94,6 +94,23 @@ const BACKLOG_PAGE = '/backlog';
94
94
  export function buildBacklogBoardUrl(resumeToken) {
95
95
  return `${cliLoginUrl()}?t=${Date.now()}#token=${encodeURIComponent(resumeToken)}&next=${BACKLOG_PAGE}`;
96
96
  }
97
+ /**
98
+ * WHAT IS SAID WHEN THE BOARD OPENS -- one wording for both doors into
99
+ * it: the in-game "backlog web" (the game keeps running) and the
100
+ * launcher's `maka play:backlog --web` (user request, 2026-09-10: "can
101
+ * I get a maka play:backlog --web to view the backlog in the browser?").
102
+ * The URL is ALWAYS in the lines, for the same reason
103
+ * characterForgeHandoff spells out: openBrowser is fire-and-forget, so
104
+ * the printed URL is the only thing that works headless or over SSH.
105
+ */
106
+ export function backlogBoardHandoff(url, opts) {
107
+ return [
108
+ opts.gameRunning
109
+ ? `Your backlog board is opening in the browser -- the game keeps running right here.`
110
+ : `Your backlog board is opening in the browser.`,
111
+ ` ${url}`,
112
+ ];
113
+ }
97
114
  /**
98
115
  * WHAT THE CLI SAYS ON ITS WAY OUT of the chargen handoff. Extracted
99
116
  * from the command handler so the two things that matter about it are
@@ -1,12 +1,13 @@
1
1
  import ShadowrunCommand, { ShadowrunCompat } from './sideQuest.sub.cmd.js';
2
2
  import { Command } from '../../command.js';
3
+ import { Log } from '../../tools/log/log.class.js';
3
4
  import { registerBacklogMcp } from './sideQuest-backlog-mcp.sub.cmd.js';
4
5
  // Registered under BOTH the new spelling (play:backlog) and the compat
5
6
  // sub (play:shadowrun:backlog) from ONE definition -- two commands, one
6
7
  // options object, one handler, so the pair cannot drift.
7
8
  const registerBacklog = (parent) => Command.create({
8
9
  name: 'backlog',
9
- usage: 'maka play:backlog [<item id>]',
10
+ usage: 'maka play:backlog [<item id>] [--web]',
10
11
  shortDesc: 'Read the play-tester board without starting a game.',
11
12
  description: `The play-tester backlog on maka-cli.com: what has been reported, what
12
13
  the rulebooks made of it, what closed it, and which items ship a repro
@@ -21,9 +22,11 @@ const registerBacklog = (parent) => Command.create({
21
22
  { name: 'all', boolFlag: true, description: 'Include closed items, which are hidden by default.' },
22
23
  { name: 'close', boolFlag: true, description: 'With an item id: close it outright -- filed in error, duplicate, no longer real. Remaining words are the reason.' },
23
24
  { name: 'detach', description: 'With an item id: take a wrongly attached commit back off it (a full sha, or several separated by commas). Admin only. Remaining words say why.' },
25
+ { name: 'web', boolFlag: true, description: 'Open the live board in your browser (the same handoff as "backlog web" in-game) instead of printing it here.' },
24
26
  ],
25
27
  examples: [
26
28
  'maka play:backlog',
29
+ 'maka play:backlog --web',
27
30
  'maka play:backlog --filter in-review',
28
31
  'maka play:backlog --commit 359ad1fe',
29
32
  'maka play:backlog b9YeNqTNBJuk9dbrk',
@@ -31,6 +34,26 @@ const registerBacklog = (parent) => Command.create({
31
34
  'maka play:backlog b9YeNqTNBJuk9dbrk --detach 7ed04359 attached to the wrong row',
32
35
  ],
33
36
  }, async function (args, opts) {
37
+ // `--web` (user request, 2026-09-10): the browser board, from the
38
+ // launcher. Same /cli-login handoff the in-game "backlog web" uses --
39
+ // one URL builder, one wording -- and nothing else below runs: opening
40
+ // a page is not a dump with extra steps. Checked FIRST so it never
41
+ // needs the board fetched to say where the board is.
42
+ if (opts.web === true) {
43
+ const { authToken } = await import('./sideQuest/utilities/cloud-saves.js');
44
+ const token = authToken();
45
+ if (!token) {
46
+ Log.error('The backlog runs on your maka-cli.com login -- run `maka login` first.');
47
+ return;
48
+ }
49
+ const { buildBacklogBoardUrl, backlogBoardHandoff } = await import('./sideQuest/utilities/web-character-generator.js');
50
+ const url = buildBacklogBoardUrl(token);
51
+ const { openBrowser } = await import('../../tools/browser/open-browser.js');
52
+ openBrowser(url);
53
+ for (const line of backlogBoardHandoff(url, { gameRunning: false }))
54
+ Log.info(line);
55
+ return;
56
+ }
34
57
  const { dumpBacklog } = await import('./sideQuest/utilities/backlog-dump.js');
35
58
  // `--close` STILL ARRIVES AS A STRING when a reason follows it, even
36
59
  // here: minimist's boolean set is global to the CLI and teaching it
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maka/maka-cli",
3
- "version": "5.158.0",
3
+ "version": "5.160.0",
4
4
  "type": "module",
5
5
  "summary": "A command line tool for scaffolding Meteor 3.x applications using either React.",
6
6
  "description": "A command line tool for scaffolding Meteor 3.x applications using React.",