@maka/maka-cli 5.72.0 → 5.74.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 (88) hide show
  1. package/bundle/typescript/package.json +1 -1
  2. package/bundle/typescript/src/commands/game/_index.d.ts +0 -4
  3. package/bundle/typescript/src/commands/game/_index.js +6 -5
  4. package/bundle/typescript/src/commands/game/_index.js.map +1 -1
  5. package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.js +18 -3
  6. package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.js.map +1 -1
  7. package/bundle/typescript/src/commands/game/sideQuest/commands/breach.d.ts +1 -0
  8. package/bundle/typescript/src/commands/game/sideQuest/commands/breach.js +3 -0
  9. package/bundle/typescript/src/commands/game/sideQuest/commands/breach.js.map +1 -1
  10. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.d.ts +4 -0
  11. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +14 -0
  12. package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js.map +1 -1
  13. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.d.ts +2 -0
  14. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +25 -6
  15. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -1
  16. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +17 -1
  17. package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
  18. package/bundle/typescript/src/commands/game/sideQuest/commands/mark.js +8 -3
  19. package/bundle/typescript/src/commands/game/sideQuest/commands/mark.js.map +1 -1
  20. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +2 -2
  21. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -1
  22. package/bundle/typescript/src/commands/game/sideQuest/commands/snoop.js +8 -1
  23. package/bundle/typescript/src/commands/game/sideQuest/commands/snoop.js.map +1 -1
  24. package/bundle/typescript/src/commands/game/sideQuest/commands/sustain.d.ts +48 -0
  25. package/bundle/typescript/src/commands/game/sideQuest/commands/sustain.js +135 -0
  26. package/bundle/typescript/src/commands/game/sideQuest/commands/sustain.js.map +1 -0
  27. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +3 -0
  28. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
  29. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +38 -2
  30. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
  31. package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +49 -0
  32. package/bundle/typescript/src/commands/game/sideQuest/game.js +93 -11
  33. package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
  34. package/bundle/typescript/src/commands/game/sideQuest/headless.js +44 -3
  35. package/bundle/typescript/src/commands/game/sideQuest/headless.js.map +1 -1
  36. package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +28 -0
  37. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +62 -1
  38. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
  39. package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +39 -6
  40. package/bundle/typescript/src/commands/game/sideQuest/models/player.js +74 -31
  41. package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
  42. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.js +6 -6
  43. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.js.map +1 -1
  44. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.d.ts +21 -7
  45. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +50 -30
  46. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -1
  47. package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.d.ts +63 -0
  48. package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js +41 -0
  49. package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js.map +1 -1
  50. package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-names.d.ts +43 -0
  51. package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-names.js +83 -0
  52. package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-names.js.map +1 -0
  53. package/bundle/typescript/src/commands/game/sideQuest/utilities/identity.d.ts +26 -0
  54. package/bundle/typescript/src/commands/game/sideQuest/utilities/identity.js +37 -0
  55. package/bundle/typescript/src/commands/game/sideQuest/utilities/identity.js.map +1 -1
  56. package/bundle/typescript/src/commands/game/sideQuest/utilities/map-view.d.ts +19 -0
  57. package/bundle/typescript/src/commands/game/sideQuest/utilities/map-view.js +22 -0
  58. package/bundle/typescript/src/commands/game/sideQuest/utilities/map-view.js.map +1 -1
  59. package/bundle/typescript/src/commands/game/sideQuest/utilities/repro-launch.d.ts +1 -1
  60. package/bundle/typescript/src/commands/game/sideQuest/utilities/session-legs.d.ts +74 -0
  61. package/bundle/typescript/src/commands/game/sideQuest/utilities/session-legs.js +74 -0
  62. package/bundle/typescript/src/commands/game/sideQuest/utilities/session-legs.js.map +1 -0
  63. package/bundle/typescript/src/commands/game/sideQuest/utilities/splash.d.ts +6 -0
  64. package/bundle/typescript/src/commands/game/sideQuest/utilities/splash.js +60 -0
  65. package/bundle/typescript/src/commands/game/sideQuest/utilities/splash.js.map +1 -0
  66. package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.js +15 -10
  67. package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.js.map +1 -1
  68. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.d.ts +1 -0
  69. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +103 -56
  70. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
  71. package/bundle/typescript/src/commands/registry.js +1 -1
  72. package/bundle/typescript/src/commands/registry.js.map +1 -1
  73. package/package.json +1 -1
  74. package/bundle/typescript/src/commands/game/battleship.sub.cmd.d.ts +0 -1
  75. package/bundle/typescript/src/commands/game/battleship.sub.cmd.js +0 -12
  76. package/bundle/typescript/src/commands/game/battleship.sub.cmd.js.map +0 -1
  77. package/bundle/typescript/src/commands/game/play.command.d.ts +0 -3
  78. package/bundle/typescript/src/commands/game/play.command.js +0 -18
  79. package/bundle/typescript/src/commands/game/play.command.js.map +0 -1
  80. package/bundle/typescript/src/commands/game/pong.sub.cmd.d.ts +0 -1
  81. package/bundle/typescript/src/commands/game/pong.sub.cmd.js +0 -12
  82. package/bundle/typescript/src/commands/game/pong.sub.cmd.js.map +0 -1
  83. package/bundle/typescript/src/commands/game/snake.sub.cmd.d.ts +0 -1
  84. package/bundle/typescript/src/commands/game/snake.sub.cmd.js +0 -12
  85. package/bundle/typescript/src/commands/game/snake.sub.cmd.js.map +0 -1
  86. package/bundle/typescript/src/commands/game/tetris.sub.cmd.d.ts +0 -1
  87. package/bundle/typescript/src/commands/game/tetris.sub.cmd.js +0 -12
  88. package/bundle/typescript/src/commands/game/tetris.sub.cmd.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import blessed from 'blessed';
