@maka/maka-cli 5.47.0 → 5.49.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.
Files changed (34) hide show
  1. package/bundle/typescript/package.json +1 -1
  2. package/bundle/typescript/src/commands/game/sideQuest/commands/map.d.ts +1 -1
  3. package/bundle/typescript/src/commands/game/sideQuest/commands/map.js +29 -1
  4. package/bundle/typescript/src/commands/game/sideQuest/commands/map.js.map +1 -1
  5. package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +25 -0
  6. package/bundle/typescript/src/commands/game/sideQuest/game.js +91 -2
  7. package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
  8. package/bundle/typescript/src/commands/game/sideQuest/headless.js +25 -0
  9. package/bundle/typescript/src/commands/game/sideQuest/headless.js.map +1 -1
  10. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +1 -0
  11. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
  12. package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +9 -0
  13. package/bundle/typescript/src/commands/game/sideQuest/models/player.js +21 -0
  14. package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
  15. package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +3 -0
  16. package/bundle/typescript/src/commands/game/sideQuest/ui.d.ts +3 -0
  17. package/bundle/typescript/src/commands/game/sideQuest/ui.js +17 -11
  18. package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
  19. package/bundle/typescript/src/commands/game/sideQuest/utilities/map-view.d.ts +70 -0
  20. package/bundle/typescript/src/commands/game/sideQuest/utilities/map-view.js +289 -0
  21. package/bundle/typescript/src/commands/game/sideQuest/utilities/map-view.js.map +1 -0
  22. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +6 -0
  23. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -1
  24. package/bundle/typescript/src/commands/game/sideQuest/utilities/prefs.d.ts +4 -0
  25. package/bundle/typescript/src/commands/game/sideQuest/utilities/prefs.js +44 -0
  26. package/bundle/typescript/src/commands/game/sideQuest/utilities/prefs.js.map +1 -0
  27. package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.js +13 -0
  28. package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.js.map +1 -1
  29. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +5 -0
  30. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
  31. package/bundle/typescript/src/tools/ai/ai.class.d.ts +15 -0
  32. package/bundle/typescript/src/tools/ai/ai.class.js +20 -0
  33. package/bundle/typescript/src/tools/ai/ai.class.js.map +1 -1
  34. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maka/maka-cli",
3
- "version": "5.47.0",
3
+ "version": "5.49.0",
4
4
  "type": "module",
5
5
  "summary": "A command line tool for scaffolding Meteor 2.x applications using either React.",
6
6
  "description": "A command line tool for scaffolding Meteor 2.x applications using React.",
