@maka/maka-cli 5.202.0 → 5.204.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.
- package/bundle/typescript/package.json +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +3 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/compile.js +7 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/erase-mark.js +13 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/message.js +3 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.js +11 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/say.js +9 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +40 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.js +7 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +18 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.204.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.",
|
|
@@ -595,7 +595,9 @@ export class CallCommand extends Command {
|
|
|
595
595
|
try {
|
|
596
596
|
const sr = await import('../utilities/shared-run.js');
|
|
597
597
|
await sr.HubLink.ready(this.game ?? undefined);
|
|
598
|
-
|
|
598
|
+
// `from` names the SPEAKER, not the account (t8qhbB3c3PRRkq5sP --
|
|
599
|
+
// see say.ts's party branch for the report this closes).
|
|
600
|
+
const res = await sr.HubLink.call('sideQuest.partyPage', { text: greeting, from: this.actor.name });
|
|
599
601
|
if (this.actor.activeCallPartner) {
|
|
600
602
|
this.actor.activeCallPartner.activeCallPartner = undefined;
|
|
601
603
|
this.actor.activeCallPartner = undefined;
|
|
@@ -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.`
|
|
@@ -90,7 +90,9 @@ export class MessageCommand extends Command {
|
|
|
90
90
|
}
|
|
91
91
|
const text = rest.join(' ');
|
|
92
92
|
try {
|
|
93
|
-
const res = await sr.HubLink.call(
|
|
93
|
+
const res = await sr.HubLink.call(
|
|
94
|
+
// `from` names the SPEAKER (t8qhbB3c3PRRkq5sP) -- see say.ts.
|
|
95
|
+
'sideQuest.message', { handle: target.handle, text, from: this.actor.name });
|
|
94
96
|
const landed = res.reach === 'online'
|
|
95
97
|
? `They're on the street -- it lands now.`
|
|
96
98
|
: `They're off the grid; it waits on their link until they jack in.`;
|
|
@@ -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
|
-
|
|
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
|
|
@@ -208,8 +208,16 @@ export class SayCommand extends Command {
|
|
|
208
208
|
try {
|
|
209
209
|
if (channel.party) {
|
|
210
210
|
// THE PARTY LINE: one say, every accepted seat hears it.
|
|
211
|
+
//
|
|
212
|
+
// `from` NAMES THE SPEAKER (t8qhbB3c3PRRkq5sP, live
|
|
213
|
+
// 2026-09-16: "Ted says Hi, who's Ted?" -- Ted being another
|
|
214
|
+
// character on the speaker's account). This call used to
|
|
215
|
+
// carry the text alone, so the server had nothing to sign it
|
|
216
|
+
// with but the account's presence row, which names whichever
|
|
217
|
+
// runner beat last and can be a day stale. The 1:1 branch
|
|
218
|
+
// below always sent `from`; the party line simply never did.
|
|
211
219
|
const sr = await import('../utilities/shared-run.js');
|
|
212
|
-
await sr.HubLink.call('sideQuest.partyPage', { text: message });
|
|
220
|
+
await sr.HubLink.call('sideQuest.partyPage', { text: message, from: currentPlayer.name });
|
|
213
221
|
}
|
|
214
222
|
else {
|
|
215
223
|
const transport = await this.game?.streetTransport();
|
|
@@ -741,5 +741,44 @@
|
|
|
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
|
-
|
|
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
|
+
// 1.66.0 (2026-09-16): THE CREW CHANNEL NAMES WHO SPOKE
|
|
766
|
+
// (t8qhbB3c3PRRkq5sP, live: "Ted says Hi, who's Ted?" -- Ted being
|
|
767
|
+
// another character on the speaker's account, who was playing Jynx).
|
|
768
|
+
// A page is signed server-side, and for the PARTY LINE the server had
|
|
769
|
+
// nothing to sign with but the account's presence row: ONE PER
|
|
770
|
+
// ACCOUNT, naming whichever runner heartbeated last, and never written
|
|
771
|
+
// at all by the browser or a hosted session. The reported row was a
|
|
772
|
+
// day stale, so every crew line that evening went out under a
|
|
773
|
+
// character nobody at the table was playing.
|
|
774
|
+
// - say.ts's party branch and call.ts's openPartyLine now send
|
|
775
|
+
// `from` -- the speaking actor -- exactly as the 1:1 branch beside
|
|
776
|
+
// them always has. `message` too.
|
|
777
|
+
// - game.ts's default street `send` stops DROPPING the `from` its own
|
|
778
|
+
// signature documents as "the sending ACTOR, which a multi-human
|
|
779
|
+
// server scene resolves to the right account".
|
|
780
|
+
// The name is still only a claim: the server verifies it against the
|
|
781
|
+
// account's seats and saves before stamping it, and an older client
|
|
782
|
+
// that sends none keeps the presence fallback.
|
|
783
|
+
export const ENGINE_VERSION = '1.66.0';
|
|
745
784
|
//# sourceMappingURL=engine-version.js.map
|
|
@@ -2368,7 +2368,13 @@ export default class Game {
|
|
|
2368
2368
|
const players = await fetchPlayers().catch(() => undefined);
|
|
2369
2369
|
return (players ?? []).map(p => ({ playerName: p.playerName, handle: p.handle }));
|
|
2370
2370
|
},
|
|
2371
|
-
|
|
2371
|
+
// `from` IS PASSED ON, NOT DROPPED (t8qhbB3c3PRRkq5sP): the
|
|
2372
|
+
// signature has always named the sending actor so that a
|
|
2373
|
+
// multi-human scene resolves it to the right account -- this
|
|
2374
|
+
// default quietly threw it away, leaving the server to sign the
|
|
2375
|
+
// page from the account's presence row (one per ACCOUNT, naming
|
|
2376
|
+
// whichever runner heartbeated last).
|
|
2377
|
+
send: ({ from, handle, text }) => sr.HubLink.call('sideQuest.page', { handle, text, from }),
|
|
2372
2378
|
};
|
|
2373
2379
|
}
|
|
2374
2380
|
/**
|
|
@@ -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.
|
|
3
|
+
"version": "5.204.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.",
|