@maka/maka-cli 5.202.0 → 5.203.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.202.0",
3
+ "version": "5.203.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.",
@@ -1,6 +1,7 @@
1
1
  import { Command } from './command.js';
2
2
  import { rollPool, formatRoll } from '../utilities/dice.js';
3
3
  import { hint } from '../utilities/hints.js';
4
+ import { spriteMatrix } from '../sprite-powers.js';
4
5
  import { fuzzyPickName } from '../utilities/fuzzy-match.js';
5
6
  /** Exported for game.ts: re-shelling a REGISTERED sprite after travel
6
7
  * or a resumed save needs the same stat builder. */
@@ -161,6 +162,12 @@ export class CompileCommand extends Command {
161
162
  // A sprite rides its compiler's persona: same grid, same host.
162
163
  if (shell)
163
164
  shell.matrixPosition = actor.matrixPosition;
165
+ // ...and carries its OWN Matrix array (p.254, p.259), which is what
166
+ // fills the [Sleaze]/[Attack] bracket on every roll it makes. It
167
+ // has no deck for the rig lookup to find, so without this its
168
+ // limits computed to 0 and rollPool refused them as "not a limit".
169
+ if (shell)
170
+ shell.spriteMatrixAttrs = spriteMatrix(typeKey, level);
164
171
  if (shell && this.game) {
165
172
  const entry = this.game.companions.find(c => c.npc === shell);
166
173
  if (entry)
@@ -13,6 +13,17 @@ export class EraseMarkCommand extends Command {
13
13
  static verb = 'unmark';
14
14
  static description = 'Erase Mark (Complex Action, SR5 p.239): "unmark me" scrubs the marks others hold on your persona; "unmark <icon>" needs three marks on that icon first. Computer + Logic [Attack] v. Willpower + Firewall. An Attack action -- GOD counts it. Also "erase mark on <icon>".';
15
15
  static npcPolicy = 'authorized';
16
+ /**
17
+ * A PLACER'S NAME STARTING A SENTENCE. `hostLabel` yields "the Approach
18
+ * host", lowercase and correct mid-clause -- and these lines open with
19
+ * it, so a bench read "the Approach host's key sloughs off...". The
20
+ * same class of blemish grid-names.ts records at length: cosmetic, and
21
+ * not harmless on a repro bench, where a reviewer meeting broken prose
22
+ * reasonably starts doubting the fixture.
23
+ */
24
+ static opening(name) {
25
+ return name.charAt(0).toUpperCase() + name.slice(1);
26
+ }
16
27
  /** p.239: two marks at -4, three at -10; one is unpenalised. */
17
28
  static penaltyFor(count) {
18
29
  if (count >= 3)
@@ -180,7 +191,7 @@ export class EraseMarkCommand extends Command {
180
191
  if (attempt.hits <= resist.hits) {
181
192
  this.logger.write(`${actor.name} failed Erase Mark on ${label} (${chosen.name}): ${attempt.hits} v ${resist.hits}.`);
182
193
  return [
183
- `The key holds. ${chosen.name}'s mark is still written into ${label} and your scrub slides off it.`,
194
+ `The key holds. ${EraseMarkCommand.opening(chosen.name)}'s mark is still written into ${label} and your scrub slides off it.`,
184
195
  hint(` (A Complex Action each try${take > 1 ? `; going for ${take} at once cost you ${penalty} dice` : ''}.)`),
185
196
  ...(god.length > 0 ? [`\n${god.join('\n')}`] : []),
186
197
  ].join('');
@@ -192,7 +203,7 @@ export class EraseMarkCommand extends Command {
192
203
  this.logger.write(`${actor.name} erased ${take} of ${chosen.name}'s mark(s) on ${label}: ${attempt.hits} v ${resist.hits}.`);
193
204
  const left = this.remainingOn(target, actor);
194
205
  return [
195
- `{light-blue-fg}${chosen.name}'s ${take > 1 ? `${take} keys slough` : 'key sloughs'} off ${label} -- the recognition pattern unwrites itself and ${target.kind === 'self' ? 'your icon stops answering to it' : 'the icon forgets it ever agreed'}.{/light-blue-fg}`,
206
+ `{light-blue-fg}${EraseMarkCommand.opening(chosen.name)}'s ${take > 1 ? `${take} keys slough` : 'key sloughs'} off ${label} -- the recognition pattern unwrites itself and ${target.kind === 'self' ? 'your icon stops answering to it' : 'the icon forgets it ever agreed'}.{/light-blue-fg}`,
196
207
  target.kind === 'self'
197
208
  ? (left > 0
198
209
  ? `\n${left} mark${left === 1 ? '' : 's'} still on you.`
@@ -265,6 +265,16 @@ export class OrderCommand extends Command {
265
265
  // Result strings that mean the atomic tier bounced -- collected from
266
266
  // real refusals (go/attack/talk/take across sessions). The ’ variant
267
267
  // covers commands that answer with a smart quote.
268
- static ATOMIC_REFUSAL = /not a way to go|can['’]t go that way|isn['’]t here|don['’]t see|there is no item|too heavy|doesn['’]t know how|not valid|doesn['’]t seem to have/i;
268
+ //
269
+ // THE MATRIX REFUSALS WERE MISSING, and a repro bench found it the day
270
+ // sprites started being billed at all (wjFBY3zgyWzJP9adw). Order a
271
+ // sprite at a maglock slaved to a host you hold no mark on and `hack`
272
+ // answers "a host's devices answer nobody who holds no mark on the
273
+ // host itself" -- a refusal, nothing rolled, nothing changed. It
274
+ // matched none of the phrases below, so the atomic tier read it as
275
+ // obedience and charged a task for it. Free before this only because
276
+ // no sprite was ever charged for anything; a spirit ordered into the
277
+ // same wall has always paid a service for nothing.
278
+ static ATOMIC_REFUSAL = /not a way to go|can['’]t go that way|isn['’]t here|don['’]t see|there is no item|too heavy|doesn['’]t know how|not valid|doesn['’]t seem to have|answer nobody who holds no mark|no cyberdeck|needs a MARK|hold none on|is not here to|nothing here answers to|finds no persona|finds no device/i;
269
279
  }
270
280
  //# sourceMappingURL=order.js.map
@@ -741,5 +741,26 @@
741
741
  // - PURGED: the dead `firearms` skill key from the NPC prompt, the
742
742
  // ganger constant and the seed doc; a seed still carrying it maps
743
743
  // onto pistols/automatics/longarms at the boundary.
744
- export const ENGINE_VERSION = '1.64.0';
744
+ // 1.65.0 (2026-09-16): THREE THINGS THE FIRST SPRITE BENCH FOUND. The
745
+ // repro bench for wjFBY3zgyWzJP9adw made an ordered sprite's dice
746
+ // visible for the first time, and visible dice are readable dice.
747
+ // - A SPRITE'S MATRIX ARRAY IS ITS OWN (p.254, p.259). It carries no
748
+ // deck, so baseMatrixAttribute's rig lookup returned 0 and every
749
+ // bracketed sprite roll computed a limit of zero -- which rollPool
750
+ // refuses as "not a limit" and said so, out loud, in the
751
+ // transcript. commands/compile.ts now stamps the book's per-type
752
+ // table (sprite-powers.spriteMatrix) onto the shell, so [Sleaze],
753
+ // [Attack] and [Data Processing] finally have numbers in them.
754
+ // Only Resonance equals Level; the four attributes do not.
755
+ // - A REFUSED ORDER MUST NOT COST A TASK. order.ts decides the atomic
756
+ // tier bounced by matching the result against a phrase list, and
757
+ // the Matrix refusals were never in it -- so a sprite ordered at a
758
+ // maglock slaved to a host it holds no mark on was told no AND
759
+ // charged for it. Free before only because sprites were charged for
760
+ // nothing; a spirit walked into the same wall and paid a service.
761
+ // - Erase Mark opened two lines with a host's lowercase label ("the
762
+ // Approach host's key sloughs off..."). Cosmetic, and the same
763
+ // class of blemish grid-names.ts records at length, because a
764
+ // reviewer meeting broken prose on a bench doubts the fixture.
765
+ export const ENGINE_VERSION = '1.65.0';
745
766
  //# sourceMappingURL=engine-version.js.map
@@ -630,6 +630,14 @@ export class Player extends AbstractPlayer {
630
630
  * long as the sprite.
631
631
  */
632
632
  cookiedBy = new Map();
633
+ /**
634
+ * A SPRITE'S FOUR MATRIX ATTRIBUTES (SR5 p.254, p.259), stamped on the
635
+ * shell by commands/compile.ts. A sprite carries no deck, so without
636
+ * this every bracketed sprite roll computed a limit of 0 -- which
637
+ * rollPool rightly refuses as "not a limit" rather than honouring.
638
+ * Only Resonance equals Level; the four attributes are per TYPE.
639
+ */
640
+ spriteMatrixAttrs;
633
641
  /**
634
642
  * DIAGNOSTICS (p.257): the Teamwork bonus a machine sprite is holding
635
643
  * on ONE device -- "it takes the sprite's entire attention", so there
@@ -907,6 +915,16 @@ export class Player extends AbstractPlayer {
907
915
  baseMatrixAttribute(kind) {
908
916
  if (this.icHost)
909
917
  return this.icHost.attributes()[kind];
918
+ // A SPRITE'S ARRAY IS ITS OWN (SR5 p.254, p.259). It has no deck, so
919
+ // the rig lookup below returned 0 -- and a 0 reaching rollPool is
920
+ // refused as "not a limit", which is exactly what a repro bench
921
+ // caught the day an ordered sprite's dice first became visible
922
+ // (wjFBY3zgyWzJP9adw): the roll happened, unlimited, and said so.
923
+ // Set on the shell at compile time from sprite-powers.spriteMatrix,
924
+ // which carries the book's per-type table; only Resonance equals
925
+ // Level, the four attributes do not.
926
+ if (this.spriteMatrixAttrs)
927
+ return this.spriteMatrixAttrs[kind];
910
928
  if (this.isTechnomancer()) {
911
929
  switch (kind) {
912
930
  case 'attack': return this.charisma;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maka/maka-cli",
3
- "version": "5.202.0",
3
+ "version": "5.203.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.",