@@ -8,7 +8,7 @@ import { Command, ICommand } from './command.js';
8
8
  export declare class MapCommand extends Command implements ICommand {
9
9
  protected static verb: string;
10
10
  protected static description: string;
11
- execute(_args?: string[]): Promise<string>;
11
+ execute(args?: string[]): Promise<string>;
12
12
  /**
13
13
  * Every room in the scene as a grid icon. ● = a live host node
14
14
  * (ice and paydata country), · = thin grid (an overlay you can
@@ -3,6 +3,8 @@ import { hint } from '../utilities/hints.js';
3
3
  import { Door } from '../models/door.js';
4
4
  import { isWatched, camerasLive } from '../utilities/surveillance.js';
5
5
  import { capitalCase } from 'change-case';
6
+ import { renderMapDetailed } from '../utilities/map-view.js';
7
+ import { getPref, setPref } from '../utilities/prefs.js';
6
8
  /**
7
9
  * On-demand exits panel, replacing the always-on blessed sidebar box.
8
10
  * Registered as both "map" and "exits". Locked ways out matter most, so
@@ -12,11 +14,22 @@ import { capitalCase } from 'change-case';
12
14
  export class MapCommand extends Command {
13
15
  static verb = 'map';
14
16
  static description = 'Where you are and every way out, with lock states. Jacked in, it lights THE GRID instead: every room as an icon -- host nodes bright, thin grid dim, air-gapped hosts dark -- because a persona jumps anywhere by name, no exits needed.';
15
- async execute(_args = []) {
17
+ async execute(args = []) {
16
18
  const room = this.actor.currentLocation;
17
19
  if (!room) {
18
20
  return "You're nowhere. This is a bug.";
19
21
  }
22
+ const sub = (args[0] ?? '').toLowerCase();
23
+ // "map overlay": toggle the persistent icon minimap (map-overlay
24
+ // wave 2026-08-24) -- preference sticks across sessions.
25
+ if (sub === 'overlay') {
26
+ const on = !getPref('mapOverlay', true);
27
+ setPref('mapOverlay', on);
28
+ this.game?.updateExits(room);
29
+ if (!on)
30
+ this.game?.hideMapOverlay();
31
+ return on ? `The overlay flickers on -- icons in the corner of your eye.` : `The overlay winks out.`;
32
+ }
20
33
  // THE GRID VIEW (RAW p.217-218/235; player ruling 2026-08-23):
21
34
  // jacked in, exits are furniture -- icons and hosts are visible
22
35
  // from anywhere (only silence and air gaps hide anything), and
@@ -24,11 +37,26 @@ export class MapCommand extends Command {
24
37
  if (this.actor.plane === 'matrix') {
25
38
  return this.gridMap(room);
26
39
  }
40
+ // No modal (ruling 2026-08-24: the modal was scrapped after two
41
+ // rounds -- the docked minimap is the graphic; "map" stays the
42
+ // text view). "map list" is kept as a working alias.
27
43
  const lines = [`=== ${room.name.toUpperCase()} ===`];
28
44
  if (room.exits.size === 0) {
29
45
  lines.push('There are no exits here.');
30
46
  return lines.join('\n');
31
47
  }
48
+ // THE MINIMAP (player request 2026-08-24): the room graph laid out
49
+ // spatially -- ▣ marks you, ✕ marks a locked or spell-sealed way,
50
+ // ▲/▼ flag up/down exits. Box-drawing only (no emoji -- blessed's
51
+ // width tables, see the ui.ts patch saga). The textual exits list
52
+ // below stays as the detail view. Renderer shared with the modal
53
+ // and the icon overlay (utilities/map-view.ts).
54
+ const mini = renderMapDetailed(this.rooms ?? {}, room, (r, d) => this.scene.barrierSealing(r, d), {
55
+ visited: this.actor.visitedRooms,
56
+ });
57
+ if (mini.length > 0) {
58
+ lines.push(...mini, '');
59
+ }
32
60
  lines.push('Exits:');
33
61
  for (const [direction, exit] of room.exits.entries()) {
34
62
  if (exit instanceof Door) {
@@ -1 +1 @@
1
- {"version":3,"file":"map.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/map.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"map.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/map.ts"],"names":[],"mappings":"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"}
@@ -50,6 +50,9 @@ export default class Game {
50
50
  private _escArmedAt;
51
51
  private _statusBox;
52
52
  private _inputBox;
53
+ /** The floating icon-minimap (map-overlay wave 2026-08-24). Optional:
54
+ * headless sessions never build widgets. */
55
+ private _mapBox?;
53
56
  private _useAi;
54
57
  private _aiRefusalAnnounced;
55
58
  private _owner?;
@@ -704,6 +707,28 @@ export default class Game {
704
707
  * pieces, not a status framework built ahead of need.
705
708
  */
706
709
  private initStatusBox;
710
+ /**
711
+ * THE MINIMAP (map-overlay wave 2026-08-24): a small icon viewport
712
+ * DOCKED at the top of the Mechanics column -- not floated over the
713
+ * log (a float occluded log text and, being numerically anchored,
714
+ * drifted on terminal resize; percentage geometry re-solves both).
715
+ * The Mechanics pane shifts down while the map is shown and takes the
716
+ * space back when it hides. keys:false -- a keyable box appended
717
+ * after the input steals focus (the "eexxiitt" bug, see initInputBox).
718
+ * Hidden until the first setMapOverlay with content.
719
+ */
720
+ private static readonly MAP_DOCK_ROWS;
721
+ private initMapBox;
722
+ /** Shifts the Mechanics pane down (map shown) or back up (hidden). */
723
+ private dockMap;
724
+ /**
725
+ * Paints (or hides) the docked minimap. Solo: updateExits feeds it
726
+ * from the local scene; shared runs: SharedRunSession.route feeds it
727
+ * from the server's per-player kind:'map' events. The preference
728
+ * gates both paths in one place.
729
+ */
730
+ setMapOverlay(lines: string[]): void;
731
+ hideMapOverlay(): void;
707
732
  /**
708
733
  * Refreshes the status box from current player state. Called after any
709
734
  * command that can change what belongs there (currently "call"/"end-call")
@@ -11,6 +11,8 @@ import { pushSave, burnCloudSaveFor } from './utilities/cloud-saves.js';
11
11
  import { DOCWAGON_TIERS, RESUSC_FEE, DEATH_COMP } from './utilities/docwagon.js';
12
12
  import { isFence, LIFESTYLE_TIERS } from './utilities/commerce.js';
13
13
  import { bestFakeSin, wandRead, processArrest } from './utilities/sin.js';
14
+ import { renderMapViewport } from './utilities/map-view.js';
15
+ import { getPref } from './utilities/prefs.js';
14
16
  import { rollPool, formatRoll } from './utilities/dice.js';
15
17
  import { Direction } from './types/shared/direction-enum.js';
16
18
  import { Logger } from './utilities/logger.js';
@@ -141,6 +143,9 @@ export default class Game {
141
143
  _escArmedAt = 0;
142
144
  _statusBox;
143
145
  _inputBox;
146
+ /** The floating icon-minimap (map-overlay wave 2026-08-24). Optional:
147
+ * headless sessions never build widgets. */
148
+ _mapBox;
144
149
  _useAi = false;
145
150
  _aiRefusalAnnounced = false;
146
151
  // ACCOUNT BINDING (ruling 2026-08-23): who this runner belongs to,
@@ -1823,6 +1828,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
1823
1828
  this.initLogBox(screen);
1824
1829
  this.initMetaBox(screen);
1825
1830
  this.initStatusBox(screen);
1831
+ this.initMapBox(screen); // docked atop the Mechanics column
1826
1832
  this._screen = screen;
1827
1833
  }
1828
1834
  /** The engine half of startup: scene synthesis, command registration,
@@ -2985,7 +2991,12 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
2985
2991
  // auto-scrolls (alwaysScroll) and keys/vi still scroll it when
2986
2992
  // focused -- wheel-scroll wasn't worth shells full of coordinate
2987
2993
  // bytes every time a session died hard.
2988
- tags: true // Intercept tags
2994
+ tags: true, // Intercept tags
2995
+ // Terminal-style flow (playtest 2026-08-24: "it would work if the
2996
+ // text scrolled from the bottom up"): content anchors to the
2997
+ // bottom edge and pushes upward, like a shell. Probe-verified to
2998
+ // coexist with insertBottom, tail-follow, and PgUp paging.
2999
+ valign: 'bottom'
2989
3000
  });
2990
3001
  this._logBox = logBox;
2991
3002
  // Scrolling without focus (player report: "can't scroll the game log
@@ -3093,6 +3104,8 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
3093
3104
  scrollable: true,
3094
3105
  alwaysScroll: true,
3095
3106
  tags: true,
3107
+ // Bottom-up flow, same as the world log (see initLogBox).
3108
+ valign: 'bottom',
3096
3109
  });
3097
3110
  this._metaBox = metaBox;
3098
3111
  // Scrolling (player report: menus render here now and PgUp/PgDn
@@ -3145,6 +3158,67 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
3145
3158
  this._statusBox = statusBox;
3146
3159
  screen.append(statusBox);
3147
3160
  }
3161
+ /**
3162
+ * THE MINIMAP (map-overlay wave 2026-08-24): a small icon viewport
3163
+ * DOCKED at the top of the Mechanics column -- not floated over the
3164
+ * log (a float occluded log text and, being numerically anchored,
3165
+ * drifted on terminal resize; percentage geometry re-solves both).
3166
+ * The Mechanics pane shifts down while the map is shown and takes the
3167
+ * space back when it hides. keys:false -- a keyable box appended
3168
+ * after the input steals focus (the "eexxiitt" bug, see initInputBox).
3169
+ * Hidden until the first setMapOverlay with content.
3170
+ */
3171
+ static MAP_DOCK_ROWS = 11; // 9 viewport rows + border
3172
+ initMapBox(screen) {
3173
+ const mapBox = blessed.box({
3174
+ id: 'mapBox',
3175
+ top: 0,
3176
+ left: '65%',
3177
+ width: '35%',
3178
+ height: Game.MAP_DOCK_ROWS,
3179
+ border: { type: 'line' },
3180
+ style: { border: { fg: 'blue' } },
3181
+ label: ' Map ',
3182
+ tags: true,
3183
+ keys: false,
3184
+ content: '',
3185
+ hidden: true,
3186
+ });
3187
+ this._mapBox = mapBox;
3188
+ screen.append(mapBox);
3189
+ }
3190
+ /** Shifts the Mechanics pane down (map shown) or back up (hidden). */
3191
+ dockMap(shown) {
3192
+ if (!this._metaBox)
3193
+ return;
3194
+ this._metaBox.top = shown ? Game.MAP_DOCK_ROWS : 0;
3195
+ this._metaBox.height = shown ? `100%-${11 + Game.MAP_DOCK_ROWS}` : '100%-11';
3196
+ }
3197
+ /**
3198
+ * Paints (or hides) the docked minimap. Solo: updateExits feeds it
3199
+ * from the local scene; shared runs: SharedRunSession.route feeds it
3200
+ * from the server's per-player kind:'map' events. The preference
3201
+ * gates both paths in one place.
3202
+ */
3203
+ setMapOverlay(lines) {
3204
+ if (!this._mapBox)
3205
+ return;
3206
+ if (lines.length === 0 || !getPref('mapOverlay', true)) {
3207
+ this.hideMapOverlay();
3208
+ return;
3209
+ }
3210
+ this._mapBox.setContent(lines.join('\n'));
3211
+ this.dockMap(true);
3212
+ this._mapBox.show();
3213
+ this._screen?.render();
3214
+ }
3215
+ hideMapOverlay() {
3216
+ if (!this._mapBox)
3217
+ return;
3218
+ this._mapBox.hide();
3219
+ this.dockMap(false);
3220
+ this._screen?.render();
3221
+ }
3148
3222
  /**
3149
3223
  * Refreshes the status box from current player state. Called after any
3150
3224
  * command that can change what belongs there (currently "call"/"end-call")
@@ -3340,7 +3414,22 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
3340
3414
  this.notePresenceAffectingChange();
3341
3415
  }
3342
3416
  updateExits(_room) {
3343
- // Nothing to render -- the "map" command reads live room state.
3417
+ // THE ICON OVERLAY (map-overlay wave 2026-08-24): this hook was
3418
+ // kept as a no-op for exactly this -- it already fires on movement
3419
+ // (go/lock/unlock, ui.ts), scene transitions, and barrier changes.
3420
+ // Session mode: the server's per-player kind:'map' events feed the
3421
+ // overlay instead (SharedRunSession.route).
3422
+ if (!this._mapBox || this.remoteSession)
3423
+ return;
3424
+ const here = this.player.currentLocation;
3425
+ if (!here || this.player.plane === 'matrix') {
3426
+ this.hideMapOverlay();
3427
+ return;
3428
+ }
3429
+ this.setMapOverlay(renderMapViewport(this.scene.getRooms(), here, (r, d) => this.scene.barrierSealing(r, d), {
3430
+ visited: this.player.visitedRooms,
3431
+ arEyes: this.player.hasMatrixEyes(),
3432
+ }));
3344
3433
  }
3345
3434
  updateInventory(_playerInventory, _currencyName = 'currency') {
3346
3435
  this.updateStatus();