2
- import { nameThem } from './utilities/identity.js';
2
+ import { nameThem, scrubHandles } from './utilities/identity.js';
3
3
  import { dirname } from 'path';
4
4
  import { capitalCase } from 'change-case';
5
5
  import { Category, Size, Rating } from './types/shared/item-enum.js';
@@ -13,7 +13,7 @@ import { pushSave, burnCloudSaveFor } from './utilities/cloud-saves.js';
13
13
  import { DOCWAGON_TIERS, RESUSC_FEE, DEATH_COMP } from './utilities/docwagon.js';
14
14
  import { isFence, LIFESTYLE_TIERS } from './utilities/commerce.js';
15
15
  import { bestFakeSin, wandRead, processArrest } from './utilities/sin.js';
16
- import { renderMapViewport } from './utilities/map-view.js';
16
+ import { renderMapViewport, mapCaption } from './utilities/map-view.js';
17
17
  import { tallestRoomRows } from './utilities/room-grid.js';
18
18
  import { renderRoomLayoutCompact, crewOfTable } from './utilities/room-view.js';
19
19
  import { getPref } from './utilities/prefs.js';
@@ -102,6 +102,7 @@ import { ThreadCommand } from './commands/thread.js';
102
102
  import { RegisterCommand } from './commands/register.js';
103
103
  import { SpritesCommand } from './commands/sprites.js';
104
104
  import { StandbyCommand } from './commands/standby.js';
105
+ import { SustainCommand } from './commands/sustain.js';
105
106
  import { AbandonCommand } from './commands/abandon.js';
106
107
  import { UnravelCommand } from './commands/unravel.js';
107
108
  import { OrderCommand } from './commands/order.js';
@@ -1236,11 +1237,42 @@ export default class Game {
1236
1237
  entry.npc.deathClaimed = true;
1237
1238
  this.scene.removeActor(entry.npc.name);
1238
1239
  }
1240
+ this.returnSustainedForms(entry);
1239
1241
  const idx = this.companions.indexOf(entry);
1240
1242
  if (idx >= 0)
1241
1243
  this.companions.splice(idx, 1);
1242
1244
  Logger.getInstance().write(`Companion dismissed: ${entry.npc.name} -- ${reason}`);
1243
1245
  }
