@maka/maka-cli 5.238.0 → 5.239.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/enter-host.js +15 -5
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +2 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +4 -4
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +28 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-reach.js +36 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grid-view.js +12 -2
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.239.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,6 @@
|
|
|
1
1
|
import { Command } from './command.js';
|
|
2
2
|
import { movePersonaWith } from '../utilities/matrix-roster.js';
|
|
3
|
-
import { resolveHostInReach, hostsInReach, gridVicinity, hostOver } from '../utilities/grid-reach.js';
|
|
3
|
+
import { resolveHostInReach, hostsInReach, gridVicinity, hostOver, hostDoorOpenFor } from '../utilities/grid-reach.js';
|
|
4
4
|
import { hint } from '../utilities/hints.js';
|
|
5
5
|
import { hostLabel } from '../utilities/grid-names.js';
|
|
6
6
|
import { billAction } from '../utilities/action-cost.js';
|
|
@@ -61,11 +61,21 @@ export class EnterHostCommand extends Command {
|
|
|
61
61
|
// actions to get a mark has bought the door, and charging them a
|
|
62
62
|
// test here would be inventing a rule the book explicitly denies
|
|
63
63
|
// ("There is no test involved").
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
//
|
|
65
|
+
// AND IT IS THE ONLY GATE (DxfeZTBrP6Bu7MLF4). It used to read `||
|
|
66
|
+
// hostCracked`, which is the SITE's state and never expires -- see
|
|
67
|
+
// grid-reach.ts hostDoorOpenFor for why that was a door nobody could
|
|
68
|
+
// ever close again. A persona whose keys are gone gets its own line:
|
|
69
|
+
// the wreckage it can see from out here is real, and saying "doesn't
|
|
70
|
+
// know you" about a node it personally tore open would read as the
|
|
71
|
+
// engine forgetting the last ten minutes.
|
|
72
|
+
if (!hostDoorOpenFor(target, actor)) {
|
|
73
|
+
const wrecked = target.hostCracked;
|
|
66
74
|
return [
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
wrecked
|
|
76
|
+
? `{light-blue-fg}${hostLabel(target, { capital: true })} is still hanging open where you broke it -- and it does not know YOU. Your keys are out of the lattice; the architecture has nothing shaped like your icon to open for.{/light-blue-fg}`
|
|
77
|
+
: `{light-blue-fg}${hostLabel(target, { capital: true })} doesn't know you. Its architecture has no door shaped like your icon.{/light-blue-fg}`,
|
|
78
|
+
hint(`A host opens to anyone holding a MARK on it, and marks die with the session you placed them in (p.239, p.236) -- "hack ${target.name}" keys it quietly, "force ${target.name}" takes one loud.`),
|
|
69
79
|
].join('\n');
|
|
70
80
|
}
|
|
71
81
|
// A Complex Action (p.239) -- billed only inside a Combat Turn.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { whereIsThat } from '../utilities/matrix-roster.js';
|
|
2
|
-
import { resolveHostInReach, roomsInReach, noiseNote, gridVicinity } from '../utilities/grid-reach.js';
|
|
2
|
+
import { resolveHostInReach, roomsInReach, noiseNote, gridVicinity, hostDoorOpenFor } from '../utilities/grid-reach.js';
|
|
3
3
|
import { perceptionTest } from '../utilities/perception.js';
|
|
4
4
|
import { matchesHostName, matchesCameraName, hostLabel } from '../utilities/grid-names.js';
|
|
5
5
|
import { Door } from '../models/door.js';
|
|
@@ -392,7 +392,7 @@ export class LookCommand extends Command {
|
|
|
392
392
|
return `That file is on the ${room.offlineServer} -- a box with no Matrix presence. Nothing out here reaches it; your body has to be in ${room.name} (p.233).`;
|
|
393
393
|
}
|
|
394
394
|
if (reach === 'enter') {
|
|
395
|
-
return `That file is INSIDE the host -- from out on the grid you have its shell and nothing through it (p.246). ${(room
|
|
395
|
+
return `That file is INSIDE the host -- from out on the grid you have its shell and nothing through it (p.246). ${hostDoorOpenFor(room, this.actor) ? `"enter" to go in.` : `A mark opens the door: "hack ${hostLabel(room)}" (quiet) or "force ${hostLabel(room)}" (loud), then "enter".`}`;
|
|
396
396
|
}
|
|
397
397
|
// The host's seal covers the HOST's archive. A file on an offline
|
|
398
398
|
// server is not in there -- cracking the building's host does
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from './command.js';
|
|
2
2
|
import { whereIsThat } from '../utilities/matrix-roster.js';
|
|
3
|
-
import { gridVicinity } from '../utilities/grid-reach.js';
|
|
3
|
+
import { gridVicinity, hostDoorOpenFor } from '../utilities/grid-reach.js';
|
|
4
4
|
import { fileReach } from '../utilities/planes.js';
|
|
5
5
|
import { canReach, ensureAtSpot, sealedRouteTo } from '../utilities/spots.js';
|
|
6
6
|
import { hint } from '../utilities/hints.js';
|
|
@@ -143,7 +143,7 @@ export class TakeCommand extends Command {
|
|
|
143
143
|
return `Those files are on the ${room.offlineServer} -- off the network entirely. No persona reaches that box; your BODY has to be in ${room.name} (p.233).`;
|
|
144
144
|
}
|
|
145
145
|
if (reach === 'enter') {
|
|
146
|
-
return `Those files are INSIDE the host, and you're out on the grid looking at its shell (p.246). ${room
|
|
146
|
+
return `Those files are INSIDE the host, and you're out on the grid looking at its shell (p.246). ${hostDoorOpenFor(room, this.actor) ? `"enter" first.` : `Get a mark on it and "enter" -- or "hack" your way in.`}`;
|
|
147
147
|
}
|
|
148
148
|
// Same split as look.ts: the host's seal does not reach a box that
|
|
149
149
|
// is not on the network. The air gap IS the server's security.
|
|
@@ -291,7 +291,7 @@ export class TakeCommand extends Command {
|
|
|
291
291
|
if (far.reach === 'offline')
|
|
292
292
|
return `${far.item.name} is on the ${far.room.offlineServer} in ${far.room.name} -- an offline server, off the network entirely. No persona reaches that box; your BODY has to be in ${far.room.name} (p.233).`;
|
|
293
293
|
if (far.reach === 'host')
|
|
294
|
-
return `${far.item.name} is INSIDE ${far.room.name}'s host, and you're out on the grid looking at its shell (p.246). ${far.room
|
|
294
|
+
return `${far.item.name} is INSIDE ${far.room.name}'s host, and you're out on the grid looking at its shell (p.246). ${hostDoorOpenFor(far.room, this.actor) ? `"enter ${far.room.name}" first.` : `Get a mark on it and "enter" -- or "hack" your way in.`}`;
|
|
295
295
|
if (far.reach === 'open')
|
|
296
296
|
return `${far.item.name} is loose on the grid -- a dim icon. ${hint(`"download ${far.item.name}" writes it to a chip from here.`)}`;
|
|
297
297
|
}
|
|
@@ -337,7 +337,7 @@ export class TakeCommand extends Command {
|
|
|
337
337
|
return `The ${item.name} sits on the ${room.offlineServer} -- a box with no Matrix presence at all. No persona reaches it from anywhere: get your BODY into ${room.name} and cable in (p.233).`;
|
|
338
338
|
}
|
|
339
339
|
if (reach === 'enter') {
|
|
340
|
-
return `The ${item.name} is INSIDE the host -- you're on the outside grid, reading its shell (p.246). ${(room
|
|
340
|
+
return `The ${item.name} is INSIDE the host -- you're on the outside grid, reading its shell (p.246). ${hostDoorOpenFor(room, this.actor) ? `"enter" first.` : `Get a mark on it and "enter" -- or "hack" your way in.`}`;
|
|
341
341
|
}
|
|
342
342
|
// A LOOSE END IS ERASED, NOT CARRIED (win-condition-seed.ts 'erase',
|
|
343
343
|
// 2026-09-14): pulling the footage down to a chip leaves the desk's
|
|
@@ -1614,5 +1614,32 @@
|
|
|
1614
1614
|
// names the cable. The AR overlay deliberately says NOTHING: that
|
|
1615
1615
|
// surface annotates broadcasts, which is its stated contract, and the
|
|
1616
1616
|
// first cut of this violated it.
|
|
1617
|
-
|
|
1617
|
+
// 1.88.0 (2026-09-17): THE DOOR INTO A HOST IS A MARK AND NOTHING ELSE
|
|
1618
|
+
// (DxfeZTBrP6Bu7MLF4, Maka: "I shouldn't be able to re-enter the host
|
|
1619
|
+
// if I have no marks on it"). `enter` accepted Room.hostCracked as a
|
|
1620
|
+
// substitute for the key. That flag is ROOM-GLOBAL and permanent for
|
|
1621
|
+
// the save -- once anybody took a node to three marks its door never
|
|
1622
|
+
// shut again, for anybody. The reporter's own transcript walks it:
|
|
1623
|
+
// three marks forced into the Approach host, cracked, JACK OUT (canon
|
|
1624
|
+
// deletes every mark they placed, p.242), jack back in reading MARKS
|
|
1625
|
+
// 0 held -- and straight back inside with the Patrol locking on.
|
|
1626
|
+
// Canon is one sentence (p.239, RAG-checked 2026-09-17): "a host
|
|
1627
|
+
// allows anyone to enter if they've got a mark", marks "only last a
|
|
1628
|
+
// single Matrix session" (p.236), three of them buy nothing that
|
|
1629
|
+
// outlives them, and a host's owner cannot be changed (p.237). This
|
|
1630
|
+
// is 1.56.0's ruling (spcebZTKN24GYRHXW, a cracked host is not a host
|
|
1631
|
+
// you hold marks on) finally applied to the one verb the flag was
|
|
1632
|
+
// actually a door for. The crack's WORLD consequences are untouched:
|
|
1633
|
+
// the vault still hangs open, the archive still reads unsealed, the
|
|
1634
|
+
// maglocks it released stay released -- those are facts about the
|
|
1635
|
+
// site, and the key is a fact about you.
|
|
1636
|
+
// ONE GATE, ONE ANSWER: grid-reach.ts hostDoorOpenFor is now the only
|
|
1637
|
+
// place that decides, and every surface that says "enter" asks it --
|
|
1638
|
+
// the verb, look/take's file refusals, and the grid icon, which used
|
|
1639
|
+
// to print `("enter" walks in)` under a crack and would otherwise have
|
|
1640
|
+
// become an invitation the verb refuses.
|
|
1641
|
+
// THE HAVEN IS THE ONE EXEMPTION and is labelled as an engine ruling,
|
|
1642
|
+
// not canon: a sanctioned host (Room.hostSanctioned, JackPoint) is a
|
|
1643
|
+
// members' place, and membership is the mark.
|
|
1644
|
+
export const ENGINE_VERSION = '1.88.0';
|
|
1618
1645
|
//# sourceMappingURL=engine-version.js.map
|
|
@@ -41,6 +41,42 @@ export function hostsInReach(rooms, actor) {
|
|
|
41
41
|
export function hostOver(room) {
|
|
42
42
|
return room?.hasNode ? room : undefined;
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* IS THE DOOR OPEN TO THIS PERSONA -- the one answer, so that the verb
|
|
46
|
+
* that crosses and every hint that says "enter" cannot disagree
|
|
47
|
+
* (DxfeZTBrP6Bu7MLF4, Maka: "I shouldn't be able to re-enter the host if
|
|
48
|
+
* I have no marks on it").
|
|
49
|
+
*
|
|
50
|
+
* p.239 is one sentence long: "Marks required 1 ... a host allows anyone
|
|
51
|
+
* to enter if they've got a mark." RAG-checked 2026-09-17, which also
|
|
52
|
+
* settles the other half: marks "only last a single Matrix session and
|
|
53
|
+
* are deleted when you reboot" (p.236), reaching three of them buys
|
|
54
|
+
* nothing that outlives them, and a host's owner cannot be changed
|
|
55
|
+
* (p.237) -- so there is no state in canon that stands in for the key.
|
|
56
|
+
*
|
|
57
|
+
* WHAT USED TO STAND IN FOR IT. `enter` accepted Room.hostCracked, which
|
|
58
|
+
* is ROOM-GLOBAL and permanent for the save: once anybody took the node
|
|
59
|
+
* to three marks, that door never closed again -- not for the decker who
|
|
60
|
+
* jacked out (canon wipes their marks, p.242) and not for a team-mate
|
|
61
|
+
* who had never touched it. That is the same confusion 1.56.0 named for
|
|
62
|
+
* `hack`/`mark` (spcebZTKN24GYRHXW: a cracked host is not a host you
|
|
63
|
+
* hold marks on) with the one verb the flag was actually a door for left
|
|
64
|
+
* out. The crack's WORLD consequences are untouched -- a vault hanging
|
|
65
|
+
* open stays open, its archive stays listed -- because those are facts
|
|
66
|
+
* about the site and this is a fact about your keys.
|
|
67
|
+
*
|
|
68
|
+
* THE HAVEN IS THE ONE EXEMPTION, and it is an engine ruling, not canon:
|
|
69
|
+
* a sanctioned host (utilities/jackpoint.ts, Room.hostSanctioned) is a
|
|
70
|
+
* members' place you belong to, and membership is the mark. Labelled
|
|
71
|
+
* here rather than hidden in a boolean.
|
|
72
|
+
*/
|
|
73
|
+
export function hostDoorOpenFor(room, actor) {
|
|
74
|
+
if (!room.hasNode)
|
|
75
|
+
return false;
|
|
76
|
+
if (room.hostSanctioned)
|
|
77
|
+
return true;
|
|
78
|
+
return (room.hostMarksBy.get(actor.name) ?? 0) >= 1;
|
|
79
|
+
}
|
|
44
80
|
/**
|
|
45
81
|
* A host by any name the game shows for it (grid-names.ts), from
|
|
46
82
|
* anywhere on the grid. Bare "host" (or nothing) means the one over the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { sameHostSide } from '../models/player.js';
|
|
2
2
|
import { personasInside } from './matrix-roster.js';
|
|
3
|
-
import { hostsInReach, hostLine, roomsInReach, gridVicinity } from './grid-reach.js';
|
|
3
|
+
import { hostsInReach, hostLine, roomsInReach, gridVicinity, hostDoorOpenFor } from './grid-reach.js';
|
|
4
4
|
import { NPC } from '../models/npc.js';
|
|
5
5
|
import { hostLabel, hostPurposeFor } from './grid-names.js';
|
|
6
6
|
import { isLinked } from './comm-style.js';
|
|
@@ -142,7 +142,17 @@ export function gridIcons(scene, actor, room) {
|
|
|
142
142
|
icons.push(`● ${hostLabel(room, { capital: true })} -- three spheres turning over rooms that were never sold to anyone. You're on the list; nothing here is hunting.`);
|
|
143
143
|
}
|
|
144
144
|
else if (room.hostCracked) {
|
|
145
|
-
|
|
145
|
+
// THE WRECKAGE IS THE SITE'S; THE DOOR IS STILL YOURS TO HOLD
|
|
146
|
+
// (DxfeZTBrP6Bu7MLF4). This line offered `"enter" walks in` on the
|
|
147
|
+
// room-global crack alone, so a persona whose marks a jack-out had
|
|
148
|
+
// just wiped (p.242) read an invitation the verb then refused --
|
|
149
|
+
// or, before the verb was fixed, accepted, which is the report.
|
|
150
|
+
// Both halves stay true now: the vault hangs open, and the key is
|
|
151
|
+
// per-persona and dies with the session (p.236).
|
|
152
|
+
const way = hostDoorOpenFor(room, actor)
|
|
153
|
+
? `("enter" walks in on your mark)`
|
|
154
|
+
: `("hack ${hostLabel(room)}" or "force ${hostLabel(room)}" for a mark -- yours are gone, and a host still asks for one, p.239)`;
|
|
155
|
+
icons.push(`● ${hostLabel(room, { capital: true })}${hr}${purpose} -- cracked open, security in shreds. Whatever it guarded is unsealed, inside. ${way}`);
|
|
146
156
|
}
|
|
147
157
|
else {
|
|
148
158
|
const myMarks = room.hostMarksBy.get(actor.name) ?? 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.239.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.",
|