1246
+ /**
1247
+ * A FORM A SPRITE WAS CARRYING COMES HOME WHEN THE SPRITE GOES
1248
+ * (SR5 p.256 Sustain Complex Form; see commands/sustain.ts).
1249
+ *
1250
+ * The task hands a technomancer's complex form to a registered sprite
1251
+ * so the SPRITE eats the -2. That means the only entry point in the
1252
+ * game that moves a form off its weaver is also the only one that
1253
+ * could destroy it: dismiss, kill or park the sprite and the form
1254
+ * would go into the Resonance with it, silently, looking exactly like
1255
+ * a form the player had dropped on purpose.
1256
+ *
1257
+ * Canon says the technomancer "can then take over sustaining again",
1258
+ * so taking over is the natural end of the arrangement -- and a sprite
1259
+ * leaving is the arrangement ending whether or not anybody typed the
1260
+ * verb. The weave was never the sprite's; it was only being carried.
1261
+ *
1262
+ * Called from BOTH teardown paths on purpose. dismissCompanion covers
1263
+ * dismissal and standby (standbySpriteToResonance dismisses to park),
1264
+ * onActorRemoved covers death. Either alone would leave a hole that
1265
+ * only shows up as a missing form several minutes later.
1266
+ */
1267
+ returnSustainedForms(entry) {
1268
+ const held = entry.npc.sustainedForms;
1269
+ if (!held || held.length === 0)
1270
+ return;
1271
+ const owner = (entry.npc.allyOf ? this.scene?.getPlayerByName(entry.npc.allyOf) : undefined) ?? this.player;
1272
+ owner.sustainedForms.push(...held);
1273
+ entry.npc.sustainedForms = [];
1274
+ Logger.getInstance().logWithColor(`👥 ${entry.npc.name} lets go of ${held.map(f => f.key).join(', ')} -- the weave falls back to you, and so does the sustaining.`, 'yellow');
1275
+ }
1244
1276
  /**
1245
1277
  * An actor left the world (Scene.removeActor). For a companion shell
1246
1278
  * that DIED (not a deliberate dismissal -- those set deathClaimed
@@ -1265,6 +1297,8 @@ export default class Game {
1265
1297
  const entry = this.companions.find(c => c.npc.name === name);
1266
1298
  if (!entry)
1267
1299
  return;
1300
+ // A dead sprite still gives back what it was only carrying.
1301
+ this.returnSustainedForms(entry);
1268
1302
  const idx = this.companions.indexOf(entry);
1269
1303
  if (idx >= 0)
1270
1304
  this.companions.splice(idx, 1);
@@ -1774,6 +1808,36 @@ export default class Game {
1774
1808
  this._pendingRide = undefined;
1775
1809
  this.pendingRunAccepted = false;
1776
1810
  }
1811
+ /**
1812
+ * EVERYTHING THAT BELONGS TO AN OFFER, RESET TOGETHER
1813
+ * (8jZMqtXmxbLiACo3E: "I haven't pushed the number yet").
1814
+ *
1815
+ * An offer carries its own haggle window at the hub -- "call <fixer>"
1816
+ * delivers it and `haggle` works on the spot. Push on one, decline
1817
+ * it, hear the NEXT one, and nothing cleared the flag: not
1818
+ * refreshEdge (departure only, and no ride was called), not
1819
+ * returnToHub (no run to come home from). The first push on the new
1820
+ * offer was then refused with "you already pushed on the number once
1821
+ * this job" -- about a job the runner had turned down.
1822
+ *
1823
+ * THE THIRD HOLE IN ONE BOOLEAN, which is why this is a method and
1824
+ * not another line at a call site. `haggledThisJob` had already been
1825
+ * patched twice, each time for its own report and each time at the
1826
+ * one site that report happened to name: returnToHub for
1827
+ * d4yoYPcRAtWpLtm9y, the headless boot for the shared-run arrival.
1828
+ * There are TWO places a fresh offer is installed -- the solo draft
1829
+ * and the shared-run quote -- and both had the same gap, so a third
1830
+ * per-site patch would have fixed one and left the other reporting
1831
+ * the same sentence.
1832
+ *
1833
+ * NOT called from restoreFromSave, deliberately: a resumed pendingRun
1834
+ * is the SAME offer, and clearing there would forget a push the
1835
+ * runner really did make before they quit.
1836
+ */
1837
+ resetForNewOffer() {
1838
+ this.pendingRunAccepted = false;
1839
+ this.player.haggledThisJob = false;
1840
+ }
1777
1841
  get pendingRun() {
1778
1842
  return this._pendingRunSeed;
1779
1843
  }
@@ -2124,6 +2188,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
2124
2188
  CommandFactory.registerCommand('sprites', SpritesCommand);
2125
2189
  // STANDBY (p.256): the registered-sprite task that parks one for 1.
2126
2190
  CommandFactory.registerCommand('standby', StandbyCommand);
2191
+ CommandFactory.registerCommand('sustain', SustainCommand);
2127
2192
  // Walk out for good -- the taxi's irreversible half (mYTCzJbs...).
2128
2193
  CommandFactory.registerCommand('abandon', AbandonCommand);
2129
2194
  // Kill Complex Form (p.250) -- the Resonance counterpart to dispel.
@@ -3201,7 +3266,24 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
3201
3266
  // raw server error stitched into Krow's fiction read as an
3202
3267
  // instruction to "update the server" (real player note) -- it
3203
3268
  // means update THIS machine.
3204
- const skew = /runs engine ([\d.]+)/.exec(String(shared.declined));
3269
+ // THE SERVER'S REASON IS SPOKEN ALOUD, so it goes through the
3270
+ // identity rule first (5wjyaaY7EKGttGZLQ: "don't put player
3271
+ // names (doubleglizzy) in the message about 'Couldn't raise the
3272
+ // whole crew'. This should be character names").
3273
+ //
3274
+ // The `absent` list below was already fixed to name runners via
3275
+ // nameThem. This is its SIBLING and was missed: a decline comes
3276
+ // back as free text the server composed, and it can name the
3277
+ // seat it could not raise -- by account handle, because that is
3278
+ // what the seat plumbing scopes to. Stitched into Krow's quoted
3279
+ // dialogue, that put a person's site-wide identity in the
3280
+ // fiction.
3281
+ //
3282
+ // Scrubbed ONCE here rather than at each branch: two of the four
3283
+ // branches below interpolate it, and the next one added would
3284
+ // have had to remember.
3285
+ const declined = scrubHandles(String(shared.declined), this.crew.map(m => ({ handle: m.ghost?.owner, name: m.name })));
3286
+ const skew = /runs engine ([\d.]+)/.exec(declined);
3205
3287
  sharedDeclineNote = skew
3206
3288
  ? ` "Crew channel's scrambled tonight -- no job till it clears."\n{yellow-fg}(Out of character: engine mismatch -- this machine runs ${srMod?.engineVersion() ?? '?'}, the street runs ${skew[1]}. If yours is older: npm i -g @maka/maka-cli@latest, then relaunch. If newer, the street is still rolling out.){/yellow-fg}`
3207
3289
  : shared.code === 'unverified'
@@ -3212,8 +3294,8 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
3212
3294
  : shared.code === 'not-your-table'
3213
3295
  // Leader-only crew jobs (ruling 2026-08-24): Krow takes
3214
3296
  // commissions from the head of the table, nobody else.
3215
- ? ` "${shared.declined} Want crew work? Take theirs, or seat a table of your own."`
3216
- : ` "Couldn't raise the whole crew -- ${shared.declined} No crew on the line, no job -- raise them and call again."`;
3297
+ ? ` "${declined} Want crew work? Take theirs, or seat a table of your own."`
3298
+ : ` "Couldn't raise the whole crew -- ${declined} No crew on the line, no job -- raise them and call again."`;
3217
3299
  // CREW EXCLUSIVITY (ruling 2026-08-24): a declined crew draft
3218
3300
  // never falls back to a solo quote -- the ping explains, and
3219
3301
  // the docket stays empty until the table answers.
@@ -3237,7 +3319,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
3237
3319
  // a server draft doesn't survive a quit).
3238
3320
  this._pendingRunTier = undefined;
3239
3321
  this._pendingRide = Game.RIDE_POOL[Math.floor(Math.random() * Game.RIDE_POOL.length)];
3240
- this.pendingRunAccepted = false;
3322
+ this.resetForNewOffer();
3241
3323
  // Off-street seat-mates were dropped from tonight's quote by the
3242
3324
  // server (their seats survive -- back on the street, back on the
3243
3325
  // job). Krow NAMES them; silence here already cost one playtest.
@@ -3334,7 +3416,7 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
3334
3416
  this._pendingRunSeed = nextSeed;
3335
3417
  this._pendingRunTier = nextTier;
3336
3418
  this._pendingRide = Game.RIDE_POOL[Math.floor(Math.random() * Game.RIDE_POOL.length)];
3337
- this.pendingRunAccepted = false;
3419
+ this.resetForNewOffer();
3338
3420
  return `Your link pings -- 1 new message: ${FIXER_NAME}.${sharedDeclineNote}${hint(` ("call ${FIXER_NAME}" to hear the job -- "jobs" shows the board.)`)}`;
3339
3421
  }
3340
3422
  // Classic sessions transition immediately, hideout-first, as always.
@@ -4336,10 +4418,10 @@ ${client.name} won't be remembering anything. Dead Johnsons pay nothing -- and t
4336
4418
  // justify the elevation bar and to trim the caption rows.
4337
4419
  const boxWidth = screenW > 0 ? Math.floor(screenW * Game.ROOM_DOCK_PCT) - 2 : undefined;
4338
4420
  const mapWidth = screenW > 0 ? Math.floor(screenW * Game.MAP_DOCK_PCT) - 2 : undefined;
4339
- const caption = (text, width) => {
4340
- const w = width ?? text.length;
4341
- return `{bold}${text.length > w ? `${text.slice(0, Math.max(1, w - 1))}…` : text}{/bold}`;
4342
- };
4421
+ // ONE CAPTION BUILDER, shared with the server push in headless.ts
4422
+ // -- see mapCaption. Two inline copies is how the district map ended
4423
+ // up captioned solo and blank on a shared run (RwPkFsRwd4c2uHvGN).
4424
+ const caption = mapCaption;
4343
4425
  // The district viewport must FIT ITS BOX. It was a hardcoded 15
4344
4426
  // columns, which was fine while the Map box was 35% wide and
4345
4427
  // silently overflowed into the Room box once it shrank to 12% --